This commit is contained in:
DavidXanatos 2021-07-13 21:59:14 +02:00
parent 01697e9ff2
commit 966c0fba24
7 changed files with 121 additions and 114 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

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

View File

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

View File

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

View File

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

View File

@ -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);
}