欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

CVE-2018-11776:如何通过Semmle QL找到Apache Struts的远程执行代码漏洞

来源:本站整理 作者:佚名 时间:2018-09-07 TAG: 我要投稿
    m.getDeclaringType().hasName("ValueStackShadowMap") and
    node.getEnclosingCallable() = m
  )
}
这个predicate意思是如果非法数据流入ValueStackShadowMap的get()或containsKey()方法,那么就不要继续跟踪它。
新漏洞:CVE-2018-11776
只有10对源和接收点,就很容易通过手工检查发现这些是否真正存在问题。通过一些路径,作者发现有些路径是无效的,因为它们在测试用例中,所以在查询中添加了一些过滤来过滤掉这些路径。这就留下了一些非常有趣的结果。
以ServletActionRedirectResult.java中的源代码为例:

在第一步中,调用getNamespace()的源通过变量namespace流入ActionMapping构造函数的参数:
public void execute(ActionInvocation invocation) throws Exception {
  actionName = conditionalParse(actionName, invocation);
  if (namespace == null) {
    namespace = invocation.getProxy().getNamespace();  //源
  } else {
    namespace = conditionalParse(namespace, invocation);
  }
  if (method == null) {
    method = "";
  } else {
    method = conditionalParse(method, invocation);
  }
  String tmpLocation = actionMapper.getUriFromActionMapping(new ActionMapping(actionName, namespace, method, null)); //namespace进入ActionMapping的构造函数
  setLocation(tmpLocation);
继续执行这些步骤之后,可以看到getUriFromActionMapping()返回一个URL字符串,该字符串使用构造的ActionMapping中的namespace。然后通过变量tmpLocation流入setLocation()的参数,然后setLocation()在超类StrutsResultSupport中设置字段位置:
public void setLocation(String location) {
    this.location = location;
}
然后代码在ServletActionResult上调用execute():
String tmpLocation = actionMapper.getUriFromActionMapping(new ActionMapping(actionName, namespace, method, null));
setLocation(tmpLocation);
super.execute(invocation);
它将location字段传递给对conditionalParse()的调用:
public void execute(ActionInvocation invocation) throws Exception {
    lastFinalLocation = conditionalParse(location, invocation);
    doExecute(lastFinalLocation, invocation);
}
然后conditionalParse()将位置传递给translateVariables():
protected String conditionalParse(String param, ActionInvocation invocation) {
    if (parse && param != null && invocation != null) {
        return TextParseUtil.translateVariables(
            param,
            invocation.getStack(),
            new EncodingParsedValueEvaluator());
    } else {
        return param;
    }
}
所以当在ServletActionRedirectResult中没有设置namespace参数时,代码从ActionProxy获取namespace,然后将其作为OGNL表达式进行评估。为了测试这个,作者通过以下方法替换了showcase应用程序中的一个配置文件(例如struts-actionchaining.xml)中的struts标记:
struts>
    package name="actionchaining" extends="struts-default">
        action name="actionChain1" class="org.apache.struts2.showcase.actionchaining.ActionChain1">
           result type="redirectAction">
             param name = "actionName">register2param>
           result>
        action>
    package>
struts>
然后在本地运行showcase应用程序,并访问了一个可以触发此漏洞的URL并执行shell命令以在计算机上打开计算器应用程序。
不仅如此,来自ActionChainResult,PostbackResult和ServletUrlRenderer的不可信来源也同样有效!PortletActionRedirectResult中的那个可能也可以,但没有被测试。四个RCE足以证明问题的严重性。
总结
在这篇文章中,作者展示了通过使用已知(过去的)的漏洞来帮助构建应用程序的污点模型,只需将麻烦的工作留给QL DataFlow库就可以找到新的漏洞。
鉴于S2-032,S2-033和S2-037都是在短时间内被发现和修复的,安全研究人员研究了S2-032以寻找类似问题并发现S2-033和S2-037。所以这里最大的问题是:鉴于在这里发现的漏洞(S2-057)也来自类似的问题,安全研究人员和供应商是如何错过的,而且在两年后才发现?在作者看来,这是因为S2-032,S2-033和S2-037之间的相似性在某种意义上是局部的,因为它们都出现在源代码中的相似位置(全部在Rest插件中)。S2-057和S2-032之间的相似性处于更加语义的层面。它们由受污染的源连接,而不是源代码的位置,因此任何能够成功找到这样的变体的软件或工具都需要能够在整个代码库中执行这种语义分析。
 

上一页  [1] [2] [3] 

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载