Jos*_*ica 3 security assembly x86-64 linux-kernel page-tables
我的印象是,Linux 内核试图保护自己的核心是不让恶意代码在内核空间中运行。特别是,如果要加载恶意内核模块,从安全角度来看,这将是“游戏结束”。然而,我最近看到一篇与这种观点相矛盾的帖子,并说内核可以通过某种方式保护自身的一部分免受自身其他部分的影响:
有很多机制可以保护您免受恶意模块的侵害。我写内核代码是为了好玩,所以我在这个领域有一些经验;它基本上是页表中的一个标志。
有什么可以阻止任何内核模块更改分页表中的那个标志?防止恶意模块的唯一保护是完全阻止它们加载。一旦加载,游戏就结束了。
使分页表只读。完毕。
内核模块可以再次将其设为可读写,就像您的代码将其设为只读一样,然后继续进行更改。
您实际上可以将其锁定,以便内核模式在发生中断之前无法修改页表。如果您的 IDT 也是只读的,则模块无法对其进行任何处理。
这对我来说没有任何意义。我是否遗漏了一些关于内核内存如何工作的重要信息?内核空间代码可以限制自己修改页表吗?这真的能阻止内核 rootkit 吗?如果是这样,那么为什么今天的 Linux 内核不这样做以结束所有内核 rootkit?
如果恶意内核代码以受信任的方式加载(例如加载内核模块而不是利用漏洞),则不:内核代码是内核代码。
Intel CPU 确实有一系列机制来禁用对内核内存的读/写访问:
CR0.WP如果设置不允许写入访问用户和内核只读页面。用于检测内核代码中的错误。CR4.PKE如果设置(必须启用 4 级分页,在 64 位模式下是强制性的)不允许内核访问(不包括指令获取)用户页面模式,除非它们用正确的键标记(标记了它们的 RW 权限)。用于允许内核写入 VSDO 之类的结构,KUSER_SHARED_DATA但不允许写入其他用户模式结构。密钥权限在 MSR 中,而不是在内存中;键本身在页表条目中。CR4.SMEP如果设置不允许从用户模式页面获取内核指令。用于防止将内核函数指针重定向到用户模式分配页面的nelson.c攻击(例如特权提升漏洞)。CR4.SMAPif set 不允许内核在隐式访问期间或任何类型(隐式或显式)访问期间访问用户模式页面(如果EFLAGS.AC=0,从而覆盖保护密钥)。用于执行更严格的无用户模式访问策略。R/W和U/S位控制项目是只读/读写并分配给用户或内核。您可以在 Intel 手册中阅读如何为主管模式访问应用权限:
数据写入超级模式地址。
访问权限取决于 CR0.WP 的值:
-如果 CR0.WP = 0,则数据可以写入任何监控模式地址。
- 如果 CR0.WP = 1,则数据可以写入任何管理模式地址,并且在每个控制转换的分页结构条目中,R/W 标志(位 1)为 1 的转换;数据不得写入任何管理模式地址,在任何控制转换的分页结构条目中,其 R/W 标志为 0 的转换。
因此,即使内核将页面保护X为只读,然后将页面结构本身保护为只读,恶意模块也可以简单地清除CR0.WP.
它还可以更改CR3和使用自己的分页结构。
请注意,英特尔开发SGX 是为了解决内核本身是邪恶的威胁模型。
然而,以安全的方式(即没有单点故障)将内核组件运行到飞地中可能并非易事。
另一种方法是使用VMX扩展虚拟化内核,尽管这绝非易事。
最后,CPU 在分段层有四个保护级别,但分页只有两个:主管(CPL = 0)和用户(CPL > 0)。
理论上可以在“Ring 1”中运行内核组件,但是您需要创建一个接口(例如调用门或 之类的东西syscall)才能访问其他内核函数。
在用户模式下运行它更容易(因为您首先不信任该模块)。
我不知道这是什么意思:
您实际上可以将其锁定,以便内核模式在发生中断之前无法修改页表。
我不记得中断处理将锁定/解锁任何东西的任何机制。不过我很好奇,如果有人能透露一些信息,欢迎他们。
x86 CPU 中的安全性(但这可能是概括的)一直是分层的:先来者为后来者设置约束。
在同一层级的非隔离组件之间通常几乎没有保护。
| 归档时间: |
|
| 查看次数: |
387 次 |
| 最近记录: |