基于模式的漏洞分析能够比较精确地通过形式化描述证明软件系统的执行,并能够以自动机的形式化语言对软件程序进行形式化建模,从而合理地描述模式中各个模块的不同属性和属性之间的依赖关系,方便分析人员对软件系统的检测和分析。
在对软件程序进行模式分析之前,需要进行不同漏洞模式的构建,以待后续进行基于模式的匹配分析。根据不同漏洞模式触发原理和触发机制,分析各个软件模块的不同属性和依赖关系,从中抽象出漏洞触发的核心条件,并建立基于形式化语言或描述性语言的漏洞模式。漏洞模式建立后,下一步将针对二进制抽象进行基于漏洞模式的分析检测,首先将程序反汇编,并将反汇编代码转化为中间表示。针对二进制程序的中间表示进一步分析出其相关属性信息描述,并针对其属性信息进行模式匹配和检测分析。
利用反汇编技术可以将二进制代码转化为可理解程度更高的汇编级代码。
将程序反汇编后,可以得到许多程序分析的重要信息:
反汇编的不足:
目前常用的中间表示有:REIL、VEX、Vine 等。
缓冲区溢出类漏洞模式:
char *strcpy(char *dest, const char *src);
,为其建立漏洞模式首先需要获取目标地址缓冲区大小和源数据缓冲区大小,如果源缓冲区大于目的缓冲区,则存在溢出。
循环写内存模式。如果一个程序的写缓冲区操作发生在循环中,且循环次数是用户可控的,就可能发生溢出,如:
taint_data = fread();
buffer[256];
taint_size = len(taint_data);
index = 0;
while (index < taint_size) {
buffer[index] = taint_data[index];
index++;
} // 如果 taint_size > buffer_size,则会发生溢出
整数溢出类漏洞模式:
Operation(addr) = {(opcode, result, loperand, roperand)}
Assignment(addr) = {(destination, source-value)}
内存地址对象破坏性调用漏洞模式:如 use-after-free。