CVE-2019-17556:Apache Olingo中的反序列化漏洞

iso60001  1821天前

22.png

这篇文章描述了我在Apache Olingo中发现的一个小漏洞,这个缺陷在4.7.0版本中得到了修复。

Apache Olingo是一个实现Open Data Protocol (OData)的Java库。该协议可帮助开发者以一种简单的方式创建和使用可查询和交互的RESTful API。

33.jpg

详情地址:https://blog.gypsyengineer.com

问题

Apache Olingo有一个AbstractService类,是公共API的一部分。根据相关Java文档,该类是代理模式的入口点。它可让用户访问实体容器实例。类的构造器可接受压缩的元数据。更准确地说,构造器期望得到序列化的xml元数据对象,使用base64进行编码,用GZIP压缩。那么它使用哪种序列化机制呢?就是默认的Java序列化,一种已知的易受到反序列化攻击的机制。以下是构造器如何处理压缩的元数据:

protected AbstractService(final String compressedme tadata, final String me tadataETag,
          final ODataServiceVersion version, final String serviceRoot, final boolean transactional) {
ByteArrayInputStream bais = null;
    GZIPInputStream gzis = null;
    objectInputStream ois = null;
    xmlmetadata metadata = null;
    try {
          // use commons codec's base64 in this fashion to stay compatible with Android
          bais = new ByteArrayInputStream(new base64().decode(compressedme tadata.getBytes("UTF-8")));
          gzis = new GZIPInputStream(bais);
          ois = new objectInputStream(gzis);
          metadata = (xmlmetadata) ois.readobject();

首先,它使用base64.decode()方法来解码数据。然后,将解码后的数据转换为字节数组,并将数组包装为ByteArrayInputStream实例。接下来,将输入流包装到GZIPInputStream对象中以解压缩数据。最后,将GZIP输入流包装到objectInputStream中以反序列化元数据。

默认情况下,objectInputStream在反序列化数据时不会进行任何安全检查。这意味着如果攻击者能够将恶意元数据提供给和AbstractService有关的类,那么就有可能导致远程代码执行。

这个缺陷的严重程度在很大程度上取决于特定应用如何使用AbstractService类,以及元数据来自何处。

如果应用从受保护的资源处加载元数据,则攻击者必须找到将恶意元数据插入受保护资源处的方法,这可能并不容易。如果元数据是从正确配置的数据库加载的,那么攻击者必须找到SQL注入或其他可将恶意数据注入数据库的方法。此外,如果应用从具有权限控制的文件加载元数据,那么攻击者必须找到一种方法来将恶意代码写入文件。

另一方面,如果应用通过网络接收到元数据,则攻击者可能更容易让目标应用接收到恶意数据。

不管如何,加强AbstractService类的安全性是最有效的。

解决方案

通过可反序列化类的白名单,可暂时防御此类攻击。例如,可以通过扩展objectInputStream类,重写resolveClass()方法,实现白名单控制。当然这并不是必须的,因为Olingo使用了Apache IO,它提供了ValidatingobjectInputStream类来实现类似功能的白名单。另一种选择是在JEP 290中添加过滤器,但这种方式需要使用较新版本的Java。

修复办法很简单:

  • 添加了一个工厂方法createobjectInputStream(),创建一个ValidatingobjectInputStream实例,利用其配置了一个允许反序列化类的白名单。

  • AbstractService类的构造器调用createobjectInputStream()方法来获取元数据的反序列化器。

  • 默认情况下,白名单只包含org.apache.olingo中的类。

  • 如果用户希望扩展默认白名单,可以重写getAllowedClasses()方法,返回白名单列表。

相关补丁已经在Apache Olingo 4.7.0中发布。

我的应用存在漏洞么?

当然,并不是每一个使用旧版本Apache Olingo的应用都是脆弱的。你可以通过两项检查来确定漏洞存在与否:

1.它是否使用了AbstractService类?

2.攻击者是否有一种方法可以向类提供恶意数据?

上述问题的答案取决于不同的应用。如果两个答案都是肯定的,那么这个应用很可能存在缺陷。

结论

这个漏洞是应用程序使用默认Java反序列化机制时所存在一个反序列化漏洞,并不是所有使用Apache Olingo的应用在默认情况下都有漏洞,但为了安全起见,最好还是更新一下库。

本文由白帽汇整理并翻译,不代表白帽汇任何观点和立场
来源:https://medium.com/bugbountywriteup/cve-2019-17556-unsafe-deserialization-in-apache-olingo-8ebb41b66817

最新评论

昵称
邮箱
提交评论