Skip to content

Commit

Permalink
BreakoutProcess support
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidXanatos committed Jan 8, 2022
1 parent ade657b commit 0da573a
Show file tree
Hide file tree
Showing 7 changed files with 385 additions and 343 deletions.
6 changes: 5 additions & 1 deletion Sandboxie/core/dll/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -958,7 +958,11 @@ _FX BOOL Proc_CreateProcessInternalW(
resume_thread = TRUE;
dwCreationFlags |= CREATE_SUSPENDED;

dwCreationFlags &= ~CREATE_BREAKAWAY_FROM_JOB;
// no longer required see comment in GuiServer::GetJobObjectForAssign
//extern BOOLEAN SysInfo_UseSbieJob;
//if (SysInfo_UseSbieJob) {
// dwCreationFlags &= ~CREATE_BREAKAWAY_FROM_JOB;
//}


//
Expand Down
66 changes: 57 additions & 9 deletions Sandboxie/core/drv/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ static void Process_NotifyProcess(
#endif

static void Process_NotifyProcessEx(
HANDLE ParentId, HANDLE ProcessId, PPS_CREATE_NOTIFY_INFO CreateInfo);
PEPROCESS ParentId, HANDLE ProcessId, PPS_CREATE_NOTIFY_INFO CreateInfo);

static PROCESS *Process_Create(
HANDLE ProcessId, const BOX *box, const WCHAR *image_path,
HANDLE ProcessId, HANDLE StarterId, const BOX *box, const WCHAR *image_path,
KIRQL *out_irql);

static void Process_NotifyProcess_Delete(HANDLE ProcessId);
Expand Down Expand Up @@ -587,7 +587,7 @@ _FX void Process_CreateTerminated(HANDLE ProcessId, ULONG SessionId)


_FX PROCESS *Process_Create(
HANDLE ProcessId, const BOX *box, const WCHAR *image_path,
HANDLE ProcessId, HANDLE StarterId, const BOX *box, const WCHAR *image_path,
KIRQL *out_irql)
{
POOL *pool;
Expand Down Expand Up @@ -620,6 +620,7 @@ _FX PROCESS *Process_Create(
memzero(proc, sizeof(PROCESS));

proc->pid = ProcessId;
proc->starter_id = StarterId; // the pid of teh process that called CreateProcess, usually the parent
proc->pool = pool;

proc->box = Box_Clone(pool, box);
Expand Down Expand Up @@ -1164,14 +1165,37 @@ _FX BOOLEAN Process_NotifyProcess_Create(
ExReleaseResourceLite(Process_ListLock);
KeLowerIrql(irql);

//
// check if this process is set up as break out program,
// it must't be located in a sandboxed for this to work.
//

BOX* breakout_box = NULL;

if (box && Process_IsBreakoutProcess(box, ImagePath)) {

UNICODE_STRING image_uni;
RtlInitUnicodeString(&image_uni, ImagePath);
if (!Box_IsBoxedPath(box, file, &image_uni)) {

check_forced_program = TRUE; // the break out process of one mox may be the forced process of an otehr
breakout_box = box;
box = NULL;
}
}

//
// check forced processes
//

if (check_forced_program) {

//
// 4. if parent process is not in the dfp list, then
// check if it might be a forced process
//

box = Process_GetForcedStartBox(ProcessId, ParentId, ImagePath, FALSE);
box = Process_GetForcedStartBox(ProcessId, ParentId, ImagePath, FALSE, breakout_box ? breakout_box->sid : NULL);

if (box == (BOX *)-1) {

Expand All @@ -1185,7 +1209,7 @@ _FX BOOLEAN Process_NotifyProcess_Create(
}
else
{
box = Process_GetForcedStartBox(ProcessId, ParentId, ImagePath, TRUE);
box = Process_GetForcedStartBox(ProcessId, ParentId, ImagePath, TRUE, breakout_box ? breakout_box->sid : NULL);

if (box == (BOX *)-1) {

Expand All @@ -1202,6 +1226,24 @@ _FX BOOLEAN Process_NotifyProcess_Create(
}
}

//
// if this is a break out process and no other box clamed it as forced,
// set bHostInject and threat it accordingly, we need this in order for
// the custom SetInformationProcess call from CreateProcessInternalW to succeed
//

if (breakout_box) {
if (!box) {
bHostInject = TRUE;
add_process_to_job = FALSE;
box = breakout_box;
}
else {
Box_Free(breakout_box);
breakout_box = NULL;
}
}

//
// if parent is a sandboxed process but for some reason we don't
// have a box at this point, then terminate the new process
Expand Down Expand Up @@ -1244,7 +1286,7 @@ _FX BOOLEAN Process_NotifyProcess_Create(

if (box) {

PROCESS *new_proc = Process_Create(ProcessId, box, ImagePath, &irql);
PROCESS *new_proc = Process_Create(ProcessId, CallerId, box, ImagePath, &irql);
if (!new_proc) {

create_terminated = TRUE;
Expand All @@ -1262,8 +1304,12 @@ _FX BOOLEAN Process_NotifyProcess_Create(
new_proc->rights_dropped = parent_had_rights_dropped;
new_proc->forced_process = process_is_forced;

if (! bHostInject)
{
if (! bHostInject) {

//
// Notify the agent about the new process using a specialized silent message
//

WCHAR msg[48], *buf = msg;
RtlStringCbPrintfW(buf, sizeof(msg), L"%s%c%d", new_proc->box->name, L'\0', (ULONG)ParentId);
buf += wcslen(buf) + 1;
Expand All @@ -1272,8 +1318,11 @@ _FX BOOLEAN Process_NotifyProcess_Create(
if (! add_process_to_job)
new_proc->parent_was_sandboxed = TRUE;

add_process_to_job = TRUE; // we need this because of JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK used in GuiServer::GetJobObjectForAssign

//
// don't put the process into a job if OpenWinClass=*
// don't put the process into a job if NoSecurityIsolation=y
//

if (new_proc->open_all_win_classes || new_proc->bAppCompartment || Conf_Get_Boolean(new_proc->box->name, L"NoAddProcessToJob", 0, FALSE)) {
Expand All @@ -1291,7 +1340,6 @@ _FX BOOLEAN Process_NotifyProcess_Create(
new_proc->can_use_jobs = Conf_Get_Boolean(new_proc->box->name, L"AllowBoxedJobs", 0, FALSE);
}


//
// on Windows Vista, a forced process may start inside a
// Program Compatibility Assistant (PCA) job, if its parent
Expand Down
9 changes: 8 additions & 1 deletion Sandboxie/core/drv/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ struct _PROCESS {
// process id

HANDLE pid;
HANDLE starter_id;

// process pool. created on process creation. it is freed in its
// entirety when the process terminates
Expand Down Expand Up @@ -242,6 +243,10 @@ BOOLEAN Process_NotifyProcess_Create(
BOOLEAN Process_IsSameBox(PROCESS *proc, PROCESS *proc2, ULONG_PTR proc2_pid);


// Process_IsStarter returns TRUE if proc2 was started by proc1

BOOLEAN Process_IsStarter(PROCESS* proc1, PROCESS* proc2);

// Process_MatchImage: given an image name pattern 'pat_str', which
// may contain wild cards, tests the image name 'test_str' against
// the pattern. If 'pat_len' is specified, only the first 'pat_len'
Expand Down Expand Up @@ -382,8 +387,10 @@ NTSTATUS Process_GetSidStringAndSessionId(
// Get a box for a forced sandboxed process

BOX *Process_GetForcedStartBox(
HANDLE ProcessId, HANDLE ParentId, const WCHAR *ImagePath, BOOLEAN bHostInject);
HANDLE ProcessId, HANDLE ParentId, const WCHAR *ImagePath, BOOLEAN bHostInject, const WCHAR *pSidString);


BOOLEAN Process_IsBreakoutProcess(BOX *box, const WCHAR *ImagePath);

// Manipulation of the List of Disabled Forced Processes: (Process_List2)
// Add ProcessId to list if ParentId is already listed
Expand Down
Loading

0 comments on commit 0da573a

Please sign in to comment.