Persisting Active Directory, part 2

Persisting Active Directory, part 2

@cherepawwka

Всем привет!

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

Persisting Active Directory

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

Схема атакуемой сети представлена на рисунке ниже:

Схема атакуемой сети

Продолжим!


Закрепление через сетрификаты

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

Последние два метода закрепления были основаны на учетных данных. Хотя мы определенно можем усложнить жизнь группе ИБ, они могут в конечном итоге изменить все учетные данные, чтобы выгнать нас. Таким образом, мы должны использовать методы закрепления, которые не зависят от учетных данных, а это означает, что их смена не сможет выкинуть нас из домена. Первый из таких методов — это сертификаты.

Возвращение AD CS

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

В зависимости от нашего доступа, мы можем продвинуться ещё дальше. Мы могли бы просто украсть закрытый ключ сертификата корневого ЦС, чтобы генерировать наши собственные сертификаты, когда захотим. Хуже того, поскольку эти сертификаты никогда не выдавались центром сертификации, синяя команда не имеет возможности их отозвать. Это делает ситуацию катастрофической, поскольку это означало бы "ротацию" ЦС (все выданные сертификаты должны быть отозваны, чтобы выгнать злоумышленника из сети).

Извлечение закрытого ключа

Закрытый ключ ЦС хранится на самом сервере ЦС. Если закрытый ключ не защищен с помощью аппаратных методов защиты, таких как аппаратный модуль безопасности (Hardware Security Module, HSM), что часто имеет место в организациях, которые просто используют Active Directory Certificate Services (AD CS) для внутренних целей, он защищен Data Protection API (DPAPI). Это означает, что мы можем использовать такие инструменты, как Mimikatz и SharpDPAPI, для извлечения сертификата ЦС и, следовательно, закрытого ключа из ЦС. Mimikatz — самый простой в использовании инструмент (если хотите испытать другие инструменты, загляните сюда).

Для этой задачи мы авторизуемся на THMDC.za.tryhackme.loc, используя учетные данные администратора домена. Запустим Mimikatz:

C:\Users\Cherepawwka>C:\Tools\mimikatz_trunk\x64\mimikatz.exe

Давайте сначала посмотрим, можем ли мы просмотреть сертификаты, хранящиеся на контроллере домена :

mimikatz # crypto::certificates /systemstore:local_machine
Просмотр сертификатов

Мы видим, что на DC есть сертификат CA. В задаче также отмечается, что некоторые из этих сертификатов были настроены так, чтобы мы не могли экспортировать ключ. Без этого закрытого ключа мы не смогли бы генерировать новые сертификаты. К счастью, Mimikatz позволяет нам исправить память, чтобы сделать эти ключи экспортируемыми:

mimikatz # privilege::debug
mimikatz # crypto::capi
mimikatz # crypto::cng
Патчим с mimi

После исправления этих сервисов мы можем использовать Mimikatz для экспорта сертификатов:

mimikatz # crypto::certificates /systemstore:local_machine /export
Экспорт сертификатов

Экспортированные сертификаты будут храниться на диске в формате PFX и DER:

Сертификат za-THMDC-CA.pfx — это то, что нас особенно интересует. Чтобы экспортировать закрытый ключ, необходимо использовать пароль для шифрования сертификата. По умолчанию Mimikatz назначает пароль mimikatz. Загрузим этот сертификат на атакующую машину с помощью SCP, а затем скопируем его в домашний каталог пользователя с низким уровнем привилегий на THMWRK1:

scp za\\Administrator@thmdc.za.tryhackme.loc:C:/Users/Cherepawwka/local_machine_My_1_za-THMDC-CA.pfx .
Загрузка сертификата на атакующую машину
scp local_machine_My_1_za-THMDC-CA.pfx za\\Administrator@thmwrk1.za.tryhackme.loc:C:/Users/Cherepawwka/za-THMDC-CA.pfx
Переброс сертификата на thmwrk1
Содержимое папки на thmwrk1

Создание собственных сертификатов

Теперь, когда у нас есть закрытый ключ и корневой сертификат ЦС, мы можем использовать инструмент SpectorOps ForgeCert для подделки сертификата проверки подлинности клиента для любого пользователя, которого захотим. Давайте используем ForgeCert для создания нового сертификата:

C:\Tools\ForgeCert\ForgeCert.exe --CaCertPath za-THMDC-CA.pfx --CaCertPassword mimikatz --Subject CN=User --SubjectAltName Administrator@za.tryhackme.loc --NewCertPath fullAdmin.pfx --NewCertPassword Password123 

Объяснение параметров:

  • CaCertPath — путь к нашему экспортированному сертификату ЦС;
  • CaCertPassword — пароль, используемый для шифрования сертификата. По умолчанию Mimikatz назначает пароль mimikatz;
  • Subject — субъект или обычное имя сертификата. Это не имеет большого значения в контексте того, для чего мы будем использовать сертификат;
  • SubjectAltName — это основное имя пользователя (UPN) учетной записи, которую мы хотим олицетворять с помощью этого сертификата. Это должен быть легитимный пользователь;
  • NewCertPath — путь, по которому ForgeCert будет хранить сгенерированный сертификат;
  • NewCertPassword — поскольку для сертификата потребуется секретный ключ, экспортированный для целей аутентификации, мы должны установить новый пароль, используемый для его шифрования.
Выпуск сертификата

Мы можем использовать Rubeus для запроса TGT с использованием сертификата, чтобы убедиться, что сертификат является доверенным. Мы будем использовать следующую команду:

C:\Tools\Rubeus.exe asktgt /user:Administrator /enctype:aes256 /certificate: /password: /outfile: /domain:za.tryhackme.loc /dc:

Разберем параметры:

  • /user — указывает пользователя, которого мы будем олицетворять, и должен соответствовать имени участника-пользователя для созданного нами сертификата;
  • /enctype — указывает тип шифрования билета. Установка этого значения важна для уклонения, так как алгоритм шифрования по умолчанию слаб, что приведет к предупреждению о превышении хеш-значения;
  • /certificate — путь к сгенерированному нами сертификату;
  • /password — пароль для нашего файла сертификата;
  • /outfile — файл, в который будет выводиться наш TGT;
  • /domain — полное доменное имя домена, который мы сейчас атакуем;
  • /dc — IP-адрес контроллера домена, с которого мы запрашиваем TGT. Обычно лучше выбрать контроллер домена, на котором запущена служба ЦС.

Как только мы выполним команду, мы должны получить наш TGT :

Терминал

C:\Tools\Rubeus.exe asktgt /user:Administrator /enctype:aes256 /certificate:fullAdmin.pfx /password:Password123 /outfile:administrator.kirbi /domain:za.tryhackme.loc /dc:10.200.61.101
Запрос TGT
Полученный TGT

Теперь мы можем использовать Mimikatz для загрузки TGT и аутентификации в THMDC:

C:\Tools\mimikatz_trunk\x64\mimikatz.exe
mimikatz # kerberos::ptt administrator.kirbi
Pass-The-Ticket
Билеты активной сессии
PoC

Мы больше не друзья с синей командой

Защита от закрепления с использованием сертификатов значительно сложнее. Даже если защита поменяет учетные данные скомпрометированной учетной записи, сертификат останется действительным. Единственный способ устранить присутствие злоумышленника — отозвать сертификат. Однако это было бы возможно только в том случае, если бы мы сгенерировали сертификат законным путём. Поскольку мы экспортировали ЦС и сами создали сертификат, он не отображается в списке выданных сертификатов AD CS, а это означает, что синяя команда не сможет отозвать наш сертификат.

Итак, какое единственное решение для ликвидации присутствия злоумышленника? Ну, поэтому мы больше не друзья с сотрудниками ИБ :) Им придется отозвать корневой сертификат CA. Но отзыв этого сертификата означает, что все сертификаты, выданные AD CS, внезапно станут недействительными. Это означает, что им придется создавать новый сертификат для каждой системы, использующей AD CS. Теперь вы должны начать понимать, почему такой способ закрепления невероятно опасен и потребует полной перестройки сети.


Закрепление через историю SID

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

Легитимный вариант использования истории SID — предоставить доступ для эффективного клонирования учетной записи в другую. Это становится полезным, когда организация осуществляет миграцию AD, поскольку такой механизм позволяет пользователям сохранить доступ к исходному домену во время миграции на новый. В новом домене у пользователя будет новый SID, но мы можем добавить существующий SID пользователя в историю SID, что по-прежнему позволит ему получать доступ к ресурсам в предыдущем домене, используя новую учетную запись. Хотя история SID хороша для миграций, мы, как злоумышленники, также можем злоупотреблять этой функцией для сохранения.

История может быть такой, какой мы хотим ее видеть

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

  • Обычно для выполнения этой атаки нам требуются права администратора домена или их эквивалент;
  • Когда учетная запись создает событие входа в систему, идентификаторы безопасности, связанные с учетной записью, добавляются к маркеру пользователя, который затем определяет привилегии, связанные с учетной записью. Макрер включает SID групп;
  • Мы можем пойти дальше, используя эту атаку, если внедрим SID Enterprise Admin, поскольку это повысит привилегии учетной записи до уровня администратора домена во всех доменах леса;
  • Поскольку идентификаторы безопасности добавляются к токену пользователя, привилегии будут соблюдаться, даже если учетная запись не является членом фактической группы. Это очень хитрый метод закрепления. У нас есть все разрешения, необходимые для компрометации всего домена (возможно, всего леса), но наша учетная запись может быть просто обычной учетной записью пользователя с членством только в группе «Пользователи домена». Мы можем поднять скрытность на другой уровень, всегда используя эту учетную запись для изменения истории SID другой учетной записи, поэтому первоначальный вектор присутствия не так легко обнаружить и исправить.

Forging History

Здесь я буду использовать сеанс на THMDC от имени администратора домена. Прежде чем мы подделаем историю SID, давайте сначала получим некоторую информацию о SID. Во-первых, давайте удостоверимся, что у нашего пользователя с низким уровнем привилегий в настоящее время нет никакой информации в его истории SID:

Get-ADUser louis.cole -properties sidhistory,memberof
Запрос истории SID нашего пользователя

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

Get-ADGroup "Domain Admins"

DistinguishedName : CN=Domain Admins,CN=Users,DC=za,DC=tryhackme,DC=loc
GroupCategory     : Security
GroupScope        : Global
Name              : Domain Admins
ObjectClass       : group
ObjectGUID        : 3a8e1409-c578-45d1-9bb7-e15138f1a922
SamAccountName    : Domain Admins
SID               : S-1-5-21-3885271727-2693558621-2658995185-512
SID DA

Мы могли бы использовать что-то вроде Mimikatz для добавления истории SID. Однако в последней версии Mimikatz есть недостаток, который не позволяет исправлять LSASS для обновления истории SID. Следовательно, нам нужно использовать что-то еще. В этом случае мы будем использовать инструменты DSInternals, чтобы напрямую исправить файл ntds.dit, базу данных AD, в которой хранится вся информация:

> Stop-Service -Name ntds -force
> Add-ADDBSidHistory -SamAccountName louis.cole -SidHistory S-1-5-21-3885271727-2693558621-2658995185-512 -DatabasePath C:\Windows\NTDS\ntds.dit 
> Start-Service -Name ntds  
Исправление NTDS.dit

База данных NTDS блокируется во время работы службы NTDS. Чтобы исправить нашу историю SID, мы должны сначала остановить службу. 

После выполнения этих шагов давайте подключимся к THMWRK1 по SSH с нашими учетными данными с низким уровнем привилегий и убедимся, что история SID была добавлена ​​и что теперь у нас есть права администратора домена:

Терминал

Get-ADUser aaron.jones -Properties sidhistory 
dir \\thmdc.za.tryhackme.loc\c$ 
Появившаяся история SID
PoC

Судя по приведенному выше выводу, атака сработала. Мы смогли подделать историю SID, предоставив нашей учетной записи с низким уровнем привилегий доступ DA!

Что же делать синей команде?

Если использовать оснастку «AD Users and Groups», мы могли бы увидеть атрибут SID history, добавленный пользователю. Однако даже с максимально возможными привилегиями мы не сможем удалить этот атрибут, поскольку он защищен. Чтобы удалить его, придется использовать такие инструменты, как командлеты AD-RSAT PowerShell для удаления истории SID.

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

Представим, что мы — синяя команда, занимающаяся расследованием и ликвидацией последствий инцидента. Мы дважды изменили пароль учетной записи krbtgt, удалили золотые и серебряные билеты и перестроили весь сервер ЦС с нуля, просто чтобы увидеть, что злоумышленник все еще выполняет команды, доступные DA, из-под учетной записи с низким уровнем привилегий. День говна, получается..


Закрепление через членство в группе

Если мы не хотим вмешиваться в историю SID, мы можем просто добавить себя непосредственно в группы AD для закрепления в домене. Несмотря на то, что история SID — отличный метод закрепления, ротация учетных данных и очистка все же могут лишить нас доступа к домену. В некоторых случаях может быть лучше закрепиться, ориентируясь на сами группы AD.

Закрепление через группы

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

  • Группу IT Support можно использовать для получения привилегий, таких как принудительное изменение паролей пользователей. Хотя в большинстве случаев мы не сможем изменить пароли привилегированных пользователей, возможность изменить даже пользователей с низким уровнем привилегий может позволить нам перемещаться по рабочим станциям;
  • Группы, предоставляющие права локального администратора, часто не контролируются так тщательно, как защищенные группы. Имея права локального администратора на правильные хосты через членство в такой группе, мы можем получить хорошую точку опоры, которую можно использовать для повторной компрометации домена;
  • Не всегда речь идет о прямых привилегиях. Иногда группы с косвенными привилегиями, такими как владение объектами групповой политики (GPO), могут быть столь же хороши для закрепления.

Вложенные группы

В большинстве организаций существует значительное количество рекурсивных групп. Рекурсивная группа — это группа, которая является членом другой группы. Вложенность групп используется для создания более организованной структуры в AD. Возьмем, к примеру, группу IT Support. ИТ-поддержка — очень общее понятие. Так что, возможно, под этой группой есть подгруппы, такие как Helpdesk, Access Card Managers и Network Managers. Мы можем добавить все эти группы в качестве членов в группу IT Support, что дает всем пользователям в этих подгруппах разрешения и привилегии, связанные с группой IT Support, но затем мы можем назначить более детальные разрешения и привилегии для каждой из подгрупп.

Хотя вложение групп помогает организовать AD, оно снижает видимость фактического доступа. Возьмем снова наш пример ИТ-поддержки. Если мы запросим у AD членство в группе IT Support, она ответит числом три. Однако этот подсчет не совсем верен, поскольку это три группы. Чтобы получить представление об эффективном доступе, теперь нам нужно также перечислить эти подгруппы. Но эти подгруппы также могут иметь подгруппы. Таким образом, возникает вопрос: «Сколько уровней глубины мы должны перечислить, чтобы получить реальный эффективный номер доступа?»

Это также становится проблемой мониторинга. Предположим, например, что у нас есть алерт, который срабатывает, когда новый член добавляется в группу Domain Admins. Это хорошее предупреждение, но оно не сработает, если пользователь будет добавлен в подгруппу в группе Domain Admins. Это очень распространенная проблема, поскольку AD управляется командой администраторов, а оповещением и мониторингом занимается группа SOC.

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

Закрепляемся через вложенность

Давайте смоделируем этот тип закрепления. Для этого создадим несколько собственных групп. Давайте начнем с создания новой базовой группы, которую мы скроем в People->IT Organizational Unit (OU). Для этого используем административный доступ на контроллере домена:

New-ADGroup -Path "OU=IT,OU=People,DC=ZA,DC=TRYHACKME,DC=LOC" -Name "Cherepawwka Net Group 1" -SamAccountName "cherepawwka_nestgroup1" -DisplayName "Cherepawwka Nest Group 1" -GroupScope Global -GroupCategory Security
Создание группы

Давайте теперь создадим еще одну группу в OU People->Sales и добавим нашу предыдущую группу в качестве члена:

New-ADGroup -Path "OU=SALES,OU=People,DC=ZA,DC=TRYHACKME,DC=LOC" -Name "<username> Net Group 2" -SamAccountName "<username>_nestgroup2" -DisplayName "<username> Nest Group 2" -GroupScope Global -GroupCategory Security 

Add-ADGroupMember -Identity "<username>_nestgroup2" -Members "<username>_nestgroup1"
Создание вложенных групп

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

New-ADGroup -Path "OU=CONSULTING,OU=PEOPLE,DC=ZA,DC=TRYHACKME,DC=LOC" -Name "cherepawwka Net Group 3" -SamAccountName "cherepawwka_nestgroup3" -DisplayName "cherepawwka Nest Group 3" -GroupScope Global -GroupCategory Security
Add-ADGroupMember -Identity "cherepawwka_nestgroup3" -Members "cherepawwka_nestgroup2"

New-ADGroup -Path "OU=MARKETING,OU=PEOPLE,DC=ZA,DC=TRYHACKME,DC=LOC" -Name "cherepawwka Net Group 4" -SamAccountName "cherepawwka_nestgroup4" -DisplayName "cherepawwka Nest Group 4" -GroupScope Global -GroupCategory Security
Add-ADGroupMember -Identity "cherepawwka_nestgroup4" -Members "cherepawwka_nestgroup3"

New-ADGroup -Path "OU=IT,OU=PEOPLE,DC=ZA,DC=TRYHACKME,DC=LOC" -Name "cherepawwka Net Group 5" -SamAccountName "cherepawwka_nestgroup5" -DisplayName "cherepawwka Nest Group 5" -GroupScope Global -GroupCategory Security
Add-ADGroupMember -Identity "cherepawwka_nestgroup5" -Members "cherepawwka_nestgroup4"
Ещё большее вложенных групп

Теперь давайте добавим последнюю группу в группу администраторов домена:

Add-ADGroupMember -Identity "Domain Admins" -Members "cherepawwka_nestgroup5"
Добавление нашей группы в группу администраторов домена

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

Add-ADGroupMember -Identity "cherepawwka_nestgroup1" -Members "louis.cole"
Добавление пользователя в группу

Мгновенно наш пользователь с низким уровнем привилегий теперь имеет привилегированный доступ к THMDC. Давайте проверим это, используя наш SSH-терминал на THMWRK1:

dir \\thmdc.za.tryhackme.loc\c$\ 
PoC

Давайте также проверим, что, несмотря на то, что мы создали несколько групп, в группе «Администраторы домена» есть только один новый член:

Get-ADGroupMember -Identity "Domain Admins"
Членство в группе
Пасьянс из групп

Боль синей команды

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


На этом вторая часть завершается. Вторая часть статьи доступна по ссылке ниже:

Пишет эксплоент, чтобы взломать вас

Report Page