From 12d7e0f1d0182b65ac485aa18adf8e5f90d7c0ab Mon Sep 17 00:00:00 2001 From: Samuel Tulach Date: Tue, 14 Apr 2020 18:37:25 +0200 Subject: [PATCH] Tue, Apr 14, 2020 6:37:25 PM --- client/client/client.sln | 31 ++++++ client/client/client/client.cpp | 44 ++++++++ client/client/client/client.vcxproj | 163 ++++++++++++++++++++++++++++ client/client/client/driver.h | 78 +++++++++++++ client/client/client/nt.h | 105 ++++++++++++++++++ client/client/client/utils.h | 44 ++++++++ driver/main.c | 47 ++++---- update.sh | 15 +++ 8 files changed, 499 insertions(+), 28 deletions(-) create mode 100644 client/client/client.sln create mode 100644 client/client/client/client.cpp create mode 100644 client/client/client/client.vcxproj create mode 100644 client/client/client/driver.h create mode 100644 client/client/client/nt.h create mode 100644 client/client/client/utils.h create mode 100644 update.sh diff --git a/client/client/client.sln b/client/client/client.sln new file mode 100644 index 0000000..cdaa340 --- /dev/null +++ b/client/client/client.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29728.190 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client", "client\client.vcxproj", "{73BB66C2-5447-4DA2-8790-E9CE90AF6821}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {73BB66C2-5447-4DA2-8790-E9CE90AF6821}.Debug|x64.ActiveCfg = Debug|x64 + {73BB66C2-5447-4DA2-8790-E9CE90AF6821}.Debug|x64.Build.0 = Debug|x64 + {73BB66C2-5447-4DA2-8790-E9CE90AF6821}.Debug|x86.ActiveCfg = Debug|Win32 + {73BB66C2-5447-4DA2-8790-E9CE90AF6821}.Debug|x86.Build.0 = Debug|Win32 + {73BB66C2-5447-4DA2-8790-E9CE90AF6821}.Release|x64.ActiveCfg = Release|x64 + {73BB66C2-5447-4DA2-8790-E9CE90AF6821}.Release|x64.Build.0 = Release|x64 + {73BB66C2-5447-4DA2-8790-E9CE90AF6821}.Release|x86.ActiveCfg = Release|Win32 + {73BB66C2-5447-4DA2-8790-E9CE90AF6821}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5032EDB2-BA80-44F5-A9C5-E09C36732671} + EndGlobalSection +EndGlobal diff --git a/client/client/client/client.cpp b/client/client/client/client.cpp new file mode 100644 index 0000000..41b0136 --- /dev/null +++ b/client/client/client/client.cpp @@ -0,0 +1,44 @@ +/* + Copyright (c) 2020 Samuel Tulach + Copyright (c) 2019 z175 + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#include +#include "nt.h" +#include "driver.h" +#include "utils.h" + +int main() +{ + std::cout << "[>] Enabling SE_SYSTEM_ENVIRONMENT_PRIVILEGE..." << std::endl; + bool status = Driver::Init(); + if (!status) + { + std::cout << "[-] Failed to enable privilege" << std::endl; + } + + std::cout << "[>] Testing driver..." << std::endl; + status = Driver::Test(); + if (!status) + { + std::cout << "[-] Driver test failed" << std::endl; + } +} diff --git a/client/client/client/client.vcxproj b/client/client/client/client.vcxproj new file mode 100644 index 0000000..b49ec66 --- /dev/null +++ b/client/client/client/client.vcxproj @@ -0,0 +1,163 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + {73BB66C2-5447-4DA2-8790-E9CE90AF6821} + Win32Proj + client + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + false + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + $(SolutionDir)build\bin\ + $(SolutionDir)build\int\ + + + false + + + false + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/client/client/client/driver.h b/client/client/client/driver.h new file mode 100644 index 0000000..e05cc00 --- /dev/null +++ b/client/client/client/driver.h @@ -0,0 +1,78 @@ +#pragma once + +namespace Driver +{ + typedef struct _MemoryCommand + { + int magic; + int operation; + unsigned long long data1; + unsigned long long data2; + int size; + } MemoryCommand; + #define VARIABLE_NAME L"yromeMifE" // EfiMemory + #define COMMAND_MAGIC 0xDEAD + + GUID DummyGuid + = { 0x8BE4DF61, 0x93CA, 0x11D2, { 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C } }; + + #define EFI_VARIABLE_NON_VOLATILE 0x00000001 + #define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 + #define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 + #define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008 + #define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010 + #define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020 + #define EFI_VARIABLE_APPEND_WRITE 0x00000040 + #define ATTRIBUTES (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS) + + NTSTATUS SetSystemEnvironmentPrivilege(BOOLEAN Enable, PBOOLEAN WasEnabled) + { + if (WasEnabled != nullptr) + *WasEnabled = FALSE; + + BOOLEAN SeSystemEnvironmentWasEnabled; + const NTSTATUS Status = nt::RtlAdjustPrivilege(22L, // SE_SYSTEM_ENVIRONMENT_PRIVILEGE + Enable, + FALSE, + &SeSystemEnvironmentWasEnabled); + + if (NT_SUCCESS(Status) && WasEnabled != nullptr) + *WasEnabled = SeSystemEnvironmentWasEnabled; + + return Status; + } + + void SendCommand(MemoryCommand* cmd) + { + UNICODE_STRING VariableName = RTL_CONSTANT_STRING(VARIABLE_NAME); + NTSTATUS status = nt::NtSetSystemEnvironmentValueEx(&VariableName, + &DummyGuid, + &cmd, + sizeof(MemoryCommand), + ATTRIBUTES); + } + + bool Init() + { + BOOLEAN SeSystemEnvironmentWasEnabled; + NTSTATUS status = SetSystemEnvironmentPrivilege(TRUE, &SeSystemEnvironmentWasEnabled); + return NT_SUCCESS(status); + } + + bool Test() + { + uintptr_t read = 0; + uintptr_t value = 123; + + MemoryCommand cmd; + cmd.operation = 0; + cmd.magic = COMMAND_MAGIC; + cmd.data1 = (uintptr_t)&read; + cmd.data2 = (uintptr_t)&value; + cmd.size = sizeof(uintptr_t); + + SendCommand(&cmd); + + return (read == 123); + } +} \ No newline at end of file diff --git a/client/client/client/nt.h b/client/client/client/nt.h new file mode 100644 index 0000000..0a980a4 --- /dev/null +++ b/client/client/client/nt.h @@ -0,0 +1,105 @@ +#pragma once +#include +#include +#pragma comment(lib, "ntdll.lib") + +namespace nt +{ + constexpr auto PAGE_SIZE = 0x1000; + constexpr auto STATUS_INFO_LENGTH_MISMATCH = 0xC0000004; + + constexpr auto SystemModuleInformation = 11; + constexpr auto SystemHandleInformation = 16; + constexpr auto SystemExtendedHandleInformation = 64; + + typedef struct _SYSTEM_HANDLE + { + PVOID Object; + HANDLE UniqueProcessId; + HANDLE HandleValue; + ULONG GrantedAccess; + USHORT CreatorBackTraceIndex; + USHORT ObjectTypeIndex; + ULONG HandleAttributes; + ULONG Reserved; + } SYSTEM_HANDLE, * PSYSTEM_HANDLE; + + typedef struct _SYSTEM_HANDLE_INFORMATION_EX + { + ULONG_PTR HandleCount; + ULONG_PTR Reserved; + SYSTEM_HANDLE Handles[1]; + } SYSTEM_HANDLE_INFORMATION_EX, * PSYSTEM_HANDLE_INFORMATION_EX; + + typedef enum _POOL_TYPE { + NonPagedPool, + NonPagedPoolExecute, + PagedPool, + NonPagedPoolMustSucceed, + DontUseThisType, + NonPagedPoolCacheAligned, + PagedPoolCacheAligned, + NonPagedPoolCacheAlignedMustS, + MaxPoolType, + NonPagedPoolBase, + NonPagedPoolBaseMustSucceed, + NonPagedPoolBaseCacheAligned, + NonPagedPoolBaseCacheAlignedMustS, + NonPagedPoolSession, + PagedPoolSession, + NonPagedPoolMustSucceedSession, + DontUseThisTypeSession, + NonPagedPoolCacheAlignedSession, + PagedPoolCacheAlignedSession, + NonPagedPoolCacheAlignedMustSSession, + NonPagedPoolNx, + NonPagedPoolNxCacheAligned, + NonPagedPoolSessionNx + } POOL_TYPE; + + typedef struct _RTL_PROCESS_MODULE_INFORMATION + { + HANDLE Section; + PVOID MappedBase; + PVOID ImageBase; + ULONG ImageSize; + ULONG Flags; + USHORT LoadOrderIndex; + USHORT InitOrderIndex; + USHORT LoadCount; + USHORT OffsetToFileName; + UCHAR FullPathName[256]; + } RTL_PROCESS_MODULE_INFORMATION, * PRTL_PROCESS_MODULE_INFORMATION; + + typedef struct _RTL_PROCESS_MODULES + { + ULONG NumberOfModules; + RTL_PROCESS_MODULE_INFORMATION Modules[1]; + } RTL_PROCESS_MODULES, * PRTL_PROCESS_MODULES; + + extern "C" + { + NTSYSAPI + NTSTATUS + NTAPI + RtlAdjustPrivilege( + _In_ ULONG Privilege, + _In_ BOOLEAN Enable, + _In_ BOOLEAN Client, + _Out_ PBOOLEAN WasEnabled + ); + + NTSYSCALLAPI + NTSTATUS + NTAPI + NtSetSystemEnvironmentValueEx( + _In_ PUNICODE_STRING VariableName, + _In_ LPGUID VendorGuid, + _In_reads_bytes_opt_(ValueLength) PVOID Value, + _In_ ULONG ValueLength, + _In_ ULONG Attributes + ); + } + + #define RTL_CONSTANT_STRING(s) { sizeof(s) - sizeof((s)[0]), sizeof(s), (PWSTR)s } +} \ No newline at end of file diff --git a/client/client/client/utils.h b/client/client/client/utils.h new file mode 100644 index 0000000..1022e46 --- /dev/null +++ b/client/client/client/utils.h @@ -0,0 +1,44 @@ +#pragma once + +namespace Utils +{ + uint64_t GetKernelModuleAddress(const std::string& module_name) + { + void* buffer = nullptr; + DWORD buffer_size = 0; + + NTSTATUS status = NtQuerySystemInformation(static_cast(nt::SystemModuleInformation), buffer, buffer_size, &buffer_size); + + while (status == nt::STATUS_INFO_LENGTH_MISMATCH) + { + VirtualFree(buffer, 0, MEM_RELEASE); + + buffer = VirtualAlloc(nullptr, buffer_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + status = NtQuerySystemInformation(static_cast(nt::SystemModuleInformation), buffer, buffer_size, &buffer_size); + } + + if (!NT_SUCCESS(status)) + { + VirtualFree(buffer, 0, MEM_RELEASE); + return 0; + } + + const auto modules = static_cast(buffer); + + for (auto i = 0u; i < modules->NumberOfModules; ++i) + { + const std::string current_module_name = std::string(reinterpret_cast(modules->Modules[i].FullPathName) + modules->Modules[i].OffsetToFileName); + + if (!_stricmp(current_module_name.c_str(), module_name.c_str())) + { + const uint64_t result = reinterpret_cast(modules->Modules[i].ImageBase); + + VirtualFree(buffer, 0, MEM_RELEASE); + return result; + } + } + + VirtualFree(buffer, 0, MEM_RELEASE); + return 0; + } +} \ No newline at end of file diff --git a/driver/main.c b/driver/main.c index d76971d..e43bd21 100644 --- a/driver/main.c +++ b/driver/main.c @@ -15,10 +15,6 @@ static const EFI_GUID ProtocolGuid static const EFI_GUID VirtualGuid = { 0x13FA7698, 0xC831, 0x49C7, { 0x87, 0xEA, 0x8F, 0x43, 0xFC, 0xC2, 0x51, 0x96 }}; -// Global variable GUID (gEfiGlobalVariableGuid) -static const EFI_GUID VariableGuid - = { 0x8BE4DF61, 0x93CA, 0x11D2, { 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C }}; - // ExitBootServices GUID (gEfiEventExitBootServicesGuid) static const EFI_GUID ExitGuid = { 0x27ABF055, 0xB1B8, 0x4C26, { 0x80, 0x48, 0x74, 0x8F, 0x37, 0xBA, 0xA2, 0xDF }}; @@ -91,32 +87,25 @@ HookedSetVariable( { // Check of input is not null if (VariableName != NULL && VariableName[0] != CHAR_NULL && VendorGuid != NULL) - { - // Check if GUID is correct - if (CompareGuid(VendorGuid, &VariableGuid)) - { - // Testing (instant bsoder 2000) - RT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); - - // Check if variable name is same as our declared one - // this is used to check if call is really from our program - // running in the OS (client) - if (StrnCmp(VariableName, VARIABLE_NAME, - (sizeof(VARIABLE_NAME) / sizeof(CHAR16)) - 1) == 0) + { + // Check if variable name is same as our declared one + // this is used to check if call is really from our program + // running in the OS (client) + if (StrnCmp(VariableName, VARIABLE_NAME, + (sizeof(VARIABLE_NAME) / sizeof(CHAR16)) - 1) == 0) + { + if (DataSize == 0 && Data == NULL) { - if (DataSize == 0 && Data == NULL) - { - // Skip no data - return EFI_SUCCESS; - } + // Skip no data + return EFI_SUCCESS; + } - // Check if the data size is correct - if (DataSize == sizeof(MemoryCommand)) - { - // We did it! - // Now we can call the magic function - return RunCommand((MemoryCommand*)Data); - } + // Check if the data size is correct + if (DataSize == sizeof(MemoryCommand)) + { + // We did it! + // Now we can call the magic function + return RunCommand((MemoryCommand*)Data); } } } @@ -298,4 +287,6 @@ efi_main(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) Print(L"Made by: Samuel Tulach\n"); Print(L"Thanks to: @Mattiwatti (EfiGuard), Roderick W. Smith (rodsbooks.com)\n\n"); Print(L"Driver has been loaded successfully. You can now boot to the OS.\n"); + + return EFI_SUCCESS; } \ No newline at end of file diff --git a/update.sh b/update.sh new file mode 100644 index 0000000..167c3ba --- /dev/null +++ b/update.sh @@ -0,0 +1,15 @@ +git add *.c +git add *.cpp +git add *.h +git add *.cs +git add *.sh +git add *.sln +git add *.csproj +git add *.vcxproj +git add *.config +git add *.hpp +git add *.md + +git commit -m "$(date)" + +git push