基于地址随机和段隔离的全局偏移表保护方法
【技术领域】
[0001] 本发明涉及计算机可执行文件安全技术领域,特别涉及一种基于地址随机和段隔 离的全局偏移表保护方法。
【背景技术】
[0002] 在动态链接的ELF程序中,所引用的外部符号分为两大类,一是对外地全局数据 (如全局变量)的引用,二是对外地全局函数的调用;引用和调用的位置分布在整个可执行 程序中。为了便于管理,ELF格式的可执行文件中定义了两个节.got和.got. pit,称为全 局偏移表GOT (Global Offset Table),专门用于集中存放可执行程序引用的各全局符号和 函数的目的地址,其中,全局数据符号的目的地址记录在.got节中,全局函数符号的目的 地址记录在.got. pit节中。
[0003] 出于执行效率的考虑,ELF程序通常采用延迟解析机制,只有在第一次真正引用时 才对全局库函数进行解析。解析程序获得库函数的真正的目的地址并将其写入到GOT表 中,因此GOT表必须是可写的。在Linux操作系统中,应用进程的地址空间布局是相对固定 的,特别地,应用进程的代码和数据段在地址空间中的位置是固定的,GOT表的位置也是固 定的,因而节.got. pit实际上是位于固定内存空间的一组可写的函数指针。利用这一属 性,恶意代码可以通过修改GOT表的值来劫持程序的控制流程。
[0004] 现有的GOT表保护方法,如RELR0,通过禁用延迟解析来保护GOT表,其实现思路 是:在为进程加载程序时,一次性解析所有的全局库函数,完成GOT表的初始化,而后将GOT 表所在的页标记为只读页,禁止再对其进行修改。然而函数解析工作比较耗时,加载时解析 所有的库函数会延缓程序的启动过程,而且很多库函数可能根本不会被执行到,对它们的 解析也是一种浪费,所以该方法并未在GCC编译器中默认启用。
【发明内容】
[0005] 针对现有技术中的不足,本发明提供一种基于地址随机和段隔离的全局偏移表保 护方法,增加随机化处理,性能开销较小,安全性能高,进一步防止恶意代码通过修改GOT 表值来劫持程序控制流程。
[0006] 按照本发明所提供的设计方案,一种基于地址随机和段隔离的全局偏移表保护方 法,包含如下步骤:
[0007] 步骤I. ELF程序完成加载后,随机申请内存空间,并将ELF节段内容拷贝到该 内存空间中,赋予新的节段名称,在ELF程序表头中定义加载字段PT_DYNAMIC,用于描 述· dynamic节的信息;
[0008] 步骤2.对步骤1中随机申请的内存空间创建段描述符,选择一个空闲的段寄存器 作为特殊段寄存器,将段描述符加载到该特殊段寄存器中;
[0009] 步骤3.修改程序表头及步骤1中赋予新的节段名称的节段内容,使之满足ELF中 节段的指向关系,并修改.Plt节中的代码,使其通过特殊段寄存器访问GOT表;
[0010] 步骤4.初始化动态链接器,修改程序表头中PT_DYNAMIC段内容,并隐藏.dynamic 节所在地址。
[0011] 上述的,所述步骤1中随机申请内存空间并将ELF节段内容拷贝到该内存空间 中具体包含随机地按需申请至少三页内存空间,包含可读可执行页、只可读页和可读可写 页,其中,.pit拷贝到可读可执行页中,记为.new. pit rel. pit拷贝到只可读页中,记 为· new. rel. pit ;· dynamic和· got. pit拷贝到可读可写页中,并分别记为· new. dynamic 和· new. got. pit〇
[0012] 上述的,步骤I中将ELF节段内容拷贝到该内存空间中,赋予新的节段名称具体 包含:将.pit、. rel. pit、. dynamic、. got. pit节的内容拷贝到该内存空间中,并分别标记 为· new. pit、· new. rel. pit、· new. dynamic、· new. got. pit,其中· pit 为过程链接表,通过 jmp指令对GOT表进行引用,.rel. pit包含与过程链接表相关联的重定向地址,.dynamic 用于提供动态链接器所需信息,.got. pit用于记录全局函数符号的目的地址。
[0013] 上述的,所述步骤3中ELF中节段的指向关系具体为ELF文件头指向ELF程序表 头内存位置,ELF程序表头指向加载字段PT_DYNAMIC内存位置,加载字段PT_DYNAMIC指 向· got. pit、· rel. pit的内存位置,通过· got. pit中的第一个函数初始值计算· pit内存 位置。
[0014] 本发明的有益效果:
[0015] 本发明克服现有技术中GOT表位置固定、保护困难、一次性解析所有库函数造成 资源浪费等问题,增加随机化处理,.Plt表中有对GOT表的引用,正常反汇编.pit表中的 代码可以知道GOT表地址,引入段隔离之后,在不知道段寄存器的段基地址的情况下,无法 计算出GOT表的地址,段基地址在用户态是没有权限读取的,让常规的对原来固定的GOT表 地址进行恶意代码劫持攻击失效,对尝试读取固定内存地址并计算出GOT表地址的方法恶 意攻击失效。
【附图说明】:
[0016] 图1为本发明的流程示意图;
[0017] 图2为实施例二流程示意图;
[0018] 图3为实施例二ELF各节点的指向关系示意图;
[0019] 图4为实施例二修改后的ELF各节点的指向关系示意图;
[0020] 图5为实施例二中PLT表结构示意图;
[0021] 图6为实施例二中PLT表和GOT表的关系示意图;
[0022] 图7为实施例二中Elf32_Dyn结构体定义示意图;
[0023] 图8为实施例三中Elf32_Rel和Elf32_Rela定义示意图;
[0024] 图9为实施例三中分配后的内存布局不意图;
[0025] 图10为实施例三中修改指令示意图。
【具体实施方式】:
[0026] 下面结合附图和技术方案对本发明作进一步详细的说明,并通过优选的实施例详 细说明本发明的实施方式,但本发明的实施方式并不限于此。
[0027] 实施例一,参见图1所示,基于地址随机和段隔离的全局偏移表保护方法,包含如 下步骤:
[0028] 步骤I. ELF程序完成加载后,随机申请内存空间,并将ELF节段内容拷贝到该 内存空间中,赋予新的节段名称,在ELF程序表头中定义加载字段PT_DYNAMIC,用于描 述· dynamic节的信息;
[0029] 步骤2.对步骤1中随机申请的内存空间创建段描述符,选择一个空闲的段寄存器 作为特殊段寄存器,将段描述符加载到该特殊段寄存器中;
[0030] 步骤3.修改程序表头及步骤1中赋予新的节段名称的节段内容,使之满足ELF中 节段的指向关系,并修改.Plt节中的代码,使其通过特殊段寄存器访问GOT表;
[0031] 步骤4.初始化动态链接器,修改程序表头中PT_DYNAMIC段内容,并隐藏.dynamic 节所在地址。
[0032] 增加随机化处理,让常规的对原来固定的GOT表地址进行恶意代码劫持攻击失 效,对尝试读取固定内存地址并计算出GOT表地址的方法恶意攻击失效,性能开销较小,安 全性能高,进一步防止恶意代码通过修改GOT表值来劫持程序控制流程。
[0033] 实施例二,参见图2~4所示,与实施例一基本相同,不同之处在于:所述步骤1中 随机申请内存空间并将ELF节段内容拷贝到该内存空间中具体包含随机地按需申请至少 三页内存空间,包含可读可执行页、只可读页和可读可写页,其中,.pit拷贝到可读可执行 页中,记为· new. pit ;· rel. pit拷贝到只可读页中,记为· new. rel. pit ;· dynamic和· got. pit拷贝到可读可写页中,并分别记为· new. dynamic和· new. got. pit,三页内存空间可以 是地址空间中任意未用的三页内存。
[0034] 优选的,步骤1中将ELF节段内容拷贝到该内存空间中,赋予新的节段名称具体 包含:将.pit、. rel. pit、. dynamic、. got. pit节的内容拷贝到该内存空间中,并分别标记 为· new. pit、· new. rel. pit、· new. dynamic、· new. got. pit,其中,· pit 为过程链接表,通 过jmp指令对GOT表进行引用,除PLTO之外,每个PLT表项由3条指令构成,PLT表结构如 图5所示,PLT表和GOT表的关系如图6所示,PLT表通过jmp指令对GOT表进行引用,在 未解析之前,GOT表中的值默认指向PLT+6的地址,即PLT中push指令的地址;在解析之 后,GOT表中的值是函数的目的地址;.rel. pit包含与过程链接表相关联的重定向地址,在 动态解析后将对应GOT表中的值改写为目标函数的真正地址时,根据.rel. pit节快速得到 到对应函数在GOT表中的地址;.dynamic用于提供动态链接器所需信息;.got. pit用于记 录全局函数符号的目的地址,第一项为.dynamic节所在地址,第二项为自身的链接映射结 构link_map的地址,第三项为动态链接器中符号解析函数_dl_runtime_resolve的入口地 址,第二项和第