PEGASUS iOS内核漏洞分析(第二部分) - 嘶吼 RoarTalk – 网络安全行业综合服务平台,4hou.com

PEGASUS iOS内核漏洞分析(第二部分)

Change 技术 2016-09-12 15:20:52
240935
收藏

导语:Apple公司早在今年5月份就为了UAF漏洞修补过一次OSUnserializeBinary(),但是这个补丁是用来修补CVE-2016-1828漏洞的。

背景

上次介绍了PEGASUS IOS内核漏洞之后,又发现了几个新的问题:

1. Apple公司早在今年5月份就为了UAF漏洞修补过一次OSUnserializeBinary(),但是这个补丁是用来修补CVE-2016-1828漏洞的。
2. 我们描述的UAF触发方法在iOS9和 OSX 10.11之前版本的代码中并不存在。

获知这两个细节后,我们决定对我们的分析做一个小的更新。

The old code

退后一步看看iOS 9和OS X 10.11之前版本的OSUnserializeBinary()代码。

从上述代码中可以看出,iOS 9.0 和OS 10.11之前版本的字典键必须是OSSymbol对象。并且OSString代码路径还没有添加。这意味着我们分析中提到的UAF方法在老版本的代码中无法实现。此外,仔细查看这段代码并与我们的分析比较后,可以发现老版本中调用setObject()时只有2个参数,而不是3个。这是因为上述代码在CVE-2016-1828的补丁之前就存在。

现在仔细地看一下上述代码,并找出触发UAF的代码路径。

Trigger 1

在这段代码中,触发UAF的第一种方法就是利用CVE-2016-1828:

1. 398行代码会设置字典键k1为对象o1
2. 这会使o1和k1的引用计数器加1(变成2)
3. 399行处对象o1被释放,它的引用计数器减小到1
4. 400行处对象k1(sym)被释放,它的引用计数器减小到1
5. 此时由于字典保持了对两个对象的引用,没有任何问题
6. 当下一个对象o2被逆序列化并插入字典后,重用相同的键k1时,398行的setObject()方法会在字典中用o2替换o1。在替换的时候o1的引用计数器从0减少到1
7. 此时o1被从内存中释放。如果此时逆序列器重新尝试产生一个指向这个对象的引用,就会造成UAF。

Trigger 2

在这段代码中,触发UAF的第二种方法可能就是PEGASUS(CVE-2016-4656)真正用到的方法:

1. 如果我们正在插入的对象o是对dict本身的一个引用,389行代码则不会调用setObject()
2. 如果setObject()没有被执行,o和sym的引用计数器永远不会增加
3. 399行代码将会减小o的引用计数器到大于或等于1的值(因为它是对dict的引用)
4. 400行代码最多将会减小sym的引用计数器到0(如果symbol是奇怪的字符串)
5. 此时,OSSymbol对象sym被销毁
6. 此后创建任何指向对象sym的引用都是UAF

可以看到,在iOS 9 和 OS X 10.11之前版本的代码中早已存在两个单独但又相关的UAF触发代码路径。这意味着加上Part1中描述的,在仅仅20行代码中就已经有3个UAF触发代码路径。

The fixes

Apple公司5月份发布的CVE-2016-1828漏洞补丁中对这段代码唯一的改变是增加了调用setObject()时的第3个参数ture

if (o != dict) ok = dict->setObject(sym, o, true);

当代码中出现错误时,就会重写已经设定的字典键,因此Brandon Azad提到的UAF情形便不能再被触发。不幸的是Apple公司认为这样已经足够好了,所以他们没有及时对OSUnserializeBinary()进行代码安全检查。不然的话,一个熟练的代码审计员一定会意识到代码中有大量对release()的直接调用。这可以被用来从objsArray中释放对象,从而触发UAF。这种仅仅给setObject添加第三个参数ture不是一个完美的修复方法。

Apple没有对他们的安全补丁进行安全审计,又或者说相关责任人没有查看函数中的其它release()调用。因此这20行代码中的其它两种UAF触发方法仍然存在,并能控制内核执行渗透系统的操作。PEGASUS被发现后,Apple花了很多精力去修复这20行代码。他们废除CVE-2016-1828的补丁,并重写函数使其不再调用任何release()(除了对错误和临时变量的清理),从而在函数的最后、返回结果之前,所有的对象从objsArray中得到释放。这样反序列化时引用计数器永远不会下降到0。

Conclusion

在过去的两周内,许多安全专家都称赞苹果对PEGASUS的快速反应。这一赞扬是因为有关方面不对独立的第三方研究人员开放样本,并且没有透露该内核漏洞的详细信息给公众。没有这些信息,公众只是简单地认为PEGASUS使用的是全新的内核漏洞来控制iOS设备。然而逆向PEGASUS使用的内核漏洞后,发现了一个完全不同的画面:

仅仅因为2016年5月Apple修复CVE-2016-1828漏洞时没有对问题代码进行安全审计,导致CVE-2016-4656内核漏洞仍然存在。仅仅20行代码中就存在3条代码路径可以触发UAF。尽管这些release()方法离得很近,但是Apple只修复了其中一条路径。此外,从对PEGASUS补丁的分析可以看出,只需要稍微修改一下代码就能够同时修复这3个问题。这可以被认为是一个非常严重的疏忽:修补工作并有在BrandonAzad提出UAF后就立刻展开。如果Apple公司用不同于之前的方式修补CVE-2016-4656漏洞,那么CVE-2016-1828漏洞将不会被滥用。

  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论

 
本站4hou.com,所使用的字体和图片文字等素材部分来源于原作者或互联网共享平台。如使用任何字体和图片文字有侵犯其版权所有方的,嘶吼将配合联系原作者核实,并做出删除处理。
©2024 北京嘶吼文化传媒有限公司 京ICP备16063439号-1 本站由 提供云计算服务