在尝试理解ASLR时,我构建了这个简单的程序:
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("%p\n", &system);
return 0;
}
似乎启用了ALSR:
$ cat /proc/sys/kernel/randomize_va_space
2
我使用GCC编译程序:
$ gcc aslrtest.c
每次运行此程序时,它都会打印相同的地址(0x400450
)。
如果glibc在随机地址加载,我希望这个程序每次都打印一个不同的地址。这对我来说是令人惊讶的,特别是考虑到防止返回libc攻击应该是ASLR的主要动机(特别是system()
调用)。
我怀疑system()
的地址应该是随机的吗?或者我的配置可能有问题?
答案 0 :(得分:4)
这这是一个从在主程序的非位置无关的对象文件进行共享库中的函数的任何引用需要PLT条目,通过该主叫方可以经由真实解析为一个固定的地址在一个调用指令进行呼叫链接时。这是因为目标文件没有使用特殊代码(PIC)构建,以使其能够支持在变量地址处调用函数。
每当这样的PLT条目用于在一个库中的函数,这PLT条目,而不是函数的原始地址的地址,成为其“正式”的地址(如在你的例子,其中已打印的地址{ {1}})。这是必要的,因为必须以相同的方式从C程序的所有部分看到函数的地址。 system
地址的语言不允许根据程序的哪个部分来查看它,因为这会破坏两个指向同一函数的指针相等的规则。
如果您真的希望获得ASLR的好处,以防止使用已知固定地址调用函数的攻击,则需要将主程序构建为PIE。
答案 1 :(得分:0)
实际上printf("%p\n", &system);
不会打印实际的libc地址
打印system@plt
地址,该地址未由ASLR
但它会随机化libc地址,最终保护ret2libc攻击!!