联发科芯片Rootkit误差剖析(CVE-2020-0069)

宣布时间 2020-06-24

一、误差配景


2020年3月 ,谷歌修补了一个保存于联发科芯片中的清静误差(CVE-2020-0069) ,误差影响20余款联发科芯片和数百万Android装备。该误差保存于MediaTek Command Queue驱动(CMDQ下令行列驱动) ,允许外地攻击者实现对物理内存地址的恣意读写 ,从而导致权限提升。


二、受影响国产手机型号


Huawei GR3 TAG-L21

Huawei Y5II

Huawei Y6II MT6735 series

Lenovo A5

Lenovo C2 series

Lenovo Tab E7

Lenovo Tab E8

Lenovo Tab2 A10-70F

Meizu M5c

Meizu M6

Meizu Pro 7 Plus

Oppo A59 series

Oppo A5s

Oppo A7x -- up to Android 8.x

Oppo F5 series/A73 -- up to A.39

Oppo F7 series -- Android 8.x only

Oppo F9 series -- Android 8.x only

Oppo R9xm series

Xiaomi Redmi 6/6A series

ZTE Blade A530

ZTE Blade D6/V6

ZTE Quest 5 Z3351S


三、CMDQ驱动简析


DMA(直接内存会见)是允许专用硬件直接从主存储器(RAM)发送或吸收数据的一种特征。其目的是通过允许大内存会见而不过多占用CPU来加速系统。MediaTek Command Queue驱动(CMDQ下令行列驱动)允许从用户层与DMA控制器通讯 ,以实现媒体或显示相关的使命。


基于Redmi 6/6A 源代码剖析 ,在cmdq_driver.h头文件中 ,声明cmdq驱动的IOCTL挪用如下:


ku酷游(集团)官方网站


CMDQ_IOCTL_ALLOC_WRITE_ADDRESS指令为分派一个DMA缓冲区。

CMDQ_IOCTL_FREE_WRITE_ADDRESS指令为释放一个DMA缓冲区。

CMDQ_IOCTL_READ_WRITE_ADDRESS指令为读取一个DMA缓冲区中的数据。

CMDQ_IOCTL_EXEC_COMMAND指令运行发送其他下令。


1、分派历程


通过CMDQ_IOCTL_ALLOC_WRITE_ADDRESS挪用cmdqCoreAllocWriteAddress ()函数 ,分派一个DMA缓冲区 ,该函数要害代码实现如下:


ku酷游(集团)官方网站


然后 ,挪用cmdq_core_alloc_hw_buffer()函数分派DMA缓冲区 ,pWriteAddr->va是虚拟地址 ,pWriteAddr->pa为物理地址 ,两者逐一对应。并整理缓冲区。


ku酷游(集团)官方网站


最后 ,将物理地址赋值到*paStart ,并将pWriteAddr结构体添加到gCmdqContext.writeAddrList链表中。


2、执行下令历程


在CMDQ_IOCTL_EXEC_COMMAND挪用中 ,接纳cmdqCommandStruct结构体作为参数 ,结构体界说如下:


ku酷游(集团)官方网站


pVABase指向用户层存放下令的缓冲区 ,缓冲区巨细放在blockSize中。其中cmdqReadAddressStruct结构体界说如下:


ku酷游(集团)官方网站


DmaAddresses是要读取的物理地址 ,读取的值存放在values中。在CMDQ_IOCTL_EXEC_COMMAND下令的执行历程 ,实现代码如下:


ku酷游(集团)官方网站


函数挪用路径如下:


ku酷游(集团)官方网站


Cmdq_core_acquire_task()函数会将command绑定到task中执行。详细实现如下:


ku酷游(集团)官方网站


挪用cmdq_core_find_free_task()函数获取一个空闲task。拿到空闲task并举行一些初始化设置 ,然后最先挪用cmdq_core_insert_read_reg_command()函数执行下令。


ku酷游(集团)官方网站


该函数实现剖析 ,先拷贝用户层传入的下令到DMA缓冲区中。


ku酷游(集团)官方网站


pCommandDesc->pVABase是存放下令的内存起始地址� ?奖赐晗铝詈� ,后面分几种方法最后。


ku酷游(集团)官方网站

这里不做深究 ,最后拷贝EOC和JUMP指令最后。这里也是将用户层传入的下令拷贝过来。


ku酷游(集团)官方网站


从cmdq_core_acquire_task()函数中返回后 ,如下:


ku酷游(集团)官方网站


挪用cmdq_core_consume_waiting_list()函数执行task。先从期待行列中获取task。


ku酷游(集团)官方网站


然后 ,获取空闲内核线程。


ku酷游(集团)官方网站


最后 ,将task绑定到thread中去执行。


ku酷游(集团)官方网站


四、读写下令剖析


以cmdq_test.c测试代码为例 ,剖析明确一个完整的读写下令结构。cmdq驱动中界说了两类寄存器 ,一类是地址寄存器用于存放地址 ,一类是数值寄存器用于存放读取或写入的数值。


ku酷游(集团)官方网站


regResults是虚拟地址 ,挪用cmdq_core_alloc_hw_buffer()函数分派一个dma地址 ,regResultsMVA与之对应 ,然后设置regResults中的数据� W钕绕唇佣寥『托慈胂铝睿�


ku酷游(集团)官方网站


将regResults[0]的地址写入CMDQ_DATA_REG_DEBUG_DST类型的地址寄存器中。


ku酷游(集团)官方网站


然后 ,从CMDQ_DATA_REG_DEBUG_DST地址寄存器中读取数据并写入到CMDQ_DATA_REG_DEBUG数值寄存器中。这时间 ,CMDQ_DATA_REG_DEBUG数值寄存器中的值应该为0xdeaddead。


ku酷游(集团)官方网站


接着 ,将regResults[1]的地址转存到CMDQ_DATA_REG_DEBUG_DST地址寄存器中。


ku酷游(集团)官方网站


最后 ,将CMDQ_DATA_REG_DEBUG数值寄存器中的0xdeaddead写入到CMDQ_DATA_REG_DEBUG_DST地址寄存器中生涯的regResults[1]的地址中 ,即regResults[1]=0xdeaddead。判断regResults[0]和regResults[1]是否相等。


ku酷游(集团)官方网站


若是相等 ,说明读写乐成。


五、PoC剖析与测试


(1)PoC代码中 ,执行写操作的要害代码如下:


ku酷游(集团)官方网站


写入历程中 ,先将value[count]移动到CMDQ_DATA_REG_DEBUG数值寄存器中 ,然后将pa_address+offset地址移动到CMDQ_DATA_REG_DEBUG_DST地址寄存器中 ,最后将CMDQ_DATA_REG_DEBUG数值寄存器中的value写入到CMDQ_DATA_REG_DEBUG_DST地址寄存器中生涯的pa_address+offset地址中 ,即*(pa_address+offset)= value[count]。


(2)PoC代码中 ,执行读操作的要害代码如下:


ku酷游(集团)官方网站


读取历程中 ,第一步先将pa_address+offset地址移动到CMDQ_DATA_REG_DEBUG_DST地址寄存器中 ,然后从CMDQ_DATA__REG_DEBUG_DST地址寄存器中存储的地址pa_address+offset中读取数据放到CMDQ_DATA_REG_DEBUG数据寄存器中 ,再将dma_address+offset地址移动到CMDQ_DATA_REG_DEBUG_DST地址寄存器中 ,最后将CMDQ_DATA_REG_DEBUG数值寄存器中生涯的数据写入到CMDQ_DATA_REG_DEBUG_DST地址寄存器中存储的dma_address+offset地址中 ,即*(dma_address+ offset) = *(pa_address + offset)。


(3)在Reami6测试机中 ,执行PoC测试 ,乐成将Linux修改成minix。


ku酷游(集团)官方网站


参考链接:

[1]https://github.com/MiCode/Xiaomi_Kernel_OpenSource/tree/cactus-p-oss/drivers/misc/mediatek/cmdq

[2]https://github.com/quarkslab/CVE-2020-0069_poc/blob/master/jni/kernel_rw.c

[3]https://blog.quarkslab.com/cve-2020-0069-autopsy-of-the-most-stable-mediatek-rootkit.html

[4]https://forum.xda-developers.com/android/development/amazing-temp-root-mediatek-armv8-t3922213

[5]https://source.android.com/security/bulletin/2020-03-01



酷游官网起劲防御实验室(ADLab)


ADLab建设于1999年 ,是中国清静行业最早建设的攻防手艺研究实验室之一 ,微软MAPP妄想焦点成员 ,“黑雀攻击”看法首推者。阻止现在 ,ADLab已通过CVE累计宣布清静误差1000余个 ,通过 CNVD/CNNVD累计宣布清静误差800余个 ,一连坚持国际网络清静领域一流水准。实验室研究偏向涵盖操作系统与应用系统清静研究、移动智能终端清静研究、物联网智能装备清静研究、Web清静研究、工控系统清静研究、云清静研究。研究效果应用于产品焦点手艺研究、国家重点科技项目攻关、专业清静服务等。


ku酷游(集团)官方网站