Windows遗产之RPC/DCOM:还在用吗,内部又有什么区别?

从原理和使用程度上看,微软没有必要,也的确没有要废弃RPC/DCOM的迹象,但是显然这些技术会长期退入幕后当作基础设施了。

他们都是跨进程间的通信的(跨机器自然也算是也),无非就是寻找接口,数据序列化反序列化,但他们的确是最高效的。

广为人知的point:

  • RPC是基础。DCOM可以看成RPC的C++版。

  • RPC/DCOM在本机使用时主要是依靠LPC Port(而他又使用共享内存,queue等东西)。用WinObj工具能够看到各种ALPC类型的东西,其中就有很多是RPC/DCOM生成的。

  • 这类东西,别的系统里也有,例如Android里的Binder,非常类似于DCOM,只不过仅限于本机而已。而Mac OS X里也有XPC Service,NSProxy/NSConnection之类的。

不够广为人知的point:

  • RPC可以通过文件共享协议(SMB)来调用,也就是TCP端口445。这是SMB协议为RPC开的一个扩展。这时,RPC的认证也就委托给SMB了,这其实很方便实用。

  • RPC在本机的使用非常频繁,但在跨机器间的使用较少,几乎只限于微软做的服务(例如计算机管理,远程注册表...)。

  • 通过注册表把普通组件升级成DCOM组件的使用方式实际存在很多。

  • 在跨机器场景里,DCOM和RPC的认证方式,通信端口不一样。RPC/DCOM本身的认证方式不方便。

  • 每次看到DllHost.exe启动了,就说明有DCOM组件被启动了,而且是Dll组件升级的那种。

本机内RPC/DCOM使用例

  • 各种服务通过原始RPC提供基本控制接口,就是sc命令那套。还有很多系统服务提供额外接口,例如Registry,Netlogon,Firewall,Service Control,SQL Server... ,具体RPC接口信息可以在msdn里有(检索rpc找到相应的服务,然后可以概括看看idl,例如netlogon的idl)。

    有工具例如rpcdump,rpcdump.py,ifids,portqry可以列出本机或者远程机器上所有活动的RPC接口:

    ... ... 
    
    [MS-RSP]: Remote Shutdown Protocol 
    [MS-TSCH]: Task Scheduler Service Remoting Protocol 
    [MS-TSCH]: Task Scheduler Service Remoting Protocol 
    [MS-TSCH]: Task Scheduler Service Remoting Protocol 
    [MS-EVEN6]: EventLog Remoting Protocol 
    Adh APIs
    AppInfo
    Base Firewall Engine API
    DHCP Client LRPC Endpoint
    DHCPv6 Client LRPC Endpoint
    DfsDs service
    EFSK RPC Interface
    Event log TCPIP
    Fw APIs
    Group Policy RPC Interface
    IP Transition Configuration endpoint
    IdSegSrv service
    Impl friendly name
    KeyIso
    LicenseManager
    NRP server endpoint
    NSI server endpoint
    NetSetup API
    Ngc Pop Key Service
    Proxy Manager client server endpoint
    Proxy Manager provider server endpoint
    Secure Desktop LRPC interface
    Security Center
    UserMgrCli
    WM_WindowManagerRPC\Server
    WinHttp Auto-Proxy Service
    Witness Client Test Interface
    Witness Client Upcall Server
    XactSrv service
    ...
    
    Received 499 endpoints.
  • Component Services工具(运行comexp.msc或者DCOMCnfg)列出了很多DCOM组件,包括COM+ Applications里的一部分。

    我曾经好奇DCOMCnfg->My Computer->Property->“Launch Permissions->Edit Limits是干什么用的,我把所有的ACL(权限控制)都给删除了,结果系统几乎不能操作了!后来明白那是一个“最大”权限定义)。

    Windows遗产之RPC/DCOM:还在用吗,内部又有什么区别?_第1张图片

  • 具体点,Excel,Internet Explorer,Visual Studio... 他们都提供了DCOM组件,所以才能自动化遥控操作。

    Windows遗产之RPC/DCOM:还在用吗,内部又有什么区别?_第2张图片

  • 还有,各种DllHost.exe进程都是DCOM。

    Windows遗产之RPC/DCOM:还在用吗,内部又有什么区别?_第3张图片

    系统里经常会运行DllHost.exe,这是一个泛用的DCOM套子,把普通的COM组件包在里面运行,而利用者那边不需要意识到,仍然像以前一样利用组件,系统会自动提供虚拟的组件来做跨进程通信。用Process Explorer工具看看这些DllHost.exe进程的命令行,里面包含了AppID,再拿着他到注册表里找找就知道包含的组件是什么了。

    例如,Explorer里的一部分Shell Extension,例如文件属性对话框组件,以前使用的是普通的组件方式,即调入Exploer进程内部来使用,后来为了安全性,越来越多的把Shell Extension组件隔离到单独的DllHost进程了,就是升级成DCOM了。

    具体的做法仅仅是向组件的注册表信息里增加AppID设定。不光是Explorer,其实IE或者其它的系统程序有时为了安全都这样配置组件。

    实际上,我按照上面的Link结合这个Link折腾了一阵子发现:单单修改这些注册表并不自动起作用!还要改一丁点代码。创建组件时,需要指定明确的标记:CLSCTX_LOCAL_SERVER。后来发现的确也有人发现这个现象。

跨机器RPC/DCOM使用例

  • 远程管理工具,例如:计算机管理,注册表,sc.exe,psexec.exe,都可以管理别的机器。其底层是通过RPC over SMB做的,更具体点,就是通过文件共享服务的TCP端口445。 但这些不是DCOM,仅仅是原始的RPC。代码例:DNSRPC over SMB。

    Windows遗产之RPC/DCOM:还在用吗,内部又有什么区别?_第4张图片

    C:¥> psexec ¥¥remote_machine -u user -p password cmd.exe
    C:¥> TASKLIST /S remote_machine /U username /P password
  • Domain服务器上提供了较多的原始RPC服务,直接通过TCP 135公开的(进一步会使用其它单独的port)。代码例:DNS RPC。

  • 遗憾,跨机器使用DCOM没找到什么实例。有个安全产品OPC跨机器使用了DCOM,可以看到配置是比较罗嗦的,认证方式,权限,用户,policy...。原因是他是通过原始的RPC端口TCP 135认证的,特别不便于从外部控制。

    一般RPC/DCOM跨机器调用时,有两种传输途径:

    • A: 通过默认的RPC接口查询端口(TCP135)。DCOM的CoCreateInstanceEx就是这么干的。

      恶心的是,在网络身份认证上,除非在客户端在代码里写好类型和用户密码,否则只能用当前用户身份,也就是说无法从外部控制通信隧道。DCOM也只是稍微从侧面提供了一点点认证后的身份利用方面的设定而已(通过DCOMCnfg设定里的Edit Limits最大权限配置)。

      所以比较现实的认证方式是,两台机器都加入domain,客户端机器使用domain用户登录,或者让两边都做相同的本地用户名称和密码。否则就只能干瞪眼被当作匿名用户,然后一般会得到拒绝访问的错误。看了这个帖子后我才停止追查。

    • B: 通过RPC over SMB(TCP port 445)。这是一些诸如sc,psexec的远程管理工具用的。

      在网络身份认证上,可以轻松地事先在Explorer或者net use命令行里认证远程机器(有密码输入对话框的),等于说是可以从外部事先建立一个隧道,两台机器不需要同属一个domain,用户可以自由设定。

      关于通过这种路径调用DCOM,可以先使用RPC的IRemoteActivator之类的接口,进一步启动任何DCOM组件,用的人很少,例子:DNSRPC over SMB。但我还没有完全做好这类实验,牵扯到一些安全设定。

    • 有个开源projet里提供了不少这方面的协议的python代码:impacket,当然metasploit里就更全了。

      还有一种通过HTTP调用的没研究,服务器端要额外安装一些东西,好啰嗦。

那COM+呢?

COM+是个更加晦涩混杂的技术,有一部分是DCOM。COM+的管理也是放在上面提到的Component Service工具里。

COM+实际上等同于微软拦截了COM底层API,一旦把普通组件登记到COM+里,那么当调用这些组件时,就会有不同的效果。COM+透明地实现了一下几个功能:

    • 组件进程独立化(通过DllHost.exe变成DCOM)。当然,这不是必须的,只是在把组件登记到COM+里时的选项。如果不选独立,那么就还是和普通组件一样在调用者进程里动作,只不过多了后面要说的几个额外的好处。

    • 组件内接口调用监视。

    • Transaction注入。让组件可以使用调用者本身拥有的Transaction。这个和TLS(Thread-Local-Storage)技术类似,在当前线程里藏一些Transaction关联信息。关键字:GetObjectContext。

  • COM+的使用很少,几乎只有IIS的ASP组件以及SENS服务在使用。

  • COM+的登记信息基本不放在注册表里,而是在C:¥Windows¥registration¥*里。

在组件进程独立化上,相比于依靠注册表添加AppID加上修改客户端代码的方法,COM+做地极好,完全不需要修改代码,却能强行改变所有利用处。我做过实验,把一个组件(例如Scripting.Dictionary)登记到COM+ Applications里(新作一个空的Server Application,然后忘其下的Components里引入既存组件),结果该组件就会被单独拎出来放在DllHost.exe里运行,调用者还是像以前一样Set obj = CreateObject(Scripting.Dictionary)就可以的。

Windows遗产之RPC/DCOM:还在用吗,内部又有什么区别?_第5张图片

另外,COM+的Library Application型我也试了试,就是依然让组件运行在调用者进程内部,只是可以监视其使用情况,能看到哪个方法在什么时候被调用的,什么时候结束的,还可以取消Transaction。

我在Windows 10上试了试依然是管用的。(只不过,有一点,向Components里添加时,如果按照添加新组件,那么在删除时会出错,这个估计是因为注册表的好多地方都是没有权限删除,哪怕是升级后的管理员,而是只有Trusted Installer才行。)

COM+的组件进程独立化、监视看起来很好用啊,但是在COM退入幕后的如今年代,其实也没什么大用了。

你可能感兴趣的:(windows,rpc,com+,DCOM)