【问题标题】:Why does ASLR not seem to be working为什么 ASLR 似乎不起作用
【发布时间】:2016-08-07 20:08:06
【问题描述】:

我检查了是否启用了 ASLR,如下所示,我认为是:

[user@localhost test]$ cat /proc/sys/kernel/randomize_va_space
2

我尝试使用以下程序对其进行测试:

test.c

#include <stdio.h>
int main(void)
{
    printf("%p\n", main);
    return 1;
}

我预计,如果 ASLR 处于活动状态,每次运行都会到不同的地址,对吧?但我每次都一样。我测试了 64 位和 32 位可执行文件。我正在使用 64 位 Arch Linux 系统进行测试:

[user@localhost test]$ gcc test.c -o test
[user@localhost test]$ ./test
0x4004c6
[user@localhost test]$ ./test
0x4004c6
[user@localhost test]$ ./test
0x4004c6
[user@localhost test]$ ./test
0x4004c6
[user@localhost test]$ gcc -m32 test.c -o test
[user@localhost test]$ ./test
0x80483eb
[user@localhost test]$ ./test
0x80483eb
[user@localhost test]$ ./test
0x80483eb
[user@localhost test]$ ./test
0x80483eb

如您所见,每次运行的地址都是相同的。这不是说ASLR关闭了吗?

【问题讨论】:

  • 尝试获取变量的地址,而不是非静态函数
  • 顺便说一句,将非 void* 传递给 printf 中的 '%p' 参数是未定义的行为
  • @Elazar 为什么? .text 部分中的函数应该受 ASLR 影响,不是吗?这难道不是 ASLR 最基本的用途——随机化可执行部分吗?
  • 最基本的层次是栈指针
  • 尽管对奇怪的哈佛架构目标给予了应有的尊重,但函数指针问题显然与提出的问题无关。

标签: c linux aslr


【解决方案1】:

您的可执行文件必须与位置无关才能允许这样做。

gcc -pie -fPIE -o test test.c

尝试以这种方式运行,每次运行时地址都会明显变化。

非 PI 可执行文件应加载到存储在其 ELF 标头中的固定、明确的非随机地址。这种假设允许编译器和链接器将绝对地址硬编码到输出中,使其在某些目标上更小更快。

在任何其他地址加载非 PI 可执行文件会使所有这些绝对引用无效,导致最好的情况是 SIGSEGV,最坏的情况是运行一些随机代码。 main 的地址不能安全地随机化,因为允许编译器假设它不会,所以即使启用了 ASLR,它也永远不会完成。

为了允许随机化,必须告知编译器生成与位置无关的代码 (-fPIE),并且生成的可执行文件必须标记为与位置无关 (-pie),以便内核知道可以安全加载在任何地址。

实现这一点需要哪些选项很大程度上取决于工具链配置,-fpie-fPIE-fpic-fPIC,有些可能会默认生成 PI 代码。安全的选择是使用-fPIE 编译并使用-pie -fPIE 链接。

【讨论】:

  • 谢谢。在接受之前,我花了一些时间研究 -pie 和 -fpie,但如果你简要解释一下它们的作用或为什么这与 ASLR 有关系,它可能会对其他人有所帮助。
  • 更新了帖子,希望它现在足够独立,无需太多谷歌搜索即可阅读。
  • 相关:32-bit absolute addresses no longer allowed in x86-64 Linux? 有更多关于 PIE 可执行文件的信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-14
  • 2010-10-14
  • 2022-11-13
  • 2012-10-19
  • 2018-06-09
  • 1970-01-01
  • 2020-05-20
相关资源
最近更新 更多