一种基于多级指针的UAF漏洞防御方法与流程

文档序号:17588902发布日期:2019-05-03 21:35阅读:481来源:国知局
一种基于多级指针的UAF漏洞防御方法与流程

本发明属于本发明属于软件安全领域,更具体地,涉及一种基于多级指针的uaf漏洞防御方法。



背景技术:

内存错误漏洞一般分为两类:空间内存错误(数组越界错误、未初始化指针解引用、无效的类型转换错误、格式化字符串错误等)和时间内存错误(uaf、双重释放等)。对指针不合理的使用可能造成程序中存在野指针,野指针也是导致一些uaf等严重程序漏洞的根本原因。

uaf(use-after-free,释放后再使用)漏洞是指已分配的内存释放后,指向该区域的指针并没有置为null,之后又通过该野指针读、写已释放内存。这类漏洞会导致信息泄露以及任意代码执行等严重问题。并很可能引发任意代码执行。

要解决uaf的问题,并不能简单把释放堆对象的指针置为空指针就可以了。在实际的大型程序中,指针数量多、生命周期长、函数调用栈复杂、多线程间指针传递等导致一个指针的值可能存在多个不同的副本。这也是要准确地解决uaf才变得非常困难的主要原因之一。其次是多线程程序在运行时的不确定性,导致指针的值只有在运行时下才能确定,所以通过静态分析来准确检测漏洞的效果不够好。



技术实现要素:

针对现有技术的缺陷,本发明的目的在于解决现有技术难以解决uaf漏洞的技术问题。

为实现上述目的,第一方面,本发明实施例提供了一种基于多级指针的uaf漏洞防御方法,该方法包括以下步骤:

s1.将待防御的程序编译成中间语言;

s2.对中间语言中与指针和堆对象相关的操作,进行插桩和/或替换,得到处理后的中间语言文件;

s3.基于多级指针构建动态uaf漏洞防御组件;

s4.将所述动态uaf漏洞防御组件链接到所述处理后的中间语言文件,并将它们编译为安全可执行文件。

具体地,所述与指针和堆对象相关的操作包括:堆对象分配操作、指针解引用操作、带有指针计算的指针赋值操作和堆对象释放操作。

具体地,步骤s2包括以下步骤:

步骤s20.遍历中间语言的每一个操作,判断当前操作的类型,若当前操作为堆对象分配操作,进入步骤s21;若当前操作为指针解引用操作,进入步骤s22;若当前操作为带有指针计算的指针赋值操作,进入步骤s23;若当前操作为堆对象释放操作,进入步骤s24;若当前操作为其他操作,不进行任何处理;

步骤s21.堆对象分配操作将被替换为安全堆对象分配操作;

步骤s22.指针解引用操作插入检查代码;

步骤s23.带有指针计算的指针赋值操作将被插桩替换为带有追踪指针计算的指针赋值操作;

步骤s24.堆对象释放操作将被替换为安全堆对象释放操作。

具体地,步骤s3包括以下步骤:

步骤s31.构建用于监控堆对象分配操作的安全堆对象分配模块;

步骤s32.构建用于监控指针解引用操作的指针检查器;

步骤s33.构建用于监控带有指针计算的指针赋值操作的指针追踪器;

步骤s34.构建用于监控堆对象释放操作的安全堆对象释放模块。

具体地,所述安全堆对象分配模块的具体工作机制如下:

步骤s310.若监控到堆对象分配操作,申请一块用于存储基指针链表的头节点的第一堆内存;

步骤s311.申请一块与堆对象申请大小相同的第二堆内存,该内存用来满足对堆对象的内存请求;

步骤s312.将基指针链表的头节点指向第二堆内存的首地址;

步骤s313.通过反转第一堆内存地址值的最高位,对基指针链表的头节点的地址进行标记处理;

步骤s314.将标记处理后的头节点地址赋值给堆对象分配的指针。

具体地,所述指针检查器的具体工作机制如下:

步骤s320.若监控到指针解引用操作,判断待解引用的地址最高位是否被标记处理,如果是,说明该指针指向基指针,进入步骤s321,否则,说明该指针指向非堆区,直接解引用;

步骤s321.通过最高位反转去掉标记,再解引用去掉标记后的地址,到达基指针节点,进入步骤s322;

步骤s322.判断该基指针是否保存堆对象地址,如果是,则再解引用一次基指针所存储的对象的地址,到达堆对象;否则,直接解引用无效指针,导致程序崩溃。

具体地,所述指针检查器的具体工作机制还包括:步骤s323.打印出触发uaf行为解引用指针的相关信息和相应基指针链表每个节点。

具体地,所述指针追踪器的具体工作机制如下:

步骤s330.若监控到带有指针计算的指针赋值操作,设置临时变量,再判断指针计算表达式中等号右边指针是指向非堆区还是基指针节点,如果是指向非堆区,则将堆对象地址赋值给临时变量;如果是基指针节点,则解引用该指针到达基指针节点,并获取存储在该基指针节点的堆对象地址,并赋值给临时变量;

步骤s331.根据指针计算表达式和临时变量,计算表达式算出的新对象地址;

步骤s332.如果指针计算表达式中等号右边的指针指向的是非堆区对象,则直接将新的新对象地址赋值给指针计算表达式中等号左边的指针;如果指针计算表达式中等号右边的指针指向的是基指针节点,进入步骤s333;

步骤s333.从该基指针链表中查找是否存在一个指向新对象地址的节点,如果存在,则将标记后的该已存在节点的地址赋值给指针计算表达式中等号左边的指针;否则,进入步骤s334;

步骤s334.创建一个指向新对象地址的基指针节点,并插入到这个对象的基指针链表中,再将标记后的新创建节点的地址赋值给指针计算表达式中等号左边的指针。

具体地,所述安全堆对象释放模块的具体工作机制如下:

步骤s340.若监控到堆对象释放操作,获取基指针链表头节点的地址,遍历该基指针链表并将该链表上所有的节点并置为无效值,进入步骤s341;

步骤s341.把相应的堆对象释放。

第二方面,本发明实施例提供了一种计算机可读存储介质,该计算机可读存储介质上存储有计算机程序,该计算机程序被处理器执行时实现上述第一方面所述的uaf漏洞防御方法。

总体而言,通过本发明所构思的以上技术方案与现有技术相比,具有以下有益效果:

1.本发明基于多级指针的uaf漏洞防御机制,向原本的指针和对象关系中插入一级基指针节点,将普通指针与对象关系拓展为多级指针,通过基指针维护指针与堆对象的关系、基指针与基指针间的关系,在对象释放后,让基指针节点上的基指针失效,从而防止释放对象的指针访问内存,从而防止uaf漏洞的产生。

2.本发明通过将记录指针与对象关系的数据结构独立出来,形成与对象一一对应的基指针链表,降低对象释放后,需要在大的数据结构中找到有关的数据结构,带来更好的性能。

附图说明

图1为本发明实施例提供的一种基于多级指针的uaf漏洞防御方法流程图;

图2为本发明实施例提供的安全堆对象分配模块工作流程图;

图3为本发明实施例提供的指针追踪器工作流程图。

具体实施方式

为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。

如图1所示,一种基于多级指针的uaf漏洞防御方法,该方法包括以下步骤:

s1.将待防御的程序编译成中间语言;

s2.对中间语言中与指针和堆对象相关的操作,进行插桩和/或替换,得到处理后的中间语言文件;

s3.基于多级指针构建动态uaf漏洞防御组件;

s4.将所述动态uaf漏洞防御组件链接到所述处理后的中间语言文件,并将它们编译为安全可执行文件。

步骤s1.将待防御的程序编译成中间语言。

将待防御的程序通过编译器编译成中间语言。

步骤s2.对中间语言中与指针和堆对象相关的操作,进行插桩和/或替换,得到处理后的中间语言文件。

与指针和堆对象相关的操作包括:堆对象分配操作、指针解引用操作、带有指针计算的指针赋值操作和堆对象释放操作。步骤s2包括以下步骤:

步骤s20.遍历中间语言的每一个操作,判断当前操作的类型,若当前操作为堆对象分配操作,进入步骤s21;若当前操作为指针解引用操作,进入步骤s22;若当前操作为带有指针计算的指针赋值操作,进入步骤s23;若当前操作为堆对象释放操作,进入步骤s24;若当前操作为其他操作,不进行任何处理。

步骤s21.堆对象分配操作将被替换为安全堆对象分配操作。

例如,堆对象分配操作callmalloc(10),将被替换为安全堆对象分配操作callsecmalloc(10)。安全堆对象分配操作将在防御阶段用作对象管理器中安全堆对象分配模块入口。

步骤s22.指针解引用操作插入检查代码。

例如,指针解引用操作*p,插入检查代码后变为*ptrcheck(p),其中,p为指针。插入检查代码的指针解引用操作将在防御阶段用作指针检查器入口。

步骤s23.带有指针计算的指针赋值操作将被插桩替换为带有追踪指针计算的指针赋值操作。

例如,带有指针计算的指针赋值操作q=p+1,将被插桩替换为带有追踪指针计算的指针赋值操作q=getptr(p,ptrcheck(p)+1),其中,p、q为指针。带有追踪指针计算的指针赋值操作将在防御阶段用作指针追踪器的入口。

步骤s24.堆对象释放操作将被替换为安全堆对象释放操作。

例如,堆对象释放操作callfree(p)将被替换为安全堆对象释放操作callsecfree(p),其中,p为指针。安全堆对象释放操作将在防御阶段用作堆对象管理器中安全堆对象释放模块入口。

步骤s3.基于多级指针构建动态uaf漏洞防御组件。

动态uaf漏洞防御组件用于在安全可执行文件执行过程中,对指针和堆对象分配管理相关操作进行监控。动态uaf漏洞防御组件包括:安全堆对象分配模块、指针检查器、指针追踪器和安全堆对象释放模块。通过在原始指针和堆对象之间插入基指针,从而使得原始指针变为多级指针。

对于堆对象分配操作,安全堆对象分配模块先分配基指针头节点和堆对象,然后建立两者的关系。对于堆对象释放操作,安全堆对象释放模块先释放堆对象,然后找到所有基指针节点构成的链表,并将链表上的所有基指针置为无效。对于指针解引用操作,指针检查器判断当前指针是否为指向堆区的多级指针,若是,多解引用一次,实现对原本逻辑的堆地址的内存的读或写;否则,正常解引用指针。对于指针传播操作,且当前指针指向堆区,指针追踪器开启追踪,先查找基指针链表是否已存在对新对象地址的引用,存在则直接获取已存在基指针节点的地址;不存在则新建一个指向新地址的基指针节点。

步骤s3包括以下步骤:

步骤s31.构建用于监控堆对象分配操作的安全堆对象分配模块,所述安全堆对象分配模块的具体工作机制如下:

步骤s310.若监控到堆对象分配操作,申请一块用于存储基指针链表的头节点的第一堆内存。

如图2所示,通过malloc(bp)申请一块堆内存,该内存是用来存储基指针链表的头节点h,完成初始化基指针链表h。

步骤s311.申请一块与堆对象申请大小相同的第二堆内存,该内存用来满足对堆对象的内存请求。

如图2所示,通过malloc(size)申请一块大小为堆对象申请一样大的堆内存,该内存用来满足对堆对象1的内存请求,完成创建堆对象1。

步骤s312.将基指针链表的头节点指向第二堆内存的首地址。

如图2所示,通过将基指针链表的头节点指向第二堆内存的首地址,完成建立基指针头节点h与堆对象1的关系。

步骤s313.通过反转第一堆内存地址值的最高位,对基指针链表的头节点的地址进行标记处理。

在64位linux系统中,只有低48位被用于地址空间,高16位未被使用。64位地址中,最高16位在用户态为0x0000,内核态为0xffff。则反转后,用户态的地址最高16位为0x8000,内核态位为0x7fff。

步骤s314.将标记处理后的头节点地址赋值给堆对象分配的指针。

如图2所示,通过return&基指针头节点h将标记处理后的头节点地址赋值给堆对象分配的指针,&是取地址符,&基指针头节点h即为基指针头节点h的地址(该值是被反转最高位标记后的地址值)。在程序中,堆对象的分配函数一般会返回分配好的堆内存首地址,然后开发者会把该值赋值给一个指针,比如p=malloc(size),p指针保存堆对象的首地址;修改后p=secmalloc(size),p指针保存标记后基指针地址。

原始堆对象请求是通过malloc申请一块内存,并且将这块内存的首地址返回,外部调用完malloc后,会把返回的地址赋值给一个指针。在安全堆对象分配处理后,将基指针节点的地址返回,使得原始的指针和堆对象之间存在该基指针,本发明主要是要让所有指向堆对象的指针都通过基指针(可能是不同的,但是同一个堆对象一定是基指针链表上的节点)访问堆对象,安全堆对象分配就是初始化基指针链表,并完成原有的内存分配请求。

步骤s32.构建用于监控指针解引用操作的指针检查器,所述指针检查器的具体工作机制如下:

步骤s320.若监控到指针解引用操作,判断待解引用的地址最高位是否被标记处理,如果是,说明该指针指向基指针,进入步骤s321,否则,说明该指针指向非堆区,直接解引用。

指针的值最高位是否被反转决定该指针是否为指向堆区的多级指针。由于程序中,除了有指向堆区的指针,还有指向非堆区(栈区、全局变量等)的指针,由于本发明只在堆对象和与之相关的指针之间插入基指针,在指针解引用时,需要区分是原始未被本发明改变的指针(原本指向非堆区)还是指向基指针的指针(原本指向堆区),从而完成不同的解引用操作。直接接引用是指正常引用一次。

步骤s321.通过最高位反转去掉标记,再解引用去掉标记后的地址,到达基指针节点,进入步骤s322。

步骤s322.判断该基指针是否保存堆对象地址,如果是,则再解引用一次基指针所存储的对象的地址,到达堆对象;否则,直接解引用无效指针,导致程序崩溃。

若程序中有操作试图通过指针解引用,去访问一个已经释放的堆对象(uaf漏洞)。由于这些指针实际上都被改为多级指针(指向基指针而不是对象本身),它们都指向一条基指针链表中的某个基指针节点,而安全堆对象释放操作结束后,与该对象对应的基指针链表上的所有基指针节点都被设置为无效了。当存在通过指针访问已释放的对象,直接解引用无效值会引发程序段错误,故程序会直接崩溃,从而防御了uaf漏洞。

进一步地,步骤s32还可以包括:步骤s323.打印出触发uaf行为解引用指针的相关信息和相应基指针链表每个节点。

在控制台打印相关信息,是为了给用户或者开发者进行漏洞分析提供更多信息,知晓哪个指针产生uaf行为。

步骤s33.构建用于监控指针传播操作的指针追踪器,所述指针追踪器的具体工作机制如下:

步骤s330.若监控到指针传播操作,设置临时变量tmp,再判断指针计算表达式中等号右边指针是指向非堆区还是基指针节点,如果是指向非堆区,则将堆对象地址赋值给临时变量tmp;如果是基指针节点,则解引用该指针到达基指针节点,并获取存储在该基指针节点的堆对象地址,并赋值给临时变量tmp。

如图3所示,设置一个临时变量tmp,再判断指针计算表达式中的右边指针(p1或者p2)指向非堆区还是基指针节点(原本就指向堆区)。例如:q1=p1+10(堆区)或者q2=p2+10(栈区),这两个表达式用于区分指针指向非堆区和基指针的两种情况。

如果是指向非堆区,则将对象1地址(即p2的值,如图中所示该值为0x321)赋值临时变量tmp(tmp=p2,即tmp的值为0x321)。

如果是指向基指针节点(如图中的基指针h),则解引用该指针到达基指针节点(基指针h),并获取存储在该基指针节点的堆对象2地址(*p1的值,如图中所示该值为0x123)并赋值给临时变量tmp(tmp=*p1,即tmp的值为0x123)。

步骤s331.根据指针计算表达式和临时变量tmp,计算表达式算出的新对象地址。

如图3所示,根据指针计算表达式(q1=p1+10或者q2=p2+10)和临时变量tmp计算表达式,算出的新对象地址(tmp+10,对于q1=p1+10,tmp=*p1=0x123;对于q2=p2+10,tmp=p2=0x321)。

步骤s332.如果指针计算表达式中等号右边的指针指向的是非堆区对象,则直接将新的新对象地址赋值给指针计算表达式中等号左边的指针;如果指针计算表达式中等号右边的指针指向的是基指针节点,进入步骤s333。

如图3所示,如果表达式右边的指针(p2)指向的是对象2,则直接将新的新对象地址(tmp+10,此时tmp为0x321,则tmp+10为0x32b)直接赋值(返回)给计算表达式中等号左边的指针(q2,如图所示此值为0x32b)。如果中表达式右边的指针(p1)指向的是基指针节点,执行步骤s333。

步骤s333.从该基指针链表中查找是否存在一个指向新对象地址的节点,如果存在,则将标记后的该已存在节点的地址赋值给指针计算表达式中等号左边的指针;否则,进入步骤s334。

如图3所示,从该基指针链表中查找是否存在一个指向新对象1地址(tmp+1,此时tmp为0x123,则tmp+10为0x12d)的节点。如果存在(如图中所示为基指针1这个节点),则将标记后的该已存在节点的地址复制(返回)给原指针(q1);否则,执行步骤s334。

步骤s334.创建一个指向新对象地址的基指针节点,并插入到这个对象的基指针链表中,再将标记后的新创建节点的地址赋值给指针计算表达式中等号左边的指针。

如图3所示,首先创建一个指向新对象1地址(tmp+10,此时tmp为0x123,则tmp+10为0x12d)的基指针节点并插入到这个对象的基指针链表中(把基指针1节点插入到在基指针h节点后),再将标记后的新创建节点的地址赋值(返回)给计算表达式中等号左边的指针(q1)(一个新的标记处理后的基指针的地址,即&基指针1)。通过这种机制,增加基指针链表的节点,1个堆对象对应一张基指针链表。

步骤s34.构建用于监控堆对象释放操作的安全堆对象释放模块,所述安全堆对象释放模块的具体工作机制如下:

步骤s340.若监控到堆对象释放操作,获取基指针链表头节点的地址,遍历该基指针链表并将该链表上所有的节点并置为无效值,进入步骤s341。

因为指针的赋值(传播)都被指针追踪器追踪了,所以传递给对象管理器中安全堆对象释放的参数(指针)一定指向一个基指针头节点。由于指针可以指向对象的一个地址范围,并且存在指针计算表达式指针传播,所以一个对象的所有指针会指向不同的地址。由于指针追踪器会为指向同一个堆对象不同的地址生成不同的基指针,并用链表的方式把它们链接起来。所以一个对象的基指针链表会有若干个基指针节点,最少有一个基指针头节点。

步骤s341.把相应的堆对象释放。

步骤s4.将所述动态uaf漏洞防御组件链接到所述处理后的中间语言文件,并将它们编译为安全可执行文件。

uaf漏洞防御的验证阶段,在程序运行时(即加载安全可执行文件),程序执行每条操作时,持续判断操作类型,若执行到原始操作(未被插桩替换的操作),正常执行;若执行到对象管理器中安全堆对象分配操作时,进入对象管理器中安全堆对象分配模块进行防御;若执行到带有指针检查器的指针解引用操作时,进入指针检查器进行防御;若执行到指针追踪器的操作时,进入指针追踪器进行防御;若执行到安全堆对象释放的操作时,进入对象管理器中安全堆对象释放模块进行防御;若全部执行完毕,则正常退出。

以上,仅为本申请较佳的具体实施方式,但本申请的保护范围并不局限于此,任何熟悉本技术领域的技术人员在本申请揭露的技术范围内,可轻易想到的变化或替换,都应涵盖在本申请的保护范围之内。因此,本申请的保护范围应该以权利要求的保护范围为准。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1