利用 Linux 内核中的空引用
最近有消息称,谷歌 Project Zero 团队的研究人员开发了一种方法,可以利用 Linux 内核中因 NULL 指针解引用而导致的漏洞。
到目前为止,与空指针解引用相关的内核问题还没有得到应有的重视,因为将此类问题转化为导致权限提升或执行自身代码的攻击被认为是不现实的(禁止将非特权进程映射到地址空间的较低区域)。
一般而言,此类错误会导致内核生成 oops 警告,之后问题任务会完成,状态会恢复,而无需停止系统。
这种新的攻击方法基于对“oops”状态的处理,这会导致引用计数器(refcount)的值增加,进而导致计数器溢出并释放与 refcount 关联的内存。
在这种情况下,利用被简化为释放后使用攻击的典型操作(出现对象的引用计数变为零,内存被释放,但实际上有工作链接指向已释放内存的情况)。
目前,当 Linux 内核在进程上下文中触发空指针解引用时,会生成一个oops 错误,这与内核 panic 不同。内核 panic 发生在内核判定没有安全的方法可以继续执行,因此必须停止所有执行时。然而,内核在 oops 错误发生时并不会停止所有执行;相反,内核会尝试尽可能地恢复并继续执行。
取消引用 NULL 指针在这里用作以受控方式生成“oops”状态的方法。 问题是大约需要 232 次“oops”状态调用才能达到 32 位引用计数溢出。
从实际角度来看,利用所提出的漏洞进行攻击大约需要连续生成八天的非原地(OOP)状态。如果攻击成功,该漏洞允许您在内核级别执行代码。
漏洞利用中使用的 NULL 指针取消引用已于 XNUMX 月修复,但由于类似问题并不少见,并且以前被视为错误,而不是漏洞,开发人员将对 Linux 内核添加一般保护,以防止操纵“oops”生成的攻击”
在任务的情况下,这意味着丢弃现有的内核堆栈并直接转到调用 do_exit 的 make_task_dead。 内核还将向 dmesg 发布“崩溃”日志和内核跟踪,显示错误发生时内核所处的状态。 当明显发生内存损坏时,这似乎是一个奇怪的选择; 然而,其目的是让内核错误更容易检测和记录,因为运行中的系统比停机系统更容易调试。
具体来说,内核 6.2 包含限制“oops”最大次数的更改。当达到限制(默认设置为 10 次 oops,如果需要,可以使用 oops_limit 参数更改此值)后,内核将进入“panic”状态,然后重启,这将阻止将引用计数重置为零所需的迭代次数。
还计划将限制转移到以前发布但仍受支持的内核分支,以及流行发行版的内核包。
最后,如果您有兴趣了解更多相关信息,可以点击以下链接查看详情。