StackGuard

gcc -o test test.c						// 默认情况下,不开启Canary保护
gcc -fno-stack-protector -o test test.c  //禁用栈保护
gcc -fstack-protector -o test test.c   //启用堆栈保护,不过只为局部变量中含有 char 数组的函数插入保护代码
gcc -fstack-protector-all -o test test.c //启用堆栈保护,为所有函数插入保护代码

FORTIFY

fority其实非常轻微的检查,用于检查是否存在缓冲区溢出的错误。适用情形是程序采用大量的字符串或者内存操作函数,如memcpy,memset,stpcpy,strcpy,strncpy,strcat,strncat,sprintf,snprintf,vsprintf,vsnprintf,gets以及宽字符的变体。

gcc -o test test.c							// 默认情况下,不会开这个检查
gcc -D_FORTIFY_SOURCE=1 -o test test.c		// 较弱的检查
gcc -D_FORTIFY_SOURCE=2 -o test test.c		// 较强的检查

NX(DEP)

NX即No-eXecute(不可执行)的意思,NX(DEP)的基本原理是将数据所在内存页标识为不可执行,当程序溢出成功转入shellcode时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执行恶意指令。

gcc -o test test.c					// 默认情况下,开启NX保护
gcc -z execstack -o test test.c		// 禁用NX保护
gcc -z noexecstack -o test test.c	// 开启NX保护

ASLR

每次执行时,栈、堆、库的位置都不一样

0 - 表示关闭进程地址空间随机化。
1 - 表示将mmap的基址,stack和vdso页面随机化。
2 - 表示在1的基础上增加栈(heap)的随机化。
sudo -s echo 0 > /proc/sys/kernel/randomize_va_space

ASLR 不负责代码段以及数据段的随机化工作,这项工作由 PIE 负责。但是只有在开启 ASLR 之后,PIE 才会生效

PIE

PIE(position-independent executable, 地址无关可执行文件)技术就是一个针对代码段.text, 数据段.data,.bss等固定地址的一个防护技术。同ASLR一样,应用了PIE的程序会在每次加载时都变换加载基址。没有开启的情况下.text, 数据段.data,.bss等段的地址是固定的。

如果不开启PIE的话,那么每次ELF文件加载的地址都是相同的。如果开启PIE,那么每次都会不同。

-fpie -pie	#即开启 PIE
-no-pie 	#关闭PIE保护
32位:	No PIE (0x8048000)
64位:	No PIE (0x400000)

RELRO

GCC, GNU linker以及Glibc-dynamic linker一起配合实现了一种叫做relro的技术: read only relocation。大概实现就是由linker指定binary的一块经过dynamic linker处理过 relocation之后的区域为只读.

设置符号重定向表格为只读或在程序启动时就解析并绑定所有动态符号,从而减少对GOT(Global Offset Table)攻击。RELRO为” Partial RELRO”,说明我们对GOT表具有写权限。

Partial RELRO:some sections(.init_array .fini_array .jcr .dynamic .got) are marked as read-only after they have been initialized by the dynamic loader

gcc -o test test.c						// 默认情况下,是Partial RELRO
gcc -z norelro -o test test.c			// 关闭,即No RELRO
gcc -z lazy -o test test.c				// 部分开启,即Partial RELRO
gcc -z now -o test test.c				// 全部开启,即

总结

  • NX:-z execstack / -z noexecstack (关闭 / 开启)
  • Canary:-fno-stack-protector /-fstack-protector / -fstack-protector-all (关闭 / 开启 / 全开启)
  • ASLR:sudo -s echo 0 > /proc/sys/kernel/randomize_va_space
  • `-fpie -pie -no-pie #关闭PIE保护
  • RELRO:-z norelro / -z lazy / -z now (关闭 / 部分开启 / 完全开启)