资源预览内容
第1页 / 共89页
第2页 / 共89页
第3页 / 共89页
第4页 / 共89页
第5页 / 共89页
第6页 / 共89页
第7页 / 共89页
第8页 / 共89页
第9页 / 共89页
第10页 / 共89页
亲,该文档总共89页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
网络攻防实战技术之 缓冲区溢出篇 内容摘要 l 缓冲区溢出相关概念 l 缓冲区溢出原理 l 溢出保护技术 l 安全编程技术 学习要求 l了解缓冲区溢出的相关概念 l明确缓冲区溢出的危害 l理解栈溢出、堆溢出、整型溢出、格式化 字符串溢出及文件流溢出的原因 l掌握安全编程技术 引言-缓冲区溢出的历史 l1988年的Morris蠕虫病毒,感染了6000多台机 器:利用UNIX服务finger中的缓冲区溢出漏洞 来获得访问权限,得到一个shell l1996年前后,开始出现大量的缓冲区溢出攻击 ,因此引起人们的广泛关注 l源码开放的操作系统首当其冲 l随后,Windows系统下的缓冲区溢出也相继被 发掘出来 l已经有一些非常经典细致的文章来介绍与缓冲 区溢出有关的技术 l这两年广泛流行的一些Internet worms利用了 一些缓冲区溢出漏洞 缓冲区溢出相关概念 l缓冲区 l从程序的角度,缓冲区就是应用程序用来保 存用户输入数据、程序临时数据的内存空间 l缓冲区的本质 l数组 l存储位置 lStack lHeap l数据段 缓冲区溢出相关概念 l缓冲区溢出 l如果用户输入的数据长度超出了程序为其分 配的内存空间,这些数据就会覆盖程序为其 它数据分配的内存空间,形成所谓的缓冲区 溢出 为什么会缓冲区溢出? l在C语言中,指针和数组越界不保护是Buffer overflow的根源,而且,在C语言标准库中就有 许多能提供溢出的函数,如strcat(), strcpy(), sprintf(), vsprintf(), bcopy(), gets()和scanf() l通过指针填充数据 l不好的编程习惯 l溢出类型 l栈溢出 l堆溢出 利用缓冲区溢出进行的攻击 l基本的思想 l通过修改某些内存区域,把一段恶意代码存储到一个buffer中, 并且使这个buffer被溢出,以便当前进程被非法利用(执行这段恶 意的代码) l危害性 l在UNIX平台上,通过发掘Buffer Overflow, 可以获得一个交互式 的shell l在Windows平台上,可以上载并执行任何的代码 l溢出漏洞发掘起来需要较高的技巧和知识背景,但是,一旦有人 编写出溢出代码,则用起来非常简单 l与其他的攻击类型相比,缓冲区溢出攻击 l不需要太多的先决条件 l杀伤力很强 l技术性强 l在Buffer Overflows攻击面前,防火墙往往显得很无奈 利用缓冲区溢出的攻击 l随便往缓冲区中填东西造成它溢出一般只会出现“ 分段错误”(Segmentation fault),而不能达到 攻击的目的。 l如果覆盖缓冲区的是一段精心设计的机器指令序 列,它可能通过溢出,改变返回地址,将其指向 自己的指令序列,从而改变该程序的正常流程。 程序指令流被改变后 l溢出之后,让程序执行我们指定的代码 l我们自己提供的一段代码 l系统现有的调用 l由于这段代码往往不能太长,所以需要精心设计,并且充 分利用系统中现有的函数和指令 l对于不同的操作系统 lLinux/Unix,尽可能地得到一个shell(最好是root shell) lWindows,一个可以远程建立连接的telnet会话 l通用的模式 l找到具有漏洞的程序(vulnerable program ) l编写出shellcode, l然后编写把shellcode送到漏洞程序的程序(称为exploit) Windows平台下缓冲区溢出 l过程 l发现目标 l找到有漏洞的程序,如果在 输入非正常字符串的时候, 出现右图的情形 l或者从程序中找漏洞,用好 的反汇编工具,加上耐心 l以一个特定的字符串作为线 索,跟踪到strcpy这样的函 数,看是否有边界检查 l编写shellcode l编写exploit程序,并试验 ,直到成功 简单溢出实例 #include int main() char name8 = 0; printf(“Your name:”); gets(name); printf(“Hello,%s!”,name); return 0; 缓冲区溢出的危害 l应用程序异常 l系统不稳定甚至崩溃 l程序跳转到恶意代码,控制权被窃 缓冲区溢出原理 l预备知识 l理解程序内存空间 l理解堆栈 l理解函数调用过程 l理解缓冲区溢出的原理 Windows环境下的堆栈 l程序空间由何构成? l堆栈是什么? l堆栈里面放的都是什么信息? l程序使用超过了堆栈默认的大小怎么办? l在一次函数调用中,堆栈是如何工作的? 程序在内存中的映像 文本(代码)段 数据段 堆栈段 内存低地址 内存高地址 内存递增方向 初始化数据段 非初始化数据段(BSS) 堆(Heap) 栈(stack) 堆的增长方向 栈的增长方向 内核数据代码 0 x80000000 0 x7FFFFFFF PEB strcpy(stack,input); void bar() printf(nAh,Ive been hacked!n); void main(int argc,char *argv) foo(argv1); main: pushl %ebp movl %esp,%ebp subl $8,%esp addl $-12,%esp movl 12(%ebp),%eax addl $4,%eax movl (%eax),%edx pushl %edx call foo addl $16,%esp .L4: leave ret foo: pushl %ebp movl %esp,%ebp subl $24,%esp addl $-8,%esp movl 8(%ebp),%eax pushl %eax leal -12(%ebp),%eax pushl %eax call strcpy addl $16,%esp .L2: leave ret 例子2 int AFunc(int i,int j) int m = 3; int n = 4; m = i; n = j; BFunc(m,n); return 8; int BFunc(int i,int j) int m = 1; int n = 2; m = i; n = j; return m; int main() AFunc(5,6); return 0; 6 当前EBP 当前ESP AFunc(5,6); push 6 push 5 call _AFunc add esp+8 语句执行前的EBP 语句执行前的ESP 函数调用中栈的工作过程 5 EIP _AFunc push ebp mov ebp,esp sub esp,48h /压入环境变量 /为局部变量分配空间 EBP 48h EDI ESI EBX 3(m=3) 4(n=4) 6 当前EBP 当前ESP AFunc(5,6); call _AFunc add esp+8 语句执行前的EBP 语句执行前的ESP 函数调用中栈的工作过程 5 EIP _AFunc return 0; pop edi pop esi pop ebx add esp,48h /栈校验 pop ebp ret EBP 48h EDI ESI EBX 3(m=3) 4(n=4) 当缓冲区溢出发生时 int AFunc(int i,int j) int m = 3; int n = 4; char szBuf8 = 0; strcpy(szBuf, “This is a overflow buffer!”); m = i; n = j; BFunc(m,n); return 8; 6 szBuf 5 EIP EBP EDI ESI EBX 3(m=3) 4(n=4) 缓冲区溢出原理及其利用 l缓冲区溢出种类 l栈溢出 l堆溢出 l整型溢出 l格式化字符串溢出 l其他溢出 栈溢出 l特点 l缓冲区在栈中分配 l拷贝的数据过长 l覆盖了函数的返回地址或其它一些重要数据 结构、函数指针 栈溢出实例 int AFunc(int i,int j) int m = 3; int n = 4; char szBuf8 = 0; *(int *)(int)szBuf+20) = BFunc; m = i; n = j; BFunc(m,n); return 8; 用BFunc的地址替换正常 的AFunc返回地址,使程 序运行至BFunc 堆溢出 l堆和栈有何区别 l内存的动态分配与 静态分配 l数据增长方向 l堆溢出特点 l缓冲区在堆中分配 l拷贝的数据过长 l覆盖了堆管理结构 #define BUFLEN 32 int main(int argc, char* argv ) char *buf1; buf1 = (char*)malloc(BUFLEN); strcpy(buf1,argv1); printf(%sn,buf1); free(buf1); return 0; 关于堆溢出 l比较少引起人们的关注,原因在于 l比栈溢出难度更大 l需要结合其他的技术,比如 l函数指针改写 lVtable改写 lMalloc库本身的漏洞 l对于内存中变量的组织方式有一定的要求 整型溢出 l宽度溢出(Widthness Overflow) l尝试存储一个超过变量表示范围的大数到变量中 l运算溢出(Arithmetic Overflow) l如果存储值是一个运算操作,稍后使用这个结果的 程序的任何一部分都将错误的运行,因为这个计算 结果是不正确的。 l符号溢出(Signedness Bug) l一个无符号的变量被看作有符号,或者一个有符号 的变量被看作无符号 宽度溢出示例 void main(int argc,char* argv) unsigned short s; int i; char buf80; i = atoi(argv1);/将字符串转换为整型数据 s = i; if(s = 80) return; memcpy(buf,argv2,i); 运算溢出示例 void CopyIntArray(int *array,int len) int* myarray,i; myarray = malloc(len*sizeof(int); if(myarray = NULL) return; for(i=0;i size) return; memcpy(kbuf,buf,len); 格式化字符串溢出 l关键字 l“%n” l产生原因 lprintf()是不定参数输入 lprintf()不会检查输入参数的个数 其他溢出类型 l.data section溢出 lPEB/TEB溢出 l文件流溢出 归纳 l溢出的共性 l大object向小object复制数据(字符串或整型) ,容纳不下造成溢出 l溢出会覆盖一些关键性数据(返回地址、管 理数据、异常处理或文件指针等) l利用程序的后续流程,得到程序的控制权 缓冲区溢出的利用 char szBuf8 = 0; strcpy(szBuf,argv2); largv2的内容: l对EIP的填充 lShellcode
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号