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

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

来源:本站整理 作者:佚名 时间:2018-09-07 TAG: 我要投稿
包含标准QL TaintTracking库来跟踪标准Java库调用,字符串操作等。第二个是一个近似值,允许通过字段访问跟踪非法数据:
exists(Field f, RefType t | node1.asExpr() = f.getAnAssignedValue() and node2.asExpr() = f.getAnAccess() and
  node1.asExpr().getEnclosingCallable().getDeclaringType() = t and
  node2.asExpr().getEnclosingCallable().getDeclaringType() = t
)
这表示如果将字段分配给某个非法值,只要表达式都由相同类型的方法调用,那么对该字段的访问也将被视为非法。查看以下案例:
public void foo(String taint) {
  this.field = taint;
}
public void bar() {
  String x = this.field; //x非法,因为字段被分配给`foo`中的非法值
}
如你所见,bar()中this.field的访问可能并不总是非法。例如,如果在bar()之前未调用foo()。那么不会在默认的DataFlow::Configuration中包含此流程步骤,因为我们无法保证数据始终以这种方式流动。但是,对于找到漏洞,将它们包含在DataFlow::Configuration中就很有用。
初始结果和查询细化
在最新版本的源代码上运行查询,并开始检查结果,S2-032,S2-033和S2-037仍然被查询标记。在查看其他结果之前,先调查为什么即使代码已修复,这些特定的结果仍然被标记。
虽然最初通过过滤输入来修复第一个漏洞,但是在S2-037之后,Struts团队决定通过调用OgnlUtil::getMalue()替换对OgnlUtil::getMalue()的调用来修复漏洞。
methodResult = ognlUtil.callMethod(methodName + "()", getStack().getContext(), action);
方法callMethod()封装对compileAndExecuteMethod()的调用:
public Object callMethod(final String name, final MapString, Object> context, final Object root) throws OgnlException {
  return compileAndExecuteMethod(name, context, new OgnlTaskObject>() {
    public Object execute(Object tree) throws OgnlException {
      return Ognl.getValue(tree, context, root);
    }
  });
}
并且compileAndExecuteMethod()在执行之前对表达式执行额外检查:
private  Object compileAndExecuteMethod(String expression, MapString, Object> context, OgnlTask task) throws OgnlException {
  Object tree;
  if (enableExpressionCache) {
    tree = expressions.get(expression);
    if (tree == null) {
      tree = Ognl.parseExpression(expression);
      checkSimpleMethod(tree, context); //额外检查
    }
这意味着我们实际上可以从接收点中移除compileAndExecuteMethod()。
在重新运行查询后,高亮的getMethod()作为接收点的调用的结果消失了。但是,仍然有一些结果突出显示了DefaultActionInvocation.java中的代码,这些代码被认为是已经被修复的,例如对getActionName()的调用,并且这里的数据路径并不是很明显。
路径探索和进一步查询细化
为了研究为什么这个结果被标记,就需要看到DataFlow库用来产生这个结果的每个流程步骤。QL允许编写特殊的路径问题查询,这些查询可生成可逐节点探索的可变长度路径,DataFlow库允许编写输出此数据的查询。
LGTM本身没有路径问题查询的路径探索UI,因此需要使用另一个Semmle应用程序:QL for Eclipse。这是一个Eclipse插件,其中包含一个可视化工具,允许完成污点跟踪中的各个步骤。用户可以免费下载并安装此Eclipse插件。它不仅可以在LGTM.com上对开源项目进行离线分析,还可以提供更强大的开发环境。下文的查询可以在semmle-security-java目录下的Semmle/SecurityQueries Git存储库中找到。你可以按照README.md文件中的说明在Eclipse插件中运行它们。
首先,在initial.ql中运行查询。 在QL for Eclipse中,从DefaultActionInvocation.java中选择结果后,你可以在Path Explorer窗口中看到从源到接收点的详细路径。

在上图中,你可以看到,经过几个步骤后,调用getActionName()返回的值会流入对pkg.getActionConfigs()返回的对象的get()调用中的参数:
String chainedTo = actionName + nameSeparator + resultCode
actionName来自某个地方的`getActionName`
ActionConfig chainedToConfig = pkg.getActionConfigs().get(chainedTo)
//chainedTo包含`actionName`并最终出现在`get`方法中
单击下一步,就到了ValueStackShadowMap::get()方法,如下所示:
public Object get(Object key) {
  Object value = super.get(key);  //
  if ((value == null) && key instanceof String) {
    value = valueStack.findValue((String) key);  //key`
  }
  return value;
}
事实证明,因为pkg.getActionConfigs()返回一个Map,而ValueStackShadowMap实现了Map接口,所以理论上pkg.getActionConfigs()返回的值可能是ValueStackShadowMap的一个实例。因此,QL DataFlow库显示了从变量chainedTo到类ValueStackShadowMap中的get()实现的潜在流程。实际上,ValueStackShadowMap类属于jasperreports插件,该类的实例仅在几个地方创建,并都不会被pkg.getActionConfigs()返回。在发现ValueStackShadowMap::get()不太可能被命中之后,作者通过在DataFlow::Configuration中添加一个过滤来删除依赖它的结果:
override predicate isBarrier(DataFlow::Node node) {
  exists(Method m | (m.hasName("get") or m.hasName("containsKey")) and

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

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