Merge branch 'experimental' into test_x

This commit is contained in:
DavidXanatos 2024-05-20 10:15:57 +02:00 committed by GitHub
commit b577cb6d12
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 1197 additions and 91 deletions

View File

@ -244,8 +244,9 @@ _FX BOOLEAN AdvApi_Init(HMODULE module)
// only hook SetSecurityInfo if this is Chrome. Outlook 2013 uses delayed loading and will cause infinite callbacks
// Starting with Win 10, we only want to hook ntmarta!SetSecurityInfo. Do NOT hook advapi!SetSecurityInfo. Delay loading for advapi will cause infinite recursion.
// Note: the infinite recursion issue has been resolved int 5.43
if (Config_GetSettingsForImageName_bool(L"UseSbieDeskHack", TRUE)
|| (Dll_ImageType == DLL_IMAGE_GOOGLE_CHROME) || (Dll_ImageType == DLL_IMAGE_MOZILLA_FIREFOX) || (Dll_ImageType == DLL_IMAGE_ACROBAT_READER)) {
if ((Config_GetSettingsForImageName_bool(L"UseSbieDeskHack", TRUE)
|| (Dll_ImageType == DLL_IMAGE_GOOGLE_CHROME) || (Dll_ImageType == DLL_IMAGE_MOZILLA_FIREFOX) || (Dll_ImageType == DLL_IMAGE_ACROBAT_READER))
&& !SbieApi_QueryConfBool(NULL, L"OpenWndStation", FALSE)) {
SetSecurityInfo = __sys_SetSecurityInfo;
GetSecurityInfo = __sys_GetSecurityInfo;
SBIEDLL_HOOK(AdvApi_, SetSecurityInfo);
@ -706,8 +707,9 @@ _FX BOOLEAN Ntmarta_Init(HMODULE module)
#define GETPROC2(x,s) __sys_Ntmarta_##x##s = (P_##x) Ldr_GetProcAddrNew(DllName_ntmarta, L#x L#s,#x #s);
GETPROC2(GetSecurityInfo, );
if (Config_GetSettingsForImageName_bool(L"UseSbieDeskHack", TRUE)
|| (Dll_ImageType == DLL_IMAGE_GOOGLE_CHROME) || (Dll_ImageType == DLL_IMAGE_MOZILLA_FIREFOX) || (Dll_ImageType == DLL_IMAGE_ACROBAT_READER)) {
if ((Config_GetSettingsForImageName_bool(L"UseSbieDeskHack", TRUE)
|| (Dll_ImageType == DLL_IMAGE_GOOGLE_CHROME) || (Dll_ImageType == DLL_IMAGE_MOZILLA_FIREFOX) || (Dll_ImageType == DLL_IMAGE_ACROBAT_READER))
&& !SbieApi_QueryConfBool(NULL, L"OpenWndStation", FALSE)) {
GetSecurityInfo = __sys_Ntmarta_GetSecurityInfo;
if (GetSecurityInfo)

View File

@ -1152,11 +1152,17 @@ _FX NTSTATUS File_NtFsControlFile(
handle = File_GetProxyPipe(FileHandle, NULL);
if (! handle) {
status = STATUS_BAD_INITIAL_PC;
if (IoControlCode == FSCTL_SET_REPARSE_POINT) {
status = File_SetReparsePoint(
FileHandle, InputBuffer, InputBufferLength);
SetLastError(LastError);
BOOLEAN BoxReparsTarget = SbieApi_QueryConfBool(NULL, L"BoxReparsTarget", FALSE);
if(BoxReparsTarget) {
status = File_SetReparsePoint(
FileHandle, InputBuffer, InputBufferLength);
SetLastError(LastError);
}
} else if (IoControlCode == FSCTL_PIPE_WAIT) {
@ -1172,8 +1178,7 @@ _FX NTSTATUS File_NtFsControlFile(
else
status = STATUS_ACCESS_DENIED;
} else
status = STATUS_BAD_INITIAL_PC;
}
if (status == STATUS_BAD_INITIAL_PC) {

View File

@ -416,7 +416,18 @@ _FX BOOLEAN Gui_Init(HMODULE module)
GUI_IMPORT___(ClipCursor);
GUI_IMPORT___(GetClipCursor);
GUI_IMPORT___(GetCursorPos);
GUI_IMPORT___(SetCursorPos);
GUI_IMPORT___(SetCursorPos);
GUI_IMPORT___(SetTimer);
HMODULE temp = module;
module = Dll_Kernel32;
GUI_IMPORT___(Sleep);
GUI_IMPORT___(SleepEx);
GUI_IMPORT___(GetTickCount);
GUI_IMPORT___(GetTickCount64);
GUI_IMPORT___(QueryUnbiasedInterruptTime);
GUI_IMPORT___(QueryPerformanceCounter);
module = temp;
GUI_IMPORT___(SetTimer);
GUI_IMPORT___(MsgWaitForMultipleObjects);
@ -925,6 +936,24 @@ _FX BOOLEAN Gui_ConnectToWindowStationAndDesktop(HMODULE User32)
return FALSE;
}
if (SbieApi_QueryConfBool(NULL, L"OpenWndStation", FALSE)) {
static BOOLEAN Connected = FALSE;
if (Connected)
return TRUE;
ULONG req = GUI_GET_WINDOW_STATION;
GUI_GET_WINDOW_STATION_RPL *rpl = Gui_CallProxyEx(
&req, sizeof(ULONG), sizeof(*rpl), FALSE);
if (rpl) {
Dll_Free(rpl);
Connected = TRUE;
}
return TRUE;
}
//
// the first win32k service call (i.e. service number >= 0x1000)
// triggers "thread GUI conversion". the kernel system service

View File

@ -102,8 +102,8 @@ typedef HWND(*P_SetActiveWindow)(HWND hWnd);
typedef UINT_PTR (*P_SetTimer)(
HWND hWnd,
UINT_PTR nIDEvent,
UINT uElapse,
UINT_PTR nIDEvent,
UINT uElapse,
TIMERPROC lpTimerFunc
);
@ -621,7 +621,7 @@ GUI_SYS_VAR_2(SendNotifyMessage)
GUI_SYS_VAR_2(PostMessage)
GUI_SYS_VAR_2(PostThreadMessage)
GUI_SYS_VAR_2(DispatchMessage)
GUI_SYS_VAR(SetTimer)
GUI_SYS_VAR(MapWindowPoints)

View File

@ -234,6 +234,9 @@ _FX BOOLEAN Gui_InitEnum(HMODULE module)
// hook desktop APIs
//
if (SbieApi_QueryConfBool(NULL, L"OpenWndStation", FALSE))
return TRUE;
SBIEDLL_HOOK_GUI(EnumDesktopsW);
SBIEDLL_HOOK_GUI(EnumDesktopsA);
SBIEDLL_HOOK_GUI(OpenDesktopW);

View File

@ -285,7 +285,7 @@ _FX BOOLEAN Gui_InitMisc(HMODULE module)
__sys_GetThreadDpiAwarenessContext = (P_GetThreadDpiAwarenessContext)
Ldr_GetProcAddrNew(DllName_user32, L"GetThreadDpiAwarenessContext","GetThreadDpiAwarenessContext");
HMODULE current = module;
if (SbieApi_QueryConfBool(NULL, L"BlockInterferePower", FALSE)) {
SBIEDLL_HOOK_GUI(ShutdownBlockReasonCreate);
@ -1703,3 +1703,45 @@ _FX void Gui_SwitchToThisWindow(HWND hWnd, BOOL fAlt)
return;
__sys_SwitchToThisWindow(hWnd, fAlt);
}
_FX DWORD Gui_GetTickCount() {
return __sys_GetTickCount() * SbieApi_QueryConfNumber(NULL, L"AddTickSpeed", 1) / SbieApi_QueryConfNumber(NULL,L"LowTickSpeed", 1);
}
_FX ULONGLONG Gui_GetTickCount64() {
return __sys_GetTickCount64() * SbieApi_QueryConfNumber(NULL, L"AddTickSpeed", 1) / SbieApi_QueryConfNumber(NULL, L"LowTickSpeed", 1);
}
_FX BOOL Gui_QueryUnbiasedInterruptTime(
PULONGLONG UnbiasedTime
) {
BOOL rtn = __sys_QueryUnbiasedInterruptTime(UnbiasedTime);
*UnbiasedTime *= SbieApi_QueryConfNumber(NULL, L"AddTickSpeed", 1) / SbieApi_QueryConfNumber(NULL, L"LowTickSpeed", 1);
return rtn;
}
_FX void Gui_Sleep(DWORD dwMiSecond) {
__sys_Sleep(dwMiSecond * SbieApi_QueryConfNumber(NULL, L"AddSleepSpeed", 1) / SbieApi_QueryConfNumber(NULL, L"LowSleepSpeed", 1));
}
_FX DWORD Gui_SleepEx(DWORD dwMiSecond, BOOL bAlert) {
return __sys_SleepEx(dwMiSecond * SbieApi_QueryConfNumber(NULL, L"AddSleepSpeed", 1) / SbieApi_QueryConfNumber(NULL, L"LowSleepSpeed", 1),bAlert);
}
_FX BOOL Gui_QueryPerformanceCounter(
LARGE_INTEGER* lpPerformanceCount
) {
BOOL rtn = __sys_QueryPerformanceCounter(lpPerformanceCount);
lpPerformanceCount->QuadPart = lpPerformanceCount->QuadPart*SbieApi_QueryConfNumber(NULL, L"AddTickSpeed", 1)/ SbieApi_QueryConfNumber(NULL, L"LowTickSpeed", 1);
return rtn;
}
_FX UINT_PTR Gui_SetTimer(
HWND hWnd,
UINT_PTR nIDEvent,
UINT uElapse,
TIMERPROC lpTimerFunc
)
{
return __sys_SetTimer(hWnd, nIDEvent, uElapse * SbieApi_QueryConfNumber(NULL, L"AddTimerSpeed", 1) / SbieApi_QueryConfNumber(NULL, L"LowTimerSpeed", 1), lpTimerFunc);
}

View File

@ -416,8 +416,7 @@ _FX BOOLEAN Secure_Init(void)
// note: when running as the built in administrator we should always act as if we have admin rights
//
Secure_FakeAdmin = Config_GetSettingsForImageName_bool(L"FakeAdminRights", Secure_IsBuiltInAdmin())
&& (_wcsicmp(Dll_ImageName, L"msedge.exe") != 0); // never for msedge.exe
Secure_FakeAdmin = Config_GetSettingsForImageName_bool(L"FakeAdminRights", Secure_IsBuiltInAdmin());
void* NtAccessCheckByType = GetProcAddress(Dll_Ntdll, "NtAccessCheckByType");

View File

@ -184,7 +184,8 @@ _FX BOX *Process_GetForcedStartBox(
if (! ProcessObject)
return NULL;
if ( (_wcsicmp(pSidString, Driver_S_1_5_18) == 0 || // System
if ((! Conf_Get_Boolean(NULL, L"AllowForceSystem", 0, FALSE)) &&
(_wcsicmp(pSidString, Driver_S_1_5_18) == 0 || // System
_wcsicmp(pSidString, Driver_S_1_5_19) == 0 || // Local Service
_wcsicmp(pSidString, Driver_S_1_5_20) == 0) // Network Service
&& (! Process_IsDcomLaunchParent(ParentId)) ){
@ -274,7 +275,8 @@ _FX BOX *Process_GetForcedStartBox(
&boxes, DocArg, force_alert, &alert);
}
if (box && Process_IsImmersiveProcess(
if (box && (! Conf_Get_Boolean(NULL, L"AllowForceImmersive", 0, FALSE)) &&
Process_IsImmersiveProcess(
ProcessObject, ParentId, SessionId)) {
box = NULL;
alert = 1;

View File

@ -34,6 +34,60 @@
#include "dyn_data.h"
//---------------------------------------------------------------------------
// Structures and Types
//---------------------------------------------------------------------------
/*struct _TOKEN// Size=0x2a0
{
struct _TOKEN_SOURCE TokenSource;// Offset=0x0 Size=0x10
struct _LUID TokenId;// Offset=0x10 Size=0x8
struct _LUID AuthenticationId;// Offset=0x18 Size=0x8
struct _LUID ParentTokenId;// Offset=0x20 Size=0x8
union _LARGE_INTEGER ExpirationTime;// Offset=0x28 Size=0x8
struct _ERESOURCE *TokenLock;// Offset=0x30 Size=0x4
struct _LUID ModifiedId;// Offset=0x34 Size=0x8
struct _SEP_TOKEN_PRIVILEGES Privileges;// Offset=0x40 Size=0x18
struct _SEP_AUDIT_POLICY AuditPolicy;// Offset=0x58 Size=0x1f
unsigned long SessionId;// Offset=0x78 Size=0x4
unsigned long UserAndGroupCount;// Offset=0x7c Size=0x4
unsigned long RestrictedSidCount;// Offset=0x80 Size=0x4
unsigned long VariableLength;// Offset=0x84 Size=0x4
unsigned long DynamicCharged;// Offset=0x88 Size=0x4
unsigned long DynamicAvailable;// Offset=0x8c Size=0x4
unsigned long DefaultOwnerIndex;// Offset=0x90 Size=0x4
struct _SID_AND_ATTRIBUTES *UserAndGroups;// Offset=0x94 Size=0x4
struct _SID_AND_ATTRIBUTES *RestrictedSids;// Offset=0x98 Size=0x4
void *PrimaryGroup;// Offset=0x9c Size=0x4
unsigned long *DynamicPart;// Offset=0xa0 Size=0x4
struct _ACL *DefaultDacl;// Offset=0xa4 Size=0x4
enum _TOKEN_TYPE TokenType;// Offset=0xa8 Size=0x4
enum _SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;// Offset=0xac Size=0x4
unsigned long TokenFlags;// Offset=0xb0 Size=0x4
unsigned int TokenInUse;// Offset=0xb4 Size=0x1
unsigned long IntegrityLevelIndex;// Offset=0xb8 Size=0x4
unsigned long MandatoryPolicy;// Offset=0xbc Size=0x4
struct _SEP_LOGON_SESSION_REFERENCES *LogonSession;// Offset=0xc0 Size=0x4
struct _LUID OriginatingLogonSession;// Offset=0xc4 Size=0x8
struct _SID_AND_ATTRIBUTES_HASH SidHash;// Offset=0xcc Size=0x88
struct _SID_AND_ATTRIBUTES_HASH RestrictedSidHash;// Offset=0x154 Size=0x88
struct _AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION *pSecurityAttributes;// Offset=0x1dc Size=0x4
void *Package;// Offset=0x1e0 Size=0x4
struct _SID_AND_ATTRIBUTES *Capabilities;// Offset=0x1e4 Size=0x4
unsigned long CapabilityCount;// Offset=0x1e8 Size=0x4
struct _SID_AND_ATTRIBUTES_HASH CapabilitiesHash;// Offset=0x1ec Size=0x88
struct _SEP_LOWBOX_NUMBER_ENTRY *LowboxNumberEntry;// Offset=0x274 Size=0x4
struct _SEP_LOWBOX_HANDLES_ENTRY *LowboxHandlesEntry;// Offset=0x278 Size=0x4
struct _AUTHZBASEP_CLAIM_ATTRIBUTES_COLLECTION *pClaimAttributes;// Offset=0x27c Size=0x4
void *TrustLevelSid;// Offset=0x280 Size=0x4
struct _TOKEN *TrustLinkedToken;// Offset=0x284 Size=0x4
void *IntegrityLevelSidValue;// Offset=0x288 Size=0x4
struct _SEP_SID_VALUES_BLOCK *TokenSidValues;// Offset=0x28c Size=0x4
struct _SEP_LUID_TO_INDEX_MAP_ENTRY *IndexEntry;// Offset=0x290 Size=0x4
struct _SEP_TOKEN_DIAG_TRACK_ENTRY *DiagnosticInfo;// Offset=0x294 Size=0x4
unsigned long VariablePart;// Offset=0x298 Size=0x4
};*/
//---------------------------------------------------------------------------
// Functions
//---------------------------------------------------------------------------
@ -78,7 +132,7 @@ static BOOLEAN Token_AssignPrimary(
static void *Token_DuplicateToken(void *TokenObject, PROCESS *proc);
static void *Token_CreateNew(void *TokenObject, PROCESS *proc);
static void *Token_CreateToken(void *TokenObject, BOOLEAN Replicate, PROCESS *proc);
//---------------------------------------------------------------------------
@ -880,13 +934,22 @@ _FX void *Token_Restrict(
// Create a heavily restricted primary token
//
if (Conf_Get_Boolean(proc->box->name, L"CreateToken", 0, FALSE)) {
if (Conf_Get_Boolean(proc->box->name, L"CreateToken", 0, FALSE)) {
//
// Create a new token from scratch, experimental
// Create a custom restricted token from scratch
//
FixedTokenObject = Token_CreateNew(TokenObject, proc);
return Token_CreateToken(TokenObject, FALSE, proc);
}
if (Conf_Get_Boolean(proc->box->name, L"ReplicateToken", 0, FALSE)) {
//
// Create a new replicated token from scratch
//
FixedTokenObject = Token_CreateToken(TokenObject, TRUE, proc);
}
else {
@ -1369,6 +1432,7 @@ _FX void *Token_RestrictHelper3(
BOOLEAN AnonymousLogonSidAlreadyInGroups = FALSE;
BOOLEAN KeepUserGroup = Conf_Get_Boolean(proc->box->name, L"KeepUserGroup", 0, FALSE);
BOOLEAN OpenWndStation = Conf_Get_Boolean(proc->box->name, L"OpenWndStation", 0, FALSE);
n = 0;
@ -1377,6 +1441,9 @@ _FX void *Token_RestrictHelper3(
if (Groups->Groups[i].Attributes & SE_GROUP_INTEGRITY)
continue;
if (OpenWndStation && (Groups->Groups[i].Attributes & SE_GROUP_LOGON_ID))
continue;
if (RtlEqualSid(Groups->Groups[i].Sid, UserSid)) {
if (KeepUserGroup)
continue;
@ -1704,6 +1771,7 @@ _FX BOOLEAN Token_ReplacePrimary(PROCESS *proc)
#ifdef _WIN64
// OpenToken BEGIN
if (!Conf_Get_Boolean(proc->box->name, L"CreateToken", 0, FALSE)
&& !Conf_Get_Boolean(proc->box->name, L"ReplicateToken", 0, FALSE)
&& !Conf_Get_Boolean(proc->box->name, L"UnrestrictedToken", 0, FALSE)
&& Conf_Get_Boolean(proc->box->name, L"AnonymousLogon", 0, TRUE))
// OpenToken END
@ -2116,11 +2184,11 @@ _FX NTSTATUS SbieCreateToken(PHANDLE TokenHandle, ACCESS_MASK DesiredAccess, POB
//---------------------------------------------------------------------------
// Token_CreateNew
// Token_CreateToken
//---------------------------------------------------------------------------
_FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
_FX void* Token_CreateToken(void* TokenObject, BOOLEAN Replicate, PROCESS* proc)
{
HANDLE TokenHandle = NULL;
NTSTATUS status = STATUS_UNSUCCESSFUL;
@ -2141,15 +2209,19 @@ _FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
PTOKEN_SOURCE LocalSource = NULL;
PTOKEN_DEFAULT_DACL NewDefaultDacl = NULL;
PTOKEN_OWNER NewOwner = NULL;
ULONG DefaultDacl_Length = 0;
PACL NewDacl = NULL;
OBJECT_ATTRIBUTES ObjectAttributes;
TOKEN_TYPE TokenType = TokenPrimary;
LUID AuthenticationId = ANONYMOUS_LOGON_LUID;
LARGE_INTEGER ExpirationTime;
OBJECT_ATTRIBUTES ObjectAttributes;
SECURITY_QUALITY_OF_SERVICE SecurityQos;
//
// Get the information from the original token
// Gether informations from the original token
//
if ( !NT_SUCCESS(SeQueryInformationToken(TokenObject, TokenStatistics, &LocalStatistics))
@ -2170,6 +2242,58 @@ _FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
MandatoryPolicy = (PTOKEN_MANDATORY_POLICY)ExAllocatePoolWithTag(PagedPool, sizeof(TOKEN_MANDATORY_POLICY), tzuk);
if (MandatoryPolicy) MandatoryPolicy->Policy = TOKEN_MANDATORY_POLICY_NO_WRITE_UP;
//
// Create a new token from scratch
//
InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_CASE_INSENSITIVE, NULL, NULL);
SecurityQos.Length = sizeof(SecurityQos);
SecurityQos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
SecurityQos.EffectiveOnly = FALSE;
ObjectAttributes.SecurityQualityOfService = &SecurityQos;
if (Replicate)
{
SecurityQos.ImpersonationLevel = LocalStatistics->ImpersonationLevel;
TokenType = LocalStatistics->TokenType;
AuthenticationId = LocalStatistics->AuthenticationId;
ExpirationTime = LocalStatistics->ExpirationTime;
}
else
{
SecurityQos.ImpersonationLevel = SecurityAnonymous;
ExpirationTime.QuadPart = 0x7FFFFFFFFFFFFFFF;
if (!Conf_Get_Boolean(proc->box->name, L"UnstrippedToken", 0, FALSE))
{
BOOLEAN KeepUserGroup = Conf_Get_Boolean(proc->box->name, L"KeepUserGroup", 0, FALSE);
BOOLEAN OpenWndStation = Conf_Get_Boolean(proc->box->name, L"OpenWndStation", 0, FALSE);
for (ULONG i = 0; i < LocalGroups->GroupCount; i++) {
if (LocalGroups->Groups[i].Attributes & SE_GROUP_INTEGRITY) {
if (!Conf_Get_Boolean(proc->box->name, L"KeepTokenIntegrity", 0, FALSE))
*RtlSubAuthoritySid(LocalGroups->Groups[i].Sid, 0) = SECURITY_MANDATORY_UNTRUSTED_RID;
continue;
}
if (OpenWndStation && (LocalGroups->Groups[i].Attributes & SE_GROUP_LOGON_ID))
continue;
if (RtlEqualSid(LocalGroups->Groups[i].Sid, LocalUser->User.Sid)) {
if (KeepUserGroup)
continue;
}
LocalGroups->Groups[i].Attributes = 0;
}
}
}
//
// Change the SID
//
@ -2181,37 +2305,28 @@ _FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
if (proc->SandboxieLogonSid)
{
//
// free old user and create a new one with the new SID
//
ULONG Attributes = LocalUser->User.Attributes;
ExFreePool((PVOID)LocalUser);
LocalUser = ExAllocatePoolWithTag(PagedPool, sizeof(TOKEN_USER) + RtlLengthSid(proc->SandboxieLogonSid), tzuk);
LocalUser->User.Attributes = Attributes;
LocalUser->User.Sid = ((UCHAR*)LocalUser) + sizeof(TOKEN_USER);
memcpy(LocalUser->User.Sid, proc->SandboxieLogonSid, RtlLengthSid(proc->SandboxieLogonSid));
}
//
// Create a new token from scratch
//
SecurityQos.Length = sizeof(SecurityQos);
SecurityQos.ImpersonationLevel = LocalStatistics->ImpersonationLevel;
SecurityQos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
SecurityQos.EffectiveOnly = FALSE;
ObjectAttributes.SecurityQualityOfService = &SecurityQos;
InitializeObjectAttributes(
&ObjectAttributes,
NULL,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
//LUID AuthenticationId = ANONYMOUS_LOGON_LUID;
status = SbieCreateToken(
&TokenHandle,
TOKEN_ALL_ACCESS,
&ObjectAttributes,
LocalStatistics->TokenType,
&LocalStatistics->AuthenticationId,
&LocalStatistics->ExpirationTime,
TokenType,
&AuthenticationId,
&ExpirationTime,
LocalUser,
LocalGroups,
LocalPrivileges,
@ -2248,18 +2363,19 @@ _FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
NewDefaultDacl->DefaultDacl = NewDacl = (PACL)((ULONG_PTR)NewDefaultDacl + sizeof(TOKEN_DEFAULT_DACL));
NewDefaultDacl->DefaultDacl->AclSize += 128;
NewOwner = (PTOKEN_OWNER)ExAllocatePoolWithTag(PagedPool, sizeof(TOKEN_OWNER), tzuk);
NewOwner->Owner = LocalUser->User.Sid;
ExFreePool((PVOID)LocalOwner);
LocalOwner = (PTOKEN_OWNER)ExAllocatePoolWithTag(PagedPool, sizeof(TOKEN_OWNER), tzuk);
LocalOwner->Owner = LocalUser->User.Sid;
RtlAddAccessAllowedAce(NewDacl, ACL_REVISION2, GENERIC_ALL, NewOwner->Owner);
RtlAddAccessAllowedAce(NewDacl, ACL_REVISION2, GENERIC_ALL, LocalOwner->Owner);
status = SbieCreateToken(
&TokenHandle,
TOKEN_ALL_ACCESS,
&ObjectAttributes,
LocalStatistics->TokenType,
&LocalStatistics->AuthenticationId,
&LocalStatistics->ExpirationTime,
TokenType,
&AuthenticationId,
&ExpirationTime,
LocalUser,
LocalGroups,
LocalPrivileges,
@ -2269,7 +2385,7 @@ _FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
0, //DeviceGroups,
MandatoryPolicy,
NewOwner,
LocalOwner,
LocalPrimaryGroup,
NewDefaultDacl,
LocalSource
@ -2294,17 +2410,16 @@ _FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
ULONG virtualizationAllowed = 1;
status = ZwSetInformationToken(TokenHandle, TokenVirtualizationAllowed, &virtualizationAllowed, sizeof(ULONG));
if (Conf_Get_Boolean(proc->box->name, L"CopyTokenAttributes", 0, FALSE))
{
HANDLE OldTokenHandle;
status = ObOpenObjectByPointer(
TokenObject, OBJ_KERNEL_HANDLE, NULL, TOKEN_ALL_ACCESS,
*SeTokenObjectType, KernelMode, &OldTokenHandle);
if (NT_SUCCESS(status))
{
void* ptr = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, tzuk);
/*HANDLE OldTokenHandle;
status = ObOpenObjectByPointer(
TokenObject, OBJ_KERNEL_HANDLE, NULL, TOKEN_ALL_ACCESS,
*SeTokenObjectType, KernelMode, &OldTokenHandle);
if (NT_SUCCESS(status)) {
__try {
void* ptr = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, tzuk);
if (ptr) {
ULONG len = 0;
status = ZwQueryInformationToken(OldTokenHandle, TokenSecurityAttributes, ptr, PAGE_SIZE, &len);
if (NT_SUCCESS(status)) {
@ -2320,18 +2435,12 @@ _FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
status = ZwSetInformationToken(TokenHandle, TokenSecurityAttributes, data, len);
}
ExFreePool(ptr);
ZwClose(OldTokenHandle);
}
if (ptr)ExFreePool(ptr);
} __except (EXCEPTION_EXECUTE_HANDLER) {
status = GetExceptionCode() + 0x01000000;
}
DbgPrint("TokenSecurityAttributes %08x", status);
ZwClose(OldTokenHandle);
}*/
}
finish:
if (LocalStatistics) ExFreePool((PVOID)LocalStatistics);
@ -2350,8 +2459,6 @@ finish:
if (LocalSource) ExFreePool((PVOID)LocalSource);
if (NewDefaultDacl) ExFreePool((PVOID)NewDefaultDacl);
if (NewOwner) ExFreePool((PVOID)NewOwner);
//
// get the actual token object from the handle
@ -2366,5 +2473,4 @@ finish:
NtClose(TokenHandle);
}
return NewTokenObject;
}
}

View File

@ -0,0 +1,665 @@
/*
* Copyright 2023 David Xanatos, xanasoft.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// Box Manager
//---------------------------------------------------------------------------
#include "stdafx.h"
#include "BoxManager.h"
#include "ProcessServer.h"
#include "MountManager.h"
//---------------------------------------------------------------------------
// Defines
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Structures and Types
//---------------------------------------------------------------------------
/*typedef struct _LINGER_LEADER {
HANDLE orig_pid;
HANDLE curr_pid;
WCHAR image[1];
} LINGER_LEADER;*/
struct BOX_INSTANCE
{
std::wstring BoxName;
//bool HiveMounted = false;
std::map<ULONG, BOXED_PROCESS*> ProcessMap;
/*ULONG linger_count;
ULONG leader_count;
LINGER_LEADER **lingers;
LINGER_LEADER **leaders;
BOOLEAN any_leaders;*/
};
struct BOXED_PROCESS
{
ULONG ProcessId;
ULONG SessionId;
BOX_INSTANCE* pBox;
HANDLE hProcHandle;
HANDLE hProcWait;
};
//---------------------------------------------------------------------------
// Variables
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Constructor
//---------------------------------------------------------------------------
BoxManager::BoxManager()
{
InitializeCriticalSection(&m_CritSec);
LoadProcesses();
}
//---------------------------------------------------------------------------
// BoxManager
//---------------------------------------------------------------------------
BoxManager *BoxManager::GetInstance()
{
static BoxManager *_instance = NULL;
if (! _instance)
_instance = new BoxManager();
return _instance;
}
void BoxManager::LoadProcesses()
{
ULONG pid_count = 0;
SbieApi_EnumProcessEx(NULL, TRUE, -1, NULL, &pid_count); // query count
pid_count += 128;
std::vector<ULONG> pids;
pids.resize(pid_count + 1); // allocate oen more for the -1 marker
SbieApi_EnumProcessEx(NULL, TRUE, -1, &pids.front(), &pid_count); // query pids
ULONG reg_root_len = 256;
WCHAR* reg_root_path = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, reg_root_len + 16);;
for (ULONG i = 0; i <= pid_count; ++i) {
WCHAR boxname[34];
ULONG session_id;
SbieApi_QueryProcess((HANDLE)(ULONG_PTR)pids[i], boxname, NULL, NULL, &session_id);
ULONG reg_len = reg_root_len;
if (!NT_SUCCESS(SbieApi_QueryProcessPath((HANDLE)(ULONG_PTR)pids[i], NULL, NULL, NULL, NULL, &reg_len, NULL)))
continue;
if (reg_len > reg_root_len) {
reg_root_len = reg_len;
reg_root_path = (WCHAR*)HeapReAlloc(GetProcessHeap(), 0, reg_root_path, reg_root_len + 16);
if (!reg_root_path)
continue;
}
if (!NT_SUCCESS(SbieApi_QueryProcessPath((HANDLE)(ULONG_PTR)pids[i], NULL, reg_root_path, NULL, NULL, &reg_len, NULL)))
continue;
ProcessCreated(pids[i], boxname, reg_root_path, session_id);
}
if (reg_root_path)
HeapFree(GetProcessHeap(), 0, reg_root_path);
}
//---------------------------------------------------------------------------
// WaitOrTimerCallback
//---------------------------------------------------------------------------
VOID CALLBACK WaitOrTimerCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
{
BOXED_PROCESS* pProcess = (BOXED_PROCESS*)lpParameter;
UnregisterWait(pProcess->hProcWait);
CloseHandle(pProcess->hProcHandle);
EnterCriticalSection(&BoxManager::GetInstance()->m_CritSec);
if (pProcess->pBox) {
pProcess->pBox->ProcessMap.erase(pProcess->ProcessId);
#if 0
BoxManager::GetInstance()->CheckLinger(pProcess->pBox, pProcess->SessionId);
#endif
}
LeaveCriticalSection(&BoxManager::GetInstance()->m_CritSec);
delete pProcess;
}
extern "C" {
WINBASEAPI DWORD WINAPI GetFinalPathNameByHandleW(
_In_ HANDLE hFile,
_Out_writes_(cchFilePath) LPWSTR lpszFilePath,
_In_ DWORD cchFilePath,
_In_ DWORD dwFlags
);
}
//std::wstring BoxManager__GetFinalPath(const WCHAR* file_root_path)
//{
// std::wstring FileRootPath;
// FileRootPath.resize(8192);
//
// //
// // get the final file path by opening it and retrieving it from the handle
// //
//
// UNICODE_STRING objname;
// RtlInitUnicodeString(&objname, file_root_path);
//
// OBJECT_ATTRIBUTES objattrs;
// InitializeObjectAttributes(
// &objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
//
// HANDLE handle = INVALID_HANDLE_VALUE;
// IO_STATUS_BLOCK IoStatusBlock;
// NTSTATUS status = NtCreateFile(
// &handle, GENERIC_READ, &objattrs, &IoStatusBlock, NULL, 0,
// FILE_SHARE_VALID_FLAGS, FILE_OPEN, 0, NULL, 0);
//
// DWORD dwRet = GetFinalPathNameByHandleW(handle, (WCHAR*)FileRootPath.c_str(), FileRootPath.size(), VOLUME_NAME_NT);
// //if (dwRet == 0 || dwRet > FileRootPath.size()) // failed || buffer to small
// // goto finish;
//
// if (handle != INVALID_HANDLE_VALUE)
// NtClose(handle);
//
// return FileRootPath;
//}
bool BoxManager::ProcessCreated(ULONG ProcessId, const WCHAR* boxname, const WCHAR* reg_root, ULONG session_id)
{
bool IsFirst = false;
EnterCriticalSection(&m_CritSec);
BOX_INSTANCE* &pBox = m_BoxMap[reg_root];
if (!pBox) {
pBox = new BOX_INSTANCE;
pBox->BoxName = std::wstring(boxname);
SbieApi_LogEx(session_id, 2201, L"BoxCreated %S", pBox->BoxName.c_str());
#if 0
InitLinger(pBox);
#endif
IsFirst = true;
}
BOXED_PROCESS* &pProcess = pBox->ProcessMap[ProcessId];
if (!pProcess) {
pProcess = new BOXED_PROCESS;
pProcess->ProcessId = ProcessId;
pProcess->SessionId = session_id;
pProcess->pBox = pBox;
pProcess->hProcHandle = OpenProcess(SYNCHRONIZE, FALSE, ProcessId);
if (pProcess->hProcHandle) {
RegisterWaitForSingleObject(&pProcess->hProcWait, pProcess->hProcHandle, WaitOrTimerCallback, (void*)pProcess, INFINITE, WT_EXECUTEONLYONCE);
}
}
LeaveCriticalSection(&m_CritSec);
return IsFirst;
}
void BoxManager::BoxOpened(const WCHAR* reg_root, ULONG session_id)
{
EnterCriticalSection(&m_CritSec);
auto I = m_BoxMap.find(reg_root);
if (I != m_BoxMap.end()){
SbieApi_LogEx(session_id, 2201, L"BoxOpened %S", I->second->BoxName.c_str());
//I->second->HiveMounted = TRUE;
}
LeaveCriticalSection(&m_CritSec);
}
void BoxManager::BoxClosed(const WCHAR* reg_root, ULONG session_id)
{
EnterCriticalSection(&m_CritSec);
auto I = m_BoxMap.find(reg_root);
if (I != m_BoxMap.end()){
SbieApi_LogEx(session_id, 2201, L"BoxClosed %S", I->second->BoxName.c_str());
// the process map should be empty
for (auto J = I->second->ProcessMap.begin(); J != I->second->ProcessMap.end(); ++J)
{
// keep the process around untill the event fires, but set the box pointer to NULL
J->second->pBox = NULL;
//delete pProcess;
}
#if 0
for (ULONG i = 0; i < pBox->linger_count; ++i) {
HeapFree(GetProcessHeap(), 0, pBox->lingers[i]);
}
HeapFree(GetProcessHeap(), 0, pBox->lingers);
for (ULONG i = 0; i < pBox->leader_count; ++i) {
HeapFree(GetProcessHeap(), 0, pBox->leaders[i]);
}
HeapFree(GetProcessHeap(), 0, pBox->leaders);
#endif
delete I->second;
m_BoxMap.erase(I);
}
LeaveCriticalSection(&m_CritSec);
}
#if 0
#include "../../common/my_version.h"
#define MAX_LINGER_LEADER_COUNT 512
static const WCHAR *_SandboxieRpcSs = SANDBOXIE L"RpcSs.exe";
static const WCHAR *_msiexec = L"msiexec.exe";
static const WCHAR *_SandboxieDcomLaunch = SANDBOXIE L"DcomLaunch.exe";
static const WCHAR *_SandboxieCrypto = SANDBOXIE L"Crypto.exe";
static const WCHAR *_SandboxieBITS = SANDBOXIE L"BITS.exe";
static const WCHAR *_SandboxieWUAU = SANDBOXIE L"WUAU.exe";
static const WCHAR *_wuauclt = L"wuauclt.exe";
static const WCHAR *_TrustedInstaller = L"TrustedInstaller.exe";
static const WCHAR *_tiworker = L"tiworker.exe";
_FX void Add_LL_Entry(
LINGER_LEADER **lingers, ULONG *inout_count, const WCHAR *image)
{
ULONG linger_count = *inout_count;
if (linger_count >= MAX_LINGER_LEADER_COUNT)
return;
lingers[linger_count] = (LINGER_LEADER*)HeapAlloc(
GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS,
sizeof(LINGER_LEADER) + (wcslen(image) + 4) * sizeof(WCHAR));
lingers[linger_count]->orig_pid = NULL;
lingers[linger_count]->curr_pid = NULL;
wcscpy(lingers[linger_count]->image, image);
++linger_count;
*inout_count = linger_count;
}
void BoxManager::InitLinger(BOX_INSTANCE* pBox)
{
// ULONG i, j;
// HANDLE pids_i;
WCHAR image[128];
// PROCESS_DATA *myData;
LONG rc;
if (1) {
//
// read and store LingerProcess configuration
//
pBox->lingers = (LINGER_LEADER**)HeapAlloc(
GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS,
sizeof(LINGER_LEADER *) * MAX_LINGER_LEADER_COUNT);
while (1)
{
rc = SbieApi_QueryConfAsIs(
NULL, L"LingerProcess", pBox->linger_count,
image, sizeof(WCHAR) * 120);
if (rc != 0)
break;
Add_LL_Entry(pBox->lingers, &pBox->linger_count, image);
}
//
// see which of the LingerProcess programs were already active
// before SandboxieRpcSs started. they will not be considered
// LingerProcess programs and will not be terminated
//
/*ULONG pid_count = 0;
SbieApi_EnumProcessEx(NULL, FALSE, -1, NULL, &pid_count); // query count
pid_count += 128;
ULONG* pids = (ULONG*)HeapAlloc(
GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(ULONG) * pid_count);
SbieApi_EnumProcessEx(NULL, FALSE, -1, pids, &pid_count); // query pids
AddPid(pids, pid_count);
for (i = 0; i <= pid_count; ++i) {
pids_i = (HANDLE) (ULONG_PTR) pids[i];
SbieApi_QueryProcess(pids_i, NULL, image, NULL, NULL);
for (j = 0; j < linger_count; ++j) {
if (_wcsicmp(lingers[j]->image, image) == 0) {
lingers[j]->orig_pid = pids_i;
break;
}
}
}
HeapFree(GetProcessHeap(), 0, pids);*/
//
// add standard lingers. note that we don't check if any of
// the following processes was already active before we started
//
Add_LL_Entry(pBox->lingers, &pBox->linger_count, _SandboxieDcomLaunch);
Add_LL_Entry(pBox->lingers, &pBox->linger_count, _SandboxieCrypto);
Add_LL_Entry(pBox->lingers, &pBox->linger_count, _SandboxieBITS);
Add_LL_Entry(pBox->lingers, &pBox->linger_count, _SandboxieWUAU);
Add_LL_Entry(pBox->lingers, &pBox->linger_count, _wuauclt);
Add_LL_Entry(pBox->lingers, &pBox->linger_count, _TrustedInstaller);
Add_LL_Entry(pBox->lingers, &pBox->linger_count, _tiworker);
//
// read and store LeaderProcess configuration
//
pBox->leaders = (LINGER_LEADER**)HeapAlloc(
GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS,
sizeof(LINGER_LEADER *) * MAX_LINGER_LEADER_COUNT);
while (1) {
rc = SbieApi_QueryConfAsIs(
NULL, L"LeaderProcess", pBox->leader_count,
image, sizeof(WCHAR) * 120);
if (rc != 0)
break;
Add_LL_Entry(pBox->leaders, &pBox->leader_count, image);
}
}
}
void BoxManager::CheckLinger(BOX_INSTANCE* pBox, ULONG SessionId)
{
// ULONG i, j;
ULONG j;
WCHAR image[128];
ULONG cur_session_id;
{
BOOLEAN any_leaders_local = FALSE;
BOOLEAN terminate_and_stop = TRUE;
//
// wait for the process exit event (my_event)
//
// WaitForSingleObject(heventRpcSs, INFINITE);
// EnterCriticalSection(&ProcessCritSec);
// SbieApi_EnumProcessEx(NULL, FALSE, -1, NULL, &process_count); // query count
// process_count += 128;
// ULONG* pids = HeapAlloc(
// GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(ULONG) * (process_count + 1)); // allocate oen more for the -1 marker
// SbieApi_EnumProcessEx(NULL, FALSE, -1, pids, &process_count); // query pids
// pids[process_count] = -1; // set the end marker
//
// query running processes
//
map_iter_t iter = map_iter();
while (map_next(&pBox->process_map, &iter)) {
BOXED_PROCESS* pProcess = (BOXED_PROCESS*)iter.value;
// for (i = 0; i < process_count; ++i) {
//
// if the process in question was started by Start.exe,
// then we do not treat the process as lingering. except:
//
// - if the process is running as LocalSystem, it was probably
// spawned using Start.exe by SbieSvc::ServiceServer.
//
// - if the process is SandboxieCrypto, which can get invoked
// by Start.exe in some cases
//
BOOLEAN excluded_from_linger = FALSE;
BOOLEAN is_local_system_sid = FALSE;
//pids_i = (HANDLE)(ULONG_PTR)pids[i];
HANDLE pids_i = (HANDLE)(ULONG_PTR)pProcess->ProcessId;
image[0] = L'\0';
if (0 == SbieApi_QueryProcess(pids_i, NULL, image, NULL, &cur_session_id)
&& _wcsicmp(image, _SandboxieCrypto) != 0) {
//
// check if this is a local system process
//
HANDLE ProcessHandle = SbieDll_OpenProcess(PROCESS_QUERY_INFORMATION, pids_i);
if (ProcessHandle) {
if (SbieDll_CheckProcessLocalSystem(ProcessHandle))
is_local_system_sid = TRUE;
CloseHandle(ProcessHandle);
}
if (!is_local_system_sid) {
//
// then check if the process was started explicitly
// (via forced mechanism or as a child of start.exe)
// and then don't terminate it as a linger
//
// (note that sevice processes running as local system
// are also children of start.exe, but in that case,
// is_local_system_sid would be TRUE and we would not
// reach this point.)
//
// fix-me: services are no longer started by default as system
//
ULONG64 ProcessFlags =
SbieApi_QueryProcessInfo(pids_i, 0);
if (ProcessFlags & (SBIE_FLAG_FORCED_PROCESS |
SBIE_FLAG_PARENT_WAS_START_EXE |
SBIE_FLAG_PROCESS_IS_START_EXE )) {
excluded_from_linger = TRUE;
}
}
}
//
// ignore processes fron other sessions
//
if (cur_session_id != SessionId)
continue;
//
// ignore rpcss process
//
if (_wcsicmp(image, _SandboxieRpcSs) == 0)
continue;
//
// find a leader process
//
for (j = 0; j < pBox->leader_count; ++j) {
if (_wcsicmp(pBox->leaders[j]->image, image) == 0) {
any_leaders_local = TRUE;
break;
}
}
//
// for each process we find, check if the image appears on
// the linger list. if so, we update the last known pid
// for that linger. but if that process was already active
// before RpcSs started, then don't kill any lingers
//
// alternatively, if the process is not on the linger list,
// then we won't be killing any of the LingerProcess yet
//
for (j = 0; j < pBox->linger_count; ++j) {
if (_wcsicmp(pBox->lingers[j]->image, image) == 0) {
pBox->lingers[j]->curr_pid = pids_i;
if (excluded_from_linger)
pBox->lingers[j]->orig_pid = pids_i;
if (pids_i == pBox->lingers[j]->orig_pid)
terminate_and_stop = FALSE;
break;
}
}
if (j == pBox->linger_count) {
//
// we found an active process that is not a linger process,
// so reset the flag to kill lingers
//
terminate_and_stop = FALSE;
}
}
//
// if leader processes ended (i.e. after being active for some time)
// then kill all processes
//
if (pBox->any_leaders && (! any_leaders_local)) {
terminate_and_stop = TRUE;
goto do_kill_all;
} else
pBox->any_leaders = any_leaders_local;
//
// don't terminate if a lingering process has an open window
//
/*if (terminate_and_stop) {
//
// if a process in the PID list has a window LingerEnumWindowsProc will return FALSE
// what causes the enumeration to abort and EnumWindows to return FALSE as well
//
BOOL ret = EnumWindows(LingerEnumWindowsProc, (LPARAM)pids);
if (ret == FALSE)
terminate_and_stop = FALSE;
}*/
//
// don't terminate if a lingering process has just started recently
//
/*if (terminate_and_stop) {
for (i = 0; i < process_count; ++i) {
HANDLE hProcess = NULL;
ULONG64 ProcessFlags = SbieApi_QueryProcessInfo(
pids_i, 0);
if (! (ProcessFlags & SBIE_FLAG_IMAGE_FROM_SBIE_DIR)) {
hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION, FALSE, (DWORD)(UINT_PTR)pids_i);
}
if (hProcess) {
FILETIME time, time1, time2, time3;
BOOL ok = GetProcessTimes(
hProcess, &time, &time1, &time2, &time3);
if (ok) {
LARGE_INTEGER liProcess, liCurrent;
__int64 diff;
liProcess.LowPart = time.dwLowDateTime;
liProcess.HighPart = time.dwHighDateTime;
GetSystemTimeAsFileTime(&time);
liCurrent.LowPart = time.dwLowDateTime;
liCurrent.HighPart = time.dwHighDateTime;
diff = liCurrent.QuadPart - liProcess.QuadPart;
if (diff < SECONDS(5))
terminate_and_stop = FALSE;
}
CloseHandle(hProcess);
}
if (! terminate_and_stop)
break;
}
}*/
//
// kill all programs and quit
//
// LeaveCriticalSection(&ProcessCritSec);
do_kill_all:
// HeapFree(GetProcessHeap(), 0, pids);
if (terminate_and_stop) {
BOOLEAN TerminateJob = FALSE; // todo
extern ProcessServer* pProcessServer;
pProcessServer->KillAllHelper(pBox->boxname, SessionId, TerminateJob);
}
}
}
#endif

View File

@ -0,0 +1,73 @@
/*
* Copyright 2023 David Xanatos, xanasoft.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// Box Manager
//---------------------------------------------------------------------------
#ifndef _MY_BOXMANAGER_H
#define _MY_BOXMANAGER_H
#include <windows.h>
#include "common/win32_ntddk.h"
#include "common/list.h"
#include "common/map.h"
#include "common/pool.h"
#include <string>
#include <map>
#include <list>
#include <vector>
#include <memory>
struct BOX_INSTANCE;
struct BOXED_PROCESS;
class BoxManager
{
public:
static BoxManager *GetInstance();
void LoadProcesses();
bool ProcessCreated(ULONG ProcessId, const WCHAR* boxname, const WCHAR* reg_root, ULONG session_id);
void BoxOpened(const WCHAR* reg_root, ULONG session_id);
void BoxClosed(const WCHAR* reg_root, ULONG session_id);
protected:
friend VOID CALLBACK WaitOrTimerCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired);
BoxManager();
#if 0
void InitLinger(BOX_INSTANCE* pBox);
void CheckLinger(BOX_INSTANCE* pBox, ULONG SessionId);
#endif
CRITICAL_SECTION m_CritSec;
std::map<std::wstring, BOX_INSTANCE*> m_BoxMap;
};
#endif /* _MY_BOXMANAGER_H */

View File

@ -35,6 +35,7 @@
#include "core/dll/sbiedll.h"
#include "core/drv/api_defs.h"
#include "sbieiniserver.h"
#include "BoxManager.h"
#include "MountManager.h"
//---------------------------------------------------------------------------
@ -613,6 +614,12 @@ void DriverAssist::HiveMounted(void *_msg)
goto finish;
}
//
// notify the manager that this boxed has started
//
//BoxManager::GetInstance()->BoxOpened(reg_root_path, msg->session_id);
//
// lock box root if present
//
@ -755,6 +762,12 @@ void DriverAssist::UnmountHive(void *_msg)
if (rc == 0) {
//
// notify the manager that this boxed is finished
//
//BoxManager::GetInstance()->BoxClosed(root_path, msg->session_id);
//
// unmount box container if present
//

View File

@ -1278,6 +1278,7 @@ bool GuiServer::GetWindowStationAndDesktopName(WCHAR *out_name)
// create window station object, then switch to this window station
// to create the desktop object within this window station.
// WRITE_OWNER access is needed in order to adjust integrity levels
// administrative privileges are needed to be able to specify a name
//
wsprintf(_CombinedName, L"%s_WinSta_%d", SANDBOXIE, GetTickCount());
@ -1449,6 +1450,83 @@ finish:
}
//---------------------------------------------------------------------------
// SetSecurity
//---------------------------------------------------------------------------
BOOL SetSecurity(HANDLE handle, PSID pSid, ULONG Access)
{
long lRc;
static SECURITY_INFORMATION struSecInfo;
PSECURITY_DESCRIPTOR pSecDesc;
PACL pOldDACL = NULL, pNewDACL = NULL;
EXPLICIT_ACCESS ea;
lRc = GetSecurityInfo(handle, SE_WINDOW_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, &pSecDesc);
if(lRc != ERROR_SUCCESS)
return FALSE;
//PSID pSid;
//ConvertStringSidToSid(L"S-1-5-100-714847823-3683748338-340537075-1126068394-222809190", &pSid);
LPWSTR pStr;
ConvertSidToStringSid(pSid, &pStr);
memset(&ea, 0, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = Access;
ea.grfAccessMode = GRANT_ACCESS;
ea.grfInheritance = NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea.Trustee.ptstrName = (LPTSTR) pSid;
lRc = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
if (ERROR_SUCCESS != lRc)
goto Cleanup;
//
// on Windows Vista, we set the process token to the untrusted integrity
// level, so we need to adjust the window station and desktop objects to
// allow access from processes at untrusted integrity. the first step
// is to create an untrusted integrity sacl. note that the utility
// ConvertStringSecurityDescriptorToSecurityDescriptor only supports
// low integrity, so we have to manually adjust the sacl to untrusted
//
PACL sacl = NULL;
PSECURITY_DESCRIPTOR label_sd = NULL;
if (ConvertStringSecurityDescriptorToSecurityDescriptor(
L"S:(ML;;NW;;;LW)", SDDL_REVISION_1, &label_sd, NULL)) {
ULONG_PTR sacl_offset =
(ULONG_PTR)((SECURITY_DESCRIPTOR_RELATIVE *)label_sd)->Sacl;
ULONG *sacl_ulongs = (ULONG *)((ULONG_PTR)label_sd + sacl_offset);
sacl_ulongs[6] = 0; // change "low" to "untrusted" level
BOOL sacl_present, sacl_defaulted;
if (! GetSecurityDescriptorSacl(
label_sd, &sacl_present, &sacl, &sacl_defaulted))
sacl = NULL;
}
lRc = SetSecurityInfo(handle, SE_WINDOW_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDACL, sacl);
Cleanup:
if(pSecDesc != NULL)
LocalFree((HLOCAL) pSecDesc);
if(pNewDACL != NULL)
LocalFree((HLOCAL) pNewDACL);
if(lRc != ERROR_SUCCESS)
return FALSE;
return TRUE;
}
//---------------------------------------------------------------------------
// GetWindowStationSlave
//---------------------------------------------------------------------------
@ -1458,9 +1536,14 @@ ULONG GuiServer::GetWindowStationSlave(SlaveArgs *args)
{
ULONG errlvl;
ULONG status;
WCHAR boxname[BOXNAME_COUNT];
ULONG session_id;
HWINSTA local_winsta = NULL;
HDESK local_desktop = NULL;
BOOLEAN close_desktop = FALSE;
HANDLE hProcess = NULL;
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | TOKEN_QUERY
| PROCESS_DUP_HANDLE, FALSE, args->pid);
if (! hProcess) {
status = GetLastError();
@ -1469,7 +1552,7 @@ ULONG GuiServer::GetWindowStationSlave(SlaveArgs *args)
}
status = SbieApi_QueryProcess((HANDLE)(ULONG_PTR)args->pid,
NULL, NULL, NULL, &session_id);
boxname, NULL, NULL, &session_id);
if (status != 0 || session_id != m_SessionId) {
if (status == 0)
@ -1497,8 +1580,25 @@ ULONG GuiServer::GetWindowStationSlave(SlaveArgs *args)
//
//
HWINSTA local_winsta = GetProcessWindowStation();
HDESK local_desktop = GetThreadDesktop(GetCurrentThreadId());
local_winsta = GetProcessWindowStation();
WCHAR deskname[128] = { 0 };
/*SbieApi_QueryConfAsIs(boxname, L"SandboxDesktopName", 0, deskname, sizeof(deskname));
if(*value)
local_desktop = OpenDesktop(value, 0, FALSE, GENERIC_ALL);
else*/
if (SbieApi_QueryConfBool(boxname, L"UseSandboxDesktop", FALSE)) {
wsprintf(deskname, L"%s_%s_Session_%d_Desktop", //_%08X",
SANDBOXIE, boxname, m_SessionId); //GetTickCount());
local_desktop = OpenDesktop(deskname, 0, FALSE, GENERIC_ALL);
if (!local_desktop)
local_desktop = CreateDesktop(deskname, NULL, NULL, 0, GENERIC_ALL, NULL);
close_desktop = TRUE;
} else
local_desktop = GetThreadDesktop(GetCurrentThreadId());
if ((! local_winsta) || (! local_desktop)) {
status = -1;
@ -1523,6 +1623,35 @@ ULONG GuiServer::GetWindowStationSlave(SlaveArgs *args)
_WinStaAccess |= WINSTA_WRITEATTRIBUTES;
}
if (SbieApi_QueryConfBool(boxname, L"OpenWndStation", FALSE))
{
UCHAR UserBuff[64];
PTOKEN_USER pUser = (PTOKEN_USER)UserBuff;
HANDLE hToken = NULL;
if (OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken))
{
DWORD len;
GetTokenInformation(hToken, TokenUser, pUser, sizeof(UserBuff), &len);
CloseHandle(hToken);
}
SetSecurity(local_winsta, pUser->User.Sid, _WinStaAccess | WINSTA_CREATEDESKTOP);
ULONG _DeskAccess = DESKTOP_READOBJECTS
| DESKTOP_CREATEWINDOW
| DESKTOP_CREATEMENU
// | DESKTOP_HOOKCONTROL
// | DESKTOP_JOURNALRECORD
// | DESKTOP_JOURNALPLAYBACK
| DESKTOP_ENUMERATE
| DESKTOP_WRITEOBJECTS
// | DESKTOP_SWITCHDESKTOP
;
SetSecurity(local_desktop, pUser->User.Sid, _DeskAccess);
}
if (! DuplicateHandle(NtCurrentProcess(), local_winsta,
hProcess, (HANDLE *)&rpl->hwinsta,
_WinStaAccess, FALSE, 0)) {
@ -1538,7 +1667,7 @@ ULONG GuiServer::GetWindowStationSlave(SlaveArgs *args)
errlvl = 0x76;
goto finish;
}
#ifdef _WIN64
//
@ -1568,6 +1697,9 @@ finish:
if (hProcess)
CloseHandle(hProcess);
if (close_desktop && local_desktop)
CloseDesktop(local_desktop);
if (errlvl) {
ReportError2336(-1, errlvl, status);
return STATUS_ACCESS_DENIED;

View File

@ -411,6 +411,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64EC'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="BoxManager.cpp" />
<ClCompile Include="comserver.cpp" />
<ClCompile Include="comserver2.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
@ -584,6 +585,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64EC'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="BoxManager.h" />
<ClInclude Include="comserver.h" />
<ClInclude Include="comwire.h" />
<ClInclude Include="DriverAssist.h" />

View File

@ -78,6 +78,7 @@
<ClCompile Include="DriverAssistSid.cpp">
<Filter>DriverAssist</Filter>
</ClCompile>
<ClCompile Include="BoxManager.cpp" />
<ClCompile Include="MountManager.cpp">
<Filter>MountManager</Filter>
</ClCompile>
@ -153,6 +154,7 @@
<ClInclude Include="..\..\common\ini.h">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="BoxManager.h" />
<ClInclude Include="MountManagerWire.h">
<Filter>MountManager</Filter>
</ClInclude>

View File

@ -22,6 +22,7 @@
#include "stdafx.h"
#include <Sddl.h>
#include "BoxManager.h"
#include "MountManager.h"
#include "DriverAssist.h"
#include "PipeServer.h"

View File

@ -46,7 +46,8 @@ typedef enum _COMMAND {
CMD_SCANDLL,
CMD_SCANDLL_SILENT,
CMD_MESSAGE,
CMD_FIXDACLS
CMD_FIXDACLS,
CMD_SWITCHDESK
} COMMAND;
typedef enum _OPTIONS {
@ -231,6 +232,10 @@ BOOL Parse_Command_Line(
*Command = CMD_FIXDACLS;
num_args_needed = 0;
} else if (_wcsicmp(args[1], L"switchdesk") == 0) {
*Command = CMD_SWITCHDESK;
num_args_needed = 1;
} else {
*Command = CMD_ERROR;
MessageBox(NULL, L"Invalid command", L"KmdUtil",
@ -741,6 +746,26 @@ BOOL Kmd_Show_Message(
return TRUE;
}
//---------------------------------------------------------------------------
// Kmd_Show_Message
//---------------------------------------------------------------------------
BOOL Kmd_SwitchDesk(
const wchar_t *name)
{
HDESK hDesktop = OpenDesktop(name, 0, FALSE, GENERIC_ALL);
if (hDesktop == NULL) {
//DWORD err = GetLastError();
return FALSE;
}
BOOL ok = SwitchDesktop(hDesktop);
CloseDesktop(hDesktop);
return ok;
}
//---------------------------------------------------------------------------
// WinMain
//---------------------------------------------------------------------------
@ -778,6 +803,11 @@ int __stdcall WinMain(
goto finish;
}
if (Command == CMD_SWITCHDESK) {
ok = Kmd_SwitchDesk(Driver_Name);
goto finish;
}
ScMgr = OpenSCManager(
NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CREATE_SERVICE);