CVE-2019-17556:Apache Olingo中的反序列化漏洞
这篇文章描述了我在Apache Olingo中发现的一个小漏洞,这个缺陷在4.7.0版本中得到了修复。
Apache Olingo是一个实现Open Data Protocol (OData)的Java库。该协议可帮助开发者以一种简单的方式创建和使用可查询和交互的RESTful API。
详情地址: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
最新评论