Linux程序与系统的保护机制简介
一、程序保护机制
Linux程序通常是ELF格式的,关于程序的保护机制有如下几种:
| 序号 | 名称 | 作用 |
| 1 | RELRO | 将符号重定位表(.got)设置为只读 |
| 2 | Stack-canary | 栈溢出保护,加入类似cookie验证 |
| 3 | NX | 栈中数据没有执行权限 |
| 4 | PIE | 随机化,生成与位置无关可执行文件,类似ASLR |
| 5 | FORTIFY | 由GCC实现的源码级别的保护机制,使用危险函数时会检查边界 |
| 6 | RPATH | 在搜索程序的间接依赖库时,RPATH起作用 |
| 7 | RUNPATH | 在使用RUNPATH的情况下,很可能还要再配合LD_LIBRARY_PATH一块使用 |
检查程序是否开启这些保护机制,可以使用工具checksec,安装方法如下:
# 方法一:ubuntu 系统安装
sudo apt install checksec
# 方法二:下载安装
git clone https://github.com/slimm609/checksec.sh
sudo cp checksec.sh/checksec /usr/local/bin/
使用方法比较简单,这是使用gcc不加参数编译的程序,使用checksec工具查看,如下所示:

可以看出开启的保护措施有:默认开启随机化,关闭栈执行权限,got表设置为只读。
那么如何开启措施呢,使用gcc编译的时候加上对应参数即可:
| 序号 | 名称 | gcc参数示例 |
| 1 | RELRO | -z norelro (关闭) -z lazy (部分开启) -z now (全开启) |
| 2 | Stack-canary | -fno-stack-protector (关闭) -fstack-protector (开启) -fstack-protector-all (全开启) |
| 3 | NX | -z execstack (关闭) -z noexecstack(开启) |
| 4 | PIE | -no-pie / -pie (关闭 / 开启) -fpie -pie (开启PIE,此时强度为1) -fPIE -pie (开启PIE,此时为最高强度2,注意是大写的fPIE) |
| 5 | FORTIFY | -D_FORTIFY_SOURCE=1 (较弱的检查) -D_FORTIFY_SOURCE=2 (较强的检查) |
| 6 | RPATH | gcc -L. main.c -Wl,--rpath='.',--disable-new-dtags -o main |
| 7 | RUNPATH | gcc -L. main.c -Wl,--rpath='.',--enable-new-dtags -o main |
注:搜索.so的优先级顺序
- 编译目标代码时指定的动态库搜索路径; 如果在编译程序时增加参数-Wl,-rpath='.' , 这时生成程序的Dynamic section会新加一个RPATH段
- 环境变量LD_LIBRARY_PATH指定的动态库搜索路径; ( 可用export LD_LIBRARY_PATH="NEWDIRS" 命令添加临时环境变量 )
- RUNPATH: 写在elf文件中
- ldconfig的缓存:配置文件/etc/ld.so.conf中指定的动态库搜索路径;(系统默认情况下未设置)
- 默认的动态库搜索路径/lib;
- 默认的动态库搜索路径/usr/lib;
RPATH与RUNPATH中间隔着LD_LIBRARY_PATH,可以通过修改LD_LIBRARY_PATH来指定.so文件,大多数编译器都将输出的RPATH留空,并用RUNPATH代替RPATH。
二、系统保护机制
ASLR(Address space layout randomization)是一种针对缓冲区溢出的安全保护技术,通过对堆、栈、共享库映射等线性区布局的随机化,通过增加攻击者预测目的地址的难度,防止攻击者直接定位攻击代码位置,达到阻止溢出攻击的目的。据研究表明ASLR可以有效的降低缓冲区溢出攻击的成功率,如今Linux、FreeBSD、MacOS、Windows等主流操作系统都已采用了该技术。通过以下方法可查询系统是否开启ASLR:
# 方法一:使用命令
sysctl -n kernel.randomize_va_space
# 方法二:查看文件
cat /proc/sys/kernel/randomize_va_space
查询之后显示一个数字:

数字含义如下:
| 值 | 定义 |
| 0 | 关闭ASLR |
| 1 | mmap base、stack、vdso page将随机化。这意味着.so文件将被加载到随机地址。链接时指定了-pie选项的可执行程序,其代码段加载地址将被随机化。配置内核时如果指定了CONFIG_COMPAT_BRK,randomize_va_space缺省为1。此时heap没有随机化。 |
| 2 | 在1的基础上增加了heap随机化。配置内核时如果禁用CONFIG_COMPAT_BRK,randomize_va_space缺省为2。 |
注意,当系统开启ASLR,程序关闭PIE,程序也是未随机化的。
参考链接:
https://blog.csdn.net/weixin_62675330/article/details/123203234
https://blog.csdn.net/Little_Small_Joze/article/details/114465018
https://blog.csdn.net/pwl999/article/details/111035160
https://blog.csdn.net/cszhouwei/article/details/43277347