diff --git a/CHANGELOG.md b/CHANGELOG.md index 18138965..aa70e982 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,16 +18,17 @@ This project adheres to [Semantic Versioning](http://semver.org/). - 'OpenProtectedStorage=y' has been replaced with a template - moved all built in access rules to a set of default template’s - moved WinInetCache control to a template OpenWinInetCache, 'CloseWinInetCache=y' is now obsolete -- added hook for CreateAppContainerToken, should also improve compatibility with other apps +- added hook for CreateAppContainerToken, should also improve compatibility with other apps [#1926](https://github.com/sandboxie-plus/Sandboxie/issues/1926) -- note: Template_Edge_Fix is no longer required - replaced a few icons - moved the "Support" settings page the above "Advance Options" page and renamed it to "Support & Updates" - when dragging and dropping a file on to the sandman UI to run it the currently selected box will be pre-selected in the box picker dialog +- improved access rule handling [#2633](https://github.com/sandboxie-plus/Sandboxie/discussions/2633) ### Fixed - added AppContainer support for Compartment type boxes - FIXED SECURITY ISSUE ID-22 NtCreateSectionEx was not filtered by the driver - +- fixed issue starting services without a system token diff --git a/Sandboxie/apps/start/start.cpp b/Sandboxie/apps/start/start.cpp index 120f1443..be97116d 100644 --- a/Sandboxie/apps/start/start.cpp +++ b/Sandboxie/apps/start/start.cpp @@ -1064,6 +1064,14 @@ int Program_Start(void) expanded = MyHeapAlloc(8192 * sizeof(WCHAR)); ExpandEnvironmentStrings(cmdline, expanded, 8192); + // + // When the service proces has a manifest which requires elevated privileges, + // CreateProcess will fail if we did not start with a elevated token. + // To fix this issue we always fake being elevated when starting a service. + // + + SbieDll_SetFakeAdmin(TRUE); + // // If the command contains a space but no ", try to fix it // diff --git a/Sandboxie/core/dll/sbiedll.h b/Sandboxie/core/dll/sbiedll.h index b0aa3b66..caafef86 100644 --- a/Sandboxie/core/dll/sbiedll.h +++ b/Sandboxie/core/dll/sbiedll.h @@ -189,6 +189,8 @@ SBIEDLL_EXPORT BOOL SbieDll_StartBoxedService( SBIEDLL_EXPORT BOOL SbieDll_CheckProcessLocalSystem(HANDLE ProcessHandle); +SBIEDLL_EXPORT VOID SbieDll_SetFakeAdmin(BOOLEAN FakeAdmin); + SBIEDLL_EXPORT HANDLE SbieDll_OpenProcess(ACCESS_MASK DesiredAccess, HANDLE idProcess); SBIEDLL_EXPORT HRESULT SbieDll_ComCreateProxy( diff --git a/Sandboxie/core/dll/secure.c b/Sandboxie/core/dll/secure.c index 64abb8a0..ad45b8bd 100644 --- a/Sandboxie/core/dll/secure.c +++ b/Sandboxie/core/dll/secure.c @@ -226,6 +226,7 @@ PSECURITY_DESCRIPTOR Secure_NormalSD = NULL; PSECURITY_DESCRIPTOR Secure_EveryoneSD = NULL; +BOOLEAN Secure_ShouldFakeRunningAsAdmin = FALSE; BOOLEAN Secure_IsInternetExplorerTabProcess = FALSE; BOOLEAN Secure_Is_IE_NtQueryInformationToken = FALSE; @@ -404,21 +405,17 @@ _FX BOOLEAN Secure_Init(void) && (_wcsicmp(Dll_ImageName, L"msedge.exe") != 0); // never for msedge.exe - if (Secure_FakeAdmin || Dll_OsBuild >= 9600) { + void* NtAccessCheckByType = GetProcAddress(Dll_Ntdll, "NtAccessCheckByType"); + void* NtAccessCheck = GetProcAddress(Dll_Ntdll, "NtAccessCheck"); + void* NtQuerySecurityAttributesToken = GetProcAddress(Dll_Ntdll, "NtQuerySecurityAttributesToken"); + void* NtQueryInformationToken = GetProcAddress(Dll_Ntdll, "NtQueryInformationToken"); + void* NtAccessCheckByTypeResultList = GetProcAddress(Dll_Ntdll, "NtAccessCheckByTypeResultList"); - void* NtAccessCheckByType = GetProcAddress(Dll_Ntdll, "NtAccessCheckByType"); - void* NtAccessCheck = GetProcAddress(Dll_Ntdll, "NtAccessCheck"); - void* NtQuerySecurityAttributesToken = GetProcAddress(Dll_Ntdll, "NtQuerySecurityAttributesToken"); - void* NtQueryInformationToken = GetProcAddress(Dll_Ntdll, "NtQueryInformationToken"); - void* NtAccessCheckByTypeResultList = GetProcAddress(Dll_Ntdll, "NtAccessCheckByTypeResultList"); - - - SBIEDLL_HOOK(Ldr_, NtQuerySecurityAttributesToken); - SBIEDLL_HOOK(Ldr_, NtAccessCheckByType); - SBIEDLL_HOOK(Ldr_, NtAccessCheck); - SBIEDLL_HOOK(Ldr_, NtAccessCheckByTypeResultList); - SBIEDLL_HOOK(Ldr_, NtQueryInformationToken); - } + SBIEDLL_HOOK(Ldr_, NtQuerySecurityAttributesToken); + SBIEDLL_HOOK(Ldr_, NtAccessCheckByType); + SBIEDLL_HOOK(Ldr_, NtAccessCheck); + SBIEDLL_HOOK(Ldr_, NtAccessCheckByTypeResultList); + SBIEDLL_HOOK(Ldr_, NtQueryInformationToken); if (Dll_OsBuild >= 9600) { // Windows 8.1 and later if (DLL_IMAGE_GOOGLE_CHROME == Dll_ImageType) { @@ -444,16 +441,17 @@ _FX BOOLEAN Secure_Init(void) if (RtlQueryElevationFlags) { - BOOLEAN ShouldFakeRunningAsAdmin = Secure_FakeAdmin - || Dll_ImageType == DLL_IMAGE_SANDBOXIE_SBIESVC + SBIEDLL_HOOK(Secure_,RtlQueryElevationFlags); + + // $Workaround$ - 3rd party fix + Secure_ShouldFakeRunningAsAdmin = + Dll_ImageType == DLL_IMAGE_SANDBOXIE_SBIESVC || Dll_ImageType == DLL_IMAGE_SANDBOXIE_RPCSS || Dll_ImageType == DLL_IMAGE_INTERNET_EXPLORER || (_wcsicmp(Dll_ImageName, L"SynTPEnh.exe") == 0) || (_wcsicmp(Dll_ImageName, L"SynTPHelper.exe") == 0); - if (ShouldFakeRunningAsAdmin) { - - SBIEDLL_HOOK(Secure_,RtlQueryElevationFlags); + if (Secure_ShouldFakeRunningAsAdmin) { // // if this is an Internet Explorer tab process then we always @@ -489,20 +487,25 @@ _FX BOOLEAN Secure_Init(void) RtlCheckTokenMembershipEx = GetProcAddress(Dll_Ntdll, "RtlCheckTokenMembershipEx"); - if (RtlCheckTokenMembershipEx) { - - if (Secure_FakeAdmin) { - - SBIEDLL_HOOK(Secure_, RtlCheckTokenMembershipEx); - } - + SBIEDLL_HOOK(Secure_, RtlCheckTokenMembershipEx); } return TRUE; } +//--------------------------------------------------------------------------- +// SbieDll_SetFakeAdmin +//--------------------------------------------------------------------------- + + +_FX VOID SbieDll_SetFakeAdmin(BOOLEAN FakeAdmin) +{ + Secure_FakeAdmin = FakeAdmin; +} + + //--------------------------------------------------------------------------- // SbieDll_OpenProcess //--------------------------------------------------------------------------- @@ -1108,14 +1111,16 @@ NTSTATUS Ldr_NtAccessCheckByType(PSECURITY_DESCRIPTOR SecurityDescriptor, PSID P NTSTATUS rc; HANDLE hTokenReal = NULL; - // todo: is that right? It seems wrong - if (Dll_ImageType == DLL_IMAGE_SANDBOXIE_BITS || - Dll_ImageType == DLL_IMAGE_SANDBOXIE_WUAU || - Dll_ImageType == DLL_IMAGE_WUAUCLT) { - *GrantedAccess = 0xFFFFFFFF; - *AccessStatus = TRUE; - SetLastError(0); - return TRUE; + if (Dll_OsBuild >= 9600) { + // todo: is that right? It seems wrong + if (Dll_ImageType == DLL_IMAGE_SANDBOXIE_BITS || + Dll_ImageType == DLL_IMAGE_SANDBOXIE_WUAU || + Dll_ImageType == DLL_IMAGE_WUAUCLT) { + *GrantedAccess = 0xFFFFFFFF; + *AccessStatus = TRUE; + SetLastError(0); + return TRUE; + } } Ldr_TestToken(ClientToken, &hTokenReal, TRUE); @@ -1332,64 +1337,72 @@ _FX NTSTATUS Secure_RtlQueryElevationFlags(ULONG *Flags) // - InstallerDetectEnabled (0x04) - Detection of installers // - BOOLEAN fake = Secure_FakeAdmin; // FALSE; - - if (Dll_ImageType == DLL_IMAGE_INTERNET_EXPLORER) { - - // - // RtlQueryElevationFlags hook for Internet Explorer: - // - // if the check occurs during CreateProcess, then return the real - // elevation flags, so UAC elevation may occur for the new process. - // - // otherwise, this check is related to Protected Mode, so pretend - // there is no need to elevate - // - - if (! TlsData->proc_create_process) - fake = TRUE; - - } else if (Dll_ImageType == DLL_IMAGE_SANDBOXIE_SBIESVC) { - - // - // RtlQueryElevationFlags hook for SbieSvc UAC elevation process: - // - // even when running as Administrator, in some cases the - // kernel32!CheckElevationEnabled function (called by - // kernel32!kernel32!CreateProcessInternalW) will decide that - // elevation is required for some EXEs, and fail CreateProcess - // with ERROR_ELEVATION_REQUIRED. this will cause SH32_DoRunAs - // to run and invoke ShellExecuteEx/runas, which will result in - // another invocation of CreateProcess, and an infinite loop. - // - // to work around this problem, we need to turn off the bit - // InstallerDetectEnabled (returning zero flags is also ok), as - // this disables the checks in kernel32!CheckElevationEnabled - // - // we do this only for the SbieSvc UAC elevator process, because - // we know that process is already running as Administrator. - // - - if (TlsData->proc_create_process) - fake = TRUE; - - } else { - - // - // RtlQueryElevationFlags hook for anything else: - // - // - SandboxieRpcSs, which is used to run elevated COM objects, - // for example the Internet Explorer Protected Mode ActiveX - // Installation Broker, or elevated Control Panel applets. - // we return zero flags and the COM object runs without elevation. - // - // - a couple of Synaptics programs, which reportedly caused - // UAC prompts, and seem to run well without actually elevating - // - // pretend there is no need to elevate - // + BOOLEAN fake = FALSE; + if (Secure_FakeAdmin) + { fake = TRUE; + } + else if (Secure_ShouldFakeRunningAsAdmin) { + + if (Dll_ImageType == DLL_IMAGE_INTERNET_EXPLORER) { + + // + // RtlQueryElevationFlags hook for Internet Explorer: + // + // if the check occurs during CreateProcess, then return the real + // elevation flags, so UAC elevation may occur for the new process. + // + // otherwise, this check is related to Protected Mode, so pretend + // there is no need to elevate + // + + if (! TlsData->proc_create_process) + fake = TRUE; + + } else if (Dll_ImageType == DLL_IMAGE_SANDBOXIE_SBIESVC) { + + // + // RtlQueryElevationFlags hook for SbieSvc UAC elevation process: + // + // even when running as Administrator, in some cases the + // kernel32!CheckElevationEnabled function (called by + // kernel32!kernel32!CreateProcessInternalW) will decide that + // elevation is required for some EXEs, and fail CreateProcess + // with ERROR_ELEVATION_REQUIRED. this will cause SH32_DoRunAs + // to run and invoke ShellExecuteEx/runas, which will result in + // another invocation of CreateProcess, and an infinite loop. + // + // to work around this problem, we need to turn off the bit + // InstallerDetectEnabled (returning zero flags is also ok), as + // this disables the checks in kernel32!CheckElevationEnabled + // + // we do this only for the SbieSvc UAC elevator process, because + // we know that process is already running as Administrator. + // + + if (TlsData->proc_create_process) + fake = TRUE; + + } else { + + // + // RtlQueryElevationFlags hook for anything else: + // + // - SandboxieRpcSs, which is used to run elevated COM objects, + // for example the Internet Explorer Protected Mode ActiveX + // Installation Broker, or elevated Control Panel applets. + // we return zero flags and the COM object runs without elevation. + // + // - a couple of Synaptics programs, which reportedly caused + // UAC prompts, and seem to run well without actually elevating + // + // pretend there is no need to elevate + // + + fake = TRUE; + } + } //