如何检测内核漏洞?

信息安全 开发 取证 记忆 检测 核心
2021-08-18 11:23:25

所有内核漏洞利用有什么共同点吗?

当然,它们都利用内核,但我对底层机制或结果更感兴趣。目前,我的兴趣主要集中在记忆取证的方向上。由于内核在启动后存储在内存中,我想知道漏洞是否一定需要在这个内存区域进行更改,因此可以被检测到。当然,如果您在该级别有漏洞,您可以禁用操作系统上的每个检测机制,但这是一个不同的主题,内存取证也并不总是需要在操作系统级别进行。

我不确定内存取证是否会起作用,或者是否适用于每种漏洞利用机制。也许还有其他方法?检测是否依赖于特定的内核,即来自 Windows、Linux 或 Unix 系统的内核?

1个回答

不,所有内核漏洞利用都没有任何共同点。

或者至少,它们没有什么独特之处,也没有出现在与内核的标准合法交互中(例如使用系统调用或访问特殊文件系统)。通常,内核漏洞利用涉及使用专门设计的参数进行系统调用(允许用户空间进程与内核通信的接口),以导致意外行为,尽管系统调用试图仅允许有效参数。其他漏洞利用可能涉及两个系统调用之间的并发问题(竞争条件)。让我们看几个例子:

CVE-2016-5195

这更好地称为DirtyCow,并且涉及内核内存管理中的竞争条件,特别是写时复制(CoW)。Copy-on-write 是一种内存管理技术,它允许即时复制大量数据,而与数据量无关。当一系列内存页面被 CoWed 时,它在两个任务之间共享。如果一项任务修改了页面,那么只有复制该页面以允许对其进行修改。这样,两个任务可以共享相同的物理内存,同时仍然不能相互干扰。

该漏洞利用涉及两个系统调用的竞争条件,madvise()并且ptrace()在两个尝试写入同一页面的任务之间。如果一个页面被映射到内存中并被madvise(MADV_DONTNEED)调用,内核会被告知该页面将来不会被使用。ptrace(PTRACE_POKETEXT)将此与直接写入内存的调用相结合,允许修改原始的只读页面,因为 CoW 位被不适当地删除。这可以通过写入vDSO来利用,vDSO是所有进程共享的一个小的可执行内存区域。如果一个无特权的恶意进程能够更改 vDSO,那么当它被无辜的特权进程执行时,这些特权进程可能会受到损害。

madvise()通话和通话都是ptrace()良性动作。没有理由认为,通过以特定顺序快速使用它们,内核中由许多进程共享的内存页面最终会被恶意进程“拥有”,从而允许该进程以任何方式更改它想要。这怎么可能被发现?

CVE-2016-0728

该漏洞涉及利用系统调用keyctl()来管理内核内密钥环设施该错误涉及引用计数器的溢出,导致引用计数归零。当多个进程共享单个密钥环会话时,引用计数会增加。这是为了让内核知道何时没有人再使用该内存,以便它可以释放它。

由于内核中的一个错误,有一种特定的方法来增加引用计数器而不在之后减少它,导致重复该操作以任意增加计数器。一旦此引用计数泄漏导致变量回绕为零,内核自然认为没有人再使用该对象,释放它就可以了。但是,当该对象被释放时,仍有一个或多个任务使用该对象。结果,如果他们尝试访问它,他们将访问未分配的内存。如果攻击者随后通过从用户空间创建另一个内核对象来分配内存,并将他们自己的恶意数据放入其中,则先前引用该内存区域的高特权内核任务将改为访问恶意代码,从而导致其执行。这被称为释放后使用漏洞,或 UAF。

在内核中使用keyctl()系统调用和触发内存分配都是正常的、良性的行为。如果不预先知道漏洞,怎么可能检测到这样的事情?毕竟,假设是引用计数器不会泄漏!

CVE-2017-1000112

Linux 内核能够“窥视”现有的数据包,而不会将其从接收队列中删除,从而允许任务在实际从内核中获取数据之前窥视一些数据。这是通过recvfrom(), 使用MSG_PEEK标志来完成的。

内核实现 UDP分片卸载(UFO) 的一个相当复杂的错误可能允许攻击者使用 UFO 设置网络接口来禁用 CRC 检查,触发大负载的分片,并将用户控制的字节数复制到另一个内存位置。这可用于用任意数据覆盖重要的结构。这个结构的某个内存包含一个指向函数的指针,如果该成员被修改为指向恶意攻击者控制的代码的地址,内核就可以执行它,从而危及系统。

配置网络接口不是恶意活动,禁用 CRC 校验或使用MSG_PEEK.

概括

确实,许多内核漏洞都属于几个“类”,例如 UAF、整数溢出、引用计数溢出、缓冲区溢出等,它们都涉及系统在被告知执行某项任务时以意想不到的方式表现。此任务是否正常并应导致正常行为,或者是否不正确并应导致返回错误都无关紧要。内核应该是无论人们如何与之交互,都可以正常运行,并且存在允许完全合法交互的错误,例如告诉内核它已完成页面或创建新的密钥环对象以导致内核部分的错误操作被攻击者滥用。应该定义与内核的所有交互,因此即使是攻击内核的漏洞也会利用已定义但未正确实现的行为。

但是,有一些方法可以防止整个类别的漏洞利用。例如,控制流完整性(CFI) 可用于缓解利用乱序执行的所有形式的错误,例如 ROP。SMEP、SMAP 和 grsecurity 的 UDEREF虽然可以通过利用其他错误来绕过,但可以防止内核对用户空间内存的所有形式的无意访问,从而防止涉及修改函数指针以指向攻击者控制的用户空间的攻击。这些技术无法击败所有漏洞,因为它们太多了,并且它们无法使用全新的技术来击败漏洞(尽管谢天谢地,这些漏洞很少见)。

Grsecurity 是一家旨在减轻所有类型的错误的公司,尽管它已经对公众关闭(希望只是暂时的),但它仍然有一些公开的分支。通过阅读他们最新的公共补丁源代码,可以了解许多有趣的漏洞利用缓解措施。