diff --git a/Sandboxie/apps/com/RpcSs/linger.c b/Sandboxie/apps/com/RpcSs/linger.c index 11683c7c..844a70af 100644 --- a/Sandboxie/apps/com/RpcSs/linger.c +++ b/Sandboxie/apps/com/RpcSs/linger.c @@ -471,8 +471,7 @@ int DoLingerLeader(void) HANDLE ProcessHandle = 0; SbieApi_OpenProcess(&ProcessHandle, pids_i); if (ProcessHandle) { - extern BOOL CheckProcessLocalSystem(HANDLE); // common.h - if (CheckProcessLocalSystem(ProcessHandle)) + if (SbieDll_CheckProcessLocalSystem(ProcessHandle)) is_local_system_sid = TRUE; CloseHandle(ProcessHandle); } diff --git a/Sandboxie/apps/com/common.h b/Sandboxie/apps/com/common.h index cdc617dc..2def6935 100644 --- a/Sandboxie/apps/com/common.h +++ b/Sandboxie/apps/com/common.h @@ -92,44 +92,6 @@ void Check_Windows_7(void) } -//--------------------------------------------------------------------------- -// CheckProcessLocalSystem -//--------------------------------------------------------------------------- - - -_FX BOOL CheckProcessLocalSystem(HANDLE ProcessHandle) -{ - BOOL IsLocalSystem = FALSE; - - HANDLE TokenHandle; - BOOL b = OpenProcessToken(ProcessHandle, TOKEN_QUERY, &TokenHandle); - if (b) { - - union { - TOKEN_USER user; - UCHAR space[64]; - } info; - ULONG len = sizeof(info); - WCHAR *sid; - - b = GetTokenInformation( - TokenHandle, TokenUser, &info, len, &len); - if (b) { - b = ConvertSidToStringSid(info.user.User.Sid, &sid); - if (b) { - if (wcscmp(sid, L"S-1-5-18") == 0) - IsLocalSystem = TRUE; - LocalFree(sid); - } - } - - CloseHandle(TokenHandle); - } - - return IsLocalSystem; -} - - //--------------------------------------------------------------------------- // FindProcessId //--------------------------------------------------------------------------- @@ -180,7 +142,7 @@ _FX ULONG FindProcessId( } if (process) { - if (CheckProcessLocalSystem(process)) + if (SbieDll_CheckProcessLocalSystem(process)) found = TRUE; CloseHandle(process); } diff --git a/Sandboxie/core/dll/file.c b/Sandboxie/core/dll/file.c index 7d8f5f64..cc324837 100644 --- a/Sandboxie/core/dll/file.c +++ b/Sandboxie/core/dll/file.c @@ -2441,9 +2441,10 @@ _FX NTSTATUS File_NtCreateFileImpl( DesiredAccess &= ~ACCESS_SYSTEM_SECURITY; // for TiWorker.exe (W8) // MSIServer without system - if (Dll_ImageType == DLL_IMAGE_MSI_INSTALLER && (DesiredAccess & ACCESS_SYSTEM_SECURITY) != 0 + extern BOOLEAN Scm_MsiServer_Systemless; + if ((DesiredAccess & ACCESS_SYSTEM_SECURITY) != 0 && Dll_ImageType == DLL_IMAGE_MSI_INSTALLER && Scm_MsiServer_Systemless && ObjectAttributes && ObjectAttributes->ObjectName && ObjectAttributes->ObjectName->Buffer - && _wcsicmp(ObjectAttributes->ObjectName->Buffer + (ObjectAttributes->ObjectName->Length / sizeof(WCHAR)) - 3, L".msi") == 0 + && _wcsicmp(ObjectAttributes->ObjectName->Buffer + (ObjectAttributes->ObjectName->Length / sizeof(WCHAR)) - 4, L".msi") == 0 ){ // @@ -3035,7 +3036,7 @@ ReparseLoop: //} // MSIServer without system - if (status == STATUS_ACCESS_DENIED && Dll_ImageType == DLL_IMAGE_MSI_INSTALLER + if (status == STATUS_ACCESS_DENIED && Dll_ImageType == DLL_IMAGE_MSI_INSTALLER && Scm_MsiServer_Systemless && ObjectAttributes->ObjectName->Buffer && ObjectAttributes->ObjectName->Length >= 34 && _wcsicmp(ObjectAttributes->ObjectName->Buffer + (ObjectAttributes->ObjectName->Length / sizeof(WCHAR)) - 11, L"\\Config.Msi") == 0 ) { diff --git a/Sandboxie/core/dll/sbiedll.h b/Sandboxie/core/dll/sbiedll.h index 2a714f4c..846b7f8f 100644 --- a/Sandboxie/core/dll/sbiedll.h +++ b/Sandboxie/core/dll/sbiedll.h @@ -179,6 +179,8 @@ SBIEDLL_EXPORT BOOLEAN SbieDll_IsBoxedService(HANDLE hService); SBIEDLL_EXPORT BOOL SbieDll_StartBoxedService( const WCHAR *ServiceName, BOOLEAN WithAdd); +SBIEDLL_EXPORT BOOL SbieDll_CheckProcessLocalSystem(HANDLE ProcessHandle); + SBIEDLL_EXPORT HRESULT SbieDll_ComCreateProxy( REFIID riid, void *pUnkOuter, void *pChannel, void **ppUnknown); diff --git a/Sandboxie/core/dll/scm.c b/Sandboxie/core/dll/scm.c index 23949780..eb3a0744 100644 --- a/Sandboxie/core/dll/scm.c +++ b/Sandboxie/core/dll/scm.c @@ -1214,3 +1214,25 @@ _FX void Scm_DiscardKeyCache(const WCHAR *ServiceName) Key_DiscardMergeByPath(keyname, TRUE); Dll_Free(keyname); } + + +//--------------------------------------------------------------------------- +// SbieDll_CheckProcessLocalSystem +//--------------------------------------------------------------------------- + + +_FX BOOL SbieDll_CheckProcessLocalSystem(HANDLE ProcessHandle) +{ + BOOL IsLocalSystem = FALSE; + + HANDLE TokenHandle; + if (NtOpenProcessToken(ProcessHandle, TOKEN_QUERY, &TokenHandle)) { + + extern BOOL Secure_IsTokenLocalSystem(HANDLE hToken); + IsLocalSystem = Secure_IsTokenLocalSystem(TokenHandle); + + NtClose(TokenHandle); + } + + return IsLocalSystem; +} diff --git a/Sandboxie/core/dll/scm_msi.c b/Sandboxie/core/dll/scm_msi.c index 4557d922..456da88a 100644 --- a/Sandboxie/core/dll/scm_msi.c +++ b/Sandboxie/core/dll/scm_msi.c @@ -98,6 +98,7 @@ static P_GetTokenInformation __sys_GetTokenInformation = NULL; //--------------------------------------------------------------------------- static volatile BOOLEAN Scm_IsMsiServer = FALSE; +BOOLEAN Scm_MsiServer_Systemless = FALSE; static const WCHAR *_MsiServerInUseEventName = SBIE L"_WindowsInstallerInUse"; @@ -120,47 +121,51 @@ _FX BOOLEAN Scm_SetupMsiHooks() SBIEDLL_HOOK(Scm_, CreateWaitableTimerW); - // - // To run MSIServer without system privileges we need to make it think it is running as system - // we do that by hooking OpenProcessToken and if it opened the current process caching the resulting token handle - // than in GetTokenInformation when asked for TokenUser for this handle we return the system SID - // finally on NtClose we clear the cached token value in case it gets reused later - // - - /* - msi.dll!RunningAsLocalSystem - v2 = GetCurrentProcess(); - if ( OpenProcessToken(v2, 8u, &hObject) ) - { - v3 = IsLocalSystemToken(hObject); - ... - - msi.dll!IsLocalSystemToken - if ( GetUserSID(a1, Sid) ) - return 0; - StringSid = 0i64; - if ( !ConvertSidToStringSidW(Sid, &StringSid) ) - return 0; - v2 = L"S-1-5-18"; - wcscmp... - - - msi.dll!GetUserSID - if ( GetTokenInformation(a1, TokenUser, TokenInformation, 0x58u, ReturnLength) ) - { - if ( CopySid(0x48u, a2, TokenInformation[0]) ) - ... - */ - // MSIServer without system - fake running as system - HMODULE hAdvapi32 = LoadLibrary(L"Advapi32.dll"); + if (!SbieDll_CheckProcessLocalSystem(GetCurrentProcess())) + { + Scm_MsiServer_Systemless = TRUE; - void *OpenProcessToken = (P_OpenProcessToken)GetProcAddress(hAdvapi32, "OpenProcessToken"); - SBIEDLL_HOOK(Scm_, OpenProcessToken); + // + // To run MSIServer without system privileges we need to make it think it is running as system + // we do that by hooking OpenProcessToken and if it opened the current process caching the resulting token handle + // than in GetTokenInformation when asked for TokenUser for this handle we return the system SID + // finally on NtClose we clear the cached token value in case it gets reused later + // - void *GetTokenInformation = (P_GetTokenInformation)GetProcAddress(hAdvapi32, "GetTokenInformation"); - SBIEDLL_HOOK(Scm_, GetTokenInformation); + /* + msi.dll!RunningAsLocalSystem + v2 = GetCurrentProcess(); + if ( OpenProcessToken(v2, 8u, &hObject) ) + { + v3 = IsLocalSystemToken(hObject); + ... + + msi.dll!IsLocalSystemToken + if ( GetUserSID(a1, Sid) ) + return 0; + StringSid = 0i64; + if ( !ConvertSidToStringSidW(Sid, &StringSid) ) + return 0; + v2 = L"S-1-5-18"; + wcscmp... + + msi.dll!GetUserSID + if ( GetTokenInformation(a1, TokenUser, TokenInformation, 0x58u, ReturnLength) ) + { + if ( CopySid(0x48u, a2, TokenInformation[0]) ) + ... + */ + + HMODULE hAdvapi32 = LoadLibrary(L"Advapi32.dll"); + + void* OpenProcessToken = (P_OpenProcessToken)GetProcAddress(hAdvapi32, "OpenProcessToken"); + SBIEDLL_HOOK(Scm_, OpenProcessToken); + + void* GetTokenInformation = (P_GetTokenInformation)GetProcAddress(hAdvapi32, "GetTokenInformation"); + SBIEDLL_HOOK(Scm_, GetTokenInformation); + } return TRUE; } diff --git a/Sandboxie/core/dll/secure.c b/Sandboxie/core/dll/secure.c index c506cf9a..8b2dd7b8 100644 --- a/Sandboxie/core/dll/secure.c +++ b/Sandboxie/core/dll/secure.c @@ -1087,6 +1087,54 @@ _FX BOOLEAN Secure_IsRestrictedToken(BOOLEAN CheckThreadToken) } +//--------------------------------------------------------------------------- +// Secure_IsTokenLocalSystem +//--------------------------------------------------------------------------- + + +_FX BOOL Secure_IsTokenLocalSystem(HANDLE hToken) +{ + NTSTATUS status; + BOOLEAN return_value = FALSE; + + ULONG64 user_space[88]; + PTOKEN_USER user = (PTOKEN_USER)user_space; + ULONG len; + + len = sizeof(user_space); + status = NtQueryInformationToken( + hToken, TokenUser, user, len, &len); + + if (status == STATUS_BUFFER_TOO_SMALL) { + + user = Dll_AllocTemp(len); + status = NtQueryInformationToken( + hToken, TokenUser, user, len, &len); + } + + if (NT_SUCCESS(status)) { + + UNICODE_STRING SidString; + + status = RtlConvertSidToUnicodeString( + &SidString, user->User.Sid, TRUE); + + if (NT_SUCCESS(status)) { + + if (_wcsicmp(SidString.Buffer, L"S-1-5-18") == 0) + return_value = TRUE; + + RtlFreeUnicodeString(&SidString); + } + } + + if (user != (PTOKEN_USER)user_space) + Dll_Free(user); + + return return_value; +} + + //--------------------------------------------------------------------------- // Secure_IsLocalSystemToken //--------------------------------------------------------------------------- @@ -1121,39 +1169,7 @@ _FX BOOLEAN Secure_IsLocalSystemToken(BOOLEAN CheckThreadToken) if (NT_SUCCESS(status)) { - ULONG64 user_space[8]; - PTOKEN_USER user = (PTOKEN_USER)user_space; - ULONG len; - - len = sizeof(user_space); - status = NtQueryInformationToken( - hToken, TokenUser, user, len, &len); - - if (status == STATUS_BUFFER_TOO_SMALL) { - - user = Dll_AllocTemp(len); - status = NtQueryInformationToken( - hToken, TokenUser, user, len, &len); - } - - if (NT_SUCCESS(status)) { - - UNICODE_STRING SidString; - - status = RtlConvertSidToUnicodeString( - &SidString, user->User.Sid, TRUE); - - if (NT_SUCCESS(status)) { - - if (_wcsicmp(SidString.Buffer, L"S-1-5-18") == 0) - return_value = TRUE; - - RtlFreeUnicodeString(&SidString); - } - } - - if (user != (PTOKEN_USER)user_space) - Dll_Free(user); + return_value = Secure_IsTokenLocalSystem(hToken); NtClose(hToken); }