Windows Kernel Out-of-Bounds Read in CI!HashKComputeFirstPageHash While Parsing Malformed PE File

2019.10.25
Credit: Anonymous
Risk: High
Local: Yes
Remote: No
CVE: N/A
CWE: N/A

We have encountered a Windows kernel crash in CI!HashKComputeFirstPageHash while trying to load a malformed PE image into the process address space as a data file (i.e. LoadLibraryEx(LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE)). An example crash log generated after triggering the bug is shown below: --- cut --- *** Fatal System Error: 0x00000050 (0xFFFFF80068F02000,0x0000000000000000,0xFFFFF80067291A2C,0x0000000000000000) Driver at fault: *** CI.dll - Address FFFFF80067291A2C base at FFFFF80067230000, DateStamp 8581dc0d . Break instruction exception - code 80000003 (first chance) A fatal system error has occurred. Debugger entered on first try; Bugcheck callbacks have not been invoked. A fatal system error has occurred. [...] ******************************************************************************* * * * Bugcheck Analysis * * * ******************************************************************************* PAGE_FAULT_IN_NONPAGED_AREA (50) Invalid system memory was referenced. This cannot be protected by try-except. Typically the address is just plain bad or it is pointing at freed memory. Arguments: Arg1: fffff80068f02000, memory referenced. Arg2: 0000000000000000, value 0 = read operation, 1 = write operation. Arg3: fffff80067291a2c, If non-zero, the instruction address which referenced the bad memory address. Arg4: 0000000000000000, (reserved) [...] TRAP_FRAME: ffffe20f4b7d6400 -- (.trap 0xffffe20f4b7d6400) NOTE: The trap frame does not contain all registers. Some register values may be zeroed or incorrect. rax=00000000000000c8 rbx=0000000000000000 rcx=144670b8d60e0000 rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000 rip=fffff80067291a2c rsp=ffffe20f4b7d6590 rbp=ffffe20f4b7d6690 r8=00000000fffffe00 r9=fffff80068ef0000 r10=0000000000000002 r11=ffffe20f4b7d6760 r12=0000000000000000 r13=0000000000000000 r14=0000000000000000 r15=0000000000000000 iopl=0 nv up ei pl nz na pe nc CI!HashKComputeFirstPageHash+0x1f4: fffff800`67291a2c 418b5dd4 mov ebx,dword ptr [r13-2Ch] ds:ffffffff`ffffffd4=???????? Resetting default scope LAST_CONTROL_TRANSFER: from fffff80065aa6642 to fffff800659c46a0 STACK_TEXT: ffffe20f`4b7d59b8 fffff800`65aa6642 : fffff800`68f02000 00000000`00000003 ffffe20f`4b7d5b20 fffff800`65922be0 : nt!DbgBreakPointWithStatus ffffe20f`4b7d59c0 fffff800`65aa5d32 : fffff800`00000003 ffffe20f`4b7d5b20 fffff800`659d0fb0 ffffe20f`4b7d6060 : nt!KiBugCheckDebugBreak+0x12 ffffe20f`4b7d5a20 fffff800`659bca07 : ffff8bc5`e2f17f80 fffff800`65ad0110 00000000`00000000 fffff800`65c63900 : nt!KeBugCheck2+0x952 ffffe20f`4b7d6120 fffff800`659e0161 : 00000000`00000050 fffff800`68f02000 00000000`00000000 ffffe20f`4b7d6400 : nt!KeBugCheckEx+0x107 ffffe20f`4b7d6160 fffff800`6587aaef : fffffb00`023b21b0 00000000`00000000 00000000`00000000 fffff800`68f02000 : nt!MiSystemFault+0x1d3171 ffffe20f`4b7d6260 fffff800`659ca920 : ffffe20f`4b7d6860 00000000`00000000 00000000`00000200 fffff800`65c651c0 : nt!MmAccessFault+0x34f ffffe20f`4b7d6400 fffff800`67291a2c : 00000000`00000000 ffffe20f`4b7d6690 00000000`00000000 00000000`00001000 : nt!KiPageFault+0x360 ffffe20f`4b7d6590 fffff800`67280829 : 00000000`00000000 ffffce0d`8ae71003 ffffac8f`23a2a9e8 00000000`00000000 : CI!HashKComputeFirstPageHash+0x1f4 ffffe20f`4b7d67c0 fffff800`6727f10d : ffffac8f`23a2a5a0 ffffce0d`8ae71080 ffffce0d`00000000 00000000`00000000 : CI!CipGetEmbeddedSignatureAndFindFirstMatch+0x181 ffffe20f`4b7d6860 fffff800`6727e89a : ffffac8f`23a2a5a0 ffffce0d`8b7e1d50 ffffce0d`8ae71080 fffff800`68ef0000 : CI!CipValidatePageHash+0xfd ffffe20f`4b7d6950 fffff800`6727cc8b : fffff800`6727f010 ffffe20f`4b7d6c8c ffffce0d`8b7e1d50 ffffce0d`8ae71080 : CI!CipValidateImageHash+0xe6 ffffe20f`4b7d6a30 fffff800`65e85766 : ffffe20f`4b7d6c70 fffff800`68ef0000 00000000`0000000e fffff800`68ef0000 : CI!CiValidateImageHeader+0x68b ffffe20f`4b7d6bb0 fffff800`65e8528a : 00000000`00000000 00000000`00000001 00000000`00000000 00000000`00012000 : nt!SeValidateImageHeader+0xd6 ffffe20f`4b7d6c60 fffff800`65e1e0da : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!MiValidateSectionCreate+0x436 ffffe20f`4b7d6e50 fffff800`65dfc861 : ffffe20f`4b7d7180 ffffe20f`4b7d6fb0 00000000`40000000 ffffe20f`4b7d7180 : nt!MiValidateSectionSigningPolicy+0xa6 ffffe20f`4b7d6eb0 fffff800`65ddca20 : ffffce0d`8b7e1d50 ffffe20f`4b7d7180 ffffe20f`4b7d7180 ffffce0d`8b7e1d20 : nt!MiCreateNewSection+0x5ad ffffe20f`4b7d7010 fffff800`65ddcd24 : ffffe20f`4b7d7040 ffffac8f`2af6a9f0 ffffce0d`8b7e1d50 00000000`00000000 : nt!MiCreateImageOrDataSection+0x2d0 ffffe20f`4b7d7100 fffff800`65ddc37f : 00000000`11000000 ffffe20f`4b7d74c0 00000000`00000001 00000000`00000002 : nt!MiCreateSection+0xf4 ffffe20f`4b7d7280 fffff800`65ddc110 : 00000010`0e3f8dc8 00000000`00000005 00000000`00000000 00000000`00000001 : nt!MiCreateSectionCommon+0x1ff ffffe20f`4b7d7360 fffff800`659ce115 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!NtCreateSection+0x60 ffffe20f`4b7d73d0 00007ffe`c317c9a4 : 00007ffe`c0511ae7 00000000`00000000 00000000`00000001 40b28496`f324e4f9 : nt!KiSystemServiceCopyEnd+0x25 00000010`0e3f8d58 00007ffe`c0511ae7 : 00000000`00000000 00000000`00000001 40b28496`f324e4f9 feafc9c1`1796ffa1 : ntdll!NtCreateSection+0x14 00000010`0e3f8d60 00007ffe`c0515640 : 00000129`5f442be0 0000001b`00000000 00007ffe`c1f72770 00000000`00000022 : KERNELBASE!BasepLoadLibraryAsDataFileInternal+0x2e7 00000010`0e3f8f90 00007ffe`c04fc41d : 00000129`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNELBASE!LoadLibraryExW+0xe0 00000010`0e3f9000 00007ffe`c16903d1 : 00000129`5f414f00 00000000`00000000 00000129`5f443840 00007ffe`c16a6d85 : KERNELBASE!GetFileVersionInfoSizeExW+0x3d 00000010`0e3f9060 00007ffe`c169035c : 00000000`00000000 00007ffe`c08710ff 00000129`5f414f00 00000010`0e3f93b0 : shell32!_LoadVersionInfo+0x39 00000010`0e3f90d0 00007ffe`c08ec1c1 : 00000000`00000000 00000000`00000000 ffffffff`fffffffe 00000000`00000000 : shell32!CVersionPropertyStore::Initialize+0x2c [...] --- cut --- We have minimized one of the crashing samples down to a 3-byte difference in relation to the original file: one which decreases NumberOfSections from 4 to 3, one which increases SizeOfOptionalHeader from 0xF0 to 0xCEF0, and one which changes DllCharacteristics from 0 to 0x00FF (IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY | IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE | 0xf). The issue reproduces on Windows 10 and Windows Server 2019 64-bit (Special Pools not required). The crash occurs when any system component calls LoadLibraryEx(LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE) against the file, either directly or through another API such as GetFileVersionInfoSizeExW() or GetFileVersionInfoW(). In practice, this means that as soon as the file is displayed in Explorer, or the user hovers the cursor over it, or tries to open the file properties, or tries to rename it or perform any other similar action, the system will panic. In other words, just downloading such a file may permanently block the user's machine until they remove it through Recovery Mode etc. The attack scenario is similar to the one described in https://www.fortinet.com/blog/threat-research/microsoft-windows-remote-kernel-crash-vulnerability.html. Due to the nature of the bug (OOB read), it could be also potentially exploited as a limited information disclosure primitive. Attached is an archive with a minimized proof-of-concept PE image, the original file used to generate it, and one additional non-minimized sample. Please be careful when unpacking the ZIP as Windows may crash immediately once it sees the corrupted files on disk.


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2024, cxsecurity.com

 

Back to Top