内容提要
本文讨论了Linux内核漏洞利用技术,重点分析了如何绕过KCanary、KASLR、SMEP和SMAP等保护机制。通过分析内核函数地址、计算偏移量和构建ROP链,攻击者可以利用堆栈溢出等手段获取root权限。文章提供了多种攻击方法和示例代码,展示了在不同保护级别下的内核漏洞利用。
延伸解读
保护机制递进:从KCanary到KPTI的绕过思路
文章以QWB 2018 core挑战为例,逐步叠加KCanary、KASLR、SMEP、SMAP和KPTI保护。Lv1仅需读取/tmp/kallsyms获取commit_creds和prepare_kernel_cred地址,并利用栈溢出覆盖返回地址;Lv2引入SMEP/SMAP后,需改用KROP或禁用CR4相关位;Lv3加入KPTI后,需通过swapgs_restore_regs_and_return_to_usermode或信号处理返回用户态。这种递进方式清晰展示了不同保护组合下的利用策略变化。
关键信息泄露:/tmp/kallsyms与偏移计算
在KASLR启用时,攻击者可通过读取/tmp/kallsyms获取内核函数地址,从而绕过地址随机化。文章示例中,通过解析该文件获得prepare_kernel_cred和commit_creds的运行时地址,再结合vmlinux.unstripped中的符号地址计算偏移量(如commit_creds - 0x9c8e0 - 0xffffffff81000000)。这一方法依赖于系统暴露符号信息,若该文件不可读或权限受限,则需寻找其他泄露途径。
SMEP/SMAP绕过:KROP与CR4操作对比
面对SMEP和SMAP,文章给出两种思路:一是直接使用内核ROP链(KROP)调用prepare_kernel_cred和commit_creds,避免执行用户态代码;二是通过gadget将CR4寄存器的SMEP/SMAP位清零(如设置为0x6f0),从而禁用保护。前者更通用,后者在KPTI启用时可能失效,因为KPTI要求返回用户态时切换页表。两种方法各有适用场景,需根据实际保护组合选择。
KPTI应对:页表切换与信号处理技巧
KPTI通过隔离用户和内核页表增加利用难度。文章提到,在KPTI启用时,方法0x2(禁用SMEP/SMAP)不再有效,但方法0x1仍可使用,因为KPTI仅强制隔离。返回用户态时,需使用swapgs_restore_regs_and_return_to_usermode函数或手动切换CR3的第13位。此外,若直接返回导致段错误,可通过注册SIGSEGV信号处理函数来执行shell,这提供了一种绕过页表切换的替代方案。
Q&A
Linux内核漏洞利用的主要保护机制有哪些?
主要保护机制包括KCanary、KASLR、SMEP和SMAP。
攻击者如何绕过KCanary和KASLR?
攻击者可以通过读取/tmp/kallsyms获取commit_creds和prepare_kernel_cred函数的地址,从而绕过KCanary和KASLR。
在启用SMEP和SMAP的情况下,攻击者可以使用什么方法?
攻击者可以使用ROP链直接写入返回地址,或者通过禁用SMEP和SMAP来绕过保护。
KPTI启用后,攻击者需要进行哪些额外操作?
攻击者需要切换回内核模式,使用swapgs_restore_regs_and_return_to_usermode函数进行切换。
文章中提到的攻击示例代码有什么作用?
示例代码展示了在不同保护级别下的内核漏洞利用方法,帮助理解攻击过程。
如何计算commit_creds函数的偏移量?
可以使用工具如checksec查看PIE地址,并通过commit_creds的地址计算偏移量。