MSI NTIOLib.sys / WinIO.sys Local Privilege Escalation

2016-09-26T00:00:00
ID PACKETSTORM:138857
Type packetstorm
Reporter ReWolf
Modified 2016-09-26T00:00:00

Description

                                        
                                            `#Exploit Title: MSI NTIOLib.sys, WinIO.sys local privilege escalation  
#Date: 2016-09-26  
#Exploit Author: ReWolf  
#Vendor Homepage: http://www.msi.com  
#Version: too many  
#Tested on: Windows 10 x64 (TH2, RS1)  
  
Full description: http://blog.rewolf.pl/blog/?p=1630  
Exploit github repo: https://github.com/rwfpl/rewolf-msi-exploit  
  
EDB PoC Mirror:  
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/40426.zip  
  
NTIOLib.sys is installed with a few different MSI utilities that are part of the software package for MSI motherboards and graphic cards. WinIO.sys is completely different driver and is installed with Dragon Gaming Center application, which is part of the software package for MSI notebooks. Since both drivers expose physical memory access to the unprivileged users, I decided to put it into one report (Iall describe the technical differences later). Actually when I was verifying list of affected software, Iave found third driver that is doing exactly the same thing, just have a bit different interface and name (RTCore32.sys / RTCore64.sys).  
  
Affected software:  
  
NTIOLib.sys / NTIOLib_X64.sys  
MSI FastBoot  
MSI Command Center  
MSI Live Update  
MSI Gaming APP  
MSI Super Charger  
MSI Dragon Center  
WinIO.sys / WinIO64.sys  
MSI Dragon Gaming Center  
MSI Dragon Center  
RTCore32.sys / RTCore64.sys  
MSI Afterburner  
  
NTIOLib functionality exposed through IOCTLs:  
  
read/write physical memory (using MmMapIoSpace)  
read write MSR registers (using rdmsr/wrmsr opcodes)  
read PMC register (using rdpmc opcode)  
in/out port operations  
HalGetBusDataByOffset / HalSetBusDataByOffset  
  
WinIO functionality exposed through IOCTLs:  
  
read/write physical memory (ZwMapViewOfSection of a\\Device\\PhysicalMemorya)  
in/out port operations  
  
RTCore functionality exposed through IOCTLs:  
  
read/write physical memory (ZwMapViewOfSection of a\\Device\\PhysicalMemorya)  
read write MSR registers (using rdmsr/wrmsr opcodes)  
in/out port operations  
HalGetBusDataByOffset / HalSetBusDataByOffset  
  
It appears that RTCore driver is kind of hybrid between NTIOLib and WinIO. Itas also worth noting that WinIO driver is just compiled (and signed by MSI) version of the code that can be found here: http://www.internals.com/utilities_main.htm.  
  
UPDATE: RTCore driver is part of RivaTuner software, so all OEM branded RivaTuner clones are vulnerable (https://twitter.com/equilibriumuk/status/780367990160326656).  
  
Some of the mentioned applications load vulnerable driver on demand, but some of them loads the driver with service startup and keeps it loaded for the whole time, thus exploitation is rather trivial. I havenat thoroughly inspected all MSI applications, since itas not really possible (different version of the software for different hardware, multiple installers etc), so itas very probable that my list doesnat cover all cases. Generally if someone owns any MSI hardware, itas good to check if any of above drivers (or with similar name) is loaded, and if yes, just remove the application that installed it.  
  
Disclosure timeline:  
30.05.2016 sent e-mail notification to the addresses: security@msi.com, secure@msi.com, bugs@msi.com (none of those is valid, but it was worth trying)  
31.05.2016 a 03.06.2016 tried reporting through official support channel, without any luck, final reply:  
  
Please donat worry about it and the software files are secure.Anyway,we will send the information to relative department.Thanks!  
  
03.06.2016 tried contact through a friend from security team of some super-secret big corporation a also without luck  
26.09.2016 full disclosure  
  
Technical details & PoC  
  
After ASMMAP disclosure, Iave read that the exploitation of this kind of vulnerability is rather easy:  
  
This can be done by scanning for EPROCESS structures within memory and identifying one, then jumping through the linked list to find your target process and a known SYSTEM process (e.g. lsass), then duplicating the Token field across to elevate your process. This part isnat really that novel or interesting, so I wonat go into it here.  
  
Since I donat have much experience in this area, I decided to try above method and see if the exploitation is really straightforward. Iave started randomly poking with physical pages, just to see how it behaves. My first observation was, that the WinIO driver is a lot more stable than NTIOLib, it probably stems from the method that is used to expose physical memory to the user application (MmMapIoSpace vs ZwMapViewOfSection). NTIOLib tends to BSODs sometimes, especially if the accessed addresses are random (aligned to the 0x1000). My second observation was, that NTIOLib becomes quite stable if the memory is accessed sequentially (page by page). This is actually good, because EPROCESS search is sequential activity.  
  
EPROCESS structures are allocated with Proc pool tag, this is the first indicator that EPROCESS search algorithm will look for. Each memory chunk starts with POOL_HEADER structure, followed by a few OBJECT_HEADER_xxx_INFO structures and finally by the OBJECT_HEADER. OBJECT_HEADER.Body is the actual EPROCESS. More details can be found in Uninformed Journal or in WRK (ObpAllocateObject, \wrk\base\ntos\ob\obcreate.c). On Windows 10 x64 (TH2, RS1) all those structures sums up to 0x80 bytes. To successfully execute local privilege escalation, I need to locate EPROCESS structure of 2 processes. One will be some system process and the second should be the process that privileges are supposed to be escalated. For system process I chose wininit.exe, and the escalated process will be the current process. Having names and PIDs of chosen processes, exploit can proceed to final EPROCESS verification (checks of UniqueProcessId and ImageFileName fields).  
  
With above information it is possible to test initial exploit a it is very slow, so slow that I havenat wait till it finish. The slowdown comes from accessing addresses that are reserved for hardware IO devices. Those reserved memory ranges will vary from one machine to another, so itas required to find them out and skip during EPROCESS search. The easiest method to get those ranges is calling NtQuerySystemInformation with SuperfetchInformationClass (http://www.alex-ionescu.com/?p=51), however this call requires elevation, so it has no use in this case. Second place where this information can be obtained is WMI (CIMV2, Win32_DeviceMemoryAddress). This method is not as accurate as SuperfetchInformationClass, but I decided to use it in my PoC. Information returned on VMware test system were 100% accurate, and the slowdown disappeared, however I was still experiencing slowdown on my host machine. I come up with really simple and ugly solution: Iave added hardcoded <0xF0000000-0xFFFFFFFF> region to the ranges returned from WMI. At this point PoC successfully runs on both VMware test machine (Win10 x64 TH2) and my host machine (Win10 x64 RS1):  
  
Whoami: secret\user  
Found wininit.exe PID: 000002D8  
Looking for wininit.exe EPROCESS...  
EPROCESS: wininit.exe, token: FFFF8A06105A006B, PID: 2D8  
Stealing token...  
Stolen token: FFFF8A06105A006B  
Looking for MsiExploit.exe EPROCESS...  
EPROCESS: MsiExploit.exe, token: FFFF8A0642E3B957, PID: CAA8  
Reusing token...  
Whoami: nt authority\system  
  
Over-engineered version of PoC can be found on github (Visual Studio 2015 recommended):  
  
https://github.com/rwfpl/rewolf-msi-exploit  
  
It has hard-coded EPROCESS field offsets, so it only works on Win10 x64 TH2/RS1. PoC should work with any version of NTIOLib and WinIO drivers. I havenat fully analyzed RTCore interface due to the fact, that I found it just today, so obviously it is not included in PoC.  
  
`