【问题标题】:Why aren't glibc's function addresses randomized when ASLR is enabled?为什么启用 ASLR 时 glibc 的函数地址不随机化?
【发布时间】:2014-09-19 00:47:58
【问题描述】:

为了理解 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() 的地址应该是随机的,我错了吗?还是我的配置可能有问题?

【问题讨论】:

  • @HansPassant 重启后没有变化
  • 编译时需要使用-pie -fPIE 让内核将镜像移动到随机地址。
  • 谢谢,成功了。

标签: c linux gcc glibc aslr


【解决方案1】:

任何对来自主程序中非位置无关目标文件的共享库函数的引用都需要一个 PLT 条目,调用者可以通过该 PLT 条目通过解析为固定地址的调用指令进行调用链接时间。这是因为目标文件没有使用特殊代码 (PIC) 构建以使其能够支持在变量地址处调用函数。

每当这样的 PLT 条目用于库中的函数时,这个 PLT 条目的地址,而不是函数的原始地址,将成为它的“官方”地址(如在您打印 @ 地址的示例中987654321@)。这是必要的,因为必须以相同的方式从 C 程序的所有部分看到函数的地址。语言不允许 system 的地址根据程序的哪个部分正在查看它而变化,因为这会破坏指向同一函数的两个指针比较相等的规则。

如果你真的想获得 ASLR 的好处来对抗使用已知固定地址调用函数的攻击,你需要将主程序构建为 PIE。

【讨论】:

    【解决方案2】:

    实际上printf("%p\n", &amp;system); 并没有打印出它实际的 libc 地址 打印system@plt 地址,该地址不是由 ASLR 随机化的

    但它确实随机化了最终保护 ret2libc 攻击的 libc 地址!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      相关资源
      最近更新 更多