2

任何人都知道如何使用 C# 在远程服务上获取 SACL?我尝试了许多不同的方法,但基本上没有任何效果。我可以在本地机器上获取 DACL 和 SACL,但在远程机器上获取其中任何一个似乎都是不可能的。

我所做的是创建一个名为的类,该类ServiceSecurity继承自该类NativeObjectSecurity并且其行为与RegistrySecurity该类非常相似。以下是我拥有的两个构造函数:

public ServiceSecurity(string serviceName, AccessControlSections includeSections)
        : base(true, ResourceType.Service, serviceName, includeSections, null, null)
    {
    }

    public ServiceSecurity(System.Runtime.InteropServices.SafeHandle handle, AccessControlSections includeSections)
        : base(true, ResourceType.Service, handle, includeSections)
    {
    }

第一个使用服务名称,而第二个需要服务的句柄。显然,第一个可以很好地获取 DACL 和 SACL,因为它都是本地的,但是要访问远程机器,我使用ServiceController该类在远程机器上查找服务。得到它后,我将ServiceHandle服务的属性传递给ServiceSecurity我构建的类,此时我得到一个未经授权的访问异常,这似乎不正确,因为我的用户帐户是域的域管理员,而本地管理员在目标框上。我也有SeSecurityPrivilege权利,这应该允许我访问。

有人有想法么?似乎SafeHandle我得到的不正确,但SafeHandle属性说它没有关闭并且它是一个有效的句柄,所以我不太清楚发生了什么。

这是我用来尝试检索数据的代码:

ServiceSecurity sSec = new ServiceSecurity(services[i].ServiceName, accessSections);
string outputData = sSec.GetSecurityDescriptorSddlForm(accessSections);

以上内容适用于本地权限和审核设置(DACL 和 SACL)。但它被设计为在本地机器上工作。如果我这样做:

ServiceSecurity sSec = new ServiceSecurity(services[i].ServiceHandle, accessSections);
string outputData = sSec.GetSecurityDescriptorSddlForm(accessSections);

ServiceSecurity 构造函数在 SACL 的本地和远程服务器上均失败,如下所示,但仍适用于 DACL:

System.UnauthorizedAccessException: Attempted to perform an unauthorized operation.
   at System.Security.AccessControl.Win32.GetSecurityInfo(ResourceType resourceType, String name, SafeHandle handle, AccessControlSections accessControlSections, RawSecurityDescriptor& resultSd)
   at System.Security.AccessControl.NativeObjectSecurity.CreateInternal(ResourceType resourceType, Boolean isContainer, String name, SafeHandle handle, AccessControlSections includeSections, Boolean createByName, ExceptionFromErrorCode exceptionFromErrorCode, Object exceptionContext)
   at System.Security.AccessControl.NativeObjectSecurity..ctor(Boolean isContainer, ResourceType resourceType, SafeHandle handle, AccessControlSections includeSections)

对于 accessSections,我只指定了一个AccessControlSections,无论是 Audit 还是 Access,并且每次我通过ServiceHandle.


更新:所以也许问题真的应该是,我如何获得ACCESS_SYSTEM_SECURITY有权获得 SACL 的服务的句柄?

4

1 回答 1

3

您从 ServiceController 获得的句柄将没有 ACCESS_SYSTEM_SECURITY 权限,因此您无法使用它访问 SACL。

为了获得该权利,您需要掌握该权利。您可能需要使用 DuplicateHandle 来获得额外的权限,但为远程系统启用 SeSecurityPrivilege 可能会很棘手。

您是否尝试过使用具有远程名称的命名服务构造函数?

我需要检查一下,然后回复你。如果明天之前没有人给出更好的答案,我会为你挖掘答案。

编辑:通过命名服务构造函数,我的意思是尝试使用服务名称以 \\server_name\service_name 或 \\IP_address\service_name 的形式创建一个 ServiceSecurity 对象。理论上它应该可以工作,但它可能不是因为 SeSecurityPrivilege 将在本地机器上而不是在远程机器上启用。

为了获得授予 ACCESS_SYSTEM_SECURITY 权限的句柄,您必须按照以下步骤操作:

  • 检索句柄(从 ServiceController 或通过互操作)
  • 为当前令牌启用 SeSecurityPrivilege(这是棘手的部分),请参阅:AdjustTokenPrivilegesTOKEN_PRIVILEGESLUID_AND_ATTRIBUTES等。
  • 在句柄上调用DuplicateHandle请求您需要的任何权限,包括 ACCESS_SYSTEM_SECURITY 以检索具有适当权限的新句柄。
  • 禁用 SeSecurityPrivilege(如上)。

不幸的是,我没有适当设置测试环境来测试它,所以我不能保证它适用于远程服务。为远程服务器启用 SeSecurityPrivilege 似乎是主要的绊脚石。无论如何,我希望这至少有所帮助。

于 2009-01-08T22:56:15.077 回答