跳转至

ASLR

ASLR

ASLR,应为全称为Address Space Layout Randomization,即地址空间布局随机化。它是一种概率性安全防御机制,由PaX团队于2001年正式提出,并在2005年开始引入到Linux内核之中。ASLR能够在每次运行可执行文件的时候通过基地址随机映射的方式来为其随机分配地址空间。ASLR存在的目的,就是为了防止那些需要了解内存地址来利用内存崩溃漏洞的攻击行为。

在此之前,内存崩溃漏洞的成功利用需要来了解硬编码的内存地址,以便攻击者获取到可执行指令的地址并实现任意代码执行,或破坏关键的程序数据。ASLR最初是用来抵御和防范远程攻击者的,因为攻击者需要获取到目标设备的内存地址才能执行攻击,那么对于远程攻击者来说,实现掌握的关于内存地址的信息肯定不会很多。

ASLR 的局限性

尽管 ASLR 使得对系统漏洞的利用更加困难了,但其保护系统的能力是有限的。理解关于 ASLR 的以下几点是很重要的:

  • 它不能解决漏洞,而是增加利用漏洞的难度
  • 并不追踪或报告漏洞
  • 不能对编译时没有开启 ASLR 支持的二进制文件提供保护
  • 不能避免被绕过

ASLR 是如何工作的

通过对攻击者在进行缓冲区溢出攻击时所要用到的内存布局中的偏移做了随机化,ASLR 加大了攻击成功的难度,从而增强了系统的控制流完整性。

通常认为 ASLR 在 64 位系统上效果更好,因为 64 位系统提供了更大的熵(可随机的地址范围)。

ASLR 是否正在你的 Linux 系统上运行?

下面展示的两条命令都可以告诉你的系统是否启用了 ASLR 功能:

Bash
$ cat /proc/sys/kernel/randomize_va_space
2
$ sysctl -a --pattern randomize
kernel.randomize_va_space = 2

上方指令结果中的数值(2)表示 ASLR 工作在全随机化模式。其可能为下面的几个数值之一:

Bash
0 = Disabled
1 = Conservative Randomization
2 = Full Randomization

如果你关闭了 ASLR 并且执行下面的指令,你将会注意到前后两条 ldd 的输出是完全一样的。ldd 命令会加载共享对象并显示它们在内存中的地址。

Bash
$ sudo sysctl -w kernel.randomize_va_space=0    < == disable
[sudo] password for shs:
kernel.randomize_va_space = 0

如果将其重新设置为 2 来启用 ASLR,你将会看到每次运行 ldd,得到的内存地址都不相同。

Bash
$ sudo sysctl -w kernel.randomize_va_space=2    < == enable
[sudo] password for shs:
kernel.randomize_va_space = 2

永远修复不完的Linux本地ASLR漏洞