# 前言

ASLRPIE 是不同的,两者不能认为是同一个机制,但是他们都是对地址进行 随机化 ,只不过作用的 对象 和作用 时期 不太一样

# 1.ASLR (操作系统的功能):

ASLR 是 Linux操作系统 的功能选项,作用于程序 (ELF) 装入 内存 运行时。是一种针对缓冲区溢出的安全保护技术,通过对加载地址的随机化,防止攻击者直接定位攻击代码位置,到达阻止溢出攻击的一种技术。

# 打开 / 关闭 ASLR:

# 查看 ASLR 打开情况:

l
sudo cat /proc/sys/kernel/randomize_va_space

# 关闭 ALSR

1. 手动修改(长期生效):

修改的是 randomize_va_space 文件的枚举值,设置的值不同,linux 内核加载程序的地址空间的策略就会不同

l
# echo 0 > /proc/sys/kernel/randomize_va_space

2. 利用 sysctl 控制 ASLR (临时有效,重启后复原):

l
$ sysctl -w kernel.randomize_va_space=0

3. 利用 setarch 控制单独程序的随机化:

如果你想历史关闭单个程序的 ASLR,使用 setarch 是很好的选择。setarch 命令如其名,改变程序的运行架构环境,并可以自定义环境 flag。

l
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 表等的地址,需要加上一个固定的偏移量,例如:

n
base=main-e.symbols["main"] #获得基地址
write_plt=base + e.plt["write"] #计算真实地址
write_got=base + e.got["write"]

参考:

https://blog.51cto.com/duallay/1876841

https://www.mrskye.cn/archives/9058dffc/# 开启 - PIE