BloodHound — это популярный инструмент, который используется для сбора и анализа данных во время проведения пентеста внутренней инфраструктуры на базе Active Directory. Этот инструмент позволяет визуализировать некорректные настройки объектов Active Directory и строить цепочки атак. Основная особенность — это использование теории графов при анализе данных.

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

Обычно администраторы добавляют членов в группу локальных администраторов через групповые политики. Обычно это происходит через Restricted Group или Group Police Preferences. Но есть еще один небезопасный способ. Локальный администратор добавляется через групповые политики, а точнее – через запуск скрипта, который создает локальную учетную запись и добавляет ее в группу локальных администраторов. В данном случае пароль от учетной записи локального администратора хранится в открытом виде.

Скрипты для групповых политик могут быть наследием, а по факту тот или иной скрипт может уже давно не использоваться. Также одни групповые политики могут перекрывать другие. Проверить, используется ли скрипт в групповой политике, можно с помощью PowerView:

Get-DomainGPO -Identity <GUID>

GUID – идентификатор групповой политики. В выводе стоит обратить внимание на атрибут gpcmachineextensionnames: если в нем присутствуют 42B5FAAE-6536-11D2-AE5A-0000F87571E3 – ProcessScriptsGroupPolicy и 40B6664F-4972-11D1-A7CA-0000F87571E3 - Scripts (Startup/Shutdown), то скрипт выполняется при применении групповой политики.

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

Для начала потребуется создать новый Label, под название LocalUser с именем и паролем, указанными в скрипте. А также необходимо сгенерировать новый uuid для свойства objectid – это можно сделать с помощью Powershell - [guid]::NewGuid().

Теперь можно создать узел локального администратора, запрос cypher будет следующим:

MERGE (:LocalUser {name: "LOCALADMIN", password:"Qwerty123", objectid:"f04064f5-c9b1-4112-988c-1ed6af915fbc"})

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

MATCH (l:LocalUser) RETURN l

 

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

MATCH (g:GPO) WHERE g.gpcpath CONTAINS "0D7D58C6-7F3C-41FD-B4A3-E8F3A696D1DB"

MATCH (l:LocalUser) WHERE l.name = "LOCALADMIN"

MERGE (g)-[:CreateUser]->(l)

Данный запрос стоит рассмотреть подробнее. Первый запрос выбирает из всей базы neo4j групповую политику, которая содержит в свойстве pgcpath идентификатор групповой политики. Второй запрос выбирает из базы узел, созданный на предыдущем шаге. Третий запрос создает связь CreateUser между групповой политикой и учетной записью локального администратора.

Проверить, что связь создалась правильно с помощью запроса cypher:

 MATCH p=((g:GPO)-[r:CreateUser]->(l:LocalUser)) WHERE g.gpcpath CONTAINS "0D7D58C6-7F3C-41FD-B4A3-E8F3A696D1DB"  RETURN p

Заключительный этап – связать узел LOCALADMIN с компьютерами, к которым применяется групповая политика.

MATCH (g:GPO) WHERE g.gpcpath CONTAINS "0D7D58C6-7F3C-41FD-B4A3-E8F3A696D1DB"

MATCH (g)-[:GpLink|Contains*1..]->(c:Computer)

MATCH (l:LocalUser) WHERE l.name = "LOCALADMIN"

MERGE (l)-[r:AdminTo]-(c)

Первый запрос уже рассматривался. Второй запрос выбирает компьютеры, к которым применяется выбранная из предыдущего запроса групповая политика. Как известно групповая политика применяется к OU (организационным единицам), и данная группировка связей позволяет убрать из запроса OU и получить сразу компьютеры. Здесь тоже можно оптимизировать выборку и добавить условие WHERE c.enabled = true в результате будут выбраны только активные компьютеры. Третий запрос уже рассматривался. Четвертый создает связь AdminTo между локальным пользователем и выборкой компьютеров.

Проверить создание связи:

MATCH p=((l:LocalUser)-[r:AdminTo]->(c:Computer)) RETURN p

Вот и все. Теперь можно проверить всю цепочку:

MATCH p=((g:GPO)-[r:CreateUser|AdminTo*1..]->(c:Computer)) RETURN p

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

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

 

На этом сегодня всё. До новых встреч в новом году!

Автор: Дмитрий Неверов, руководитель группы анализа защищенности внутренней инфраструктуры, "Ростелеком-Солар"

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