我们先来看一个实例,使用pwntools的checksec对一个程序进行检测
RELRO(Relocation Read-Only):
设置符号重定位表格为只读或在程序启动时就解析并绑定所有动态符号,从而减少对 GOT 攻击。
(1)No RELRO:
在这种模式下关于重定位并不进行任何保护。
(2)Partial RELRO:
1.这种模式是gcc编译的默认模式。
2.一些段 (包括.init_array .fini_array .jcr .dynamic .got) 在初始化后将会被标识为只读。
3.ELF 部分被重新排序,以便 ELF 内部数据部分(.got、.dtors 等)在程序的数据部分(.data 和 .bss)之前。
4.对于攻击者来说,由于linux的lazy bind机制,(.plt.got)段依然可写,只是(.got)段不在可写。
(3)FULL RELRO:
1.Full RELRO 不是默认编译器设置,因为它可以大大增加程序启动时间,因为必须在程序启动之前解析所有符号。在需要链接数千个符号的大型程序中,这可能会导致启动时间明显延迟。
2.将会继承Partial RELRO的所有功能。
3.lazy bind 将被禁用,所有导入的符号都在startup time被解析。
4.Full RELRO 使整个 GOT 成为只读的,其中一个函数的 GOT 地址不会被另一个函数或者通过ROP gadget 覆盖。
关于重定位与Lazy Bind机制会再以后讲到
Canary:
Canary 不管是实现还是设计思想都比较简单高效,就是插入一个值在 stack overflow 发生的高危区域的尾部。当函数返回之时检测 Canary 的值是否经过了改变,以此来判断 stack/buffer overflow 是否发生。
canary通常有三种类型
1.Terminator canaries
由于大多数缓冲区溢出攻击都是基于以某些字符结束符终结的字符串操作。Terminator canaries是由零终止子,CR