新型FlipSwitch钩子方法突破Linux内核防御
一种名为FlipSwitch的新型rootkit钩子方法已经出现,它绕过了最新的Linux 6.9内核分发保护机制,重新引发了人们对内核级漏洞的担忧。
通过操纵新的系统调用分发器的机器代码,而不是已弃用的sys_call_table,FlipSwitch恢复了系统调用钩子的经典能力,能够隐秘拦截关键系统调用,如kill和getdents64。
多年来,像Diamorphine和PUMAKIT这样的Linux rootkit利用sys_call_table(一个简单的函数指针数组)通过攻击者控制的函数重新路由系统调用。通过禁用写保护并覆盖特定条目,攻击者可以隐藏恶意文件使其不出现在ls输出中,或阻止进程终止尝试。
然而,Linux内核6.9的发布给这种方法带来了致命打击:内核将直接数组查找
|
|
替换为x64_sys_call内部的switch语句分发,在实际系统调用处理中有效地忽略了对sys_call_table的任何修改。
FlipSwitch:重新发现钩子
FlipSwitch的关键洞察是,原始的系统调用逻辑仍然以编译形式存在于switch语句后面。FlipSwitch不是篡改sys_call_table,而是在x64_sys_call中定位并修补调用目标系统调用函数的机器级调用指令。这个过程分为四个阶段:
发现原始函数地址 虽然sys_call_table不再控制分发,但它仍然持有有效的指针以保持兼容性。通过读取诸如sys_call_table[__NR_kill]这样的条目,FlipSwitch获得原始sys_kill例程的地址。
定位kallsyms_lookup_name 为了以编程方式查找内核符号,FlipSwitch在已知符号上使用kprobe,提取kallsyms_lookup_name的地址。这使得能够查找任何导出的系统调用函数指针,绕过直接导出限制。
扫描唯一的调用指令 逐字节搜索x64_sys_call函数的机器代码,寻找单字节操作码0xe8,后跟精确的4字节相对偏移量,该偏移量指向sys_kill。这个独特的签名精确定位了要劫持的确切指令。
修补分发器 在ring 0级别操作,FlipSwitch通过清除CR0中的WP位来禁用CPU写保护。然后,它覆盖已识别调用指令的4字节偏移量,指向恶意的fake_kill处理程序。在模块卸载时,重新启用保护并恢复原始偏移量,留下最少的取证证据。
影响和防御策略
FlipSwitch强调了内核加固与对手创新之间持续的猫鼠游戏动态。虽然Linux开发人员继续加强系统调用分发,但攻击者通过针对编译的分发逻辑本身来适应。缓解措施可能包括:
运行时完整性验证:定期哈希和验证x64_sys_call的机器代码以检测未经授权的修改。 增强的Kprobe限制:进一步限制或审计使用kprobes定位关键符号地址。 控制流完整性(CFI):在内核内部使用CFI技术来强制所有间接调用匹配合法目标。
使用YARA检测FlipSwitch
在内核控制流中保持可见性并利用基于签名的检测,对于在持续进行的Linux内核完整性战斗中保持领先至关重要。
由于内核级rootkit的隐秘、内存中操作,检测它们仍然具有挑战性。为了帮助防御者,Elastic Security发布了一个针对FlipSwitch概念验证的YARA规则。该规则扫描在修补过程中引入的独特机器代码模式:
|
|
通过在内存扫描工具或端点保护平台中部署此规则,安全团队可以在发生重大损害之前标记FlipSwitch修补的分发器的存在并做出响应。
随着内核防御的发展,像FlipSwitch这样的研究凸显了分层保护和主动监控的迫切需求。