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

В нашей статье основным инструментом позволяющим провести проверку безопасности AD будет PingCastle.

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

Установка PingCastle


Как сказано на сайте производителя, установка не требуется.

Скачиваем последний релиз на наш рядовой доменный ПК. Сейчас доступна версия 3.2.0.1. Распаковываем архив, запускаем PingCastle.exe.


Несколько раз нажимаем enter, соглашаясь на выбор нашего имени домена.
По окончании работы программы в папке запуска будет сформирован html файл, вида: ad_hc_example.domain.html.

Запускаем файл в любом браузере и удивляемся!


Общая оценка показывает максимальную уязвимость из 4-х доступных индикаторов:

Privileged accounts — про админов;
Trusts — связь между доменами;
Stale objects — про AD;
Security anomalies — всё остальное.

Как видно из рисунка наша инфраструктура по всем направлениям.
Начнём с самых критичных (выделено красным).

GoldenTicket


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

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

Нашей основной задачей будет закрыть данную уязвимость.

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

Kerberos password last changed: 2014-05-16 06:03:33Z version: 2

Используя PowerShell, мы можем получить более расширенную информацию:

Get-AdUser krbtgt -property created, passwordlastset, enabled


krbtgt — это сервисная учётная запись созданная автоматически при создании домена Active Directory. Данная учётная запись с RID 502 отключена, находится в контейнере Users и состоит в группах:

  • Domain Users
  • Denied RODC Password Replication Group

Best Practice говорит следующее:

  • Пароль от krbtgt рекомендуется менять один раз в год, в особых компаниях — два раза в год.
  • Пароль от krbtgt также рекомендуется менять после увольнения любого администратора домена.

И так, непосредственная смену пароля можно выполнить через оснастку RSAT «Пользователи и компьютеры Active Directory».

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

Переходим по ссылке и скачиваем:


Запускаем PowerShell ISE с правами админа и выполняем скрипт, если хотите почитать о продукте, пишем YES, в обратном случае NO.


Запуск буду производите в режиме «Симуляции», чтобы понять, насколько далеко и соответственно, как долго синхронизируются контроллеры. Встречаются случаи, когда не все контроллеры домена доступны, но это уже совершенно другая ситуация, в данной статье мы это не рассматриваем, самостоятельно загуглите команды представленные ниже, они запускаются от имени администратора.


dcdiag /fix
dcdiag /s:dc01 /test:dns /e
repadmin /replsummary
repadmin /showrepl
repadmin /syncall

Нажимаем цифру 2, далее указываем наш домен:


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


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


Запускаем скрипт снова, но на этот раз выбираем цифру 4.





Результат успешен, повторим начальный запрос в командной строке, видим что предыдущее время пароля изменилось.


Менять пароль нужно два раза подряд. Сменили первый раз, через час или 2 повторили смену пароля (дождались выполнения репликации в домене). В домене хранится текущий и предыдущий пароль, нам нужно заменить оба.

При смене пароля учетной записи krbtgt при задержках репликации могут наблюдаться проблемы некоторых доменных служб. После смены пароля вручную перезапустите службу Kerberos Key Distribution Center на всех контроллерах домена. PowerShell в помощь:

$DCs=Get-ADDomainController
Get-Service KDC –ComputerName $DCs | Restart-Service

Запускаем скрипт снова, выполняем так же цифры 4 и 2.

Захват аккаунта


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

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


Заходим в оснастку RSAT, «Пользователи и компьютеры AD», и каждому администратору из списка выше проставляем галочку, по аналогии:


Best Practice: Используется 2 или 3 учетки в домене.

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

Старый протокол аутентификации


Полностью отключить NTLM и перейти на Kerberos я пока не готов, поэтому переходим в GPO и отключаем NTLMv1.

Default Domain Controller Policy


Конфигурация компьютера->Политики->Конфигурация Windows->Параметры безопасности->Локальные политики->Параметры безопасности->Сетевая безопасность уровня проверки подлинности LAN Manager.

Устанавливаем значение:

Отправлять только NTLMv2.Отказывать LM и NTLMv1


Тоже самое проделываем в политике.

Default Domain Policy


После отключения возникает ошибка авторизации через RADIUS — это может повлиять у вас связку VPN, dot1x, Wi-fi, смотря у кого что используется.

When MS-CHAP or MS-CHAPv2 are configured, RAS in Windows Server 2008 R2 will default to NTLM to hash the password. Because the DC only accepts NTLMv2, the request will be denied

У меня всего два RADIUS сервера, я сделал ручками, но можно и через GPO.
Запускаем редактор реестра на сервере (regedit) и переходим по ветке:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\RemoteAccess\Policy

Создаём новый параметр Enable NTLMv2 Compatibility DWORD со значением 1:


Потенциально проблемы при отключении NTLMv1 могут быть у небольших опенсорсных продуктов, различных старых моделей сетевых сканеров (который складывают сканы в сетевые папки), некоторых NAS устройств и другого устаревшего оборудования, ПО и ОС.

У меня некоторые МФУ Kyocera перестали работать, складывать сканы на папку в шару, т. к. у нас отключается авторизация для SMBv1. Список устройств не поддерживающих SMB выше версии 1.

Не официальные администраторы


Атрибут adminCount определяет, является ли пользователь администратором. Однако, поскольку этот атрибут не сбрасывается Windows после удаления пользователя из административной («защищенной») группы, это иногда может приводить к неточным отчетам в PignCastle.

Как уже упоминалось ранее, пользовательские записи и администраторские должны быть разделены, в нашем случае в AD они разнесены по разным OU, например показан на следующем изображении.


Включаем дополнительные параметры:


Заходим в свойства нашей OU, нам потребуется параметр distinguishedName, копируем его, в следующий ниже скрипт для PowerShell ISE:


Get-ADObject -SearchBase 'OU=МО,DC=corp,DC=ru'  -LDAPFilter "(adminCount=1)"

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


Выполняем скрипт, учётку «admin» отключаем, проверяем 3-5 дней что она ни на что не влияет, потом удаляем.

Get-ADObject -SearchBase 'OU=МО,DC=corp,DC=ru'  -LDAPFilter "(adminCount=1)" | Set-ADObject -Clear adminCount

Kerberos со слабым шифрованием (алгоритм DES)


Сделаем запрос для понимая, где у нас используются старые алгоритмы:

Get-ADObject -Filter {UserAccountControl -band 0x200000 -or msDs-supportedEncryptionTypes -band 3}

Получили список серверов с использованием старого алгоритма:


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

Default Domain Policy


Конфигурация компьютера->Политики->Конфигурация Windows->Параметры безопасности->Локальные политики->Параметры безопасности->Сетевая безопасность: настройка типов шифрования, разрешённых Kerberos.

Устанавливаем значение:

  • RC4_HMAC_MD5
  • AES128_HMAC_SHA1
  • AES256_HMAC_SHA1
  • Будущие типы шифрования


Отключаем у пользователей поддержку DES алгоритма:


$users=Get-ADObject -Filter {msDs-supportedEncryptionTypes -band 3 -and (objectCategory -eq "computer") } | Select-Object -ExpandProperty Name 
foreach ($user in $users)
  {
    Set-ADComputer $User -Replace @{"msDS-SupportedEncryptionTypes"="28"}
 
 }

Обновление Windows


Узнаем каким ПК требуется обновление до версии 22H2:

Get-ADComputer -Filter {OperatingSystemVersion -Like "10.0 (10*"} -Property * | Format-Table Name,OperatingSystem,OperatingSystemServicePack,OperatingSystemVersion -Wrap -Auto

Я у себя развернул WSUS для автоматизированного обновления.

Принудительно импортируем обновления с помощью PS на wsus.
Открываем страничку, вбиваем в поиске искомую KB-шку, жамкаем загрузить, копируем ID:


Скопировал код скрипта с сайта Microsoft:

<#
.SYNOPSIS
Powershell script to import an update, or multiple updates into WSUS based on the UpdateID from the catalog.

.DESCRIPTION
This script takes user input and attempts to connect to the WSUS server.
Then it tries to import the update using the provided UpdateID from the catalog.

.INPUTS
The script takes WSUS server Name/IP, WSUS server port, SSL configuration option and UpdateID as input. UpdateID can be viewed and copied from the update details page for any update in the catalog, https://catalog.update.microsoft.com.

.OUTPUTS
Writes logging information to standard output.

.EXAMPLE
# Use with remote server IP, port and SSL
.\ImportUpdateToWSUS.ps1 -WsusServer 127.0.0.1 -PortNumber 8531 -UseSsl -UpdateId 12345678-90ab-cdef-1234-567890abcdef

.EXAMPLE
# Use with remote server Name, port and SSL
.\ImportUpdateToWSUS.ps1 -WsusServer WSUSServer1.us.contoso.com -PortNumber 8531 -UseSsl -UpdateId 12345678-90ab-cdef-1234-567890abcdef

.EXAMPLE
# Use with remote server IP, defaultport and no SSL
.\ImportUpdateToWSUS.ps1 -WsusServer 127.0.0.1  -UpdateId 12345678-90ab-cdef-1234-567890abcdef

.EXAMPLE
# Use with localhost default port
.\ImportUpdateToWSUS.ps1 -UpdateId 12345678-90ab-cdef-1234-567890abcdef

.EXAMPLE
# Use with localhost default port, file with updateID's
.\ImportUpdateToWSUS.ps1 -UpdateIdFilePath .\file.txt

.NOTES  
# On error, try enabling TLS: https://learn.microsoft.com/mem/configmgr/core/plan-design/security/enable-tls-1-2-client

# Sample registry add for the WSUS server from command line. Restarts the WSUSService and IIS after adding:
reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 /V SchUseStrongCrypto /T REG_DWORD /D 1

## Sample registry add for the WSUS server from PowerShell. Restarts WSUSService and IIS after adding:
$registryPath = "HKLM:\Software\Microsoft\.NETFramework\v4.0.30319"
$Name = "SchUseStrongCrypto"
$value = "1" 
if (!(Test-Path $registryPath)) {
    New-Item -Path $registryPath -Force | Out-Null
}
New-ItemProperty -Path $registryPath -Name $name -Value $value -PropertyType DWORD -Force | Out-Null
Restart-Service WsusService, w3svc

# Update import logs/errors are under %ProgramFiles%\Update Services\LogFiles\SoftwareDistribution.log

#>

param(
    [Parameter(Mandatory = $false, HelpMessage = "Specifies the name of a WSUS server, if not specified connects to localhost")]
    # Specifies the name of a WSUS server, if not specified connects to localhost.
    [string]$WsusServer,

[Parameter(Mandatory = $false, HelpMessage = "Specifies the port number to use to communicate with the upstream WSUS server, default is 8530")]
    # Specifies the port number to use to communicate with the upstream WSUS server, default is 8530.
    [ValidateSet("80", "443", "8530", "8531")]
    [int32]$PortNumber = 8530,

[Parameter(Mandatory = $false, HelpMessage = "Specifies that the WSUS server should use Secure Sockets Layer (SSL) via HTTPS to communicate with an upstream server")]
    # Specifies that the WSUS server should use Secure Sockets Layer (SSL) via HTTPS to communicate with an upstream server.  
    [Switch]$UseSsl,

[Parameter(Mandatory = $true, HelpMessage = "Specifies the update Id we should import to WSUS", ParameterSetName = "Single")]
    # Specifies the update Id we should import to WSUS
    [ValidateNotNullOrEmpty()]
    [String]$UpdateId,

[Parameter(Mandatory = $true, HelpMessage = "Specifies path to a text file containing a list of update ID's on each line", ParameterSetName = "Multiple")]
    # Specifies path to a text file containing a list of update ID's on each line.
    [ValidateNotNullOrEmpty()]
    [String]$UpdateIdFilePath
)

Set-StrictMode -Version Latest

# set server options
$serverOptions = "Get-WsusServer"
if ($psBoundParameters.containsKey('WsusServer')) { $serverOptions += " -Name $WsusServer -PortNumber $PortNumber" }
if ($UseSsl) { $serverOptions += " -UseSsl" }

# empty updateID list
$updateList = @()

# get update id's
if ($UpdateIdFilePath) {
    if (Test-Path $UpdateIdFilePath) {
        foreach ($id in (Get-Content $UpdateIdFilePath)) {
            $updateList += $id.Trim()
        }
    }
    else {
        Write-Error "[$UpdateIdFilePath]: File not found"
		return
    }
}
else {
    $updateList = @($UpdateId)
}

# get WSUS server
Try {
    Write-Host "Attempting WSUS Connection using $serverOptions... " -NoNewline
    $server = invoke-expression $serverOptions
    Write-Host "Connection Successful"
}
Catch {
    Write-Error $_
    return
}

# empty file list
$FileList = @()

# call ImportUpdateFromCatalogSite on WSUS
foreach ($uid in $updateList) {
    Try {
        Write-Host "Attempting WSUS update import for Update ID: $uid... " -NoNewline
        $server.ImportUpdateFromCatalogSite($uid, $FileList)
        Write-Host "Import Successful"
    }
    Catch {
        Write-Error "Failed. $_"
    }
}

Теперь в папке Temp, в корне диска, лежит скрипт ImportUpdateToWSUS.ps1.

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

PS C:\Windows\system32> cd /temp
PS C:\temp> .\ImportUpdateToWSUS.ps1 -UpdateId 304891ed-9464-4dc0-b7f7-7d8fe5ec9c48

Чтобы импортировать несколько обновлений в WSUS, вставьте идентификаторы обновлений для каждого обновления, которое вы хотите импортировать в текстовый файл. Укажите по одному идентификатору обновления в строке, а затем сохраните текстовый файл, когда закончите. Используйте место, к которому вы можете легко получить доступ, например

C:\temp\UpdateIDs.txt.

Моё содержимое файла:

  • a9cdb394-9543-44ec-a1c0-a87a6818591e
  • 7b3d4fe2-808a-44f4-b1c7-3000a27b152a
  • a7c19c3f-d7d4-4101-897b-8483e6b2e0fa
  • 18c76ec3-0f7c-47e0-a8c1-0c54c3701574
  • ce1d40fd-3564-4f85-80a7-e09b8284f706
  • 75447a4f-2c6a-45a9-b534-e834d1a9a7b6
  • 76fa5373-59c3-4d98-984c-6d87354143cf
  • cf5b7ab3-1684-4893-a334-506fd026d1a6
  • a4c2c302-83c4-446f-86da-81d5cc60dd4b
  • 9fe9f22d-6cb2-4e81-a8ef-c4aee8567057
  • a8761130-35b6-41ce-8b67-2d35bb2d0846
  • 95c2fae9-219b-4a7c-b664-a6001bc86770
  • 5c6647e5-7fe4-44ba-865b-ae89bc401f8c
  • 628f5572-7e1a-4934-b864-3e6e24d3c758
  • 7ed43de3-a2f4-475d-a717-daa30b0a3b9f
  • 306f7ec0-e61f-46f6-a58b-ba9de2ebc3b9
  • 3233e02a-6344-434a-9aa0-a7881922fc6f
  • b9f238e7-174f-45d1-864f-afd116298e86
  • b0734db4-1a11-424e-81f8-f790533364ee
  • 89b4b2cb-b8a7-4776-85df-e720c141d593
  • 4bfa124f-768b-47d4-95f6-77527e742fb3
  • 06e3fc11-4baa-47b7-b77f-5bbd228a7317
  • e803564f-ebbc-4071-8d14-ee91b1b0b273
  • 8e032b68-2486-4055-ba64-73b0d1a066a8
  • ff78369c-f1f7-40de-b618-c477865ac33a
  • 97a22ca6-050f-42aa-8b12-bf868ac2b226
  • 37521dc6-417e-4479-8566-a0b551de2a9b
  • b8456653-68d5-4bbf-bb44-aff5aa1294ec
  • 0f2d7e37-31a5-4f17-b464-59ace1689368
  • d9c1caa5-b4c1-427c-886c-828e20b56530
  • 714316fa-f6db-4450-ab54-ebf60dbc19bd
  • d1180485-3b02-4bdf-bc29-801d1ccb4a51
  • bf3f6db9-f329-4144-b850-73979a3974f4
  • 6427d3da-6eb6-46c3-b34f-42c14a13d485
  • eba09cd1-3065-45c7-89c9-db88a14a229a
  • b5c740bd-cb0c-42bb-8046-820cf49161b2
  • b7c0a052-db76-4081-ae2c-58ab20714d39
  • 88d004ff-2072-4722-a760-fc3e59fefb63
  • 30587323-eed8-4a09-b3a9-0d3324c382c5
  • ee5f536a-3628-4d23-b88d-aa31f3689024
  • 0d469809-72d2-412a-83a3-29b9175a8469
  • b5230a04-28a0-4377-a02f-69542e2e928f
  • b41f8c80-ee6b-4466-8b80-c7d805fafced
  • 454bebbc-d20d-4ac1-953e-52d57054d474
  • b6d12270-95f0-4636-a8df-54282bae82f7
  • 88c70949-b5ed-4206-a766-90d66d96cc35
  • d0acfca2-bf20-4fd3-b5d3-6286f4f21c69
  • ff9034de-6475-4eed-9006-2c89d65c3730
  • ca01a16e-432e-452d-ad43-efe9b94f3c64
  • 6a8d6989-0f05-4af9-bf66-b3e322bdff2b
  • 790330b8-da5c-47f2-82f3-38ad0326e682
  • d267bdc0-033b-45c7-a32e-030ace20c29a
  • 20475448-8a02-4d47-94b4-466c50bf506c
  • 1f687c65-d108-4fcd-aba0-3942ce9a8c1f
  • f6c6e642-b604-4ab9-ab8b-4cbf1307b3c7
  • 10fc11b7-fbff-4c24-a7e7-8794952626c7
  • f39116ae-d925-4d35-b3f7-191f3382e4b0
  • 560f7047-07d7-4af3-bd44-d7fb294145f4
  • dc463771-a79d-41b1-bb08-85fe4943136a
  • 790330b8-da5c-47f2-82f3-38ad0326e682
  • d354f89a-5c8e-4bf6-826e-59f2b53882bb
  • a0802032-eb5b-48b3-bbe6-4b05ba4aea5f
  • 06b65dc9-c1ea-4a63-97f3-22989d748291
  • 903cd787-a7cf-455c-b195-9bf122df94d8
  • 2964d7dd-8ba6-4c3e-992c-e154a1008cce
  • d24f2611-9859-40c3-b3b7-d8d0692118e5
  • 461c417d-8a23-4bce-bb26-de4cc095bedb

Импортируем несколько обновлений на сервер WSUS с включённым SSL следующим синтаксисом:

PS C:\Windows\system32> cd /temp
PS C:\temp> .\ImportUpdateToWSUS.ps1 -WsusServer wsus.corp.ru -PortNumber 8531 -UseSsl -UpdateIdFilePath C:\temp\UpdateIDs.txt

Если SSL не включен, то:

PS C:\Windows\system32> cd /temp
PS C:\temp> .\ImportUpdateToWSUS.ps1 -WsusServer wsus.corp.ru -PortNumber 8530 -UpdateIdFilePath C:\temp\UpdateIDs.txt

Далее запускаем синхронизацию в ручном режиме:

```js
reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NetFramework\v4.0.30319 /V SchUseStrongCrypto /T REG_DWORD /D 1
```
Чтобы изменения вступили в силу, необходимо перезапустить сервер. После этого импорт обновлений в WSUS должен работать.

Если будет «Служба WSUS» автоматически завершаться, то изучите эту статью.

Спасибо за внимание, на этом всё!

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

Список используемых источников:



Новости, обзоры продуктов и конкурсы от команды Timeweb.Cloud — в нашем Telegram-канале





? Читайте также:

Комментарии (9)


  1. fat_dude
    21.08.2024 14:37
    +2

    О, а я и не знал что виндовый radius можно починить. Просто выкинул его, как и active directory. Надо будет дома ещё разок попробовать. Спасибо за наводочку!

    Блин, раздражает MS своим подходом, честно говоря. Протокол (ntlmv1) старый, небезопасный, почему бы не выключить его по умолчанию, и так, чтоб не ломались основные компоненты продукта за сотни нефти? Нет блин, догадывайся сам, ещё и в их этом реестре попробуй что-то найти.


    1. WarP
      21.08.2024 14:37

      Мне кажется, если сейчас развернуть АД из последнего свежего дистро - он там будет выключен. У автора поста , учитывая что пароль керберос не менялся с 2014 - скорее всего это стоит на 2012 винде, а 10-12 лет назад нтлмв1 еще как-то где-то мог использоваться.


  1. DikSoft
    21.08.2024 14:37
    +1

    Через раз наблюдаю у компаний ещё и такой ляп: разрешение регистрации в домене станций простым пользователям. 0 в квоту админы забывают прописывать:

    ms-DS-MachineAccountQuota


    1. Mur81
      21.08.2024 14:37
      +1

      Это через политику делается, что мне кажется корректнее.


      1. xxxkms
        21.08.2024 14:37

        Какую политику?


        1. Mur81
          21.08.2024 14:37

          Политикой накатываемой на контроллеры домена (можно в "Default Domain Controllers Policy"): Конфигурация компьютера -> Политики -> Конфигурация Windows -> Параметры Безопасности -> Локальные политики -> Назначение прав пользователя - Добавление рабочих станций к домену: Администраторы домена (или кому там нужен доступ)


  1. navion
    21.08.2024 14:37
    +2

    Менять пароль нужно два раза подряд. Сменили первый раз, через час или 2 повторили смену пароля (дождались выполнения репликации в домене).

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


  1. WarP
    21.08.2024 14:37

    Почему не включить флаг NTLMv2 compatibility ДО выключения нтлмв1 ?
    Зачем в статье список всех апдейтов на ВАШЕЙ системе?


  1. romin1952
    21.08.2024 14:37
    +1

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