一、前言
2020年8月13日,Apache官方发布了一则公告,该公告称Apache Struts2使用某些标签时,会对标签属性值进行二次表达式解析,当标签属性值使用了%{skillName}并且skillName的值用户可以控制,就会造成OGNL表达式执行。
二、漏洞复现
我这里选用的测试环境 Tomcat 7.0.72、Java 1.8.0_181、Struts 2.2.1,受影响的标签直接使用官网公告给出的例子
<s:url var="url" namespace="/employee" action="list"/><s:a id="%{payload}" href="%{url}">List available Employees</s:a>
测试漏洞URL
http://localhost:8088/S2-059.action?payload=%25{3*3}
在s2-029中由于调用了completeExpressionIfAltSyntax方法会自动加上"%{" + expr + "}",所以payload不用带%{},在s2-029的payload里加上%{}就是s2-059的payload,具体原因看下面的分析。
三、漏洞分析
根据官网公告的漏洞描述及上面的测试过程可以知道,这次漏洞是由于标签属性值进行二次表达式解析产生的。struts2 jsp 标签解析是org.apache.struts2.views.jsp.ComponentTagSupport类的doStartTag和doEndTag方法。debug跟下 doStartTag方法。
跟下populateParams方法
org/apache/struts2/views/jsp/ui/AnchorTag.class
这里又去调用了父类的populateParams方法,接着调用org/apache/struts2/views/jsp/ui/AbstractUITag.class类的populateParams方法
可以看到这里有给setId赋值,跟下setId方法,org/apache/struts2/components/UIBean.class
由于id不为null,会执行this.findString方法,接着跟下.org/apache/struts2/components/Component.class
altSyntax默认开启, 所以this.altSyntax()会返回true,toType的值传过来是String.class,if条件成立会执行到TextParseUtil.translateVariables('%', expr, this.stack)
可以看到这里是首先截取去掉%{}字符,然后从stack中寻找payload参数,传输的payload参数是%{3*2},这里会得到这个值。
执行完populateParams方法可以得知这个方法是对属性进行初始化赋值操作。接着跟下start方法
org/apache/struts2/components/Anchor.class的start方法调用了父类org/apache/struts2/components/ClosingUIBean.class的start方法
在接着跟下org/apache/struts2/components/UIBean.class$evaluateParams方法
接着调用了populateComponentHtmlId方法
在看下findStringIfAltSyntax方法的实现
org/apache/struts2/components/Component.class$findStringIfAltSyntax
可以看到这里又执行了一次TextParseUtil.translateVariables方法.
整个过程跟S2-029和S2-036漏洞产生的原因一样,都是由标签属性二次表达式解析造成漏洞。分析完漏洞产生原因后,我查看了UIBean class相关代码,并没有发现除id外其它标签属性值可以这样利用。
四、总结
此次漏洞需要开启altSyntax功能,只能是在标签id属性中存在表达式,并且参数还可以控制,这种场景在实际开发中非常少见,危害较小。
五、参考链接
https://cwiki.apache.org/confluence/display/WW/S2-059
http://blog.topsec.com.cn/struts2%e6%bc%8f%e6%b4%9es2-029%e5%88%86%e6%9e%90/
                    
                    
投稿
                                
                                
                                
                                
                                
                            












