Google Project Zero KASLR被动绕过研究:线性映射静态特性分析
引言
在内核安全防护体系中,内核地址空间布局随机化(KASLR,Kernel Address Space Layout Randomization)一直被视为防范内核级攻击的重要缓解措施。然而,近期Google Project Zero团队发布的研究揭示了一个令人担忧的事实:在arm64架构上,KASLR的防护效果远未达到预期。更确切地说,研究表明即使在启用了KASLR的系统中,攻击者仍然能够通过被动观察系统行为而非主动攻击来获取精确的内核基址信息。
这篇研究文章的独特之处在于,它不依赖于传统的漏洞利用技术,而是深入分析系统架构层面的固有缺陷。这种被动信息泄露方式在现实世界中更难检测和防护,因为它利用的是系统设计的内在特性,而非安全漏洞。
arm64架构下线性映射的静态特性
线性映射基本原理
在Linux内核中,线性映射(Linear Mapping)是内核虚拟地址空间中一个直接映射物理内存的区域。理论上,这个区域应该在虚拟地址空间中被随机化放置,以防止攻击者预测物理地址到虚拟地址的转换。然而,研究发现Linux内核在arm64架构上存在一个关键的设计缺陷。
在arm64架构上,Linux内核使用以下宏来计算线性映射的虚拟地址:
#define phys_to_virt(x) ((unsigned long)((x) - PHYS_OFFSET) | PAGE_OFFSET)
其中,PAGE_OFFSET在Android的39位虚拟地址空间上固定为0xffffff8000000000,而PHYS_OFFSET通过memstart_addr变量确定。关键问题在于:memstart_addr在现代arm64系统上不再是随机化的变量。
内存热插拔与随机化的矛盾
Linux内核开发者面临一个架构设计挑战:内存热插拔功能(CONFIG_MEMORY_HOTPLUG=y)的需求与线性映射随机化之间的矛盾。由于Android在arm64平台上使用4KiB页面大小和3级分页,虚拟地址空间被限制在39位。这与使用4级分页和48位虚拟地址空间的x86-64桌面系统形成鲜明对比。
为了支持未来可能的大容量内存热插拔,内核开发者选择将线性映射放置在虚拟地址空间的最低可能位置。然而,这种设计决策导致线性映射在虚拟地址空间中的位置变得可预测。研究表明,Linux内核团队在commit 1db780bafa4c后,正式放弃了arm64 Linux内核中线性映射的虚拟地址随机化支持。
静态地址计算方法与实际案例
Pixel设备上的物理地址固定问题
问题不仅限于虚拟地址空间的静态化。在Google Pixel设备上,内核引导程序每次都以相同的物理地址0x80010000解压缩内核。这一发现特别重要,因为:
- 物理地址的可预测性:不同于许多其他设备(如Samsung S25)会随机化内核的物理加载位置,Pixel设备始终将内核加载到固定的物理地址
- 静态转换计算:结合线性映射的静态特性,这意味着内核符号的虚拟地址可以通过简单计算得到
实际攻击场景:modprobe_path案例
研究中的实际演示清晰展示了这种攻击方法的有效性。研究人员通过以下步骤成功计算并访问了modprobe_path字符串的内核虚拟地址:
- 符号偏移计算:从
/proc/kallsyms获取modprobe_path和_stext的内核符号地址
- 物理地址推导:通过内核基址
0x80010000加上符号偏移得到物理地址
- 虚拟地址计算:使用
phys_to_virt(0x81ff2398)计算对应的线性映射虚拟地址
- 验证访问:通过BPF辅助函数直接读取计算出的虚拟地址,确认内容正确
关键发现是,在Pixel设备上,modprobe_path将始终可在内核虚拟地址0xffffff8001ff2398处访问,无论KASLR是否启用。
技术实现细节
这种攻击方法的技术优势在于其计算的简单性和可预测性。研究表明,在Pixel设备上,攻击者可以简单地使用硬编码的静态内核基址0xffffff8000010000来替代传统上需要泄露的KASLR滑动值。
更重要的是,线性映射内存对于内核数据区域(如.data段)具有读写权限,这为攻击者提供了强大的任意读写原语。虽然.text区域在这种情况下不可执行,限制了ROP(Return-Oriented Programming)攻击的可行性,但任意读写能力对于大多数内核攻击场景已经足够。
对物理地址随机化设备的影响分析
跨设备的技术适用性
虽然Pixel设备上内核物理地址的固定化使得攻击特别简单,但研究揭示了一个更广泛的安全影响:即使在实现了物理地址随机化的设备上,线性映射的不随机化仍然显著降低了系统的整体安全性。
物理页面分配的可预测性
研究进行了一项开创性的实验:在Samsung S23设备上,分配了约5GB的物理内存,然后分析物理页面帧号(PFN)的分配模式。这项研究进行了100次独立测试(每次重启设备),发现某些PFN范围内表现出令人担忧的一致性。
实验结果显示:
- 高可靠性范围:存在PFN范围,攻击者控制的页面在这些范围内被持续分配
- 可利用的可预测性:即使在运行时间较长的设备上,可靠性仍然足够高,为现实世界攻击者提供机会
- 内存喷射的改进:攻击者可以将内核数据结构或用户控制的内存放置在已知的内核虚拟地址
防护建议与未来方向
立即可实施的改进措施
考虑到这些发现对Android、Linux内核和Pixel设备安全态势的直接影响,研究建议了三个具体的改进方向:
- 线性映射位置随机化:在内核虚拟地址空间中随机化线性映射的位置
- 物理页面分配熵增加:提高物理页面分配的随机性程度
- 内核物理地址随机化:确保内核在物理地址空间中的加载位置随机化
技术挑战与平衡考虑
虽然从安全角度实施这些改进具有明显优势,但需要认识到实施过程中面临的技术挑战:
- 内存热插拔兼容性:新的实现必须保持对内存热插拔功能的支持
- 系统性能影响:随机化可能带来的性能开销需要仔细评估
- 向后兼容性:改进不能破坏现有的系统和应用程序
结论
Google Project Zero的这项研究揭示了一个令人不安的现实:KASLR在arm64架构上的有效性远低于预期。更具体地说,线性映射的静态特性和特定设备上的物理地址固定化共同创造了一个环境,使得被动信息泄露成为可能。
这种研究方法的重要意义在于,它展示了如何通过深入分析系统架构特性而非依赖特定漏洞来实现攻击目标。攻击者不需要找到或利用安全漏洞,而是利用系统设计的内在特性来绕过安全防护机制。
从防护角度来看,这项研究强调了持续安全评估的重要性,以及在系统设计初期考虑安全影响的必要性。虽然KASLR在缓解远程内核攻击方面仍然发挥重要作用,但应该避免对其本地攻击防护能力产生过度依赖。
最终,这项研究不仅提供了对当前安全态势的深刻洞察,也为未来的安全改进指明了方向。随着移动设备在我们的数字生活中变得越来越重要,确保这些设备的内核安全变得至关重要。
参考资料