CVE-2021-44852 – Biostar RACING GT Evo

Mike Alfaro 1/1/2022

What Is a CVE?

The mission of the CVE® Program is to identify, define, and catalog publicly disclosed cybersecurity vulnerabilities. Common Vulnerabilities and Exposures (CVE) is a database of these security issues. A CVE number uniquely identifies one vulnerability from the list. Enterprises typically use CVE, and corresponding CVSS scores, for planning and prioritization in their vulnerability management programs.

The CVE Program actively partners with community members worldwide to help grow CVE content and expand its use. Mike Alfaro, NephōSec Cybersecurity Engineer, submitted CVE-2021-44852 – Biostar RACING GT Evo and it has been published to the CVE List. The CVE Record is now available for viewing by the public. The CVE details can be viewed below on the NephōSec website or can be downloaded from the CVE website. https://www.cve.org/ 

Overview

CVE-2021-44852 describes the principal vulnerability within the BS_RCIO64.sys driver, provided by Biostar’s RACING GT Evo utility. The provided driver fails to assign a strict access control list (ACL) to the driver’s device object, which is a symbolic name that a User Mode (UM)  or Kernel Mode (KM) process may open to interact with and instruct the driver. Analysis has shown the driver contains and exposes known-vulnerable functions, which may be exploited by low-privileged, UM processes on the system.  Vulnerable drivers from gaming peripheral manufacturers’ often share much in common with, and may even directly copy source or functionality from well known hardware-control drivers such as WinIO and WinRing0. These drivers present inherent security risks, as they are explicitly designed to perform privileged actions within the Kernel that are normally safe-guarded against low-privileged UM processes. Further, the driver is signed by BioStar, and has been certified by Windows Hardware Quality Labs (WHQL), allowing the driver to be loaded on Windows systems that require stricter driver signature enforcement such as the Enterprise and Pro versions of Windows.

This article serves to describe potential risks associated with these drivers, as well as a few mitigation measures to prevent or otherwise identify the loading of known-vulnerable drivers on sensitive systems.

Risks

Many antivirus (AV) or endpoint security solutions (EDR) use a combination of UM and Kernel Mode (KM) monitoring of the system to identify and terminate potentially malicious behavior from processes running on the system. A malicious process may load and interact with these vulnerable drivers to terminate or alter the state of AV/EDR products to hide malicious behavior, perform privileged actions to tamper with the system, or otherwise negatively impact the security of the infected host.

An attacker may leverage such privileged access to perform the following actions, among many other potential behaviors, to compromise the security and integrity of a host:

  • Manual loading of a malicious driver (“rootkit”) bypassing normal driver load monitoring
  • Termination of AV/EDR processes
  • Removal of AV/EDR process and thread notification routines
  • Process tampering
    • Injection of code into an arbitrary process
    • Removal of process protection level
    • etc.
  • Filesystem tampering

Detections and Mitigations

Microsoft provides and maintains a recommended block-list of known-vulnerable drivers:

https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/microsoft-recommended-driver-block-rules

While this list is not exhaustive, and does not protect the environment from newly identified drivers, this list should include many of the commonly-found vulnerable drivers. A further step towards remediation should include driver monitoring capability within an organization to monitor loaded drivers with the same – or similar device names as well as monitoring for the file hash of the driver, as many of these drivers often use the same or similar device name across revisions or operating system versions.

Many AV/EDR products have the capability to list and monitor loaded drivers on the host, and should be configured to alert upon the loading or detection of any of the aforementioned drivers on a protected device.

A baseline driver catalogue of an organization’s “golden image” may also provide valuable data to identify any drivers loaded on a host that are not frequently found on other devices of a similar type within a target organization.

Cybersecurity Detailed Analysis

The Biostar RGB Peripheral Configuration utility, RACING GT Evo v2.1.1905.1700 deploys a driver whose device is created with an insufficient DACL. The driver in question, “BS_RCIO64.sys” contains three vulnerable functions:

  • Arbitrary read of physical memory via MmMapIoSpace
    • IOCTL : 0x226040
    • Description: A low-integrity process may leverage the device to read arbitrary physical memory. This may aid in privilege escalation or code execution.
  • Arbitrary write of physical memory via MmMapIoSpace
    • IOCTL : 0x226044
    • Description: A low-integrity process may leverage the device to write arbitrary physical memory. This may aid in privilege escalation or code execution.
  • Arbitrary code execution
    • IOCTL : 0x226000
    • Description: A low-integrity process may leverage the device to call an arbitrary address, leading to code execution which may result in privilege escalation.

File information:

  • BS_RCIO64.sys
    • SHA256 – D205286BFFDF09BC033C09E95C519C1C267B40C2EE8BAB703C6A2D86741CCD3E
    • File Version (self-reported): 10.0.0.0
    • Product Version (self-reported): 10.0.1901.1100
    • Device Symlink: \.BS_RCIO
  • RACING GT Evo
    • Product Version: 2.1.1905.1700
      • Source: hxxps://www.biostar[.]com[.]tw/event/RAZER/2.1.1905.1700.rar

Demonstrating opening device as a low integrity user by leveraging OSR’s FileTest application:

The following screenshot demonstrates the ioctl dispatch routine invoking the vulnerable routines (noted by EOL comments with the corresponding IOCTL codes):

Arbitrary Physical Read Routine:

Arbitrary Physical Write Routine:

Arbitrary Execution Routine:

The first QWORD in the associated input buffer is cast to a function pointer receiving three arguments, and then calls the user-controlled pointer. The following screenshot shows arbitrary code execution by setting the first QWORD in the input buffer to 0x4141414141411441:

Side-by-side view showing disassembly and decompilation of the target vulnerable function:

Bugcheck output in Windbg Preview:

1: kd> g
KDTARGET: Refreshing KD connection

*** Fatal System Error: 0x0000003b
                       (0x00000000C0000005,0xFFFFF800766311CA,0xFFFF9402CC6C9C80,0x0000000000000000)

Break instruction exception - code 80000003 (first chance)

A fatal system error has occurred.
Debugger entered on first try; Bugcheck callbacks have not been invoked.

A fatal system error has occurred.

For analysis of this file, run !analyze -v
nt!DbgBreakPointWithStatus:
fffff800`7a61dbf0 cc              int     3
1: kd> !analyze -v
*** Unable to resolve unqualified symbol in Bp expression 'BS_RCIO64+0x10CD'.
Connected to Windows 10 22000 x64 target at (Tue Dec  7 13:24:37.265 2021 (UTC - 5:00)), ptr64 TRUE
*** Unable to resolve unqualified symbol in Bp expression 'BS_RCIO64+0x10CD'.
Loading Kernel Symbols
...............................................................
................................................................
................................................................
.
Loading User Symbols
.....
Loading unloaded module list
.........

************* Symbol Loading Error Summary **************
Module name            Error
SharedUserData         No error - symbol load deferred

You can troubleshoot most symbol related issues by turning on symbol loading diagnostics (!sym noisy) and 
repeating the command that caused symbols to be loaded.
You should also verify that your symbol search path (.sympath) is correct.
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

SYSTEM_SERVICE_EXCEPTION (3b)
An exception happened while executing a system service routine.
Arguments:
Arg1: 00000000c0000005, Exception code that caused the BugCheck
Arg2: fffff800766311ca, Address of the instruction which caused the BugCheck
Arg3: ffff9402cc6c9c80, Address of the context record for the exception that caused the BugCheck
Arg4: 0000000000000000, zero.

Debugging Details:
------------------

*** WARNING: Unable to verify checksum for BiostarDriverExploit.exe

KEY_VALUES_STRING: 1

    Key  : Analysis.CPU.mSec
    Value: 4312

    Key  : Analysis.DebugAnalysisManager
    Value: Create

    Key  : Analysis.Elapsed.mSec
    Value: 45866

    Key  : Analysis.Init.CPU.mSec
    Value: 1265

    Key  : Analysis.Init.Elapsed.mSec
    Value: 108666

    Key  : Analysis.Memory.CommitPeak.Mb
    Value: 112

    Key  : WER.OS.Branch
    Value: co_release

    Key  : WER.OS.Timestamp
    Value: 2021-06-04T16:28:00Z

    Key  : WER.OS.Version
    Value: 10.0.22000.1

BUGCHECK_CODE:  3b

BUGCHECK_P1: c0000005

BUGCHECK_P2: fffff800766311ca

BUGCHECK_P3: ffff9402cc6c9c80

BUGCHECK_P4: 0

CONTEXT:  ffff9402cc6c9c80 -- (.cxr 0xffff9402cc6c9c80)
rax=ffff840f53efb340 rbx=0000000000000002 rcx=00000000002260c4
rdx=ffff840f535f8230 rsi=0000000000000000 rdi=0000000000000000
rip=fffff800766311ca rsp=ffff9402cc6ca6a0 rbp=0000000000000000
 r8=0000000000000110  r9=ffff9402cc6ca730 r10=0000fffff8007663
r11=ffff9ffeeae00000 r12=0000000000000000 r13=ffff840f535f8230
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei pl nz na pe nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00050202
BS_RCIO64+0x11ca:
fffff800`766311ca ff10            call    qword ptr [rax] ds:002b:ffff840f`53efb340=4141414141414141
Resetting default scope

PROCESS_NAME:  BiostarDriverExploit.exe

STACK_TEXT:  
ffff9402`cc6ca6a0 fffff800`7a44d501     : ffff840f`548d97c0 ffff840f`535f8230 00000000`00040282 fffff800`00000000 : BS_RCIO64+0x11ca
ffff9402`cc6ca760 fffff800`76632d58     : ffff840f`535f8230 ffff9402`cc6ca871 00000000`00000002 00000000`00000001 : nt!IoStartPacket+0x91
ffff9402`cc6ca7a0 fffff800`7a502f65     : 840f5645`42536f49 f177d485`c891927c 00000000`00000000 00000000`00000110 : BS_RCIO64+0x2d58
ffff9402`cc6ca7d0 fffff800`7a96b532     : 00000000`00000001 ffff840f`535f8230 ffff9402`cc6ca871 fffff800`00000000 : nt!IofCallDriver+0x55
ffff9402`cc6ca810 fffff800`7a96acbf     : ffff840f`535f8230 ffff9402`cc6cab60 00000000`00226005 00000000`00226000 : nt!IopSynchronousServiceTail+0x1d2
ffff9402`cc6ca8c0 fffff800`7a96a6c6     : 00007ff6`be416480 00000000`00000000 00000000`00000000 00000000`00000000 : nt!IopXxxControlFile+0x5df
ffff9402`cc6caa00 fffff800`7a627b78     : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!NtDeviceIoControlFile+0x56
ffff9402`cc6caa70 00007ffb`68783444     : 00007ffb`66053edb 00007ff6`00002282 00007ff6`be3b04f3 00007ff6`be489100 : nt!KiSystemServiceCopyEnd+0x28
000000a9`6ceff3d8 00007ffb`66053edb     : 00007ff6`00002282 00007ff6`be3b04f3 00007ff6`be489100 00007ff6`be3b04f3 : ntdll!NtDeviceIoControlFile+0x14
000000a9`6ceff3e0 00007ffb`66c35f91     : 00000000`00226000 00007ff6`be40cd97 000000a9`6ceff4c8 00007ff6`be3c469d : KERNELBASE!DeviceIoControl+0x6b
000000a9`6ceff450 00007ff6`be38a946     : 00000000`00000000 cccccccc`cccccccc 000000a9`6ceff4e0 00000000`00000000 : KERNEL32!DeviceIoControlImplementation+0x81
000000a9`6ceff4a0 00000000`00000000     : cccccccc`cccccccc 000000a9`6ceff4e0 00000000`00000000 00000000`00000000 : BiostarDriverExploit!ExecuteFunction+0xd6 
[C:UsersMichaelsourcereposBiostarDriverExploitBiostarDriverExploitBiostar.cpp @ 90] 


SYMBOL_NAME:  BS_RCIO64+11ca

MODULE_NAME: BS_RCIO64

IMAGE_NAME:  BS_RCIO64.sys

STACK_COMMAND:  .cxr 0xffff9402cc6c9c80 ; kb

BUCKET_ID_FUNC_OFFSET:  11ca

FAILURE_BUCKET_ID:  0x3B_c0000005_BS_RCIO64!unknown_function

OS_VERSION:  10.0.22000.1

BUILDLAB_STR:  co_release

OSPLATFORM_TYPE:  x64

OSNAME:  Windows 10

FAILURE_ID_HASH:  {ba69bbee-70a0-25f2-73c1-6621f523085b}

Followup:     MachineOwner
---------

1: kd> k
 # Child-SP          RetAddr               Call Site
00 ffff9402`cc6c8b28 fffff800`7a762af2     nt!DbgBreakPointWithStatus
01 ffff9402`cc6c8b30 fffff800`7a762331     nt!KiBugCheckDebugBreak+0x12
02 ffff9402`cc6c8b90 fffff800`7a615697     nt!KeBugCheck2+0xa71
03 ffff9402`cc6c9300 fffff800`7a6281a9     nt!KeBugCheckEx+0x107
04 ffff9402`cc6c9340 fffff800`7a6275bc     nt!KiBugCheckDispatch+0x69
05 ffff9402`cc6c9480 fffff800`7a61ed32     nt!KiSystemServiceHandler+0x7c
06 ffff9402`cc6c94c0 fffff800`7a486347     nt!RtlpExecuteHandlerForException+0x12
07 ffff9402`cc6c94f0 fffff800`7a48a291     nt!RtlDispatchException+0x2d7
08 ffff9402`cc6c9c50 fffff800`7a6282ce     nt!KiDispatchException+0x1b1
09 ffff9402`cc6ca330 fffff800`7a623e8f     nt!KiExceptionDispatch+0x10e
0a ffff9402`cc6ca510 fffff800`766311ca     nt!KiGeneralProtectionFault+0x30f
0b ffff9402`cc6ca6a0 fffff800`7a44d501     BS_RCIO64+0x11ca
0c ffff9402`cc6ca760 fffff800`76632d58     nt!IoStartPacket+0x91
0d ffff9402`cc6ca7a0 fffff800`7a502f65     BS_RCIO64+0x2d58
0e ffff9402`cc6ca7d0 fffff800`7a96b532     nt!IofCallDriver+0x55
0f ffff9402`cc6ca810 fffff800`7a96acbf     nt!IopSynchronousServiceTail+0x1d2
10 ffff9402`cc6ca8c0 fffff800`7a96a6c6     nt!IopXxxControlFile+0x5df
11 ffff9402`cc6caa00 fffff800`7a627b78     nt!NtDeviceIoControlFile+0x56
12 ffff9402`cc6caa70 00007ffb`68783444     nt!KiSystemServiceCopyEnd+0x28
13 000000a9`6ceff3d8 00007ffb`66053edb     ntdll!NtDeviceIoControlFile+0x14
14 000000a9`6ceff3e0 00007ffb`66c35f91     KERNELBASE!DeviceIoControl+0x6b
15 000000a9`6ceff450 00007ff6`be38a946     KERNEL32!DeviceIoControlImplementation+0x81
16 000000a9`6ceff4a0 00000000`00000000     BiostarDriverExploit!ExecuteFunction+0xd6 
[C:UsersMichaelsourcereposBiostarDriverExploitBiostarDriverExploitBiostar.cpp @ 90] 
1: kd> r
rax=0000000000000000 rbx=0000000000000003 rcx=0000000000000003
rdx=000000000000008a rsi=0000000000000000 rdi=0000000000000000
rip=fffff8007a61dbf0 rsp=ffff9402cc6c8b28 rbp=ffff9402cc6c8c90
 r8=0000000000000065  r9=0000000000000000 r10=0000000000000010
r11=0000000000000000 r12=0000000000000003 r13=fffff8007a200000
r14=ffff9402cc6c9c01 r15=fffff8007a762bb0
iopl=0         nv up ei ng nz na po nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00040286
nt!DbgBreakPointWithStatus:
fffff800`7a61dbf0 cc              int     3

BSOD – bugcheck after RIP set to 0x4141414141414141:

🙁