是否可以通过替换页表来覆盖内核代码?

时间:2020-09-09 01:26:06

标签: linux linux-kernel

因此,您似乎无法修改内核代码,因为指向它的PTE被标记为可执行文件,而不是可写文件。我想知道是否可以使用以下方法覆盖内核代码? (这仅适用于x86,并假设我们具有root用户访问权限,因此我们将以下步骤作为内核模块运行)

  1. 读入CR3寄存器的内容
  2. 使用kmalloc分配足够大的内存以复制所有PTE和PDE
  3. 使用从CR3寄存器获得的值将所有分页数据复制到新分配的内存中
  4. 将相关页面标记为可执行和可写
  5. 使用指向我们在第2步中分配的内存的指针覆盖CR3寄存器

在这一点上,假设一切正常,您是否能够覆盖返回地址和内核代码的其他部分?而在此之前,我们将停止使用分页机制保护?

1 个答案:

答案 0 :(得分:1)

3。使用从CR3寄存器获得的值将所有分页数据复制到新分配的内存中

5。用指向我们在步骤2中kmalloc的内存的指针覆盖CR3寄存器

这两个步骤可能不起作用:

CR3为您提供物理地址;但是,要读取页面数据,您需要一个虚拟地址。甚至不能保证PTD当前已映射(因此可以访问)。

要覆盖CR3寄存器,您需要知道使用kmalloc分配的内存的物理地址;但是,您只知道虚拟地址。

但是,您可以使用virt_to_physphys_to_virt将物理地址转换为虚拟地址。

是否可以覆盖内核代码...?

我不确定,但是以下尝试应该起作用:

页表本身应该是可读写的-至少是kmalloc使用的页表。

您可以使用kmalloc分配一些内存,而不是复制PTD和页表,该内存的大小为2页长(如果使用“传统” 4 KiB内存页,则为8 KiB)。这意味着在任何情况下,“您的”内存块都包含一个完整的内存页面。

当您拥有PTD和页表的虚拟地址时,可以重新映射“您的”内存页,这样它就不再指向“ kmalloc”内存,而是指向您想要的内核代码修改...

在这一点上,假设这一切都可行,那么您是否能够覆盖返回地址和内核代码的其他部分?

我不确定我是否正确理解了你的问题。

但是内核模块是内核的一部分-因此,没有什么能阻止内核模块做完全愚蠢的事情(故意或由于错误)。

因此,在编程内核模块时必须非常小心。

由于“ root”具有加载内核模块的能力,因此黑客或恶意软件永远不要获得“ root”访问权限非常重要。否则,可以使用insmod将恶意软件注入内核。