网络安全12-Windows缓冲区溢出攻击.pptx
《网络安全12-Windows缓冲区溢出攻击.pptx》由会员分享,可在线阅读,更多相关《网络安全12-Windows缓冲区溢出攻击.pptx(67页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。
1、第12讲第10章 Windows系统的缓冲区溢出攻击第10章Windows系统的缓冲区溢出攻击Windows系统是目前应用最广泛的桌面操作系统,对其入侵能获得巨大的利益,因而其安全漏洞及利用技术是黑客最乐意研究的。Windows系统是闭源软件,在没有源代码的情况下很难获得该系统全面而准确的信息,而这些信息对于漏洞攻击是至关重要。因此,要成功攻破Windows系统,难度是很大的。Linux和Windows系统的缓冲溢出原理是相同的:用超过缓冲区容量的数据写缓冲区,从而覆盖缓冲区之外的存储空间(高地址空间),破坏进程的数据。由于函数的返回地址一般位于缓冲区的上方,返回地址也是可以改写的,这样就可控
2、制进程的执行流程。Windows溢出攻击210.1 Win32的进程映像了解内存中的进程映像是进行攻击的基础,例程mem_distribute.c用于观察进程的内存映像。编译并运行该例程:C:Worknswin32Codebincl.srcmem_distribute.c./out:mem_distribute.exemem_distribute.objC:Worknswin32Codebinmem_distribute.exeWindows溢出攻击3(.text)addressoffun1=00401000fun2=0040100Bmain=00401017(.datainitedGloba
3、lvariable)addressofx(inited)=00406030z(inited)=00406034(.bssuninitedGlobalvariable)addressofy(uninit)=00406BF4(stack)addressofargc=0012FF88argv=0012FF8Cargv0=00410EC8(Localvariable)addressofvulnbuff64=0012FF34(Localvariable)addressofa(inited)=0012FF7Cb(uninit)=0012FF78c(inited)=0012FF74Windows溢出攻击4W
4、in32进程映像的特点Win32进程的内存分布呈现与Linux IA32进程类似的内存分布,也分成代码、变量、堆栈区等。具有以下特点:1)可可执执行行代代码码fun1,fun2,main存放在内存的低地址端,且按照源代码中的顺序从低地址到高地址排列(先定义的函数的代码存放在内存的低地址)。2)全全局局变变量量(x,y,z)也存放内存低端,位于可执行代码之上(起始地址高于可执行代码的地址)。初始化的全局变量存放在低地址,而未初始化的全局变量位于高地址。Windows溢出攻击53)局局部部变变量量位于堆栈的低地址区(0 x0012 FFxx):字符串变量虽然先定义,但是其起始地址小于其他变量,最后
5、进栈;其它变量从低地址到高地址依次逆序(先定义的放在高地址,类似于栈的push操作)存放。4)函函数数的的入入口口参参数数的地址(0 x0012 FFxx)位于堆栈的高地址区,位于函数局部变量之上。Windows溢出攻击6由 3、4可 以 推 断 出,栈 底(最 高 地 址)位 于0 x0012FFFC,环境变量和局部变量处于进程的栈区。进一步的分析知道,函数的返回地址也位于进程的栈区。整体上看,Win32进程的内存映像上分成3大块:0 x7CXX XXXX:动态链接库的映射区,比如kernel32.dll,ntdll.dll0 x0040 0000:可执行程序的代码段及数据段0 x0012
6、FFFC:堆栈区7Windows溢出攻击Win32进程映像高地址0 x7CXX-XXXX动态链接库的映射区比如kernel32.dll,ntdll.dll空白区高地址.bssglobal未初始化全局变量.dataglobal初始化的全局变量mainfun20 x00401000fun1低地址低地址0 x0012FFFC(堆栈堆栈)高高地址地址0 x0012FF8Cargvmain的参数的地址即命令行参数的地址0 x0012FF88argclocal局部变量低地址低地址8Windows溢出攻击注注:该程序(mem_distribute.c)在Windows7下的运行结果每次都不同,这就说明了Wi
7、ndows7对进程的地址空间使用了地址随机化机制,使得进程的地址空间每次运行均不同。进一步的测试表明,Windows7动态链接库的加载基址不随进程的运行次数改变,然而,如果重新启动操作系统,则动态链接库的加载基址也会变化。Windows溢出攻击9数据段进程有三种数据段:.text、.data、.bss。.text(文本区),任何尝试对该区的写操作会导致段违法出错。文本区存放了程序的代码,包括main函数和其他子函数。.data和.bss都是可写的。它们保存全局变量,.data段包含已初始化的静态变量,而.bss包含未初始化的数据。10Windows溢出攻击栈的信息函数调用时所建立的栈帧包含了下
8、面的信息:1)函函数数的的返返回回地地址址。IA32的返回地址都是存放在被调用函数的栈帧里。2)调调用用函函数数的的栈栈帧帧信信息息,即栈顶和栈底(最高地址)。3)为为函数的局部变量分配的空间函数的局部变量分配的空间。4)为为被调用函数的参数分配的空间被调用函数的参数分配的空间。返返回回地地址址位于高地址,局部变量位于底地址,因此对字符串的操作有有可能可能覆盖返回地址覆盖返回地址。11Windows溢出攻击10.2 Win32缓冲区溢出流程为了改写被调用函数的返返回回地地址址,必须确定返回地址与缓冲区起始地址的距离(也称为偏移,常用OFF_SET表示)。这就需要对可执行文件进行调试和追踪。例程
9、2:overflow.cchar largebuff=01234567890123456789ABCDEFGH;/28 bytesvoid foo()char smallbuff16;strcpy(smallbuff,largebuff);int main(void)foo();Windows溢出攻击12例程overflow.c有一个缓冲区溢出漏洞。编译并执行该程序:C:Worknswin32Codebincl.srcoverflow.c/out:overflow.exeoverflow.objC:Worknswin32Codebinoverflow.exe软件运行出错,系统弹出一个窗口,结果
10、如图10-1所示。Windows溢出攻击13图10-1 进程运行错误的提示窗口Windows溢出攻击14系统提示overflow.exe已停止工作。为了找到错误的根源,必须调试overflow.exe。为了对Windows的进程进行调试,需要选择合适的调试和反汇编工具。著名的第三方工具有IDA、ollydbg、softICE等。这些工具提供了友好的界面和强大的功能,读者可以根据个人偏好选用。这里选用微软公司为其设备驱动开发套件(Windows Driver Kit)配套的windbg。Windows溢出攻击15Windows溢出攻击16图10-2 打开可执行文件Windows溢出攻击17图10
11、-3 windbg的command窗口反汇编main函数,在command的命令行输入:u main,则显示如下信息:0:000 u main*WARNING:Unable to verify checksum for image00400000*ERROR:Module load completed but symbols could not be loaded for image00400000*ERROR:Symbol file could not be found.Defaulted to export symbols for C:WINDOWSsystem32kernel32.dll
12、-Couldnt resolve error at mainwindbg提示找不到符号main。这是因为默认编译C程序并不会输出符号文件。Windows溢出攻击18为了便于调试程序,用/Fd/Zi选项重新编译overflow.c,以输出符号表文件(*.pdb)。C:Worknswin32Codebincl/FD/Zi.srcoverflow.c/out:overflow.exe/debugoverflow.objC:Worknswin32Codebindir overflow.*2014-12-13 08:48 112,640 overflow.exe2014-12-13 08:48 554,
13、424 overflow.ilk2014-12-13 08:48 3,247 overflow.obj2014-12-13 08:48 838,656 overflow.pdboverflow.pdb就是符号表文件。启动windbg,在File菜单中选Open Executable打开overflow.exe,windbg打开默认的command窗口。Windows溢出攻击19在command的命令行输入:u main,则显示汇编代码如下:0:000 u main*WARNING:Unable to verify checksum for overflow.exeoverflow!main c
14、:worknswin32codeoverflow.c 13:00401050 55 push ebp00401051 8bec mov ebp,esp00401053 e8adffffff call overflow!ILT+0(_foo)(00401005)00401058 33c0 xor eax,eax0040105a 5d pop ebp0040105b c3 retWindows溢出攻击20反汇编函数foo:0:000 u foo L12overflow!foo c:worknswin32codeoverflow.c 8:00401020 55 push ebp00401021 8b
15、ec mov ebp,esp00401023 83ec14 sub esp,14h00401026 a120b04100 mov eax,dword ptr overflow!_security_cookie(0041b020)0040102b 33c5 xor eax,ebp0040102d 8945fc mov dword ptr ebp-4,eax00401030 6800b04100 push offset overflow!largebuff(0041b000)00401035 8d45ec lea eax,ebp-14h00401038 50 push eax00401039 e8
16、32000000 call overflow!strcpy(00401070)0040103e 83c408 add esp,800401041 8b4dfc mov ecx,dword ptr ebp-400401044 33cd xor ecx,ebp00401046 e81d010000 call overflow!_security_check_cookie(00401168)0040104b 8be5 mov esp,ebp0040104d 5d pop ebp0040104e c3 retWindows溢出攻击21Windows溢出攻击22图10-4 反汇编窗口Windows溢出攻
17、击23图10-5 反汇编窗口在函数的入口、strcpy调用点和函数的返回点用bp命令设置3个断点。设置断点后,反汇编窗口中的相应行用红色背景突出显示。在command窗口输入g,或按F5,启动调试。进程执行到第一个断点(foo的第一条语句),并在command窗口中显示当前指令及寄存器的值:0:000 gBreakpoint 0 hiteax=00373008 ebx=7ffd9000 ecx=00000001 edx=7c95845c esi=00000000 edi=00000000eip=00401020 esp=0012ff74 ebp=0012ff78 iopl=0 nv up ei
18、 pl zr na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246overflow!foo:00401020 55 push ebp0:000 dd esp0012ff74 00401058 0012ffc0 004012e2 00000001Windows溢出攻击24记录下esp的值:A=esp=0012ff74,该地址的内存(堆栈)保存了foo的返回地址。用dd esp命令显示堆栈的值为00401058,该地址是函数main第4条汇编指令的地址,而main的第3条 汇 编 指 令 为 call overfl
19、ow!ILT+0(_foo)(00401005)。在反汇编窗口中可以看到地址为00401005的汇编指令为jmp overflow!foo(00871020),如图10-6所示。这样就验证了esp指向的栈保存的是函数foo的返回地址。Windows溢出攻击25Windows溢出攻击26图10-6 esp等于存放返回地址的栈指针按F5执行到下一个断点,观察执行strcpy之前esp寄存器的值。0:000 dd esp0012ff54 0012ff5c 0041b000 00402b40 3c85029b.0:000 da 0041b0000041b000 01234567890123456789
20、ABCDEFGH可见smallbuf的起始地址B=0012ff5c,largebuf的起始地址=0041b000。返回地址与smallbuf的起始地址的距离=A-B=0 x18=24。因此,可以推测返回地址被覆盖为largebuf偏移24开始的4个字符“EFGH”。以下命令的结果也证实了这点。0:000 da 0041b000+0 x180041b014 EFGHWindows溢出攻击27按F5继续执行,在命令窗口的输出为0:000 g.ntdll!KiFastSystemCallRet:7c95845c c3 ret0:000 g No runnable debuggees error in
21、 g程序并未执行到下一个断点,而是跳转到内核去执行其他的指令。这是因为新版本的VC编译器默认打开了函数的安全检查,即security check,对应于函数foo的以下两条汇编指令:00401026 a120b04100 mov eax,dword ptr overflow!_security_cookie(0041b020)00401046 e81d010000 call overflow!_security_check_cookie(00401168)Windows溢出攻击28security check机制是这样的:(1)函数foo先调用_security_cookie保存一个cooki
22、e,再执行其他指令;(2)函数foo退出之前调用_security_check_cookie,检查cookie的值是否被改写。若cookie被改写,则说明出现了缓冲区溢出错误,引发异常且中断程序的执行,从而防止了错误的进一步扩散。一般说来,如果打开了编译器的安全检查,则缓冲区溢出漏洞虽然也能破坏进程的内存空间(相邻的变量),但并不能导致进程被劫持。这是因为即使返回地址被改写,函数中的ret语句也不会被执行,从而无法改变进程的执行流程。Windows溢出攻击29为了演示进程被劫持的原理,我们关闭编译器的安全检查,用参数/GS-重新编译overflow.c:C:Worknswin32Codebin
23、cl/FD/Zi/GS-.srcoverflow.c用gdb调试overflow.exe,函数foo的反汇编代码如下:0:000 u foo L10overflow!foo c:worknswin32codeoverflow.c 8:00401020 55 push ebp00401021 8bec mov ebp,esp0040102f e83c000000 call overflow!strcpy(00401070)00401039 5d pop ebp0040103a c3 retWindows溢出攻击30在0108120、0108102f、0108103a设置3个断点。在command
24、窗口输入g或按F5,启动进程执行到foo的第一条语句,观察esp寄存器的值。0:000 dd esp0012ff74 00401048 0012ffc0 004012e2 00000001按F5执行到下一个断点,观察执行strcpy之前esp寄存器的值。0:000 dd esp0012ff58 0012ff60 0041b000 84af87e3 fffffffe.0:000 da 0041b0000041b000 01234567890123456789ABCDEFGH可见smallbuf的起始地址B=0012ff60,函数的返回地址保存在A=0012ff74。Windows溢出攻击31返回
25、地址与smallbuf的起始地址的距离(偏偏移移)OFF_SET=A-B=0 x14=20。因此,可以推测返回地址被覆盖为largebuf偏移20开始的4个字符“ABCD”。以下命令的结果证实了这点。0:000 da 0041b000+0 x140041b014 ABCDEFGH细心的读者会发现,现在的OFF_SET为0 x14。若打开C编译器的安全检查,则OFF_SET为0 x18,这多出的4个字节用于保存cookie的值。Windows溢出攻击32按F5继续执行,观察执行ret之前esp寄存器的值。0:000 dd esp0012ff74 44434241 48474645 0040120
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 网络安全 12 Windows 缓冲区 溢出 攻击
限制150内