SACL for services using C # || get a handle to a service that has ACCESS_SYSTEM_SECURITY permissions using C #

Does anyone know how to get SACL on a remote service using C #? I tried many different methods and basically nothing works. I can get DACL and SACL on the local computer, but getting on the remote machine is not possible.

I created a ServiceSecurity class that inherits from NativeObjectSecurity and acts like a RegistrySecurity class. Below are the two constructors that I have:

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

The first uses the name of the service, and the second expects a handle to this service. Obviously, the former works just fine to get DACL and SACL, because it is all local, but to get to the remote machine, I use the ServiceController class to search for services on the remote machine. Upon receiving it, I pass the ServiceHandle property of the service to the ServiceSecurity class that I created, and at this point I get a Unauthorized Access exception that does not seem correct because my user account is the domain administrator for the domain and the local administrator in the target field. I also have the SeSecurityPrivilege , which should allow me access.

Does anyone have any ideas? It seems that the SafeHandle I am getting is wrong, but the SafeHandle properties say that it is not closed and that it is a valid handle, so I do not quite understand what is happening.

Here is the code I use to try to extract the data:

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

The above will work for local permissions and audit settings (DACL and SACL). But it is designed to work on a local machine. If I do this instead:

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

The ServiceSecurity constructor does not work on local and remote servers for SACL as follows, but still works for 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) 

For accessSections, I specify only one of the AccessControlSections , whether audit or access and audit, seem to fail every time I pass a ServiceHandle .


Update: So maybe the question really should be, how do I get a handle to a service that has ACCESS_SYSTEM_SECURITY so that I can get the SACL?

+2
source share
1 answer

The handler that you get from the ServiceController will not have ACCESS_SYSTEM_SECURITY privileges so that you cannot access the SACL using it.

To get this right, you will need to get a pen with that right. You may need to use DuplicateHandle to get additional privileges, but enabling SeSecurityPrivilege for a remote system can be tricky.

Have you tried using a named service constructor with a remote name?

I need to check it out a bit and get back to you. If no one gives a better answer tomorrow, I will dig up the answer for you.

EDIT: by the named constructor of the service, I mean trying to create a ServiceSecurity object with the service name in the form \\ server_name \ service_name or \\ IP_address \ service_name. Theoretically, it should work, but this may not be due to the fact that SeSecurityPrivilege will be enabled on the local machine not on the remote machine.

To access with ACCESS_SYSTEM_SECURITY privileges, you must do the following:

  • Extract handle (from ServiceController or via interop)
  • Enable SeSecurityPrivilege for the current token (this is the difficult part), see AdjustTokenPrivileges , TOKEN_PRIVILEGES , LUID_AND_ATTRIBUTES , etc.
  • Call DuplicateHandle on a handle requesting any permissions you need, including ACCESS_SYSTEM_SECURITY, to get a new handle with the appropriate permissions.
  • Disable SeSecurityPrivilege (as described above).

Unfortunately, I do not have a test environment configured properly to test this, so I cannot guarantee that it will work for remote services. SeSecurityPrivilege permission for the remote server seems to be the main stumbling block. Anyway, I hope this helps at least.

+3
source

Source: https://habr.com/ru/post/1270289/


All Articles