【技术分享】深入分析Struts2 S2-052(CVE-2017-9805)远程命令执行漏洞

阅读量261554

|

发布时间 : 2017-09-29 11:46:31

x
译文声明

本文是翻译文章,文章来源:mcafee.com

原文地址:https://securingtomorrow.mcafee.com/mcafee-labs/apache-struts-at-rest-analyzing-remote-code-execution-vulnerability-cve-2017-9805/

译文仅供参考,具体内容表达以及含义原文为准。

https://p0.ssl.qhimg.com/t010086aaa5bd861da6.png

译者:興趣使然的小胃

预估稿费:100RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿

一、前言

Apache Struts是一种开源Web开发框架,非常容易出现漏洞。我们在七月份曾写过关于CVE-2017-9791漏洞的一篇文章。根据现有资料,目前Struts最新的漏洞编号为CVE-2017-9805,这是另一个正在被利用的远程命令执行漏洞。Struts的REST(Representational State Transfer)插件受此漏洞影响。Apache已经将Struts版本更新为2.5.13,修复了这个问题。在本文中,我们会深入分析该漏洞以及漏洞利用技术的工作原理。

二、补丁分析

漏洞修复前后REST的改动如下图所示(左图为修复前,2.5.12版,右图为修复后,2.5.13版)。

https://p2.ssl.qhimg.com/t01df5d3b45a80af6e7.png

参考来源:Fossies(the Fresh Open Source Software Archive)

如图所示,为了修复这个漏洞,Struts做了如下几处代码调整:

1.    在修复版中,“Class XStreamHandler”继承(extends)自“AbstractContentTypeHandler”。

2.    “toObject”以及“fromObject”这两个方法的第一个参数变成了“ActionInvocation”类型。(如果我们检查AbstractContentTypeHandler.java代码,我们可以发现“AbstractContentTypeHandler”实现了(implements)“ContentTypeHandler”类,并且废除(deprecated)了“toObject”以及“fromObject”方法)。

3.    “createXstream”方法已被废除,新增了一个同名方法,所接受的参数类型为“ActionInvocation”,如下图所示:

https://p4.ssl.qhimg.com/t01d9035c8124ca0461.png

这个改动清除了现有的权限状态,每次操作会添加默认权限,因此可以修复这个问题。


三、代码调试

如果某台主机正在运行的Apache Struts存在REST插件漏洞,为了利用这个漏洞,我们需要精心构造一段XML数据,并通过POST请求将该数据发给目标主机。

https://p4.ssl.qhimg.com/t019f21bd6375b16ad2.png

跟踪相关代码,我们发现该请求会被传递给ContentTypeInterceptor.java进行处理。

https://p0.ssl.qhimg.com/t018d3800a0939ce604.png

该函数用来识别负责处理HTTP请求的具体函数。在这种情况下,该函数为“XStreamHandler”,随后,该函数会调用“handler.toObject(reader, target);”。因此,程序控制权会交给XStreamHandler.java中的“toObject”函数。

https://p5.ssl.qhimg.com/t01c8cf73db1acaf5fc.png

该函数会调用“fromXML”方法,后者负责将XML反序列化为某个对象:

https://p1.ssl.qhimg.com/t01d23742e0fbdac393.png

随后,“fromXML”方法会调用“MapConverter.java”中的“unmarshal”方法,以创建并填充一个HashMap对象。

https://p0.ssl.qhimg.com/t01e2a697da4a47907e.png

“PopulateMap”方法会调用“PutCurrentEntryIntoMap”方法,后者会继续调用“readItem”方法。在这里,map中的元素来自于我们精心构造的XML中的元素。

https://p1.ssl.qhimg.com/t0107a983bc010e78ee.png

随后,程序代码会调用“AbstractReflectionConverter.java”中的“doUnmarshal”方法。我们可以看到代码会从reader对象中读取节点名称,然后搜索包含reader定义或声明的那个类名。代码也会检查相应的字段是否包含在这个类中:

https://p2.ssl.qhimg.com/t01ee7e55de6491317d.png

如果类中存在这个字段,那么代码会更新对象中的这个字段。如下图所示,该对象为“ImageIO$ContainsFilter”对象,“reflectionProvider.writeField”方法正在修改该对象的方法的值。

https://p4.ssl.qhimg.com/t0159d264bb9674e051.png

这个过程重复多次,最终,该对象的值如下图所示(为便于阅读我们截断并重新组织了这些值)。这些数据全部源自于我们精心构造的XML:

https://p2.ssl.qhimg.com/t013397048ea7ebf87b.png

代码会在“PutCurrentEntryIntoMap”方法中使用“readItem”方法返回这个对象,并将其保存在“Object Key”中:

https://p4.ssl.qhimg.com/t01fcd287b334f1835a.png

如上图所示,程序代码调用了“target.put”方法。调用这个方法时,程序会访问这个键值对(key&value)。由于键值对中包含我们所构造的对象,因此程序代码首先会调用“Nativestring.hashCode()”,而该方法会调用“Base64Data.get()”,我们可以观察调用栈以证实这一点:

https://p4.ssl.qhimg.com/t01fa5686afbd3bf8ad.png

随后,程序代码会调用“Cipher.Java”中的“chooseFirstProvider()”方法:

https://p4.ssl.qhimg.com/t017115cbbe8b8c8013.png

“serviceIterator.next()”方法会返回ProcessBuilder对象,该对象包含我们输入的那条命令。由于这些对象都链接在一起,因此java.lang.ProcessBuilder.Start()会使用ImageIO$ContainsFilter对象的方法,最终完成代码执行。

四、总结

Apache Struts是一个非常流行的Web开发框架,因此相应的漏洞也会影响深远。我们建议用户使用最新版本的Struts,并保持产品更新。

McAfee Network Security Platform可以保护客户免受此漏洞影响。

原文链接:https://securingtomorrow.mcafee.com/mcafee-labs/apache-struts-at-rest-analyzing-remote-code-execution-vulnerability-cve-2017-9805/

本文翻译自mcafee.com 原文链接。如若转载请注明出处。
分享到:微信
+10赞
收藏
興趣使然的小胃
分享到:微信

发表评论

内容需知
  • 投稿须知
  • 转载须知
  • 官网QQ群8:819797106
  • 官网QQ群3:830462644(已满)
  • 官网QQ群2:814450983(已满)
  • 官网QQ群1:702511263(已满)
合作单位
  • 安全客
  • 安全客
Copyright © 北京奇虎科技有限公司 360网络攻防实验室 安全客 All Rights Reserved 京ICP备08010314号-66