SACL на Сервисах, использующих C# || получить дескриптор службы, которая имеет права ACCESS_SYSTEM_SECURITY, используя C#
Кто-нибудь есть идеи, как получить SACL на удаленном сервисе с использованием C#? Я пробовал множество разных методов, и в основном ничего не работает. Я могу получить 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)
Для разделов доступа я указываю только один из AccessControlSections
Будь то Аудит или Доступ и Аудит, кажется, терпит неудачу каждый раз, когда я прохожу ServiceHandle
,
Обновление: так что, возможно, вопрос действительно должен быть, как мне получить справку для службы, которая имеет ACCESS_SYSTEM_SECURITY
права, чтобы я мог получить SACL?
1 ответ
Дескриптор, который вы получаете от ServiceController, не будет иметь прав ACCESS_SYSTEM_SECURITY, поэтому вы не сможете получить доступ к SACL, используя его.
Для того, чтобы получить это право, вам понадобится справиться с этим правом. Возможно, вам придется использовать DuplicateHandle, чтобы получить дополнительные права, но включить SeSecurityPrivilege для удаленной системы может быть сложно.
Вы пытались использовать именованный конструктор службы с удаленным именем?
Мне нужно немного проверить это и вернуться к вам. Если никто не дал лучшего ответа к завтрашнему дню, я найду ответ для вас.
РЕДАКТИРОВАТЬ: под именем конструктора службы я имею в виду попытаться создать объект ServiceSecurity с именем службы в форме \\ имя_сервера \ имя_службы или \\IP_адрес \ имя_службы. Теоретически это должно работать, но это может не произойти из-за того, что SeSecurityPrivilege будет включен на локальном компьютере, а не на удаленном компьютере.
Чтобы получить ручку с предоставленным правом ACCESS_SYSTEM_SECURITY, вы должны выполнить следующие шаги:
- Получить дескриптор (из ServiceController или через взаимодействие)
- Включите SeSecurityPrivilege для текущего токена (это сложная часть), см.: AdjustTokenPrivileges, TOKEN_PRIVILEGES, LUID_AND_ATTRIBUTES и т. Д.
- Вызовите DuplicateHandle для дескриптора, запрашивая любые необходимые вам разрешения, включая ACCESS_SYSTEM_SECURITY, чтобы получить новый дескриптор с соответствующими правами.
- Отключите SeSecurityPrivilege (как указано выше).
К сожалению, у меня нет тестовой среды, настроенной для этого, поэтому я не могу гарантировать, что она будет работать для удаленных сервисов. Включение SeSecurityPrivilege для удаленного сервера кажется основным камнем преткновения. Во всяком случае, я надеюсь, что это поможет, по крайней мере, несколько.