kernel.randomize_va_space=2是ASLR完全启用的前提,但需结合/proc/self/maps地址浮动、checksec显示“Yes”、ldd libc地址变化等多维度验证,缺一不可。

检查 kernel.randomize_va_space 当前值是否为 2
这是最直接的判断依据,但仅看这个值不能代表 ASLR 真正起效。它只是内核参数开关,必须配合验证步骤才能确认防护就绪。
执行命令:cat /proc/sys/kernel/randomize_va_space
预期输出应为 2。若为 0 或 1,说明未完全启用;若报错“没有那个文件或目录”,则内核可能未编译 ASLR 支持(如 CONFIG_COMPAT_BRK=y 强制关闭了随机化)。
用 /proc/self/maps 观察进程内存布局是否浮动
ASLR 的核心表现是每次启动进程时,关键内存区域地址变化。只查一次没用,必须多次比对。
运行以下命令至少 3 次,重点关注 [stack]、vvar、vdso 和 libc 映射行起始地址:
cat /proc/self/maps | head -n 5
如果这些地址每次都不一样(尤其是 [stack] 行开头的十六进制数),说明栈、vdso、vvar 等已随机化。若固定不变,可能是:
- 系统启用了
norandmaps内核启动参数 - SELinux 或 AppArmor 策略显式禁用了 mmap 随机化
- 在容器中运行,且运行时(如 Docker)覆盖了宿主的 ASLR 设置
用 checksec 查看二进制文件的 ASLR 标记
checksec 是专用于检测二进制安全特性的工具,它会综合判断内核参数 + 程序自身是否支持 ASLR。
安装后执行:checksec --file /bin/bash
关键字段是 ASLR,预期输出为 Yes。若显示 No,常见原因有:
-
/bin/bash不是 PIE 可执行文件(file /bin/bash输出不含PIE executable) - 程序被静态链接(无动态依赖,
ldd /bin/bash报错或无输出) - 系统使用了
gcc的-no-pie默认行为(某些旧发行版或交叉编译环境)
用 ldd 多次比对共享库加载地址
动态链接库(如 libc)的随机化是 ASLR 最易观察的环节,且不依赖程序是否为 PIE。
执行:ldd /bin/ls | grep libc
反复运行 3–5 次,观察输出中 libc.so.6 后面的地址(如 0x00007f9a2b1c3000)是否每次不同。若始终一致,说明:
- 内核参数虽为 2,但
ld.so加载器被环境变量(如LD_PRELOAD)干扰 - 程序以
setuid方式运行,部分内核版本会为安全起见临时禁用 ASLR - 系统开启了
kernel.unprivileged_userfaultfd = 0等限制,间接影响 mmap 行为
真正难搞的不是设成 2,而是让每个环节都配合:内核参数、用户态程序编译方式、动态链接器行为、运行时环境约束——漏掉任何一环,ASLR 就会出现“看起来开了,其实没防住”的假象。


















