发明名称 一种基于简易符号执行的二进制代码漏洞挖掘方法
摘要 本发明公开了一种基于简易符号执行的二进制代码漏洞挖掘方法,它有五大步骤;首先把二进制代码通过二进制代码翻译组件,转化为一种静态单赋值的中间语言。然后使用反汇编引擎对二进制代码进行反汇编,提取其中的控制流信息,基于该控制流信息在中间语言上进行静态的符号执行,在符号执行过程中需确认输入点,把输入向量转化为符号,并对调用函数进行建模。当符号执行过程完成后可得到依赖输入向量的中间语言的语句集合,对该集合中的语句简化后,使用安全属性规则验证后生成漏洞确认报告。
申请公布号 CN102841844B 申请公布日期 2015.12.16
申请号 CN201210243800.7 申请日期 2012.07.13
申请人 北京航空航天大学 发明人 马金鑫;李舟军;忽朝俭
分类号 G06F11/36(2006.01)I 主分类号 G06F11/36(2006.01)I
代理机构 北京慧泉知识产权代理有限公司 11232 代理人 王顺荣;唐爱华
主权项 一种基于简易符号执行的二进制代码漏洞挖掘方法,其特征在于:该方法包括以下步骤:步骤A:将二进制代码交给反汇编引擎,解码为汇编指令,提取出汇编指令中的函数信息,再对每个函数分析,提取出该函数的控制流信息;得到函数信息后,生成调用图,使用反向的深度遍历算法,从调用图的叶子结点开始向上处理,保证在处理某函数时,调用子函数都已经被处理过;步骤B.实现二进制代码翻译组件,将二进制代码转化成中间语言;所述中间语言与动态产生的中间语言并不相同,动态生成的中间语言,跳转指令已经得到确定,或者跳转、或者顺序执行;静态下翻译的中间语言遇到分支指令时转化为CMP‑JCC语句,并不能确定是否跳转;步骤C.确认输入点即函数的参数及子函数调用,对函数中调用的子函数进行建模;包括两种输入,一种为函数自身的参数,它是由用户指定的,表示为栈桢指针与正数偏移相加;另一种为具有副作用的函数引入的外部输入,包括ReadFile、fread、accept、recv函数,需要建立一张函数信息表描述这些函数、参数与返回值之间的映射关系,从而确定输入符号;步骤D.根据前述步骤A、B、C产生的结果,在翻译后的中间语言上进行简易符号执行过程,称之为简易的符号执行,是因为符号执行过程是在函数体内进行的,而并非针对整段二进制代码,这样就跳过一些没意义的函数,从而减少符号执行所用的时间;其次,该符号执行过程是一个静态解释中间语言的过程,传播描述输入的符号,对于循环,只执行一次循环后即跳出,从而避免由循环引起的状态爆炸问题;对于分支,需要保存当前的上下文信息,先执行其中一条路径,当执行完成返回后,恢复保存后的上下文信息,再继续解释另一条路径;步骤E.当执行到函数结束时,符号执行过程产生一些与输入相关的表达式集合,根据安全属性规则,简化、分析这些表达式最后判断是否有漏洞;该简易符号执行的二进制代码漏洞挖掘方法中只添加了非法写内存漏洞模式的规则:<maths num="0001" id="cmaths0001"><math><![CDATA[<mfenced open = "{" close = ""><mtable><mtr><mtd><mo>(</mo><mi>a</mi><mo>)</mo><mi>S</mi><mi>t</mi><mi>o</mi><mi>r</mi><mi>e</mi><mo>(</mo><mi>E</mi><mi>x</mi><mi>p</mi><msub><mi>r</mi><mn>1</mn></msub><mrow><mo>(</mo><mi>I</mi><mo>)</mo></mrow><mo>)</mo><mo>=</mo><mi>E</mi><mi>x</mi><mi>p</mi><msub><mi>r</mi><mn>2</mn></msub><mo>(</mo><mi>I</mi><mo>)</mo></mtd></mtr><mtr><mtd><mo>(</mo><mi>b</mi><mo>)</mo><mi>S</mi><mi>t</mi><mi>o</mi><mi>r</mi><mi>e</mi><mo>(</mo><mi>E</mi><mi>x</mi><mi>p</mi><msub><mi>r</mi><mn>1</mn></msub><mrow><mo>(</mo><mi>I</mi><mo>)</mo></mrow><mo>)</mo><mo>=</mo><mi>E</mi><mi>x</mi><mi>p</mi><msub><mi>r</mi><mn>2</mn></msub><mo>(</mo><msub><mi>f</mi><mn>0</mn></msub><mo>)</mo></mtd></mtr><mtr><mtd><mo>(</mo><mi>c</mi><mo>)</mo><mi>S</mi><mi>t</mi><mi>o</mi><mi>r</mi><mi>e</mi><mo>(</mo><mi>E</mi><mi>x</mi><mi>p</mi><msub><mi>r</mi><mn>1</mn></msub><mrow><mo>(</mo><msub><mi>f</mi><mn>0</mn></msub><mo>)</mo></mrow><mo>)</mo><mo>=</mo><mi>E</mi><mi>x</mi><mi>p</mi><msub><mi>r</mi><mn>2</mn></msub><mo>(</mo><mi>I</mi><mo>)</mo></mtd></mtr></mtable></mfenced>]]></math><img file="FDA0000798792890000021.GIF" wi="802" he="292" /></maths>其中Store为存储函数,Store(a)=b表示把b写入由地址a表示的内存中;Expr(x)表示关于x的表达式,I表示输入,f<sub>0</sub>表示固定值;其中,步骤A中所述的二进制代码为Windows、Linux操作系统下的x86可执行代码;所述控制流信息是由基本块信息组成的链表,基本块信息包括:A1.基本块标号Label,表示该基本块的标识符,值唯一;A2.基本块的开始地址Start Address;A3.基本块的结束地址End Address;A4.基本块的入度数In Count,表示到达该基本块的前驱的数量,入度数为0的基本块为本函数的第一个基本块;A5.基本块的出度数Out Count,表示由该基本块到达的后继的数量,该出度数的值不大于2,出度数为0的基本块为本函数的最后一个基本块;A6.基本块的前驱数组,表示到达该基本块的前驱的集合;A7.基本块的后继数组,表示由该基本块到达的后继的集合;A8.循环标志,表示该基本块是否处于循环中;其中,步骤B所述的中间语言中,包括三种存储介质:B11.临时变量,在每个基本块中临时申请,用于实现静态单赋值,为寄存器与内存间的媒介;B12.寄存器,与机器指令中的寄存器相同,读写寄存器使用中间语言中的Get和Put操作完成;B13.内存,内存地址由常量或临时变量表示,读写内存使用中间语言中的LDle和STle操作完成;步骤B中所述的中间语言由语句IRStmt组成,语句IRStmt包括:B21.IMark语句,表示每个基本块的入口标志,其中包括该基本块对应机器指令的开始地址及该指令的字节数;B22.Put语句,表示把临时变量的值写入寄存器;B23.Store语句,表示把临时变量的值写入内存;B24.IRDirty语句,表示调用有副作用的函数;B25.Exit语句,表示基本块的出口;其中,所述的语句IRStmt由表达式IRExpr组成,表达式IRExpr包括:B31.Get表达式,表示从寄存器中读取值;B32.Tmp表达式,表示临时变量;B33.Binop表达式,表示二元操作;B34.Unop表达式,表示一元操作;B35.Load表达式,表示从内存中读取值;B36.Const表达式,表示常量;B37.MuxOX表达式,表示if‑then‑else语句;其中,步骤C所述的输入点一般指函数的参数或者从外部引入的值,在x86指令集中,参数表示为栈桢指针与正数偏移相加,但栈桢指针是ESP或者EBP,需要启发式判断;另外这种输入是从外部引入的值,在函数内部调用ReadFile、Recv、Accept函数时引入的外部值,在函数建模后就针对这些输入向量适当地引入符号;其中,步骤D所述的简易符号执行方法是在中间语言上进行,需要考虑以下几种情况:D1.Put操作,检查赋值给寄存器的临时变量是否依赖于输入;D2.赋值给临时变量时,左值需要考虑以下几种情况:D21.从临时变量中读,检查该临时变量是否依赖于输入;D22.从内存中读,检查该内存中的值是否依赖于输入;D23.从寄存器中读,检查该寄存器是否依赖于输入;D24.一元操作与二元操作,检查操作数是否依赖于输入;D3.Store操作,检查写入内存的临时变量是否依赖于输入;步骤D所述的Put与Store操作为与输入相关的表达式,包括二元操作,一元操作、位移操作,有符号扩展、无符号扩展;步骤D所述的符号执行达到分支指令时,需要保存当前的上下文信息,该信息包括执行到当前指令所有寄存器、临时变量、以及内存的符号信息,然后执行一条路径,执行完成后回溯到分支处,恢复保存的上下文信息再继续执行另一条路径;其中,步骤E中所述的安全属性规则为判断指令是否为漏洞的依据,目前,成功添加三种安全属性规则来判断非法写内存模式的漏洞:E1.写任意值到任意地址;E2.写任意值到固定地址;E3.写固定值到任意地址。
地址 100191 北京市海淀区学院路37号