Pwn学习总结(2):ELF保护知识篇

在学习下面的内容前,希望你对x86及amd64体系结构的汇编、Linux下的调用约定、ELF文件格式有一定的了解[1][2][3][4][5][7]。

一般在做Pwn的时候,出题方都会把Pwn的ELF二进制文件给出,以方便你进行分析。我们首先使用checksec查看一个示例ELF的各项保护属性,并以此为依托介绍各项保护属性。

    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      PIE enabled
    RWX:      Has RWX segments

1、Arch:介绍机器的体系架构、基本字长、大小端序。以本示例为例,体系结构为amd64,64位机,小端序。
2、RELRO(RELocation Read-Only,只读重定位)[6][8][9]:Linux下的动态链接机制通过GOT表和PLT表的协同作用调用外部函数,其中GOT表负责存储外部符号重定位后的地址。为了减少不必要的开销,Linux应用了懒设计思想,对外部符号的重定位直到调用时才发生,这要求GOT表可写,进而导致攻击者可以通过改写GOT表内容劫持控制流[10],因此有了RELRO安全保护机制。当RELRO机制完全开启(Full RELRO)时,ld动态链接器在跳转到程序入口点前一次性将GOT表中外部符号重定位完毕,并将GOT表所在节记为不可写,防止攻击者对GOT表的改写;当RELRO机制部分开启(Partial RELRO)时,GOT表仍然可写。
3、Stack(Canary,金丝雀):Canary是一种栈保护机制。x86的栈帧布局由高地址向低地址依次为:函数参数、返回地址、自动变量及数组。当程序员利用不进行大小边界检查的函数向自动变量类型的数组(缓冲区)中填充内容时,可能导致内容的大小超出缓冲区大小,进而覆盖到返回地址及函数参数。攻击者可通过构造特定的输入覆盖返回地址及函数参数,进而劫持控制流。为防止这种情况的发生,编译器的设计者在函数序言部分执行指令,使栈上“返回地址”与“自动变量及数组”间插入一特殊随机值,名为Canary。该值保存两份,一份在栈上,另一份在CPU的段寄存器中(段寄存器难以被攻击者破坏)。在本函数返回之前,编译器比对这两个值是否相等,若相等则按正常流程返回,否则跳转到出错处理程序,终止可能存在的异常控制流。
4、NX(Non-eXecuteable,不可执行位)[8]:在x86进化到64位字长之前,处理器对虚拟内存页面访问控制的标记只有1个Bit。分别标记该页为R或RW[10]。此时,所有页面上的内容都是可执行的。此时,只要程序中存在缓冲区溢出漏洞,攻击者即可按照先布局shellcode,再布局返回地址的方式,将控制流劫持到栈上的shellcode。为缓解此问题,AMD在推出64位处理器时加入了NX特性,可标志一个虚拟内存页面为“不可执行”,若IP指向不可执行页中的代码,处理器会产生相应的异常。在汇编器将汇编生成为ELF时,只有代码段所对应的Segment属性被标记为X,其他段均为非X。操作系统加载器在载入程序时,会将各Segment的访问控制属性映射到虚拟内存页面的访问控制属性。此时栈上的代码无法执行,也就缓解了上述所述的漏洞利用方式。在Windows上这种机制被称为DEP。
5、PIE(Position Independent Executable):开启了本选项的ELF程序,地址布局是随机化的。每次运行ELF的每个节、甚至是不同的库文件,都会被操作系统映射到随机的虚拟内存地址。这样加大了攻击者获取其想使用的敏感函数的实际虚拟地址的难度。这种机制在Windows上被称为ASLR[8]。
6、RWX(Read Write eXecute):查询ELF文件中是否存在同时可以读写执行的段。如果有的话,非常利于填充shellcode。

参考资料:
[1] 《汇编语言:基于x86处理器》
[2] https://gitlab.com/x86-psABIs/x86-64-ABI
[3] https://gitlab.com/x86-psABIs/i386-ABI
[4] https://ftp2.renjikai.com/CA/Calling-Convention/amd64-abi.pdf
[5] https://ftp2.renjikai.com/CA/Calling-Convention/i386-abi.pdf
[6] https://www.cnblogs.com/clingyu/p/8546619.html
[7] 《程序员的自我修养:链接,装载与库》
[8] https://blog.lao-yuan.com/2018/06/09/Linux-GCC%E5%AE%89%E5%85%A8%E4%BF%9D%E6%8A%A4%E6%9C%BA%E5%88%B6.html
[9] https://www.sohu.com/a/295470303_467784
[10] 感谢Foobar科学院twd2院士对本文章提供的大量支持。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注