黑客攻防技术与实践 教学课件 作者 李建华 第八章缓冲区溢出攻击.pptVIP

  • 6
  • 0
  • 约6.17千字
  • 约 25页
  • 2017-08-21 发布于广东
  • 举报

黑客攻防技术与实践 教学课件 作者 李建华 第八章缓冲区溢出攻击.ppt

第8章缓冲区溢出攻击 8.1 缓冲区溢出攻击简介 8.2 缓冲区溢出技术原理 8.3 缓冲区溢出漏洞分析 8.4 缓冲区溢出漏洞的预防 8.5 小结 缓冲区溢出简介 缓冲区溢出,是指程序的一种异常状况,由于某些特定的环境,可能使进程在向定长的内存缓冲区写入数据时超出预定的边界。 在人为的刻意设计下,溢出的部分可能会导致进程的执行流程更改,从而达到执行任意代码的效果。 缓冲区溢出攻击的历史 1998年的Morris蠕虫事件 1995年Thomas Lopatic独立地发现了缓冲区溢出,分析的对象是NCSA HTTPD 1996年,Elias Levy在Phrack发表论文(Smashing the Stack for Fun and Profit)详细描述了Linux系统中栈的结构和如何利用基于栈的缓冲区溢出 1997年,Smith提供了如何在各种Unix变种中写缓冲区溢出的指导原则 1998年,“Cult of the Dead Cow” 以Microsoft Netmeeting为例子详细介绍了如何利用Windows的溢出 1999年,dark spyrit提出使用系统核心DLL中的指令来完成控制的想法,将Windows下的溢出Exploit推进了实质性的一步 2000年以后比较有代表性的Internet蠕虫攻击,2 2001年Code Red利用了Microsoft IIS 5.0中的缓冲区溢出漏洞 2003年,SQL Slammer利用了Microsoft SQL Server 2000中的漏洞,这些蠕虫的爆发都造成了巨大的损失。 缓冲区溢出攻击 堆栈溢出漏洞普遍存在于各个操作系统平台和流行的应用软件中,针对一个有溢出漏洞的网络守护进程的攻击是系统入侵的首选方案. 堆栈溢出的原理: 1.堆栈是一个先入后出的队列,反向增长 2.函数调用中,堆栈中将被依次压入:参数,返回地址 3.函数内部的局部变量在堆栈内分配 4.c函数库的字符串处理函数(gets,strcpy等)没有对数组越界加以监视和限制,我们利用字符数组写越界,覆盖堆栈中的老元素的值,就可以修改返回地址 函数调用的约定 栈是一种先进后出的数据结构,栈有一个存储区、一个栈顶指针。栈顶指针指向堆栈中第一个可用的数据项(被称为栈顶)。用户可以在栈顶上方向栈中加入 数据,这个操作被称为压栈(Push),压栈以后,栈顶自动变成新加入数据项的位置,栈顶指针也随之修改。用户也可以从堆栈中取走栈顶,称为弹出栈 (pop),弹出栈后,栈顶下的一个元素变成栈顶,栈顶指针随之修改。 函数调用时,调用者依次把参数压栈,然后调用函数,函数被调用以后,在堆栈中取得数据,并进行计算。函数计算结束以后,或者调用者、或者函数本身修改堆栈,使堆栈恢复原装。 stdcall的调用约定意味着:1)参数从右向左压入堆栈,2)函数自身修改堆栈 3)函数名自动加前导的下划线,后面紧跟一个@符号,其后紧跟着参数的尺寸 cdecl调用约定:又称为C调用约定,是C语言缺省的调用约定。cdecl调用约定的参数压栈顺序是和stdcall是一样的,参数首先由右向左压入堆栈。所不同的是,函数本身不清理堆栈,调用者负责清理堆栈。由于这种变化,C调用约定允许函数的参数的个数是不固定的,这也是C语言的一大特色。 Linux X86平台的stack溢出 用户空间又可以分为几个部分, Text部分是进程的可执行映像,其中包括了代码部分.text,全局数据部分.data,和未初始化的全局数据.bss。 Heap部分是堆空间,即动态分配的内存所使用的空间,它与Text部分相邻并向上生长。在Linux中,这是通过sbrk等系统调用实现的。 Mmap部分是Linux的系统调用mmap所使用的空间,主要用来映射磁盘文件或者其他进程的地址空间。 Stack也就是攻击者最为关心的栈,是从0xC0000000向下生长的,它包括了所有函数内分配的auto变量以及函数调用时的程序返回点信息 Linux X86平台的stack溢出 ——一个简单的例子 #include stdio.h int f(int *ptr) { int c = *ptr; return c; } ? int main() { int a; int b[10]; a = f(b); return 0; } Linux X86平台的stack溢出 #include stdio.h #include string.h void unexpected(void) { printf(running in unexpected\n); } void expected(char *ptr) { char buf1[5]; char buf2[10];

文档评论(0)

1亿VIP精品文档

相关文档