"use strict";
var randomstring = require("randomstring");
var express = require("express");
var {
VM
} = require("vm2");
var fs = require("fs");
var app = express();
var flag = require("./config.js").flag
app.get("/", function(req, res) {
res.header("Content-Type", "text/plain");
/* Orange is so kind so he put the flag here. But if you can guess correctly :P */
eval("var flag_" + randomstring.generate(64) + " = \"flag{" + flag + "}\";")
if (req.query.data && req.query.data.length <= 12) {
var vm = new VM({
timeout: 1000
});
console.log(req.query.data);
res.send("eval ->" + vm.run(req.query.data));
} else {
res.send(fs.readFileSync(__filename).toString());
}
});
app.listen(3000, function() {
console.log("listening on port 3000!");
});
程序逻辑很简单,读取flag,存入随机名字的变量中。
创建vm2沙箱,在沙箱中执行代码,并返回执行的结果。
原本思路是沙箱逃逸,搜来搜去发现了另一个漏洞,和沙箱逃逸没啥关系。
Node.js中存在一个对象Buffer,用于创建缓冲区,但是不同于TypedArray,在使用new Buffer(size)或者它的别名Buffer(size)创建时,会得到一块未被清空的内存,而这块内存包含之前的各种变量以及数据。
那么接下来就可以通过这个对象来读取到flag变量。
payload:
http://111.200.241.244:48918/?data=Buffer(1e4)
访问后会下载一个文件,在文件中搜索flag关键字即可拿到flag。