通灵纸:iOS沙盒逃脱

2020-05-02 18:04:48

昨天苹果发布了iOS13.5Beta3(似乎将iOS13.4.5重新命名为13.5),这杀死了我的一个bug。不过,这不是一个普通的错误,这是我发现的第一个0day。而且这可能也是最好的一次。不一定是因为它给了你多少,但肯定是因为我用了它多少,也因为它有多么简单。事实上,如此简单,以至于我在推特上发布的PoC看起来绝对是一个笑话。但这是100%真实的。

我称它为“通灵纸”是因为,就像“神秘博士”喜欢携带的那个名字的物品一样,它可以让你通过安检,让别人相信你有很多你不应该拥有的证件。

与几乎任何其他bug和我不得不处理的任何其他漏洞相比,这个错误在没有任何iOS和/或漏洞背景知识的情况下应该是可以理解的。本着这种精神,我也将尝试以一种没有iOS或利用特定知识的方式来撰写这篇文章。不过,我确实希望您大致了解什么是XML、公钥加密和哈希,理解C代码当然是一个很大的优势。

所以,系好安全带,我大胆地说,这是iOS上迄今为止最强大的沙盒逃逸的最优雅的漏洞。:P。

基本概念是<;tag>;打开一个标记,<;/tag>;关闭它,然后在其间插入内容。这些内容可以是原始文本,也可以是更多标签。空标记可以是自动关闭的,如<;tag/>;,它们还可以具有a=";b";以及yada yada等属性。上述文件中有三项内容超出了基本标记的范围:

<;?.?>;-以问号开头和结尾的标签,即所谓的“处理指令”,会受到特殊处理。

<;!DOCTYPE.>;-以!DOCTYPE开头的标记是“文档类型声明”,也会被特殊处理。

<;!->;-以<;!--开头和-->;结尾的标记是注释,它们加上其内容将被忽略。

完整的XML规范包含更多内容,但是a)这与我们无关,b)任何人都不应该被强迫阅读。现在,XML很难解析,原因是这篇XKCD很好地说明了这一点:

因此,您可以构造<;mis>;matching<;/tag>;,<;属性,这些属性永远不会关闭>;,甚至是永远不会关闭的<;标记,也可能是这样的标记:<;!>;,列表就是不会结束。这使得XML成为一种极难正确解析的格式,这一点很快就会变得重要起来。

现在,在XML的基础上,我们有了“属性列表”,或简称为“plist”:另一种用于存储序列化数据的通用格式。你有数组、带有键-值对的字典、字符串、数字等等。plist文件有一堆不同的形式,但在苹果生态系统中,你会实际看到的只有两种:“bplist”二进制格式和基于XML的格式,这两种格式超出了本文的讨论范围。有效的XML plist可能如下所示:

<;?xml version=";UTF-8";?>;<;!DOCTYPE plist public";-//APPLIST//dtd plist 1.0//en";";http://www.apple.com/DTDs/PropertyList-1.0.dtd";>;<;plist version=";1.0";>;<;dict&>;<;key>;操作系统内部版本<;/key>;<;string>;19D76<;/string>;IOConsoleLocked<;/key>;<;false/>;<;!--abc-->;<;key>;IOConsoleUsers<;/key>;<;array>;<;

PLIST文件在整个iOS和MacOS中都用于配置文件、软件包属性,最后但并非最不重要的是作为代码签名的一部分。

所以:代码签名。当二进制文件想要在iOS上运行时,名为AppleMobileFileIntegrity(或“AMFI”)的内核扩展要求它具有有效的代码签名,否则它将被当场杀死。这个代码签名是什么样子对我们来说并不重要,重要的是它是由散列和标识的。此哈希可以通过以下两种方式之一进行验证:

它可以提前为内核所知,这就是所谓的“临时(ad-hoc)”签名。它用于iOS系统应用程序和守护进程,并且直接根据内核中的已知散列集合检查散列。

它需要使用有效的代码签名证书进行签名。这适用于所有第三方应用程序,在此场景中,AMFI会调用userland守护进程amfid,让它运行所有必要的检查。

App Store证书。这只由苹果自己持有,为了以这种方式签名,你的应用程序需要通过App Store的审查。

开发者证书。这可以是免费的“7天”证书、“常规”开发人员证书或企业分发证书。

在后一种情况下,有问题的应用程序还需要“配置配置文件”,即Xcode(或某些第三方软件)可以为您获取的文件,该文件需要放在Payload/Your.app/embedded.mobil的App.ipa包中