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
EXPLOIT-CVE-2026-22778 — Proof-of-concept exploit per CVE-2026-22778, una RCE non autenticata nell'elaborazione video di vLLM, che dimostra la divulgazione di indirizzi heap e un heap buffer overflow nel decoder JPEG2000 di FFmpeg. Include un laboratorio vulnerabile per test autorizzati. | Kitploit
Strumenti/GitHubGitHub/joaovicdev/exploit-cve-2026-22778
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebFuzzingPenetration TestingApprendimento e FormazioneBinary ExploitationLab e Pratica

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 →
GitHub
joaovicdev/exploit-cve-2026-22778

EXPLOIT-CVE-2026-22778

Proof-of-concept exploit per CVE-2026-22778, una RCE non autenticata nell'elaborazione video di vLLM, che dimostra la divulgazione di indirizzi heap e un heap buffer overflow nel decoder JPEG2000 di FFmpeg. Include un laboratorio vulnerabile per test autorizzati.

Vedi Repository
19h 14m faNon ancora revisionato
Condividi

CVE-2026-22778 — RCE in vLLM nell'elaborazione video

Laboratorio vulnerabile + proof of concept per CVE-2026-22778 (CVSS 9.8), una catena di esecuzione remota di codice non autenticata nel percorso di ingestione multimodale di vLLM.

CVECVE-2026-22778
AdvisoryGHSA-4r2x-xpjr-7cvv
Versioni interessatevLLM >= 0.8.3, < 0.14.1 (deployment che servono modelli video)
Corretta invLLM 0.14.1
CVSS9.8 — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Bug sottostanteCVE-2025-9951 — heap buffer overflow nel decoder JPEG2000 di FFmpeg

La vulnerabilità

Due difetti distinti concatenati tra loro. Un vllm serve predefinito non ha autenticazione, quindi entrambi sono raggiungibili senza autenticazione su /v1/chat/completions e /v1/invocations.

Fase 1 — divulgazione dell'indirizzo heap (bypass ASLR)

Quando un'immagine non riesce a essere analizzata, Pillow solleva un'eccezione il cui messaggio incorpora il repr() dell'oggetto BytesIO da cui stava leggendo:

root@kitploit:~
cannot identify image file <_io.BytesIO object at 0x7f4a9c2e1d50>

vLLM trasformava gli errori di caricamento dei media in un HTTP 400 e restituiva exc.detail al client senza modifiche (api_server.py):

root@kitploit:~
async def http_exception_handler(_: Request, exc: HTTPException):
    err = ErrorResponse(
        error=ErrorInfo(
            message=exc.detail,          # <-- divulga l'indirizzo senza modifiche
            ...

Quel singolo indirizzo riduce l'ASLR dell'heap da ~32 bit di entropia a circa 3, ed è ciò che rende la fase 2 sfruttabile anziché un semplice crash.

Fase 2 — heap buffer overflow nel decoder JPEG2000

Un video_url viene recuperato dal server e passato a OpenCV:

root@kitploit:~
MediaConnector.load_from_url()      vllm/multimodal/utils.py
  -> OpenCVVideoBackend.load_bytes()   vllm/multimodal/video.py
    -> cv2.VideoCapture(BytesIO(data), backend, [])
      -> FFmpeg 5.1.x (incluso in opencv-python-headless < 4.13)

vLLM ha fissato opencv-python-headless >= 4.11.0, che include FFmpeg 5.1.x. Il suo decoder JPEG2000 seleziona il piano di destinazione direttamente dal box channel-definition (cdef) del file — libavcodec/jpeg2000dec.c, write_frame_8:

root@kitploit:~
if (planar)
    plane = s->cdef[compno] ? s->cdef[compno]-1 : (s->ncomponents-1);
...
int w = tile->comp[compno].coord[0][1] - ...;   /* dal componente  */
int h = tile->comp[compno].coord[1][1] - ...;   /* non dal piano! */

plane è controllato dall'attaccante ma w/h provengono dal componente in fase di decodifica, e nulla verifica che uno rientri nell'altro. Una voce cdef di cn=0, asoc=2 invia il componente 0 — il piano luma a piena risoluzione — nel piano 1, il piano chroma sottocampionato 2×2.

Per il frame 150×64 utilizzato da questo PoC:

dimensione
Componente Y (scritto)150 × 64 = 9.600 byte
Piano U (destinazione)75 × 32 = 2.400 byte
Overflow7.200 byte oltre l'allocazione

FFmpeg alloca ogni piano come un proprio AVBuffer, quindi l'overflow attraversa i chunk heap adiacenti — inclusi gli struct AVBuffer che contengono un puntatore a funzione free. Combinato con la leak della fase 1, sovrascrivere quel puntatore è ciò che trasforma la corruzione in esecuzione di codice.

Questo PoC si ferma alla corruzione della memoria. Dimostra la scrittura fuori dai limiti terminando il processo del server. Il heap grooming e la sovrascrittura del puntatore a funzione non sono deliberatamente implementati.

Il laboratorio

lab/app.py è una reimplementazione minimale del percorso di ingestione multimodale di vLLM 0.13.0 — MediaConnector, ImageMediaIO, OpenCVVideoBackend e il gestore degli errori pre-patch, ciascuno annotato con il file upstream che replica. Il runtime del modello è simulato: la vulnerabilità risiede interamente nell'ingestione dei media, che viene eseguita prima dell'inferenza e non richiede GPU o pesi del modello.

Tutto sul percorso di attacco è reale — la stessa chiamata Pillow che divulga l'indirizzo, e la stessa chiamata cv2.VideoCapture in un opencv-python-headless==4.11.0.86 non patchato (FFmpeg 5.1.x, libavcodec 59.37.100).

Utilizzo

root@kitploit:~
docker compose up -d --build
python3 exploit.py

Opzioni:

root@kitploit:~
python3 exploit.py --target http://localhost:8000
python3 exploit.py --serve                  # consegna il payload via HTTP
python3 exploit.py --write-payload evil.jp2 # scrive solo il file dannoso

L'exploit usa esclusivamente la libreria standard — nessuna dipendenza.

Output atteso

root@kitploit:~
[*] Fase 1 -- divulgazione dell'indirizzo heap tramite messaggio di errore PIL
    HTTP 400
    cannot identify image file <_io.BytesIO object at 0xffff8f555300>
[+] Indirizzo heap divulgato: 0xffff8f555300
    ASLR bypassato: la base dell'heap è ora nota a ~3 bit di entropia.

[*] Fase 2 -- heap buffer overflow nel decoder JPEG2000
    Target attivo: boot_id=95b62f18-13c0-4d6d-97d3-1b029207dc01 pid=1
    Payload: 203 byte, JP2 150x64 yuv420p
    cdef mappa il componente 0 -> piano 1: scrive 9600 byte in un piano da 2400 byte (overflow di 7200 byte)
    Richiesta mai completata: l'estremità remota ha chiuso la connessione senza risposta
    Verifica di /health per vedere cosa è successo al worker...
[+] Il worker è stato terminato e riavviato: boot_id 95b62f18-... -> 4494d28c-...
[+] Scrittura fuori dai limiti confermata.

E sul lato server:

root@kitploit:~
$ docker compose logs vllm
cve-2026-22778-lab  | INFO:     POST /v1/chat/completions HTTP/1.1" 400 Bad Request
cve-2026-22778-lab  | corrupted size vs. prev_size
cve-2026-22778-lab  | INFO:     Started server process [1]

Smontaggio:

root@kitploit:~
docker compose down

Il payload

203 byte, costruiti da zero in build_payload(). Un contenitore JP2 che contiene un codestream JPEG2000 minimale che dichiara tre componenti con sottocampionamento 4:2:0 (così FFmpeg alloca un frame yuv420p), più un box cdef che li rimappa:

root@kitploit:~
cn=0, typ=0, asoc=2   <-- componente 0 (risoluzione piena) nel piano 1 (sottocampionato)
cn=1, typ=0, asoc=2
cn=2, typ=0, asoc=3

I dati dei coefficienti sono vuoti. Il decoder alloca comunque il frame dall'header SIZ ed esegue comunque il ciclo di scrittura, quindi non sono necessari dati immagine reali.

Correzione

vLLM 0.14.1, tramite tre PR:

  • #31987 — aggiunge sanitize_message(), che rimuove at 0x<addr>> dai repr degli oggetti prima che raggiungano il client.
  • #32319 — instrada i percorsi di errore rimanenti attraverso di essa.
  • #32668 — porta opencv-python-headless a >= 4.13.0, includendo la correzione FFmpeg per CVE-2025-9951.

FFmpeg upstream ora rifiuta una mappa cdef che non sia una permutazione dei canali, e deriva il formato pixel dagli indici rimappati:

root@kitploit:~
int cdef_used = 0;
for (i = 0; i < s->ncomponents; i++)
    cdef_used |= 1<<s->cdef[i];
if (cdef_used != ((int[]){0,2,3,14,15})[s->ncomponents])
    return AVERROR_INVALIDDATA;

Portando il pin del laboratorio a opencv-python-headless>=4.13.0, lo stesso payload fallisce in modo innocuo con error during processing marker segment ff51.

Se non puoi aggiornare: non servire modelli video, metti l'autenticazione davanti all'API e limita il recupero dei media con --allowed-media-domains.

Note

  • Il laboratorio si riavvia automaticamente dopo ogni crash, quindi il PoC può essere eseguito ripetutamente.
  • Su Apple Silicon, lascia che docker compose compili per l'architettura arm64 nativa (quella predefinita). Forzare --platform linux/amd64 esegue il container in emulazione, dove il processo che termina si blocca invece di uscire e il crash è più difficile da osservare.

Riferimenti

  • NVD — CVE-2026-22778
  • Advisory vLLM — GHSA-4r2x-xpjr-7cvv
  • Advisory FFmpeg — GHSA-39q3-f8jq-v6mg (CVE-2025-9951)

Disclaimer

Solo per scopi educativi e test di sicurezza autorizzati. Eseguilo contro il laboratorio in questo repository o su sistemi per cui hai esplicita autorizzazione al test.

Scarica lo strumento