我也来分析S2-045

0、须要了解的术语

git仓库的tag:是使用git作版本管理的时候打的标签,至关于一个再也不变化的,固定的分支,对应于仓库中的一个commit。html

 

一、漏洞环境复现

首先为了复现漏洞环境,须要下载漏洞代码,由于该漏洞主要出现  Struts 2.3.5 - Struts 2.3.31, Struts 2.5 - Struts 2.5.10 这几个版本的struts2发行版,那么直接从tag下checkout出来这些代码就可以复现有漏洞的struts2,因此咱们将从struts的git仓库中的tag下checkout代码,这里咱们从github上checkout出来STRUTS_2_5_10这个tag。git

同时经过网上提供的文章,咱们知道漏洞补丁主要修复的位置,使用git log查看漏洞修复后提交的内容,咱们只须要将代码回滚到漏洞修复的前一个commit。即回退到红框下的一个commit。github

这个时候安装maven,进行build,web

mvn -Dmaven.test.skip=true package  -DskipAssembly=trueapache

maven会自动下载依赖包,和build出来须要发布的版本,生成的jar包是struts2-core-2.5.10.jar安全

经过使用maven新建web项目,和添加struts2支持,可以获取到依赖度包。app

这个时候把这些包copy过来,并使用eclipse新建web工程,就可以得到一个存在漏洞的struts2工程。eclipse

struts2工程的目录结构以下所示。maven

这个时候就能够进行调试了。函数

在eclipse中加载上struts2的源码,就能够对struts2进行调试了

咱们将出错的报文复制出来,放到burp里头进行调试。并在struts2的入口点打上断点,这里咱们打的断点在org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter的dofilter函数上。

二、struts2执行流程及漏洞成因分析

这里讲了struts2的执行流程以后对理解漏洞成因的理解有很大帮助。

当请求到来时,struts2会对请求作处理,将裸露的http报文转换成本身须要的结构体,本次漏洞在这种转化过程当中会发生转化错误,并将错误信息存在告终构体重。转化出错的位置以下图所示。存在于org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter的dofilter函数的图中所示的代码位置。

因为struts2会对每个请求执行拦截器操做,当执行到FileuploadInterceptor的时候,这里咱们看FileuploadInterceptor的intercept函数,每个拦截器都要实现这个函数。

漏洞出现的位置以下图所示。

图中51行,因为multiWrapper对象如前所述,已经被parse过,且存在错误,因此51行执行经过,可以执行到54行,这里就是漏洞出现的位置。

出现漏洞的函数就是LocalizedTextUtil.findText。

咱们看一下这个函数的说明。

注意第三条。

中文大意是:这个函数会去查找错误信息究竟是什么,查找方式是查找出错的对象的自己,及他的父类,若是在这些地方都没有查找到那么就将查找对象的其余属性,并把这些信息当作ognl表达式进行执行。(我猜测此处须要使用ognl表达式执行的缘由是做者认为出错的信息能在这些信息中,获取这些信息,当作ognl表达式执行,而后照前面的方式继续查找)

本案中,出错代码

findText(error.getClazz(), error.getTextKey(), ActionContext.getContext().getLocale(), error.getDefaultMessage(), error.getArgs()));

就是查找了error.getClazz()的class没有找到,

后来查找了error的error.getDefaultMessage()中的信息,并把它当作ognl表达式进行执行了。这里咱们放入了ognl表达式,并得到了命令执行的效果。因此该漏洞出现的缘由是信任了客户提交的输入,错误地将客户的输入放入了能够执行ognl表达式的函数中。

三、须要说明的问题

本文指出了调试struts2的方法,同时标记了出错的几个关键点,读者有兴趣能够执行单步操做,进行调试。

欢迎老司机指导findText函数的设计本意。我的认为common-upload包返回了正确的出错信息,struts2没有判断是否存在安全问题,执行了其中的错误信息的ognl表达式。是两个包之间的协做问题。

 

四、参考资料

http://bobao.360.cn/learning/detail/3596.html

http://bobao.360.cn/learning/detail/3587.html

http://bobao.360.cn/learning/detail/3574.html

http://blog.csdn.net/yuan_xw/article/details/7838123

相关文章
相关标签/搜索