ASISCTF
本文最后更新于502 天前,其中的信息可能已经过时,如有错误请发送邮件到1714510997@qq.com

国内很多报了名的比赛大都是十月份左右才开始,所以协会里就提议打打国外的比赛,最近的就是这一场了,国外的比赛跟国内在题型上还是有很大的差别的,web题全是xss和js这种阴间题目,我们四五个人看了几个小时才解出了一道web,哎,终究还是不够努力

hello

<?php
/*
Read /next.txt
Hint for beginners: read curl's manpage.
*/
highlight_file(__FILE__);
$url = 'file:///hi.txt';
if(
    array_key_exists('x', $_GET) &&
    !str_contains(strtolower($_GET['x']),'file') && 
    !str_contains(strtolower($_GET['x']),'flag')
){
    $url = $_GET['x'];
}
system('curl '.escapeshellarg($url));

hiii o/

这一步很简单,主要就是绕过file和next的检测,array_key_exists('x', $_GET) &&!str_contains(strtolower($_GET['x']),'file') && !str_contains(strtolower($_GET['x']),'flag'),这里的三个函数虽然不多见,但是猜也能猜个大概出来

array_key_exists():判断传入的数组里有没有x这个键

str_contains():和正则匹配的函数类似,匹配前面的参数里是否有后面参数中的关键词

strtolower():将传入的字符串转为小写

可以看到,大小写绕过肯定是不行了,但是利用正则匹配绕过还是可以的

给了我们一个地址,访问一下,有这样一句话

did you know i can read files?? amazing right,,, maybe try /39c8e9953fe8ea40ff1c59876e0e2f28/read/?file=/proc/self/cmdline

那我们就照着他的意思读一下进程,里面有base64加密的密文,解码后得到这样的进程/bin/bun-1.0.2/app/index.js

拿到源码

const fs = require('node:fs');
const path = require('path')

/*
I wonder what is inside /next.txt  
*/

const secret = '39c8e9953fe8ea40ff1c59876e0e2f28'
const server = Bun.serve({
  port: 8000,
  fetch(req) {
  	let url = new URL(req.url);
  	let pname = url.pathname;
  	if(pname.startsWith(`/${secret}`)){
      if(pname.startsWith(`/${secret}/read`)){
        try{
          let fpath = url.searchParams.get('file');
          if(path.basename(fpath).indexOf('next') == -1){ 
            return new Response(fs.readFileSync(fpath).toString('base64'));
          } else {
            return new Response('no way');
          }
        } catch(e){ }
        return new Response("Couldn't read your file :(");
      }
      return new Response(`did you know i can read files?? amazing right,,, maybe try /${secret}/read/?file=/proc/self/cmdline`);
    }
    return 
  }
});

我们重点关注这几行代码

if(path.basename(fpath).indexOf('next') == -1){ 
            return new Response(fs.readFileSync(fpath).toString('base64'));
          } else {
            return new Response('no way');
          }

path.basename():这个函数会将我们传入的路径分割,将最后一个/后面的内容作为返回值

index.of():也是相当于匹配字符串,如果没有就返回-1

fs.readFileSync(fpath).toString('base64'):将读取到的文件用base64编码输出

我们猜测flag应该就在next.txt文件里面,但是如何绕过呢?既然basename()以最后一个/后面的内容作为返回值,我们不妨构造?file=/next.txt/1,这样返回的数据文件就是1,成功绕过了if条件,但是另一个问题来了,/next.txt/1这个文件肯定是不存在的,我们要想办法把/1截断,到这里你肯定会想到文件读取中的%00截断,没错我们最后的payload就是

?file=/next.txt%00/1

文末附加内容

评论

  1. smallblack
    iPhone Safari
    2 年前
    2023-9-24 1:41:42

    好好好,本来还想自己写的,明天直接抄了🐶

    • 博主
      smallblack
      Windows Edge
      2 年前
      2023-9-24 11:03:08

      好好好,偷看我博客是吧

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇