2

C# を使用してリモート サービスで SACL を取得する方法を知っている人はいますか? さまざまな方法を試しましたが、基本的に何も機能しません。ローカル マシンでは DACL と SACL を取得できますが、リモート マシンではどちらも取得できないようです。

私が行ったことは、クラスServiceSecurityから継承し、クラスNativeObjectSecurityのように機能するというクラスを作成することRegistrySecurityです。以下は、私が持っている2つのコンストラクターです。

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)
    {
    }

1 つ目はサービス名を使用し、2 つ目はサービスへのハンドルを想定しています。明らかに最初のものは DACL と SACL を取得するのに問題なく機能します。なぜなら、それはすべてローカルだからですServiceControllerServiceHandleそれを取得した後、作成したクラスにサービスのプロパティを渡しますServiceSecurity。その時点で Unauthorized Access 例外が発生します。これは、私のユーザー アカウントがドメインのドメイン管理者であり、ローカル サーバーであるため、正しくないようです。ターゲット ボックスの管理者。また、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)

AccessControlSectionsaccessSections については、Audit または Accessの 1 つだけを指定しています。Audit は、 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 に答える