为什么 ASLR 似乎不起作用
Why does ASLR not seem to be working
我检查了 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 关闭了吗?
您的可执行文件必须是 position-independent 才能允许。
gcc -pie -fPIE -o test test.c
试试 运行 以这种方式连接它,地址应该在每个 运行.
上明显改变
Non-PI 可执行文件应加载到存储在其 ELF header 中的固定、显式 non-random 地址。此假设允许编译器和 linker 将 hard-code 绝对地址输入到输出中,使其在某些目标上更小更快。
在任何其他地址加载 non-PI 可执行文件会使所有这些绝对引用无效,导致最好的 SIGSEGV 和一些随机代码 运行ning 最坏的。 main
的地址无法安全地随机化,因为允许编译器假定它不会,所以即使启用了 ASLR,它也永远不会完成。
要允许随机化,必须告知编译器生成 position-independent 代码 (-fPIE
),并且生成的可执行文件必须标记为 position-independent (-pie
)这样内核就会知道在任何地址加载都是安全的。
需要哪些选项来实现这在很大程度上取决于工具链配置,-fpie
、-fPIE
、-fpic
、-fPIC
,有些可能会默认生成PI代码.安全的选择是使用 -fPIE
和 link 以及 -pie -fPIE
.
进行编译
我检查了 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 关闭了吗?
您的可执行文件必须是 position-independent 才能允许。
gcc -pie -fPIE -o test test.c
试试 运行 以这种方式连接它,地址应该在每个 运行.
上明显改变Non-PI 可执行文件应加载到存储在其 ELF header 中的固定、显式 non-random 地址。此假设允许编译器和 linker 将 hard-code 绝对地址输入到输出中,使其在某些目标上更小更快。
在任何其他地址加载 non-PI 可执行文件会使所有这些绝对引用无效,导致最好的 SIGSEGV 和一些随机代码 运行ning 最坏的。 main
的地址无法安全地随机化,因为允许编译器假定它不会,所以即使启用了 ASLR,它也永远不会完成。
要允许随机化,必须告知编译器生成 position-independent 代码 (-fPIE
),并且生成的可执行文件必须标记为 position-independent (-pie
)这样内核就会知道在任何地址加载都是安全的。
需要哪些选项来实现这在很大程度上取决于工具链配置,-fpie
、-fPIE
、-fpic
、-fPIC
,有些可能会默认生成PI代码.安全的选择是使用 -fPIE
和 link 以及 -pie -fPIE
.