From 520dbc77e257ca024f77062d6b7164485030a867 Mon Sep 17 00:00:00 2001 From: DavidXanatos Date: Fri, 15 Apr 2022 18:32:50 +0200 Subject: [PATCH] 1.0.19 --- CHANGELOG.md | 12 ++ Sandboxie/core/dll/ipc.c | 263 +++++++++++++++++++++++++++--- Sandboxie/core/drv/ipc.c | 18 +- Sandboxie/core/drv/obj.c | 6 +- Sandboxie/core/drv/syscall_open.c | 16 +- 5 files changed, 284 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2c2ddba..30bbda9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,18 @@ This project adheres to [Semantic Versioning](http://semver.org/). + + +## [1.0.19 / 5.55.19] - 2022-04-?? + +### Fixed +- fixed crash issue in the sandman ui +- fixed issue some installers when EnableObjectFiltering is enabled [#1795](https://github.com/sandboxie-plus/Sandboxie/issues/1795) +- fixed to allow NtCreateSymbolicLinkObject to be used safely in the sandbox + + + + ## [1.0.18 / 5.55.18] - 2022-04-13 ### Added diff --git a/Sandboxie/core/dll/ipc.c b/Sandboxie/core/dll/ipc.c index 3ad26511..68e29f66 100644 --- a/Sandboxie/core/dll/ipc.c +++ b/Sandboxie/core/dll/ipc.c @@ -245,11 +245,16 @@ static NTSTATUS Ipc_NtOpenSection( //--------------------------------------------------------------------------- static NTSTATUS Ipc_NtCreateSymbolicLinkObject ( - PHANDLE pHandle, + PHANDLE SymbolicLinkHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PUNICODE_STRING DestinationName); +static NTSTATUS Ipc_NtOpenSymbolicLinkObject( + PHANDLE SymbolicLinkHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes); + //--------------------------------------------------------------------------- @@ -279,6 +284,7 @@ static P_NtCreateSection __sys_NtCreateSection = NULL; static P_NtOpenSection __sys_NtOpenSection = NULL; static P_NtCreateSymbolicLinkObject __sys_NtCreateSymbolicLinkObject= NULL; +static P_NtOpenSymbolicLinkObject __sys_NtOpenSymbolicLinkObject = NULL; static P_NtImpersonateAnonymousToken __sys_NtImpersonateAnonymousToken @@ -383,6 +389,12 @@ _FX BOOLEAN Ipc_Init(void) SBIEDLL_HOOK(Ipc_,NtOpenSection); SBIEDLL_HOOK(Ipc_,NtCreateSymbolicLinkObject); + SBIEDLL_HOOK(Ipc_,NtOpenSymbolicLinkObject); + + //NtOpenDirectoryObject + //NtQueryDirectoryObject + //NtCreateDirectoryObject + //NtCreateDirectoryObjectEx // OriginalToken BEGIN if (!Dll_CompartmentMode && !SbieApi_QueryConfBool(NULL, L"OriginalToken", FALSE)) @@ -3108,6 +3120,235 @@ OpenTruePath: } +//--------------------------------------------------------------------------- +// Ipc_NtCreateSymbolicLinkObject +//--------------------------------------------------------------------------- + + +_FX NTSTATUS Ipc_NtCreateSymbolicLinkObject( + PHANDLE SymbolicLinkHandle, ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, PUNICODE_STRING DestinationName) +{ + ULONG LastError; + THREAD_DATA *TlsData; + + NTSTATUS status; + OBJECT_ATTRIBUTES objattrs; + UNICODE_STRING objname; + WCHAR *TruePath; + WCHAR *CopyPath; + ULONG mp_flags; + + // + // shortcut processing when object name is not specified + // + + if ((! ObjectAttributes) || (! ObjectAttributes->ObjectName)) { + + return __sys_NtCreateSymbolicLinkObject( + SymbolicLinkHandle, DesiredAccess, ObjectAttributes, + DestinationName); + } + + // + // normal processing + // + + TlsData = Dll_GetTlsData(&LastError); + + Dll_PushTlsNameBuffer(TlsData); + + __try { + + // + // get the full paths for the true and copy objects + // + + status = Ipc_GetName2(ObjectAttributes, &TruePath, &CopyPath); + if (! NT_SUCCESS(status)) + __leave; + + if (! TruePath) { + + if(ObjectAttributes->ObjectName->Buffer) + SbieApi_MonitorPut2(MONITOR_IPC, ObjectAttributes->ObjectName->Buffer, FALSE); + + status = __sys_NtCreateSymbolicLinkObject( + SymbolicLinkHandle, DesiredAccess, ObjectAttributes, + DestinationName); + + __leave; + } + + InitializeObjectAttributes(&objattrs, + &objname, OBJECT_ATTRIBUTES_ATTRIBUTES, NULL, Secure_EveryoneSD); + + // + // check if this is an open or closed path + // + + mp_flags = SbieDll_MatchPath2(L'i', TruePath, FALSE, TRUE); // SbieDll_MatchPath(L'i', TruePath); + + if (PATH_IS_CLOSED(mp_flags)) { + status = STATUS_ACCESS_DENIED; + __leave; + } + + if (PATH_IS_OPEN(mp_flags)) { + + RtlInitUnicodeString(&objname, TruePath); + objattrs.SecurityDescriptor = ObjectAttributes->SecurityDescriptor; + + status = __sys_NtCreateSymbolicLinkObject( + SymbolicLinkHandle, DesiredAccess, &objattrs, + DestinationName); + + __leave; + } + + // + // try to create the object name by its CopyPath, creating the + // CopyPath hierarchy if needed + // + + RtlInitUnicodeString(&objname, CopyPath); + + status = __sys_NtCreateSymbolicLinkObject( + SymbolicLinkHandle, DesiredAccess, &objattrs, + DestinationName); + + if (status == STATUS_OBJECT_PATH_NOT_FOUND) { + + status = Ipc_CreatePath(TruePath, CopyPath); + + if (NT_SUCCESS(status)) { + status = __sys_NtCreateSymbolicLinkObject( + SymbolicLinkHandle, DesiredAccess, &objattrs, + DestinationName); + } + } + + // + // finish + // + + } __except (EXCEPTION_EXECUTE_HANDLER) { + status = GetExceptionCode(); + } + + Dll_PopTlsNameBuffer(TlsData); + SetLastError(LastError); + return status; +} + + +//--------------------------------------------------------------------------- +// Ipc_NtOpenSymbolicLinkObject +//--------------------------------------------------------------------------- + + +_FX NTSTATUS Ipc_NtOpenSymbolicLinkObject( + HANDLE *SymbolicLinkHandle, + ACCESS_MASK DesiredAccess, + OBJECT_ATTRIBUTES *ObjectAttributes) +{ + ULONG LastError; + THREAD_DATA *TlsData = Dll_GetTlsData(&LastError); + + NTSTATUS status; + OBJECT_ATTRIBUTES objattrs; + UNICODE_STRING objname; + WCHAR *TruePath; + WCHAR *CopyPath; + ULONG mp_flags; + + Dll_PushTlsNameBuffer(TlsData); + + __try { + + // + // get the full paths for the true and copy objects + // + + status = Ipc_GetName2(ObjectAttributes, &TruePath, &CopyPath); + if (! NT_SUCCESS(status)) + __leave; + + if (! TruePath) { + + status = __sys_NtOpenSymbolicLinkObject( + SymbolicLinkHandle, DesiredAccess, ObjectAttributes); + + __leave; + } + + InitializeObjectAttributes( + &objattrs, &objname, OBJECT_ATTRIBUTES_ATTRIBUTES, NULL, NULL); + + // + // check if this is an open or closed path + // + + mp_flags = SbieDll_MatchPath(L'i', TruePath); + + if (PATH_IS_CLOSED(mp_flags)) { + status = STATUS_ACCESS_DENIED; + __leave; + } + + if (PATH_IS_OPEN(mp_flags)) goto OpenTruePath; + + // + // open the object by its CopyPath first + // finish on success, else try true path + // + + RtlInitUnicodeString(&objname, CopyPath); + + status = __sys_NtOpenSymbolicLinkObject( + SymbolicLinkHandle, DesiredAccess, &objattrs); + + if(NT_SUCCESS(status)) + __leave; + + //if (status == STATUS_OBJECT_PATH_NOT_FOUND) { + // + // status = Ipc_CreatePath(TruePath, CopyPath); + // + // if (NT_SUCCESS(status)) + // status = STATUS_OBJECT_NAME_NOT_FOUND; + //} + // + //__leave; + + // + // try the TruePath + // + +OpenTruePath: + + RtlInitUnicodeString(&objname, TruePath); + + status = __sys_NtOpenSymbolicLinkObject( + SymbolicLinkHandle, DesiredAccess, &objattrs); + + if (PATH_NOT_OPEN(mp_flags) && (status == STATUS_ACCESS_DENIED)) + status = STATUS_OBJECT_NAME_NOT_FOUND; + + // + // finish + // + + } __except (EXCEPTION_EXECUTE_HANDLER) { + status = GetExceptionCode(); + } + + Dll_PopTlsNameBuffer(TlsData); + SetLastError(LastError); + return status; +} + + //--------------------------------------------------------------------------- // Ipc_IsKnownDllInSandbox //--------------------------------------------------------------------------- @@ -3758,23 +3999,3 @@ _FX ULONG Ipc_NtQueryObjectName(UNICODE_STRING *ObjectName, ULONG MaxLen) return 0; } - - -//--------------------------------------------------------------------------- -// Ipc_NtCreateSymbolicLinkObject -//--------------------------------------------------------------------------- - - -_FX NTSTATUS Ipc_NtCreateSymbolicLinkObject( - PHANDLE pHandle, ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes, PUNICODE_STRING DestinationName) -{ - WCHAR strW[8192]; - Sbie_snwprintf(strW, 8192, L"NtCreateSymbolicLinkObject, %s", DestinationName); - SbieApi_MonitorPutMsg(MONITOR_OTHER | MONITOR_TRACE, strW); - - SbieApi_Log(2205, L"NtCreateSymbolicLinkObject"); - - return STATUS_PRIVILEGE_NOT_HELD; - //return __sys_NtCreateSymbolicLinkObject(pHandle, DesiredAccess, ObjectAttributes, DestinationName); -} \ No newline at end of file diff --git a/Sandboxie/core/drv/ipc.c b/Sandboxie/core/drv/ipc.c index 799f1c2f..bbcbeca7 100644 --- a/Sandboxie/core/drv/ipc.c +++ b/Sandboxie/core/drv/ipc.c @@ -102,6 +102,7 @@ static const WCHAR *Ipc_Mutant_TypeName = L"Mutant"; static const WCHAR *Ipc_Semaphore_TypeName = L"Semaphore"; static const WCHAR *Ipc_Section_TypeName = L"Section"; static const WCHAR *Ipc_JobObject_TypeName = L"JobObject"; +static const WCHAR *Ipc_SymLink_TypeName = L"SymbolicLinkObject"; //--------------------------------------------------------------------------- @@ -137,6 +138,9 @@ _FX BOOLEAN Ipc_Init(void) if (! Ipc_Init_Type(Ipc_JobObject_TypeName, Ipc_CheckJobObject)) return FALSE; + if (! Ipc_Init_Type(Ipc_SymLink_TypeName, Ipc_CheckGenericObject)) + return FALSE; + // // set object open handlers for port objects // @@ -1141,7 +1145,7 @@ _FX NTSTATUS Ipc_Api_DuplicateObject(PROCESS *proc, ULONG64 *parms) HANDLE SourceHandle; HANDLE TargetProcessHandle; HANDLE *TargetHandle; - HANDLE TestHandle; + HANDLE DuplicatedHandle; ULONG DesiredAccess; ULONG HandleAttributes; ULONG Options; @@ -1287,15 +1291,15 @@ _FX NTSTATUS Ipc_Api_DuplicateObject(PROCESS *proc, ULONG64 *parms) status = ZwDuplicateObject( SourceProcessKernelHandle, SourceHandle, - TargetProcessKernelHandle, &TestHandle, + TargetProcessKernelHandle, &DuplicatedHandle, DesiredAccess, HandleAttributes, Options & ~DUPLICATE_CLOSE_SOURCE); if (NT_SUCCESS(status)) { - status = Ipc_CheckObjectName(TestHandle, UserMode); + status = Ipc_CheckObjectName(DuplicatedHandle, UserMode); - NtClose(TestHandle); + NtClose(DuplicatedHandle); } ZwClose(SourceProcessKernelHandle); @@ -1310,10 +1314,12 @@ _FX NTSTATUS Ipc_Api_DuplicateObject(PROCESS *proc, ULONG64 *parms) if (NT_SUCCESS(status)) { - status = NtDuplicateObject( + status = ZwDuplicateObject( SourceProcessHandle, SourceHandle, - TargetProcessHandle, TargetHandle, + TargetProcessHandle, &DuplicatedHandle, DesiredAccess, HandleAttributes, Options); + + *TargetHandle = DuplicatedHandle; } // diff --git a/Sandboxie/core/drv/obj.c b/Sandboxie/core/drv/obj.c index 7168ef67..5b409b76 100644 --- a/Sandboxie/core/drv/obj.c +++ b/Sandboxie/core/drv/obj.c @@ -172,10 +172,10 @@ _FX BOOLEAN Obj_Init(void) // Obj_ObjectTypes = Mem_AllocEx( - Driver_Pool, sizeof(POBJECT_TYPE) * 9, TRUE); + Driver_Pool, sizeof(POBJECT_TYPE) * 10, TRUE); if (! Obj_ObjectTypes) return FALSE; - memzero(Obj_ObjectTypes, sizeof(POBJECT_TYPE) * 9); + memzero(Obj_ObjectTypes, sizeof(POBJECT_TYPE) * 10); if (! Obj_AddObjectType(L"Job")) // PsJobType return FALSE; @@ -197,6 +197,8 @@ _FX BOOLEAN Obj_Init(void) if (! Obj_AddObjectType(L"ALPC Port")) // AlpcPortObjectType - not exported return FALSE; } + if (! Obj_AddObjectType(L"SymbolicLink")) // ObpSymbolicLinkObjectType - not exported + return FALSE; //DbgPrint("JobObject; Known: %p; Found: %p\r\n", *PsJobType, Obj_ObjectTypes[0]); diff --git a/Sandboxie/core/drv/syscall_open.c b/Sandboxie/core/drv/syscall_open.c index a9e84de6..b75fa94a 100644 --- a/Sandboxie/core/drv/syscall_open.c +++ b/Sandboxie/core/drv/syscall_open.c @@ -189,6 +189,18 @@ _FX NTSTATUS Syscall_CheckObject( proc->pool, OpenedObject, &Name, &NameLength); if (NT_SUCCESS(status)) { + // + // we enforce only CreateSymbolicLinkObject to use copy paths, + // OpenSymbolicLinkObject can use true paths + // + + if ((syscall_entry->name_len == 22 && memcmp(syscall_entry->name, "OpenSymbolicLinkObject", 22) == 0)) + goto finish; + + // + // invoke the Ipc_Check[Type]Object handler + // + status = syscall_entry->handler2_func( proc, OpenedObject, &Name->Name, HandleInfo->GrantedAccess); @@ -200,7 +212,7 @@ _FX NTSTATUS Syscall_CheckObject( (syscall_entry->name_len == 10 && memcmp(syscall_entry->name, "OpenThread", 10) == 0) || (syscall_entry->name_len == 21 && memcmp(syscall_entry->name, "AlpcOpenSenderProcess", 21) == 0) || (syscall_entry->name_len == 20 && memcmp(syscall_entry->name, "AlpcOpenSenderThread", 20) == 0)) - goto skip_log; + goto finish; if ((status != STATUS_SUCCESS) && (status != STATUS_BAD_INITIAL_PC)) { @@ -213,7 +225,7 @@ _FX NTSTATUS Syscall_CheckObject( Log_Msg_Process(MSG_2112, msg, puName != NULL ? puName->Buffer : L"Unnamed object", -1, proc->pid); } -skip_log: +finish: if (Name != &Obj_Unnamed) Mem_Free(Name, NameLength); }