SACL на Сервисах, использующих C # || получить дескриптор службы, которая имеет права ACCESS_SYSTEM_SECURITY, используя C # - PullRequest
2 голосов
/ 09 января 2009

У кого-нибудь есть идеи, как получить 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)

Для accessSections я указываю только один из AccessControlSections, будь то Аудит или Доступ и Аудит, похоже, дает сбой каждый раз, когда я передаю ServiceHandle.


Обновление: Так что, возможно, вопрос действительно должен быть: как мне получить дескриптор службы, обладающей правами ACCESS_SYSTEM_SECURITY, чтобы я мог получить SACL?

1 Ответ

3 голосов
/ 09 января 2009

Дескриптор, который вы получаете от ServiceController, не будет иметь прав ACCESS_SYSTEM_SECURITY, поэтому вы не можете получить доступ к SACL, используя его.

Чтобы получить это право, вам понадобится справиться с этим правом. Возможно, вам придется использовать DuplicateHandle, чтобы получить дополнительные права, но включить SeSecurityPrivilege для удаленной системы может быть сложно.

Вы пытались использовать именованный конструктор службы с удаленным именем?

Мне нужно немного проверить это и вернуться к вам. Если никто не даст лучшего ответа к завтрашнему дню, я найду для вас ответ.

РЕДАКТИРОВАТЬ: Под именованным конструктором службы я имею в виду попытку создания объекта ServiceSecurity с именем службы в форме \\ имя_сервера \ имя_службы или \\ IP_address \ имя_службы. Теоретически это должно работать, но это может не произойти из-за того, что SeSecurityPrivilege будет включен на локальном компьютере, а не на удаленном компьютере.

Чтобы получить дескриптор с предоставленным правом ACCESS_SYSTEM_SECURITY, вы должны выполнить следующие шаги:

  • Получить дескриптор (из ServiceController или через взаимодействие)
  • Включить SeSecurityPrivilege для текущего токена (это сложная часть), см .: AdjustTokenPrivileges , TOKEN_PRIVILEGES , LUID_AND_ATTRIBUTES и т. Д.
  • Вызовите DuplicateHandle на дескрипторе, запрашивая любые необходимые вам разрешения, включая ACCESS_SYSTEM_SECURITY, чтобы получить новый дескриптор с соответствующими правами.
  • Отключить SeSecurityPrivilege (как указано выше).

К сожалению, у меня нет тестовой среды, настроенной соответствующим образом, чтобы проверить это, поэтому я не могу гарантировать, что она будет работать для удаленных сервисов. Включение SeSecurityPrivilege для удаленного сервера кажется основным камнем преткновения. Во всяком случае, я надеюсь, что это поможет, по крайней мере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...