From b1657e88e4f7922cda6795d843b5b7723b27102f Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Mon, 18 Sep 2023 00:13:52 +0200 Subject: Windows Security: make memory protection enabled by default. Add process mitigation (ASLR, Dynamic code, extension points) Memory protection can be disabled using registry value "VeraCryptEnableMemoryProtection" under the key "HKLM\SYSTEM\CurrentControlSet\Services\veracrypt" --- src/Common/Apidrvr.h | 2 + src/Common/Dlgcode.c | 129 ++++++++++++++++++++++++++++++++++++++++++- src/Common/Dlgcode.h | 4 +- src/Common/Tcdefs.h | 4 ++ src/ExpandVolume/WinMain.cpp | 2 +- src/Format/Tcformat.c | 2 +- src/Mount/Mount.c | 2 +- 7 files changed, 139 insertions(+), 6 deletions(-) diff --git a/src/Common/Apidrvr.h b/src/Common/Apidrvr.h index 7a3ea868..463d4fa6 100644 --- a/src/Common/Apidrvr.h +++ b/src/Common/Apidrvr.h @@ -418,6 +418,8 @@ typedef struct #define VC_ERASE_KEYS_SHUTDOWN DRIVER_STR("VeraCryptEraseKeysShutdown") +#define VC_ENABLE_MEMORY_PROTECTION DRIVER_STR("VeraCryptEnableMemoryProtection") + // WARNING: Modifying the following values can introduce incompatibility with previous versions. #define TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD 0x1 #define TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES 0x2 diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index 7282b2ec..8f357208 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -32,6 +32,9 @@ #include #include #endif +#ifdef _WIN32_WINNT >= 0x0602 +#include "processthreadsapi.h"" +#endif #include "Resource.h" @@ -216,6 +219,9 @@ volatile BOOL NeedPeriodicDeviceListUpdate = FALSE; BOOL DisablePeriodicDeviceListUpdate = FALSE; BOOL EnableMemoryProtection = FALSE; +BOOL MemoryProtectionActivated = FALSE; +BOOL ProcessMitigationsActivated = FALSE; + BOOL WaitDialogDisplaying = FALSE; /* Handle to the device driver */ @@ -3238,6 +3244,17 @@ uint32 ReadEncryptionThreadPoolFreeCpuCountLimit () return count; } +BOOL ReadMemoryProtectionConfig () +{ + DWORD config; + + if (!ReadLocalMachineRegistryDword (L"SYSTEM\\CurrentControlSet\\Services\\veracrypt", VC_ENABLE_MEMORY_PROTECTION, &config)) + { + // enabled by default + config = 1; + } + return (config)? TRUE: FALSE; +} BOOL LoadSysEncSettings () { @@ -3431,6 +3448,17 @@ extern "C" { // Force loading dlls from system32 directory only SetDefaultDllDirectoriesFn (LOAD_LIBRARY_SEARCH_SYSTEM32); } + + // activate process mitigations (currently only ASLR, dynamic code and extensions points) + ActivateProcessMitigations(); + +#ifndef SETUP + // call ActivateMemoryProtection if corresponding setting has been enabled (default is enabled) + if (ReadMemoryProtectionConfig()) + { + ActivateMemoryProtection(); + } +#endif return wWinMainCRTStartup(); } } @@ -14035,7 +14063,7 @@ BOOL BufferHasPattern (const unsigned char* buffer, size_t bufferLen, const void * * 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 ActivateMemoryProtection() { BOOL bSuccess = FALSE; @@ -14050,7 +14078,10 @@ BOOL EnableProcessProtection() // Acces mask DWORD dwAccessMask = SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE; // same as protected process - + + if (MemoryProtectionActivated) + return TRUE; + if (IsAdmin ()) { // if we are running elevated, we allow CreateProcessXXX calls alongside PROCESS_DUP_HANDLE and PROCESS_QUERY_INFORMATION in order to be able @@ -14113,6 +14144,9 @@ BOOL EnableProcessProtection() NULL // do not change SACL ))? TRUE: FALSE; + if (bSuccess) + MemoryProtectionActivated = TRUE; + Cleanup: if (pACL != NULL) { @@ -14128,6 +14162,97 @@ Cleanup: return bSuccess; } +// define missing structures Windows 8 +#if (_WIN32_WINNT < 0x0602) + +typedef struct _PROCESS_MITIGATION_ASLR_POLICY { + union { + DWORD Flags; + struct { + DWORD EnableBottomUpRandomization : 1; + DWORD EnableForceRelocateImages : 1; + DWORD EnableHighEntropy : 1; + DWORD DisallowStrippedImages : 1; + DWORD ReservedFlags : 28; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; +} PROCESS_MITIGATION_ASLR_POLICY, *PPROCESS_MITIGATION_ASLR_POLICY; + +typedef struct _PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY { + union { + DWORD Flags; + struct { + DWORD DisableExtensionPoints : 1; + DWORD ReservedFlags : 31; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; +} PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY, *PPROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY; + +typedef struct _PROCESS_MITIGATION_DYNAMIC_CODE_POLICY { + union { + DWORD Flags; + struct { + DWORD ProhibitDynamicCode : 1; + DWORD AllowThreadOptOut : 1; + DWORD AllowRemoteDowngrade : 1; + DWORD AuditProhibitDynamicCode : 1; + DWORD ReservedFlags : 28; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; +} PROCESS_MITIGATION_DYNAMIC_CODE_POLICY, *PPROCESS_MITIGATION_DYNAMIC_CODE_POLICY; + +typedef enum _PROCESS_MITIGATION_POLICY { + ProcessDEPPolicy, + ProcessASLRPolicy, + ProcessDynamicCodePolicy, + ProcessStrictHandleCheckPolicy, + ProcessSystemCallDisablePolicy, + ProcessMitigationOptionsMask, + ProcessExtensionPointDisablePolicy, + ProcessControlFlowGuardPolicy, + ProcessSignaturePolicy, + ProcessFontDisablePolicy, + ProcessImageLoadPolicy, + ProcessSystemCallFilterPolicy, + ProcessPayloadRestrictionPolicy, + ProcessChildProcessPolicy, + ProcessSideChannelIsolationPolicy, + ProcessUserShadowStackPolicy, + MaxProcessMitigationPolicy +} PROCESS_MITIGATION_POLICY, *PPROCESS_MITIGATION_POLICY; + +#endif + +void ActivateProcessMitigations() +{ + if (ProcessMitigationsActivated) + return; + + // we load the function pointer of SetProcessMitigationPolicy dynamically because we are building with Windows 7 SDK that does not have the definition of this function + typedef BOOL (WINAPI *SetProcessMitigationPolicyFunc) (PROCESS_MITIGATION_POLICY MitigationPolicy, PVOID lpBuffer, SIZE_T dwLength); + SetProcessMitigationPolicyFunc SetProcessMitigationPolicy = (SetProcessMitigationPolicyFunc) GetProcAddress (GetModuleHandle (L"kernel32.dll"), "SetProcessMitigationPolicy"); + if (SetProcessMitigationPolicy) + { + PROCESS_MITIGATION_ASLR_POLICY aslrPolicy = { 0 }; + PROCESS_MITIGATION_DYNAMIC_CODE_POLICY dynCodePolicy = { 0 }; + PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY extensionPointDisablePolicy = { 0 }; + + aslrPolicy.EnableBottomUpRandomization = TRUE; + aslrPolicy.EnableForceRelocateImages = TRUE; + aslrPolicy.EnableHighEntropy = TRUE; + + dynCodePolicy.ProhibitDynamicCode = TRUE; + + extensionPointDisablePolicy.DisableExtensionPoints = TRUE; + + SetProcessMitigationPolicy (ProcessASLRPolicy, &aslrPolicy, sizeof (aslrPolicy)); + SetProcessMitigationPolicy (ProcessDynamicCodePolicy, &dynCodePolicy, sizeof (dynCodePolicy)); + SetProcessMitigationPolicy (ProcessExtensionPointDisablePolicy, &extensionPointDisablePolicy, sizeof (extensionPointDisablePolicy)); + } + + ProcessMitigationsActivated = TRUE; +} + // Based on sample code from: // https://blogs.msdn.microsoft.com/aaron_margosis/2009/06/06/faq-how-do-i-start-a-program-as-the-desktop-user-from-an-elevated-app/ // start a program non-elevated as the desktop user from an elevated app diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h index 12957232..245df6c1 100644 --- a/src/Common/Dlgcode.h +++ b/src/Common/Dlgcode.h @@ -349,6 +349,7 @@ BOOL IsTrueCryptInstallerRunning (void); uint32 ReadDriverConfigurationFlags (); uint32 ReadServiceConfigurationFlags (); uint32 ReadEncryptionThreadPoolFreeCpuCountLimit (); +BOOL ReadMemoryProtectionConfig (); BOOL LoadSysEncSettings (); int LoadNonSysInPlaceEncSettings (WipeAlgorithmId *wipeAlgorithm); void RemoveNonSysInPlaceEncNotifications (void); @@ -582,7 +583,8 @@ 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(); +void ActivateProcessMitigations(); +BOOL ActivateMemoryProtection(); void SafeOpenURL (LPCWSTR szUrl); BitLockerEncryptionStatus GetBitLockerEncryptionStatus(WCHAR driveLetter); BOOL IsTestSigningModeEnabled (); diff --git a/src/Common/Tcdefs.h b/src/Common/Tcdefs.h index 1b6189a3..8027f58b 100644 --- a/src/Common/Tcdefs.h +++ b/src/Common/Tcdefs.h @@ -344,8 +344,12 @@ extern BOOLEAN VC_KeAreAllApcsDisabled (VOID); #ifndef TC_LOCAL_WIN32_WINNT_OVERRIDE # undef _WIN32_WINNT +#ifdef _M_ARM64 +# define _WIN32_WINNT 0x0A00 +#else # define _WIN32_WINNT 0x0601 /* Does not apply to the driver */ #endif +#endif #include /* Windows header */ #include /* The common controls */ diff --git a/src/ExpandVolume/WinMain.cpp b/src/ExpandVolume/WinMain.cpp index 0dbc41ba..9a822153 100644 --- a/src/ExpandVolume/WinMain.cpp +++ b/src/ExpandVolume/WinMain.cpp @@ -962,7 +962,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa if (EnableMemoryProtection) { /* Protect this process memory from being accessed by non-admin users */ - EnableProcessProtection (); + ActivateMemoryProtection (); } InitMainDialog (hwndDlg); diff --git a/src/Format/Tcformat.c b/src/Format/Tcformat.c index ce289910..aa28d5ee 100644 --- a/src/Format/Tcformat.c +++ b/src/Format/Tcformat.c @@ -6239,7 +6239,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa if (EnableMemoryProtection) { /* Protect this process memory from being accessed by non-admin users */ - EnableProcessProtection (); + ActivateMemoryProtection (); } if (ComServerMode) diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index f5c22a9e..41672e1a 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -7096,7 +7096,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa if (EnableMemoryProtection) { /* Protect this process memory from being accessed by non-admin users */ - EnableProcessProtection (); + ActivateMemoryProtection (); } if (ComServerMode) -- cgit v1.2.3