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