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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
wp2shell-lab — wp2shell用の非破壊検出器 + Dockerラボ(WordPressコア6.9.0-6.9.4 / 7.0.0-7.0.1におけるCVE-2026-63030 REST /batch/v1 ルート混同 + CVE-2026-60137 author__not_in SQLi) | Kitploit
ツール/GitHubGitHub/dinosn/wp2shell-lab
脆弱性分析エクスプロイトウェブアプリケーション悪用ペネトレーションテスト学習と教育ラボと実践
GitHubdinosn/wp2shell-lab

wp2shell-lab

wp2shell用の非破壊検出器 + Dockerラボ(WordPressコア6.9.0-6.9.4 / 7.0.0-7.0.1におけるCVE-2026-63030 REST /batch/v1 ルート混同 + CVE-2026-60137 author__not_in SQLi)

リポジトリを見る
5417212ヶ月前Kitploit レビュー済み

人気

すべて見る →

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

すべてのツールを探索

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

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

wp2shell ラボ & 検出ツール + 事前認証 RCE PoC

wp2shell — WordPress コアの事前認証脆弱性チェーン — のための自己完結型ラボ、非破壊検出ツール、そして完全な事前認証 RCE 概念実証 (PoC) です:

CVEコンポーネント分類CVSS
CVE-2026-60137WP_Query::author__not_inSQL インジェクション (CWE-89)9.1
CVE-2026-63030REST /batch/v1 ルート混乱解釈の競合 (CWE-436) → RCE に連鎖7.5

影響を受けるバージョン: WordPress コア 6.9.0–6.9.4 および 7.0.0–7.0.1 (SQLi シンクのみでも 6.8.0–6.8.5 に影響)。6.8.6 / 6.9.5 / 7.0.2 で修正。 Adam Kues (Assetnote / Searchlight Cyber) が報告。SQLi は TF1T、dtro、haongo にもクレジットされています。ストックデフォルト RCE チェーン (oEmbed → changeset → re-entry) は Mustafa Can İPEKÇİ (nukedx) によるものです。

まず更新を。 WordPress はこれに対する強制自動更新を配信しました。このリポジトリは、あなた自身の環境がパッチ適用済みであることを確認し、このバグを理解するために存在します — 誰かを攻撃するためではありません。SECURITY.md を参照してください。


実際に何をするのか

常に成立するプリミティブは、認証不要・プラグイン不要・ストックコアの SQL インジェクションであり、データベース全体の読み取り (管理者パスワードハッシュ、wp_options/wp_users 内のすべて) を可能にします。これだけで CVSS 9.1 に値し、即時のパッチ適用が求められます。

RCE は現実に存在し、ストックデフォルトの WordPress で動作します — FILE 権限、永続オブジェクトキャッシュ、プラグイン、設定ミスのいずれも不要です。このチェーンは読み取り専用の SQLi を行偽造プリミティブとして使用し (UNION ALL SELECT が偽の wp_posts 行を注入)、WordPress 自身のコンテンツレンダリングパイプラインを利用して、oEmbed キャッシング経由でそれらの偽造行を実際のデータベース書き込みに変換します。そこから、changeset の昇格と再入可能な parse_request が管理者コンテキストで実行され、新しい管理者アカウントが作成されます — すべて単一の認証不要 HTTP リクエストからです。

完全なチェーン (認証情報なし、単一のエントリポイント POST /?rest_route=/batch/v1)

1. Route confusion    — double-nested batch desyncs $matches/$validation so a GET
                        /wp/v2/widgets runs under posts::get_items() (public), reaching
                        WP_Query's author__not_in with attacker-controlled input.

2. Row forgery        — author__not_in is string-concatenated into SQL;
                        "1) AND 1=0 UNION ALL SELECT <23 cols> -- -" injects fake
                        WP_Post rows. per_page=-1 bypasses split_the_query (WP_Query
                        treats -1 as "no limit" → empty $limits → split=false →
                        full SELECT wp_posts.* → UNION columns match).

3. oEmbed write       — forged posts carry [embed]<self-url>[/embed]; rendering via
                        context=view makes WordPress cache real oembed_cache posts in
                        the DB (turns read-only SQLi into writes with predictable IDs).

4. Elevation+re-entry — a forged customize_changeset (user_id = real admin) plus a
                        forged post_type=request row with parent loops drives an
                        in-process re-entrant parse_request in admin context.

5. Admin creation     — POST /wp/v2/users in the same batch passes
                        current_user_can('create_users') → new administrator.

6. RCE                — login → plugin webshell upload → command execution → cleanup.

構造を支えるガジェット (チェーンが成立する理由)

新規性は構成 (composition) にあり、単一のバグではありません — 個々のガジェットは WordPress の正当な動作です。それらに名前を付けること (Adam Kues の記事による) で、exploit() 内の偽造行グラフが読みやすくなり、エントリポイントがパッチ適用された後に再監査すべき箇所を示します:

  • キャッシュ/DB の調整 (reconciliation) — インメモリにキャッシュされた投稿が DB の行と食い違う場合、WordPress は wp_update_post() で調整し、インメモリの post_type/post_status を優先するため、oembed_cache 行を実際の post/customize_changeset に型変換できます。
  • post_content を保持するサイクル検出 — wp_insert_post_parent フィルタは親チェーンを辿ります。サイクルを検出すると、2 回目の wp_update_post() を呼び出して、post_content を上書きせずに親を修正します。これが決定的なリンクです: 偽造 changeset の悪意ある post_content を生き残らせることができます。(これが偽造行が自己/相互親ループを使用する理由です。)
  • parse_request によるフック再実行 (replay) — 投稿の公開は do_action("{$status}_{$type}") を発火させます。post_status=parse / post_type=request を持つ偽造行は parse_request をトリガーし、changeset が仮定する管理者 ID (wp_set_current_user) が有効なままバッチパイプラインを再実行します。

これらのガジェットはパッチ適用済みの WordPress にも残っています — 閉じられたのは 2 つのエントリポイント (バッチデシンク + author__not_in スカラーバイパス) のみです。インメモリの投稿キャッシュを偽造する、または oembed_cache 行を書き込む新しいプリミティブがあれば、同一の管理者乗っ取りテールが再び有効になります。

レンダリング時書き込みプリミティブ

4 つすべてのレンダリング時書き込みプリミティブは 7.0.1 に対して実機で確認済みです — それぞれ認証不要の投稿として偽造され、バッチ混乱を介してレンダリングされ、結果として生じる DB 書き込みがブラインド SQLi で検証されました:

プリミティブトリガーマークアップシンク予測される識別子検証結果
oembed[embed]<url>[/embed]wp_posts 行 (oembed_cache)post_name = md5(url+attrs)投稿 ID が作成された
rsswp:rss {feedURL}wp_options サイトトランジェント_site_transient_feed_<md5(url)>option_id、5192 B キャッシュ済み
navigationwp:navigationwp_posts 行 (wp_navigation)post_name = 'navigation' (固定)ID 作成済み、スラッグ navigation
calendarwp:calendarwp_optionswp_calendar_block_has_published_postsoption_id、値 '1'

各結果が証明すること:

  • oembed — 参照プリミティブ: 攻撃者が予測可能なスラッグ (md5(url+serialize(attrs))) と実際の auto-increment ID を持つ新しい wp_posts 行を得られます。複数・オンデマンド・攻撃者命名の投稿行を提供する唯一のものであり、RCE チェーンが偽造 changeset/request グラフのバックエンドにこれを使用する理由です。
  • rss — 最も強力な汎用書き込み: キー _site_transient_feed_<md5(url)> は完全に予測可能で、格納されるバイトは攻撃者の URL が配信するフィード本文です — つまり、攻撃者はキーと値の両方を制御します。wp_options への書き込み (投稿 ID なし) のため、changeset のバックエンドにそのまま使える代替ではなく、オプション汚染 (option-poisoning) プリミティブです。
  • navigation — もう 1 つの認証不要「レンダリングによる実際の投稿行の作成」パス。固定スラッグで単発 (公開済みの wp_navigation が存在する場合はスキップ) のため、oEmbed の N 行とは異なり、偽造オブジェクトを最大 1 つしかバックできません。
  • calendar — レンダリング→update_option パスが認証不要で発火することを確認しますが、オプション名とその '1'/'0' の値は固定/DB 由来のため、キーや値に対する攻撃者の制御がない「書き込みが発生する」ことのデモです。

以前の条件付きチェーン (上記のストックデフォルトチェーンに置き換え)

  • INTO OUTFILE ウェブシェル: WordPress の DB ユーザーがグローバル FILE 権限を保持し、secure_file_priv が Web からアクセス可能で、出力先が Web ユーザーに読み取り可能であることが必要です。通常の/マネージドホストではどれも成立しません。
  • SimplePie → WP_HTML_Token POP: call_user_func('wp_insert_user', user_data_array) — 要件: gc_enabled()=false + 有効な HMAC (正確なシリアライズ済みバイト列の wp_hash、wp-config.php のシークレットが必要)。

クイックスタート

必要条件: Docker + Docker Compose v2、Python 3.8+ (標準ライブラリのみ)、make、curl。

make up          # WordPress 6.9.4 (vulnerable) + MySQL 8.0, auto-installed on :8093
make check       # -> [VULNERABLE] http://localhost:8093 (WordPress 6.9.4 ...)
make proof       # -> also reads @@version and current_user() as read-only evidence
make exploit     # -> full pre-auth RCE: creates admin, deploys webshell, runs "id"
make patched     # rebuild on the fixed image and re-check -> [not vulnerable]
make down        # tear down (removes volumes)

ポートを変更するには WP_PORT=8100 make up を使用します。

パッチ適用済みイメージに関する注意: 公式 Docker wordpress イメージは WordPress コアのセキュリティリリースより 1〜2 日遅れることがあります。make patched が wordpress:7.0.2 はまだ Docker Hub にないと報告した場合は、後で再試行するか、公開済みの修正タグを指定してください: make patched WP_PATCHED_TAG=6.9.5 (または 7.0.2 / 6.8.6)。WordPress 6.9.5 / 7.0.2 / 6.8.6 のいずれか以上であれば not vulnerable を返します。

期待される出力

$ make check
[VULNERABLE] http://localhost:8093  (WordPress 6.9.4, affected-full-chain)  [active=fired | method=boolean rows(true/false)=5/0 via x-wp-total | delivery=json | slot=users]
        confirmed: unauthenticated SQL injection
        rce: reachable on stock config; additionally requires no persistent object cache (not verified remotely -- the RCE PoC preflights it before writing)

$ make exploit
[*] seeding oEmbed caches ...
[*] extracting table prefix ...
[+] table prefix: wp_
[*] extracting admin user ID ...
[+] admin ID: 1
[*] recovering oEmbed cache post IDs ...
[+] cache IDs: [5, 6, 7]
[*] forging changeset + re-entry, creating administrator ...
[+] administrator created: w2s_...:W2s!...  ([email protected])
[*] logging in, deploying webshell, executing command ...
[+] vulnerable (unauth SQLi confirmed: method=boolean slot=users delivery=json)
[+] RCE output:

uid=33(www-data) gid=33(www-data) groups=33(www-data)

$ make patched
[not vulnerable] http://localhost:8093  (WordPress 7.0.2, outside-affected-range)  [active=negative | method=time fast=0.01s slow=0.01s delta=-0.00s | delivery=json | slot=users]

ツール (wp2shell_check.py)

標準ライブラリのみ、依存関係なし。

検出 (デフォルト)

ツールをダウンロード