服务安全和访问权限

Windows 安全模型使你能够控制对服务控制管理器 (SCM) 和服务对象的访问。 以下各节提供了详细信息:

服务控制管理器的访问权限

下面是 SCM 的特定访问权限。

访问权限 描述
SC _管理器 _ 所有 _ 访问 (0xF003F) 除了此表中的所有访问权限外,还包括 _ _ 所需的标准权限
SC _管理器 _ 创建 _ 服务 (0x0002) 需要调用 CreateService 函数来创建服务对象并将其添加到数据库中。
SC _MANAGER _ 连接 (0x0001) 需要连接到服务控制管理器。
SC _管理器 _ 枚举 _ 服务 (0x0004) 需要调用 EnumServicesStatusEnumServicesStatusEx 函数以列出数据库中的服务。
需要调用 NotifyServiceStatusChange 函数,以便在创建或删除任何服务时接收通知。
SC _管理器 _ 锁 (0x0008) 需要调用 LockServiceDatabase 函数以获取数据库的锁。
SC _管理器 _ 修改 _ 启动 _ 配置 (0x0020) 需要调用 NotifyBootConfigStatus 函数。
SC _管理器 _ 查询 _ 锁定 _ 状态 (0x0010) 需要调用 QueryServiceLockStatus 函数来检索数据库的锁定状态信息。

下面是 SCM 的 一般访问权限

访问权限 描述
GENERIC_READ
STANDARD_RIGHTS_READ
SC_MANAGER_ENUMERATE_SERVICE
SC_MANAGER_QUERY_LOCK_STATUS
GENERIC_WRITE
STANDARD_RIGHTS_WRITE
SC_MANAGER_CREATE_SERVICE
SC_MANAGER_MODIFY_BOOT_CONFIG
GENERIC_EXECUTE
STANDARD_RIGHTS_EXECUTE
SC_MANAGER_CONNECT
SC_MANAGER_LOCK
GENERIC_ALL
SC_MANAGER_ALL_ACCESS

具有正确访问权限的进程可以打开 SCM 的句柄,该句柄可用于 OpenServiceEnumServicesStatusExQueryServiceLockStatus 函数。 只有具有管理员权限的进程才能打开 CreateServiceLockServiceDatabase 函数可以使用的对 SCM 的句柄。

系统为 SCM 创建安全描述符。 若要获取或设置 SCM 的安全描述符,请将 QueryServiceObjectSecuritySetServiceObjectSecurity 函数用于 SCManager 对象的句柄。

Windows Server 2003 和 WINDOWS XP: 与大多数其他安全对象不同,SCM 的安全描述符不能修改。 此行为已更改,因为 Windows Server 2003 Service Pack 1 (SP1) 。

授予以下访问权限。

帐户 访问权限
经过身份验证的远程用户
SC_MANAGER_CONNECT
(包括 LocalService 和 NetworkService 的本地经过身份验证的用户)
SC_MANAGER_CONNECT
SC_MANAGER_ENUMERATE_SERVICE
SC_MANAGER_QUERY_LOCK_STATUS
STANDARD_RIGHTS_READ
LocalSystem
SC_MANAGER_CONNECT
SC_MANAGER_ENUMERATE_SERVICE
SC_MANAGER_MODIFY_BOOT_CONFIG
SC_MANAGER_QUERY_LOCK_STATUS
STANDARD_RIGHTS_READ
管理员
SC_MANAGER_ALL_ACCESS

请注意,通过网络身份验证但未以交互方式登录的远程用户可以连接到 SCM,但不会执行需要其他访问权限的操作。 若要执行这些操作,用户必须以交互方式登录,否则服务必须使用某个服务帐户。

Windows Server 2003 和 WINDOWS XP: 向远程身份验证的用户授予了 sc _ manager _ CONNECTsc _ manager _ 枚举 _ 服务sc _ manager _ 查询 _ 锁定 _ 状态标准 _ 权限 _ 读取 访问权限。 这些访问权限受到限制,如以前的表中所述,从 Windows Server 2003 SP1

当进程使用 OpenSCManager 函数打开已安装服务的数据库的句柄时,它可以请求访问权限。 系统在授予请求的访问权限之前,对 SCM 的安全描述符执行安全检查。

服务的访问权限

下面是服务的特定访问权限。

访问权限 描述
服务 _所有 _ ACCESS (0xF01FF) 除了此表中的所有访问权限外,还包括 _ _ 所需的标准权限
服务 _更改 _ 配置 (0x0002) 需要调用 ChangeServiceConfigChangeServiceConfig2 函数来更改服务配置。 由于这会授予调用方更改系统运行的可执行文件的权限,因此应仅向管理员授予它。
服务 _枚举 _ 依赖项 (0x0008) 需要调用 EnumDependentServices 函数来枚举依赖于该服务的所有服务。
服务 _询问 (0x0080) 需要调用 control 服务 函数来要求服务立即报告其状态。
服务 _暂停 _ (0x0040) 需要调用 control 服务 函数以暂停或继续该服务。
服务 _查询 _ 配置 (0x0001) 需要调用 QueryServiceConfigQueryServiceConfig2 函数来查询服务配置。
服务 _查询 _ 状态 (0x0004) 需要调用 QueryServiceStatusQueryServiceStatusEx 函数来询问服务控制经理有关服务状态的信息。
需要调用 NotifyServiceStatusChange 函数,以便在服务更改状态时接收通知。
服务 _开始 (0x0010) 需要调用 StartService 函数来启动该服务。
服务 _停止 (0x0020) 需要调用 control 服务 函数以停止服务。
服务 _用户 _ 定义的 _ 控件 (0x0100) 需要调用 control 服务 函数来指定用户定义的控件代码。

下面是服务的 标准访问权限

访问权限 描述
访问 _ 系统 _ 安全 需要调用 QueryServiceObjectSecuritySetServiceObjectSecurity 函数来访问 SACL。 获取此访问权限的正确方法是在调用方的当前访问令牌中启用 " SE _ 安全 _ 名称"特权,打开 "访问 _ 系统 _ 安全 访问的句柄",然后禁用该权限。
删除 (0x10000) 需要调用 DeleteService 函数来删除服务。
阅读 _控制 (0x20000) 需要调用 QueryServiceObjectSecurity 函数来查询服务对象的安全说明符。
写入 _DAC (0x40000) 需要调用 SetServiceObjectSecurity 函数来修改服务对象安全描述符的 Dacl 成员。
写入 _所有者 (0x80000) 需要调用 SetServiceObjectSecurity 函数来修改服务对象的安全描述符的 所有者 成员。

下面是服务的 一般访问权限

访问权限 描述
GENERIC_READ
STANDARD_RIGHTS_READ
SERVICE_QUERY_CONFIG
SERVICE_QUERY_STATUS
SERVICE_INTERROGATE
SERVICE_ENUMERATE_DEPENDENTS
GENERIC_WRITE
STANDARD_RIGHTS_WRITE
SERVICE_CHANGE_CONFIG
GENERIC_EXECUTE
STANDARD_RIGHTS_EXECUTE
SERVICE_START
SERVICE_STOP
SERVICE_PAUSE_CONTINUE
SERVICE_USER_DEFINED_CONTROL

CreateService 函数安装服务时,SCM 会创建服务对象的安全描述符。 服务对象的默认安全描述符授予以下访问权限。

帐户 访问权限
经过身份验证的远程用户 默认情况下不授予。Windows Server 2003 SP1: SERVICE_USER_DEFINED_CONTROL
Windows Server 2003 和 WINDOWS XP: 远程身份验证用户的访问权限与用于本地身份验证的用户的访问权限相同。
(包括 LocalService 和 NetworkService 的本地经过身份验证的用户)
READ_CONTROL
SERVICE_ENUMERATE_DEPENDENTS
SERVICE_INTERROGATE
SERVICE_QUERY_CONFIG
SERVICE_QUERY_STATUS
SERVICE_USER_DEFINED_CONTROL
LocalSystem
READ_CONTROL
SERVICE_ENUMERATE_DEPENDENTS
SERVICE_INTERROGATE
SERVICE_PAUSE_CONTINUE
SERVICE_QUERY_CONFIG
SERVICE_QUERY_STATUS
SERVICE_START
SERVICE_STOP
SERVICE_USER_DEFINED_CONTROL
管理员
DELETE
READ_CONTROL
SERVICE_ALL_ACCESS
WRITE_DAC
WRITE_OWNER

若要执行任何操作,用户必须以交互方式登录,否则该服务必须使用某个服务帐户。

若要获取或设置服务对象的安全描述符,请使用 QueryServiceObjectSecuritySetServiceObjectSecurity 函数。 有关详细信息,请参阅 修改服务的 DACL

当进程使用 OpenService 函数时,系统会根据服务对象的安全描述符来检查请求的访问权限。

向不受信任的用户授予某些访问权限 (例如, 服务 _ 更改 _ 配置服务 _ 停止) 会使它们干扰你的服务的执行,并且可能会允许他们在 LocalSystem 帐户下运行应用程序。

调用 EnumServicesStatusEx 函数 时,如果调用方不具有服务 _ 查询 _ 状态 "对服务的访问权限",则该服务将从返回给客户端的服务列表中无提示地省略。