DOC / 1439 SysAdminHub.ru

Как проверить опасные учётные записи в Active Directory с помощью PowerShell

Как проверить опасные учётные записи в Active Directory с помощью PowerShell

При этом потенциально опасная учётная запись далеко не всегда выглядит подозрительно. Это может быть обычный пользователь с бессрочным паролем, забытая учётная запись бывшего сотрудника, старый сервисный аккаунт или администратор с избыточными привилегиями.

Отдельного внимания требуют учётные записи с настройками Kerberos, которые могут создавать дополнительные возможности для атак Kerberoasting и AS-REP Roasting.

В этой статье разберём, какие учётные записи стоит проверять в Active Directory в первую очередь, как найти их с помощью PowerShell и как автоматизировать аудит с формированием удобного HTML-отчёта.

Какие учётные записи будем проверять

При аудите Active Directory недостаточно просто получить список пользователей и посмотреть, когда они последний раз меняли пароль. Намного полезнее искать сочетания признаков, которые действительно могут повысить риск компрометации.

В рамках проверки обратим внимание на следующие категории:

  • учётные записи с зарегистрированными SPN;
  • учётные записи Kerberos с отключённой предварительной аутентификацией;
  • учётные записи с бессрочными паролями;
  • учётные записи, пароли которых давно не менялись;
  • активные, но длительное время неиспользуемые учётные записи;
  • привилегированные учётные записи;
  • сервисные учётные записи;
  • учётные записи с настроенным делегированием Kerberos;
  • учётные записи с SIDHistory;
  • учётные записи с потенциально небезопасными параметрами паролей.

Например, наличие SPN у сервисной учётной записи — совершенно нормальная ситуация. Проблема становится значительно серьёзнее, если эта же учётная запись имеет бессрочный пароль, который не менялся несколько лет, а сама учётная запись обладает повышенными привилегиями.

Именно поэтому в дальнейшем мы будем смотреть не только на отдельные настройки, но и на их сочетание.

Подготовка к проверке Active Directory

Для выполнения команд потребуется PowerShell и модуль ActiveDirectory, входящий в состав средств удалённого администрирования RSAT.

Проверить наличие модуля можно командой:


Get-Module -ListAvailable ActiveDirectory

Если модуль установлен, PowerShell вернёт информацию примерно следующего вида:


Directory: C:\Windows\system32\WindowsPowerShell\v1.0\Modules

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   1.0.1.0    ActiveDirectory                     {Add-ADCentralAccessPolicyMember, Add-ADComputerServiceAcc...

Главное здесь — наличие модуля ActiveDirectory в столбце Name. Версия модуля и путь к нему могут отличаться в зависимости от версии Windows и установленных компонентов.

Если команда ничего не вернула, значит модуль ActiveDirectory в текущей системе не найден. В таком случае необходимо установить соответствующие компоненты RSAT.

Отдельно импортировать модуль перед каждой проверкой не требуется. При первом обращении к командам Active Directory, например Get-ADUser, PowerShell автоматически загрузит установленный модуль.

Запускать аудит непосредственно на контроллере домена также необязательно. Удобнее выполнять проверку с административной рабочей станции или сервера управления, где установлен RSAT и имеется сетевой доступ к контроллерам домена.

Перед автоматизацией аудита посмотрим, как найти основные потенциально опасные настройки отдельными командами PowerShell.

Учётные записи с SPN и Kerberoasting

Начнём с Service Principal Name — SPN.

SPN используется Kerberos для идентификации экземпляра службы. Например, SPN может быть связан с SQL Server, IIS или другим сервисом, работающим от имени доменной учётной записи.

Получить пользовательские учётные записи, для которых зарегистрирован SPN, можно следующей командой:


Get-ADUser -LDAPFilter "(servicePrincipalName=*)" `
    -Properties ServicePrincipalName |
    Select-Object SamAccountName, Enabled, ServicePrincipalName

Например, результат может выглядеть так:


SamAccountName Enabled ServicePrincipalName
-------------- ------- --------------------
svc-sql01         True {MSSQLSvc/sql01.contoso.local:1433}
svc-web           True {HTTP/web01.contoso.local}
svc-legacy        True {HOST/legacy.contoso.local}

В данном примере обнаружены три активные пользовательские учётные записи, для которых зарегистрированы SPN.

Само наличие SPN не означает, что учётная запись уязвима.

Проблема заключается в особенностях работы Kerberos. Пользователь домена может запросить сервисный билет для службы, зарегистрированной через SPN. Часть данных такого билета защищается ключом, производным от пароля сервисной учётной записи. Полученный билет может быть использован для автономной проверки вариантов пароля.

Такой сценарий атаки получил название Kerberoasting.

Поэтому гораздо интереснее не просто найти учётные записи с SPN, а одновременно посмотреть состояние их паролей.

Для этого расширим предыдущую команду:


Get-ADUser -LDAPFilter "(servicePrincipalName=*)" `
    -Properties ServicePrincipalName, PasswordLastSet, PasswordNeverExpires |
    Select-Object SamAccountName,
                  Enabled,
                  PasswordLastSet,
                  PasswordNeverExpires,
                  ServicePrincipalName

Пример результата:


SamAccountName       : svc-sql01
Enabled              : True
PasswordLastSet      : 15.03.2024 11:42:17
PasswordNeverExpires : True
ServicePrincipalName : {MSSQLSvc/sql01.contoso.local:1433}

SamAccountName       : svc-web
Enabled              : True
PasswordLastSet      : 18.07.2026 09:15:32
PasswordNeverExpires : False
ServicePrincipalName : {HTTP/web01.contoso.local}

Теперь ситуация выглядит гораздо понятнее.

У учётной записи svc-web присутствует SPN, однако пароль относительно свежий и для него не установлен параметр бессрочного действия.

А вот svc-sql01 требует дополнительного внимания. Учётная запись активна, имеет SPN, пароль давно не менялся и одновременно установлен параметр PasswordNeverExpires.

Особого внимания заслуживают ситуации, когда одновременно выполняются несколько условий:

  • учётная запись активна;
  • присутствует SPN;
  • установлен бессрочный пароль;
  • пароль не менялся продолжительное время;
  • учётная запись входит в привилегированные группы.

Чем больше таких факторов присутствует одновременно, тем выше приоритет проверки этой учётной записи.

Для сервисов, которые это поддерживают, одним из вариантов снижения подобных рисков является использование Group Managed Service Accounts (gMSA). В этом случае Active Directory автоматически управляет сложным паролем сервисной учётной записи и его ротацией.

К gMSA мы ещё вернёмся отдельно после разбора результатов аудита.

Kerberos без Pre-Auth и AS-REP Roasting

Следующая настройка, которую стоит проверить, — отключение предварительной аутентификации Kerberos.

В свойствах пользователя Active Directory ей соответствует параметр Do not require Kerberos preauthentication.

Найти такие учётные записи можно командой:


Get-ADUser -Filter 'DoesNotRequirePreAuth -eq $true' `
    -Properties DoesNotRequirePreAuth |
    Select-Object SamAccountName, Enabled, DoesNotRequirePreAuth

Если такие учётные записи существуют, результат может выглядеть следующим образом:


SamAccountName Enabled DoesNotRequirePreAuth
-------------- ------- ---------------------
legacy-app        True                  True
svc-oldapp        True                  True

Это означает, что для двух найденных учётных записей отключена предварительная аутентификация Kerberos.

Если таких объектов в домене нет, команда просто не вернёт строк:


PS C:\> Get-ADUser -Filter 'DoesNotRequirePreAuth -eq $true' `
>>     -Properties DoesNotRequirePreAuth |
>>     Select-Object SamAccountName, Enabled, DoesNotRequirePreAuth

PS C:\>

В данном случае отсутствие результата — как раз хороший признак: учётных записей с отключённой Kerberos Pre-Authentication команда не обнаружила.

При стандартной работе Kerberos клиент должен подтвердить знание секрета пользователя ещё на начальном этапе аутентификации.

Если Kerberos Pre-Authentication для учётной записи отключена, появляется возможность получить данные AS-REP без обычного предварительного подтверждения. Эти данные впоследствии могут использоваться для автономной проверки вариантов пароля.

Такая техника называется AS-REP Roasting.

Поэтому активная учётная запись с DoesNotRequirePreAuth = True требует проверки причины такой настройки.

Особенно внимательно стоит относиться к ситуации, когда одновременно присутствуют дополнительные факторы риска:

  • установлен бессрочный пароль;
  • пароль давно не менялся;
  • учётная запись обладает повышенными привилегиями;
  • назначение учётной записи неизвестно.

Бессрочные пароли

Одна из самых распространённых проблем, которую можно встретить в Active Directory, — учётные записи с отключённым сроком действия пароля.

В свойствах пользователя за это отвечает параметр PasswordNeverExpires.

Получить список активных учётных записей с бессрочным паролем можно следующей командой:


Get-ADUser -Filter 'Enabled -eq $true -and PasswordNeverExpires -eq $true' `
    -Properties PasswordNeverExpires, PasswordLastSet |
    Select-Object SamAccountName, PasswordLastSet, PasswordNeverExpires

Пример результата:


SamAccountName    PasswordLastSet       PasswordNeverExpires
--------------    ---------------       --------------------
administrator     26.04.2026 18:53:21                  True
svc-backup        28.04.2025 11:23:17                  True
svc-monitoring    28.04.2025 11:35:42                  True
user01            09.04.2025 15:30:11                  True

В данном случае обнаружены четыре активные учётные записи, для которых срок действия пароля не ограничен.

Однако относиться ко всем найденным объектам одинаково неправильно.

Например, svc-backup или svc-monitoring могут оказаться сервисными учётными записями, пароль которых используется службой, заданием планировщика или внешней системой. Простое включение срока действия пароля без предварительной проверки зависимостей может привести к остановке соответствующего сервиса.

Совсем другая ситуация — обычная пользовательская учётная запись user01. Если для неё нет обоснованного исключения из парольной политики, наличие бессрочного пароля требует проверки.

Отдельного внимания заслуживают привилегированные учётные записи. Если административный аккаунт имеет бессрочный пароль, необходимо понимать причину такой настройки и оценить остальные факторы риска.

Особенно внимательно стоит проверять сочетания:

  • бессрочный пароль + привилегированная учётная запись;
  • бессрочный пароль + SPN;
  • бессрочный пароль + пароль не менялся продолжительное время;
  • бессрочный пароль + давно неиспользуемая учётная запись.

В итоговом скрипте эти признаки будут анализироваться совместно.

Устаревшие пароли

Следующий важный показатель — дата последней смены пароля.

Получить её можно из свойства PasswordLastSet.

Например, найдём активные учётные записи и посмотрим, когда для них последний раз устанавливался пароль:


Get-ADUser -Filter 'Enabled -eq $true' `
    -Properties PasswordLastSet |
    Select-Object SamAccountName, PasswordLastSet |
    Sort-Object PasswordLastSet

Пример результата:


SamAccountName    PasswordLastSet
--------------    ---------------
svc-legacy        15.03.2023 10:17:42
svc-backup        28.04.2025 11:23:17
user01            09.04.2025 15:30:11
user02            18.07.2026 09:15:32
user03            25.08.2026 14:41:06

Такой вывод уже позволяет увидеть учётные записи с давно не менявшимися паролями, но при большом количестве пользователей анализировать список вручную неудобно.

Поэтому лучше сразу задать порог.

Например, найдём активные учётные записи, пароль которых не менялся более 365 дней:


$StalePasswordDays = 365
$PasswordLimit = (Get-Date).AddDays(-$StalePasswordDays)

Get-ADUser -Filter 'Enabled -eq $true' `
    -Properties PasswordLastSet |
    Where-Object {
        $_.PasswordLastSet -and
        $_.PasswordLastSet -lt $PasswordLimit
    } |
    Select-Object SamAccountName, PasswordLastSet

Пример результата:


SamAccountName    PasswordLastSet
--------------    ---------------
svc-legacy        15.03.2023 10:17:42
svc-backup        28.04.2025 11:23:17
user01            09.04.2025 15:30:11

Теперь в вывод попали только активные учётные записи, для которых пароль не менялся более года.

Значение 365 здесь используется как пример порогового значения, а не как универсальное требование для любой инфраструктуры. В своей организации его необходимо выбирать с учётом действующей парольной политики, типа учётных записей и принятых исключений.

Кроме того, старый пароль сервисной учётной записи и старый пароль обычного пользователя требуют разного подхода.

Для обычного пользователя стоит проверить актуальность учётной записи и соблюдение парольной политики.

Для сервисной учётной записи сначала необходимо определить:

  • владельца;
  • назначение;
  • службы, которые запускаются от её имени;
  • задания планировщика;
  • пулы приложений;
  • интеграции с другими системами;
  • другие зависимости от используемых учётных данных.

Менять пароль сервисной учётной записи без такой проверки опасно — можно устранить один риск и одновременно создать отказ информационной системы.

В нашем итоговом скрипте значение 365 будет использоваться как порог по умолчанию, но его можно изменить при запуске.

Неактивные учётные записи

Ещё одна типичная проблема Active Directory — активные учётные записи, которыми давно никто не пользуется.

Причины их появления могут быть разными:

  • сотрудник уволился, а учётную запись забыли отключить;
  • временный сотрудник или подрядчик завершил работу;
  • тестовая учётная запись больше не нужна;
  • сервис был выведен из эксплуатации;
  • старую интеграцию отключили, а связанный аккаунт остался;
  • учётная запись создавалась для миграции или разовых работ.

Если такая учётная запись остаётся активной, она продолжает представлять потенциальную точку доступа в инфраструктуру.

Для первичной проверки можно использовать свойство LastLogonDate.

Например, найдём активные учётные записи, которые не использовались более 180 дней:


$InactiveDays = 180
$InactiveLimit = (Get-Date).AddDays(-$InactiveDays)

Get-ADUser -Filter 'Enabled -eq $true' `
    -Properties LastLogonDate |
    Where-Object {
        $_.LastLogonDate -and
        $_.LastLogonDate -lt $InactiveLimit
    } |
    Select-Object SamAccountName, LastLogonDate |
    Sort-Object LastLogonDate

Пример результата:


SamAccountName    LastLogonDate
--------------    -------------
user-old01        08.03.2025 11:26:14
svc-scanner       11.02.2026 09:49:37
contractor01      19.02.2026 15:12:08
test-user         25.02.2026 10:31:54

В данном примере все четыре учётные записи активны, однако последний зафиксированный вход был более 180 дней назад.

Есть и ещё одна ситуация: LastLogonDate вообще отсутствует.

Посмотреть такие активные учётные записи можно отдельно:


Get-ADUser -Filter 'Enabled -eq $true' `
    -Properties LastLogonDate, WhenCreated |
    Where-Object { -not $_.LastLogonDate } |
    Select-Object SamAccountName, WhenCreated, LastLogonDate

Пример:


SamAccountName    WhenCreated          LastLogonDate
--------------    -----------          -------------
svc-oldapp        28.04.2025 11:20:03
migration-user    09.04.2025 15:41:18
test-service      20.05.2025 16:33:51

Пустое значение LastLogonDate не означает автоматически, что учётную запись можно отключать.

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

Поэтому в нашем скрипте при отсутствии LastLogonDate дополнительно учитывается возраст самой учётной записи. Если объект существует дольше установленного порога и при этом информация о входах отсутствует, он попадает в отчёт как требующий проверки.

Для пользователя необходимо определить владельца и актуальность учётной записи.

Для сервисного аккаунта сначала нужно проверить все зависимости и только после этого принимать решение об отключении.

Привилегированные учётные записи

Если компрометация обычной пользовательской учётной записи может дать злоумышленнику первоначальный доступ, то компрометация административной учётной записи способна привести уже к значительно более серьёзным последствиям.

Поэтому привилегированные аккаунты необходимо рассматривать отдельно.

Самый очевидный пример — члены группы Domain Admins.

Получить их можно командой:


Get-ADGroupMember "Domain Admins" -Recursive |
    Where-Object { $_.objectClass -eq "user" } |
    Select-Object Name, SamAccountName

Пример результата:


Name                    SamAccountName
----                    --------------
Administrator           Administrator
Admin User              admin.user
Infrastructure Admin    infra.admin

Параметр -Recursive здесь важен: он позволяет учитывать пользователей, которые получили членство в Domain Admins через вложенные группы.

Однако проверять только Domain Admins недостаточно.

В зависимости от структуры Active Directory повышенные возможности могут иметь участники и других групп, например:

  • Enterprise Admins;
  • Schema Admins;
  • Administrators;
  • Account Operators;
  • Server Operators;
  • Backup Operators;
  • Print Operators;
  • Group Policy Creator Owners;
  • DNSAdmins.

Например, посмотрим членов Enterprise Admins:


Get-ADGroupMember "Enterprise Admins" -Recursive |
    Where-Object { $_.objectClass -eq "user" } |
    Select-Object Name, SamAccountName

Пример:


Name              SamAccountName
----              --------------
Administrator     Administrator
Forest Admin      forest.admin

После получения списка административных учётных записей полезно проверить состояние их паролей:


Get-ADGroupMember "Domain Admins" -Recursive |
    Where-Object { $_.objectClass -eq "user" } |
    ForEach-Object {
        Get-ADUser $_.SamAccountName `
            -Properties PasswordLastSet, PasswordNeverExpires
    } |
    Select-Object SamAccountName,
                  Enabled,
                  PasswordLastSet,
                  PasswordNeverExpires

Пример результата:


SamAccountName PasswordLastSet       PasswordNeverExpires
-------------- ---------------       --------------------
Administrator  26.04.2026 18:53:21                  True
admin.user     13.08.2026 15:20:04                  True
infra.admin    29.08.2026 10:41:18                 False

Теперь видно, что две административные учётные записи имеют бессрочный пароль.

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

Стоит обращать внимание на сочетание нескольких факторов:

  • административные права + бессрочный пароль;
  • административные права + давно не менявшийся пароль;
  • административные права + SPN;
  • административные права + отключённая Kerberos Pre-Authentication;
  • административные права + делегирование;
  • административные права + длительная неактивность.

Нужно понимать не только кто является администратором, но и какие дополнительные факторы риска присутствуют у этой учётной записи.

В итоговом скрипте членство в привилегированных группах будет использоваться как дополнительный коэффициент риска.

Делегирование Kerberos

Следующий блок проверки — учётные записи, для которых настроено делегирование Kerberos.

Делегирование используется в инфраструктуре, когда одной службе необходимо обращаться к другой службе от имени пользователя. Сам механизм является штатной возможностью Active Directory, однако неправильная или оставшаяся от старой инфраструктуры конфигурация может существенно увеличить последствия компрометации учётной записи.

В первую очередь нас интересуют три варианта:

  • Unconstrained Delegation — неограниченное делегирование;
  • Constrained Delegation — ограниченное делегирование;
  • делегирование с Protocol Transition.

Начнём с поиска пользовательских учётных записей с включённым неограниченным делегированием.


Get-ADUser -Filter 'TrustedForDelegation -eq $true' `
    -Properties TrustedForDelegation |
    Select-Object SamAccountName, Enabled, TrustedForDelegation

Пример результата:


SamAccountName    Enabled TrustedForDelegation
--------------    ------- --------------------
svc-legacy-web       True                 True
svc-oldapp           True                 True

Если таких объектов нет, команда ничего не вернёт:


PS C:\> Get-ADUser -Filter 'TrustedForDelegation -eq $true' `
>>     -Properties TrustedForDelegation |
>>     Select-Object SamAccountName, Enabled, TrustedForDelegation

PS C:\>

Теперь посмотрим более широкий вариант проверки:


Get-ADUser -Filter * `
    -Properties TrustedForDelegation,
                TrustedToAuthForDelegation,
                'msDS-AllowedToDelegateTo' |
    Where-Object {
        $_.TrustedForDelegation -or
        $_.TrustedToAuthForDelegation -or
        $_.'msDS-AllowedToDelegateTo'
    } |
    Select-Object SamAccountName,
                  Enabled,
                  TrustedForDelegation,
                  TrustedToAuthForDelegation,
                  'msDS-AllowedToDelegateTo'

Пример результата:


SamAccountName             : svc-legacy-web
Enabled                    : True
TrustedForDelegation       : True
TrustedToAuthForDelegation : False
msDS-AllowedToDelegateTo   : {}

SamAccountName             : svc-webapp
Enabled                    : True
TrustedForDelegation       : False
TrustedToAuthForDelegation : False
msDS-AllowedToDelegateTo   : {MSSQLSvc/sql01.contoso.local:1433}

SamAccountName             : svc-portal
Enabled                    : True
TrustedForDelegation       : False
TrustedToAuthForDelegation : True
msDS-AllowedToDelegateTo   : {HTTP/app01.contoso.local}

Здесь уже видно три разных ситуации.

Для svc-legacy-web установлен параметр TrustedForDelegation = True, то есть используется неограниченное делегирование.

У svc-webapp заполнен атрибут msDS-AllowedToDelegateTo, что указывает на настроенное ограниченное делегирование к определённой службе.

У svc-portal дополнительно установлен TrustedToAuthForDelegation = True, что требует отдельной проверки сценария использования Protocol Transition.

Сам факт наличия делегирования ещё не означает ошибку конфигурации. Оно может быть необходимо приложению для нормальной работы.

Однако при аудите необходимо определить:

  • действительно ли делегирование требуется этой учётной записи;
  • существует ли ещё приложение, ради которого оно было настроено;
  • к каким именно сервисам разрешено делегирование;
  • обладает ли учётная запись дополнительными привилегиями;
  • насколько защищён её пароль;
  • кто является владельцем учётной записи.

В AD-SecurityAudit.ps1 наличие неограниченного делегирования получает значительно больший вес при расчёте риска, чем обычное ограниченное делегирование.

SIDHistory

Следующая проверка — атрибут SIDHistory.

Каждый объект безопасности в Active Directory имеет собственный Security Identifier — SID. Именно SID, а не имя пользователя, фактически используется Windows при проверке доступа к ресурсам.

Атрибут SIDHistory позволяет сохранить старые SID учётной записи. Это штатный механизм, который часто используется при миграции пользователей между доменами.

Проверить пользовательские учётные записи с заполненным SIDHistory можно следующей командой:


Get-ADUser -Filter * `
    -Properties SIDHistory |
    Where-Object { $_.SIDHistory } |
    Select-Object SamAccountName, Enabled, SIDHistory

Пример результата:


SamAccountName Enabled SIDHistory
-------------- ------- ----------
user01           True {S-1-5-21-111111111-222222222-333333333-1107}
migration-admin  True {S-1-5-21-111111111-222222222-333333333-512}

Само наличие SIDHistory не является доказательством компрометации или неправильной настройки.

Например, для user01 этот атрибут мог сохраниться после штатной миграции из старого домена.

Однако migration-admin требует значительно более внимательной проверки.

В примере старый SID заканчивается на -512. RID 512 используется группой Domain Admins домена. Поэтому необходимо выяснить происхождение этого значения и действительно ли сохранение такого SID требуется после миграции.

Для каждой учётной записи с SIDHistory стоит определить:

  • откуда появился старый SID;
  • проводилась ли миграция домена;
  • завершена ли она;
  • требуется ли SIDHistory до сих пор;
  • какие права предоставляет сохранённый SID;
  • существует ли документированное обоснование его использования.

Дополнительные небезопасные параметры

Основные проверки мы уже рассмотрели, но в Active Directory есть ещё несколько параметров пользовательских учётных записей, которые полезно включить в аудит.

В нашем скрипте дополнительно проверяются:

  • PasswordNotRequired;
  • AllowReversiblePasswordEncryption;
  • adminCount.

PasswordNotRequired

Параметр PasswordNotRequired указывает, что для учётной записи установлен флаг PASSWD_NOTREQD.


Get-ADUser -Filter 'PasswordNotRequired -eq $true' `
    -Properties PasswordNotRequired |
    Select-Object SamAccountName, Enabled, PasswordNotRequired

Пример:


SamAccountName    Enabled PasswordNotRequired
--------------    ------- -------------------
legacy-user          True                True
test-account         True                True

Если команда ничего не вернула:


PS C:\> Get-ADUser -Filter 'PasswordNotRequired -eq $true' `
>>     -Properties PasswordNotRequired |
>>     Select-Object SamAccountName, Enabled, PasswordNotRequired

PS C:\>

значит пользовательских объектов с этим флагом не обнаружено.

Наличие PasswordNotRequired = True не следует воспринимать буквально как гарантию того, что у пользователя прямо сейчас отсутствует пароль. Этот флаг указывает на соответствующую настройку учётной записи и требует проверки фактической конфигурации и причины её появления.

AllowReversiblePasswordEncryption

Следующий параметр — разрешение хранения пароля с использованием обратимого шифрования.


Get-ADUser -Filter 'AllowReversiblePasswordEncryption -eq $true' `
    -Properties AllowReversiblePasswordEncryption |
    Select-Object SamAccountName,
                  Enabled,
                  AllowReversiblePasswordEncryption

Пример результата:


SamAccountName Enabled AllowReversiblePasswordEncryption
-------------- ------- ---------------------------------
legacy-app        True                              True

Подобная настройка может встречаться из-за требований старых приложений или протоколов, однако для каждой такой учётной записи необходимо понимать причину её использования.

adminCount

Ещё один интересный атрибут — adminCount.


Get-ADUser -LDAPFilter "(adminCount=1)" `
    -Properties adminCount |
    Select-Object SamAccountName, Enabled, adminCount

Пример:


SamAccountName    Enabled adminCount
--------------    ------- ----------
Administrator        True          1
admin.user           True          1
old-admin            True          1

На первый взгляд может показаться, что все три учётные записи сейчас являются администраторами.

Но это не обязательно так.

adminCount = 1 нельзя использовать как единственный способ определения текущих привилегированных пользователей. Этот атрибут может сохраниться у пользователя даже после его удаления из защищённой группы.

Например, проверим old-admin:


Get-ADPrincipalGroupMembership "old-admin" |
    Select-Object Name

Пример результата:


Name
----
Domain Users
Remote Desktop Users

В данном примере пользователь уже не состоит в очевидных административных группах, однако adminCount у него всё ещё может оставаться равным 1.

Поэтому в нашем скрипте adminCount = 1 используется только как дополнительный исторический сигнал.

На этом этапе у нас уже получился достаточно большой набор отдельных PowerShell-проверок.

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

Нам нужно сопоставить результаты между собой и выделить учётные записи, где одновременно присутствуют несколько факторов риска.

Поэтому следующим шагом объединим рассмотренные проверки в один PowerShell-скрипт — AD-SecurityAudit.ps1.

Автоматизация аудита с помощью AD-SecurityAudit.ps1

Все рассмотренные выше проверки можно выполнять отдельными командами PowerShell, но для регулярного аудита такой подход неудобен.

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

Поэтому объединим проверки в один скрипт — AD-SecurityAudit.ps1.

Скрипт выполняет аудит пользовательских учётных записей Active Directory, сопоставляет найденные признаки между собой и формирует итоговый отчёт с оценкой риска.

В рамках аудита проверяются:

  • наличие SPN;
  • отключение Kerberos Pre-Authentication;
  • бессрочные пароли;
  • PasswordNotRequired;
  • разрешение обратимого шифрования пароля;
  • давно не менявшиеся пароли;
  • длительно неиспользуемые активные учётные записи;
  • членство в привилегированных группах;
  • неограниченное делегирование Kerberos;
  • ограниченное делегирование;
  • Protocol Transition;
  • SIDHistory;
  • исторический признак adminCount.

Скачивание скрипта

Скачайте файл AD-SecurityAudit.ps1 и сохраните его, например, на рабочем столе или в каталоге с административными скриптами.

Предположим, файл находится по пути:


C:\Users\Administrator\Desktop\AD-SecurityAudit.ps1

После скачивания Windows может пометить PowerShell-скрипт как полученный из Интернета.

Если при запуске возникает соответствующая блокировка, её можно снять командой:


Unblock-File "C:\Users\Administrator\Desktop\AD-SecurityAudit.ps1"

При успешном выполнении Unblock-File ничего не выводит:


PS C:\> Unblock-File "C:\Users\Administrator\Desktop\AD-SecurityAudit.ps1"
PS C:\>

Первый запуск

Перейдём в каталог, где находится скрипт:


cd "C:\Users\Administrator\Desktop"

PowerShell изменит текущий каталог:


PS C:\> cd "C:\Users\Administrator\Desktop"
PS C:\Users\Administrator\Desktop>

Теперь запустим аудит:


.\AD-SecurityAudit.ps1

После запуска скрипт определит текущий домен, получит пользовательские объекты Active Directory, проверит необходимые атрибуты и членство в привилегированных группах, после чего сформирует отчёты.

Пример консольного вывода:


PS C:\Users\Administrator\Desktop> .\AD-SecurityAudit.ps1

=== AD Security Audit ===

Домен: CONTOSO.LOCAL
Получение пользователей Active Directory...
Получено объектов: 209

Проверка привилегированных групп...
Анализ учётных записей...
Обработано: 209 из 209

Формирование отчётов...

HTML: C:\Users\Administrator\Desktop\AD-Security-Audit\AD-Security-Audit-20260902-203506.html
CSV:  C:\Users\Administrator\Desktop\AD-Security-Audit\AD-Security-Audit-20260902-203506.csv

Критический:     0
Высокий:         6
Средний:       125
Информационный:  0
Всего в отчёте: 131

Аудит завершён.

Количество объектов и найденных проблем, разумеется, будет зависеть от конкретного домена.

В нашем тестовом примере скрипт проверил 209 пользовательских объектов. После анализа в итоговый отчёт попала 131 учётная запись:

  • 0 с критическим уровнем риска;
  • 6 с высоким;
  • 125 со средним;
  • 0 с информационным уровнем.

Где сохраняются отчёты

По умолчанию рядом со скриптом автоматически создаётся каталог:


AD-Security-Audit

Если AD-SecurityAudit.ps1 находится здесь:


C:\Users\Administrator\Desktop\AD-SecurityAudit.ps1

то отчёты будут сохранены здесь:


C:\Users\Administrator\Desktop\AD-Security-Audit\

В каталоге создаются два файла:


AD-Security-Audit-20260902-203506.html
AD-Security-Audit-20260902-203506.csv

Дата и время добавляются к имени автоматически, поэтому предыдущие результаты аудита не перезаписываются.

HTML предназначен в первую очередь для просмотра и анализа результатов.

CSV удобно использовать для дополнительной обработки, фильтрации, импорта в Excel или передачи результатов другим специалистам.

Параметры запуска скрипта

Для первого знакомства AD-SecurityAudit.ps1 можно запустить вообще без дополнительных параметров:


.\AD-SecurityAudit.ps1

В этом случае будут использованы значения по умолчанию.

InactiveDays

Параметр InactiveDays определяет, через сколько дней отсутствия активности учётная запись будет считаться неактивной.

По умолчанию используется:


InactiveDays = 90

Например, чтобы увеличить период до 180 дней:


.\AD-SecurityAudit.ps1 -InactiveDays 180

Какое значение использовать, зависит от инфраструктуры. Порог в 90 дней позволяет находить больше потенциально забытых учётных записей, но в некоторых организациях создаёт много лишних результатов.

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

StalePasswordDays

Параметр StalePasswordDays определяет возраст пароля, после которого он будет отмечен как давно не менявшийся.

По умолчанию:


StalePasswordDays = 365

Например:


.\AD-SecurityAudit.ps1 -StalePasswordDays 365

Если необходимо искать пароли старше 180 дней:


.\AD-SecurityAudit.ps1 -StalePasswordDays 180

Само значение 365 дней не следует воспринимать как универсальную парольную политику. Это порог аудита, который администратор может выбрать самостоятельно.

IncludeInfo

По умолчанию скрипт не добавляет в таблицу результаты, имеющие только информационный уровень.

Если необходимо увидеть и информационные результаты, используется параметр:


.\AD-SecurityAudit.ps1 -IncludeInfo

IncludeInfo является переключателем, поэтому после него не нужно указывать True, 1 или другое значение.

При этом сводная статистика HTML-отчёта по основным категориям формируется для всех проверенных учётных записей.

OutputPath

Если отчёты необходимо сохранять не рядом со скриптом, каталог можно указать вручную через OutputPath.


.\AD-SecurityAudit.ps1 -OutputPath "C:\Reports\AD-Audit"

После завершения скрипт покажет фактические пути:


HTML: C:\Reports\AD-Audit\AD-Security-Audit-20260902-210315.html
CSV:  C:\Reports\AD-Audit\AD-Security-Audit-20260902-210315.csv

Рекомендуемый вариант запуска

Для первого полноценного аудита я предпочитаю не использовать слишком маленький период неактивности.


.\AD-SecurityAudit.ps1 `
    -InactiveDays 180 `
    -StalePasswordDays 365

Именно с такими параметрами проводился тестовый запуск, результаты которого дальше будем использовать для разбора HTML-отчёта.

Если требуется максимально полный результат, включая информационные события:


.\AD-SecurityAudit.ps1 `
    -InactiveDays 180 `
    -StalePasswordDays 365 `
    -IncludeInfo

Запуск по полному пути

Переходить в каталог со скриптом необязательно.


& "C:\Users\Administrator\Desktop\AD-SecurityAudit.ps1" `
    -InactiveDays 180 `
    -StalePasswordDays 365

Здесь используется оператор вызова &, после которого указывается полный путь к PowerShell-скрипту.

После завершения аудита открываем сформированный HTML-файл в браузере.

HTML-отчёт

После завершения AD-SecurityAudit.ps1 в каталоге результатов появляется HTML-файл:


AD-Security-Audit-20260902-203506.html

Его можно открыть обычным браузером. Никакого отдельного веб-сервера или дополнительного программного обеспечения для просмотра отчёта не требуется.

В верхней части отображается общая информация об аудите:

  • домен;
  • дата формирования отчёта;
  • количество проверенных пользовательских объектов;
  • количество строк, попавших в итоговую таблицу;
  • распределение результатов по уровням риска.
Как проверить опасные учётные записи в Active Directory с помощью PowerShell

Ниже расположена дополнительная сводка по отдельным категориям проверки:

  • учётные записи с SPN;
  • Kerberos без Pre-Auth;
  • привилегированные учётные записи с найденными рисками;
  • неактивные учётные записи;
  • бессрочные пароли;
  • устаревшие пароли;
  • делегирование;
  • SIDHistory.

На тестовом домене результат выглядел следующим образом:


Проверено учётных записей: 209
В таблице:                 131

Критический:                 0
Высокий:                     6
Средний:                   125
Информационный:              0

Учётные записи с SPN:        0
Kerberos без Pre-Auth:       0
Привилегированные с рисками: 6
Неактивные:                 41
Бессрочный пароль:         129
Устаревший пароль:          78
Делегирование:               0
SIDHistory:                  0

Уже по одной этой сводке можно сделать несколько предварительных выводов.

Например, в тестовой инфраструктуре не обнаружены пользовательские учётные записи с SPN, отключённой Kerberos Pre-Authentication, делегированием или SIDHistory.

При этом значительно более массовой оказалась другая проблема — бессрочные пароли. Такой параметр обнаружен у 129 из 209 проверенных пользовательских объектов.

Также 78 учётных записей имели пароль старше установленного порога, а 41 активная учётная запись соответствовала критерию длительной неактивности.

Поиск и фильтры

При большом количестве результатов просматривать таблицу вручную неудобно, поэтому HTML-отчёт содержит поиск и набор фильтров.

Можно отдельно вывести:

  • критические результаты;
  • высокий риск;
  • средний риск;
  • информационные результаты;
  • привилегированные учётные записи;
  • сервисные учётные записи;
  • учётные записи с SPN;
  • неактивные учётные записи;
  • учётные записи с делегированием.
Как проверить опасные учётные записи в Active Directory с помощью PowerShell

Поиск работает совместно с выбранным фильтром.

Например, можно сначала оставить только сервисные учётные записи, а затем в строке поиска найти конкретное имя или параметр.

Почему в сводке и таблице могут быть разные цифры

Верхняя статистика по категориям рассчитывается по всем проверенным пользовательским объектам.

Основная таблица, напротив, по умолчанию не показывает результаты, имеющие только информационный уровень.

Поэтому возможна ситуация:


Учётные записи с SPN: 3

а в таблице без -IncludeInfo соответствующих строк будет меньше или не будет вообще.

Это не ошибка отчёта.

Сводка отвечает на вопрос: «Сколько таких объектов вообще обнаружено в домене?»

Таблица отвечает на другой вопрос: «Какие результаты сейчас выведены для детального анализа с учётом выбранного уровня?»

Предполагаемый тип учётной записи

В отчёте присутствует столбец Предполагаемый тип.


Пользователь
Сервисная
Привилегированная
Привилегированная / сервисная
Встроенная

Важно обратить внимание именно на слово «предполагаемый».

Active Directory не содержит универсального атрибута, который позволил бы безошибочно определить, что обычный пользовательский объект является сервисной учётной записью.

Поэтому скрипт оценивает ряд признаков и пытается определить наиболее вероятный тип объекта.

Эту классификацию следует использовать как вспомогательную.

Как читать результаты аудита

После выполнения аудита каждой учётной записи, для которой обнаружены интересующие нас признаки, назначается итоговый балл и уровень риска.

В отчёте используются четыре уровня:

  • Критический — Critical;
  • Высокий — High;
  • Средний — Medium;
  • Информационный — Info.

Как рассчитывается уровень риска

Признак Балл
Kerberos без Pre-Auth 45
Учётная запись с SPN 10
Бессрочный пароль 20
PasswordNotRequired 55
Обратимое шифрование пароля 55
Устаревший пароль 10
Неограниченное делегирование 65
Protocol Transition 40
Ограниченное делегирование 20
Длительная неактивность 10
SIDHistory 30
Исторический adminCount 10

Но простого сложения отдельных значений недостаточно. Некоторые сочетания признаков дополнительно повышают итоговый балл.

Сочетание Дополнительный балл
Найденные проблемы + привилегированная учётная запись +30
SPN + бессрочный пароль +30
SPN + устаревший пароль +30
Kerberos без Pre-Auth + привилегированная учётная запись +20

Максимальный итоговый балл ограничен значением 100.


80–100  Критический
50–79   Высокий
20–49   Средний
0–19    Информационный

Пример обычного пользователя

Если у обычного пользователя найден только бессрочный пароль:


Учётная запись:     user01
Тип:                Пользователь
Бессрочный пароль:  Да
Другие признаки:    Нет

Risk Score:         20
Уровень:            Средний

Это не означает, что учётная запись скомпрометирована. Скрипт лишь показывает отклонение, которое стоит проверить.

Пример привилегированной учётной записи


Учётная запись:     admin.ops
Тип:                Привилегированная
Группа:             Domain Admins
Бессрочный пароль:  Да
Возраст пароля:     620 дней

Расчёт:


Бессрочный пароль:          20
Устаревший пароль:          10
Привилегированная учётка:  +30

Итого:                      60
Уровень:                    Высокий

Проблемы с паролем те же, что и у обычного пользователя, но потенциальные последствия компрометации совершенно другие.

Пример сервисной учётной записи с SPN

Как проверить опасные учётные записи в Active Directory с помощью PowerShell

Представим сервисную учётную запись:


Учётная запись:     svc-sql
Тип:                Сервисная
SPN:                Да
Бессрочный пароль:  Да
Возраст пароля:     930 дней

Базовые значения:


SPN:                 10
Бессрочный пароль:   20
Устаревший пароль:   10

Дополнительные коэффициенты:


SPN + бессрочный пароль: +30
SPN + устаревший пароль: +30

Итог:


10 + 20 + 10 + 30 + 30 = 100

Risk Score: 100
Уровень:    Критический

Именно здесь хорошо видно, зачем потребовалась система оценки.

Сам по себе SPN получил бы всего 10 баллов и имел информационный уровень. Но SPN в сочетании с бессрочным паролем, который не менялся несколько лет, — совершенно другая ситуация.

При этом даже значение 100 не означает, что пароль уже подобран или учётная запись скомпрометирована. Оно говорит о том, что сочетание параметров делает объект приоритетным для дальнейшего анализа.

Почему adminCount не означает, что пользователь является администратором

Если adminCount = 1, но пользователь не обнаружен в проверяемых привилегированных группах, этот признак получает только небольшой вес:


adminCount = 1 → 10 баллов

Это сигнал для дополнительной проверки, а не доказательство текущих административных прав.

Что исправлять в первую очередь

После получения отчёта возникает естественное желание начать исправлять всё, что выделено как риск.

Но с Active Directory такой подход может создать больше проблем, чем решить.

Главный принцип: сначала определить назначение и зависимости учётной записи, затем изменять её параметры.

Критические результаты

Начинать стоит с учётных записей, получивших критический уровень.

Перед изменениями необходимо выяснить:

  • для чего используется учётная запись;
  • кто является её владельцем;
  • какие службы работают от её имени;
  • где сохранён её пароль;
  • используются ли задания планировщика;
  • есть ли зависимости в IIS, SQL Server или других приложениях;
  • действительно ли ей необходимы текущие привилегии;
  • можно ли перевести службу на gMSA.

Высокий риск

Следом проверяем результаты High.

Здесь необходимо проверить необходимость бессрочного пароля и обоснованность членства в административных группах.

Kerberos без Pre-Auth

Активные учётные записи с отключённой Kerberos Pre-Authentication требуют отдельного внимания.

Особенно высокий приоритет имеют такие учётные записи при одновременном наличии административных привилегий.

Неограниченное делегирование

TrustedForDelegation = True также стоит проверять в числе первых.

Необходимо определить:

  • какой сервис использует делегирование;
  • требуется ли оно до сих пор;
  • можно ли перейти на более ограниченную схему;
  • какие права имеет соответствующая учётная запись;
  • насколько защищён её пароль.

PasswordNotRequired и обратимое шифрование

Активные учётные записи с PasswordNotRequired = True или AllowReversiblePasswordEncryption = True требуют понимания причины появления таких параметров.

SIDHistory

Наличие SIDHistory требует не столько немедленного удаления атрибута, сколько понимания его происхождения.

Если в организации действительно проводилась миграция домена, наличие SIDHistory может быть ожидаемым.

Неактивные пользователи

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

Неактивные сервисные учётные записи

Сервисная учётная запись может использоваться:

  • службой Windows;
  • заданием планировщика;
  • пулом IIS;
  • системой резервного копирования;
  • SQL Server;
  • интеграцией;
  • скриптом;
  • внешним приложением.

Поэтому для сервисной учётной записи рекомендация должна начинаться с поиска владельца и зависимостей.

Правильная последовательность выглядит так:


Обнаружение
    ↓
Приоритизация
    ↓
Определение владельца
    ↓
Проверка назначения
    ↓
Проверка зависимостей
    ↓
Согласование изменений
    ↓
Исправление
    ↓
Повторный аудит

AD-SecurityAudit.ps1 закрывает первые два этапа — обнаружение и первичную приоритизацию.

Повторный запуск после исправлений

После устранения найденных проблем полезно запустить аудит повторно с теми же параметрами:


.\AD-SecurityAudit.ps1 `
    -InactiveDays 180 `
    -StalePasswordDays 365

Например, если до проведения работ было:


Высокий:   6
Средний: 125
Всего:   131

а после:


Высокий:   2
Средний:  87
Всего:    89

мы получаем простой способ оценить результат проведённой ревизии.

Сравнивать отчёты корректно только при одинаковых параметрах InactiveDays, StalePasswordDays и IncludeInfo.

Сервисные учётные записи и gMSA

Отдельного внимания в любом аудите Active Directory требуют сервисные учётные записи.

Именно для них чаще всего можно встретить:

  • PasswordNeverExpires = True;
  • пароль, который не менялся годами;
  • наличие SPN;
  • использование одной и той же учётной записи сразу несколькими службами;
  • неизвестного владельца;
  • отсутствие понятной документации по зависимостям.

Причина обычно простая.

Сервис работает под доменной учётной записью, её пароль прописан в службе, пуле приложений, задании планировщика или внешней системе. Если пароль изменить, сервис перестанет запускаться.

Поэтому администраторы нередко выбирают самый простой путь — устанавливают для такой учётной записи бессрочный пароль.

На практике это решает эксплуатационную проблему, но создаёт другую: пароль может не меняться несколько лет.

Почему ручная ротация сервисных паролей неудобна

Представим, что svc-backup используется на пяти серверах.

При смене пароля потребуется:

  1. изменить пароль в Active Directory;
  2. обновить пароль на каждом сервере;
  3. проверить службы;
  4. проверить задания;
  5. убедиться, что приложение действительно продолжает работать.

Если хотя бы одно место забыть, часть системы перестанет работать.

Один из вариантов решения этой проблемы — Group Managed Service Account, или gMSA.

Что такое gMSA

gMSA — управляемая сервисная учётная запись Active Directory.

Главное отличие от обычного сервисного пользователя заключается в том, что пароль такой учётной записи управляется автоматически.

Администратору не нужно самостоятельно придумывать пароль и затем вручную менять его во всех местах использования.

Что меняется с точки зрения нашего аудита

Обычные сервисные учётные записи являются объектами пользователей Active Directory.

Именно поэтому они попадают в:


Get-ADUser

gMSA относится к другому типу объектов Active Directory.

Для работы с такими учётными записями используется:


Get-ADServiceAccount

Например:


Get-ADServiceAccount -Filter * |
    Select-Object Name, SamAccountName, Enabled

Пример:


Name             SamAccountName     Enabled
----             --------------     -------
gmsa-sql01       gmsa-sql01$           True
gmsa-backup      gmsa-backup$          True
gmsa-web         gmsa-web$             True

Обратите внимание на символ $ в конце имени управляемой сервисной учётной записи.

Если приложение не поддерживает gMSA, это ещё не означает, что пароль должен оставаться неизменным навсегда.

В таком случае необходимо организовать контролируемую процедуру ротации с использованием длинного уникального пароля и заранее известного перечня всех зависимостей.

Ограничения скрипта

AD-SecurityAudit.ps1 задумывался как инструмент первичного аудита и приоритизации потенциально опасных пользовательских учётных записей.

Он не является полноценной системой анализа безопасности Active Directory и не заменяет специализированные средства аудита.

Проверяются только пользовательские объекты

Основной источник данных скрипта:


Get-ADUser

Соответственно, в текущей версии не выполняется полноценный анализ:

  • компьютерных учётных записей;
  • gMSA;
  • sMSA;
  • групп;
  • объектов Group Policy;
  • доверительных отношений;
  • ACL всех объектов каталога.

Например, компьютер также может иметь настройки делегирования, но такой объект текущий скрипт не проверит.

gMSA не входят в аудит

Получить их отдельно можно командой:


Get-ADServiceAccount -Filter *

Поэтому отсутствие gMSA в отчёте AD-SecurityAudit.ps1 является ожидаемым поведением.

LastLogonDate не является точным временем последнего входа

Для оценки неактивности используется свойство LastLogonDate.

Оно удобно для поиска пользователей, которыми давно не пользовались, но не предназначено для точного аудита времени последней аутентификации.

Предполагаемый тип учётной записи определяется эвристически

В Active Directory нет универсального свойства, которое позволяет однозначно определить обычный пользовательский объект как сервисную учётную запись.

Поэтому классификация:


Сервисная
Пользователь
Привилегированная
Привилегированная / сервисная
Встроенная

является вспомогательной и может ошибаться.

SPN не означает наличие уязвимости

Если отчёт показывает наличие SPN, это не означает, что учётная запись автоматически уязвима.

Особенно интересны комбинации:


SPN
+
PasswordNeverExpires
+
старый пароль

или:


SPN
+
привилегии

Risk Score является эвристикой

Баллы, которые рассчитывает скрипт, не являются отраслевым стандартом.

Risk Score = 80 не означает вероятность взлома 80% и не является эквивалентом CVSS 8.0.

Это исключительно механизм сортировки результатов по важности.

adminCount не используется как доказательство привилегий

Значение adminCount = 1 может сохраниться после удаления пользователя из защищённой административной группы.

Поэтому скрипт рассматривает его только как дополнительный исторический сигнал.

Проверяется ограниченный перечень привилегированных групп

Скрипт анализирует основные административные группы Active Directory, в том числе:


Domain Admins
Enterprise Admins
Schema Admins
Administrators
Account Operators
Server Operators
Backup Operators
Print Operators
Group Policy Creator Owners
DNSAdmins

Однако в конкретной организации могут существовать собственные группы с делегированными административными правами.

Например:


AD-HelpDesk-Admins
Server-Admins
Exchange-Admins
PKI-Admins
Virtualization-Admins

Такие корпоративные группы необходимо анализировать отдельно или добавлять в скрипт.

Скрипт не выполняет полный ACL-анализ

Пользователь может получить существенные возможности не только через членство в административной группе.

Например, права могут быть делегированы непосредственно через ACL объектов Active Directory.

Это могут быть права на:

  • изменение членов группы;
  • сброс пароля;
  • изменение определённых атрибутов;
  • управление организационным подразделением;
  • изменение разрешений.

Отсутствие пользователя в Domain Admins не гарантирует отсутствие у него опасных делегированных полномочий.

Результат аудита нужно проверять вручную

Скрипт отвечает на вопрос: «На какие учётные записи стоит обратить внимание?»

Но он не может достоверно ответить:

  • нужен ли этот аккаунт бизнесу;
  • можно ли его отключить;
  • можно ли прямо сейчас изменить пароль;
  • почему ему было назначено делегирование;
  • нужен ли ему SIDHistory;
  • какие приложения от него зависят.

Это уже требует знания конкретной инфраструктуры.

FAQ

Нужны ли права Domain Admins для запуска AD-SecurityAudit.ps1?

Нет. Скрипт выполняет операции чтения Active Directory, поэтому в стандартной конфигурации достаточно учётной записи с правами на чтение проверяемых объектов и атрибутов.

Изменяет ли AD-SecurityAudit.ps1 учётные записи Active Directory?

Нет. Скрипт не блокирует пользователей, не меняет пароли и членство в группах. Он собирает данные и формирует локальные HTML- и CSV-отчёты.

Означает ли наличие SPN, что учётная запись уязвима?

Нет. SPN является штатной частью Kerberos. Повышенного внимания требуют сочетания SPN с бессрочным или давно не менявшимся паролем, повышенными привилегиями и другими факторами риска.

Можно ли сразу отключать все неактивные учётные записи из отчёта?

Нет. Сначала необходимо определить владельца и назначение учётной записи, а для сервисных аккаунтов — проверить службы, задания планировщика, IIS, SQL Server и другие зависимости.

Почему LastLogonDate нельзя считать точным временем последнего входа?

Свойство LastLogonDate основано на реплицируемом атрибуте lastLogonTimestamp и подходит для поиска давно неиспользуемых учётных записей, но не для определения точного времени последней аутентификации.

Проверяет ли скрипт gMSA?

Нет. Текущая версия AD-SecurityAudit.ps1 ориентирована на пользовательские объекты, возвращаемые Get-ADUser. Управляемые сервисные учётные записи gMSA необходимо проверять отдельно через Get-ADServiceAccount.

Что означает Risk Score в отчёте?

Это внутренняя эвристическая оценка для приоритизации результатов. Она не является CVSS, вероятностью взлома или доказательством компрометации учётной записи.

Итог

Проверка безопасности учётных записей Active Directory не должна сводиться к поиску одного конкретного параметра. Наибольший интерес представляют сочетания нескольких факторов риска: бессрочный и давно не менявшийся пароль, повышенные привилегии, наличие SPN, отключённая Kerberos Pre-Authentication, делегирование или длительная неактивность учётной записи.

При этом результаты такого аудита нельзя воспринимать как готовый список учётных записей, которые необходимо немедленно отключить или изменить. Для каждого найденного объекта важно определить его назначение, владельца, используемые зависимости и только после этого принимать решение об изменении конфигурации. Особенно это касается сервисных и привилегированных учётных записей, где необдуманные изменения могут привести уже не к повышению безопасности, а к остановке сервисов.

Регулярный аудит позволяет постепенно убрать накопившиеся исключения, забытые учётные записи и устаревшие настройки, а главное — сосредоточиться в первую очередь на тех объектах, компрометация которых действительно может иметь серьёзные последствия для домена.

Вам понравилась эта статья? Тогда вам, скорее всего, будет интересна другая полезная статья Как настроить проверку и очистку DNS-записей в Active Directory.

ORIGINAL / ATTRIBUTION

Источник материала

Материал взят с https://sysadminhub.ru/. Оригинальная статья и авторство указаны по ссылке ниже.

Оригинал статьи на SysAdminHub.ru ↗

https://sysadminhub.ru/produkty-microsoft/windows-server/ad-security-audit-powershell

Материал проверен 10.10.2026. При изменении программного обеспечения сверяйтесь с актуальной документацией.
← Вернуться в базу знаний