联发科芯片Rootkit漏洞CVE-2020-0069的分析是怎么样的


联发科芯片Rootkit漏洞CVE-2020-0069的分析是怎么样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家免费云主机域名详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。2020年3月,谷歌修补了一个存在于联发科芯片中的安全漏洞(CVE-2020-0069),漏洞影响20余款联发科芯片和数百万Android设备。该漏洞存在于MediaTek Command Queue驱动(CMDQ命令队列驱动),允许本地攻击者实现对物理内存地址的任意读写,从而导致权限提升。Huawei GR3 TAG-L21Huawei Y5IIHuawei Y6II MT6735 seriesLenovo A5Lenovo C2 seriesLenovo Tab E7Lenovo Tab E8Lenovo Tab2 A10-70FMeizu M5cMeizu M6Meizu Pro 7 PlusOppo A59 seriesOppo A5sOppo A7x — up to Android 8.xOppo F5 series/A73 — up to A.39Oppo F7 series — Android 8.x onlyOppo F9 series — Android 8.x onlyOppo R9xm seriesXiaomi Redmi 6/6A seriesZTE Blade A530ZTE Blade D6/V6ZTE Quest 5 Z3351SDMA(直接内存访问)是允许专用硬件直接从主存储器(RAM)发送或接收数据的一种特性。其目的是通过允许大内存访问而不过多占用CPU来加速系统。MediaTek Command Queue驱动(CMDQ命令队列驱动)允许从用户层与DMA控制器通信,以实现媒体或显示相关的任务。基于Redmi 6/6A 源代码分析,在cmdq_driver.h头文件中,声明cmdq驱动的IOCTL调用如下:(1)CMDQ_IOCTL_ALLOC_WRITE_ADDRESS指令为分配一个DMA缓冲区(2)CMDQ_IOCTL_FREE_WRITE_ADDRESS指令为释放一个DMA缓冲区(3)CMDQ_IOCTL_READ_WRITE_ADDRESS指令为读取一个DMA缓冲区中的数据(4)CMDQ_IOCTL_EXEC_COMMAND指令运行发送其他命令1、 分配过程通过CMDQ_IOCTL_ALLOC_WRITE_ADDRESS调用cmdqCoreAllocWriteAddress ()函数,分配一个DMA缓冲区,该函数关键代码实现如下:然后,调用cmdq_core_alloc_hw_buffer()函数分配DMA缓冲区,pWriteAddr->va是虚拟地址,pWriteAddr->pa为物理地址,两者一一对应。并清理缓冲区。最后,将物理地址赋值到*paStart,并将pWriteAddr结构体添加到gCmdqContext.writeAddrList链表中。2、 执行命令过程在CMDQ_IOCTL_EXEC_COMMAND调用中,采用cmdqCommandStruct结构体作为参数,结构体定义如下:pVABase指向用户层存放命令的缓冲区,缓冲区大小放在blockSize中。其中cmdqReadAddressStruct结构体定义如下:DmaAddresses是要读取的物理地址,读取的值存放在values中。在CMDQ_IOCTL_EXEC_COMMAND命令的执行过程,实现代码如下:函数调用路径如下:Cmdq_core_acquire_task()函数会将command绑定到task中执行。具体实现如下:调用cmdq_core_find_free_task()函数获取一个空闲task。拿到空闲task并进行一些初始化设置,然后开始调用cmdq_core_insert_read_reg_command()函数执行命令。该函数实现分析,先拷贝用户层传入的命令到DMA缓冲区中。pCommandDesc->pVABase是存放命令的内存起始地址。拷贝完命令后,后面分几种方式结尾。这里不做深究,最后拷贝EOC和JUMP指令结尾。这里也是将用户层传入的命令拷贝过来。从cmdq_core_acquire_task()函数中返回后,如下:调用cmdq_core_consume_waiting_list()函数执行task。先从等待队列中获取task。然后,获取空闲内核线程。最后,将task绑定到thread中去执行。以cmdq_test.c测试代码为例,分析理解一个完整的读写命令构造。cmdq驱动中定义了两类寄存器,一类是地址寄存器用于存放地址,一类是数值寄存器用于存放读取或写入的数值。regResults是虚拟地址,调用cmdq_core_alloc_hw_buffer()函数分配一个dma地址,regResultsMVA与之对应,然后设置regResults中的数据。开始拼接读取和写入命令:将regResults[0]的地址写入CMDQ_DATA_REG_DEBUG_DST类型的地址寄存器中。然后,从CMDQ_DATA_REG_DEBUG_DST地址寄存器中读取数据并写入到CMDQ_DATA_REG_DEBUG数值寄存器中。这时候,CMDQ_DATA_REG_DEBUG数值寄存器中的值应该为0xdeaddead。接着,将regResults[1]的地址转存到CMDQ_DATA_REG_DEBUG_DST地址寄存器中。最后,将CMDQ_DATA_REG_DEBUG数值寄存器中的0xdeaddead写入到CMDQ_DATA_REG_DEBUG_DST地址寄存器中保存的regResults[1]的地址中。即regResults[1]=0xdeaddead。判断regResults[0]和regResults[1]是否相等。如果相等,说明读写成功。(1)PoC代码中,执行写操作的关键代码如下:写入过程中,先将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代码中,执行读操作的关键代码如下:读取过程中,第一步先将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。看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注云编程开发博客行业资讯频道,感谢您对云编程开发博客的支持。

相关推荐: 如何用Akamai保护网站免受MAGECART的威胁

第三方脚本的兴起现代Web应用程序越来越依赖于在浏览器中执行来自于外部的服务和供应商的JavaScript代码,这些代码通常被称为第三方脚本。作为如下所示的示例,Akamai执行了许多脚本来构建我们的主页。这些脚本中有将近70%来自外部资源。www.Akama…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

Like (0)
Donate 微信扫一扫 微信扫一扫
Previous 02/05 08:50
Next 02/05 08:55