缓冲区溢出攻击原因
- 格式:ppt
- 大小:132.50 KB
- 文档页数:7
缓冲区溢出攻击的基本原理
缓冲区溢出攻击(Buffer Overflow Attack)是一种常见的安全漏洞,指的是攻击者利用输入数据的长度或格式错误,超出程序设计者预留的存储空间范围,从而写入到相邻内存空间中,进而控制程序的执行或修改程序的行为。
缓冲区溢出攻击的基本原理如下:
1.内存分配:程序在运行时会根据变量类型和长度来分配内存空间。
2.缓冲区溢出:攻击者通过向程序输入异常数据,超出了程序预留的内存空
间。
3.覆盖关键数据:溢出的数据覆盖了原本存储的数据,可能是程序的返回地
址、函数指针等关键信息。
4.控制程序行为:攻击者利用溢出的数据修改程序的执行路径,跳转到自己
准备好的恶意代码。
5.执行恶意代码:程序执行了攻击者注入的恶意代码,可能导致系统崩溃、
拒绝服务或远程执行任意命令。
为了避免缓冲区溢出攻击,开发人员可以采取以下措施:
•使用安全的编程语言和工具,如内存安全的语言(如Rust)或经过良好测试的C/C++库。
•限制输入数据的长度,确保不会超过缓冲区可容纳的大小。
•进行输入验证和过滤,确保输入数据符合预期的格式和范围。
•定期更新软件和操作系统,及时修补已知的漏洞。
•实施数据执行保护(DEP)和地址空间布局随机化(ASLR)等安全机制。
综上所述,缓冲区溢出攻击是一种常见的安全漏洞,它利用错误处理输入数据的程序中的缺陷,从而控制程序行为。
开发人员和系统管理员应该密切关注安全问题,采取相应的防护措施,以保护系统和用户的信息安全。
第三讲缓冲区溢出n1 缓冲区溢出问题简介n2 几种典型的缓冲区溢出n3 防范措施缓冲区溢出1 缓冲区溢出问题简介缓冲区溢出是一种常见的漏洞.据统计,通过缓冲区溢出进行的攻击占所有系统攻击总数的80%以上.这种错误的状态发生在写入内存的数据超过了分配给缓冲区的大小的时候,就像一个杯子只能盛一定量的水,如果放到杯子中的水太多,多余的水就会一出到别的地方。
由于缓冲区溢出,相邻的内存地址空间被覆盖,造成软件出错或崩溃。
如果没有采取限制措施,可以使用精心设计的输入数据使缓冲区溢出,从而导致安全问题。
缓冲区溢出缓冲区溢出问题的历史很长一段时间以来,缓冲区溢出都是一个众所周知的安全问题, C程序的缓冲区溢出问题早在70年代初就被认为是C语言数据完整性模型的一个可能的后果。
这是因为在初始化、拷贝或移动数据时,C语言并不自动地支持内在的数组边界检查。
虽然这提高了语言的执行效率,但其带来的影响及后果却是深远和严重的。
•1988年Robert T. Morris的finger蠕虫程序.这种缓冲区溢出的问题使得Internet几乎限于停滞,许多系统管理员都将他们的网络断开,来处理所遇到的问题. •1989年Spafford提交了一份关于运行在VAX机上的BSD版UNIX的fingerd的缓冲区溢出程序的技术细节的分析报告,引起了部分安全人士对这个研究领域的重视•1996年出现了真正有教育意义的第一篇文章, Aleph One在Underground发表的论文详细描述了Linux系统中栈的结构和如何利用基于栈的缓冲区溢出。
缓冲区溢出Aleph One的贡献还在于给出了如何写开一个shell的Exploit的方法,并给这段代码赋予shellcode的名称,而这个称呼沿用至今,我们现在对这样的方法耳熟能详--编译一段使用系统调用的简单的C程序,通过调试器抽取汇编代码,并根据需要修改这段汇编代码。
•1997年Smith综合以前的文章,提供了如何在各种Unix变种中写缓冲区溢出Exploit更详细的指导原则。
「网络安全」常见攻击篇(10)——缓冲区溢出攻击什么是缓冲区溢出攻击?▪缓冲区程序用来保存用户输入数据、程序临时数据的内存空间,本质为数组。
▪缓冲区溢出攻击攻击者利用程序漏洞,将自己的攻击代码植入有缓冲区溢出漏洞的程序执行体中,改变该程序的执行过程,来获取目标系统的控制权。
▪缓冲区溢出攻击原理程序员通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,使程序转而执行其它指令,以达到攻击的目的。
造成缓冲区溢出的原因是程序中没有仔细检查用户输入的参数。
缓冲区溢出的攻击方式▪栈溢出(stack smashing)未检查输入缓冲区长度,导致数组越界,覆盖栈中局部变量空间之上的栈桢指针%ebp以及函数返回地址retaddr, 当函数返回执行ret指令时,retaddr从栈中弹出,作为下一条指令的地址赋给%eip寄存器,继而改变原程序的执行流程指向我们的shellcode.▪堆溢出(malloc/free heapcorruption)一种是和传统的栈溢出一样, 当输入超出malloc()预先分配的空间大小,就会覆盖掉这段空间之后的一段存储区域,如果该存储区域有一个重要的变量比如euid,那么我就可以用它来攻击。
另一种是典型的double-free堆腐败,在内存回收操作中,合并相邻空闲块重新插入双向链表时会有一个写4字节内存的操作,如果弱点程序由于编程错误free()一个不存在的块,我们就可以精心伪造这个块,从而覆盖任何我们想要的值:函数的返回地址、库函数的.plt地址等▪格式化字符窜漏洞(format stringvulnerability)如果格式窜由用户定制,攻击者就可以任意伪造格式窜,利用*printf()系列函数的特性就可以窥探堆栈空间的内容,超常输入可以引发传统的缓冲区溢出,或是用”%n”覆盖指针、返回地址等。
▪整形变量溢出(integer variableoverflow)利用整数的范围、符号等问题触发安全漏洞,大多数整形溢出不能直接利用,但如果该整形变量决定内存分配等操作,我们就有可能间接利用该漏洞。
缓冲区溢出攻击详细讲解缓冲区溢出(Buffer Overflow)是计算机安全领域既经典而又古老的话题。
随着计算机系统安全性的加强,传统的缓冲区溢出攻击方式可能变得不再奏效,相应的介绍缓冲区溢出原理的资料也变得“大众化”起来。
其中看雪的《0day安全:软件漏洞分析技术》一书将缓冲区溢出攻击的原理阐述得简洁明了。
本文参考该书对缓冲区溢出原理的讲解,并结合实际的代码实例进行验证。
不过即便如此,完成一个简单的溢出代码也需要解决很多书中无法涉及的问题,尤其是面对较新的具有安全特性的编译器——比如MS的Visual Studio2010。
接下来,我们结合具体代码,按照对缓冲区溢出原理的循序渐进地理解方式去挖掘缓冲区溢出背后的底层机制。
一、代码 <=> 数据顾名思义,缓冲区溢出的含义是为缓冲区提供了多于其存储容量的数据,就像往杯子里倒入了过量的水一样。
通常情况下,缓冲区溢出的数据只会破坏程序数据,造成意外终止。
但是如果有人精心构造溢出数据的容,那么就有可能获得系统的控制权!如果说用户(也可能是黑客)提供了水——缓冲区溢出攻击的数据,那么系统提供了溢出的容器——缓冲区。
缓冲区在系统中的表现形式是多样的,高级语言定义的变量、数组、结构体等在运行时可以说都是保存在缓冲区的,因此所谓缓冲区可以更抽象地理解为一段可读写的存区域,缓冲区攻击的最终目的就是希望系统能执行这块可读写存中已经被蓄意设定好的恶意代码。
按照冯·诺依曼存储程序原理,程序代码是作为二进制数据存储在存的,同样程序的数据也在存中,因此直接从存的二进制形式上是无法区分哪些是数据哪些是代码的,这也为缓冲区溢出攻击提供了可能。
图1 进程地址空间分布图1是进程地址空间分布的简单表示。
代码存储了用户程序的所有可执行代码,在程序正常执行的情况下,程序计数器(PC指针)只会在代码段和操作系统地址空间(核态)寻址。
数据段存储了用户程序的全局变量,文字池等。
缓冲区溢出攻击的原理与防范陈硕2004-7-12读者基础:熟悉C语言及其内存模型,了解x86汇编语言。
缓冲区溢出(buffer overflow)是安全的头号公敌,据报道,有50%以上的安全漏洞和缓冲区溢出有关。
C/C++语言对数组下标访问越界不做检查,是引起缓冲区溢出问题的根本原因。
本文以Linux on IA32(32-bit Intel Architecture,即常说的x86)为平台,介绍缓冲区溢出的原理与防范措施。
按照被攻击的缓冲区所处的位置,缓冲区溢出(buffer overflow)大致可分为两类:堆溢出1(heap overflow)和栈溢出2(stack overflow)。
栈溢出较为简单,我先以一些实例介绍栈溢出,然后谈一谈堆溢出的一般原理。
栈溢出原理我们知道,栈(stack)是一种基本的数据结构,具有后入先出(LIFO, Last-In-First-Out)的性质。
在x86平台上,调用函数时实际参数(arguments)、返回地址(return address)、局部变量(local variables)都位于栈上,栈是自高向低增长(先入栈的地址较高),栈指针(stack pointer)寄存器ESP始终指向栈顶元素。
以图表1中的简单程序为例,我们先将它编译为可执行文件,然后在gdb中反汇编并跟踪其运行:$ gcc stack.c –o stack -ggdb -mperferred-stack-boundary=2在IA32上,gcc默认按8个字节对齐,为了突出主题,我们令它按4字节对齐,最末一个参数的用处在此。
图表1在每条语句之后列出对应的汇编指令,注意这是AT&T格式汇编,mov %esp, %ebp 是将寄存器ESP的值赋给寄存器EBP(这与常用的Intel汇编格式正好相反)。
// stack.c#01 int add(int a, int b)#02 {// push %ebp// mov %esp,%ebp#03 int sum;// sub $0x4,%esp#04 sum = a + b;// mov 0xc(%ebp),%eax// add 0x8(%ebp),%eax// mov %eax,0xfffffffc(%ebp)#05 return sum;// mov 0xfffffffc(%ebp),%eax1本文把静态存储区溢出也算作一种堆溢出。
缓存溢出BufferOverflow缓存溢出(Buffer overflow),是指在存在缓存溢出安全漏洞的计算机中,攻击者可以⽤超出常规长度的字符数来填满⼀个域,通常是内存区地址。
在某些情况下,这些过量的字符能够作为“可执⾏”代码来运⾏。
从⽽使得攻击者可以不受安全措施的约束来控制被攻击的计算机。
缓存溢出(或译为缓冲溢出)为最为常⽤的攻击⼿段之⼀,蠕⾍病毒对操作系统的溢出⾼速与⼤规模传播均是利⽤此技术。
缓存从理论上来讲可以⽤于攻击任何有缺陷不完美的程序,包括对、等安全产品的攻击以及对银⾏程序的攻击。
下⾯让我们了解⼀下缓存溢出的原理。
众说周知,c语⾔不进⾏的边界检查,在许多运⽤c语⾔实现的应⽤程序中,都假定缓冲区的⼤⼩是⾜够的,其容量肯定⼤于要拷贝的字符串的长度。
然⽽事实并不总是这样,当程序出错或者恶意的⽤户故意送⼊⼀过长的字符串时,便有许多意想不到的事情发⽣,超过的那部分字符将会覆盖与相邻的其他的空间,使变量出现不可预料的值。
如果碰巧,与的返回地址邻近时,便有可能由于超出的⼀部分字符串覆盖了⼦程序的返回地址,⽽使得⼦程序执⾏完毕返回时转向了另⼀个⽆法预料的地址,使程序的执⾏流程发⽣了错误。
甚⾄,由于应⽤程序访问了不在进程范围的地址,⽽使进程发⽣违例的故障。
这种错误其实是编程中常犯的。
组成部分⼀个利⽤⽽企图破坏或⾮法进⼊系统的程序通常由如下⼏个部分组成:1.准备⼀段可以调出⼀个shell的形成的字符串,在下⾯我们将它称为shellcode。
2.申请⼀个缓冲区,并将填⼊缓冲区的低端。
3.估算在中可能的起始位置,并将这个位置写⼊缓冲区的⾼端。
这个起始的位置也是我们执⾏这⼀程序时需要反复调⽤的⼀个参数。
4.将这个缓冲区作为系统⼀个有缓冲区溢出错误程序的⼊⼝参数,并执⾏这个有错误的程序。
通过以上的分析和实例,我们可以看到缓存溢出对系统的安全带来的巨⼤威胁。
在unix系统中,使⽤⼀类精⼼编写的程序,利⽤suid程序中存在的这种错误可以很轻易地取得系统的的权限。