请求者的安全注意事项

VSS 基础结构要求 VSS 请求者(例如备份应用程序)能够作为 COM 客户端和服务器运行。

作为服务器时,请求者公开一组 COM 回调接口,这些接口可从外部进程(例如编写器或 VSS 服务) )调用 (。 因此,请求者需要安全地管理哪些 COM 客户端能够对其进程进行传入 COM 调用。

同样,请求者可以充当由 VSS 编写器或 VSS 服务提供的 COM Api 的 COM 客户端。 请求者特定的安全设置必须允许来自请求者的传出 COM 调用连接到这些其他进程。

管理请求者安全问题的最简单机制涉及到正确选择运行它的用户帐户。

请求者通常需要在作为 Administrators 组或 Backup Operators 组成员的用户下运行,或以本地系统帐户身份运行。

默认情况下,当请求者充当 COM 客户端时,如果它不在这些帐户下运行,则任何 COM 调用都将自动使用 E _ ACCESSDENIED 拒绝,甚至无需获取 COM 方法实现。

禁用 COM 异常处理

开发请求者时,请设置 COM COMGLB _ EXCEPTION _ 不 _ HANDLE 全局选项标志,以禁用 com 异常处理。 执行此操作非常重要,因为 COM 异常处理可能会掩盖 VSS 应用程序中的错误。 屏蔽的错误会使进程处于不稳定且不可预测的状态,这可能导致损坏和挂起。 有关此标志的详细信息,请参阅 IGlobalOptions

设置请求者默认 COM 访问检查权限

请求者需要注意,当其进程充当服务器 (例如,允许编写器修改备份组件文档) 时,它们必须允许来自其他 VSS 参与者(如写入程序或 VSS 服务)的传入调用。

但是,默认情况下,Windows 进程将仅允许在同一登录会话下运行的 COM 客户端 (自 SID) 或在本地系统帐户下运行。 这是一个潜在的问题,因为这些默认值对于 VSS 基础结构来说是不够的。 例如,编写器可能作为 "备份操作员" 用户帐户运行,该帐户既不是与请求者进程相同的登录会话,也不是本地系统帐户。

若要处理这种类型的问题,每个 COM 服务器进程都可以进一步控制 RPC 或 COM 客户端是否允许在这种) 情况下,通过使用 CoInitializeSecurity 设置进程范围的 "默认 COM 访问检查权限" 来执行 (服务器所实现的 COM 方法。

请求者可以显式执行以下操作:

  • 允许所有进程访问调用请求者进程。

    此选项可能足以满足大多数请求者的需要,并由其他 COM 服务器使用-例如,所有基于 SVCHOST 的 Windows 服务都已使用此选项,默认情况下,所有 com + 服务都是如此。

    允许所有进程执行传入的 COM 调用不一定是安全漏洞。 作为 COM 服务器的请求者(如所有其他 COM 服务器)始终保留选项,以便在其进程中实现的每个 COM 方法上授权其客户端。

    请注意,默认情况下,由 VSS 实现的内部 COM 回调处于受保护状态。

    若要允许所有进程通过 COM 访问请求方,可以将 NULL 安全描述符作为 CoInitializeSecurity的第一个参数传递。 (请注意,对于整个进程,必须最多调用一次 CoInitializeSecurity 。 有关 CoInitializeSecurity 调用的详细信息,请参阅 COM 文档或 MSDN。 )

    下面的代码示例演示如何在 Windows 8 和 Windows Server 2012 及更高版本中调用 CoInitializeSecurity ,以便与 (RVSS) 的远程文件共享的 VSS 兼容:

    // Initialize COM security.
       hr = CoInitializeSecurity(
            NULL,                          //  PSECURITY_DESCRIPTOR         pSecDesc,
            -1,                            //  LONG                         cAuthSvc,
            NULL,                          //  SOLE_AUTHENTICATION_SERVICE *asAuthSvc,
            NULL,                          //  void                        *pReserved1,
            RPC_C_AUTHN_LEVEL_PKT_PRIVACY, //  DWORD                        dwAuthnLevel,
            RPC_C_IMP_LEVEL_IMPERSONATE,   //  DWORD                        dwImpLevel,
            NULL,                          //  void                        *pAuthList,
            EOAC_STATIC,                   //  DWORD                        dwCapabilities,
            NULL                           //  void                        *pReserved3
            );
    

    使用 CoInitializeSecurity显式设置请求者的 COM 级别安全性时,应执行以下操作:

    • 将身份验证级别设置为至少 RPC _ C _ 身份验证 _ level _ PKT _ 完整性。 为了获得更好的安全性,请考虑使用 RPC _ C _ 身份验证 _ LEVEL _ PKT _ 隐私
    • 将模拟级别设置为 RPC _ C _ IMP _ level " _ 模拟"。
    • 将掩盖安全功能设置为 EOAC _ STATIC。 有关掩盖安全的详细信息,请参阅 掩蔽

    下面的代码示例演示了在 Windows 7 和 Windows Server 2008 R2 及 Windows 8 (更早版本中,如果不 Windows Server 2012 需要 RVSS 兼容性,请求方应如何调用 CoInitializeSecurity

    // Initialize COM security.
       hr = CoInitializeSecurity(
            NULL,                          //  PSECURITY_DESCRIPTOR         pSecDesc,
            -1,                            //  LONG                         cAuthSvc,
            NULL,                          //  SOLE_AUTHENTICATION_SERVICE *asAuthSvc,
            NULL,                          //  void                        *pReserved1,
            RPC_C_AUTHN_LEVEL_PKT_PRIVACY, //  DWORD                        dwAuthnLevel,
            RPC_C_IMP_LEVEL_IDENTIFY,      //  DWORD                        dwImpLevel,
            NULL,                          //  void                        *pAuthList,
            EOAC_NONE,                     //  DWORD                        dwCapabilities,
            NULL                           //  void                        *pReserved3
            );
    

    使用 CoInitializeSecurity显式设置请求者的 COM 级别安全性时,应执行以下操作:

    • 将身份验证级别设置为 "至少 RPC _ C _ 身份验证 _ level _ CONNECT"。 为了获得更好的安全性,请考虑使用 RPC _ C _ 身份验证 _ LEVEL _ PKT _ 隐私
    • 将模拟级别设置为 RPC _ C _ IMP _ level _ 标识 ,除非请求方进程需要允许模拟与 VSS 无关的特定 RPC 或 COM 调用。
  • 仅允许指定的进程访问请求者进程。

    一台 COM 服务器 (例如,使用非 NULL 安全描述符调用 CoInitializeSecurity的请求者) ,因为第一个参数可以使用描述符来配置自身,以仅接受来自属于特定帐户集的用户的传入呼叫。

    请求者必须确保在有效用户下运行的 COM 客户端可以调用其进程。 在第一个参数中指定安全描述符的请求者必须允许以下用户对请求方进程执行传入调用:

    • Local System

    • Local Service

      Windows XP: 在 Windows Server 2003 之前,此值不受支持。

    • Network Service

      Windows XP: 在 Windows Server 2003 之前,此值不受支持。

    • 本地 Administrators 组的成员

    • 本地备份操作员组的成员

    • 在以下注册表位置中指定的特殊用户,其 "1" 作为其 REG _ DWORD 值

显式控制对请求者的用户帐户访问

在某些情况下,将访问者限制为作为本地系统或本地管理员或本地备份操作员组运行的进程可能过于严格。

例如,指定的请求者进程通常不需要在管理员或备份操作员帐户下运行。 出于安全原因,最好不要人为升级过程来支持 VSS。

在这些情况下,必须修改 HKEY _ LOCAL _ MACHINE \ SYSTEM \ CurrentControlSet \ service \ VSS \ VssAccessControl 注册表项,以指示 VSS 指定的用户可以安全地运行 vss 请求程序。

在此项下,必须创建一个与要授予或拒绝访问的帐户同名的子项。 此子项必须设置为下表中的值之一。

含义
0 拒绝用户对编写者和请求者的访问。
1 向用户授予对编写器的访问权限。
2 向用户授予访问请求的权限。
3 向用户授予对编写者和请求者的访问权限。

以下示例授予对 "MyDomain \ MyUser" 帐户的访问权限:

HKEY_LOCAL_MACHINE
   SYSTEM
      CurrentControlSet
         Services
            VSS
               VssAccessControl
                  MyDomain\MyUser = 2<dl>
<dt>

                  Data type
</dt>
<dd>                  REG_DWORD</dd>
</dl>

此机制还可用于显式限制允许用户运行 VSS 请求者。 下面的示例将限制 "ThatDomain \ Administrator" 帐户的访问权限:

HKEY_LOCAL_MACHINE
   SYSTEM
      CurrentControlSet
         Services
            VSS
               VssAccessControl
                  ThatDomain\Administrator = 0<dl>
<dt>

                  Data type
</dt>
<dd>                  REG_DWORD</dd>
</dl>

用户 ThatDomain \ 管理员将无法运行 VSS 请求者。

执行系统状态的文件备份

如果请求者通过备份单个文件来执行系统状态备份,而不是使用卷映像进行备份,则必须调用 FindFirstFileNameWFindNextFileNameW 函数来枚举位于以下目录中的文件的硬链接:

  • Windows \system32 \ WDI \ perftrack\
  • Windows \WINSXS\

只有 Administrators 组的成员才能访问这些目录。 出于此原因,此类请求者必须在系统帐户下运行,或者在作为 Administrators 组成员的用户帐户下运行。

Windows XP 和 Windows Server 2003: 在 Windows Vista 和 Windows Server 2008 之前,不支持 FindFirstFileNameWFindNextFileNameW函数。