菜单

微信公众号:Android安全中文站

文章

Home 安卓漏洞攻防 又一个安卓序列化漏洞 —— CVE-2015-3525简单分析与思考
Home 安卓漏洞攻防 又一个安卓序列化漏洞 —— CVE-2015-3525简单分析与思考

又一个安卓序列化漏洞 —— CVE-2015-3525简单分析与思考

安卓漏洞攻防 by

0x01前言

去年11月份,安卓曾爆出过一个由Jann Horn发现的提权漏洞,该漏洞被描述为“由于java.io.InputStream未检查将要反序列化的对象是否真的可序列化,攻击者可向system_server发送一个不能被序列化的对象,在GC时对其造成任意代码执行从而实现提权。”由此可知Google和jann Horn本人认为脆弱点出现在java.io.InputStream。Google随后发布了补丁(git commit:738c833d38d41f8f76eb7e77ab39add82b1ae1e2)为java.io.InputStream添加了可序列化验证。然而事情并没有结束,前几天IBM Security披露了一系列已得到确认的漏洞,证明该问题并没有真正被修复。

0x02问题出在哪儿

我们先来简单回顾一下CVE-2014-7911。该漏洞的细节大概是这样的:system_server是一个拥有system权限的关键系统进程,任意应用可向其发送可序列化对象,虽然system_server并不会主动调用该对象的方法,但是在系统GC该对象时会调用到其finalize方法。Jann Horn发现android.os.BinderProxy这个类在finalize方法里调用了一个native指针,而这个指针可被攻击者控制指向任意地址,因此在GC时有机会造成代码执行。但android.os.BinderProxy是一个不能被序列化的类,因此理论上我们并不能通过发送它的实例来控制将要攻击的目标进程代码执行,但由于java.io.InputStream没有检查接收到的对象是否可序列化,因此我们可以通过特殊方法构造一个被序列化了的伪android.os.BinderProxy来达到目的。Google为java.io.InputStream添加了序列化检查来阻止攻击者发送android.os.,但通过这个漏洞我们可以发现一个可序列化的类只要满足以下条件就能代替android.os.BinderProxy实现代码执行的目的:

(1)实现了finalize方法;
(2)在finalize方法里调用了一个native指针;
(3)该native指针是攻击者可控的(没有被声明为transient和static);
(4)implements了Serializible接口(可序列化);
(5)没有重载readObject和readResolve方法来阻止我们控制native指针。

IBM Security在安卓原生框架中找到了一个这样的类OpenSSLX509Certificate(CVE-2015-3525),在一些第三方SDK中找到了更多的类。IBM Security的建议通过分析这个漏洞我们可以知道,CVE-2014-7911的补丁只是紧缩了攻击界面,而没有真正解决问题。Google随后发布了CVE-2015-3525的补丁,将存在于OpenSSLX509Certificate类中的native指针声明为transient,使该指针不可被序列化。然而,即使安卓的原生世界修复了所有危险的可序列化类,如果第三方SDK中存在这样的类依然可被用于序列化攻击。IBM Security建议将Bundle的解析内部资源修改为懒行为,并修改readObject、readResolve等读取方法来阻止攻击者控制危险变量。

0x03无声信息的思考

即使现在CVE-2015-3525已经得到修复,但我们仍然应该重视这样一个事实:即使原生世界和第三方SDK都已得到修复,但第三方安卓应用如果实现了一个危险类,并且接收可序列化对象,则同样有可能被攻击者劫持,从而绕过沙盒保护机制。我们的移动安全研究员分析认为安卓的类型验证机制存在隐患,攻击者可构造一个特殊的序列,在反序列化的时候造成类型混淆,组装成任意可序列化的对象,因此序列化的问题仍然没有从根本上被修复。我们会继续跟进该问题,同时第三方开发者应该审查自己的应用是否存在危险的可序列化类来避免这类问题发生在自己身上。

转载自:http://mp.weixin.qq.com/s?__biz=MzAwNTYwMjM3Mw==&mid=212075618&idx=1&sn=c4eecd5e367928c2e115ed2d3165404a&scene=0#rd     原文作者:无声说安全

 

18 2015-08