一个“短命”的iOS内核漏洞
漏洞的生命周期一直是一个很有意思的话题。人们(特别是媒体)通常对两类安全漏洞特别感兴趣。一类是许久不被修复的安全漏洞。这类漏洞通常反映出厂商对安全的漠视,甚至可以激起厂商和安全社区的对立,因此颇具新闻价值。另外一类是存在已久但刚被发现和公开的安全漏洞。这类漏洞一经公布,有时候会跳出很多人来“认货”,高喊自己手中的存货被曝光了。这类漏洞背后隐含的问题是很难估计这些漏洞的影响范围(例如漏洞已经被多少人发现了、已经被多少攻击利用了),因此特别适合各种阴谋论。
我们会在9月28号的ISC训练营讨论该漏洞的细节, 有兴趣参加训练营的同学请访问:
http://isc.360.cn/2015/training.html
在这篇blog中,我们要分享一个非常“短命”的iOS内核漏洞。这个漏洞在iOS 9的测试版中被引入,但是在iOS 9的正式版中被修复,是个典型的存活周期短、影响范围极其有限的漏洞。之所以分享这个漏洞,一是这个漏洞成因非常典型,但反映出苹果对代码安全非常重视从而确保漏洞的及时修复;二是讨论一下简单模糊测试(Fuzz Testing)在挖掘这类漏洞时候的低效问题。
1、漏洞分析
漏洞存在于名为AppleCredentialManager的内核扩展模块。该模块通过AppleCredentialManagerUserClient与用户态程序通信,AppleCredentialManagerUserClient只有一个externalmethod。这个selector 0的处理函数可以接受任意长度的struct输入。下面简要描述一下漏洞的触发流程:
a、在处理输入时,AppleCredentialManagerUserClient会首先检查输入数据的前四个字节是否为一个特定的Magic Number 0x53435244,如果不是则不会进一步处理这个输入。 b、AppleCredentialManagerUserClient进一步根据输入数据(下文简称input)的第5个字节判断数据的类型,即根据这个opcode(即input[5])进行数据分发。 c、在iOS 8.4.1 中,AppleCredentialManagerUserClient接受的opcode范围是从0到10,但是在iOS 9的beta版和正式中,AppleCredentialManagerUserClient接受的opcode范围扩展到从0到19。 d、在iOS 9 beta 版中处理opcode=11的输入数据时,AppleCredentialManagerUserClient会进一步解析从input+8开始的数据。这段数据的组织结构示意图如下: |一个以\0结尾的字符串 | 4字节(代表后继数据长度) | 二进制数据 | paramsCount | param_0 | param_1 | …. | param_n| e、paramsCount代表后继param结构的个数,而每个param结构的大小为12字节。在处理paramsCount和随后的params的时候,AppleCredentialManagerUserClient的处理逻辑如下:memmove(¶msCount, input+ offset_of_paramsCount, 4u);
if(paramsCount!=0){
parametersBuffer = (void *)IOMalloc(12 * paramsCount);
f、到这里问题已经显现。由于缺乏对 paramsCount的检查,计算内存分配size的时候存在整数溢出:如果设置 paramsCount为超大数值(例如0x80000001),会导致实际上仅分配少量字节。分配内存成功后,AppleCredentialManagerUserClient进一步将input中的param填充到分配的内存里,从而导致堆溢出。 g、此外,填充内存的循环以paramsCount为边界。通常这样的漏洞会最终引起内核panic,很难利用。但在AppleCredentialManagerUserClient的填充过程中,会判断输入param的有效性。如果发现输入的param无效,则会跳出循环,为漏洞利用创造了条件。2、漏洞修复
在iOS 9的正式版中,我们发现该漏洞已经被修复。AppleCredentialManagerUserClient增加了多处检查。
首先,AppleCredentialManagerUserClient增加检查,确保paramsCount不能大于10。
memmove(¶msCount, input+ offset_of_paramsCount, 4u);
if ( paramsCount >= 0xB )
{
...
}
对于过大的paramsCount,内核会产生下面的assert报警
AssertMacros: paramsCount <= 10 (value: 0x0), file: /BuildRoot/Library/Caches/com.apple.xbs/Sources/AppleCredentialManager/AppleCredentialManager-83.1.1/common/utils.c, line: 440
其次,在内存分配前,AppleCredentialManagerUserClient增加了乘法溢出的判断
if ( paramsCount != 12 * paramsCount / 12 )
{
...
}
3、简单Fuzzing的实效
对于这种漏洞,简单的主动式Fuzzing(即通过随机构造畸形样本对目标代码测试)会特别低效。只有当样本前四个字节是0x53435244并且第5个字节在0-19范围内,才能够对代码进行有效测试。而随机生成的样本很难满足这种约束。在PC端,大量改进代码Fuzzing的技术已经被提出并应用(例如符号执行),但在iOS内核场景下如何结合高级模糊测试技术还存在很多难题尚待解决。
本公众号是盘古实验室的官方公众号, 将会定期分享盘古实验室的技术分享以及最新的研究成果。
关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
随时掌握互联网精彩
- 1 习近平澳门之行 这些瞬间令人难忘 7904657
- 2 突发:美军战斗机被击落 7979016
- 3 湖南卫视声明 7854924
- 4 在澳门 传统文化在指尖绽放 7757742
- 5 不许说日语的App在日本爆火 7673198
- 6 上海地铁列车撞塔吊 车头变形 7591882
- 7 南昌通报李某雪已被送诊 7441052
- 8 詹姆斯又一个历史第一 7346250
- 9 考研数学 7223080
- 10 美国女教师强奸12岁男童怀孕获刑 7154246