2016年8月17日,ISC2016移动安全发展分论坛在北京国家会议中心召开。盘古团队核心成员、上海犇众信息技术有限公司首席科学家王铁磊及联合创始人徐昊在此次论坛上介绍了“Pangu9 越狱揭秘”。
以下内容为王铁磊与徐昊报告速记整理全文:
王铁磊:大家好,我和徐昊都来自盘古团队,今天主要和大家分享我们在开发盘古Pangu9过程中越狱的漏洞以及相应的技术。今天的报告主要分三个部分,首先我们会分析在越狱工具中,用户用到的相关技术,徐昊会介绍内核的漏洞。特别需要提到一点是自从IOS9发布以后,启动了关于内核保护技术,内核态,大家说的KPP,徐昊会介绍KPP的环境下如何进行内核态,最后是总结。
简单介绍一下我们的团队,盘古团队是以发布越狱被大家所熟知的,我们研究是比较广泛的,研究安卓、车联网系统,所以基本覆盖整个移动平台。我们创建了上海犇众信息技术有限公司,这个公司在上海,希望大家以后去上海的时候,去我们公司参观。我们发布了四次越狱工具,分别是针对ISO7、8、9系列的四次越狱。因为研究方向主要在移动平台,我们在上海专门组织了一个会议,这个会议在每年的6月、7月,是一个一天的短暂技术峰会,希望大家明年有空也去参加。
盘古pangu9工具是针对第一代pangu9,是IOS9.0到9.1之前的分享。我再简单介绍一下越狱,实际上IOS以安全为著称,苹果花了大量的费用设计它的IOS。我们拿到一个IOS手机以后,你只具备了手机的使用权,不具有手机的管理权。因为苹果IOS没有把最核心的管理功能开放给终端用户,这也是为什么有人喜欢越狱,有人希望通过IOS的漏洞,把系统真正开放给用户,让用户对系统有更高的管理权限。比如说用户不具有ROOT账户的,但是越狱后可以做一些读写和应用,对IOS来说是一个非常重要的环境。但是越狱中间有一个非常关键的部分,一定要去做一些攻击内核。因为IOS中很多的安全强化策略是在内核中实现的,比如说强制代码签名、沙盒,以这个为目标后,我们后面在做越狱过程中一个很大的问题,就是当你有了哪些内核漏洞时,如何在用户态设计一些,使我们真正达到合理攻击的环节。
这其中还有一个概念,就是沙盒,IOS上面用了非常严格的沙盒策略。比如,大家从苹果商店下载的沙盒,都会用一个沙盒环境,只能有不过五六个进行通讯,在沙盒里面的非常小。如果在沙盒外整个系统是非常复杂的,如果获得沙盒外的权利,你会获得很大的权利。但是如果你要获得沙盒外进行代码执行。在很长一段时间内,大家认为IOS比较安全是因为它的沙盒环境使得很难在沙盒内直接去攻击内核,但是现在的问题是自从IOS9.1之后,很多可以在沙盒之内进行漏洞攻击。包括我们最近那款攻击,也是为什么越狱发布不到一周以后,苹果专门针对漏洞发布了一个紧急的补丁。
实际上如果回顾以往的越狱工具,可以很明确地看到如果一个团队持续地发布越狱工具,就能看到越狱工具一系列工具中的技术脉络。我们一直做的越狱工具,也是取决于当时掌握的内核漏洞,是在沙盒外进行的触发,我们要花很大精力获得沙盒外越狱代码的机会。为了达到这一点我们经常做一些沙盒外任意文件补写漏洞,把这个文件转化成任意代码执行的机会。
我们首先来看在盘古9中,我们发现的一个沙盒外任意文件补写的漏洞。去年我们在ISC上提到,重点强调了在IOS平台上有一种新的机制叫做XPC,它在地层基础上做了分装使得整个更加容易实现。我们去年已经解释了,这是一个新引入的机制,大家研究比较少,我们也分析了一些漏洞。在pangu9中我们恰好用了这个问题。这个XPC在2011年引入,当时它是作为一个亮点,在WEC上苹果也进行了宣讲,但是IOS平台现在没有开发给第三者。它使得应用和服务系统之间有一个很严格的隔离,这样它在安全性上做的好处就是它能做到权限的分离,使得应用最小权限的原理,如果这个服务不需要其他的权限就可以剥离出来,只需要赋予它所需要的权限就可以了。
这是一个典型的XPC服务端的代码实现。大家通常用到的API是COM、APPLE、XPC,这是一个服务的名字,另外两个API它会设置一个分发函数,在每个函数之间你可以去设置每个。这个做成API的话,如果大家没有做过相应的IOS开发可能不是很熟悉,苹果有着比较清晰的介绍,大家可以根据苹果的官方文档进一步了解一下这些API的内部使用情况。
对于客户端来说更简单一点,连到这个服务上面,它第三个参数是零,刚才强调了一个值。XPC传递的类型是一个字典类型,是一个高级升级结构,在发送交易之前先够到一个XPC这样类型,可以通过这一系列的函数去设置双倍的值,或者你去设置其他类型的数值,通过这一类API可以把消息发送给服务端,通过业务逻辑去处理不同的内容。去年我们分享的一些漏洞,如果服务端没有对用户数据做严格验证,直接把数据进行简单的解析,这个过程中会出现很多传统的漏洞。但实际上还有更抽象,更高层的漏洞就是逻辑漏洞。比如说我们在pangu9中的漏洞就是在一个Assetsd的漏洞,它的服务名称叫做COMAPPLE Persistenturlt ranslator gatekeeper的服务,它是媒体文件的服务。Facebook都可以访问你的照片。它的成因是什么样的?实际上这个服务里面有一个接口函数,这个函数是可以被任意一个沙盒内的应用所调用到的。这个服务本意是将用户指定的一个文件转移到srcpath。它做了一个分装。这是一个很严重的问题,这是一个典型的路径穿越漏洞。如果大家使用这种方法,它本意是将某一个文件挪到DCMI上,但是如果里面含有大量的反斜杠的话,你会获得把任意文件转移到任意一个目录下的能力。其实这就是一个很典型的,可以很容易把它转换成任意读写。比如你想读写某一个程序,就可以直接转移到你想要的目录下面。它本身是以用户运行,但是没有相关的规则,没有访问沙盒任何文件的权限。
我们知道任意文件读其实是一个非常典型的隐私泄漏问题,你可以读聊天记录,或者读短信,这都可以通过任意文件读实现。任意文件写更严重,它可以简单的转变为安装任意应用,替换系统应用,具体的细节大家可以参考去年在澳大利亚的一个安全会议上分享的议题,这个本质上在Assetsd的服务里面存在一个任意写的漏洞,如果把这个任意写转化为安装任意APP,让用户以为那是一个系统默认的APP。我们现在具备了任意文件读写,我们接下来看看如何把任意文件读写转换成一个任意代码执行。
在很早的一个版本中,在IOS7当中,其实我们一直沿用的思路就是想通过设置相应的变量,把我们自己的动态库注入到系统服务中,我们的代码可以在系统进行中执行,从而达到沙盒外执行的实现。
在IOS上其实有一个环境变量,它就类似于Linux环境中,加载器在加载文件时,会优先加载你指定的文件互,就会优先执行,代码就会在当时的主环境下面执行。如果当时所诉诸这个环境没有沙盒的话,就获得了沙盒外执行的过程。但是自从我们发布盘古7越狱以后,苹果为了阻止这个技术,它发布了动态链接库,它会验证这个宿主进程是不是一致。但是这其中有一个很特殊的例子,有的时候这个系统必须加载第三方库,它设置了一个方法。我们找到了一种方法,绕过了TEAMID的验证,苹果又设计了更严格的解决方案,它直接把动态验证库进行了一个修改,除非这个宿主进程具备gettoskollow,否则它不再管这种环境变量,这种环境变量不会再被接收了。
这给我们造成了很大的困难。所以说现在的任务是我们想去找谁具有gettoskollow。这是一个代码执行段,它是不能修改的,你不能找一个可执行程序,你去设计一个gettoskollow。这个是做不到的,是被保护的。我们在pangu9做了一个全盘搜索,在IOS9的文件系统中没有任何一个可执行程序具备。很老的开发者里面我们做了搜寻,苹果发布这个机器以后,它并不是说每个用户都会成为苹果平台的开发人员,如果你想在IOS做一个开发的话,你要去开发者网站上下载一个东西安装,然后它会你手机端和PC端进行通讯以后,这样会含有一些开发者需要的组件。比如说远程调试器,或者植入支持的东西。我们就在很老的版本的DDI里面,找到了VPEGAEND程序。
我们如何把这个VPEGAEND用在工具当中呢?我们只有把老版本的DDI上传到里面就可以了,我们发现这个不成功加载在手机端里面会有一个版本检查,提示DDI太老了,不支持这个开发环境。所以我们觉得这可能是一个有很大的问题。但是我们在手机端负责加载DDI的进程,我们发现了一个逻辑上的错误。它把DDI做一个解析,加载到内核里面去做做版本比对。
我们知道苹果平台上有着强制代码签名,比如说直接由苹果直接签名的才能运行,这个DDI的程序如何在苹果平台下执行呢?是因为在加载DDI的时候,它会把DDI里面所有所执行文件保存在里面的trustcache,它的逻辑问题是虽然老版本的DDI不能成功,但是它已经注册给内核了,内核误认为这个APP是具备苹果合法签名的程序,这个事情就变得很好办了。我们所需要做的就是我们先把有问题的老版本的API,使得它有一个合法签名。
我们再加载一个正常的DDI,它进行远程调试,对开发者调试自己应用的支持程序。我们再利用之前的XPC漏洞,把老版本里面写到一个debugserver调试vpeagent,设置dyld insert。它没有办法逃避TeamID验证,我们没办法检测开发者的ID。也就是说这个时候,我们还要去照顾TEAMID验证,我们把本身开发出来的pnagent加载一个系统dylib,因此不会触发teamid验证失败。但是这个dylib会触发代码签名验证失败,你最后会触发代码签名异常,因为你把整个签名段用了系统已有程序的代码签名进行替换,这时会发生签名不一致,签名错误。
这其中又是一个很神奇的地方,大家可以想一下,开发者进行调试自己程序的时候,它是如何去做这个段点的呢?你本身是违背代码签名认证的,你修改一点是没办法对上的。如果一个进程具有这个get task allow为进程发生代码签名错误,例如如果调试器设置断点,这类断点本质上就会修改代码段,导致代码签名验证失败。但是内核会允许进程继续执行。因此vpnagent加载dylib时,虽然触发了代码签名错误,但是内核并不会终止vpnagent。
特别声明:本站注明稿件来源为其他媒体的文/图等稿件均为转载稿,本站转载出于非商业性的教育和科研之目的,并不意味着赞同其观点或证实其内容的真实性。如转载稿涉及版权等问题,请作者在两周内速来电或来函联系。