预览加载中,请您耐心等待几秒...
1/10
2/10
3/10
4/10
5/10
6/10
7/10
8/10
9/10
10/10

亲,该文档总共19页,到这已经超出免费预览范围,如果喜欢就直接下载吧~

如果您无法下载资料,请参考说明:

1、部分资料下载需要金币,请确保您的账户上有足够的金币

2、已购买过的文档,再次下载不重复扣费

3、资料包下载后请先用软件解压,在使用对应软件打开

经典转载-缓冲区溢出的原理和实践(Phrack) 经典转载-缓冲区溢出的原理和实践(Phrack) 简介 在过去的几个月中,被发现和利用的缓冲区溢出漏洞呈现上升趋势.例如syslog, splitvt,sendmail8.7.5,Linux/FreeBSDmount,Xtlibrary,at等等.本文试图 解释什么是缓冲区溢出,以及如何利用. 汇编的基础知识是必需的.对虚拟内存的概念,以及使用gdb的经验是十分有益 的,但不是必需的.我们还假定使用Intelx86CPU,操作系统是Linux. 在开始之前我们给出几个基本的定义:缓冲区,简单说来是一块连续的计算机内 存区域,可以保存相同数据类型的多个实例.C程序员通常和字缓冲区数组打交道. 最常见的是字符数组.数组,与C语言中所有的变量一样,可以被声明为静态或动态 的.静态变量在程序加载时定位于数据段.动态变量在程序运行时定位于堆栈之中. 溢出,说白了就是灌满,使内容物超过顶端,边缘,或边界.我们这里只关心动态 缓冲区的溢出问题,即基于堆栈的缓冲区溢出. 进程的内存组织形式 为了理解什么是堆栈缓冲区,我们必须首先理解一个进程是以什么组织形式在 内存中存在的.进程被分成三个区域:文本,数据和堆栈.我们把精力集中在堆栈 区域,但首先按照顺序简单介绍一下其他区域. 文本区域是由程序确定的,包括代码(指令)和只读数据.该区域相当于可执行 文件的文本段.这个区域通常被标记为只读,任何对其写入的操作都会导致段错误 (segmentationviolation). 数据区域包含了已初始化和未初始化的数据.静态变量储存在这个区域中.数 据区域对应可执行文件中的data-bss段.它的大小可以用系统调用brk(2)来改变. 如果bss数据的扩展或用户堆栈把可用内存消耗光了,进程就会被阻塞住,等待有了 一块更大的内存空间之后再运行.新内存加入到数据和堆栈段的中间. /------------------"内存低地址 || |文本| || |------------------| |(已初始化)| |数据| |(未初始化)| |------------------| || |堆栈| || "------------------/内存高地址 Fig.1进程内存区域 什么是堆栈? ~~~~~~~~~~~~~ 堆栈是一个在计算机科学中经常使用的抽象数据类型.堆栈中的物体具有一个特性: 最后一个放入堆栈中的物体总是被最先拿出来,这个特性通常称为后进先处(LIFO)队列. 堆栈中定义了一些操作.两个最重要的是PUSH和POP.PUSH操作在堆栈的顶部加入一 个元素.POP操作相反,在堆栈顶部移去一个元素,并将堆栈的大小减一. 为什么使用堆栈? ~~~~~~~~~~~~~~~~ 现代计算机被设计成能够理解人们头脑中的高级语言.在使用高级语言构造程序时 最重要的技术是过程(procedure)和函数(function).从这一点来看,一个过程调用可 以象跳转(jump)命令那样改变程序的控制流程,但是与跳转不同的是,当工作完成时, 函数把控制权返回给调用之后的语句或指令.这种高级抽象实现起来要靠堆栈的帮助. 堆栈也用于给函数中使用的局部变量动态分配空间,同样给函数传递参数和函数返 回值也要用到堆栈. 堆栈区域 ~~~~~~~~~~ 堆栈是一块保存数据的连续内存.一个名为堆栈指针(SP)的寄存器指向堆栈的顶部. 堆栈的底部在一个固定的地址.堆栈的大小在运行时由内核动态地调整.CPU实现指令 PUSH和POP,向堆栈中添加元素和从中移去元素. 堆栈由逻辑堆栈帧组成.当调用函数时逻辑堆栈帧被压入栈中,当函数返回时逻辑 堆栈帧被从栈中弹出.堆栈帧包括函数的参数,函数地局部变量,以及恢复前一个堆栈 帧所需要的数据,其中包括在函数调用时指令指针(IP)的值. 堆栈既可以向下增长(向内存低地址)也可以向上增长,这依赖于具体的实现.在我 们的例子中,堆栈是向下增长的.这是很多计算机的实现方式,包括Intel,Motorola, SPARC和MIPS处理器.堆栈指针(SP)也是依赖于具体实现的.它可以指向堆栈的最后地址, 或者指向堆栈之后的下一个空闲可用地址.在我们的讨论当中,SP指向堆栈的最后地址. 除了堆栈指针(SP指向堆栈顶部的的低地址)之外,为了使用方便还有指向帧内固定 地址的指针叫做帧指针(FP).有些文章把它叫做局部基指针(LB-localbasepointer). 从理论上来说,局部变量可以用SP加偏移量来引用.然而,当有字被压栈和出栈后,这 些偏移量就变了.尽管在某些情况下编译器能够跟踪栈中的字操作,由此可以修正偏移 量,但是在某些情况下不能.而且在所有情况下,要引入可观的管