高通启动链的研究进展如何?有哪些关键点值得关注?
摘要:之前了解到移动安全之后陆续看了各个平台的soc的安全漏洞,包括mtk unisoc qualcomm kirin 还有apple的一些经典漏洞。在说qualcomm之前我先把之前一点点微小的工作总结一下吧。 然后我是研究了kirin的boo
之前了解到移动安全之后陆续看了各个平台的soc的安全漏洞,包括mtk unisoc qualcomm kirin 还有apple的一些经典漏洞。在说qualcomm之前我先把之前一点点微小的工作总结一下吧。
然后我是研究了kirin的bootrom复现了checkm30,然后在别人的帮助下搞定了新批次利用了xloader的漏洞,然后就卡住了就放弃了,然后复现紫光的bootrom的两个漏洞(一个证书里面缓冲区溢出造成了永久安全启动和临时安全启动绕过,因为这个验证既在download模式存在也在普通模式存在),然后一个download模式的任意写入和缓冲区溢出(因为是真的物理意义的不验证),后来unisoc的bsp源码在github上有泄露所以通过审计源码得到了紫光有名的bsp漏洞也是永久安全启动绕过。
然后自己当时就开始装(还是太菜感觉),这几个复现也没有记录。然后我就开摆了精神状态太差了啥也弄不动x(其实是自己菜),当然前面我们研究的都是早期的启动链比如bootrom或者第一级的loader,所以说地址空间基本是RWX的,而且栈地址是固定的,所以说随便找一段空间就可以放shellcode然后直接溢出到栈地址是没啥含金量的,但是当时我太得瑟了(再次说明自己菜)。尤其是所谓checkm30,只能说是高一时候看到那个文章感觉很厉害所以留下了一点幻想对吧。
当然这里后续打算弄一个紫光完整一点的工具(spd_dump已经很好了),。
后来大概是25年8-9月的时候有人让我研究一下mtk,mtk确实是漏洞研究很好的平台,mtkclient利用了一个usb协议里面的bootrom漏洞,这个漏洞原理还没有复现(没有看bootrom去确认),还利用了一个gcpu和dma里面的漏洞,大概是说mtk下载模式有一个方式可以通过usb发送写入的地址在指定的地址写入内容,但是有一个白名单,只能写白名单的(也可能是黑名单),然后可以写入gcpu或者dma的映射的地址,然后利用这个额外的硬件去在任意的地址写入内容。然后mtk的启动链就是bootrom->preloader->gz->lk->kernel,preloader呢校验lk,bootrom和preloader下面有下载模式,但是bootrom的下载模式可以通过efuse屏蔽,所以之前的bootrom漏洞就失效了。当时有一个比较好的github项目,是修补lk的。
我当时一看!woc lk可以修补?然后逆向preloader加上一份leak的preloader源码我就发现如果sec policy允许在seccfg解锁情况下不校验lk,那么lk就可以随便修改,大多数机子都是可以这样做的除了小米啥的。
这样就实现了修补LK实现解锁bootloader,然后后面就有fenir漏洞,就是说有一些机子的preloader的sec policy有问题,即使seccfg锁定也不校验下一级!然后MTK在新一点的soc preloader的下一级是BL2_EXT而BL2_EXT在EL3,所以说我们不需要去利用一个任意代码执行漏洞去解锁seccfg就可以以EL3权限执行任意代码!
后面呢,新一点的soc修补了bootrom漏洞,而且变成V6的协议了。
这里面MTK在下载模式下是bootrom/preloader->DA1->DA2
BOOTROM没有漏洞了,BOOTROM有sla,也就是如果sla开启,那么进行usb发送命令之前要先通过RSA鉴权。
而SBC是安全启动状态,如果SBC off那么就没有啥验证,当然还有一个DAA,DAA开启在V5时候要发auth文件,但是V6时候好像又不需要了
另外呢在V6的DA2中,额外加了一个DA SLA验证,这个BROM SLA不一样,是DA2进行这样一个验证,而且OEM可能魔改DA2.
所以说只能考虑PRELOADER漏洞,PRELOADER模式下是没有SLA的,也就是只要求DA1通过签名验证
那么preloader呢我一下子想起了MOSEC2022讲到的preloader漏洞
也就是preloader的write/read命令会检查白名单/黑名单,但是判断时候是直接拿地址+长度这样判断,可以溢出就可以绕过这个检查
https://0rd1r3hv.github.io/posts/getting-your-phone-unlocked/
然后有这一篇很好的文章
也就是说我们只要起始地址设置的大一点就可以避开堆栈实现任意写入,但是从0地址开始写!
这个漏洞当时我觉得没法利用呢因为我担心写到0地址bootrom地址会crash
但是呢和qualcomm和华为不一样,我们写入rom的区域会自动忽略不会崩溃!这样我们可以直接把g_da_verified给改成1!
但是呢,这个漏洞肯定早就修复了,所以说preloader还有另一个漏洞是先读入da然后才检查da的长度,所以说还是有溢出,然后呢da_addr是固定的高地址应该是在这个dram的所以说我们可以覆盖后面的内容,但是这样要写很大的内容。
这样我们可以加载任意的DA1
但是这个漏洞早就修复了
于是我们想到DA1加载DA2是怎么验证签名的呢?
这里面就根据mtkclient的代码来确定DA的加载地址偏移量什么的
我打开一看,啊,da1通过sha256来验证DA2,也就是DA1和DA2是绑定在一起的!
但是啊,我们DA2的加载地址是没有检查的!
也就是说我们可以直接覆盖栈地址或者是覆盖DA1里面的sha256这样就可以加载任意的DA2!!!
然后我发现mtkclient里面实际上有一个神秘漏洞carbonara一直没有公开,但是关于漏洞检测的代码实际上早就有了,我一对比,就是这个地方!
然后呢mtkclient是怎么实现解锁的呢?这个就很厉害了,他是从DA2基础上再启动一个DA extension,通过DA extension注册额外的一些命令,比如说自由读写 写入RPMB,计算seccfg的密钥。seccfg是通过加密引擎计算出一段哈希,也就是分区头是明文后面跟着一段硬件密钥生成的哈希用来验证,mtkclient最厉害的地方在于它把sej加密引擎逆向出来了。然后调用这些和加密引擎交互的函数来生成seccfg的哈希。
这里我就在想啊,逆向水平再高逆向出这些几乎是不可能的!如果没有leak的源代码,几乎是不可能的
后来看到bkerler的存储库里面有这个gcpu的源码,我大概就明白了,实际上那些研究出来很强大的漏洞的大佬很多情况下也是要参照leak的源代码的比如说checkm8。再者说看源码也没什么。所以说某些人发的所谓自己逆向出来水平才是真的高我觉得还是不大对啊。为什么要限制住自己呢。只不过由于法律原因很多人都喜欢说是逆向出来的,实际上有没有内部资料和leak谁也不知道。
carbonara我发现之后呢,我加了一个tg群(roger大佬的),然后呢他们也发现了这个carbonara,后来他们就去写了这个利用,当时一些国内刷机圈的也在弄,最开始我还是想弄一个的后来太摆了就搁了(还是自己太菜
这样我们得到了一个隐藏了几年奇美拉等工具圈了很多年钱的神秘漏洞,原来一点也不复杂啊。
但是mtk不傻啊,这个漏洞其实24年就修复了,但是呢很多厂商用的旧DA所以漏洞一直在。后来到天玑9300开始DA的初始版本都修复了carbonara。但是奇美拉还是有办法。
我就想着有没有什么溢出,刚好bkerler说v6的xml解析的地方有一处漏洞,然后我看了,但是我走偏了。我想的是看xml协议解析器有没有漏洞,实际上那块太复杂了逆向不出来(还是水平不够哈
后来还真发现了疑似1byte的堆溢出
但是问题来了,我不清楚mtk的堆分配器,是不是和glibc的一样,而且glibc的堆溢出我都不会利用
逆向那个alloc函数我也没看懂。
所以说我当时几乎搁了,但是当时看到一个set allinone signature的命令里面好像在xml解析器的上层还有一个溢出,当时我就想着是这个地方(后来的确这里有一个漏洞但是很难利用),但是呢我不会堆溢出就放弃了。
后来呢我看到了usb数据处理的地方有一个问题就是边界条件(尺寸大小的判断)只用等号判断,也就是我某一次发一个不标准的数据包有可能可以溢出。但是呢我以为一次只接受这个<=64bit的数据包,实际上这里我没有分清楚哪个是主机给设备发的哪个是设备给主机发的。所以就彻底放弃了。
当然了,前一段时间,roger完整复现了这个usb数据处理的漏洞,并且告诉我们xml溢出的漏洞利用不了因为xml协议不能写入00。
这就是大名鼎鼎的heapb8,我们利用堆溢出可以覆盖这个指针表从而实现一个代码执行(好像是,不确定)
这个漏洞我还一直没有再去复现,还是太懒了,以后还是要复现一下。
接着一个问题就是,虽然说preloader在seccfg解锁情况下大多数不校验lk比如华为,但是也有校验的比如xiaomi ov
那么还有什么办法解锁呢?
preloader校验lk等下一级固件的时候有没有漏洞呢?
有三个漏洞在23年5月被上报了
一个漏洞是固件的固件头这里可以溢出好像是溢出0x200字节刚好可以覆盖安全启动状态(一整套都可以覆盖掉比如说secboot啥的) 但是我们需要一个固件来实施溢出,因为这个溢出好像是先确定要不要验证之后才加载的,所以说可能不能直接让当前的固件跳过验证,如果是lk先验证,那么我只能修补gz了。修补gz在里面加上shellcode来patch lk
还有两个漏洞是证书验证里面的漏洞,一个是逻辑漏洞,能够构造一个恶意证书绕过签名检查
一个是缓冲区溢出,这两个看起来比较复杂一直没看。
但是这些漏洞一直没来得及复现,所以说后面还是复现一下。
一个新问题来了,如果这个漏洞也修复了怎么办呢?我看到一些ov的解锁好像是有一些特殊的preloader不验证lk之类的。
另外呢现在有一个新项目,是patch preloader!
这个就很奇怪了,难道这些设备没有正确熔断吗?按理来说bootrom会验证preloader的签名。当然也有可能这里有漏洞。
另外呢,还有一些早期mtk的漏洞,就是早期lk没有使用avb的时候,加载boot镜像里面是有漏洞的,修复之后还有一个是lk的加载地址在内核地址之后的,所以可以制造一个恶意的内核来覆盖LK本身。
再就是fastboot也就是lk里面usb处理相关的以及一些命令是有缓冲区溢出的,比如说roger发的例子。
这里面还要再看。而且高通也有很多这样的
所以说mtk有很多东西要看和复现。
MTK我研究了这些之后呢,我感觉是啥也不会。(这样还有人觉得我mairuo也是没谁了...
接下来就该来到高通了,高通其实一直觉得比较安全是没啥漏洞的。
但是呢24年底的时候移植linux的一小点经历让我对老高通的启动流程有一点了解,PBL(bootrom)->SBL1->LK/TZ->KERNEL
而那时候高通的SBL1和9008的firehose都是运行在EL3的。
而且都是正常的ELF文件
当时也没想着研究什么高通漏洞,只是早期华为使用高通soc的设备没有开启安全启动,所以可以直接加载任意的SBL1.甚至还可以在msm8916上开启KVM(qhypstub)
然后后来...
UEFI来了...
然后,我就放弃了高通。
所以说这次研究高通纯粹是被人拉来研究的,而且整个过程非常的抽象。(bushi)
所以说呢对于高通启动链的研究下一期我再说...
毕竟我的水平有限,发出来目的纯粹是记录,当然也不能排除有一点想被别人看到的想法(
所以说我只能研究出一点东西请大家见谅,如果谁有更好的思路和方案都是欢迎交流的,而且如果正常的交流事先有说明的话我也不会到处乱说,前提是你不能耍我(比如某人)
