- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
缓冲区溢出漏洞发掘模型.ppt
内容摘要 简介(Introduction) 相关工作(Related Work) 我们的模型(Our Model) 总结(Conclusion) 简介 研究的必要性 C和C++语言仍然是开发的主要工具 缓冲区溢出攻击已成为主要攻击手段 相关工作(Related Work) 静态检测(Static Detection) 动态检测(Dynamic Detection) 主要分为动态和静态检测两种方法,其中静态检 测工具主要针对源码做相应检测,而动态检测工 具主要从对二进制程序运行时保护的角度出发。 静态检测工具 第一代:lint 第二代:Splint和LClint 第三代:Flowfinder,RATS,ITS4 动态检测工具 FIST(Fault Injection Security Tool) Libsafe和Libverify Stack Shield 我们的检测模型 静态分析 动态分析和测试 静态分析 目的:得到子过程调用的关系图,以便后续的分析。每一个子过程作为图中的一个节点,同时不安全的函数也作为一个节点存在。 方法: call和ret指令搜索 编译器优化和特征码匹配 缓冲区边界的定位 辅助:基于污点传播的双向数据流分析 有向图举例: fun(char * arg) { char src[100] = {“This is a test”}; strcpy(arg, src); printf(“%s \n”, arg); } main() { char dest[100]; fun(dest); printf(“%s\n”, dest); } 有向图节点记录 子函数的起始位置 函数所分配的堆栈大小 函数局部变量的使用情况 调用者传递给函数的参数 调用者调用本函数的地址(即函数调用的返回地址) call和ret指令搜索 采用深度优先或者广度优先的搜索算法。 编译器优化和特征码匹配 编译器对程序进行了优化以提高执行速度,有些函数(如strcpy,strcat)被硬编码到程序中。 如:strcpy() main() { char dest[100]; char src[100]; gets(src); strcpy(dest,src); return; } VC 6.0编译器 思想:只要在程序中以ECX为核心对指令进行匹配,同时配合这三条字符串操作指令,就可以定位strcat和strcpy。 repne scas byte ptr [edi] ;扫描源字符串,长度存放在ecx中 not ecx mov EnX, ECX shr ecx, 2 rep movs dword ptr [edi],dword ptr [esi] mov ecx, Enx and ecx, 3 rep movs byte ptr [edi],byte ptr [esi] VC 7.0编译器 strcpy函数也会被硬编码到程序中去,但是它产生的二进制码却和VC6.0产生的二进制码有很大的区别。 strcpy硬编码如下: mov cl,byte ptr [esp+eax] mov byte ptr [esp+eax+14h],cl inc eax 0040104A test cl,cl 0040104C jne 因为在这些硬编码的代码中使用了相对基址变址寻址方式,所以在VC7.0下简单提取strcpy的固定二进制特征码比较难,但是我们可以结合指令的语义进行分析,来构建strcpy函数的特征码。 缓冲区边界的定位 Libsafe对缓冲区估算采用最大化到栈帧的方法。 本文思想:根据指令对内存单元访问情况来界定缓冲区 边界。 方法: (1)通过分析未直接访问的堆栈单元来确定目标缓冲区长度 (2)根据局部变量的访问方式来确定目标缓冲区的长度 (3)通过其他方法判断缓冲区长度 通过分析未直接访问的堆栈单元来确定目标缓冲区长度 对于普通的变量,如果没有在程序中被使用,那么程序将不会为其在堆栈中保留地址空间。但是对于数组字符数组来说,只要数组中有一个成员被访问,程序就会在堆栈中为整个数组保留地址空间。然而在编译后的程序中没有任何一条指令对其余的地址空间进行访问。 int main(int argc, char* argv[]){ char dest[100] =
文档评论(0)