From f7bc58b38f3e61a387849ff1d840bb32a7b9b4c4 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sat, 2 Mar 2019 14:43:39 +0100 Subject: Windows: mitigate some memory attacks by making VeraCrypt applications memory inaccessible by non-admin users. Implementation borrowed from KeePassXC source code (https://github.com/keepassxreboot/keepassxc/blob/release/2.4.0/src/core/Bootstrap.cpp#L150) --- src/Common/Dlgcode.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/Common/Dlgcode.h | 1 + 2 files changed, 91 insertions(+) diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index 6d6ed69b..2bc0f7e9 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -2892,6 +2893,9 @@ void InitApp (HINSTANCE hInstance, wchar_t *lpszCommandLine) char langId[6]; InitCommonControlsPtr InitCommonControlsFn = NULL; wchar_t modPath[MAX_PATH]; + + /* Protect this process memory from being accessed by non-admin users */ + EnableProcessProtection (); GetModuleFileNameW (NULL, modPath, ARRAYSIZE (modPath)); @@ -13908,6 +13912,92 @@ BOOL BufferHasPattern (const unsigned char* buffer, size_t bufferLen, const void return bRet; } +/* Implementation borrowed from KeePassXC source code (https://github.com/keepassxreboot/keepassxc/blob/release/2.4.0/src/core/Bootstrap.cpp#L150) + * + * Reduce current user acess rights for this process to the minimum in order to forbid non-admin users from reading the process memory. + */ +BOOL EnableProcessProtection() +{ + BOOL bSuccess = FALSE; + + // Process token and user + HANDLE hToken = NULL; + PTOKEN_USER pTokenUser = NULL; + DWORD cbBufferSize = 0; + + // Access control list + PACL pACL = NULL; + DWORD cbACL = 0; + + // Open the access token associated with the calling process + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) { + goto Cleanup; + } + + // Retrieve the token information in a TOKEN_USER structure + GetTokenInformation(hToken, TokenUser, NULL, 0, &cbBufferSize); + + pTokenUser = (PTOKEN_USER) HeapAlloc(GetProcessHeap(), 0, cbBufferSize; + if (pTokenUser == NULL) { + goto Cleanup; + } + + if (!GetTokenInformation(hToken, TokenUser, pTokenUser, cbBufferSize, &cbBufferSize)) { + goto Cleanup; + } + + if (!IsValidSid(pTokenUser->User.Sid)) { + goto Cleanup; + } + + // Calculate the amount of memory that must be allocated for the DACL + cbACL = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pTokenUser->User.Sid); + + // Create and initialize an ACL + pACL = (PACL) HeapAlloc(GetProcessHeap(), 0, cbACL); + if (pACL == NULL) { + goto Cleanup; + } + + if (!InitializeAcl(pACL, cbACL, ACL_REVISION)) { + goto Cleanup; + } + + // Add allowed access control entries, everything else is denied + if (!AddAccessAllowedAce( + pACL, + ACL_REVISION, + SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE, // same as protected process + pTokenUser->User.Sid // pointer to the trustee's SID + )) { + goto Cleanup; + } + + // Set discretionary access control list + bSuccess = (ERROR_SUCCESS == SetSecurityInfo(GetCurrentProcess(), // object handle + SE_KERNEL_OBJECT, // type of object + DACL_SECURITY_INFORMATION, // change only the objects DACL + NULL, + NULL, // do not change owner or group + pACL, // DACL specified + NULL // do not change SACL + ))? TRUE: FALSE; + +Cleanup: + + if (pACL != NULL) { + HeapFree(GetProcessHeap(), 0, pACL); + } + if (pTokenUser != NULL) { + HeapFree(GetProcessHeap(), 0, pTokenUser); + } + if (hToken != NULL) { + CloseHandle(hToken); + } + + return bSuccess; +} + #if !defined(SETUP) && defined(_WIN64) #define RtlGenRandom SystemFunction036 diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h index 8a75f264..eccb8e87 100644 --- a/src/Common/Dlgcode.h +++ b/src/Common/Dlgcode.h @@ -537,6 +537,7 @@ BOOL VerifyModuleSignature (const wchar_t* path); void GetInstallationPath (HWND hwndDlg, wchar_t* szInstallPath, DWORD cchSize, BOOL* pbInstallPathDetermined); BOOL GetSetupconfigLocation (wchar_t* path, DWORD cchSize); BOOL BufferHasPattern (const unsigned char* buffer, size_t bufferLen, const void* pattern, size_t patternLen); +BOOL EnableProcessProtection(); #ifdef _WIN64 void GetAppRandomSeed (unsigned char* pbRandSeed, size_t cbRandSeed); #endif -- cgit v1.2.3