# 前言
ASLR与PIE是不同的,两者不能认为是同一个机制,但是他们都是对地址进行随机化,只不过作用的对象和作用时期不太一样
# 1.ASLR(操作系统的功能):
ASLR是Linux操作系统的功能选项,作用于程序(ELF)装入内存运行时。是一种针对缓冲区溢出的安全保护技术,通过对加载地址的随机化,防止攻击者直接定位攻击代码位置,到达阻止溢出攻击的一种技术。
# 打开/关闭ASLR:
# 查看ASLR打开情况:
sudo cat /proc/sys/kernel/randomize_va_space
# 关闭ALSR
1.手动修改(长期生效):
修改的是randomize_va_space文件的枚举值,设置的值不同,linux内核加载程序的地址空间的策略就会不同
# echo 0 > /proc/sys/kernel/randomize_va_space
2.利用sysctl控制ASLR(临时有效,重启后复原):
$ sysctl -w kernel.randomize_va_space=0
3.利用setarch控制单独程序的随机化:
如果你想历史关闭单个程序的ASLR,使用setarch是很好的选择。setarch命令如其名,改变程序的运行架构环境,并可以自定义环境flag。
setarch `uname -m` -R ./your_program
R参数代表关闭地址空间随机化(开启ADDR_NO_RANDOMIZE)
4.gbd中关闭和开启:
在调试特定程序时,可以通过set disable-randomization命令开启或者关闭地址空间随机化。默认是关闭随机化的,也就是on状态
关闭ASLR:
set disable-randomization on
开启ASLR:
set disable-randomization off
查看ASLR状态:
show disable-randomization
# ASLR保护:
Linux下的ASLR总共有三个级别:0、1、2
0:关闭ASLR,没有进行随机化,堆栈基地址每次都相同,并且libc.so每次的地址也相同。
1:普通的ASLR。mmap基地址、栈基地址、.so加载基地址(共享库(.so\libraries))都将被随机化;但是堆没有随机化
2:在1的基础上加上了堆基地址的随机化
# 2.PIE(编译器的功能):
PIE叫做代码部分地址无关,PIE是我们在编译(gcc)时可以选择的功能,作用于程序(ELF)编译过程。其针对的是代码段(.text),数据段(.data),为初始化全局变量(.bbs)等固定地址的防护,程序在开启了pie时,每次加载程序都会时程序的加载地址改变
# 开启PIE:
在使用 gcc 编译时加入命令参数 -fPIE
# 3.开启ASLR+PIE:
开启ASLR+PIE的一个直接的困扰就是,你会发现没有地方可以写,所有的got表、plt表、bss段地址都是不确定的。只有通过泄漏才可以确定地址,所以我们想利用时,必须先泄露函数的地址然后算出libc的基址才行。
【注意】
由于PIE将代码地址随机化了,我们就不能够直接通过EFL来获取got表和plt表等的地址,需要加上一个固定的偏移量,例如:
base=main-e.symbols["main"] #获得基地址
write_plt=base + e.plt["write"] #计算真实地址
write_got=base + e.got["write"]
参考: