This commit is contained in:
DavidXanatos 2021-12-20 12:55:02 +01:00
parent f36b90a1b2
commit 29b176667f
28 changed files with 473 additions and 187 deletions

View File

@ -5,11 +5,31 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [1.0.4 / 5.55.4] - 2021-12-xx
## [1.0.4 / 5.55.4] - 2021-12-20
### Added
- Mechanism to hook Win32 system calls now also works for 32 bit applications running under WoW64
- Added customization to Win32k hooking mechanism, as by default only GdiDdDDI* are installed
-- You can force the installation of other hooks by specifying them with "EnableWin32Hook=..."
-- or disable the instalation of the default hooks with "DisableWin32Hook=..."
-- Please note that some win32k hooks may cause BSOD's or undefined behavioure. (!)
-- The most obviusly problematic win32k hooks are blacklisted, this can be bypassed with "IgnoreWin32HookBlacklist=y"
- added debug option "AdjustBoxedSystem=n" option disable the adjustment of service ACL's running with a system token
- added "NoUACProxy=y" option together with the acompanying template it allows to disable UAC proxy
-- Note: Boxes configured in compartment mode activate this template by default
- added UI option to change default RpcMgmtSetComTimeout preset
### Changed
- mechanism to hook Win32k system calls now also works for 32 bit applications running under WoW64
- cleaned up low level hooking code a bit
- "EnableWin32kHooks=y" is now enabled by default, as no issues were reported in 1.0.3
-- Note: currently only the GdiDdDDI* hooks are applied, required for chromeium HW acceleration
- Cleaned up low level hooking code a bit
- "RunRpcssAsSystem=y" is now auto applied for boxes in "App Compartment" mode when "RunServicesAsSystem=y" or "MsiInstallerExemptions=y" are present
### Fixed
- fixed RPC handling in case a requested open service is not running [#1443](https://github.com/sandboxie-plus/Sandboxie/issues/1443)
- fixed a hooking issue with NdrClientCall2 with 32 bit applications
- fixed issue with start directroy when usign sandman to run sansboxed [#1436](https://github.com/sandboxie-plus/Sandboxie/issues/1436)
- fixed issue with recovering from network share locations [#1435](https://github.com/sandboxie-plus/Sandboxie/issues/1435)

View File

@ -390,7 +390,7 @@ finish:
_FX BOOLEAN Win32_Init(HMODULE hmodule)
{
// In Windows 10 all Win32k.sys calls are located in win32u.dll
if (Dll_OsBuild < 10041 || !SbieApi_QueryConfBool(NULL, L"EnableWin32kHooks", FALSE))
if (Dll_OsBuild < 10041 || !SbieApi_QueryConfBool(NULL, L"EnableWin32kHooks", TRUE))
return TRUE; // just return on older builds
// NoSysCallHooks BEGIN

View File

@ -756,6 +756,60 @@ _FX ULONG SbieDll_UpdateConf(
}
//---------------------------------------------------------------------------
// SbieDll_QueryConf
//---------------------------------------------------------------------------
_FX ULONG SbieDll_QueryConf(const WCHAR *Section, const WCHAR *Setting,
ULONG setting_index, WCHAR *out_buffer, ULONG buffer_len)
{
SBIE_INI_SETTING_REQ *req;
SBIE_INI_SETTING_RPL *rpl;
ULONG RequestLen;
ULONG status;
if ((! Section) || (! Setting))
return STATUS_INVALID_PARAMETER;
RequestLen = sizeof(SBIE_INI_SETTING_REQ);
req = Dll_Alloc(RequestLen);
if (! req)
return STATUS_INSUFFICIENT_RESOURCES;
req->h.length = RequestLen;
req->h.msgid = MSGID_SBIE_INI_GET_SETTING;
req->password[0] = L'\0';
req->refresh = FALSE;
wcscpy(req->section, Section);
wcscpy(req->setting, Setting);
req->value[0] = L'\0';
req->value_len = wcslen(req->value);
rpl = (SBIE_INI_SETTING_RPL *)SbieDll_CallServer(&req->h);
if (! rpl)
status = STATUS_INSUFFICIENT_RESOURCES;
else {
status = rpl->h.status;
if (NT_SUCCESS(status)) {
if (rpl->value_len > buffer_len)
status = STATUS_BUFFER_TOO_SMALL;
else
memcpy(out_buffer, rpl->value, rpl->value_len);
}
Dll_Free(rpl);
}
Dll_Free(req);
return status;
}
//---------------------------------------------------------------------------
// SbieDll_RunSandboxed
//---------------------------------------------------------------------------

View File

@ -101,6 +101,8 @@ _FX void *SbieDll_Hook(
static const WCHAR *_fmt1 = L"%s (%d)";
static const WCHAR *_fmt2 = L"%s (%d, %d)";
UCHAR *tramp, *func;
void* RegionBase;
SIZE_T RegionSize;
ULONG prot, dummy_prot;
ULONG_PTR diff;
ULONG_PTR target;
@ -321,11 +323,26 @@ skip_e9_rewrite: ;
func = (UCHAR *)SourceFunc;
if (!VirtualProtect(&func[-8], 20, PAGE_EXECUTE_READWRITE, &prot)) {
RegionBase = &func[-8]; // -8 for hotpatch area if present
RegionSize = 20;
ULONG err = GetLastError();
SbieApi_Log(2303, _fmt2, SourceFuncName, 33, err);
return NULL;
if (!VirtualProtect(RegionBase, RegionSize, PAGE_EXECUTE_READWRITE, &prot)) {
//
// on windows 7 hooking NdrClientCall2 in 32bit (WoW64) mode fails
// because the memory area starts at -6 and not -8
// this area could be a hot patch reagion which we dont use
// hence if that fails just start at the exact offset and try again
//
RegionBase = &func[0];
RegionSize = 12;
if (!VirtualProtect(RegionBase, RegionSize, PAGE_EXECUTE_READWRITE, &prot)) {
ULONG err = GetLastError();
SbieApi_Log(2303, _fmt2, SourceFuncName, 33, err);
return NULL;
}
}
//
@ -458,7 +475,7 @@ skip_e9_rewrite: ;
//for(; UsedCount < ByteCount; UsedCount++)
// func[UsedCount] = 0x90; // nop
VirtualProtect(&func[-8], 20, prot, &dummy_prot);
VirtualProtect(RegionBase, RegionSize, prot, &dummy_prot);
// the trampoline code begins at trampoline + 16 bytes
func = (UCHAR *)(ULONG_PTR)(tramp + 16);

View File

@ -1012,7 +1012,6 @@ _FX BOOL Proc_CreateProcessInternalW(
}
}
ok = __sys_CreateProcessInternalW(
NULL, lpApplicationName, lpCommandLine,
lpProcessAttributes, lpThreadAttributes, bInheritHandles,

View File

@ -726,22 +726,21 @@ _FX ULONG RpcRt_RpcBindingFromStringBindingW(
if (SbieDll_FindTagValue(ModulePreset, L"Resolve", tagValue, sizeof(tagValue), L'=', L','))
{
WCHAR* pwszTempPortName = GetDynamicLpcPortName(tagValue);
if (pwszTempPortName == NULL)
return RPC_S_ACCESS_DENIED;
WCHAR* ptr = wcsstr(StringBinding, L":");
if(ptr)
{
size_t len = ptr - StringBinding;
wcsncpy(wstrPortName, StringBinding, len);
wcscat(wstrPortName, L":[");
wcscat(wstrPortName, pwszTempPortName);
if(ptr[1] == L'[')
wcscat(wstrPortName, ptr + 2);
else
wcscat(wstrPortName, L"]");
}
if (pwszTempPortName != NULL)
{
WCHAR* ptr = wcsstr(StringBinding, L":");
if (ptr)
{
size_t len = ptr - StringBinding;
wcsncpy(wstrPortName, StringBinding, len);
wcscat(wstrPortName, L":[");
wcscat(wstrPortName, pwszTempPortName);
if (ptr[1] == L'[')
wcscat(wstrPortName, ptr + 2);
else
wcscat(wstrPortName, L"]");
}
}
// else error let it fail
}
@ -751,7 +750,6 @@ _FX ULONG RpcRt_RpcBindingFromStringBindingW(
}
}
RPC_STATUS status;
status = __sys_RpcBindingFromStringBindingW(*wstrPortName ? wstrPortName : StringBinding, OutBinding);
@ -852,7 +850,9 @@ _FX RPC_STATUS RpcRt_RpcBindingCreateW(
{
if (SbieDll_FindTagValue(ModulePreset, L"Resolve", tagValue, sizeof(tagValue), L'=', L','))
{
Template->StringEndpoint = GetDynamicLpcPortName(tagValue);
WCHAR* pwszTempPortName = GetDynamicLpcPortName(tagValue);
if (pwszTempPortName != NULL)
Template->StringEndpoint = pwszTempPortName;
}
/*else if (SbieDll_FindTagValue(ModulePreset, L"IpcPort", tagValue, sizeof(tagValue), L'=', L','))
{
@ -1079,6 +1079,7 @@ ALIGNED BOOLEAN __cdecl RpcRt_Ndr64AsyncClientCall_x64(
RpcRt_NdrClientCallX(L"Ndr64AsyncClientCall", ReturnAddress, pProxyInfo->pStubDesc, pProxyInfo->ProcFormatString, &pStack[1]);
}
if (!SbieApi_QueryConfBool(NULL, L"NoUACProxy", FALSE))
if (Dll_OsBuild >= 6000) {
return Secure_CheckElevation((struct SECURE_UAC_ARGS*)pStack);
}
@ -1095,6 +1096,7 @@ ALIGNED BOOLEAN __cdecl RpcRt_NdrAsyncClientCall_x86(
RpcRt_NdrClientCallX(L"NdrAsyncClientCall", ReturnAddress, pStubDescriptor, pFormat, &pStack[1]);
}
if (!SbieApi_QueryConfBool(NULL, L"NoUACProxy", FALSE))
if (Dll_OsBuild >= 6000) {
return Secure_CheckElevation((struct SECURE_UAC_ARGS*)pStack);
}

View File

@ -977,6 +977,62 @@ _FX LONG SbieApi_CheckInternetAccess(
len = 32;
memzero(MyDeviceName, sizeof(MyDeviceName));
wmemcpy(MyDeviceName, DeviceName32, len);
WCHAR* ptr = DeviceName32;
static const WCHAR *File_RawIp = L"rawip6";
static const WCHAR *File_Http = L"http\\";
static const WCHAR *File_Tcp = L"tcp6";
static const WCHAR *File_Udp = L"udp6";
static const WCHAR *File_Ip = L"ip6";
static const WCHAR *File_Afd = L"afd";
static const WCHAR *File_Nsi = L"nsi";
//
// check if this is an internet device
//
BOOLEAN chk = FALSE;
if (len == 6) {
if (_wcsnicmp(ptr, File_RawIp, 6) == 0)
chk = TRUE;
} else if (len == 5) {
if (_wcsnicmp(ptr, File_RawIp, 5) == 0)
chk = TRUE;
} else if (len == 4) {
if (_wcsnicmp(ptr, File_Http, 4) == 0)
chk = TRUE;
if (_wcsnicmp(ptr, File_Tcp, 4) == 0)
chk = TRUE;
else if (_wcsnicmp(ptr, File_Udp, 4) == 0)
chk = TRUE;
} else if (len == 3) {
if (_wcsnicmp(ptr, File_Tcp, 3) == 0)
chk = TRUE;
else if (_wcsnicmp(ptr, File_Udp, 3) == 0)
chk = TRUE;
else if (_wcsnicmp(ptr, File_Ip, 3) == 0)
chk = TRUE;
else if (_wcsnicmp(ptr, File_Afd, 3) == 0)
chk = TRUE;
else if (_wcsnicmp(ptr, File_Nsi, 3) == 0)
chk = TRUE;
} else if (len == 2) {
if (_wcsnicmp(ptr, File_Ip, 2) == 0)
chk = TRUE;
}
if (! chk) // quick bail out, don't bother the driver with irrelevant devices
return STATUS_OBJECT_NAME_INVALID;
}
memzero(parms, sizeof(parms));
@ -1249,6 +1305,25 @@ _FX LONG SbieApi_QueryConf(
}
//---------------------------------------------------------------------------
// SbieApi_QueryConf
//---------------------------------------------------------------------------
/*_FX LONG SbieApi_QueryConf(
const WCHAR* section_name, // WCHAR [66]
const WCHAR* setting_name, // WCHAR [66]
ULONG setting_index,
WCHAR* out_buffer,
ULONG buffer_len)
{
//if(SbieApi_DeviceHandle != INVALID_HANDLE_VALUE)
return SbieApi_QueryConfDrv(section_name, setting_name, setting_index, out_buffer, buffer_len);
// else try service
//return STATUS_CONNECTION_INVALID;
}*/
//---------------------------------------------------------------------------
// SbieApi_QueryConfBool
//---------------------------------------------------------------------------

View File

@ -149,6 +149,9 @@ SBIEDLL_EXPORT ULONG SbieDll_UpdateConf(
WCHAR OpCode, const WCHAR *Password, const WCHAR *Section,
const WCHAR *Setting, const WCHAR *Value);
SBIEDLL_EXPORT ULONG SbieDll_QueryConf(
const WCHAR *Section, const WCHAR *Setting,
ULONG setting_index, WCHAR *out_buffer, ULONG buffer_len);
//---------------------------------------------------------------------------
// Functions (Other)

View File

@ -2504,8 +2504,8 @@ _FX NTSTATUS File_Api_CheckInternetAccess(PROCESS *proc, ULONG64 *parms)
(API_CHECK_INTERNET_ACCESS_ARGS *)parms;
WCHAR *user_devname;
WCHAR device_name[42];
WCHAR *ptr, *ptr2;
ULONG len;
//WCHAR *ptr, *ptr2;
//ULONG len;
HANDLE ProcessId;
NTSTATUS status;
KIRQL irql;
@ -2521,7 +2521,9 @@ _FX NTSTATUS File_Api_CheckInternetAccess(PROCESS *proc, ULONG64 *parms)
ProbeForRead(user_devname, sizeof(WCHAR) * 32, sizeof(WCHAR));
wmemcpy(device_name, File_Mup, 8); // \Device\ prefix
wmemcpy(device_name + 8, user_devname, 32);
device_name[8+32] = L'\0';
/* this check is now done in unser mode
//
// convert the device name to lowercase, stop at the first backslash
//
@ -2584,6 +2586,7 @@ _FX NTSTATUS File_Api_CheckInternetAccess(PROCESS *proc, ULONG64 *parms)
if (! chk)
return STATUS_OBJECT_NAME_INVALID;
*/
//

View File

@ -222,7 +222,7 @@ _FX BOOLEAN Syscall_Init(void)
#ifdef HOOK_WIN32K
// must be windows 10 or later // Don't use experimental features by default
if (Driver_OsBuild >= 10041 && Conf_Get_Boolean(NULL, L"EnableWin32kHooks", 0, FALSE)) {
if (Driver_OsBuild >= 10041 && Conf_Get_Boolean(NULL, L"EnableWin32kHooks", 0, TRUE)) {
if (!Syscall_Init_List32())
return FALSE;

View File

@ -693,6 +693,30 @@ WCHAR *ProcessServer::RunSandboxedCopyString(
}*/
//---------------------------------------------------------------------------
// ProcessServer__RunRpcssAsSystem
//---------------------------------------------------------------------------
bool ProcessServer__RunRpcssAsSystem(WCHAR* boxname)
{
if (SbieApi_QueryConfBool(boxname, L"RunRpcssAsSystem", FALSE))
return true;
// OriginalToken BEGIN
if (SbieApi_QueryConfBool(boxname, L"NoSecurityIsolation", FALSE) || SbieApi_QueryConfBool(boxname, L"OriginalToken", FALSE)) {
// OriginalToken END
//
// if we run MSIServer as system we need to run the sandboxed Rpcss as system to or else it wil fail
//
if (SbieApi_QueryConfBool(boxname, L"MsiInstallerExemptions", FALSE) || SbieApi_QueryConfBool(boxname, L"RunServicesAsSystem", FALSE))
return TRUE;
}
return FALSE;
}
//---------------------------------------------------------------------------
// RunSandboxedGetToken
//---------------------------------------------------------------------------
@ -724,7 +748,7 @@ HANDLE ProcessServer::RunSandboxedGetToken(
const WCHAR* TokenSrc = ThreadToken;
if ((wcscmp(cmd, L"*RPCSS*") == 0 /* || wcscmp(cmd, L"*DCOM*") == 0 */)
&& SbieApi_QueryConfBool(boxname, L"RunRpcssAsSystem", FALSE)) {
&& ProcessServer__RunRpcssAsSystem(boxname)) {
TokenSrc = SystemToken;
}
@ -853,9 +877,10 @@ HANDLE ProcessServer::RunSandboxedGetToken(
if (SbieApi_QueryConfBool(boxname, L"ExposeBoxedSystem", FALSE))
ok = RunSandboxedSetDacl(CallerProcessHandle, NewTokenHandle, GENERIC_ALL, TRUE);
// OriginalToken BEGIN
else if (!SbieApi_QueryConfBool(boxname, L"NoSecurityIsolation", FALSE) && !SbieApi_QueryConfBool(boxname, L"OriginalToken", FALSE))
// OriginalToken END
else if (SbieApi_QueryConfBool(boxname, L"AdjustBoxedSystem", TRUE))
// OriginalToken BEGIN
if(!SbieApi_QueryConfBool(boxname, L"NoSecurityIsolation", FALSE) && !SbieApi_QueryConfBool(boxname, L"OriginalToken", FALSE))
// OriginalToken END
ok = RunSandboxedSetDacl(CallerProcessHandle, NewTokenHandle, GENERIC_READ, FALSE);
}

View File

@ -391,9 +391,10 @@ ULONG ServiceServer::RunHandler2(
{
if (SbieApi_QueryConfBool(boxname, L"ExposeBoxedSystem", FALSE))
ok = ProcessServer::RunSandboxedSetDacl(hProcess, hNewToken, GENERIC_ALL, TRUE, idProcess);
// OriginalToken BEGIN
else if (!SbieApi_QueryConfBool(boxname, L"NoSecurityIsolation", FALSE) && !SbieApi_QueryConfBool(boxname, L"OriginalToken", FALSE))
// OriginalToken END
else if (SbieApi_QueryConfBool(boxname, L"AdjustBoxedSystem", TRUE))
// OriginalToken BEGIN
if (!SbieApi_QueryConfBool(boxname, L"NoSecurityIsolation", FALSE) && !SbieApi_QueryConfBool(boxname, L"OriginalToken", FALSE))
// OriginalToken END
ok = ProcessServer::RunSandboxedSetDacl(hProcess, hNewToken, GENERIC_READ, FALSE);
CloseHandle(hProcess);

View File

@ -3251,6 +3251,16 @@ RpcPortBindingSvc=WPAD,WinHttpAutoProxySvc
RpcPortBinding=resourcepolicyclient.dll,{00000000-0000-0000-0000-000000000000},Resolve=GamePort
RpcPortBindingIfId=GamePort,{88ABCBC3-34EA-76AE-8215-767520655A23}
[Template_NoUACProxy]
Tmpl.Title=Open RPC for UAC
Tmpl.Class=Misc
NoUACProxy=y
#UAC for compartment Mode
RpcPortBinding=windows.storage.dll,'201ef99a-7fa0-444c-9399-19ba84f12a1a@ncalrpc:',Resolve=UAC,TimeOut=n
RpcPortBindingIfId=UAC,{201EF99A-7FA0-444C-9399-19BA84F12A1A}
#
# Optional RPC Port Config
#

View File

@ -124,7 +124,7 @@ SB_STATUS CSandBox::RunStart(const QString& Command, bool Elevated)
if ((QGuiApplication::queryKeyboardModifiers() & Qt::ControlModifier) != 0)
return RunSandboxed(Command);
#endif
return m_pAPI->RunStart(m_Name, Command, NULL, Elevated);
return m_pAPI->RunStart(m_Name, Command, Elevated);
}
SB_STATUS CSandBox::RunSandboxed(const QString& Command)

View File

@ -993,7 +993,7 @@ QString CSbieAPI::GetUserSection(QString* pUserName, bool* pIsAdmin) const
return UserSection;
}
SB_STATUS CSbieAPI::RunStart(const QString& BoxName, const QString& Command, QProcess* pProcess, bool Elevated)
SB_STATUS CSbieAPI::RunStart(const QString& BoxName, const QString& Command, bool Elevated, const QString& WorkingDir)
{
if (m_SbiePath.isEmpty())
return SB_ERR(SB_PathFail);
@ -1008,22 +1008,50 @@ SB_STATUS CSbieAPI::RunStart(const QString& BoxName, const QString& Command, QPr
StartArgs += Command;
wchar_t sysPath[MAX_PATH];
GetSystemDirectoryW(sysPath, MAX_PATH);
//wchar_t sysPath[MAX_PATH];
//GetSystemDirectoryW(sysPath, MAX_PATH);
QProcess process;
//process.setWorkingDirectory(QString::fromWCharArray(sysPath));
if (!WorkingDir.isEmpty())
process.setWorkingDirectory(WorkingDir);
process.setProgram(GetStartPath());
process.setNativeArguments(StartArgs);
process.startDetached();
/*
QString CommandLine = "\"" + GetStartPath() + "\" " + StartArgs;
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
// Start the child process.
if( !CreateProcessW( NULL, // No module name (use command line)
(wchar_t*)CommandLine.toStdWString().c_str(), // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi ) // Pointer to PROCESS_INFORMATION structure
)
{
printf( "CreateProcess failed (%d).\n", GetLastError() );
return SB_ERR();
}
// Wait until child process exits.
//WaitForSingleObject( pi.hProcess, INFINITE );
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
*/
if (pProcess) {
pProcess->setWorkingDirectory(QString::fromWCharArray(sysPath));
pProcess->setProgram(GetStartPath());
pProcess->setNativeArguments(StartArgs);
pProcess->start();
}
else {
QProcess process;
process.setWorkingDirectory(QString::fromWCharArray(sysPath));
process.setProgram(GetStartPath());
process.setNativeArguments(StartArgs);
process.startDetached();
}
return SB_OK;
}
@ -1860,6 +1888,9 @@ QString CSbieAPI::GetBoxedPath(const CSandBoxPtr& pBox, const QString& Path)
return BoxRoot + "\\user\\public" + Path.mid(m_PublicDir.length());
}
if (Path.length() >= 3 && Path.left(2) == "\\\\")
return BoxRoot + "\\share\\" + Path.mid(2);
if (Path.length() < 3 || Path.at(1) != ':')
return QString();
@ -1901,20 +1932,20 @@ QString CSbieAPI::GetRealPath(const CSandBoxPtr& pBox, const QString& Path)
if (BoxRoot.right(1) == "\\") BoxRoot.truncate(BoxRoot.length() - 1);
if (Path.length() < BoxRoot.length())
return QString();;
return QString();
RealPath = Path.mid(BoxRoot.length());
if (RealPath.left(6) == "\\share")
{
QString Temp = RealPath.mid(6);
QString NtFolder = RealPath.mid(6);
bool bBs = false;
if ((bBs = (Temp.count("\\") < 3))) Temp += "\\";
if ((bBs = (NtFolder.count("\\") < 3))) NtFolder += "\\";
bool bOk;
Temp = Nt2DosPath("\\Device\\LanmanRedirector" + Temp, &bOk);
if (!bOk) return QString();
if (bBs) Temp.truncate(Temp.length() - 1);
return Temp;
QString Folder = Nt2DosPath("\\Device\\LanmanRedirector" + NtFolder, &bOk);
if (!bOk) return "\\" + NtFolder;
if (bBs) Folder.truncate(Folder.length() - 1);
return Folder;
}
if (RealPath.left(5) == "\\user")

View File

@ -131,7 +131,7 @@ public:
// Other
virtual QString GetSbieMsgStr(quint32 code, quint32 Lang = 1033);
virtual SB_STATUS RunStart(const QString& BoxName, const QString& Command, QProcess* pProcess = NULL, bool Elevated = false);
virtual SB_STATUS RunStart(const QString& BoxName, const QString& Command, bool Elevated = false, const QString& WorkingDir = QString());
virtual QString GetStartPath() const;
virtual quint32 GetSessionID() const;

View File

@ -1747,7 +1747,7 @@ You can use 'Open for All' instead to make it apply to all programs, or change t
<item row="5" column="3">
<widget class="QLabel" name="label_54">
<property name="text">
<string>The rule specificity is a measure to how well a given rule matches a particular path, simply put the specificity is the length of characters from the begin of the path up to and including the last matching non-wildcard substring. A rule which matches only file types like &quot;*.tmp&quot; would have the highest specificity as it would always match the entire file path.
<string>The rule specificity is a measure to how well a given rule matches a particular path, simply put the specificity is the length of characters from the begin of the path up to and including the last matching non-wildcard substring. A rule which matches only file types like &quot;*.tmp&quot; would have the highest specificity as it would always match the entire file path.
The process match level has a higher priority than the specificity and describes how a rule applies to a given process. Rules applying by process name or group have the strongest match level, followed by the match by negation (i.e. rules applying to all processes but the given one), while the lowest match levels have global matches, i.e. rules that apply to any process.</string>
</property>
<property name="wordWrap">
@ -1991,17 +1991,45 @@ The process match level has a higher priority than the specificity and describes
<layout class="QGridLayout" name="gridLayout_26">
<item row="0" column="1">
<layout class="QGridLayout" name="gridLayout_2">
<item row="3" column="1" colspan="2">
<widget class="QCheckBox" name="chkNoWindowRename">
<item row="5" column="1" colspan="2">
<widget class="QCheckBox" name="chkUseSbieWndStation">
<property name="text">
<string>Don't alter window class names created by sandboxed programs</string>
<string>Emulate sandboxed window station for all processes</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QCheckBox" name="chkElevateRpcss">
<item row="12" column="1">
<widget class="QCheckBox" name="chkDropPrivileges">
<property name="text">
<string>Start the sandboxed RpcSs as a SYSTEM process (not recommended)</string>
<string>Drop critical privileges from processes running with a SYSTEM token</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QCheckBox" name="chkAddToJob">
<property name="text">
<string>Add sandboxed processes to job objects (recommended)</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QCheckBox" name="chkRestrictServices">
<property name="text">
<string>Do not start sandboxed services using a system token (recommended)</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QCheckBox" name="chkProtectSystem">
<property name="text">
<string>Protect sandboxed SYSTEM processes from unprivileged processes</string>
</property>
</widget>
</item>
<item row="14" column="1" colspan="2">
<widget class="QCheckBox" name="chkOpenCOM">
<property name="text">
<string>Open access to COM infrastructure (not recommended)</string>
</property>
</widget>
</item>
@ -2012,10 +2040,51 @@ The process match level has a higher priority than the specificity and describes
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QCheckBox" name="chkRestrictServices">
<item row="2" column="1" colspan="2">
<widget class="QCheckBox" name="chkPreferExternalManifest">
<property name="text">
<string>Do not start sandboxed services using a system token (recommended)</string>
<string>Force usage of custom dummy Manifest files (legacy behaviour)</string>
</property>
</widget>
</item>
<item row="11" column="2">
<widget class="QLabel" name="label_65">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string>(Security Critical)</string>
</property>
</widget>
</item>
<item row="16" column="2">
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="10" column="1">
<widget class="QCheckBox" name="chkElevateRpcss">
<property name="text">
<string>Start the sandboxed RpcSs as a SYSTEM process (not recommended)</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QCheckBox" name="chkNoWindowRename">
<property name="text">
<string>Don't alter window class names created by sandboxed programs</string>
</property>
</widget>
</item>
@ -2033,14 +2102,7 @@ The process match level has a higher priority than the specificity and describes
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QCheckBox" name="chkNestedJobs">
<property name="text">
<string>Allow use of nested job objects (experimental, works on Windows 8 and later)</string>
</property>
</widget>
</item>
<item row="15" column="1">
<item row="16" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -2053,71 +2115,6 @@ The process match level has a higher priority than the specificity and describes
</property>
</spacer>
</item>
<item row="14" column="1" colspan="2">
<widget class="QCheckBox" name="chkOpenCOM">
<property name="text">
<string>Open access to COM infrastructure (not recommended)</string>
</property>
</widget>
</item>
<item row="15" column="2">
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1" colspan="2">
<widget class="QCheckBox" name="chkPreferExternalManifest">
<property name="text">
<string>Force usage of custom dummy Manifest files (legacy behaviour)</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QCheckBox" name="chkAddToJob">
<property name="text">
<string>Add sandboxed processes to job objects (recommended)</string>
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QLabel" name="label_63">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<kerning>true</kerning>
</font>
</property>
<property name="toolTip">
<string>Protect the sandbox integrity itself</string>
</property>
<property name="text">
<string>COM isolation</string>
</property>
</widget>
</item>
<item row="5" column="1" colspan="2">
<widget class="QCheckBox" name="chkUseSbieWndStation">
<property name="text">
<string>Emulate sandboxed window station for all processes</string>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QCheckBox" name="chkDropPrivileges">
<property name="text">
<string>Drop critical privileges from processes running with a SYSTEM token</string>
</property>
</widget>
</item>
<item row="12" column="2">
<widget class="QLabel" name="label_64">
<property name="font">
@ -2132,27 +2129,6 @@ The process match level has a higher priority than the specificity and describes
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QCheckBox" name="chkProtectSystem">
<property name="text">
<string>Protect sandboxed SYSTEM processes from unprivileged processes</string>
</property>
</widget>
</item>
<item row="11" column="2">
<widget class="QLabel" name="label_65">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string>(Security Critical)</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_22">
<property name="font">
@ -2170,6 +2146,37 @@ The process match level has a higher priority than the specificity and describes
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QLabel" name="label_63">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<kerning>true</kerning>
</font>
</property>
<property name="toolTip">
<string>Protect the sandbox integrity itself</string>
</property>
<property name="text">
<string>COM/RPC</string>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QCheckBox" name="chkNestedJobs">
<property name="text">
<string>Allow use of nested job objects (experimental, works on Windows 8 and later)</string>
</property>
</widget>
</item>
<item row="15" column="1" colspan="2">
<widget class="QCheckBox" name="chkComTimeout">
<property name="text">
<string>Disable using RpcMgmtSetComTimeout by default (toggle this may resovle compatybility issues)</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
@ -2708,8 +2715,8 @@ instead of &quot;*&quot;.</string>
<rect>
<x>0</x>
<y>0</y>
<width>63</width>
<height>16</height>
<width>98</width>
<height>28</height>
</rect>
</property>
<layout class="QGridLayout" name="dbgLayout">

View File

@ -614,8 +614,10 @@ bool CSandMan::IsFullyPortable()
return false;
}
void CSandMan::OnMessage(const QString& Message)
void CSandMan::OnMessage(const QString& MsgData)
{
QStringList Messages = MsgData.split("\n");
QString Message = Messages[0];
if (Message == "ShowWnd")
{
if (!isVisible())
@ -637,11 +639,19 @@ void CSandMan::OnMessage(const QString& Message)
}
}
QString WrkDir;
for (int i = 1; i < Messages.length(); i++) {
if (Messages[i].left(5) == "From:") {
WrkDir = Messages[i].mid(5);
break;
}
}
if (theConf->GetBool("Options/RunInDefaultBox", false) && (QGuiApplication::queryKeyboardModifiers() & Qt::ControlModifier) == 0) {
theAPI->RunStart("DefaultBox", CmdLine);
theAPI->RunStart("DefaultBox", CmdLine, false, WrkDir);
}
else
RunSandboxed(QStringList(CmdLine), BoxName);
RunSandboxed(QStringList(CmdLine), BoxName, WrkDir);
}
else if (Message.left(3) == "Op:")
{
@ -698,9 +708,9 @@ void CSandMan::dragEnterEvent(QDragEnterEvent* e)
}
}
void CSandMan::RunSandboxed(const QStringList& Commands, const QString& BoxName)
void CSandMan::RunSandboxed(const QStringList& Commands, const QString& BoxName, const QString& WrkDir)
{
CSelectBoxWindow* pSelectBoxWindow = new CSelectBoxWindow(Commands, BoxName);
CSelectBoxWindow* pSelectBoxWindow = new CSelectBoxWindow(Commands, BoxName, WrkDir);
pSelectBoxWindow->show();
}

View File

@ -50,7 +50,7 @@ public:
CSbieView* GetBoxView() { return m_pBoxView; }
void RunSandboxed(const QStringList& Commands, const QString& BoxName);
void RunSandboxed(const QStringList& Commands, const QString& BoxName, const QString& WrkDir = QString());
QIcon GetBoxIcon(int boxType, bool inUse = false);
QString GetBoxDescription(int boxType);

View File

@ -101,6 +101,7 @@ void CNewBoxWindow::CreateBox()
pBox->SetBool("NoSecurityIsolation", true);
//pBox->SetBool("RunServicesAsSystem", true);
pBox->SetBool("UsePrivacyMode", BoxType == CSandBoxPlus::eAppBoxPlus);
pBox->InsertText("Template", "NoUACProxy");
break;
}
}

View File

@ -17,12 +17,13 @@ void COptionsWindow::CreateAdvanced()
connect(ui.chkAddToJob, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkProtectSCM, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkRestrictServices, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkRestrictServices, SIGNAL(clicked(bool)), this, SLOT(OnSysSvcChanged()));
connect(ui.chkElevateRpcss, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkProtectSystem, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkDropPrivileges, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkOpenCOM, SIGNAL(clicked(bool)), this, SLOT(OnOpenCOM()));
connect(ui.chkComTimeout, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkNoSecurityIsolation, SIGNAL(clicked(bool)), this, SLOT(OnIsolationChanged()));
connect(ui.chkNoSecurityFiltering, SIGNAL(clicked(bool)), this, SLOT(OnIsolationChanged()));
@ -73,6 +74,8 @@ void COptionsWindow::LoadAdvanced()
ui.chkProtectSystem->setChecked(!m_pBox->GetBool("ExposeBoxedSystem", false));
ui.chkDropPrivileges->setChecked(m_pBox->GetBool("StripSystemPrivileges", true));
ui.chkComTimeout->setChecked(!m_pBox->GetBool("RpcMgmtSetComTimeout", true));
ui.chkNoSecurityIsolation->setChecked(m_pBox->GetBool("NoSecurityIsolation", false));
ui.chkNoSecurityFiltering->setChecked(m_pBox->GetBool("NoSecurityFiltering", false));
@ -116,6 +119,7 @@ void COptionsWindow::LoadAdvanced()
ui.chkMonitorAdminOnly->setChecked(m_pBox->GetBool("MonitorAdminOnly", false));
UpdateBoxIsolation();
OnSysSvcChanged();
ui.chkOpenCredentials->setEnabled(!ui.chkOpenProtectedStorage->isChecked());
if (!ui.chkOpenCredentials->isEnabled()) ui.chkOpenCredentials->setChecked(true);
@ -136,6 +140,8 @@ void COptionsWindow::SaveAdvanced()
WriteAdvancedCheck(ui.chkProtectSystem, "ExposeBoxedSystem", "", "y");
WriteAdvancedCheck(ui.chkDropPrivileges, "StripSystemPrivileges", "", "n");
WriteAdvancedCheck(ui.chkComTimeout, "RpcMgmtSetComTimeout", "n", "");
WriteAdvancedCheck(ui.chkNoSecurityIsolation, "NoSecurityIsolation", "y", "");
WriteAdvancedCheck(ui.chkNoSecurityFiltering, "NoSecurityFiltering", "y", "");
@ -218,6 +224,13 @@ void COptionsWindow::UpdateBoxIsolation()
ui.chkCloseClipBoard->setEnabled(!ui.chkNoSecurityIsolation->isChecked());
}
void COptionsWindow::OnSysSvcChanged()
{
ui.chkElevateRpcss->setDisabled(ui.chkNoSecurityIsolation->isChecked() && (!ui.chkRestrictServices->isChecked() || ui.chkMsiExemptions->isChecked()));
m_AdvancedChanged = true;
OnOptChanged();
}
void COptionsWindow::OnAdvancedChanged()
{
m_AdvancedChanged = true;

View File

@ -271,7 +271,7 @@ void COptionsWindow::OnAddAutoCmd()
void COptionsWindow::OnAddAutoExe()
{
QString Value = QFileDialog::getOpenFileName(this, tr("Select Program"), "", tr("Executables (*.exe *.cmd);;All files (*.*)")).replace("/", "\\");;
QString Value = QFileDialog::getOpenFileName(this, tr("Select Program"), "", tr("Executables (*.exe *.cmd);;All files (*.*)")).replace("/", "\\");
if (Value.isEmpty())
return;
@ -314,7 +314,7 @@ void COptionsWindow::OnDelAuto()
void COptionsWindow::OnBrowsePath()
{
QString Value = QFileDialog::getOpenFileName(this, tr("Select Program"), "", tr("Executables (*.exe *.cmd)")).replace("/", "\\");;
QString Value = QFileDialog::getOpenFileName(this, tr("Select Program"), "", tr("Executables (*.exe *.cmd)")).replace("/", "\\");
if (Value.isEmpty())
return;
@ -402,6 +402,7 @@ void COptionsWindow::OnBoxTypChanged()
ui.chkMsiExemptions->setChecked(false);
//ui.chkRestrictServices->setChecked(true);
ui.chkPrivacy->setChecked(BoxType == CSandBoxPlus::eHardenedPlus);
SetTemplate("NoUACProxy", false);
break;
case CSandBoxPlus::eDefaultPlus:
case CSandBoxPlus::eDefault:
@ -411,12 +412,14 @@ void COptionsWindow::OnBoxTypChanged()
ui.chkMsiExemptions->setChecked(false);
//ui.chkRestrictServices->setChecked(true);
ui.chkPrivacy->setChecked(BoxType == CSandBoxPlus::eDefaultPlus);
SetTemplate("NoUACProxy", false);
break;
case CSandBoxPlus::eAppBoxPlus:
case CSandBoxPlus::eAppBox:
ui.chkNoSecurityIsolation->setChecked(true);
//ui.chkRestrictServices->setChecked(false);
ui.chkPrivacy->setChecked(BoxType == CSandBoxPlus::eAppBoxPlus);
SetTemplate("NoUACProxy", true);
break;
}

View File

@ -78,16 +78,21 @@ void COptionsWindow::LoadTemplates()
m_TemplatesChanged = false;
}
void COptionsWindow::OnScreenReaders()
{
if (ui.chkScreenReaders->isChecked())
m_BoxTemplates.append("ScreenReader");
void COptionsWindow::SetTemplate(const QString& Template, bool bEnabled)
{
if(bEnabled)
m_BoxTemplates.append(Template);
else
m_BoxTemplates.removeAll("ScreenReader");
m_BoxTemplates.removeAll(Template);
m_TemplatesChanged = true;
OnOptChanged();
}
void COptionsWindow::OnScreenReaders()
{
SetTemplate("ScreenReader", ui.chkScreenReaders->isChecked());
}
QString COptionsWindow::GetCategoryName(const QString& Category)
{
if (Category.compare("Local", Qt::CaseInsensitive) == 0) return tr("Custom Templates");

View File

@ -147,6 +147,7 @@ private slots:
void OnINetBlockChanged() { m_INetBlockChanged = true; OnOptChanged(); }
void OnRecoveryChanged() { m_RecoveryChanged = true; OnOptChanged(); }
void OnAccessChanged();
void OnSysSvcChanged();
void OnAdvancedChanged();
void OnOpenCOM();
void OnIsolationChanged();
@ -333,6 +334,7 @@ protected:
void LoadTemplates();
void ShowTemplates();
void SaveTemplates();
void SetTemplate(const QString& Template, bool bEnabled);
void LoadFolders();
void ShowFolders();

View File

@ -116,6 +116,8 @@ CRecoveryWindow::CRecoveryWindow(const CSandBoxPtr& pBox, QWidget *parent)
QString Folder = theAPI->Nt2DosPath(NtFolder, &bOk);
if(bOk)
m_RecoveryFolders.append(Folder);
else if(NtFolder.left(11) == "\\Device\\Mup")
m_RecoveryFolders.append("\\" + NtFolder.mid(11));
}
ui.cmbRecover->addItem(tr("Original location"), 0);
@ -154,7 +156,7 @@ void CRecoveryWindow::closeEvent(QCloseEvent *e)
void CRecoveryWindow::OnAddFolder()
{
QString Folder = QFileDialog::getExistingDirectory(this, tr("Select Directory")).replace("/", "\\");;
QString Folder = QFileDialog::getExistingDirectory(this, tr("Select Directory")).replace("/", "\\");
if (Folder.isEmpty())
return;

View File

@ -53,10 +53,11 @@ double CSelectBoxWindow__GetBoxOrder(const QMap<QString, QStringList>& Groups, c
return 1000000000;
}
CSelectBoxWindow::CSelectBoxWindow(const QStringList& Commands, const QString& BoxName, QWidget *parent)
CSelectBoxWindow::CSelectBoxWindow(const QStringList& Commands, const QString& BoxName, const QString& WrkDir, QWidget *parent)
: QDialog(parent)
{
m_Commands = Commands;
m_WrkDir = WrkDir;
Qt::WindowFlags flags = windowFlags();
flags |= Qt::CustomizeWindowHint;
@ -179,7 +180,7 @@ void CSelectBoxWindow::OnRun()
//QList<SB_STATUS> Results;
foreach(const QString & Command, m_Commands) {
theAPI->RunStart(BoxName, Command, NULL, ui.chkAdmin->isChecked());
theAPI->RunStart(BoxName, Command, ui.chkAdmin->isChecked(), m_WrkDir);
}
//CSandMan::CheckResults(Results);

View File

@ -9,7 +9,7 @@ class CSelectBoxWindow : public QDialog
Q_OBJECT
public:
CSelectBoxWindow(const QStringList& Commands, const QString& BoxName, QWidget *parent = Q_NULLPTR);
CSelectBoxWindow(const QStringList& Commands, const QString& BoxName, const QString& WrkDir = QString(), QWidget *parent = Q_NULLPTR);
~CSelectBoxWindow();
private slots:
@ -21,6 +21,7 @@ protected:
void closeEvent(QCloseEvent* e);
QStringList m_Commands;
QString m_WrkDir;
private:
Ui::SelectBoxWindow ui;

View File

@ -70,6 +70,7 @@ int main(int argc, char *argv[])
}
PendingMessage = "Run:" + QString::fromWCharArray(ChildCmdLine);
PendingMessage += "\nFrom:" + QDir::currentPath();
}
if (IsBoxed) {