欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

两个CVE案例分析:如何利用Android中的可信区域

来源:本站整理 作者:佚名 时间:2016-12-22 TAG: 我要投稿

本文将从实际出发,讲述如何一步步地利用Android中的可信区域(TrustZone)。这里我使用的是华为海思的可信执行环境(Trusted Execution Environment,TEE)。首先我找到了一个可以获得内核权限的漏洞,然后我又发现了一个可以在TEE中执行任意代码的漏洞。以上试验结果证明了在华为海思可信执行环境中任何本地应用都可以执行shellcode这一概念的可行性。
 
背景
“ARM®TrustZone®技术是一种针对各种客户端和服务器计算平台(包括手机,平板电脑,可穿戴设备和企业系统)的安全性的全系统方法。”使用可信区域技术开发的设备能够支持完整的可信执行环境。可信执行环境运行在一个被称作“安全模式”的特殊CPU模式上,这样安全模式使用的内存和安全函数就能够对正常使用环境隐藏自身。通过这种方式,Android的开发商可以提供种类丰富的安全功能,比如指纹识别、数字版权管理(DRM)、内核保护、安全启动等等。你可以在可信区域的官方网站或者探索genode.org来获取更多的信息。
华为海思的可信执行环境符合最近的全球可信执行环境平台规范,但是它的实现却完全没有文档依据可循。通过逆向它的固件,一些日志文件让我大致理解了它的架构:

下面就上图做简要说明:
TZDriver “ev/tc_ns_client”是一个内核级驱动,它给用户空间的客户端与可信执行环境之间的通信提供了接口,就如同高通安全可执行环境(QSEE)中的“/dev/qseecom”一样。两者唯一的区别在于,在使用华为海思芯片的mate7上每个本地应用都能够访问TZDriver,而高通的qseecom只能被一部分系统进程访问到。
TA是Trusted Application即可信任应用程序的缩写,它是elf格式的文件。每个可信应用程序都提供了与安全相关的服务,比如安全存储(TA_SecStorage)、安全启动、密钥存储(原文为keystone,应为key store之误,译者注)、指纹识别(TA_FingerPrints)等等。
TEEGlobalTask 是可信执行环境的用户模式下第一个可信任应用程序。它能够加载elf模块,能够将外部调用调度至其他可信任应用程序的子服务。
RTOSck是可信执行环境的核心,它是华为自主研发的实时操作系统,跟uC/OS-II有些类似。RTOSck还包含了指纹识别驱动,它只能通过TA_FingerPrints来访问,以此从设备传感器上读取指纹图像。
 
CVE-2015-4421:存在于/dev/tc_ns_client中的漏洞
安全监视器调用(SMC)主要用于进入安全监视器模式并执行安全监视器内核服务调用。 该指令只能在特权模式下执行。 所以如果用户进程试图向安全区域发送畸形的SMC来利用可信执行环境,那么它首先必须获得内核级别的权限。
“/dev/ tc_ns_client”是一个内核驱动程序,它能够为用户空间的客户端和其他内核模块提供ioctl接口。 客户端使用其“TCAPI”与安全区域进行通信。 驱动程序的文件权限是“rw-rw-rw-”,其SE上下文为“u:object_r:device:s0“。用户模式下的任何客户端都可以访问此驱动程序。
客户端使用TC_NS_ClientParam 结构体向驱动程序发送缓冲区指针,然后驱动程序向可信执行环境请求安全监视器调用,并将返回的值复制给TC_NS_ClientParam中的指针。
以下是TC_NS_ClientParam结构体的代码:
typedef union {
struct {
unsigned int buffer; //ptr of buffer
unsigned int offset; //size of buffer
unsigned int size_addr;
} memref;
struct {
unsigned int a_addr; //ptr of a 4-bytes   buffer
unsigned int b_addr; //ptr of a 4-bytes   buffer
} value;
} TC_NS_ClientParam;
然而,驱动程序在边界检查中犯了一个错误。 伪代码如下:
static int TC_NS_SMC_Call(TC_NS_ClientContext
*client_context,TC_NS_DEV_File   *dev_file, bool is_global){
....
// 建立 TC_NS_SMC_CMD 结构体
....
// 执行 SMC 指令
TC_NS_SMC(smc_cmd_phys);
// 复制 smc_cmd.operation_phys的结果给调用者
buffer(client_param.value)
if(client_operation->params[0].value.a>   0xbfffffff){
//driver think caller is from kernel space
*(u32 *)client_param->value.a_addr =   operation-
>params[i].value.a;
}
else{
//driver think caller is from user space
copy_to_user(....);
}
if(client_operation->params[0].value.b   > 0xbfffffff){
*(u32 *)client_param->value.b_addr =   operation-
>params[i].value.b;
}
else{
copy_to_user(....);
}
....
}
如果我们在用户模式发送内核指针会怎么样? 驱动程序将直接复制结果而不使用copy_to_user。所以我们就有机会给内核空间写入一个给定的值。如果可信执行环境返回的值低于0xc0000000,我们就可以通过“ret2user”获得root权限。
具体步骤如下图所示:

我选择可信执行环境系统的内部时间作为给定的返回值。可信执行环境中的全局服务提供了时间查询接口:cmd_id =“GLOBAL_CMD_ID_TEE_TIME”。
以下是“main_task”中的伪代码。
int get_sys_time()
{
int result; // r0@1
tag_TC_NS_Operation *v1; // r3@1
unsigned int v2; // [sp+0h] [bp-10h]@1
int v3; // [sp+4h] [bp-Ch]@1

[1] [2]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载