
Scannt WordPress Core 4.7.0–7.1.1 auf CVE-2026-87902, unauthnentifizierte LFI über doppelt kodierte pagename-Traversierung, mit optionaler PEAR config-create RCE-Eskalation und Massenscanning.
WordPress Core get_page_template() / locate_template() Path-Traversal-Exploit-Tool
Nur für autorisierte Sicherheitstests. Unbefugter Zugriff auf Computersysteme ist illegal.
| Element | Details |
|---|---|
| CVE-ID | CVE-2026-87902 |
| GHSA-ID | GHSA-7hp8-65ch-5whp |
| Schwachstellentyp | CWE-98 — Unsachgemäße Kontrolle des Dateinamens für Include/Require |
| CVSS v3.1 | 8.1 (Hoch) / CVSS 4.0: 9.2 (Kritisch) |
| Betroffene Komponente | WordPress Core |
| Betroffene Versionen | 4.7.0 bis 7.1.1 (alle Zweige) |
| Behobene Versionen | 7.1.2 (und Backports bis hinunter zu 4.7.37) |
| Erforderliche Authentifizierung | Keine (Nicht authentifiziert) |
| Angriffsvektor | Einzelne GET-Anfrage |
| Entdeckt von | Robert Ressl (über das WordPress-HackerOne-Programm) |
| Veröffentlichungsdatum | 22. September 2026 |
| In freier Wildbahn ausgenutzt | Ja — im CISA-KEV-Katalog aufgeführt |
CVE-2026-87902 ist eine nicht authentifizierte Path-Traversal- und lokale Dateieinbindungsschwachstelle (LFI) im WordPress Core, die jede seit 2016 veröffentlichte WordPress-Version (4.7.0 bis 7.1.1) betrifft. Ein Angreifer benötigt kein Konto und keine Authentifizierung. Durch die Erstellung eines bösartigen pagename-Abfrageparameters kann der Angreifer bewirken, dass der Seitentemplate-Auflösungsmechanismus von WordPress eine beliebige lesbare .php-Datei außerhalb des Verzeichnisses des aktiven Themes einbindet. Unter bestimmten Serverbedingungen (PHP register_argc_argv = On und eine lesbare pearcmd.php) kann die Schwachstelle zur Remote-Code-Ausführung (RCE) eskaliert werden.
| Zweig | Behobene Version |
|---|---|
| 4.7.x | 4.7.37 |
| 5.0.x | 5.0.29 |
| 5.3.x | 5.3.25 |
| 5.9.x | 5.9.18 |
| 6.0.x | 6.0.16 |
| 6.6.x | 6.6.9 |
| 6.9.x | 6.9.9 |
| 7.0.x | 7.0.6 |
| 7.1.x | 7.1.2 |
Die Schwachstelle liegt in get_page_template() in wp-includes/template.php. Wenn die Abfragevariable pagename vorhanden ist, konstruiert die Funktion page-{$pagename}.php, versäumt es jedoch, validate_file() auf diesen Wert aufzurufen, um auf Directory Traversal zu prüfen. Der Kandidatendateiname wird dann an locate_template() übergeben, das ihn mit dem Pfad des Theme-Verzeichnisses verkettet und nur file_exists() prüft — es wird nicht verifiziert, ob der aufgelöste Pfad innerhalb des Theme-Verzeichnisses bleibt. Ein Templatename, der ../ enthält, kann daher zu einer lesbaren PHP-Datei außerhalb des aktiven Themes aufgelöst und eingebunden und ausgeführt werden.
GET /?page_id=<veröffentlichte Seite>&pagename= → WP_Query löst page_id auf, gleicht eine veröffentlichte Seite ab (vermeidet 404) → get_page_template() urldecode()t pagename, erstellt page-{$pagename}.php → locate_template() verkettet den Kandidaten mit dem Theme-Verzeichnis, löst via file_exists() auf → template-loader führt realpath() + include aus
WordPress wendet sanitize_title_for_query() auf pagename an, wodurch literale Punkte (.) durch Bindestriche (-) ersetzt werden, um Traversal zu blockieren. Die Funktion arbeitet auf bereits einmal dekodierter Eingabe und dekodiert nicht rekursiv. Der Angreifer sendet %252e%252e%252f (doppelt kodiertes ../):
%252e → %2e, %252f → %2fsanitize_title_for_query() sieht %2e%2e%2f (keine literalen Punkte) und lässt es durchget_page_template() ruft intern erneut urldecode() auf: %2e%2e%2f → ../page- beginnt (z. B. page-templates/).page_id angegeben werden kann..php enden (WordPress hängt die Erweiterung an).Hinweis zu Windows-Hosts: Win32 normalisiert .. lexikalisch, sodass Traversal möglicherweise auch dann funktioniert, wenn das page--Verzeichnis nicht existiert. Unter Linux muss dieses Verzeichnis tatsächlich existieren.
Bedingungen:
register_argc_argv ist auf On gesetztpearcmd.php existiert auf dem ServerDer Angreifer bindet pearcmd.php über LFI ein und missbraucht dessen config-create-Befehl, um eine PHP-Datei auf dem Server zu schreiben, und bindet diese Datei dann erneut über LFI ein, um beliebige Befehle auszuführen.
CVE-2026-87902 wurde von Robert Ressl entdeckt und gemeldet, einem in der Schweiz ansässigen Sicherheitsforscher.
Gemeldet über das WordPress-HackerOne-Programm im Juli 2026. Das WordPress-Sicherheitsteam koordinierte den Fix und veröffentlichte ihn zusammen mit WordPress 7.1.2 am 22. September 2026.
| Datum | Ereignis |
|---|---|
| Juli 2026 | Robert Ressl meldet die Schwachstelle über das WordPress-HackerOne-Programm |
| 22. September 2026 | WordPress 7.1.2 mit dem Fix veröffentlicht; Advisory publiziert |
| 22. September 2026 | Sicherheits-Backports für die Zweige 7.0 bis 4.7 veröffentlicht |
| 23. September 2026 | Angreifer beginnen, anfällige Websites zu sondieren |
| 25. September 2026 | CISA nimmt CVE-2026-87902 in den KEV-Katalog auf |
| Funktion | Beschreibung |
|---|---|
| Versions-Fingerprinting | Identifiziert die WordPress-Version über Meta-Generator, RSS-Feed, OPML, readme.html, Asset-?ver= |
| Intelligentes Versions-Urteil | Nutzt eine Zuordnung fester Versionen, um festzustellen, ob das Ziel im betroffenen Bereich liegt |
| Theme-Erkennung | Extrahiert den Slug des aktiven Themes, erkennt das Parent-Theme, entdeckt page-*-Verzeichnisse |
| Seiten-ID-Erkennung | Findet gültige Seiten-IDs über REST API, page-id--Body-Klasse, Shortlinks |
| LFI-Oracle-Validierung | Verwendet sichere Dateien wie wp-links-opml.php und wp-trackback.php als Orakel mit Negativkontrollen |
| Doppelt kodierte Traversierung | Kodiert / und . automatisch doppelt prozentual, um sanitize_title_for_query() zu umgehen |
| PEAR-RCE-Ausnutzung | Probiert gängige PEAR-Pfade, schreibt und führt Marker-Dateien über config-create aus |
| Massen-Scanning | Mehrthreadiges gleichzeitiges Scannen von Ziellisten |
| Ergebnisausgabe | Speichert Ergebnisse in vuln_lfi.txt und vuln_lfitorce.txt |
pip install requests
python3 CVE-2026-87902.py
Interaktives Menü:
[1] Single Scan LFI [2] Single Scan LFI + RCE [3] Mass Scan LFI [4] Mass Scan LFI + RCE [5] Exit
Wählen Sie [1], geben Sie die Ziel-URL ein:
url > https://target.example.com
Wählen Sie [2], geben Sie URL und Befehl ein (Standard id):
url > https://target.example.com cmd > id
Wählen Sie [3] oder [4], geben Sie die Datei mit den Ziel-URLs ein (eine pro Zeile, # für Kommentare):
file > targets.txt
| Datei | Inhalt |
|---|---|
| vuln_lfi.txt | Bestätigte LFI-Ziele |
| vuln_lfitorce.txt | Erfolgreiche RCE-Ziele |
TIMEOUT = 8 # Request timeout (seconds) THREADS = 200 # Concurrent threads for mass scanning USE_ALL_ORACLES = False # Use all oracles (more accurate but slower)