CN101847121B - 一种软件漏洞挖掘方法 - Google Patents

一种软件漏洞挖掘方法 Download PDF

Info

Publication number
CN101847121B
CN101847121B CN2010101719790A CN201010171979A CN101847121B CN 101847121 B CN101847121 B CN 101847121B CN 2010101719790 A CN2010101719790 A CN 2010101719790A CN 201010171979 A CN201010171979 A CN 201010171979A CN 101847121 B CN101847121 B CN 101847121B
Authority
CN
China
Prior art keywords
data
target program
instruction
verification
input
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Expired - Fee Related
Application number
CN2010101719790A
Other languages
English (en)
Other versions
CN101847121A (zh
Inventor
王铁磊
韦韬
邹维
张超
戴帅夫
丁羽
李义春
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Peking University
Original Assignee
Peking University
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Peking University filed Critical Peking University
Priority to CN2010101719790A priority Critical patent/CN101847121B/zh
Publication of CN101847121A publication Critical patent/CN101847121A/zh
Application granted granted Critical
Publication of CN101847121B publication Critical patent/CN101847121B/zh
Expired - Fee Related legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Images

Landscapes

  • Debugging And Monitoring (AREA)

Abstract

本发明公开了一种软件漏洞挖掘方法,属于软件工程和信息安全领域。本方法为:1)将多个正常数据输入目标程序,收集该目标程序的运行时信息;2)生成畸形数据,并将其输入该目标程序,收集该目标程序的运行时信息;3)根据1)、2)收集的运行时信息,识别该目标程序中校验和的检测代码;4)修改校验和的检测代码,使得目标程序处理畸形数据时的执行行为与处理正常数据时一致;5)生成若干畸形数据并输入修改后的目标程序,将使其崩溃的畸形数据作为样本数据;6)修改每个样本数据中校验和的域值并将其输入原目标程序,如果原目标程序崩溃或发生异常则报告一个潜在的安全漏洞。与现有技术相比,本发明可以大大提高漏洞挖掘的效率。

Description

一种软件漏洞挖掘方法
技术领域
本发明属于软件工程和信息安全领域,具体涉及一种软件漏洞挖掘方法。
背景技术
软件安全问题已经成为信息系统诸多安全问题的根源之一,如何发现软件中的安全漏洞至关重要。一种常见的软件漏洞挖掘技术是通过对目标软件的正常输入随机修改,从而构造大量畸形数据作为程序输入,在程序处理这些畸形数据时,观测目标程序的表现,一旦程序发生异常,则发现了一个潜在的安全问题。
然而,很多文件格式和网络协议中都含有校验和(checksum)信息。校验和是一种常用的数据完整性检测方法。例如,TCP/IP协议报文中含有整个报文的校验和值、PNG图片中为每个数据块都保存了校验和值。应用程序在处理具有校验和的输入时,通常会重新计算一个校验值,并与输入中的校验和相比较。
进一步地,为表述方便,假设输入数据由两部分组成:数据部分D和校验和部分C。常见的基于校验和的输入数据完整性检测模式如下:
if(Checksum(D)!=C)
   error();
程序在处理每个输入时,通常会重新计算该输入的校验和Checksum(D),这里Checksum()代表不同的校验和算法。程序进一步比较Checksum(D)和输入数据中的C,如果二者不一致,意味着输入数据已经遭到了破坏,程序就不会再处理这个输入(例如,生成错误信息后退出)。
校验和给软件动态漏洞挖掘方法带来很多困难,特别是在文件格式和协议格式不公开的情况下。对正常数据的随机修改将导致整个数据的完整性遭到破坏,而目标程序内部通过校验和检测就能发现输入数据遭到破坏,这导致传统动态漏洞挖掘技术生成的畸形数据很难对目标程序做到有效测试。特别地,当校验和算法未知,文件格式和协议格式不公开的情况下,现有的大部分软件动态漏洞挖掘技术都无法对目标程序有效测试和分析。
校验和函数本质上是单向哈希函数,很难找到具有相同的校验值的不同数据。例如,对正常数据部分D修改后的数据部分为D’,针对D’重新计算的校验和Checksum(D’)很难与原始数据中的校验和C一致。类似地,对原始数据中校验和部分C的修改为C’,Checksum(D)也不可能与C’一致。
发明内容
本发明的目的在于克服现有软件动态漏洞挖掘技术的不足,提供一种软件漏洞挖掘方法,特别是当输入格式中含有校验和信息时,本发明依然能对目标程序有效测试。
本发明所提出一种动态软件漏洞挖掘方法,其步骤包括:
1.对目标程序输入多个正常数据,收集程序处理每个正常数据的运行时信息;
2.基于步骤1收集的运行时信息,修改正常数据,生成畸形数据;
3.对目标程序输入多个畸形数据,收集程序处理每个畸形数据的运行时信息;
4.基于步骤1、3收集的运行时信息,识别程序中进行校验和检测的代码,具体地说,定位程序中用于检测校验和的条件跳转语句:在输入正常数据时,这些条件跳转语句一直发生跳转/不发生跳转,在输入畸形数据时,这些条件跳转语句一直不发生跳转/发生跳转;
5.基于步骤4的输出,修改目标程序;具体地说,更改步骤4中定位的条件跳转指令,使得即使输入畸形数据,目标程序的执行行为与输入正常数据时一致;
6.生成大量畸形数据,对修改后的目标程序进行测试;
7.对于能够使修改后的程序崩溃的畸形样本,修改该样本中的校验和域,使原目标程序处理修改后的样本数据时的执行行为与处理正常数据时一致(即使修改后的样本数据能够通过原始目标程序的校验和检测),生成新的畸形样本;
8.将步骤7中生成的畸形样本,重新输入至原始目标程序。如果程序处理该样本时仍然崩溃,收集程序执行的调用栈以及执行上下文信息(例如当时寄存器信息),并报告一个潜在的安全漏洞。
进一步地,上述步骤1在处理每个正常输入时包括:
1.a)基于系统调用劫持技术(HOOK),劫持文件打开(例如UNIX系统里open()函数)、文件读取(例如UNIX系统里read()函数)、文件关闭(例如UNIX系统中close()函数),以及网络数据操作函数,监控目标程序对正常数据的读入。根据操作系统不同以及对输入数据关注点不同,可以对需要劫持的函数范围适当修改,以达到最佳效果。
1.b)当目标程序将正常数据读入内存时,进一步地记录相应内存地址与输入数据之间的依赖关系;特别地,以每个字节在正常输入数据中的位置偏移标示该字节,详细记录每个内存单元来源于哪些字节。
1.c)基于代码植入技术(Code Instrumentation),在目标程序的每条机器指令前都植入监控代码,跟踪输入数据的每个字节在程序运行的传播。特别的,根据不同指令的语意信息,植入不同的监控代码,监控每条指令的执行。
a)对于算术运算(例如add,sub,mul)和逻辑运算(例如and,or,xor)指令,目的操作数依赖的输入字节信息等于所有源操作数依赖的输入字节的并集。
b)对于数据传送指令(例如mov,stos),目的操作数依赖的输入字节信息等于源操作数所依赖的输入字节信息。
c)对于能够影响EFLAGS的指令(例如test,add,or),记录EFLAGS依赖的输入字节信息等于所有操作数依赖的输入字节的并集。特别地,记录该指令中第一个操作数和第二个操作数所依赖的输入字节信息。
d)对于条件跳转指令(例如JNZ,JBE,JL),检查EFLAGS依赖多少输入字节。如果EFLAGS依赖的输入字节个数超过一个预定义的数值(用户指定),输出该跳转指令的地址、跳转是否发生、以及影响EFLAGS的指令的第一个操作数和第二个操作数所依赖的输入字节信息。例如,“0x8000 je 0x8010”代表地址0x8000处的je指令的目的地址是0x8010,如果执行该指令后发生跳转,而EFLAGS依赖的输入字节个数超过了预定的数值,该步骤输出指令地址0x8000、该指令发生跳转以及影响EFLAGS的指令的第一个操作数和第二个操作数所依赖的输入字节信息。
e)类似的,对于其他类型的指令(例如setnz),根据指令的语意植入相应的监控代码。
步骤1输出的程序运行时信息包括:1)依赖的输入字节数目超过预定值的条件跳转指令,2)这些跳转指令是否发生跳转,3)影响这些指令中所用到的标志寄存器EFLAGS的指令的第一个操作数和第二个操作数所依赖的输入字节信息。
进一步地,上述步骤2包括:
2.a)对步骤1中所使用的正常数据,进行修改生成畸形样本。特别地,按照步骤1输出的条件跳转指令的先后顺序,依次将这些条件跳转指令所依赖的输入字节替换成随机值,生成畸形样本。
进一步地,上述步骤3与步骤1类似,但是输入步骤2中生成畸形数据,收集目标程序处理畸形样本时的运行时信息。
进一步地,上述步骤4包括:
4.a)对于步骤1中输出的程序运行时信息,统计两个集合:P0和P1。其中,P0包含步骤1中输出的条件跳转指令中没有发生跳转的指令;P1包含步骤1中输出的条件跳转指令中发生跳转的指令。而且,P0∪P1中的每个条件跳转指令中所使用的标志寄存器EFLAGS依赖的输入字节数目均超过了预定义的数值。
4.b)对于步骤3中输出的程序运行时信息,统计计算两个集合P0′和P1′。其中,P0′包含步骤3中输出的条件跳转指令中没有发生跳转的指令;P1′包含步骤3中输出的条件跳转指令中发生跳转的指令。而且,P0′∪P1′中的每个条件跳转指令中所使用的标志寄存器EFLAGS依赖的输入字节数目均超过了预定义的数值。
4.c)计算(P1∩P0′)∪(P0∩P1′)。该集合中包含的条件跳转指令在输入正常数据和畸形数据时表现完全不同:输入正常数据时,这些跳转指令一直发生跳转/不跳转,但是输入畸形数据时,这些跳转指令一直不跳转/发生跳转。
4.d)根据步骤1和步骤3中的输出信息,对(P1∩P0′)∪(P0∩P1′)中每一个条件跳转指令i,查找影响该条件跳转指令i所使用的标志寄存器EFLAGS的指令j,检测指令j的第一个操作数和第二个操作数所依赖的输入字节信息;如果第一个操作数依赖的输入字节个数超过第二个操作数所依赖的输入字节个数,将第二个操作数所依赖的输入字节作为输入样本中的校验和域;如果第二个操作数依赖的输入字节个数超过第一个操作数所依赖的输入字节个数,将第一个操作数所依赖的输入字节作为输入样本中的校验和域;
4.e)输出(P1∩P0′)∪(P0∩P1′)中的条件跳转指令,将这些指令作为校验和检测语句。
进一步地,上述步骤5对目标程序修改包括:
5.a)定位步骤4中输出的条件跳转指令在目标程序的位置。
5.b)如果输入正常样本时,条件跳转指令一直发生跳转。为表述方便,将条件跳转指令的跳转地址记做Addr。将目标程序中的条件跳转指令修改为直接跳转指令,其中,直接跳转指令的目的地址为Addr。
5.c)如果输入正常样本时,条件跳转指令一直不发生跳转,将目标程序中的条件跳转指令修改为等长的nop指令。
进一步地,上述步骤6对步骤5修改后的目标程序测试包括:
6.a)对正常数据修改,生成大量畸形样本。修改规则包括但不限于:
[1].将正常数据的每一个字节逐一替换为随机值;
[2].将正常数据的每一个字节逐一替换为用户定义的数值;
[3].将正常数据的连续N个字节(N可以为2、4、8或由用户指定)逐一替换为连续N个字节的随机值;
[4].将正常数据的连续N个字节(N可以为2、4、8或由用户指定)逐一替换为连续N个字节的用户定义的数值;
[5].用户自定义的其他修改策略。
6.b)逐一将畸形数据输入至步骤5修改后的目标程序,如果修改后的目标程序崩溃,记录所输入的畸形数据。
进一步地,上述步骤7对步骤6输出的畸形数据修复包括:
7.a)将畸形数据输入至原始的目标程序;
7.b)在调试模式下,在步骤4中输出的(P1∩P0′)∪(P0∩P1′)中的条件跳转指令设置断点;
7.c)断点触发后,如果该条件跳转指令在输入正常样本时不跳转/跳转,在输入当前的畸形数据时也不跳转/跳转,继续执行;
7.d)否则,如果该条件跳转指令在输入正常样本时不跳转/跳转,但是在输入当前的畸形数据时跳转/不跳转,回溯查找影响该条件跳转指令所使用的标志寄存器EFLAGS的指令i,进一步检查指令i的操作数:如果指令i的第一个操作数来源于畸形数据的校验和域,将畸形数据的校验和域替换为指令i的第二个操作数的数值;如果指令i的第二个操作数来源于畸形数据的校验和域,将畸形数据的校验和域替换为指令i的第一个操作数的数值;
7.e)输出修复后的畸形数据。
进一步地,上述步骤7对步骤6输出的畸形数据修复的另外一种形式包括:
7.f)将畸形数据输入至原始的目标程序;
7.g)将畸形数据中的校验和域视为符号值,基于符号执行技术运行目标程序;
7.h)在目标程序执行过程中,收集程序执行路径上的约束条件。
7.i)当目标程序执行到步骤4中输出的(P1∩P0′)∪(P0∩P1′)中的条件跳转指令时:如果该条件跳转指令在输入正常样本时不跳转/跳转,在输入当前的畸形数据时也不跳转/跳转,收集路径约束条件,继续执行;
7.j)否则,如果该条件跳转指令在输入正常样本时不跳转/跳转,但是在输入当前的畸形数据时跳转/不跳转,在该条件跳转指令处,添加使该条件跳转指令不跳转/跳转的路径约束,即添加使该校验和的检测代码处理正常数据时执行行为的路径约束;
7.k)求解路径约束条件。如果路径约束有解,将畸形数据中相应的校验和域替换为求解结果;输出修改后的畸形数据。如果路径约束无解,输出原始畸形数据。
与现有技术相比,本发明的积极效果为:
采用本发明的方法,可以大大提高漏洞的检测效率,特别是对输入格式中含有校验和信息时,本发明依然能对目标程序有效测试。
附图说明
图1是本发明总体流程图。
具体实施方式
下面结合附图1,更详细的描述本发明的具体实施方式。本实施实例以英特尔公司二进制植入平台PIN和微软公司约束求解器Z3给出详细的实施方式和操作过程,但本发明的保护范围不限于本实施例。
步骤1.运行正常输入数据,收集目标程序运行时敏感信息。
1.a)劫持操作系统文件操作及网络数据操作的系统调用。基于PIN平台的API接口PIN_AddSyscallEntryFunction、PIN_AddSyscallExitFunction,劫持相应的系统调用的参数和返回值。通过对一些文件打开、读入、关闭的系统调用的劫持,例如在windows平台上劫持NtCreateFile、NtOpenFile、NtReadFile,在Linux平台上劫持open、read、close、seek、lseek等,就可以获得传入这些系统调用的参数及返回值。
1.b)如果目标程序将正常输入数据读入了内存,就记录内存单元和输入数据的映射关系。例如,Linux平台上执行read(fd,buf,100)的作用是:从文件fd中读取100字节到以buf为起始地址的内存中。假设fd是输入文件,执行该read系统调用后,我们根据当时fd的文件偏移及buf的数值,详细记录:buf+0来源于第1输入字节,…buf+i来源于第i+1个输入字节…,buf+99来源于第100个输入字节。
1.c)在程序执行过程中,跟踪输入数据的传播;基于PIN提供的INS_InsertCall等API接口,在每条指令执行前,根据指令的语义信息,检查该条指令对输入数据传播的影响。
●对于算术运算(例如add,sub,mul)和逻辑运算(例如and,or,xor)指令,目的操作数依赖的输入字节信息等于所有源操作数依赖的输入字节的并集。
例如:在执行下面add指令时,
add eax,ebx;//eax=eax+ebx;
假设eax依赖于第i个输入字节,ebx依赖于第j个输入字节,执行该指令后,eax依赖于第i,j两个输入字节。
对于特殊运算指令,这类指令可以将目的操作数设置为常数,需要特殊处理。例如xor eax,eax;该指令的作用是将eax清0。假设执行该指令前eax依赖于第i个输入字节,执行该指令后eax不依赖任何输入数据。类似的运算指令还sub eaxeax,mul eax,0等。用户可根据需要,植入不同的监控代码,以达到最佳效果
●对于数据传送指令(例如mov,stos),目的操作数依赖的输入字节信息等于源操作数所依赖的输入字节信息。
例如,执行下面mov指令时,
mov eax,ebx;//eax=ebx
该mov作用是将ebx赋值给eax。执行该指令后,eax依赖于ebx所依赖的输入数据。
●对于能够影响EFLAGS的指令(例如cmp,test,add,or),记录EFLAGS依赖的输入字节信息等于所有操作数依赖的输入字节的并集。特别地,记录EFLAGS分别依赖该指令中第一个操作数和第二个操作数所依赖的输入字节信息。
例如,执行下面cmp指令时:
cmp eax,ebx
该cmp指令比较eax和ebx,并将根据比较结果设置标志寄存器EFLAGS。执行该指令后,EFLAGS依赖的输入字节信息等于eax和ebx所依赖的输入字节信息的并集。并且,同时记录cmp第一个操作数eax和第二个操作数ebx所依赖的输入字节信息。
●对于条件跳转指令(例如JA,JNBE,JAE,JNBE,JB,JNAE,JBE,JNA,JE,JZ,JNE,JNZ,JG,JNLE,JGE,JNL,JL,JNGE,JLE,JNG,JC,JNC,JNO,JNP,JPO,JNS,J0,JP,JPE,JS等),检查EFLAGS依赖多少输入字节。如果EFLAGS依赖的输入字节个数超过一个预定义的数值(用户指定,例如32,64等),输出该跳转指令的地址、跳转是否发生、以及影响EFLAGS的指令的第一个操作数和第二个操作数所依赖的输入字节信息。
例如,执行下面两条指令中的je指令时:
cmp eax,ebx
0x8000 je 0x8010
这里je是一个条件跳转指令,该指令的地址是0x8000,跳转的目的地址是0x8010,如果执行该指令后发生跳转,而EFLAGS依赖的输入字节个数超过了预定的数值,该输出指令地址0x8000、该指令发生跳转以及影响EFLAGS的指令(上面的cmp指令)的第一个操作数(上面cmp指令的eax操作数)和第二个操作数(上面cmp指令的ebx操作数)所依赖的输入字节信息。
●类似的,对于其他类型的指令(例如setnz),根据指令的语意植入相应的监控代码
步骤2.根据步骤1)中收集的信息,针对性的修改正常数据,生成畸形数据。例如,假设步骤1中输出0x8000处条件分支使用的EFLAGS寄存器依赖正常数据的第1至第100字节,则对第1至第100字节随机修改,产生一批畸形数据。
步骤3.将步骤2中产生的畸形样本依次输入至目标程序。具体地,与步骤1类似,收集程序处理每个畸形数据的运行时信息,包括哪些条件跳转指令所使用的EFLAGS依赖的输入字节个数超过了指定数值(例如32、64等,由用户定义),这些条件跳转指令是否发生跳转,以及影响EFLAGS的指令的第一个操作数和第二个操作数所依赖的输入字节信息。
步骤4.定位目标程序中的校验和检测代码和正常样本中的校验和域,具体包括:
4.a)根据步骤1中收集的目标程序运行正常数据时的信息,进一步统计两个集合:P0和P1。其中,P0包含步骤1中输出的条件跳转指令中没有发生跳转的指令;P1包含步骤1中输出的条件跳转指令中发生跳转的指令。而且,P0∪P1中的每个条件跳转指令中所使用的标志寄存器EFLAGS依赖的输入字节数目均超过了预定义的数值。
例如,假设步骤1中运行了3个正常数据,依次输出:
{b1:跳转;b2:跳转,b3:不跳转,b4:跳转,b5:不跳转},
{b1:不跳转;b2:跳转,b3:不跳转,b4:不跳转,b5:不跳转},
{b1:不跳转;b2:跳转,b3:不跳转,b4:跳转,b5:不跳转},
那么,P0={b3,b5},P1={b2},这里b1-b5代表五个不同的条件跳转语句。
4.b)对于步骤3中输出的程序运行时信息,统计计算两个集合P0′和P1′。其中,P0′包含步骤3中输出的条件跳转指令中没有发生跳转的指令;P1′包含步骤3中输出的条件跳转指令中发生跳转的指令。而且,P0′∪P1′中的每个条件跳转指令中所使用的标志寄存器EFLAGS依赖的输入字节数目均超过了预定义的数值。
例如,假设步骤3中运行了三个步骤2中生成的畸形数据,依次输出:
{b1:跳转;b2:不跳转,b3:不跳转,b4:跳转,b5:不跳转},
{b1:跳转;b2:不跳转,b3:不跳转,b4:不跳转,b5:不跳转},
{b1:跳转;b2:不跳转,b3:跳转,b4:跳转,b5:不跳转},
那么,P0′={b2,b5},P1′={b1}。
4.c)计算(P1∩P0′)∪(P0∩P1′)。该集合中包含的条件跳转指令在输入正常数据和畸形数据时表现完全不同:输入正常数据时,这些跳转指令一直发生跳转/不跳转,但是输入畸形数据时,这些跳转指令一直不跳转/发生跳转。在4.a)和4.c)中的例子里,(P1∩P0′)∪(P0∩P1′)={b2}
4.d)根据步骤1和步骤3中的输出信息,对(P1∩P0′)∪(P0∩P1′)中每一个条件跳转指令i,查找影响该条件跳转指令i所使用的标志寄存器EFLAGS的指令j,检测指令j的第一个操作数和第二个操作数所依赖的输入字节信息;如果第一个操作数依赖的输入字节个数超过第二个操作数所依赖的输入字节个数,将第二个操作数所依赖的输入字节作为输入样本中的校验和域;如果第二个操作数依赖的输入字节个数超过第一个操作数所依赖的输入字节个数,将第一个操作数所依赖的输入字节作为输入样本中的校验和域;
例如,假设影响条件跳转指令b2所使用的标志寄存器EFLAGS的指令是指令“cmp eax,ebx”,并且在该cmp指令中,第一个操作数eax依赖于{1,2,3,…100}字节,第二个操作数ebx依赖于{101,102,103,104}字节。那么,将输入数据中的第101至第104四个字节作为校验和域。
4.e)输出(P1∩P0′)∪(P0∩P1′)中的条件跳转指令,将这些指令作为校验和检测语句。
步骤5.对目标程序修改:
5.a)定位步骤4中输出的条件跳转指令在目标程序的二进制文件中的位置。
5.b)如果输入正常样本时,条件跳转指令一直发生跳转,相应的跳转地址为Addr,那么将目标程序中的条件跳转指令修改为直接跳转指令,其中,直接跳转指令的目的地址为Addr。
例如,如果待修改的条件跳转指令是je 0x8000,则修改为jmp 0x8000;
5.c)如果输入正常样本时,条件跳转指令一直不发生跳转,将目标程序中的条件跳转指令修改为等长的nop指令。
例如,如果待修改的跳转指令是je 0x8000,根据该指令的长度,用等长的nop指令替换。
步骤6对步骤5修改后目标程序测试包括:
6.a)对正常数据修改,生成大量畸形样本。具体地,将正常数据的连续4个字节逐一替换为连续4个字节的随机值和整型边界值,如0x800000001,0x7fffffff,0x00008000,0x40000001,0x10000001;
6.b)依次将畸形数据输入至步骤5修改后的目标程序,如果修改后的目标程序崩溃,记录所输入的畸形数据
步骤7对步骤6输出的畸形数据修复包括:
7.a)将畸形数据输入至原始的目标程序;
7.b)在调试模式下,在步骤4中输出的(P1∩P0′)∪(P0∩P1′)中的条件跳转指令设置断点;假设(P1∩P0′)∪(P0∩P1′)={b1,b2,b3},则在三个条件跳转指令上都设置断点;
7.c)断点触发后,检查步骤1的输出。如果断点处的条件跳转指令,在输入正常样本时不跳转/跳转,在输入当前的畸形数据时也不跳转/跳转,继续执行;
例如,如果当输入正常样本是,b1指令一直跳转,而当运行当前的畸形数据时,b1也跳转,那么就取消该断点,让程序继续执行。
7.d)否则,如果该条件跳转指令在输入正常样本时不跳转/跳转,但是在输入当前的畸形数据时跳转/不跳转,回溯查找影响该条件跳转指令所使用的标志寄存器EFLAGS的指令i,进一步检查指令i的操作数:如果指令i的第一个操作数来源于畸形数据的校验和域,将畸形数据的校验和域替换为指令i的第二个操作数的数值;如果指令i的第二个操作数来源于畸形数据的校验和域,将畸形数据的校验和域替换为指令i的第一个操作数的数值;
例如,假设b2条件跳转指令在输入正常数据和畸形数据时的行为不一致,则回溯查找影响b2所使用的标志寄存器EFLAGS的指令。假设是“cmp eax,ebx”指令设置了EFLAGS,则查看eax和ebx的取值。进一步地,根据步骤4.d),判断eax和ebx中哪个寄存器来源于校验和域。如果eax来源于校验和域,则把ebx的取值填充回畸形数据中的校验和域;如果ebx来源于校验和域,则把eax的取值填充回畸形数据中的校验和域。
7.e)输出修复后的畸形数据。
上述步骤7对步骤6输出的畸形数据修复的另外一种形式包括:
7.f)将畸形数据输入至原始的目标程序;
7.g)将畸形数据中的校验和域视为符号值,基于符号执行技术运行目标程序;
[1].劫持系统调用,监控目标程序的文件操作和网络数据操作。
[2].当畸形数据的校验和域读入内存时,记录内存单元和输入字节的映射。根据微软Z3求解器的API,为校验和域中每个字节创建一个符号值。具体地说,通过Z3_mk_bv_sort()创建长度为8的比特矢量类型后,进一步调用Z3_mk_const()创建一个符号变量。
[3].维护内存地址和符号变量之间的映射关系。例如在Linux平台上,read(fd,buf,4)是从文件fd中读取4个字节值内存buf中。假设读入的4个字节恰好是校验和域,则依次创建4个符号变量,分别为s1,s2,s3,s4,并创建映射表,记录buf保存s1,buf+1保存s2,buf+2保存s3,buf+3保存s4。
[4].基于PIN提供的INS_InsertCall等API接口,在每条指令执行前,根据指令的语义信息,模拟每条指令的运行。如果指令的每个操作数都是真实值,则正常执行该指令;如果该指令中存在时符号值的操作数时,根据指令语意模拟该指令执行。
●例如,mov eax,[0x8000],该指令将内存0x8000出数据赋值给eax。如果内存地址0x8000处保存了符号值,则记录eax保存同一个符号值。如果内存地址0x8000处是真实值,则更新eax,使eax等于该真实值。
●例如,add eax,ebx,该指令将eax与ebx求和赋值给eax。如果eax保存的是符号值s1+s2,ebx保存的是符号值s3,模拟该指令执行,令eax保存s1+s2+s3。
●对于能够影响EFLAGS的指令(包括算术指令、逻辑运算指令等),如果指令中所有的操作数都是真实值,正常执行该指令。如果指令操作数中含有符号变量,则记录影响EFLAGS的符号表达式。
例如,对于cmp eax,ebx指令,如果eax保存符号值s1,ebx保存真实值100,执行该指令后,记录EFLAGS受符号表达式s 1-100影响。
7.h)在目标程序执行过程中,收集程序执行路径上的约束条件。
●对于条件跳转指令,检查当时EFLAGS是否受符号表达式控制。如果当时EFLAGS不受符号表达式影响,直接执行该条件跳转指令,不收集约束。
●如果当时EFLAGS受符号表达式影响,根据EFLAGS依赖的符号表达,收集路径约束信息。例如,执行jz 0x8000时,假设EFLAGS受符号表达式s1-1000影响,当该指令发生跳转时,记录路径约束条件“s1-100=0”;如果该指令没有发生跳转,记录路径约束条件“s1-100!=0”
通过Z3中Z3_mk_bvugt,Z3_mk_bvult,Z3_mk_bvslt,Z3_mk_bvule,Z3_mk_bvsle,Z3_mk_bvuge,Z3_mk_bvsge,Z3_mk_bvsgt等API即可描述有符号比较或无符号比较的大于、等于、小于等约束信息。
7.i)当目标程序执行到步骤4中输出的(P1∩P0′)∪(P0∩P1′)中的条件跳转指令时:
●如果该条件跳转指令在输入正常样本时不跳转/跳转,在输入当前的畸形数据时也不跳转/跳转,收集路径约束条件,继续执行;
●如果该条件跳转指令在输入正常样本时不跳转/跳转,但是在输入当前的畸形数据时跳转/不跳转,在该条件跳转指令处,添加使该条件跳转指令不跳转/跳转的路径约束,执行步骤7.j)
7.j)求解路径约束条件。将收集到的路径约束通过调用Z3_assert_cnstr声明为谓词,进一步调用Z3_check_and_get_model求解这些约束。如果路径约束有解,将畸形数据中相应的校验和域替换为求解结果;输出修改后的畸形数据。如果路径约束无解,输出原始畸形数据。
步骤8.将步骤7中输出的畸形数据,输入至原始的目标程序,如果程序崩溃或发生异常,收集崩溃时或异常时的堆栈信息,与输入的畸形数据一起报告给测试人员。
最后应说明的是:以上实施例仅用以说明而非限制本发明的技术方案,尽管参照上述实施例对本发明进行了详细说明,本领域的技术人员应当理解:依然可以对本发明进行修改或者等同替换,而不脱离本发明的精神和范围的任何修改或局部替换,其均应涵盖在本发明的权利要求范围当中。

Claims (8)

1.一种软件漏洞挖掘方法,其步骤为:
1)将多个正常数据分别输入目标程序,收集该目标程序处理每个正常数据的运行时信息;
2)根据步骤1)所得的运行时信息,修改正常数据,生成畸形数据;
3)将生成的多个畸形数据分别输入该目标程序,收集该目标程序处理每个畸形数据的运行时信息;
4)根据步骤1)、3)收集的运行时信息,识别该目标程序中校验和的检测代码;其方法为:
a)将步骤1)中输出的运行时信息统计为两个集合:P0和P1;其中,P0包含步骤1)中输出的条件跳转指令中没有发生跳转的指令;P1包含步骤1)中输出的条件跳转指令中发生跳转的指令;
b)将步骤3)中输出的运行时信息统计为两个集合:P0′和P1′;其中,P0′包含步骤3)中输出的条件跳转指令中没有发生跳转的指令;P1′包含步骤3)中输出的条件跳转指令中发生跳转的指令;
c)输出(P1∩P0′)∪(P0∩P1′)中的条件跳转指令,将其作为校验和的检测代码;
5)修改识别出的校验和的检测代码,使得修改后的目标程序处理畸形数据时的执行行为与处理正常数据时一致;其中,修改识别出的校验和的检测代码的方法为:
a)定位步骤4)中输出的条件跳转指令在目标程序中的位置;
b)如果输入正常样本时,该条件跳转指令一直发生跳转,则将目标程序中的该条件跳转指令修改为直接跳转指令,该直接跳转指令的目的地址指向该条件跳转指令的跳转地址;
c)如果输入正常样本时,该条件跳转指令一直不发生跳转,将目标程序中的该条件跳转指令修改为等长的nop指令;
6)生成若干畸形数据并输入步骤5)所修改后的目标程序;
7)将使修改后的目标程序崩溃的畸形数据作为样本数据,修改每个样本数据中校验和的域值,使修改后的样本数据能够通过原始目标程序的校验和检测;
8)将步骤7)修改后的样本数据输入原目标程序,如果原目标程序崩溃或发生异常则收集原目标程序执行的调用栈以及执行上下文信息,并报告一个潜在的安全漏洞;
其中,所述运行时信息包括:条件跳转指令和条件跳转指令是否发生跳转、以及影响条件跳转指令中所用到的标志寄存器指令的第一个操作数所依赖的输入字节信息和第二个操作数所依赖的输入字节信息。
2.如权利要求1所述的方法,其特征在于所述条件跳转指令为依赖的输入字节数目超过预定值的条件跳转指令;利用该目标程序中的条件跳转指令识别该目标程序中校验和的检测代码。
3.如权利要求1或2所述的方法,其特征在于所述运行时信息的收集方法为:
1)利用系统调用劫持方法监控目标程序对正常数据的读入;
2)当目标程序将正常数据读入内存时,记录相应内存地址与输入数据之间的依赖关系;
3)利用代码植入方法,在目标程序的每条机器指令前植入相应的监控代码,监控每条指令的执行,收集所述运行时信息。
4.如权利要求3所述的方法,其特征在于记录相应内存地址与输入数据之间的依赖关系的方法为:当目标程序将正常数据读入内存时,以每个字节在正常输入数据中的位置偏移标示该字节,并记录每个内存单元来源于哪些字节。
5.如权利要求1所述的方法,其特征在于所述步骤4)中,同时识别正常数据中的校验和域;其方法为:对于每一校验和的检测代码,查找影响当前校验和的检测代码所使用的标志寄存器指令j,检测指令j的第一个操作数和第二个操作数所依赖的输入字节信息;如果第一个操作数依赖的输入字节个数超过第二个操作数所依赖的输入字节个数,则将第二个操作数所依赖的输入字节作为输入样本中的校验和域;如果第二个操作数依赖的输入字节个数超过第一个操作数所依赖的输入字节个数,则将第一个操作数所依赖的输入字节作为输入样本中的校验和域。
6.如权利要求1或2或5所述的方法,其特征在于修改每个样本数据中校验和的域值的方法为:
a)将样本数据输入至原目标程序;
b)在调试模式下,在所述校验和的检测代码处设置断点;
c)断点触发后,如果校验和的检测代码在输入正常数据时的执行行为与在输入当前样本数据时执行一致,则继续执行;否则,回溯查找影响该校验和的检测代码所使用的标志寄存器的指令i,然后检查指令i的操作数:如果指令i的第一个操作数来源于样本数据的校验和域,将样本数据的校验和域替换为指令i的第二个操作数的数值;如果指令i的第二个操作数来源于样本数据的校验和域,将样本数据的校验和域替换为指令i的第一个操作数的数值。
7.如权利要求1或2所述的方法,其特征在于修改每个样本数据中校验和的域值的方法为:
a)将样本数据输入至原目标程序;
b)将样本数据中的校验和域视为符号值,采用符号执行方法运行原目标程序;
c)在原目标程序执行过程中,收集原目标程序执行路径上的约束条件;
d)当原目标程序执行到校验和的检测代码时:如果该校验和的检测代码在输入正常数据时的执行行为与在输入当前样本数据时执行一致,则收集路径约束条件,继续执行;否则,在该校验和的检测代码处,添加使该校验和的检测代码处理正常数据时执行行为的路径约束;
e)求解路径约束条件,如果路径约束有解,则将样本数据中相应的校验和域替换为求解结果;如果路径约束无解,则输出原始样本数据。
8.如权利要求1或2所述的方法,其特征在于所述畸形数据的生成方法包括:将正常数据的每一个字节逐一替换为随机值、或将正常数据的每一个字节逐一替换为用户定义的数值、或将正常数据的连续N个字节逐一替换为连续N个字节的随机值、或将正常数据的连续N个字节逐一替换为连续N个字节的用户定义的数值,N为自然数。
CN2010101719790A 2010-05-07 2010-05-07 一种软件漏洞挖掘方法 Expired - Fee Related CN101847121B (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN2010101719790A CN101847121B (zh) 2010-05-07 2010-05-07 一种软件漏洞挖掘方法

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN2010101719790A CN101847121B (zh) 2010-05-07 2010-05-07 一种软件漏洞挖掘方法

Publications (2)

Publication Number Publication Date
CN101847121A CN101847121A (zh) 2010-09-29
CN101847121B true CN101847121B (zh) 2012-01-18

Family

ID=42771746

Family Applications (1)

Application Number Title Priority Date Filing Date
CN2010101719790A Expired - Fee Related CN101847121B (zh) 2010-05-07 2010-05-07 一种软件漏洞挖掘方法

Country Status (1)

Country Link
CN (1) CN101847121B (zh)

Families Citing this family (10)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN102541729A (zh) * 2010-12-31 2012-07-04 航空工业信息中心 软件安全漏洞检测装置和方法
CN108073499B (zh) * 2016-11-10 2020-09-29 腾讯科技(深圳)有限公司 应用程序的测试方法及装置
CN106657022B (zh) * 2016-11-24 2019-08-30 北京瑞星网安技术股份有限公司 Linux网络访问控制方法及装置
CN106649036B (zh) * 2016-11-24 2019-03-12 北京瑞星网安技术股份有限公司 Linux网络访问监控方法及装置
CN108416216A (zh) * 2018-02-28 2018-08-17 阿里巴巴集团控股有限公司 漏洞检测方法、装置及计算设备
CN110196815B (zh) * 2019-07-26 2019-11-01 中国人民解放军国防科技大学 一种软件模糊测试方法
CN110493226B (zh) * 2019-08-20 2020-10-20 北京大学 针对内存破坏漏洞攻击流量漏洞利用生成的方法及系统
CN115510450B (zh) * 2022-09-20 2023-08-01 中国人民解放军国防科技大学 一种面向计算机二进制程序的比对依赖识别方法与系统
CN115687111B (zh) * 2022-10-27 2024-05-14 中国人民解放军国防科技大学 面向计算机二进制程序的直接比对依赖识别方法与系统
CN118626153A (zh) * 2024-08-14 2024-09-10 北京开源芯片研究院 指令处理方法、装置、电子设备及可读存储介质

Family Cites Families (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5493649A (en) * 1994-06-21 1996-02-20 Microsoft Corporation Detecting corruption in a computer program at execution time using a checksum
CN1141644C (zh) * 1999-11-20 2004-03-10 深圳市中兴通讯股份有限公司 一种嵌入处理机内存的检测和监控方法
WO2004055634A2 (en) * 2002-12-12 2004-07-01 Finite State Machine Labs, Inc. Systems and methods for detecting a security breach in a computer system
JP4462962B2 (ja) * 2004-03-03 2010-05-12 株式会社日立製作所 不整合データ発見方法及びシステム

Also Published As

Publication number Publication date
CN101847121A (zh) 2010-09-29

Similar Documents

Publication Publication Date Title
CN101847121B (zh) 一种软件漏洞挖掘方法
CN111125716B (zh) 一种以太坊智能合约漏洞检测方法及装置
CN101853200B (zh) 一种高效动态软件漏洞挖掘方法
Eceiza et al. Fuzzing the internet of things: A review on the techniques and challenges for efficient vulnerability discovery in embedded systems
CN110580226B (zh) 操作系统级程序的目标码覆盖率测试方法、系统及介质
Chua et al. One Engine To Serve'em All: Inferring Taint Rules Without Architectural Semantics.
US10409706B2 (en) Automated test generation for structural coverage for temporal logic falsification of cyber-physical systems
CN102402479B (zh) 用于静态分析的中间表示结构
CN102081719B (zh) 基于动态污染传播的软件安全测试系统及方法
Chen et al. A large-scale empirical study on control flow identification of smart contracts
Filus et al. Software vulnerabilities in TensorFlow-based deep learning applications
Padhye et al. Travioli: A dynamic analysis for detecting data-structure traversals
CN111125697B (zh) 基于缺陷摘要的智能合约缺陷可触发性检测方法及系统
CN118094567A (zh) 一种基于x86-64指令集的二进制代码静态分析方法
CN114282226A (zh) 单次多漏洞代码检测方法及系统
Mouzarani et al. A smart fuzzing method for detecting heap-based buffer overflow in executable codes
CN101551773B (zh) 符号错误和赋值截断的二进制漏洞检测定位装置
Mouzarani et al. Towards designing an extendable vulnerability detection method for executable codes
Jin et al. Fault injection scheme for embedded systems at machine code level and verification
CN111176623B (zh) 一种基于图卷积神经网络的c++抽象信息恢复方法
Kim et al. Source code analysis for static prediction of dynamic memory usage
Liu et al. An Empirical Study of Smart Contract Decompilers
Dong A sound abstract memory model for static analysis of C programs
CN115203652B (zh) 一种基于源混淆的ios端安全加密控制方法
Kuliamin A Survey of Software Dynamic Analysis Methods

Legal Events

Date Code Title Description
C06 Publication
PB01 Publication
C10 Entry into substantive examination
SE01 Entry into force of request for substantive examination
C14 Grant of patent or utility model
GR01 Patent grant
CF01 Termination of patent right due to non-payment of annual fee

Granted publication date: 20120118

Termination date: 20190507

CF01 Termination of patent right due to non-payment of annual fee