译者:興趣使然的小胃
预估稿费: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版)。
参考来源: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”,如下图所示:
这个改动清除了现有的权限状态,每次操作会添加默认权限,因此可以修复这个问题。
三、代码调试
如果某台主机正在运行的Apache Struts存在REST插件漏洞,为了利用这个漏洞,我们需要精心构造一段XML数据,并通过POST请求将该数据发给目标主机。
跟踪相关代码,我们发现该请求会被传递给ContentTypeInterceptor.java进行处理。
该函数用来识别负责处理HTTP请求的具体函数。在这种情况下,该函数为“XStreamHandler”,随后,该函数会调用“handler.toObject(reader, target);”。因此,程序控制权会交给XStreamHandler.java中的“toObject”函数。
该函数会调用“fromXML”方法,后者负责将XML反序列化为某个对象:
随后,“fromXML”方法会调用“MapConverter.java”中的“unmarshal”方法,以创建并填充一个HashMap对象。
“PopulateMap”方法会调用“PutCurrentEntryIntoMap”方法,后者会继续调用“readItem”方法。在这里,map中的元素来自于我们精心构造的XML中的元素。
随后,程序代码会调用“AbstractReflectionConverter.java”中的“doUnmarshal”方法。我们可以看到代码会从reader对象中读取节点名称,然后搜索包含reader定义或声明的那个类名。代码也会检查相应的字段是否包含在这个类中:
如果类中存在这个字段,那么代码会更新对象中的这个字段。如下图所示,该对象为“ImageIO$ContainsFilter”对象,“reflectionProvider.writeField”方法正在修改该对象的方法的值。
这个过程重复多次,最终,该对象的值如下图所示(为便于阅读我们截断并重新组织了这些值)。这些数据全部源自于我们精心构造的XML:
代码会在“PutCurrentEntryIntoMap”方法中使用“readItem”方法返回这个对象,并将其保存在“Object Key”中:
如上图所示,程序代码调用了“target.put”方法。调用这个方法时,程序会访问这个键值对(key&value)。由于键值对中包含我们所构造的对象,因此程序代码首先会调用“Nativestring.hashCode()”,而该方法会调用“Base64Data.get()”,我们可以观察调用栈以证实这一点:
随后,程序代码会调用“Cipher.Java”中的“chooseFirstProvider()”方法:
“serviceIterator.next()”方法会返回ProcessBuilder对象,该对象包含我们输入的那条命令。由于这些对象都链接在一起,因此java.lang.ProcessBuilder.Start()会使用ImageIO$ContainsFilter对象的方法,最终完成代码执行。
四、总结
Apache Struts是一个非常流行的Web开发框架,因此相应的漏洞也会影响深远。我们建议用户使用最新版本的Struts,并保持产品更新。
McAfee Network Security Platform可以保护客户免受此漏洞影响。