
在本研究中,我继续深入分析Linux内核中的CVE-2021-26708漏洞。通过改进漏洞利用原型,我从攻击者角度研究了Linux内核运行时防护机制(LKRG)。本文将详细介绍如何发现新的LKRG绕过方法,以及如何进行负责任的漏洞披露。
在最初的研究中,我描述了针对x86_64平台Fedora 33 Server的本地权限提升漏洞利用原型。Linux内核虚拟套接字实现中的竞争条件可能导致内核内存中四个字节的损坏。攻击者可以逐步将这种错误转化为任意读写内核内存的能力,从而提升系统权限。但这种权限提升方法存在一些限制,阻碍了我在LKRG保护下的系统中进行实验。
我的漏洞利用原型通过劫持被攻击内核对象sk_buff中destructor_arg的析构函数调用来实现任意写入:
void (*callback)(struct ubuf_info *, bool zerocopy_success);当内核在skb_zcopy_clear()函数中调用此析构函数时,RDI寄存器包含函数的第一个参数(ubuf_info结构的地址),RSI寄存器存储第二个参数值1。
由于寄存器限制,我找到了特殊的ROP gadget:
mov rdx, qword ptr [rdi + 8]
mov qword ptr [rdx + rcx*8], rsi
ret这个gadget允许在不切换内核栈的情况下写入内核内存,通过将cred结构中的uid、gid、effective uid和effective gid字段置零来提升权限。
通过调试分析,发现RBP寄存器包含skb_shared_info的地址,这指向攻击者控制的内存区域。这为成功利用提供了希望。
最初尝试通过修改/etc/passwd文件来重置root密码,但由于内核权限检查和SELinux策略限制,这种方法未能成功。
通过分析LKRG代码,发现两个关键函数:
最终成功的攻击方法是通过ROP链直接重写这两个函数的代码。使用指令字节0x48 0x31 0xc0 0xc3(xor rax, rax ; ret)替换原有代码,使这些函数直接返回0。
完整的ROP链包括以下部分:
Linux内核在运行时可以通过CONFIG_DYNAMIC_FTRACE等机制修改自身代码,这导致许多预期的JOP gadget失效。
LKRG会检测内核代码修改,当gdb设置断点修改内核指令时,LKRG会将其视为"完整性错误"并导致系统崩溃。
2021年6月10日,我向Adam Zabrocki和Alexander Peslyak报告了LKRG绕过方法的实验结果。经过详细讨论后,于7月3日在lkrg-users邮件列表中公开了研究结果。
LKRG是一个优秀的项目,但在内核级别检测内核漏洞利用后果存在根本性限制。建议将LKRG移植到hypervisor级别或Arm Trusted Execution Environment中,以提供更有效的防护。
这项研究不仅改进了CVE-2021-26708的利用技术,还提供了针对内核运行时防护系统的深入分析,对Linux开发社区具有重要的实践价值。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。