内存保护机制

ASLR (Address Space Layout Randomization)

随机化栈上的地址

•/proc/sys/kernel/randomize_va_space = 0:没有随机化。即关闭 ASLR

•/proc/sys/kernel/randomize_va_space = 1:保留的随机化。共享库、栈、mmap() 以及 VDSO 将被随机化

•/proc/sys/kernel/randomize_va_space = 2:完全的随机化。在randomize_va_space = 1的基础上,通过 brk() 分配的内存空间也将被随机化

1
2
3
# 在Ubuntu上输入以下命令,可以发现系统开启了ASLR
ROP$ cat /proc/sys/kernel/randomize_va_space
2

PIE (Position-Independent Executable)

•随机化ELF文件的映射地址(随机化bss、data、text段地址)

•开启 ASLR 之后,PIE 才会生效

The NX bits (the No-eXecute bits)

•通过在内存页的标识中增加“执行”位, 可以表示该内存页是否可以执行, 若程序代码的 EIP 执行至不可运行的内存页, 则 CPU 将直接拒绝执行“指令”造成程序崩溃

Canary

•在刚进入函数时,在栈上放置一个标志canary,在函数返回时检测其是否被改变。以达到防护栈溢出的目的

•canary长度为1字长,其位置不一定与ebp/rbp存储的位置相邻,具体得看程序的汇编操作

RELRO (RELocate Read-Only)

•部分 RELRO: 在程序装入后, 将其中一些段(如.dynamic)标记为只读, 防止程序的一些重定位信息被修改

•完全 RELRO: 在部分 RELRO 的基础上, 在程序装入时, 直接解析完所有符号并填入对应的值, 此时所有的 GOT 表项都已初始化, 且不装入link_map与_dl_runtime_resolve的地址

编译pwn题

gcc的编译关于程序保护开启的选项:http://t.csdn.cn/3nNkP

加了-m32参数的二进制就是32位的,而没加这个参数的就是默认的64位的

1
2
3
4
5
ASLR:echo 0 > /proc/sys/kernel/randomize_va_space
NX:-z execstack / -z noexecstack (关闭 / 开启)
Canary:-fno-stack-protector /-fstack-protector / -fstack-protector-all (关闭 / 开启 / 全开启)
PIE:-no-pie / -pie (关闭 / 开启)
RELRO:-z norelro / -z lazy / -z now (关闭 / 部分开启 / 完全开启)

示例编译Pwn题

1
2
3
4
示例编译32bit:gcc -m32 -fno-stack-protector -z execstack -o pwn1 pwn1.c

-m32意思是编译为32位的程序
-fno-stack-protector和-z execstack这两个参数会分别关掉DEP和Stack Protector
1
示例编译64bit:gcc -fno-stack-protector -z execstack -o pwn1 pwn1.c