This commit is contained in:
DavidXanatos 2024-06-16 18:32:38 +02:00
parent 4aea811b47
commit b49c7fcde1
15 changed files with 185 additions and 20 deletions

View File

@ -16,6 +16,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Add template "BlockAccessWMI" to prevent sandboxed processes from accessing system information through WMI.
- Add template "BlockLocalConnect" to prevent sandboxed processes from sending network packs to loaclhost to breakout sandbox.
- Add new option "AllowCoverTaskbar" for [#3975](https://github.com/sandboxie-plus/Sandboxie/issues/3975)
- added RPC Port message filter mechanism to block unsafe RDP calls via the driver [#3930](https://github.com/sandboxie-plus/Sandboxie/issues/3930)
- Usage: "RpcPortFilter=Port,ID,Label" label is optional
### Changed
- Extend "Temp Template" to make it could delete local template section.
@ -43,7 +45,6 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- when it is set, a prompt pops up before launching a new program into the sandbox using "Start.exe" and checks if the program that started "Start.exe" is a Sandboxie component itself, if it is not, a warning pops up
- added option for EditAdminOnly in SetupWizard
### Changed
- splited the advanced new box wizard page in two
- reorganized box options a bit

View File

@ -65,7 +65,7 @@ const WCHAR* SbieDll_GetTagValue(const WCHAR* str, const WCHAR* strEnd, const WC
// check if tag contains a string in quotations
if ((alt = (*str == L'\"')) || (*str == L'\''))
{
WCHAR* end = wcschr(str + 1, alt ? L'\"' : L'\'');
const WCHAR* end = wcschr(str + 1, alt ? L'\"' : L'\'');
if (!end)
return NULL; // error invalid string
*value = str + 1;
@ -160,7 +160,7 @@ BOOLEAN SbieDll_FindTagValuePtr(const WCHAR* string, const WCHAR* tag_name, cons
TagFindProcParam tagFindProcParam =
{
tag_name,
wcslen(tag_name),
(ULONG)wcslen(tag_name),
NULL,
0
};
@ -175,7 +175,7 @@ BOOLEAN SbieDll_FindTagValuePtr(const WCHAR* string, const WCHAR* tag_name, cons
BOOLEAN SbieDll_FindTagValue(const WCHAR* string, const WCHAR* tag_name, WCHAR* value, ULONG value_size, WCHAR eq, WCHAR sep)
{
WCHAR* value_ptr;
const WCHAR* value_ptr;
ULONG value_len;
if (!SbieDll_FindTagValuePtr(string, tag_name, &value_ptr, &value_len, eq, sep))
return FALSE;

View File

@ -544,6 +544,17 @@ BOOLEAN SbieDll_MatchImage(const WCHAR* pat_str, const WCHAR* test_str, const WC
BOOLEAN SbieDll_GetStringForStringList(const WCHAR* string, const WCHAR* boxname, const WCHAR* setting, WCHAR* value, ULONG value_size)
{
return SbieDll_GetStringsForStringList(string, boxname, setting, 0, value, value_size);
}
//---------------------------------------------------------------------------
// SbieDll_GetStringsForStringList
//---------------------------------------------------------------------------
SBIEDLL_EXPORT BOOLEAN SbieDll_GetStringsForStringList(const WCHAR* string, const WCHAR* boxname, const WCHAR* setting, int pos, WCHAR* value, ULONG value_size)
{
BOOLEAN found = FALSE;
WCHAR buf[CONF_LINE_LEN];
@ -557,16 +568,22 @@ BOOLEAN SbieDll_GetStringForStringList(const WCHAR* string, const WCHAR* boxname
// check specific value
*ptr++ = L'\0';
if (_wcsicmp(buf, string) == 0) {
if (pos == 0) {
wcscpy_s(value, value_size / sizeof(WCHAR), ptr);
found = TRUE;
break;
}
pos--;
}
}
else if (!found) {
// default value
if (pos == 0) {
wcscpy_s(value, value_size / sizeof(WCHAR), buf);
found = TRUE;
}
pos--;
}
}
else if (status != STATUS_BUFFER_TOO_SMALL)
break;

View File

@ -226,6 +226,7 @@ SBIEDLL_EXPORT ULONG SbieDll_InjectLow(HANDLE hProcess, ULONG init_flags, BOOLE
SBIEDLL_EXPORT BOOLEAN SbieDll_MatchImage(const WCHAR* pat_str, const WCHAR* test_str, const WCHAR* BoxName);
SBIEDLL_EXPORT BOOLEAN SbieDll_GetStringForStringList(const WCHAR* string, const WCHAR* boxname, const WCHAR* setting, WCHAR* value, ULONG value_size);
SBIEDLL_EXPORT BOOLEAN SbieDll_GetStringsForStringList(const WCHAR* string, const WCHAR* boxname, const WCHAR* setting, int pos, WCHAR* value, ULONG value_size);
SBIEDLL_EXPORT BOOLEAN SbieDll_CheckStringInList(const WCHAR* string, const WCHAR* boxname, const WCHAR* setting);
SBIEDLL_EXPORT BOOLEAN SbieDll_CheckStringInListA(const char* string, const WCHAR* boxname, const WCHAR* setting);

View File

@ -469,6 +469,8 @@ API_ARGS_BEGIN(API_OPEN_DYNAMIC_PORT_ARGS)
API_ARGS_FIELD(WCHAR*,port_name)
API_ARGS_FIELD(HANDLE,process_id)
API_ARGS_FIELD(WCHAR*,port_id)
API_ARGS_FIELD(ULONG,filter_num)
API_ARGS_FIELD(ULONG*,filter_ids)
API_ARGS_CLOSE(API_OPEN_DYNAMIC_PORT_ARGS)

View File

@ -34,6 +34,9 @@ typedef struct _IPC_DYNAMIC_PORT {
WCHAR wstrPortId[DYNAMIC_PORT_ID_CHARS];
WCHAR wstrPortName[DYNAMIC_PORT_NAME_CHARS];
ULONG FilterCount;
UCHAR FilterIDs[0];
} IPC_DYNAMIC_PORT;
typedef struct _IPC_DYNAMIC_PORTS {

View File

@ -220,8 +220,6 @@ _FX NTSTATUS Ipc_CheckPortRequest_LsaEP(
ULONG len = msg->u1.s1.DataLength;
UCHAR* ptr = (UCHAR*)((UCHAR*)msg + sizeof(PORT_MESSAGE));
int i = 0;
int rc = -2;
ProbeForRead(ptr, len, sizeof(WCHAR));

View File

@ -132,6 +132,9 @@ NTSTATUS Ipc_CheckPortRequest_PowerManagement(
NTSTATUS Ipc_CheckPortRequest_SpoolerPort(
PROCESS *proc, OBJECT_NAME_INFORMATION *Name, PORT_MESSAGE *msg);
NTSTATUS Ipc_CheckPortRequest_Dynamic(
PROCESS *proc, OBJECT_NAME_INFORMATION *Name, PORT_MESSAGE *msg);
static NTSTATUS Ipc_Api_GetRpcPortName_2(
PEPROCESS ProcessObject, WCHAR* pDstPortName);
@ -248,6 +251,8 @@ _FX NTSTATUS Ipc_CheckPortRequest(
status = Ipc_CheckPortRequest_PowerManagement(proc, Name, msg);
if (status == STATUS_BAD_INITIAL_PC)
status = Ipc_CheckPortRequest_SpoolerPort(proc, Name, msg);
if (status == STATUS_BAD_INITIAL_PC)
status = Ipc_CheckPortRequest_Dynamic(proc, Name, msg);
if (status == STATUS_BAD_INITIAL_PC)
status = STATUS_SUCCESS;
@ -650,7 +655,7 @@ _FX NTSTATUS Ipc_Api_OpenDynamicPort(PROCESS* proc, ULONG64* parms)
if (port == NULL)
{
port = Mem_AllocEx(Driver_Pool, sizeof(IPC_DYNAMIC_PORT), TRUE);
port = Mem_AllocEx(Driver_Pool, sizeof(IPC_DYNAMIC_PORT) + sizeof(UCHAR) * pArgs->filter_num.val, TRUE);
if (!port)
Log_Msg0(MSG_1104);
else
@ -661,6 +666,19 @@ _FX NTSTATUS Ipc_Api_OpenDynamicPort(PROCESS* proc, ULONG64* parms)
if (_wcsicmp(port->wstrPortId, L"spooler") == 0)
Ipc_Dynamic_Ports.pSpoolerPort = port;
port->FilterCount = pArgs->filter_num.val;
if (port->FilterCount > 0)
{
try {
ProbeForRead(pArgs->filter_ids.val, sizeof(UCHAR) * port->FilterCount, sizeof(UCHAR));
memcpy(port->FilterIDs, pArgs->filter_ids.val, sizeof(UCHAR) * port->FilterCount);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
status = GetExceptionCode();
}
}
if (NT_SUCCESS(status))
List_Insert_After(&Ipc_Dynamic_Ports.Ports, NULL, port);
}
}
@ -694,6 +712,84 @@ _FX NTSTATUS Ipc_Api_OpenDynamicPort(PROCESS* proc, ULONG64* parms)
}
//---------------------------------------------------------------------------
// Ipc_CheckPortRequest_Dynamic
//---------------------------------------------------------------------------
_FX NTSTATUS Ipc_CheckPortRequest_Dynamic(
PROCESS* proc, OBJECT_NAME_INFORMATION* Name, PORT_MESSAGE* msg)
{
NTSTATUS status = STATUS_BAD_INITIAL_PC;
if (Ipc_Dynamic_Ports.pPortLock)
{
KeEnterCriticalRegion();
ExAcquireResourceSharedLite(Ipc_Dynamic_Ports.pPortLock, TRUE);
//
// find the port
//
IPC_DYNAMIC_PORT* port = List_Head(&Ipc_Dynamic_Ports.Ports);
while (port)
{
if (_wcsicmp(Name->Name.Buffer, port->wstrPortName) == 0)
{
//
// examine message
//
status = STATUS_SUCCESS;
if (port->FilterCount > 0)
{
__try {
ProbeForRead(msg, sizeof(PORT_MESSAGE), sizeof(ULONG_PTR));
if (Driver_OsVersion >= DRIVER_WINDOWS_7) {
ULONG len = msg->u1.s1.DataLength;
UCHAR* ptr = (UCHAR*)((UCHAR*)msg + sizeof(PORT_MESSAGE));
ProbeForRead(ptr, len, sizeof(WCHAR));
UCHAR uMsg = ptr[20];
//
// apply filter
//
for (ULONG i = 0; i < port->FilterCount; i++) {
if (port->FilterIDs[i] == uMsg) {
status = STATUS_ACCESS_DENIED;
break;
}
}
//DbgPrint("%S message ID: %d (%d)\n", port->wstrPortId, uMsg, NT_SUCCESS(status));
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
status = GetExceptionCode();
}
}
break;
}
port = List_Next(port);
}
ExReleaseResourceLite(Ipc_Dynamic_Ports.pPortLock);
KeLeaveCriticalRegion();
}
return status;
}
//---------------------------------------------------------------------------
// Ipc_Api_GetDynamicPortFromPid
//---------------------------------------------------------------------------

View File

@ -68,8 +68,6 @@ _FX NTSTATUS Ipc_CheckPortRequest_Sam(
ULONG len = msg->u1.s1.DataLength;
UCHAR* ptr = (UCHAR*)((UCHAR*)msg + sizeof(PORT_MESSAGE));
int i = 0;
int rc = -2;
ProbeForRead(ptr, len, sizeof(WCHAR));

View File

@ -128,8 +128,8 @@ _FX NTSTATUS Ipc_CheckPortRequest_SpoolerPort(
ULONG len = msg->u1.s1.DataLength;
UCHAR* ptr = (UCHAR*)((UCHAR*)msg + sizeof(PORT_MESSAGE));
int i = 0;
int rc = -2;
//int i = 0;
//int rc = -2;
ProbeForRead(ptr, len, sizeof(WCHAR));

View File

@ -27,6 +27,8 @@
#include "core/dll/sbiedll.h"
#include "common/defines.h"
#include "core/drv/api_defs.h"
#include <vector>
#include "common/str_util.h"
//---------------------------------------------------------------------------
// Constructor
@ -84,6 +86,8 @@ MSG_HEADER *EpMapperServer::EpmapperGetPortNameHandler(MSG_HEADER *msg)
WCHAR pwszServiceName [81];
*pwszServiceName = 0;
WCHAR buf[MAX_PATH];
if (_wcsicmp(req->wszPortId, SPOOLER_PORT_ID) == 0) {
if (SbieApi_QueryConfBool(boxname, L"ClosePrintSpooler", FALSE))
return SHORT_REPLY(E_ACCESSDENIED);
@ -116,7 +120,6 @@ MSG_HEADER *EpMapperServer::EpmapperGetPortNameHandler(MSG_HEADER *msg)
return SHORT_REPLY(E_INVALIDARG);*/
else
{
WCHAR buf[MAX_PATH];
if (SbieDll_GetStringForStringList(req->wszPortId, boxname, L"RpcPortBindingIfId", buf, sizeof(buf)))
{
unsigned short uuid[37];
@ -223,14 +226,33 @@ MSG_HEADER *EpMapperServer::EpmapperGetPortNameHandler(MSG_HEADER *msg)
// So, since here we only open non critical ports, we will use PID 0 to open them globally
// instead of only for the one process. Todo: make it per sandbox instead
//
// Note: Filter is only support for globaly open ports, i.e. when process_id == 0
// Todo: Add per process ALPC message filter
//
std::vector<UCHAR> FilterIDs;
for (int i = 0; SbieDll_GetStringsForStringList(req->wszPortId, boxname, L"RpcPortFilter", i, buf, sizeof(buf)); i++)
{
WCHAR* test_value = NULL;
ULONG test_len = 0;
if (SbieDll_GetTagValue(buf, NULL, (const WCHAR**)&test_value, &test_len, L',')) {
test_value[test_len] = L'\0';
FilterIDs.push_back((UCHAR)_wtoi(test_value));
}
}
// Param 1 is dynamic port name (e.g. "LRPC-f760d5b40689a98168"), WCHAR[DYNAMIC_PORT_NAME_CHARS]
// Param 2 is the process PID for which to open the port, can be 0 when port is special
// Param 3 is the port type/identifier
rpl->h.status = SbieApi_Call(API_OPEN_DYNAMIC_PORT, 3,
// Param 4 Filter ID count, array count
// Param 5 Filter ID buffer, UCHAR Array
rpl->h.status = SbieApi_Call(API_OPEN_DYNAMIC_PORT, 5,
(ULONG_PTR)rpl->wszPortName,
(ULONG_PTR)0,
(ULONG_PTR)req->wszPortId);
(ULONG_PTR)req->wszPortId,
(ULONG_PTR)FilterIDs.size(), // count
(ULONG_PTR)FilterIDs.data());
}
return (MSG_HEADER *)rpl;

View File

@ -393,6 +393,16 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64EC'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\common\str_util.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|ARM64EC'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64EC'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|ARM64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\common\verify.c">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">NotUsing</PrecompiledHeader>

View File

@ -87,6 +87,9 @@
<ClCompile Include="..\..\common\rc4.c">
<Filter>common</Filter>
</ClCompile>
<ClCompile Include="..\..\common\str_util.c">
<Filter>common</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="misc.h" />

View File

@ -46,6 +46,8 @@ extern "C" {
#include "common/stream.c"
#include "common/str_util.c"
#include "common/verify.c"
#ifdef __cplusplus

View File

@ -3890,6 +3890,18 @@ UseRpcMgmtSetComTimeout=WINNSI.DLL,n
RpcPortBinding=WinHttp.dll,'ncalrpc:',Resolve=WPAD,TimeOut=y
RpcPortBindingSvc=WPAD,WinHttpAutoProxySvc
#RpcPortFilter=WPAD,1,WinHttpResetAutoProxy
RpcPortFilter=WPAD,2,AutoProxySaveProxyCredentials
RpcPortFilter=WPAD,3,AutoProxyStoreSavedProxyCredentialsForClient
RpcPortFilter=WPAD,4,AutoProxyDeleteSavedProxyCredentials
#RpcPortFilter=WPAD,5,AutoProxyReindicateAllProxies
#RpcPortFilter=WPAD,6,ReadProxySettingsInternal
RpcPortFilter=WPAD,7,WinHttpWriteProxySettings
RpcPortFilter=WPAD,8,WinHttpSetProxySettingsPerUser
#RpcPortFilter=WPAD,9,WinHttpConnectionUpdateIfIndexTable
RpcPortFilter=WPAD,10,WinHttpConnectionSetPolicyEntries
RpcPortFilter=WPAD,11,WinHttpConnectionDeletePolicyEntries
# windows 10 game port
#Tmpl.ScanService=???
RpcPortBinding=resourcepolicyclient.dll,{00000000-0000-0000-0000-000000000000},Resolve=GamePort