必须设为 kernel.randomize_va_space = 2,否则堆地址不随机,缓冲区溢出攻击仍可稳定利用;需先查当前值(0/1/2),非2时写入独立配置文件 /etc/sysctl.d/10-security.conf,执行 sudo sysctl --system 加载,并用 /proc/self/maps 或 ldd 多次验证地址是否浮动,同时确保关键程序为 PIE 可执行文件。

必须设为 kernel.randomize_va_space = 2,否则堆地址不随机,缓冲区溢出攻击仍可稳定利用。
确认当前值再写入,避免覆盖已有安全配置
直接追加可能重复或冲突。先查当前设置:
cat /proc/sys/kernel/randomize_va_space
输出是 0、1 或 2。若已是 2,跳过写入;若为 0 或 1,再操作。不要用 /etc/sysctl.conf 主文件——它易被其他软件覆盖,改用独立配置文件:
sudo tee /etc/sysctl.d/10-security.conf <<EOFkernel.randomize_va_space = 2EOF
这样既隔离又明确,sysctl --system 会按字母序加载,10- 前缀确保优先生效。
执行 sysctl --system 而非 sysctl -p
sysctl -p 只读 /etc/sysctl.conf,忽略 /etc/sysctl.d/ 下的文件。正确命令是:
sudo sysctl --system
它会加载所有标准位置(包括 /etc/sysctl.d/*.conf),并打印每条已应用的配置。若看到 kernel.randomize_va_space = 2 出现在输出中,说明已载入。
验证是否真生效,别信参数值本身
写进文件 ≠ 进程内存真随机。必须实测:
- 运行
cat /proc/self/maps | grep -E "^\w+.*\[stack\]|\[vdso\]|libc\.so" | head -3多次,观察地址列(如b7ef2000)是否变化 - 用
ldd /bin/ls | grep libc执行 3 次,比对括号内地址是否浮动 - 若地址全固定,常见原因:容器 runtime 强制禁用(如 Docker 的
--security-opt no-new-privileges配合旧版内核)、启动参数含norandmaps、或 SELinux 策略限制allow domain self:process setrlimit;类规则被收紧
注意 PIE 程序不是可选项,而是 ASLR 完整性的必要条件
内核设成 2 只管堆、栈、共享库、mmap 区域,**不负责主程序代码段**。非 PIE 程序(file ./a.out 输出含 EXEC (Executable file))的代码段永远固定在 0x400000 附近,攻击者可直接 ret2plt 或硬编码调用。
必须让关键服务二进制支持 PIE:
- 编译时加
-fPIE -pie,链接时不带-no-pie - 检查现网程序:
readelf -h /usr/bin/nginx | grep Type,输出应为DYN (Shared object file) - 系统级默认行为不可靠——glibc 2.34+ 默认启用
-pie,但很多发行版打包脚本仍显式传-no-pie
没 PIE,randomize_va_space = 2 就像给门装了电子锁却留着一扇敞开的窗。


















