2020/3/28网络安全NetworkSecurity2020/3/28第7章计算机系统安全(缓冲区溢出)缓冲区溢出概述缓冲区溢出攻击的原理缓冲区溢出攻击的防御技术2020/3/28第7章计算机系统安全(缓冲区溢出)缓冲区溢出概述缓冲区溢出攻击的原理缓冲区溢出攻击的防御技术2020/3/28缓冲溢出概述1.缓冲区的定义连续的一段存储空间。2.缓冲区溢出的定义指写入缓冲区的数据量超过该缓冲区能容纳的最大限度,造成溢出的数据改写了与该缓冲区相邻的原始数据的情形。Bufferoverflowistheresultofwritingmoredataintoabufferthanthebuffercanhold.2020/3/28ExampleConsiderthefollowingcodeintmain(void){charbuffer[4];strcpy(buffer,“AAA”);……}mainstackframepreviousstackframe…………buffer[4]HighaddressesLowaddressesAAA\02020/3/28Example(contd.)Nowweinput4+4+3‘A’sinsteadof4‘A’s.intmain(void){charbuffer[4];strcpy(buffer,“”);}AAAAAAAAAAAAAAmainstackframepreviousstackframe…………buffer[4]HigheraddressesLoweraddresses?AAAAAAAAAAA\0……2020/3/28缓冲溢出概述(续)3.缓冲区溢出的危害利用缓冲区溢出实现在本地或者远程系统上实现任意执行代码的目的,从而进一步达到对被攻击系统的完全掌控;利用缓冲区溢出进行DoS(DenialofService)攻击;利用缓冲区溢出破坏关键数据,使系统的稳定性和有效性受到不同程度的影响;实现蠕虫程序1988RobertT.Morris蠕虫利用UNIX系统中In,theMorrisInternetwormexploitedbufferoverflowvulnerabilityinfingerdserverprogramonUNIXsystems.曾在2001年造成大约26亿美元损失的CodeRed蠕虫及其变体就是利用了MicrosoftIIS中的缓冲区溢出进行攻击2002年的Sapphire蠕虫和2004年的Witty蠕虫也都利用了缓冲区溢出进行攻击。In2004,theWittywormtakesadvantageofabufferoverflowflawinseveralInternetSecuritySystems™(ISS)products.2020/3/28SourcefromCERT(ComputerEmergencyResponseTeam)CERTAdvisories,缓冲区溢出相关的软件安全隐患数目占整个软件安全隐患数目的比例2020/3/28缓冲溢出概述(续)4.造成缓冲区溢出的根本原因代码在操作缓冲区时,没有有效地对缓冲区边界进行检查,使得写入缓冲区的数据量超过缓冲区能够容纳的范围,从而导致溢出的数据改写了与该缓冲区相邻存储单元的内容。CandC++arethemostcommonlanguagestocreatebufferoverflows.C语言中许多字符串处理函数如:Strcpy、Strcat、Gets、Sprintf等都没有对数组越界加以检测和限制。2020/3/28缓冲溢出概述(续)MicrosoftWindows,Linux/Unix,AppleMacintosh等主流操作系统无一例外存在缓冲区溢出问题。存在缓冲区溢出问题的应用程序也广泛存在,涉及数据库系统例如MicrosoftSQLServer2000,Oracle9i,网络服务(MicrosoftIIS),网络协议实现(例如OpenSSL),多媒体软件(AppleQuickTime)等等2020/3/28缓冲溢出概述(续)缓冲区溢出可以成为攻击者实现攻击目标的手段,但是单纯地溢出缓冲区并不能达到攻击的目的。在绝大多数情况下,一旦程序中发生缓冲区溢出,系统会立即中止程序并报告“faultsegment”。例如缓冲区溢出,将使返回地址改写为一个非法的、不存在的地址,从而出现coredump错误,不能达到攻击目的。只有对缓冲区溢出“适当地”加以利用,攻击者才能通过其实现攻击目标。2020/3/28第7章计算机系统安全(缓冲区溢出)缓冲区溢出概述缓冲区溢出攻击的原理缓冲区溢出攻击的防御技术2020/3/28缓冲溢出攻击的原理1.缓冲区溢出攻击模式AttackedSystem溢出缓冲区重定向到攻击程序任意地执行程序执行攻击程序Attacker注入恶意数据获得控制权找到可利用的缓冲区溢出隐患恶意数据可以通过命令行参数、环境变量、输入文件或者网络数据注入2020/3/28缓冲溢出攻击的原理(续)2.缓冲区溢出可能发生的位置预备知识点进程在内存中的布局2020/3/28缓冲溢出攻击的原理(续)代码段/文本段用于放置程序的可执行代码(机器码)。数据段用于放置已初始化的全局变量和已初始化的局部静态变量。BSS(BlockStartedbySymbol)段用于放置未初始化的全局变量和未初始化的局部静态变量。堆用于动态分配内存。堆栈段用于存放函数的参数,返回地址,调用函数的栈基址以及局部非静态变量。进程的环境变量和参数.text.data.bssheapunusedstackenvLowaddressHighaddressLinux/IntelIA-32architecture2020/3/28缓冲溢出攻击的原理(续)2.缓冲区溢出可能发生的位置(续)堆栈(stack)堆(heap)数据段(data)BSS段.text.data.bssheapunusedstackenvLowaddressHighaddressLinux/IntelIA-32architecture2020/3/28缓冲溢出攻击的原理(续)2.缓冲区溢出可能发生的位置(续)堆栈(stack)堆(heap)数据段(data)BSS段.text.data.bssheapunusedstackenvLowaddressHighaddressLinux/IntelIA-32architecture2020/3/28被调函数堆栈布局堆栈采用后进先出(LIFO)的方式管理数据,这种方式是实现函数嵌套调用的关键。PreviousstackframesFunctionargumentsReturnaddressPreviousframepointerLocalvariablesHighaddressLowaddress从右到左的顺序指令寄存器(EIP)基址寄存器(EBP)局部非静态变量2020/3/28缓冲溢出攻击的原理(续)基于堆栈的缓冲区溢出voidfunction(char*str){charbuffer[4];strcpy(buffer,str);}voidmain(intargc,char**argv){charlarge_string[8];inti;for(i=0;i8;i++)large_buffer[i]=‘A’function(large_string);}2020/3/28Example(contd.)Large_string上一个栈帧地址返回地址argv内存低端内存高端argcESPmain函数栈帧voidmain(intargc,char**argv)i2020/3/28缓冲溢出攻击的原理(续)基于堆栈的缓冲区溢出voidfunction(char*str){charbuffer[4];strcpy(buffer,str);}voidmain(intargc,char**argv){charlarge_string[8];inti;for(i=0;i8;i++)large_buffer[i]=‘A’function(large_string);}2020/3/28Example(contd.)Large_string上一个栈帧地址返回地址argv内存低端内存高端argcESPMain函数的栈帧i*str返回地址main函数的栈帧地址bufferfunction函数栈帧function函数被调用,调用strcpy之前voidfunction(char*str)…………2020/3/28Example(contd.)Large_string上一个栈帧地址返回地址argv内存低端内存高端argcESPMain函数的栈帧i*str返回地址AAAAAAAAfunction函数栈帧function函数被调用,调用strcpy之后voidfunction(char*str)…………2020/3/28缓冲溢出攻击的原理(续)基于堆栈的缓冲区溢出的潜在危害改写返回地址改写调用函数栈的栈帧地址被调函数……movl%ebp,%esppopl%ebpret调用函数……movl%ebp,%esppopl%ebpret2020/3/28缓冲溢出攻击的原理(续)基于堆栈的缓冲区溢出的潜在危害(续)改写函数指针改写虚函数指针改写异常处理指针改写数据指针voidBadCode(char*string){void(*p)()=...;charbuff[100];strcpy(buff,string);p();……}2020/3/28缓冲溢出攻击的原理(续)2.缓冲区溢出可能发生的位置(续)堆栈(stack)堆(heap)数据段(data)BSS段.text.data.bssheapunusedstackenvLowaddressHighaddressLinux/IntelIA-32architecture2020/3/28缓冲溢出攻击的原理(续)基于堆的缓冲区溢出Heapisacontiguousmemoryusedtodynamicallyallocatespacewherethesizewillbeknownonlyduringtheexecutionofthecode.在Linux中,堆空间按照DougLea算法实现动态分配。在C程序中,标准库函数malloc()/free()用于从堆中动态申请/释放块;对于C++程序,相应函数为new/delete。2020/3/28缓冲溢出攻击的原理(续)基于堆的缓冲区溢出(续)voidmain(intargc,char**argv){char*buf1=(char*)malloc(16);char*buf2=(char*)malloc(16);strcpy(buf1,”AAAAAAAAAAAAAAA”);strcpy(buf2,argv[1]);}0030035000300360003003700030034000300380buf[2]buf[1]buf[2]AAAAAAAAAAAAAAA\02020/3/28buf[2]AAAAAAAAAAAAAAAA基于堆的缓冲区溢出正常输入Prompt:BB..BBB(total15‘B’s)产生溢出的输入Prompt:BB..BBB(total40‘B’s)(a)heaplayoutwithoutoverflow0030035000300360003003700030034000300380BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\0AAAAAA\0(b)heaplayoutwithoverflowBBBBBBBB