Linux 进程的页表中是否有一个特殊位来停止指令在堆栈中运行,从而阻止溢出攻击?

Linux 进程的页表中是否有一个特殊位来停止指令在堆栈中运行,从而阻止溢出攻击?

所以视频中的那个人:

https://www.youtube.com/watch?v=1S0aBV-Waeo

溢出堆栈,篡改返回地址,将其指向堆栈,并使用 NOP 指令将可执行代码复制到堆栈中

但我认为所有现代 Linux 系统(包括 debian 系统)都可以使用页表中的 NX(不可执行)类型的位并使用像这样的停止指令在堆栈中工作来防御这种情况?或者我错过了什么?

答案1

不可执行页面(NX 位)是一项硬件功能。它允许操作系统标记哪些页面可以被执行。如果程序尝试在不可执行的内存页中执行代码,处理器就会出错。

此外,堆栈是否可执行还取决于编译器选项(以及生成的二进制文件)。现代 Linux 发行版为用户空间二进制文件启用了许多强化技术,例如不可执行堆栈、堆栈金丝雀、地址空间布局随机化。例如Ubuntu 用户空间强化

这是可能的使用可执行堆栈编译二进制文件,而不使用堆栈金丝雀,以使堆栈溢出成为可能,就像视频示例中所做的那样(无法看到编译的程序/使用了哪些选项,但默认情况下,gcc 不应为此类启用可执行堆栈简单的程序)。

此外,还可以配置 SELinux(和其他 Linux 安全模块)来防止系统运行需要可执行+可写内存(堆或堆栈)的二进制文件。

答案2

NX 位仅在 x86_64 架构中引入,在 32 位 Intel/AMD 处理器中不存在。当然,现在几乎每个人都在运行 64 位 PC,但似乎没有人通知那些仍然坚持在旧 386 世界的背景下解释事物的博主和视频博主。

相关内容