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)

This commit is contained in:
Mounir IDRASSI 2019-03-02 14:43:39 +01:00
parent 321715202a
commit f7bc58b38f
No known key found for this signature in database
GPG Key ID: 02C30AE90FAE4A6F
2 changed files with 91 additions and 0 deletions

View File

@ -17,6 +17,7 @@
#include <dbghelp.h>
#include <dbt.h>
#include <Setupapi.h>
#include <aclapi.h>
#include <fcntl.h>
#include <io.h>
#include <math.h>
@ -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

View File

@ -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