G06F21/57
1.一种Linux平台二进制软件堆溢漏洞动态检测系统,其特征在于,所述系统包括:二进制程序仿真加载模块、API函数挂钩模块、基于动态二进制翻译的二进制程序仿真执行模块、堆管理机制运行时托管模块、基于自定制机器码的异常报警模块,其中,二进制程序仿真加载模块根据目标程序对应的可执行文件格式,将其代码段、数据段内容载入到仿真执行环境中;API函数挂钩模块对载入到仿真执行环境中的二进制程序进行API挂钩,形成目标程序的仿真执行映像;基于动态二进制翻译的二进制程序仿真执行模块对所形成的仿真执行映像进行仿真执行;仿真执行期间目标程序发生malloc、realloc堆申请操作时,堆管理机制运行时托管模块将堆申请托管,返回给应用程序“边界精确”的内存区块;目标程序在执行中对申请得到的“边界精确”的内存区块进行读写访问时发生溢出时,基于自定制机器码的异常报警模块捕获溢出事件并通告用户该程序存在堆溢出漏洞。
2.根据权利要求1所述的Linux平台二进制软件堆溢漏洞动态检测系统,其特征在于,所述目标程序对应的可执行文件格式包括Windows平台下的PE文件格式,Linux平台下的ELF文件格式。
3.根据权利要求2所述的Linux平台二进制软件堆溢漏洞动态检测系统,其特征在于,所述二进制程序仿真加载模块基于ELF可执行文件格式对目标程序进行内容解析,确定出其代码部分、数据部分内容的内存映射信息,并映射到基于动态二进制翻译的二进制程序仿真执行模块的内存空间,调用目标环境内适配的动态链接器对该可执行文件里的外部导入项目进行动态重定位。
4.根据权利要求3所述的Linux平台二进制软件堆溢漏洞动态检测系统,其特征在于,所述基于动态二进制翻译的二进制程序仿真执行模块将客户体系结构的指令转换为主机平台下对应的机器指令,通过执行翻译得到的宿主机二进制代码对目标程序进行仿真执行。
5.根据权利要求1所述的Linux平台二进制软件堆溢漏洞动态检测系统,其特征在于,所述堆管理机制运行时托管模块将堆申请托管,旨在进行“边界精确”的内存申请,仅允许目标程序读写分配给它的内存区域,所有对其邻近区域的内存段发生的内存访问为非法报警。
6.一种Linux平台二进制软件堆溢漏洞动态检测方法,其特征在于,所述方法包括:
S1,根据目标程序对应的可执行文件格式,将代码段、数据段内容载入到仿真执行环境中;
S2,对载入到仿真执行环境中的二进制程序进行API挂钩,形成目标程序的仿真执行映像;
S3,对所形成的仿真执行映像进行仿真执行;
S4,仿真执行期间,如果目标程序发生malloc、realloc堆申请操作,将堆申请托管,返回给应用程序“边界精确”的内存区块;
S5,目标程序对所得到的“边界精确”的内存区块进行读写访问中发生溢出时,由于地址越界将访问到无效的内存页面并触发异常,进而通告用户程序存在堆溢出漏洞。
本发明属漏洞检测技术领域,特别涉及一种Linux平台二进制软件堆溢漏洞动态检测方法及系统。
堆溢出漏洞指程序在对其堆缓冲区进行写操作时,由于写入范围超出目标缓冲区的长度导致的程序漏洞。近年来,该型漏洞频繁在不同软件系统中被爆出,对信息安全产生严重危害。
模糊测试技术是当前二进制软件漏洞挖掘领域的主要方法。该方法产生大量输入实例,通过观察这些输入实例执行时是否触发异常确认目标软件是否存在漏洞。该策略可以有效挖掘栈溢出、除零等程序漏洞。然而由于堆溢出漏洞触发行为大多不会显示地产生执行异常,该方法当前在堆溢出漏洞挖掘方面效率较低。
作为当前工业界主流的二进制软件漏洞检测技术,模糊测试技术的一般运行流程如下:首先随机生成大量数据,随之将这些数据向应用程序的运行时地址空间注入,对目标程序的运行状况进行监测。当目标程序执行到目标缺陷程序点并触发崩溃时,即记录本次运行对应的输入为缺陷输入。随之继续迭代该过程直至某些分析者设定的终止条件满足。
从上可见,模糊测试技术能够有效检测出导致目标二进制程序执行崩溃的输入实例。这对于栈溢出漏洞而言,该检测原则是应用充分的(因为能够触发栈溢出漏洞的输入实例往往会将目标程序的EIP寄存器覆盖,劫持程序流程到非法区域进而产生崩溃),对于堆溢出漏洞则不然(因为触发堆溢出漏洞的输入实例往往仅仅能够覆盖堆缓冲区附近的内存区域,而这并不会造成控制流劫持、页面访问异常等执行崩溃事件)。由此导致基于崩溃检测的模糊测试方法在堆溢出漏洞检测方面效率普遍偏低。
针对上述问题,Google基于LLVM编译系统,在源码漏洞检测层面给出了AddressSanitizer解决方案。该方案在目标程序源码编译过程中隐式插入堆漏洞运行时检测代码。在运行时如果该检测代码判定出有堆漏洞触发,立即通过产生异常终止程序的执行。外围的模糊测试器可以通过检测对应类型的异常事件确认堆漏洞的存在。该方案目前与AFL、libFuzze等模糊测试器相结合,在源码漏洞挖掘领域已成为标杆级的应用范例。然而由于需要在有源码情况下基于编译系统进行插桩,该方法并不适用于对二进制程序的安全分析。
透过上述分析,可见二进制模糊测试技术虽然能够有效检测出栈溢出等触发时能够导致程序执行崩溃的输入实例,却不适用于对堆溢出等不会导致执行崩溃的漏洞进行检测;AddressSanitizer固然提供了较为理想的针对堆漏洞动态检测方案,却由于基于编译时插桩,仅适用于对有源码的目标程序进行安全分析,在二进制程序堆漏洞动态检测中效率相对低下。
因此,目前迫切需要本领域技术人员解决的一个技术问题就是:如何能够创新的提出一种有效的Linux平台二进制软件堆溢漏洞动态检测方法,克服现有技术的缺陷,满足实际应用中的更多需求。
本申请实施例的目的是提出一种Linux平台二进制软件堆溢漏洞动态检测方法及系统,依托于动态二进制翻译的用户模式软件虚拟机监控目标程序的执行轨迹,通过对堆管理机制的进行动态托管,将执行迹内发生的堆溢出行为转化为显示的异常事件,由此提升堆溢出漏洞的检测效率。
为解决上述技术问题,本申请实施例是这样实现的:
根据本申请实施例的第一方面,提出了一种Linux平台二进制软件堆溢漏洞动态检测系统,所述系统包括:二进制程序仿真加载模块、API函数挂钩模块、基于动态二进制翻译的二进制程序仿真执行模块、堆管理机制运行时托管模块、基于自定制机器码的异常报警模块,其中,二进制程序仿真加载模块根据目标程序对应的可执行文件格式,将其代码段、数据段内容载入到仿真执行环境中;API函数挂钩模块对载入到仿真执行环境中的二进制程序进行API挂钩,形成目标程序的仿真执行映像;基于动态二进制翻译的二进制程序仿真执行模块对所形成的仿真执行映像进行仿真执行;仿真执行期间目标程序发生malloc、realloc堆申请操作时,堆管理机制运行时托管模块将堆申请托管,返回给应用程序“边界精确”的内存区块;目标程序在执行中对申请得到的“边界精确”的内存区块进行读写访问时发生溢出时,基于自定制机器码的异常报警模块用于捕获溢出事件并通告用户该程序存在堆溢出漏洞。
基于本发明的Linux平台二进制软件堆溢漏洞动态检测系统的另一个实施例中,所述二进制程序仿真加载模块基于ELF可执行文件格式对目标程序进行内容解析,确定出其代码部分、数据部分内容的内存映射信息,并映射到基于动态二进制翻译的二进制程序仿真执行模块的内存空间,调用目标环境内适配的动态链接器对该可执行文件里的外部导入项目进行动态重定位。
基于本发明的Linux平台二进制软件堆溢漏洞动态检测系统的另一个实施例中,所述基于动态二进制翻译的二进制程序仿真执行模块将客户体系结构的指令转换为主机平台下对应的机器指令,通过执行翻译得到的宿主机二进制代码对目标程序进行仿真执行。
基于本发明的Linux平台二进制软件堆溢漏洞动态检测系统的另一个实施例中,所述堆管理机制运行时托管模块将堆申请托管,旨在进行“边界精确”的内存申请,仅允许目标程序读写分配给它的内存区域,所有对其邻近区域的内存段发生的内存访问为非法报警。
基于本发明实施例的另一个方面,公开一种Linux平台二进制软件堆溢漏洞动态检测方法,包括:S1,根据目标程序对应的可执行文件格式,将代码段、数据段内容载入到仿真执行环境中;
S2,对载入到仿真执行环境中的二进制程序进行API挂钩,形成目标程序的仿真执行映像;
S3,对所形成的仿真执行映像进行仿真执行;
S4,仿真执行期间,如果目标程序发生malloc、realloc堆申请操作,将堆申请托管,返回给应用程序“边界精确”的内存区块;
S5,目标程序对所得到的“边界精确”的内存区块进行读写访问中发生溢出时,由于地址越界将访问到无效的内存页面并触发异常,进而通告用户程序存在堆溢出漏洞。
本发明可以在输入实例导致堆溢出行为发生、但并不导致执行崩溃的情况下,实时判定该输入为可以触发堆溢出漏洞的验证输入(PoC)。由此强化基于模糊测试的漏洞挖掘技术的能力水平。
本申请的核心技术思想,旨在对目标程序执行轨迹的动态监控过程中,对其间发生的堆内存申请、释放操作进行动态托管,将原本不会触发异常的堆溢出越界访问行为“强制转化”成能够导致程序执行崩溃的异常事件。由此通过对执行异常事件的监视,确认目标程序的本次执行是否蕴含漏洞(含堆溢出漏洞)。
图1示出了根据本申请的一些实施例提供的Linux平台二进制软件堆溢漏洞动态检测系统的结构示意图;
图2示出了根据本申请的一些实施例提供的Linux平台二进制软件堆溢漏洞动态检测系统另一实施例的结构示意图;
图3示出了根据本申请的一些实施例提供的malloc挂钩实际申请的内存区域的示意图;
图4示出了根据本申请的一些实施例提供的程序运行于实施例1构建的执行迹堆溢出漏洞动态检测原型系统中的示意图;
图5示出了根据本申请的一些实施例提供的AFL的实验结果的示意图;
图6示出了根据本申请的实施例2的结果示意图;
图7示出了根据本申请的一些实施例提供的Linux平台二进制软件堆溢漏洞动态检测方法的流程示意图。
以下结合附图对本发明的具体实施方式作出详细说明。
图1示出了根据本申请的一些实施例提供的Linux平台二进制软件堆溢漏洞动态检测系统的示意图,结合图1对Linux平台二进制软件堆溢漏洞动态检测系统进行详细介绍,所述系统包括:二进制程序仿真加载模块101、API函数挂钩模块102、基于动态二进制翻译的二进制程序仿真执行模块103、堆管理机制运行时托管模块104、基于自定制机器码的异常报警模块105,其中,二进制程序仿真加载模块101根据目标程序对应的可执行文件格式,将其代码段、数据段内容载入到仿真执行环境中;API函数挂钩模块102对载入到仿真执行环境中的二进制程序进行API挂钩,形成目标程序的仿真执行映像;基于动态二进制翻译的二进制程序仿真执行模块103用于对所形成的仿真执行映像进行仿真执行;仿真执行期间目标程序发生malloc、realloc堆申请操作时,堆管理机制运行时托管模块104将堆申请托管,返回给应用程序“边界精确”的内存区块;目标程序在执行中对申请得到的“边界精确”的内存区块进行读写访问时发生溢出时,基于自定制机器码的异常报警模块105用于捕获溢出事件并通告用户该程序存在堆溢出漏洞。所述“边界精确”的边界访问权限被严格限制,区块对应范围的内存区域可读写,超出区块范围的内存区域不可读写。
具体实现时,参见图2,示出了根据本申请的一些实施例提供的Linux平台二进制软件堆溢漏洞动态检测系统另一实施例的结构示意图,二进制程序往往需遵从其目标运行平台所指定的文件格式,譬如Windows平台下的PE文件格式,Linux平台下的ELF文件格式等。这些文件格式指明了可执行文件中代码段、数据段等内容的磁盘文件组织形式及向内存映射的具体方式。
为使用仿真执行术对Linux平台下二进制应用程序的运行过程进行动态监控,本申请首先构建了对ELF可执行文件的仿真加载模块。该加载模块首先基于ELF可执行文件格式规约对给定目标程序进行内容解析,确定出其代码部分、数据部分内容的内存映射信息,随即将这些内容映射到仿真执行器的内存空间,并调用目标环境内适配的动态链接器对该可执行文件里的外部导入项目进行动态重定位,同时进行2.2节论述的API挂钩操作,由此形成完整的仿真执行镜像。
LD_PRELOAD是Linux系统的一个环境变量,它允许我们定义在目标程序运行前,优先加载入其地址空间的动态链接库。本申请利用Linux平台下的这一重要系统机制实现目标程序运行期间的API挂钩。具体而言,我们构建了一个在目标程序运行时,被LD_PRELOAD环境变量标明的动态链接库libhook.so,该动态链接库包含我们关注的系统函数func同名的函数定义func′。在动态链接器对目标程序进行加载时链接的时刻,将优先将libhook.so库内定义的func′函数链接到目标程序对应的func函数调用位置。由此实现目标程序对这些API函数的调用在运行时刻的动态劫持。
我们在libhook.so中对1)__libc_start_main函数、2)malloc、realloc等堆管理函数进行挂钩。基于对前者的挂钩,我们在目标程序启动时刻挂设了SIGTERM、SIGALRM等异常信号对应的事件处理函数,保证异常发生时分析引擎将立即调用“基于自定制机器码的异常报警模块”进行处理;对后者的挂钩则为堆管理机制运行时托管模块对堆申请操作的实时捕获提供了必要的监控条件。
指令仿真执行的具体办法分为解释和动态二进制翻译两种。前者一般首先将客户体系结构的指令转换为某种规整的中间表示,之后即对该中间表示解释执行;后者则将客户体系结构的指令转换为主机平台下对应的机器指令,直接执行翻译得到的二进制代码。
为兼容多种体系结构下目标程序的动态监控分析,本申请采用基于后者的仿真执行方式。对于给定的仿真执行映像和程序入口点位置,本申请构建的仿真执行引擎首先应用递归向下的反汇编算法提取仿真指令序列,并将这些指令转换成对应的微指令序列形式。然后根据微操作类型,提取出对应的以宿主机器指令描述的仿真执行模板。在完成模板中相关的指令操作数重定位后,将整合成代码块,最终生成对应于该源CPU指令的宿主机仿真执行代码。
以x86体系结构下的add eax,-16指令为例。仿真执行引擎首先分析出该指令对应的微操作序列,具体形式及对应意义如下:
对应于上述各种微操作的宿主机仿真执行二进制代码模板如下:
代码模板中出现的env->regs[R_EAX]对应于仿真环境中eax寄存器的存储位置,T0则为中间变量T0寄存器的仿真存储位置。
在将确定各个微操作及对应的仿真模板后,仿真执行引擎对各个模板整合成的仿真执行块进行代码重定位,将需要的指令操作数填充至对应的位置,得到完整的仿真执行代码块,由此实现目标程序的仿真执行。
系统堆管理的运行时托管,旨在进行“边界精确”的内存申请:即仅仅允许目标程序读写分配给它的内存区域,而所有对其邻近区域的内存段发生的内存访问为非法。当目标程序发生malloc函数调用请求length字节长度的内存空间时,我们的malloc钩子将使用mmap系统调用分配如下图所示的内存空间。
如图3,对于length长度的malloc请求,我们使用mmap系统调用一共分配出8+length+1k字节的内存空间(这里假定我们的目标程序为32位ELF格式可执行程序)。其中real-chunk部分即为我们要返回给目标程序的length字节长度分配内存。该区域之后的1页内存区域对应的访问权限被设置为PROT_NONE,以保证当目标程序运行时发生读/写访问到该区域,将由于访问不合法产生SEGMENTATION FAULT信号,进而实现堆内存访问向上溢出的实时检测;位于real-chunk区域低地址端紧邻的4个字节则被设置为我们预置的特定字节canary。如果应用程序随后对该部分内存发生写访问,则在应用程序结束时刻设置的挂钩函数会检测canary的不同,进而确认堆内存访问向下溢出事件的发生。
当目标程序由于堆访问越界发生异常时,在二进制程序仿真加载模块节挂设的异常事件信号处理回调函数将被触发。这些都发生在动态二进制翻译的软件虚拟机内。我们需要从虚拟机内将该异常消息告知运行在宿主机上的虚拟机监控器。在这里,我们以类似于S2E符号执行引擎的方式通过自定制机器码实现该过程。
自定制的“异常发生指令”机器码,如下:0x0f 0x3f 0x00 0x00 0x00 0x00。
该“异常发生指令”指令在信号处理函数内被执行。在动态二进制翻译的软件虚拟CPU中,我们补充对该指令的译码执行操作,为其添加“通告虚拟机监控器目标程序发生异常”这一指令操作语义。由此实现虚拟机内目标程序异常向外围监控器的实时报警。
实施例1:执行迹堆溢出漏洞动态检测原型系统
基于QEMU虚拟机的用户态仿真组件构建了堆溢出漏洞动态检测原型系统。对给定的目标程序和具体输入,该系统沿着具体输入对应的程序执行轨迹进行动态追踪,当发现有堆溢出行为发生时,无论是否该行为会产生异常,都会立即向用户发出报警。
实施例2:基于模糊测试的堆溢出漏洞动态挖掘原型系统
我们将实施例1构建的堆溢出漏洞动态检测原型系统和当前漏洞挖掘方面应用较为广泛的模糊测试器AFL相结合,形成了基于模糊测试的堆溢出漏洞动态挖掘原型系统。该系统较之于原始的AFL模糊测试器,可以有效检出能够触发堆溢出行为的输入实例。
实验实例1:为验证实施例1对单个程序执行迹中堆溢出漏洞的动态检测能力,我们以如下程序作为目标程序。可见该程序存在一个很明显的堆溢出写操作。
我们在64位Ubuntu-16.04操作系统上将该程序编译为32位i386架构下的ELF可执行程序test-p0。在该程序运行时通过标准输入传入32个字节给buffer缓冲区,test-p0程序却并未崩溃(因为超出buffer的额外的16个字节的内存写访问并未触发内存页面访问异常)。
我们将该程序运行于实施例1构建的执行迹堆溢出漏洞动态检测原型系统中,结果如图4所示。
可见,基于本申请提出的堆管理运行时托管机制,原型系统在对目标程序的执行监控过程中,将堆内存访问地址越界行为转化成监测系统内执行崩溃事件,由此成功产生溢出行为报警。
实验实例2:为验证实施例2在堆溢出漏洞挖掘方面的有效性,我们以上述程序作为测试目标,以共同的不会触发漏洞行为的输入实例作为模糊测试的起始种子集合,分别启动实施例2和AFL进行漏洞挖掘。
AFL的实验结果如图5。可见,经过2271轮次迭代,模糊测试器仍然未发现堆溢出漏洞。
实施例2的结果如图6所示。可见,仅仅运行1秒(经过19轮迭代)后,基于本申请改进的AFL漏洞挖掘系统即可成功发现堆溢出漏洞,并生成相应的能够触发堆溢出行为的输入实例。
图7示出了根据本申请的一些实施例提供的Linux平台二进制软件堆溢漏洞动态检测方法的流程示意图,结合图7对示例实施例中的Linux平台二进制软件堆溢漏洞动态检测方法进行详细的说明。Linux平台二进制软件堆溢漏洞动态检测方法包括:
S1,根据目标程序对应的可执行文件格式,将代码段、数据段内容载入到仿真执行环境中;
S2,对载入到仿真执行环境中的二进制程序进行API挂钩,形成目标程序的仿真执行映像;
S3,对所形成的仿真执行映像进行仿真执行;
S4,仿真执行期间,如果目标程序发生malloc、realloc堆申请操作,将堆申请托管,返回给应用程序“边界精确”的内存区块;
S5,目标程序对所得到的“边界精确”的内存区块进行读写访问中发生溢出时,由于地址越界将访问到无效的内存页面并触发异常,进而通告用户程序存在堆溢出漏洞。
具体实现中,1)二进制程序仿真加载器根据目标程序对应的可执行文件格式,将其代码段、数据段等内容载入到仿真执行环境中;2)API函数挂钩模块对载入到仿真内存中的二进制程序进行API挂钩,由此形成目标程序的仿真执行映像;3)基于动态二进制翻译的仿真执行模块随即对该执行映像进行仿真执行;4)仿真执行期间,如果目标程序发生malloc、realloc等堆申请操作,堆管理机制运行时托管模块随即将该请求托管,返回给应用程序“边界精确”的内存区块;5)目标程序在随后执行中对第4步申请得到的“边界精确”的内存区块进行读写访问时发生溢出。由于地址越界访问到无效的内存页面,该行为触发“访问违例”的异常事件。该事件被“基于自定制机器码的异常报警模块”捕获,随即通告用户该程序存在堆溢出漏洞。
对于本领域技术人员而言,显然本发明实施例不限于上述示范性实施例的细节,而且在不背离本发明实施例的精神或基本特征的情况下,能够以其他的具体形式实现本发明实施例。因此,无论从哪一点来看,均应将实施例看作是示范性的,而且是非限制性的,本发明实施例的范围由所附权利要求而不是上述说明限定,因此旨在将落在权利要求的等同要件的含义和范围内的所有变化涵括在本发明实施例内。不应将权利要求中的任何附图标记视为限制所涉及的权利要求。此外,显然“包括”一词不排除其他单元或步骤,单数不排除复数。系统、装置或终端权利要求中陈述的多个单元、模块或装置也可以由同一个单元、模块或装置通过软件或者硬件来实现。第一,第二等词语用来表示名称,而并不表示任何特定的顺序。
最后应说明的是,以上实施方式仅用以说明本发明实施例的技术方案而非限制,尽管参照以上较佳实施方式对本发明实施例进行了详细说明,本领域的普通技术人员应当理解,可以对本发明实施例的技术方案进行修改或等同替换都不应脱离本发明实施例的技术方案的精神和范围。
本文发布于:2023-04-14 11:14:34,感谢您对本站的认可!
本文链接:https://patent.en369.cn/patent/3/86586.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |