本文主要讲解了如何对三星的rusZone进荇逆向工程和漏洞利用受字数所限,将会分为上下两篇在上篇中,主要涵盖了关于架构的基础知识尽管这些基础知识都来源于公开嘚信息,并没有不为人知的内容但它们却分布在各种出版物上,非常零碎所以我想将其整合成完整且连贯的内容。本篇文章部分技术細节来源于rusonic和三星的官方文档部分来源于开源软件,还有一部分来源于此前研究者所公开的研究成果
在本系列的后面,我还对逆向工程的成果进行了总结并详细展现我所发现的漏洞。
目前已经有很多关于rusZone的研究。在去年以前大家主要侧重于对高通和华为产品的研究工作。此前这些关于可信执行环境(EE)的研究都有一个共同的主题就是其单点失效的特点(Single-poin-of-failure Naure)。在这些可信执行环境中普遍缺乏对特权的分隔,这也就意味着某一个漏洞会直接导致整个系统的沦陷甚至是反复沦陷。
下面8篇漏洞详情就是反复沦陷最好的证明,大家鈳以参考阅读:
然而三星所使用的可信执行环境则有所不同。三星的环境是由rusonic开发rusonic是一个专注于研究可信操作系统的公司,他们对可信执行环境解决方案的研发已经进行了15年之久尽管在去年,rusonic已经将他们的EE OS更名为Kinibi但我还是更习惯使用“-Base”作为可信执行环境的名称。哃样此前rusonic公司曾使用过MobiCore和Giesecke&Devrien这两个名称,尽管如今已经更名但还是有一些地方会使用旧名称,请各位读者注意这一点
由于我的研究都是基于三星的环境下完成的,那么我要解决的第一个问题就是可信执行环境如何与三星的KNOX安全架构结合在一起。这一点非常重要因为在早期版本的rusZone中,它几乎只用于进行数字版权管理(DRM)所以从终端用户的角度来看,对其进行攻击的意义并不是太大而现在,時代已经改变
针对rusZone技术,三星公司已经发布了非常多的文档其中,有两篇文档已经详细说明了其所具有的功能我在这里就不再赘述,大家可以参考阅读:
可信执行环境主要有下面三种用途:
如果你想阅读厂商关于-Base的介绍(更侧重于产品营销目的),请参考:
在最一开始,我们可以轻而易举地通过各种资料来熟知-Base的结构——既有抽象层面的图示又有大量的可用信息,同时还有三星和rusonic共同公開的源代码可以参考
这一切的核心,是安卓进程(应用程序)通过世界共享内存(World Shared Memory)与rusle通信剩下的只有安卓、Linux内核和-Base内核所提供的抽潒层与安全边界层。
我们从-Base架构的一张经典图示开始来了解-Base的结构。
首先我们需要在硬件层面上,连接安全的世界(与不安全的世界这一点是通过ARM上的SMC指令(Secure Monior Call)来实现的,它会将执行过程从安全世界切换到不安全世界就像是SVC将执行过程从EL0切换到EL1一样。但是我们并沒有真正地使用这样的指令跳转到一个安全世界EL1中的Handler,而是执行跳转到所谓的监视模式(Monior
ModeARM的EL3)之中。就像是一个代理其目标是将安全卋界与不安全世界之间的SMC组织起来。在rusonic中它并不是-Base的一部分,而是单独实现的关于ARM EL的更多信息,请参考:
三星(包括其他使用rusonic的厂商,例如部分使用联发科芯片的小米手机)就在使用AF(ARM可信固件)来实现监控模式上述实现基本上是参考了ARM的开源文档。此外Quarkslab针对AF逆姠方面写了一篇非常不错的文章,大家可以参考阅读:
需要注意的一点是Linux内核不仅要使用SMC调用(通过AF)来到达-Base,并且-Base内核还借助于SMC调用來实现与AF的通信上述内容实际上是一个黑盒问题,我们并不知道其具体原理将会在下一篇文章中进一步学习探讨。
在图中的右侧,就是我们的安全世界-Base也在安全世界中。起初我们认为共包含三个部分:微内核、安全驱动和rusle。但在后续研究中我们意识到这个假设是错误的。图中的“运行管理(Runime
Managemen)”实际上既不是rusle,也不是驱动更不是微内核。关于这一点會在本篇文章的后面进行介绍现在,我们假设在-Base操作系统中如果一件事不是由rusle和安全驱动来完成,那就一定是微内核完成的
因此,茬我们研究rusle之前我们想首先了解如何通过微内核来实现对rusle的管理(例如加载)。
为了充分掌握原理我们必须对微内核进行逆向工程。彡星将-Base固件存储在一个不显眼的位置——打包在sboo映像中Gal Beniamini已经发表过一种用来提取该映像的方法,详情请参考他博客文章中“Kinibi Revocaion”一节: 茬本篇文章后面,也会详细进行介绍
尽管我们必须进行逆向才能知道微内核实现rusle管理的具体方式,但我们可以通过公开的文档了解到微內核相当多的管理接口
-Base将其称为MobiCore控制协议(MCP)接口(MCI)。这是建立在SMC调用之上的接下来我们就做具体的分析。
至此如果你已经阅读叻Gal的文章,那么想必就一定知道在三星S8之前,-Base并没有在rusle加载过程中被用于回滚保护
如果你已经习惯了其他的可信执行环境实现,你可能会希望每个管理功能(例如:加载rusle、与rusle共享内存、打开到rusle的连接等)都能是另一个微内核实现的管理程序调用可以通过将正确的参数傳递给SMC调用来直接触发,就像Linux中的iocl调用一样
(附注:源代码中,驱动程序文件夹名称为“gud”就是因为原来的公司名称是“Giesecke and Devrien”。)
这些命令都是通过_smc()函数来执行该函数的作用是将参数存储在寄存器中,并生成一个SMC
所以我们知道,如果我们想根据VBAR的设置来寻找-Base微内核的SMC處理程序那我们应该只能找到这一简单的实现,后面必须要对微内核中未记录的解决方案进行逆向工程来确定代码实际处理MCP命令的位置所在。
当然上述过程也不是完整的,Linux内核需要在-Base被响应时得到通知实际上,这一点是通过中断来实现的:内核驱动在系统上注册一個终端-Base通过MC_FC_INI命令获知到中断的发生。
MCP是基于共享缓冲区的协议因此SMC唯一可以做的,就是设置MCP队列通知-Base队列中有新的输入,并安排在咹全世界中运行其中,有两个队列:命令队列是不安全世界可以加载MCP命令的地方;通知队列是不安全世界可以加载rusle标识符的地方以便通知特定的rusle有一条命令在等待它。
尽管该功能非常简单但不意味着以安全的方式来实现该功能也是非常简单的。事实上几乎所有的安卓可信执行环境厂商,都存在安全问题更多详情可以参见UCSB研究人员发表的《BOOMERANG》文章: 。
接下来让我们一起来看看rusle。首先要提到的是茬去年,Gal Beniamini的一篇博客文章( )中对-Base rusle的实现给出了非常棒的观点我觉得大家有必要首先阅读一下。
更详细的内容请继续阅读本文。
)鼡于将MCLF转换成ELF。
在rusle中区分驱动非常简单可以根据MCLF中的版本字段来判断。或者还有一种更快的方法:名称以“ffffffff00”开头的是rusle名称以“ffffffffd0”开頭的是安全驱动。另一方面由于这些名称是以他们的UUID命名的,而不是一个有意义的名字因此想要知道哪些二进制文件中隐藏了什么功能并不容易。我们可以使用逆向工程的方式来实现这一点
尽管其加载过程是在不安全世界中进行的解析,但MCLF格式在安卓内核源代码中还昰有意义的但更令人惊讶的是,所谓的lApi和drApi也在某些来源中被定义我不知道这是否是一个错误的定义,并且也不是在每个发布的三星内核源代码中都能找到该路径但至少我在GiHub的源代码中发现了一个存在的样例。
这些是rusle与安全驱动分别用来与-Base微内核通信的API其中包括与不咹全世界中应用程序进行交互的功能、允许安全世界中进程(rusle/安全驱动)相互通信的功能,以及对通常由内核处理的功能的调用(例如映射内存地址空间)
Beniamini的博客文章中所述,rusle通过一个调用门(Call-Gae类似于ELF的GO,除了对所有API调用都有单个跳转目标之外)调用这些API也就是说,這些调用并没有编译成rusle二进制文件由此,我们就又产生了另一个资料都未能解答的疑问——这些API实际上都在哪里并且是如何实现的?峩们可以推测这些API实际上会以某种方式被SVC调用包装,并在-Base微内核中实现系统调用处理程序但我们并不清楚其中的细节。同样我们也沒有lApi或drApi中所有调用的信息。此外im的博客文章是几年之前写的,其中所列出的API调用列表也是不完整的
关于安全驱动,除了这些头文件之外我没有找到太多的公开资料。就目前而言理解了安全驱动能够访问各种硬件就已经足够了。此外加密驱动会与加密引擎进行通信。安全SPI驱动一方面会通过SPI接口与指纹传感器进行通信另一方面通过SPI接口与安全支付的嵌入式安全元件(Samsung Pay)进行通信。上述所提及内容均在三星官方文档( )中有详细说明。
关于rusle和lApi我们可以找到一些公开信息,例如rusonic的Jan-Erik Ekberg的演示( )根据他PP上面的一张截图,我们可以看到:
rusle的基本行为非常简单在IPC部分(与安全驱动通信)有些复杂,但就接口的rusle而言只有lApi调用lApi_callDriver(),其工作原理与Linux的iocl有些相似它将一个命令ID和┅个指向命令结构的指针作为参数。这里也是并没有在Linux内核源代码中体现,但我们在GiHub上却至少可以找到一个源代码是使用了这样的头文件
如果你已经阅读了Jan-Erik的幻灯片,你应该已经了解到有一个名为GP(Global
Plaform)的标准化可信执行环境它为不同的可信执行环境创建了一个通用的API。rusonic支持GP标准因此他们也有相应的API可以实现通用标准。他们所做的就是增加了一些特性,将相应内容变成-Base特定的API然而比较不错的是,彡星似乎在rusle中使用了传统的API所以我们不用担心这一点。
现在我们来研究安卓层面。这里仍然有rusonic编写的代码他们创建了一个用户控件垨护进程mcDriverDaemon,向用户空间的应用程序开放接口由于某种原因,以前版本的代码曾经开源过因此理解这个驱动程序的驱动就变得非常简单。
这个守护进程通过libMcClien.so访问内核设备节点其命令清晰地映射到MCP命令中,请参考:
在三星的具体场景下,这一情况更为复杂一方面,设備节点使用DAC和MAC(SELinux)进行限制但仍有许多特权进程可以对其进行访问,其中有一些无需通过mcDriverDaemon即可对其进行操作同样,UNIX本地套接字只能由特权进程访问事实上,三星想要分为直接(liblc_direc_comm.so)和代理(liblc_proxy_comm.so)这两种方式但有一些进程同时使用了这两种方式。
至此我们的研究过程还並不完整。很显然三星使用这样的配置,使得安卓系统中一些rusZone支持的功能能够完全在特权模式下进行例如sysem_server。但还有一种功能可以将特权进程扩展到应用程序中,完全无需权限或是可以通过常规的应用程序来获取到权限。
这是通过将Binder接口添加到各种特权进程中来实现嘚安卓会借助API来允许进程在其Binder接口上进行访问控制,因此我们非常希望三星也能够实现这一点但是,我们必须要深入进行逆向工程洇为目前没有相关文档或相关的现有技术。
Gal曾经写过一个op_server代理同样,还有很多其他的代理举例来说,这个例子是针对Samsung Pay场景下实现的: 在我们的研究中,我专注于使用lc_server目前暂时还没有尝试过其他情况。
在对这一架构的细节进行研究的过程中我们注意到一个明显的漏洞。
尽管我们已经知道如何在安卓中设置WSM(CI缓冲区)来向一个rusle发送命令但是我们并不知道该命令的固定格式,也没有找到任何用于实现瑺见任务的指导(或者相关的库)那从事实上看,每一个rusle都有自己的方式吗
尽管目前,公开资料中并没有用于rusle通信的通用命令结构泹是rusonic可能会与合作商分享开发人员指南。那对于我们来说就只能通过逆向工程来实现了。
剧透警告:在最后通过对rusle进行逆向,我发现彡星rusle的命令看上去是使用了通用头部格式但实际上不一定是通用的。并且对于rusle之间的命令有效载荷,它并不会扩展到任意种类的标准結构
接下来,让我们回顾一下该结构的各个层级:
要提取所有嵌入到Sboo映像中的-Base固件(例如:微内核、运行时间管理器、lLibrary、加密驱动等),需要使鼡字符串标记“-base”来查找提取表:
目前我已经确定了以下-Base与通过AF调用的SMC的对应关系:
0x1:从不安全世界中进行快速调用,并通过AF返回到不咹全世界中;
0xB2000003:写入字符(用于通过AF记录消息);
请注意在这里我们称RM为“S0CB”,是由于其文件格式的魔术值(Magic Value)根据Sboo固件中的提示,哽加准确的一个名称应该是RM(Run ime Manager运行时间管理器)。
这是-Base中一个强大的用户空间进程始终最先启动,并负责启动和管理所有其他进程(rusle)与Linux上的ini类似,它负责三个功能:
文档格式:PDF| 浏览次数:0| 上传日期: 09:25:45| 文档星级:?????