首页
社区
课程
招聘
[原创]Sandboxie隐形屏障:解密COM隔离机制
发表于: 2025-5-25 20:16 813

[原创]Sandboxie隐形屏障:解密COM隔离机制

2025-5-25 20:16
813

  时镜过迁,转眼即逝,基于Sandboxie意图快速构建解决方案,除了看源码,还可以借助AI学习,对于"技术老炮"游刃有余,每当有年轻朋友来寻找答案,总会多提一句,调试,实践,分享会有更多收获。
  本篇是关于COM隔离方案见解,COM和DCOM不是一回事,是包含关系,COM是标准,容易混淆概念,Sandboxie COM隔离也是非常复杂。
  DCOM是基于微软Component Object Model(COM)协议扩展,最早是用来跨网络对象通信,是一种跨主机的通信解决方案,经典应用包括打印机共享,WMI等。DCOM和RPC有关联?DCOM是基于RPC协议扩展,来传递对象引用,需要对Object Remote Procedure Call一起处理,这里表述两者因果关系。
  题外记,琐碎时间空隙,很多年前还在甲方实习,听到乙方大佬谈论RPC/COM逃逸提权,天方夜谭,无从下手,坚持,挣扎,放弃。

  编译部署或Github/官方下载安装程序,线上版安装到本地,把自己编译好的程序替换,附加调试。
  注意!基于Sandboxie-Plus版本调试驱动会有签名检测,替换SbieSvc启动会失败。

  驱动中有签名认证,SbieSvc初始化设置端口,签名检验失败,驱动返回STATUS_INVALID_SIGNATURE错误,SbieSvc服务会退出。

编码测试单元,能够在沙箱触发COM操作

  代码通过COM口打开IE对象并访问百度网站,RPC连接,沙箱中效果如下,Unit.exe COM操作被Sandbox重定向到沙箱内的DcomLaunch.exe,进程树清晰,SboxDcomLaunch和SandboxieRpcSs是父子进程关系,SboxDcomLaunch负责执行IE相关的操作。

  如何附加调试呢?先修改测试用例,main函数的地方添加暂停,程序被加载后先不调用COM口函数。

  SbieSvc,SbieDrv先要通过KmdUtil停止卸载,自编译程序SbieDrv.sys,SbieSvc.exe,SbieDll.dll,SandboxieDcomLaunch.exe和SandboxieRpcSs.exe替换至Sandbox目录,重新启动沙箱,加载编译后的组件。

  SbieDll工程附加到Unit.exe上,RPC和DCOM附加SandboxieRpcSs.exe
和SandboxieDcomLaunch.exe,这时候程序回车运行,开始动态调试。
  沙箱内进程通过LDR注入成功后,进程加载系统DLL会被SbieDLL感染,Unit.exe调用CoCreateInstance方法会被挂钩至SbieDLL!Com_CoCreateInstance,下断后Unit.exe中回车,如下图所示:

  Sandboxie RPC,COM处理分为两个步骤,重定向和隔离。沙箱通过SbieDll Hook进程RPC,COM相关API,将沙箱内进程请求重定向至SandboxieRpcSs进程,SandboxieRpcSs实现隔离,部分重定向操作等同于隔离,需要具体区分。

  SandboxieRpcSs是一个被遗忘的进程,以往的见解中,包括各类QQ群"老炮"给出的解决方案,对SandboxieRpcSs绝口不提,对于RPC特别喜欢把重定向和隔离的概念混淆,另外绕过重定向和绕过隔离也是两个概念,不能混为一谈。
  代码还没有运行,发现RpcSs和DcomLaunch进程已经启动,虽然SbieDll也有触发时机,并不是启动RPC最早的时机。

  沙箱内RPC进程通过SbieSvc.exe启动,SboxSvc中有处理COMProxy的模块。

  RpcSs启动失败会抛出2337的错误,Plus这个地方做了重试,会不停的启动RpcSs服务。
  epmapper是RPC架构服务之一,负责RPC动态端口分配的服务,可以列出公开接口。客户端请求RPC,这时候就会找epmapper来询问相关信息,epmapper返回给客户端正确的端口和数据。
  DCOM请求先要构造出来RPC服务,才能处理DCOM请求。SandboxieRpcSs是基础组件,沙箱内任何进程请求epmapper都应该先拉起SandboxieRpcSs进程,否则沙箱内肯定是处理不了RPC请求。
SandboxieRpcSs进程启动以后,关键逻辑如下:

  WinSxs全称叫Side by Side,负责管理组件版本,系统位置C:\Windows\WinSxS,Sxs是微软提出"并行组件存储"解决方案。简单理解WinSxs下可以同时保存多个副本VC++运行库,每个程序都用自己的DLL版本。复杂的COM应用中,为不同组件分配独立的激活上下文,避免全局DLL版本冲突。
  Sandbox启动RPCSS服务的时候,Sxs_Thread线程非常关键,目的是为了Sandbox沙箱提供隔离的组件版本管理,非常有意思的隔离方案。
  sxs.dll和ole32.dll动态库加载SxsGenerateActivationContext,CreateStreamOnHGlobal,基于SxsGenerateActivationContext确保插件依赖的正确版本DLL被加载,使用CreateStreamOnHGlobal将插件配置或资源数据封装为流,供COM组件安全使用。

  创建队列,接收沙盘请求SbieDll_QueueCreate,Sxs_Request处理,Sxs_Generate解析请求数据,比如清单/配置文件,语言,架构等等,用来生成上下文句柄,并通过pCreateStreamOnHGlobal创建ManifestStream,ConfigStream,创建IStream对象.

  Sxs_GenerateHelper版本差异化处理,根据Windows版本将ISteam对象填充SXS_GENERATE_ACTIVATION_CONTEXT_VISTA_ARGS结构,通过pSxsGenerateActivationContext生成hSection.

沙盒进程通过hSection映射私有组件数据,LPC将数据回包给RPCSS_SXS

  除了上述Sxs处理,还做了网络隔离,服务隔离,注册表权限模拟,StartRpcEptMapper和Service_Start_ServiceMain,分别创建了RpcEptMapper和RPCSS服务。
  RPCSS服务COM/DCOM的核心服务,处理对象激活请求、解析分布式组件分布式通信的基石,Win7以上系统,需要额外启动RpcEptMapper服务,用于管理RPC端点映射数据库,确保RPC接口标识符的正确解析,注册会被SCM Hook拦截进入到my_StartServiceCtrlDispatcherW启动。

  ServiceMain调用会触发RpcRt_RpcBindingFromStringBindingW和AlpcConnect,最终会通过Ipc_Start沙箱内部启动RpcSs服务。

  ncalrpc:[lsasspirpc]是LSASS(Local Security Authority Subsystem Service)进程关联,负责系统安全策略、用户认证(如 NTLM/Kerberos)、凭证管理等敏感操作。
  ncalrpc:[lsapolicylookup]用于LSA(Local Security Authority)策略查询,例如检查用户权限、安全组策略、域信任关系等。
  actkernel是启动SandboxieDcomLaunch定义的服务事件,并非RPC标准的功能。
  题外话,Mimikatz通过ncalrpc:[lsasspirpc]连接到 LSASS,调用 Lsapirpc 接口读取进程内存,提取明文密码或票据。

Rpcss服务的依赖关系

  DCOM Server Process Launcher负责启动和监控DCOM服务进程,按需激活DCOM对象,管理DCOM的进程周期,另外要与RPCSS服务协同工作,确保分布式跨进程/机器的通信。DCOM服务依赖于RPCSS的UUID解析,测试用例中调用了CoCreateInstance,就是激活了DCOM对象。
  See DoLingerLeader和linger.c文件,提供了一种LingerProcess机制来检测沙箱内服务,Add_LL_Entry将SandboxieDcomLaunch添加成LingerProcess,包括Crypto,BITS,WUAU等组件。

  ProcessStartMonitor线程监听SESSION_PROCESS事件,通过SbieApi_EnumProcessEx枚举沙盒内进程,有新进程调用AddPid注册进程句柄监控。

  RpcSs进程Hook_Service_Control_Manager对SCM服务进行了Hook,重定向到沙盒内部。

  沙箱内对CreateFileMappingW函数做了处理,创建共享内存区域ComPlusCOMRegTable,模拟DCOM注册表的全局状态。

  SandboxieRpcSs初始化成功以后,会向SbieSvc发送MSGID_SBIE_INI_RUN_SBIE_CTRL的消息事件。

  SandboxieDcomLaunch启动以后,对SCM,Token进行了HOOK,注册了DCOMLAUNCH的服务,模拟Dcom服务加载对应的请求,DcomLauncher本身没太多技术细节,不做详细分析。

  沙箱内进程COM请求重定向到RpcSs进程服务中,有很多种解决方案可以用,sandboxie这块做的也比较细化,有黑白名单的概念。

  CoCreateInstance/CoCreateInstanceEx:拦截对象创建,检查CLSID是否在允许列表,也可以阻止特定类实例化,如ClosedClsid直接返回失败。
  Com_IClassFactory_New使用自定义工厂实例化对象,转发请求到沙箱内进程。CoGetClassObject也需要做同样的处理,创建和获取都不会绕过沙箱对CLSID处理。

  沙箱没设置CLSID授权列表,测试用例创建和获取COM对象,不会执行Com_IClassFactory_New,直接调用系统函数__sys_CoCreateInstance,如何将请求重定向沙箱SandboxRpcSs进程呢?
  See Ipc_NtAlpcConnectPort,Unit进程请求了InternetExplorer.Application的实例,实例被转换成了CLSID,会触发\RPC Control\epmapper,如果是沙箱内进程epmapper请求,检测DocmLaunch注册表和DcomLaunch Event.

AlpcConnectPort将PortName修改成沙箱内的SboxName,\Sandbox\zy.chen\DefaultBox\Session_3\RPC Control\epmapper

  还有个概念,比如新的进程iexplore.exe进程会向RPCSS服务注册一个唯一的RPC端点,也会被重定向沙箱内,Ipc_NtAlpcCreatePort也会重定向到沙箱内路径。

  CoCreateInstance原理感兴趣朋友,可以基于combase.dll组件对CoCreateInstance流程IDA逆向下,也可以基于DeepSeek来分析下,坑肯定有的,把符号表和汇编输入,输出的结果如下:

  DeepSeek仅做参考,另一种快捷的梳理方式,基于vs2019可以直接栈回溯,这里在SbieDll!Alpc模块下断,Ipc_NtAlpcConnectPortEx栈回溯

  除了上面的Alpc Name重定向之外,上文提到SandboxieRpcSs Sxe_Thread线程会处理来自于沙箱内的Rpc_Sxs消息,处理Sandboxie Sxs请求。消息事件的生产者是进程调用Sxs_CreateActCtxW产生的Sxs数据,调用SbieDll!Sxs_CallService将进程Sxs请求转发至RpcSs中处理,端口是RPCS_SXS.

  RpcSs中Sxs_CreateActCtxW处理打印如下,Sxs隔离方案是非常重要的环节,也是对抗水位较高的地方。

  SbieDLL!Ipc_StartServer函数中对死锁和策略绕过有细节处理,CreateProcess启动流程复杂,内部会加载LoadLibrary,线程B已持有加载器锁,并等待SandboxieRpcSs启动完成,就会造成死锁。

  DLL初始化阶段,调用CreateProcess启动RPC进程可能会出现这种情况,Sandboxie通过SbieSvc ProcessServer来启动。
  SbieSvc服务发消息MSGID_PROCESS_RUN_SANDBOXED,通过SbieDll_RunSandboxed函数负责发送,Svc收到消息后处理,关于SRP和AppLocker策略绕过方案,也可以直接抄作业。

  还有两个关于COM API基本处理,CoMarshalInterface和CoUnmarshalInterface,msdn对两个函数介绍,通俗来讲是序列化和反序列化。

  接口封送:Com_CoMarshalInterface将COM接口指针序列化时,若目标上下文为跨沙箱,则生成指向沙箱代理的OBJREF,确保反序列化时在沙箱内重建,另外对ISearchNotifyInlineSite对象做了特殊处理。

  比如类型dwDestContext等于MSHCTX_DIFFERENTMACHINE,这是由宿主环境的epmapper生成,代理OBJERF数据构建,通过SbieDll_CallServer封送。

  接口解封:Com_CoUnmarshalInterface检测到外部封送数据时,通过COM_UNMARSHAL_INTERFACE_REQ请求SbieSvc在沙箱内解封,返回本地代理对象。

  Com_CoUnmarshalInterface Hook函数用来解决什么问题呢?是解决SbieSvc OXID解析冲突,Sandboxie对epmapper做了隔离,处理不了沙箱外的SbieSvc epmapper注册的OXID,如果解析失败返回OR_INVALID_OXID,回滚流的位置,调用Com_CoUnmarshalInterface_Common自定义处理。
  Com_CoUnmarshalInterface_Common自定义处理,构造COM_UNMARSHAL_INTERFACE_REQ请求,通过Com_CreateProxy发送SBieSvc来处理,将SbieSvc解析的数据,在接收objidx和封送数据,SbieSvc返回激活上下文数据映射到当前进程。

  Sandboxie还有很多细节处理,Rpc,Com Hook囊括了多数关键接口,篇幅长短,不一一完整列举,本篇基础加以代码动态调试,也许可以给大家带来更多见解和思路,文中难免有纰漏,多多包涵。

KmdUtil.exe install SbieSvc D:\Sandboxie-Plus\SbieSvc.exe type=own start=auto display="Sandboxie Service" group=UIGroup
KmdUtil.exe install SbieSvc D:\Sandboxie-Plus\SbieSvc.exe type=own start=auto display="Sandboxie Service" group=UIGroup
本地计算机 上的 Sandboxie Service 服务启动后停止。某些服务在未由其他服务或程序使用时将自动停止。
本地计算机 上的 Sandboxie Service 服务启动后停止。某些服务在未由其他服务或程序使用时将自动停止。
SbieSvc!API_SET_SERVICE_PORT
    SbieApi_Call(API_SET_SERVICE_PORT, 1, (ULONG_PTR)m_instance->m_PortHandle);
SbieDrv!MyIsCallerSigned
    NTSTATUS KphVerifyCurrentProcess();
 
    _FX BOOLEAN MyIsCallerSigned(void)
    {
        return TRUE; // 直接返回成功
        NTSTATUS status;
 
        // in test signing mode don't verify the signature
        if (Driver_OsTestSigning)
            return TRUE;
 
        status = KphVerifyCurrentProcess();
 
        //DbgPrint("Image Signature Verification result: 0x%08x\r\n", status);
 
        if (!NT_SUCCESS(status)) {
 
            //Log_Status(MSG_1330, 0, status);
 
            return FALSE;
        }
 
        return TRUE;
    }
SbieSvc!API_SET_SERVICE_PORT
    SbieApi_Call(API_SET_SERVICE_PORT, 1, (ULONG_PTR)m_instance->m_PortHandle);
SbieDrv!MyIsCallerSigned
    NTSTATUS KphVerifyCurrentProcess();
 
    _FX BOOLEAN MyIsCallerSigned(void)
    {
        return TRUE; // 直接返回成功
        NTSTATUS status;
 
        // in test signing mode don't verify the signature
        if (Driver_OsTestSigning)
            return TRUE;
 
        status = KphVerifyCurrentProcess();
 
        //DbgPrint("Image Signature Verification result: 0x%08x\r\n", status);
 
        if (!NT_SUCCESS(status)) {
 
            //Log_Status(MSG_1330, 0, status);
 
            return FALSE;
        }
 
        return TRUE;
    }
#include <Windows.h>
#include <comdef.h>
#include <taskschd.h>
#include <iostream>
#include <rpc.h>
 
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "rpcrt4.lib")
 
const RPC_WSTR RPC_INTERFACE_UUID = (RPC_WSTR)L"6d9c4bcf-7e20-46c0-8d3a-8cfeb5a59010";
 
void TriggerDCOMOperation() {
    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    if (FAILED(hr)) {
        return;
    }
 
    IWebBrowser2* pBrowser = nullptr;
    CLSID clsidIE;
 
    do {
        hr = CLSIDFromProgID(L"InternetExplorer.Application", &clsidIE);
        if (FAILED(hr)) {
            break;
        }
 
        hr = CoCreateInstance(
            clsidIE,
            nullptr,
            CLSCTX_LOCAL_SERVER,
            IID_IWebBrowser2,
            (void**)&pBrowser
        );
        if (FAILED(hr) || !pBrowser) {
            break;
        }
 
        hr = pBrowser->put_Visible(VARIANT_TRUE);
        if (FAILED(hr)) {
            break;
        }
        VARIANT url, flags, targetFrame, postData, headers;
        VariantInit(&url);
        VariantInit(&flags);
        VariantInit(&targetFrame);
        VariantInit(&postData);
        VariantInit(&headers);
        url.vt = VT_BSTR;
        url.bstrVal = SysAllocString(L"fd7K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8b7`.`.");
        flags.vt = VT_I4;
        flags.lVal = navNoHistory;
        hr = pBrowser->Navigate2(
            &url,          // URL
            &flags,        // Flags
            &targetFrame,  // Target frame
            &postData,     // Post data
            &headers       // Headers
        );
 
        // clear
        VariantClear(&url);
        VariantClear(&flags);
        VariantClear(&targetFrame);
        VariantClear(&postData);
        VariantClear(&headers);
        if (FAILED(hr)) {
            break;
        }
 
        system("pause");
    } while (false);
 
    if (pBrowser) {
        pBrowser->Release();
        pBrowser = nullptr;
    }
    CoUninitialize();
}
 
void TriggerRPCOperation() {
    RPC_STATUS status;
    RPC_WSTR szStringBinding = nullptr;
 
    status = RpcStringBindingCompose(
        RPC_INTERFACE_UUID,
        (RPC_WSTR)L"ncalrpc",
        nullptr,
        (RPC_WSTR)L"RpcTestPort",
        nullptr,
        &szStringBinding
    );
 
    if (status != RPC_S_OK) {
        std::cerr << "[-] rpc bind error " << status << std::endl;
        return;
    }
 
    RPC_BINDING_HANDLE hBinding = nullptr;
    status = RpcBindingFromStringBinding(szStringBinding, &hBinding);
    if (status == RPC_S_OK) {
        std::cout << "[+] rpc connect success. " << std::endl;
        RpcBindingFree(&hBinding);
    }
    else {
        std::cerr << "[-] rpc connect error: " << status << std::endl;
    }
 
    RpcStringFree(&szStringBinding);
}
 
int main() {
    std::cout << "[+] unit test create dcom object.\n" << std::endl;
 
    TriggerDCOMOperation();
 
    std::cout << "[+] unit test connect rpc.\n" << std::endl;
    TriggerRPCOperation();
 
    system("pause");
    return 0;
}
 
void* __RPC_USER midl_user_allocate(size_t size) {
    return malloc(size);
}
 
void __RPC_USER midl_user_free(void* p) {
    free(p);
}
#include <Windows.h>
#include <comdef.h>
#include <taskschd.h>
#include <iostream>
#include <rpc.h>
 
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "rpcrt4.lib")
 
const RPC_WSTR RPC_INTERFACE_UUID = (RPC_WSTR)L"6d9c4bcf-7e20-46c0-8d3a-8cfeb5a59010";
 
void TriggerDCOMOperation() {
    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    if (FAILED(hr)) {
        return;
    }
 
    IWebBrowser2* pBrowser = nullptr;
    CLSID clsidIE;
 
    do {
        hr = CLSIDFromProgID(L"InternetExplorer.Application", &clsidIE);
        if (FAILED(hr)) {
            break;
        }
 
        hr = CoCreateInstance(
            clsidIE,
            nullptr,
            CLSCTX_LOCAL_SERVER,
            IID_IWebBrowser2,
            (void**)&pBrowser
        );
        if (FAILED(hr) || !pBrowser) {
            break;
        }
 
        hr = pBrowser->put_Visible(VARIANT_TRUE);
        if (FAILED(hr)) {
            break;
        }
        VARIANT url, flags, targetFrame, postData, headers;
        VariantInit(&url);
        VariantInit(&flags);
        VariantInit(&targetFrame);
        VariantInit(&postData);
        VariantInit(&headers);
        url.vt = VT_BSTR;
        url.bstrVal = SysAllocString(L"fd7K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8b7`.`.");
        flags.vt = VT_I4;
        flags.lVal = navNoHistory;
        hr = pBrowser->Navigate2(
            &url,          // URL
            &flags,        // Flags
            &targetFrame,  // Target frame
            &postData,     // Post data
            &headers       // Headers
        );
 
        // clear
        VariantClear(&url);
        VariantClear(&flags);
        VariantClear(&targetFrame);
        VariantClear(&postData);
        VariantClear(&headers);
        if (FAILED(hr)) {
            break;
        }
 
        system("pause");
    } while (false);
 
    if (pBrowser) {
        pBrowser->Release();
        pBrowser = nullptr;
    }
    CoUninitialize();
}
 
void TriggerRPCOperation() {
    RPC_STATUS status;
    RPC_WSTR szStringBinding = nullptr;
 
    status = RpcStringBindingCompose(
        RPC_INTERFACE_UUID,
        (RPC_WSTR)L"ncalrpc",
        nullptr,
        (RPC_WSTR)L"RpcTestPort",
        nullptr,
        &szStringBinding
    );
 
    if (status != RPC_S_OK) {
        std::cerr << "[-] rpc bind error " << status << std::endl;
        return;
    }
 
    RPC_BINDING_HANDLE hBinding = nullptr;
    status = RpcBindingFromStringBinding(szStringBinding, &hBinding);
    if (status == RPC_S_OK) {
        std::cout << "[+] rpc connect success. " << std::endl;
        RpcBindingFree(&hBinding);
    }
    else {
        std::cerr << "[-] rpc connect error: " << status << std::endl;
    }
 
    RpcStringFree(&szStringBinding);
}
 
int main() {
    std::cout << "[+] unit test create dcom object.\n" << std::endl;
 
    TriggerDCOMOperation();
 
    std::cout << "[+] unit test connect rpc.\n" << std::endl;
    TriggerRPCOperation();
 
    system("pause");
    return 0;
}
 
void* __RPC_USER midl_user_allocate(size_t size) {
    return malloc(size);
}
 
void __RPC_USER midl_user_free(void* p) {
    free(p);
}
int main() {
    std::cout << "[+] unit test create dcom object.\n" << std::endl;
    // 调试缓冲,不要直接运行代码
    system("pause");
    TriggerDCOMOperation();
 
    std::cout << "[+] unit test connect rpc.\n" << std::endl;
    TriggerRPCOperation();
    system("pause");
     
    return 0;
}
int main() {
    std::cout << "[+] unit test create dcom object.\n" << std::endl;
    // 调试缓冲,不要直接运行代码
    system("pause");
    TriggerDCOMOperation();
 
    std::cout << "[+] unit test connect rpc.\n" << std::endl;
    TriggerRPCOperation();
    system("pause");
     
    return 0;
}
KmdUtil stop SbieSvc
KmdUtil stop SbieDrv
KmdUtil delete SbieSvc
KmdUtil delete SbieDrv
sc query SbieSvc & sc query SbieDrv
KmdUtil stop SbieSvc
KmdUtil stop SbieDrv
KmdUtil delete SbieSvc
KmdUtil delete SbieDrv
sc query SbieSvc & sc query SbieDrv
SbieDll!Dll_InitExeEntry --> SbieDll!SbieDll_StartCOM --> SbieDll!Ipc_StartServer
SbieDll!Dll_InitExeEntry --> SbieDll!SbieDll_StartCOM --> SbieDll!Ipc_StartServer
// Start Inject
"D:\Sandboxie-Plus\Start.exe" /env:00000000_SBIE_CURRENT_DIRECTORY="D:\Sandboxie-Plus" /env:=Refresh E:\Sandboxie_Hook\x64\Release\Unit.exe
// Start Rpc
"D:\Sandboxie-Plus\SandboxieRpcSs.exe" 00000000_SBIE_ALL_USERS=\Device\HarddiskVolume3\ProgramData
// Start Inject
"D:\Sandboxie-Plus\Start.exe" /env:00000000_SBIE_CURRENT_DIRECTORY="D:\Sandboxie-Plus" /env:=Refresh E:\Sandboxie_Hook\x64\Release\Unit.exe
// Start Rpc
"D:\Sandboxie-Plus\SandboxieRpcSs.exe" 00000000_SBIE_ALL_USERS=\Device\HarddiskVolume3\ProgramData
SbieSvc.exe!RunSandboxedStartProcess
        // check if we are starting rpcss or dcomlaunch
        else if ((service = wcscmp(cmd, L"*RPCSS*") == 0 ? L"RpcSs" : NULL, service)
              /*|| (service = wcscmp(cmd, L"*DCOM*") == 0 ? L"DcomLaunch" : NULL, service)*/) {
            WCHAR program[64];
            wcscpy(program, SANDBOXIE);
            wcscat(program, service);
            wcscat(program, L".exe");
 
            WCHAR homedir[MAX_PATH];
            SbieApi_GetHomePath(NULL, 0, homedir, MAX_PATH);
 
            cmd = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, 512 * sizeof(WCHAR));
            if (! cmd) {
                SetLastError(ERROR_ACCESS_DENIED);
                return FALSE;
            }
            _snwprintf(cmd, 512, L"\"%s\\%s\"", homedir, program);
            dir = NULL;
            CmdAltered = true;
        }
                bool bSession0 = (BoxNameOrModelPid > 0) && ((si->dwFlags & 0x80000000) != 0);
        if (bSession0) {
            OpenProcessToken(GetCurrentProcess(), TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ, &PrimaryTokenHandle);
        }
 
        // impersonate caller in case they have a different device map
        // with different drive mappings
        ok = DuplicateToken(PrimaryTokenHandle,
                            SecurityImpersonation,
                            &ImpersonationTokenHandle);
 
        if (bSession0) {
            CloseHandle(PrimaryTokenHandle);
            PrimaryTokenHandle = NULL;
        }
 
        if (ok)
            ok = SetThreadToken(NULL, ImpersonationTokenHandle);
 
        if (ok) {
 
            // create new process
            ok = CreateProcessAsUser(
                    PrimaryTokenHandle, NULL, cmd, NULL, NULL, FALSE,
                    crflags2, env, dir, si, pi);
            LastError = GetLastError();
        }
SbieSvc.exe!RunSandboxedStartProcess
        // check if we are starting rpcss or dcomlaunch
        else if ((service = wcscmp(cmd, L"*RPCSS*") == 0 ? L"RpcSs" : NULL, service)
              /*|| (service = wcscmp(cmd, L"*DCOM*") == 0 ? L"DcomLaunch" : NULL, service)*/) {
            WCHAR program[64];
            wcscpy(program, SANDBOXIE);
            wcscat(program, service);
            wcscat(program, L".exe");
 
            WCHAR homedir[MAX_PATH];
            SbieApi_GetHomePath(NULL, 0, homedir, MAX_PATH);
 
            cmd = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, 512 * sizeof(WCHAR));
            if (! cmd) {
                SetLastError(ERROR_ACCESS_DENIED);
                return FALSE;
            }
            _snwprintf(cmd, 512, L"\"%s\\%s\"", homedir, program);
            dir = NULL;
            CmdAltered = true;
        }
                bool bSession0 = (BoxNameOrModelPid > 0) && ((si->dwFlags & 0x80000000) != 0);
        if (bSession0) {
            OpenProcessToken(GetCurrentProcess(), TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ, &PrimaryTokenHandle);
        }
 
        // impersonate caller in case they have a different device map
        // with different drive mappings
        ok = DuplicateToken(PrimaryTokenHandle,
                            SecurityImpersonation,
                            &ImpersonationTokenHandle);
 
        if (bSession0) {
            CloseHandle(PrimaryTokenHandle);
            PrimaryTokenHandle = NULL;
        }
 
        if (ok)
            ok = SetThreadToken(NULL, ImpersonationTokenHandle);
 
        if (ok) {
 
            // create new process
            ok = CreateProcessAsUser(
                    PrimaryTokenHandle, NULL, cmd, NULL, NULL, FALSE,
                    crflags2, env, dir, si, pi);
            LastError = GetLastError();
        }
Sxs_Thread
SbieDll_IsOpenCOM
 --> Hook_Service_Control_Manager
 --> Hook CreateFileMappingW
 --> Hook_Privilege
 --> Start_WinSock
 --> StartRpcEptMapper
 --> Service_Start_ServiceMain
Dde_Thread
  --> CreateWindows - RegisterClass - Sandboxie_DDE_ProxyClass1
Sxs_Thread
SbieDll_IsOpenCOM
 --> Hook_Service_Control_Manager
 --> Hook CreateFileMappingW
 --> Hook_Privilege
 --> Start_WinSock
 --> StartRpcEptMapper
 --> Service_Start_ServiceMain
Dde_Thread
  --> CreateWindows - RegisterClass - Sandboxie_DDE_ProxyClass1
while (!mod && (retry++ < 20)) {
    mod = LoadLibrary(L"sxs.dll");
    if (!mod) {
        NtYieldExecution();
    }
}
if (mod) {
    pSxsGenerateActivationContext = (P_SxsGenerateActivationContext)
        GetProcAddress(mod, "SxsGenerateActivationContext");
}
else {
    Sxs_Error(0x77, status);
    return FALSE;
}
mod = 0;
retry = 0;
while (!mod && (retry++ < 20)) {
    mod = LoadLibrary(L"ole32.dll");
    if (!mod) {
        NtYieldExecution();
    }
}
if (mod) {
    pCreateStreamOnHGlobal = (P_CreateStreamOnHGlobal)
        GetProcAddress(mod, "CreateStreamOnHGlobal");
}
else {
    Sxs_Error(0x88, status);
    return FALSE;
}
while (!mod && (retry++ < 20)) {
    mod = LoadLibrary(L"sxs.dll");
    if (!mod) {
        NtYieldExecution();
    }
}
if (mod) {
    pSxsGenerateActivationContext = (P_SxsGenerateActivationContext)
        GetProcAddress(mod, "SxsGenerateActivationContext");
}
else {
    Sxs_Error(0x77, status);
    return FALSE;
}
mod = 0;
retry = 0;
while (!mod && (retry++ < 20)) {
    mod = LoadLibrary(L"ole32.dll");
    if (!mod) {
        NtYieldExecution();
    }
}
if (mod) {
    pCreateStreamOnHGlobal = (P_CreateStreamOnHGlobal)
        GetProcAddress(mod, "CreateStreamOnHGlobal");
}
else {
    Sxs_Error(0x88, status);
    return FALSE;
}
if (*lpManifestText) {
    args.ManifestStream = Sxs_CreateStreamFromBuffer(lpManifestText);
    if (! args.ManifestStream)
        ok = FALSE;
} else
    ok = FALSE;
 
if (ok && *lpConfigPath && *lpConfigText) {
    args.ConfigPath   = lpConfigPath;
    args.ConfigStream = Sxs_CreateStreamFromBuffer(lpConfigText);
    if (! args.ConfigStream)
        ok = FALSE;
}
if (*lpManifestText) {
    args.ManifestStream = Sxs_CreateStreamFromBuffer(lpManifestText);
    if (! args.ManifestStream)
        ok = FALSE;
} else
    ok = FALSE;
 
if (ok && *lpConfigPath && *lpConfigText) {
    args.ConfigPath   = lpConfigPath;
    args.ConfigStream = Sxs_CreateStreamFromBuffer(lpConfigText);
    if (! args.ConfigStream)
        ok = FALSE;
}
if (Sxs_WindowsVista || Sxs_Windows7 || Sxs_Windows8 || Sxs_Windows10) {
 
    WCHAR *ptr = LangNames;
    while (*ptr) {
        if (*ptr == L'_')
            *ptr = L'\0';
        ++ptr;
    }
 
    memzero(&vista_args, sizeof(vista_args));
 
    vista_args.ArchId           = args->ArchId;
    vista_args.LangNames        = LangNames;
    vista_args.StoreDir         = args->StoreDir;
    vista_args.ManifestStream   = args->ManifestStream;
    vista_args.SourcePath       = args->SourcePath;
    vista_args.Two              = args->Two;
    vista_args.ConfigStream     = args->ConfigStream;
    vista_args.ConfigPath       = args->ConfigPath;
 
    if (pSxsGenerateActivationContext((void *)&vista_args)) {
 
        if (Sxs_WindowsVista)
            args->hSection = vista_args.hSectionVista;
 
        else if (Sxs_Windows7)
            args->hSection = vista_args.hSectionWin7;
 
        else if (Sxs_Windows8 || Sxs_Windows10)
            args->hSection = vista_args.hSectionWin8;
 
        else
            args->hSection = NULL;
 
        if (! args->hSection) {
            // in the esoteric case where pSxsGenerateActivationContext
            // returns success but zero section, we want to signal to
            // Sxs_CallService in core/dll/sxs.c to try alternate call
            args->hSection = (HANDLE)(ULONG_PTR)-1;
        }
 
    } else
        args->hSection = NULL;
 
} else {
 
    if (! pSxsGenerateActivationContext(args))
        args->hSection = NULL;
}
if (Sxs_WindowsVista || Sxs_Windows7 || Sxs_Windows8 || Sxs_Windows10) {
 
    WCHAR *ptr = LangNames;
    while (*ptr) {
        if (*ptr == L'_')
            *ptr = L'\0';
        ++ptr;
    }
 
    memzero(&vista_args, sizeof(vista_args));
 
    vista_args.ArchId           = args->ArchId;
    vista_args.LangNames        = LangNames;
    vista_args.StoreDir         = args->StoreDir;
    vista_args.ManifestStream   = args->ManifestStream;
    vista_args.SourcePath       = args->SourcePath;
    vista_args.Two              = args->Two;
    vista_args.ConfigStream     = args->ConfigStream;
    vista_args.ConfigPath       = args->ConfigPath;
 
    if (pSxsGenerateActivationContext((void *)&vista_args)) {
 
        if (Sxs_WindowsVista)
            args->hSection = vista_args.hSectionVista;
 
        else if (Sxs_Windows7)
            args->hSection = vista_args.hSectionWin7;
 
        else if (Sxs_Windows8 || Sxs_Windows10)
            args->hSection = vista_args.hSectionWin8;
 
        else
            args->hSection = NULL;
 
        if (! args->hSection) {
            // in the esoteric case where pSxsGenerateActivationContext
            // returns success but zero section, we want to signal to
            // Sxs_CallService in core/dll/sxs.c to try alternate call
            args->hSection = (HANDLE)(ULONG_PTR)-1;
        }
 
    } else
        args->hSection = NULL;
 
} else {
 
    if (! pSxsGenerateActivationContext(args))
        args->hSection = NULL;
}
status = NtMapViewOfSection(
    hSection, NtCurrentProcess(), &MappedBase,
    0, 0, &ZeroOffset, &ViewSize, xViewShare,
    MEM_PHYSICAL, PAGE_READONLY);
 
if (NT_SUCCESS(status)) {
 
    UCHAR *data = HeapAlloc(GetProcessHeap(), 0, ViewSize);
    if (data) {
 
        memcpy(data, MappedBase, ViewSize);
        *rsp_len = (ULONG)ViewSize;
        *rsp_data = data;
    }
 
    NtUnmapViewOfSection(NtCurrentProcess(), (void *)MappedBase);
}
 
CloseHandle(hSection);
status = NtMapViewOfSection(
    hSection, NtCurrentProcess(), &MappedBase,
    0, 0, &ZeroOffset, &ViewSize, xViewShare,
    MEM_PHYSICAL, PAGE_READONLY);
 
if (NT_SUCCESS(status)) {
 
    UCHAR *data = HeapAlloc(GetProcessHeap(), 0, ViewSize);
    if (data) {
 
        memcpy(data, MappedBase, ViewSize);
        *rsp_len = (ULONG)ViewSize;
        *rsp_data = data;
    }
 
    NtUnmapViewOfSection(NtCurrentProcess(), (void *)MappedBase);
}
 
CloseHandle(hSection);
// win7
StartRpcEptMapper() {
    wcscpy(ServiceName2, L"RpcEptMapper");
    swprintf(EventName, SBIE_BOXED_ L"ServiceInitComplete_%s", ServiceName2);
    hEvent = CreateEvent(NULL, TRUE, FALSE, EventName);
    if (! hEvent)
        return FALSE;
    ok = Service_Start_ServiceMain(
                ServiceName2, L"rpcepmap.dll", "ServiceMain", TRUE);
}
 
wcscpy(ServiceName, L"RPCSS");
ok = Service_Start_ServiceMain(
    ServiceName, L"rpcss.dll", "ServiceMain", TRUE);
// win7
StartRpcEptMapper() {
    wcscpy(ServiceName2, L"RpcEptMapper");
    swprintf(EventName, SBIE_BOXED_ L"ServiceInitComplete_%s", ServiceName2);
    hEvent = CreateEvent(NULL, TRUE, FALSE, EventName);
    if (! hEvent)
        return FALSE;
    ok = Service_Start_ServiceMain(
                ServiceName2, L"rpcepmap.dll", "ServiceMain", TRUE);
}
 
wcscpy(ServiceName, L"RPCSS");
ok = Service_Start_ServiceMain(
    ServiceName, L"rpcss.dll", "ServiceMain", TRUE);
BOOL my_StartServiceCtrlDispatcherW(
    const LPSERVICE_TABLE_ENTRY lpServiceTable)
{
    LPTSTR parms[1];
    LPSERVICE_MAIN_FUNCTION ServiceMain;
 
    SERVICE_TABLE_ENTRY *entry = lpServiceTable;
    while (entry->lpServiceName) {
 
        ServiceMain = entry->lpServiceProc;
        parms[0] = entry->lpServiceName;
        ServiceMain(1, parms);
 
        ++entry;
    }
 
    return 1;
}
BOOL my_StartServiceCtrlDispatcherW(
    const LPSERVICE_TABLE_ENTRY lpServiceTable)
{
    LPTSTR parms[1];
    LPSERVICE_MAIN_FUNCTION ServiceMain;
 
    SERVICE_TABLE_ENTRY *entry = lpServiceTable;
    while (entry->lpServiceName) {
 
        ServiceMain = entry->lpServiceProc;
        parms[0] = entry->lpServiceName;
        ServiceMain(1, parms);
 
        ++entry;
    }
 
    return 1;
}
NtAlpcConnectPortEx --> Ipc_StartServer
ncalrpc:[lsasspirpc] -- \RPC Control\lsasspirpc -- \Sandbox\DefaultBox\Session_3\RPC Control\lsasspirpc
ncalrpc:[lsapolicylookup] -- \RPC Control\lsapolicylookup -- \Sandbox\DefaultBox\Session_3\RPC Control\lsapolicylookup
ncalrpc:[lsapolicylookup] -- \RPC Control\actkernel -- \Sandbox\DefaultBox\Session_3\RPC Control\actkernel
NtAlpcConnectPortEx --> Ipc_StartServer
ncalrpc:[lsasspirpc] -- \RPC Control\lsasspirpc -- \Sandbox\DefaultBox\Session_3\RPC Control\lsasspirpc
ncalrpc:[lsapolicylookup] -- \RPC Control\lsapolicylookup -- \Sandbox\DefaultBox\Session_3\RPC Control\lsapolicylookup
ncalrpc:[lsapolicylookup] -- \RPC Control\actkernel -- \Sandbox\DefaultBox\Session_3\RPC Control\actkernel
SERVICE_NAME: Rpcss
        TYPE               : 20  WIN32_SHARE_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : C:\Windows\system32\svchost.exe -k rpcss -p
        LOAD_ORDER_GROUP   : COM Infrastructure
        TAG                : 0
        DISPLAY_NAME       : Remote Procedure Call (RPC)
        DEPENDENCIES       : RpcEptMapper
                           : DcomLaunch
        SERVICE_START_NAME : NT AUTHORITY\NetworkService
SERVICE_NAME: Rpcss
        TYPE               : 20  WIN32_SHARE_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : C:\Windows\system32\svchost.exe -k rpcss -p
        LOAD_ORDER_GROUP   : COM Infrastructure
        TAG                : 0
        DISPLAY_NAME       : Remote Procedure Call (RPC)
        DEPENDENCIES       : RpcEptMapper
                           : DcomLaunch
        SERVICE_START_NAME : NT AUTHORITY\NetworkService
Add_LL_Entry(lingers, &linger_count, _SandboxieDcomLaunch);
Add_LL_Entry(lingers, &linger_count, _SandboxieCrypto);
Add_LL_Entry(lingers, &linger_count, _SandboxieBITS);
Add_LL_Entry(lingers, &linger_count, _SandboxieWUAU);
Add_LL_Entry(lingers, &linger_count, _wuauclt);
Add_LL_Entry(lingers, &linger_count, _TrustedInstaller);
Add_LL_Entry(lingers, &linger_count, _tiworker);
Add_LL_Entry(lingers, &linger_count, _SandboxieDcomLaunch);
Add_LL_Entry(lingers, &linger_count, _SandboxieCrypto);
Add_LL_Entry(lingers, &linger_count, _SandboxieBITS);
Add_LL_Entry(lingers, &linger_count, _SandboxieWUAU);
Add_LL_Entry(lingers, &linger_count, _wuauclt);
Add_LL_Entry(lingers, &linger_count, _TrustedInstaller);
Add_LL_Entry(lingers, &linger_count, _tiworker);
heventRpcSs = CreateEvent(0, FALSE, FALSE, NULL);
HANDLE ThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ProcessStartMonitor, NULL, 0, NULL);
if (ThreadHandle)
    CloseHandle(ThreadHandle);
heventRpcSs = CreateEvent(0, FALSE, FALSE, NULL);
HANDLE ThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ProcessStartMonitor, NULL, 0, NULL);
if (ThreadHandle)
    CloseHandle(ThreadHandle);
for (i = 0; ; ++i) {
 
    rc = SbieApi_QueryConfAsIs(
        NULL, L"StartService", i, image, sizeof(WCHAR) * 120);
    if (rc != 0)
        break;
 
    SbieDll_StartBoxedService(image, TRUE);
}
for (i = 0; ; ++i) {
 
    rc = SbieApi_QueryConfAsIs(
        NULL, L"StartService", i, image, sizeof(WCHAR) * 120);
    if (rc != 0)
        break;
 
    SbieDll_StartBoxedService(image, TRUE);
}
HOOK_WIN32(CreateFileMappingW) --> my_CreateFileMappingW()
Name: Global\ComPlusCOMRegTable
 
ComPlusCOMRegTable = CreateFileMapping(
INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT,
0, (PAGE_SIZE * 2), ComPlusCOMRegTable_Name);
 
_FX HANDLE my_CreateFileMappingW(
    HANDLE hFile,
    LPSECURITY_ATTRIBUTES lpAttributes,
    DWORD flProtect,
    DWORD dwMaximumSizeHigh,
    DWORD dwMaximumSizeLow,
    LPCWSTR lpName)
{
    typedef HANDLE (__stdcall *P_CreateFileMappingW)(
        HANDLE hFile,
        LPSECURITY_ATTRIBUTES lpAttributes,
        DWORD flProtect,
        DWORD dwMaximumSizeHigh,
        DWORD dwMaximumSizeLow,
        LPCWSTR lpName);
 
    HANDLE handle = 0;
 
    if (lpName && _wcsicmp(lpName, ComPlusCOMRegTable_Name) == 0)
        handle = ComPlusCOMRegTable;
 
    if (! handle) {
        handle = ((P_CreateFileMappingW)__sys_CreateFileMappingW)(
            hFile, lpAttributes, flProtect,
            dwMaximumSizeHigh, dwMaximumSizeLow, lpName);
    }
 
    return handle;
}
HOOK_WIN32(CreateFileMappingW) --> my_CreateFileMappingW()
Name: Global\ComPlusCOMRegTable
 
ComPlusCOMRegTable = CreateFileMapping(
INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT,
0, (PAGE_SIZE * 2), ComPlusCOMRegTable_Name);
 
_FX HANDLE my_CreateFileMappingW(
    HANDLE hFile,
    LPSECURITY_ATTRIBUTES lpAttributes,
    DWORD flProtect,
    DWORD dwMaximumSizeHigh,
    DWORD dwMaximumSizeLow,
    LPCWSTR lpName)
{
    typedef HANDLE (__stdcall *P_CreateFileMappingW)(

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2025-5-27 09:05 被一半人生编辑 ,原因:
收藏
免费 3
支持
分享
最新回复 (1)
雪    币: 5564
活跃值: (4573)
能力值: ( LV13,RANK:300 )
在线值:
发帖
回帖
粉丝
2
刚想写这篇文章来着,
2025-5-26 09:56
0
游客
登录 | 注册 方可回帖
返回