
Privater Fortbridge-PoC für die CVE-2026-32740 Next.js/sharp Leak-to-memcpy-GOT-RCE-Kette
Funktionierender Proof of Concept, der CVE-2026-32740 im
fest verdrahteten Next.js/sharp-Bildstack in einen Write an eine gewählte Adresse und einen
validierten /usr/bin/id-Callback verwandelt.
Dies ist ein privates Fortbridge-Forschungsrepository. Verwende es nur gegen das enthaltene Lab oder ein anderes System, für dessen Test du ausdrücklich autorisiert bist.
Der Exploit nutzt ausschließlich die HTTP-Upload- und Bildoptimierungsrouten des Ziels:
g_module_open_full, eine GModule-
Routine, die dlopen umschließt, um eine native Shared Library aus einem Datei-
pfad zu laden. Der Exploit berechnet ihre Laufzeitadresse als die wiederhergestellte libvips-
Basis plus den fest verdrahteten Profil-Offset 0x3e995e. Das Laden der Bibliothek führt
ihren Konstruktor aus./usr/bin/id ausführt. Er sendet dieses ELF über die öffentliche
Upload-Route unter dem Bildnamen x.jpg und dem Medientyp image/jpeg.memcpy@GOT - 16 umleitet.uploads/x.jpg unmittelbar vor dem
GOT-Slot und ersetzt memcpy@GOT durch den abgeleiteten GModule-Loader. Die nächste
Zeile ruft diesen Loader mit dem bereits in RDI befindlichen Bibliothekspfad auf./usr/bin/id-Ausgabe über TCP zurückgibt. Ein Token pro Versuch verhindert, dass ein veralteter Callback
als Erfolg gezählt wird; die zurückgegebene uid=...-Zeile ist der Beweis.Die ursprünglichen libvips-relativen Validierungsläufe sind in
evidence/libvips-gmodule-rce-10x.json aufgezeichnet.
Alle zehn frischen Prozesse gaben gültige /usr/bin/id-Ausgaben mit zehn verschiedenen
randomisierten libvips-Basen und zehn unabhängig abgeleiteten Loader-Adressen zurück.
Die exakten Ubuntu-Laufdaten sind in
evidence/libvips-gmodule-pie-rce-10x.json.
Die exakten Debian-13-APT-Laufdaten sind in
evidence/debian13-apt-libvips-gmodule-rce-10x.json.
Wir haben den vollständigen Exploit gegen 10 neu gestartete Ubuntu-Node-Prozesse
und 10 neu gestartete Debian-Node-Prozesse getestet. Alle 20 Läufe erreichten die Befehls-
ausführung und gaben die /usr/bin/id-Ausgabe des Ziels zurück. Der Exploit berechnete
außerdem für jede randomisierte libvips-Basis eine andere GModule-Loader-Adresse.
Vor der Erstellung der finalen Payload kann der Exploit mehrere ASLR-Leak- Versuche benötigen. Jeder Versuch lädt das Leak-AVIF hoch, schickt es durch die Optimierungs- route und prüft das zurückgegebene PNG auf vier Zeiger, die ein Profil und eine libvips-Basis identifizieren. Ubuntu benötigte zwischen 3 und 23 Versuche. Debian benötigte zwischen 3 und 15. Unvollständige oder mehrdeutige Evidenz führt zu einem weiteren Versuch anstelle eines geratenen Profils.
Das Projekt hat außerdem 96 automatisierte Regressionstests. Dies sind Code-Level- Prüfungen, keine 96 zusätzlichen Exploit-Läufe. Sie decken Profilvalidierung, Klassifizierung zurückgegebener Zeiger, Heap-Kalibrierung, Adressberechnung, Payload-Konstruktion und sicheres Fehlschlagen ab, wenn die Evidenz nicht zu einem unterstützten Ziel passt.
Beide x86-64-Ziele verwenden Next.js 15.5.23, sharp 0.34.4, gebündeltes libvips 8.17.2, gebündeltes libheif 1.20.2, ASLR und NX. Ihre nativen Laufzeiten unterscheiden sich:
| Profil | Node | glibc | libstdc++ | Selektor-Beziehung |
|---|---|---|---|---|
| Ubuntu | 25.8.1, PIE ET_DYN | 2.43-2ubuntu2.4 | 6.0.35 | 0x6000 - 0x690 = 0x5970 |
| Debian 13 | Debian APT 20.19.2, PIE ET_DYN | 2.41-12+deb13u4 | 6.0.33 | 0x6000 - 0x3a0 = 0x5c60 |
Die vollständigen Build-IDs und SHA-256-Werte sind in
profiles/native_stack_profiles_pie.json.
Die Debian-Paket-, Artefakt-, Route-Smoke- und Fünf-Lebensdauer-Layout-Messungen
sind in
evidence/debian13-profile-derivation.json erfasst.
Das Debian-Ziel verwendet das Standard-Distributionspaket
nodejs=20.19.2+dfsg-1+deb13u3; Node wird nicht aus dem Quellcode kompiliert.
Die Kette benötigt nicht die randomisierte Node-Basis. Ihr Kontrollziel ist die
interne g_module_open_full-Routine innerhalb von libvips, deren randomisierte Basis
aus zurückgegebenen Pixeln wiederhergestellt wird. Jedes versionierte Profil verdrahtet die
build-spezifischen Konstanten, die der Exploit benötigt, fest:
memcpy@GOT-Offset und der g_module_open_full-Offset plus seine validierenden
Instruktionsbytes;Die randomisierte libvips-Basis, die resultierende Laufzeit-Loader-Adresse und der finale Zwei-Byte-Selektor sind nicht fest verdrahtet. Sie werden für jeden Ziel- prozess aus zurückgegebenen Pixeln und dem ausgewählten Profil abgeleitet.
Der Exploit schlägt geschlossen fehl, wenn ein Profil fehlerhaft ist oder zurückgegebene Pixel nicht genau ein unterstütztes Profil/Basis-Paar auswählen. Das Stock-Profil erfordert außerdem seinen vollständigen zurückgegebenen Heap-Record. Ein Profil ist eine exakte Kompatibilitäts- aussage, daher sollte der Operator die Zielartefakte offline verifizieren, bevor er es verwendet.
Die Loader-ABI ist wichtig. Der überschriebene Aufruf liefert den Bibliothekspfad in RDI, einen Bildzeilen-Zeiger in RSI und die 58-Byte-Kopierlänge in RDX. Diese exakte profilierte GModule-Routine verwendet nur unterstützte Flag-Bits aus ESI und dereferenziert RDX auf dem erfolgreichen Ladepfad nicht. Ein Offline-Harness validierte diesen Einstiegspunkt und die Instruktionssignatur, bevor er in den gemessenen Läufen verwendet wurde.
ffmpeg mit dem libaom-av1-Encodercc auf der Angreifer-Maschine verfügbar istInstalliere die einzige Python-Abhängigkeit:```bash python3 -m venv .venv . .venv/bin/activate python3 -m pip install -r requirements.txt
Bestätigen Sie die AV1-Kodierungsunterstützung:```bash
ffmpeg -hide_banner -encoders | grep libaom-av1