如何在 Linux 内核映像中隐藏内核符号?重新编译?

信息安全 linux 开发 核心 aslr
2021-08-22 03:56:05

为什么要隐藏内核符号?

引用

任何具有内核利用基本知识的人都知道信息收集对于可靠利用的重要性。这种保护将内核符号隐藏在攻击者在预利用阶段收集信息期间可能使用的各个地方。...此选项还可以防止通过多个 /proc 条目泄漏内核地址。

错误类/内核指针泄漏

有些地方很明显。/proc/kallsyms可以通过 sysctl 进行约束kernel.kptr_restrict=2/boot可以通过 linux 文件权限将对文件夹的访问限制为仅 root 权限,并且 apparmor 甚至可以对 root 用户隐藏。AppArmor的FullSystemPolicyAppArmor的姿态,一切)另外,其它地方如/lib/modulessystem.map和内核源码目录。

为了提出一个非常具体的问题,请忽略内核符号可能泄漏的其他地方。如果想列举它们,请提出你自己的问题,等我问或添加评论。

我非常具体的问题是围绕以下引用

内核 [...] 没有被某些发行版预编译

这是因为可以从内核映像中提取内核符号为此有开源工具。

(那句话是关于 grsecurity,但我问的是非 grsecurity,即来自 kernel.org 的常规内核。)

来自公共存储库(例如 packages.debian.org)的内核映像为攻击者所熟知。攻击者可以简单地对符号地址进行硬编码,从而反击诸如kernel.kptr_restrict=2.

为防止内核指针泄漏,内核映像不能处于公共已知状态。据我所知,它必须是独一无二的、私密的。需要自己编译内核。

可重现的构建是为每个人提高安全性的一项惊人努力。但是,在这种情况下,可重现的构建将再次导致内核的符号地址可以被攻击者很好地预测,因为 Debian linux 内核已经是可重现的,大部分是可重现的或将来完全可重现的(我没有跟进关于开发的地方那)。

如何向攻击者隐藏 linux 内核映像 (vmlinux) 的内核符号?如何确保我的内核具有唯一的内核符号?是否有内核引导参数?或者是否有可能以某种方式为内核提供一个随机文件,以便它可以随机化其符号?或者是否有某种方法可以以具有唯一符号地址的方式重新编译内核?

1个回答

分发预编译内核的布局是公开的。KASLR 尝试更改内核的基本偏移量,将所有地址更改为秘密偏移量。不幸的是,即使泄漏一个符号也将允许计算其余的符号。由于 KASLR 并没有想象的那么安全,所以这是一个问题。通过设置 sysctlkernel.dmesg_restrict=1以减轻来自printk(). 即便如此,KASLR 的安全功能是如此糟糕,以至于您无法使用它来可靠地向本地攻击者隐藏此信息。

手动编译内核将确保您将使用唯一的符号偏移量。有必要设置 sysctlkernel.kptr_restrict=2并限制对内核映像本身以及相关文件(如映射和可加载模块)的访问。如果您使用来自 grsecurity 的 RANDSTRUCT 插件(现在位于上游),则可以使基于内核结构知识的攻击更加困难。