首页
社区
课程
招聘
[原创]usbliter8--新型iPhone BootROM漏洞
发表于: 4天前 1124

[原创]usbliter8--新型iPhone BootROM漏洞

4天前
1124

一个新的BootROM漏洞,称为usbliter8,影响由A12、S4/S5和A13 SoC驱动的苹果设备。该漏洞利用了Synopsys DWC2 USB控制器中的硬件层面漏洞和固件配置缺陷,导致整个应用处理器启动链被破坏,且由于BootROM代码的不可变性,无法进行软件补丁。

该漏洞由Paradigm Shift的研究人员披露,源自DWC2 USB控制器处理连续USB设置包的方式。

漏洞分析

下面根据该团队blog内容和个人理解进行分析:

该利用同时依赖两个点:一个是 USB 控制器里的硬件级缺陷,另一个是设备固件里的特定配置问题。  

USB Setup 包的结构  

iPhone 进入 DFU 模式( Device Firmware Update,设备固件恢复模式 )时,会通过 USB 和电脑通信。USB 控制传输必须先从一个 Setup transaction 开始。主机通过它向 USB 设备发请求。一个标准的 Setup transaction 由两部分组成:先发一个 TOKEN 包,说明这是 SETUP 请求;然后发一个 DATA 包,DATA 包里有 8 字节的 USB Device Request。按照 USB 规范,这个数据载荷必须正好是 8 字节,并且格式严格。设备的软件驱动最终收到的,就是这 8 字节的请求结构。后文为了方便,把这个 8 字节载荷称为“Setup packet”。  

(1) TOKEN PACKET                                             host → device
┌───────┬──────────┬─────────┬─────────┬────────┬──────┐
│ SYNC  │   PID    │  ADDR   │  ENDP   │  CRC5  │ EOP  │
│ 8 bit │  8 bit   │  7 bit  │  4 bit  │  5 bit │      │
│       │ (SETUP)  │ device  │endpoint │        │      │
└───────┴──────────┴─────────┴─────────┴────────┴──────┘

(2) DATA PACKET                                              host → device
                   ┌────────────────────────┐
┌───────┬──────────┤   DATA  (8 bytes)      ├────────┬──────┐
│ SYNC  │   PID    │  = USB Device Request  │ CRC16  │ EOP  │
│ 8 bit │  8 bit   │                        │ 16 bit │      │
│       │ (DATA0)  │ This is what the USB   │        │      │
└───────┴──────────┤    driver receives     ├────────┴──────┘
                   └────────────────────────┘

DWC2 USB 控制器和 DMA

Apple SoC 使用的是 Synopsys 的 DWC2 USB 控制器。这个控制器可以通过 DMA 把 USB 收到的数据直接写进主内存。应用处理器会先分配一块内存缓冲区,然后把这块缓冲区的物理地址写进 USB 控制器的 DOEPDMA 寄存器。之后,控制器收到 SETUP 或 OUT 包时,就会把数据写入这块缓冲区。而这里有一个关键细节:USB 控制器写完数据后,会直接递增 DOEPDMA 里的地址值,也就是说这个寄存器不只是初始化配置,还是“下一次 DMA 写入地址”的来源。  

漏洞点

DWC2 控制器会在内存里保存最多 3 个连续的 Setup packet。正常情况下每个 Setup packet 是 8 字节,所以 3 个就是 24 字节。当收到第 4 个 Setup transaction 时,控制器会把 DMA 基址重置回最开始的位置,类似一个环形缓冲区。问题在于:控制器每收到一个包后,会按实际写入长度递增 DOEPDMA,但重置时却固定减去 24。更糟的是,控制器也接受小于 8 字节的包,虽然内部按 4 字节粒度保存。这样一来,“递增的量”和“回退的 24 字节”对不上,就形成了一个按 12 字节步进的 buffer underflow 写原语

设计者以为:
3 个包 = 8 + 8 + 8 = 24 字节
第 4 个包来时,地址减 24,刚好回到开头。
实际攻击者可以构造:
3 个短包 = 4 + 4 + 4 = 12 字节
第 4 个包来时,地址仍然减 24,
结果不是回到开头,而是倒退到缓冲区前面,就造成了缓冲区溢出。



不过能否利用,还取决于设备固件怎么配置。A12 和 A13 的 SecureROM 被确认可利用;A11 不行,因为 A11 的 USB 驱动会在每次收到包后手动把 DMA 地址重置回初始值。A12/A13 上 USB DART 被配置为 bypass 模式,所以攻击者可以通过 DMA 自由覆盖 SRAM 数据;A14 及之后的芯片正确配置了 DART,因此该漏洞变得不可利用。  

漏洞利用

总体上是先通过溢出原语,覆盖PC,然后提权到EL1,注入自定义的USB handler,实现临时降低 SoC 的 production mode,和启动未经签名检查的 raw iBoot 镜像。我这里仅做大致分析,想更深入细节的可以继续看原博客和poc,我放在文末了。

在A12上利用

A12 上比较直接。USB 控制器的 DMA 缓冲区分配在堆上,而它的位置正好靠近 USB 任务的栈。攻击者可以利用前面的 underflow 写能力,覆盖栈上保存的 LR ( Link Register,ARM 架构里常用于保存函数返回地址  ),也就是函数返回地址。等调度器把上下文切回 USB 任务时,被篡改的 LR 会影响程序流,然后就可以控制执行流。

A13上为什么更复杂

A13 引入了 PAC,Pointer Authentication Code,指针认证( 它会给函数指针、返回地址等加认证码,防止攻击者随便改指针  )。这里 PAC 主要作用在保存在栈上的 LR 上,这已经足够阻止 A12 那种直接改 USB 任务保存 LR 的方法。除此之外,A13 还要绕过堆元数据校验、上下文切换时的 LR 签名等机制。

这里的做法是分阶段推进:先覆盖 USB DMA 缓冲区前面的 DART 相关堆对象,由此获得非常有限的写能力;再借助清理流程,把 DART 分配的全局指针清零,避免损坏的堆对象被释放时触发 checksum panic;接着篡改 panic 计数器,让下一次 panic 不重启设备,而是进入死循环。那么系统虽然进入异常状态,但中断还能运行,USB 控制器也仍然能继续写内存。

随后还需要避免破坏 USB 任务的上下文,尤其是 LR 和 SP。做法是控制 DMA 写入时机,让写入发生在 USB 任务处于运行状态时,这样任务让出 CPU 时会把正确的寄存器值重新保存回任务结构。最后,继续利用内存写能力,覆盖 BSS 里的 USB IRQ handler 函数指针。中断触发时,系统会调用被覆盖后的 handler,然后就可以劫持控制流了。

为什么还要提权到 EL1

从 A12 开始,SecureROM 大部分时间运行在 EL0,也就是非特权执行级别。因此即使获得代码执行,也不能直接访问 MMU 表、ROM 元数据,或者 SCTLRTTBR 这类特殊 CPU 寄存器。SecureROM 里存在少数通过 SVC 0 切到 EL1 的位置。研究者选择了一个把执行权转交给下一阶段 iBoot 的函数位置,因为那里会短暂进入 EL1,然后继续执行启动跳板逻辑。

A12 / S4 / S5 的后利用方式

这些芯片的 SecureROM 里没有 PAC,所以可以通过破坏栈上的 LR 来做 ROP。所以链条很小:先写 USB MMIO 改变 DMA 目的地址,然后等待一小段时间,让 DMA 把 shellcode 写进 boot trampoline 区域,最后跳到特定的 SecureROM 代码位置。虽然 boot trampoline 所在内存正常情况下不可从 EL0 写入,但 DMA 可以绕过 CPU 视角下的写保护。

这里还有一个编译器行为带来的“幸运点”:某个状态检查使用了保存在栈上的 X24,而栈已经被攻击者控制,所以可以绕过中间跳转检查。拿到 EL1 权限后,可以恢复原始 boot trampoline、修复被破坏的堆分配、注入自定义 USB 控制请求处理器、在 USB 序列号中加入 PWND 字符串,并修复 USB 任务栈帧,使系统回到 DFU 模式,但此时 DFU 已经带有攻击者的扩展处理逻辑。

自定义 USB handler

注入的 handler 会把普通 DFU 请求转发给原 handler,同时增加两个自定义能力:一是临时降低 SoC 的 production mode,也就是 demotion;二是允许启动未经签名检查的 raw iBoot 镜像。blog里最初直接从 handler 调用跳转函数时失败了,因为跳转函数会关闭包括 USB 在内的一些硬件组件,而当前代码正运行在 USB 任务里。最终做法是改主任务栈上的返回地址,然后关闭 DFU session,让 USB 任务退出,由主任务被唤醒后跳到目标位置。

A13 的后利用方式

A13 因为 PAC 更难,不能简单 ROP。不过 boot trampoline 区域位于 BSS 和堆之间,攻击过程中可以被写入受控数据。这里找到一个合适的 gadget,让受控参数进入关键寄存器,并借助认证分支指令的配置缺陷完成跳转。文章提到,固件大量使用 authenticated branch 指令,但实际只有 IB key 启用,那么就更方便利用。

A13 的清理更难,所以直接选择 重启 SecureROM,让它重新初始化大部分状态。为了让修改在重启后仍然保留,需要把 ROM 复制到 SRAM 末尾,并配置 MMU,让复制到 SRAM 的代码仍映射到 ROM 期望的虚拟地址。之后还要 hook ROM 的页表生成逻辑,防止 ROM 自己切页表时破坏映射。最终打了这么几个补丁:缩小 load area,强制回到 DFU,hook USB 序列号生成以加入 PWND,以及注入 USB 请求处理器。

总结

usbliter8 说明即使是比较新的 SecureROM,有 PAC 这样的保护,但是细微的硬件缺陷仍可能被利用,从而获得完整代码执行并破坏启动信任链。BootROM 级漏洞影响很大,因为它处在设备启动链的根部,而且不可修改。不过 Apple 的 SEP,也就是 Secure Enclave Processor,仍然是用户数据和攻击者之间的额外安全边界;usbliter8 本身不直接影响 SEP,但会打开更多进一步攻击 Secure Enclave 的可能路径。  


原团队blog: 297K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3M7#2)9J5k6i4c8U0i4K6u0r3M7r3q4Y4k6i4y4Q4x3V1k6T1L8r3!0Y4i4K6u0V1N6i4y4T1L8r3W2@1k6i4t1^5i4K6u0W2K9s2c8E0L8l9`.`.

PoC: 253K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6H3M7X3c8Y4L8i4y4Z5K9h3k6@1i4K6u0r3N6i4y4T1L8r3W2@1k6i4t1^5



[招生]科锐逆向工程师培训(2026年7月3日实地,远程教学同时开班, 第56期)!

最后于 4天前 被h01mes编辑 ,原因:
收藏
免费 0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回