Linux程序与系统的保护机制简介

一、程序保护机制

Linux程序通常是ELF格式的,关于程序的保护机制有如下几种:

序号名称作用
1RELRO将符号重定位表(.got)设置为只读
2Stack-canary栈溢出保护,加入类似cookie验证
3NX栈中数据没有执行权限
4PIE随机化,生成与位置无关可执行文件,类似ASLR
5FORTIFY由GCC实现的源码级别的保护机制,使用危险函数时会检查边界
6RPATH在搜索程序的间接依赖库时,RPATH起作用
7RUNPATH在使用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参数示例
1RELRO-z norelro (关闭)
-z lazy (部分开启)
-z now (全开启)
2Stack-canary-fno-stack-protector (关闭)
-fstack-protector (开启)
-fstack-protector-all (全开启) 
3NX-z execstack (关闭)
-z noexecstack(开启)
4PIE-no-pie / -pie (关闭 / 开启)
-fpie -pie (开启PIE,此时强度为1)
-fPIE -pie (开启PIE,此时为最高强度2,注意是大写的fPIE)
5FORTIFY-D_FORTIFY_SOURCE=1 (较弱的检查)
-D_FORTIFY_SOURCE=2 (较强的检查)
6RPATHgcc -L. main.c -Wl,--rpath='.',--disable-new-dtags -o main
7RUNPATHgcc -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
1mmap 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

https://www.cnblogs.com/ar-cheng/p/13225342.html

https://www.jianshu.com/p/0f25748e6ac7