背景
近期在公司老系统中出现服务器中毒情况,原来公司服务运行在Windows系统上,中毒之后切换Linux平台,单纯的认为凭借Linux的安全性可以解决中毒的情况,没想到Linux一样也中毒了,服务器重新安装Linux服务器之后依然中毒,此时考虑到老系统中Struts漏洞的问题,经检测,确实是有这个问题。
漏洞介绍
- Struts影响版本:Struts2 2.3.5-2.3.31 Struts 2.5-2.5.10
- 漏洞原因:基于Jakarta Multipart parser的文件上传模块在处理文件上传(multipart)的请求时候对异常信息做了捕获,并对异常信息做了OGNL表达式处理。但在在判断content-type不正确的时候会抛出异常并且带上Content-Type属性值,可通过精心构造附带OGNL表达式的URL导致远程代码执行。
- 漏洞分析:本次漏洞之所以影响广泛,重要原因之一是因为本次出问题的模块是系统的默认提供的模块—Jakarta。Jakarta依赖于commons-fileupload和commons-io两个包,所以只要存在这两个包,就可以模拟文件上传。而在struts2提供的基本示例struts2_blank中,这两个包也是存在的。
另一个重要原因,就是Jakarta模块在处理文件请求的时候,会对异常信息进行OGNL表达式解析处理。这部分,通过调试的方式可以看的更清楚一些。当struts2获取到请求的会进行分析,当content_type不为空且content_type中包含multipart/form-data时,struts2处理为上传请求。
利用这个漏洞在windows 2003 2008 2012服务器跟Linux centos系统服务器上执行系统权限命令。 黑客在上传文件的同时,通过POST提交HTTP请求头中的Content-Type值来利用这个漏洞,进而执行服务器的管理员权限命令。
解决方案
升级Struts版本,更新到Struts2.3.32以上或者Struts2.5.10.1以上版本,或者直接升级到Struts的最新版本。
第一步:替换jar包
老系统中用的是Struts2.3.16.3版本,在漏洞影响版本范围内,目前最新的Struts版本为2.5.14.1,所以我决定更新到最新版本,下载完成后发现2.5.14.1包含91个jar包,并不打算完全替换,所以先替换了项目中的5个Struts的jar,然后根据报错信息找到缺失的jar,最终替换10个后成功启动。
1. commons-lang3-3.6.jar
2. freemarker-2.3.26-incubating.jar
3. javassist-3.20.0-GA.jar
4. log4j-api-2.9.1.jar
5. ognl-3.1.15.jar
6. struts2-core-2.5.14.1.jar
7. struts2-jasperreports-plugin-2.5.14.1.jar
8. struts2-json-plugin-2.5.14.1.jar
9. struts2-junit-plugin-2.5.14.1.jar
10. struts2-spring-plugin-2.5.14.1.jar
第二步:修改web.xml文件
由于是2.3-2.5的大版本更新,所以需要修改web.xml中的struts配置
将2.3版本的:
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
修改为2.5版本的:
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
第三步:修改struts的xml文件
修改头文件为最新版本
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
由于新版本struts默认关闭了通配的action请求配置,所以如果项目中有通配的action请求配置的话,需要在action的外层package上添加 strict-method-invocation=”false”
例如:
<package name="mypackage" namespace="/" extends="struts-default" strict-method-invocation="false">
通配action请求例如:
<action name="test_*" class="testAction" method="{1}"></action>
完成上述操作后,漏洞即修复成功。
在此提供两个安全检测工具:
http://matrix.cubesec.cn/src/views/scaning.html
http://0day.websaas.com.cn/?code=vsnh
推荐使用第一个
简单易用。