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 для нормального отображения нового узла.
На этом сегодня всё. До новых встреч в новом году!
Автор: Дмитрий Неверов, руководитель группы анализа защищенности внутренней инфраструктуры, "Ростелеком-Солар"