Как стать автором
Обновить
130
Солар
Безопасность за нами

Расширение списка ACE для BloodHound

Время на прочтение5 мин
Количество просмотров4.6K

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

Дальше будет много технической информации, поэтому предполагается, что читатель понимает, что такое ACL, DACL, ACE и т.д., а также имеет базовое понимание языка запросов Cypher.

Уже достаточно много написано материала по использованию BloodHound, поэтому не буду касаться основ его работы. Отмечу только основные моменты. BloodHound состоит из трех компонент:

  • SharpHound – собирает информацию об объектах Active Directory и формирует данные для загрузки в базу данных.

  • Neo4j – база данных, которая хранит и обрабатывает информацию. В качестве языка запросов используется Cypher.

  • BloodHound – визуализатор данных, написанный на JavaScript и скомпилированный в бинарное приложение.

Тот, кто использует BloodHound в своей работе, знает, что SharpHound собирает не все ACE, а выбирает только самые интересные, такие как GenericAll, GenericWrite, WriteDACL и др., которые точно могут привести к компрометации объекта Active Directory. Есть еще более специфичные WriteSPN, AddKeyCredentialLink и SelfMembership. Но остаются еще и другие ACE, которые администраторы настраивают более тонко, разрешив изменение только одного атрибута объекта, но которые так же могут привести к компрометации объекта.

Далее в статье я расскажу, как можно исправить эту ситуацию и расширить связи в BloodHound. Это будет концепт идеи – возможно, он отвечает не всем потребностям. Для сбора данных будет использоваться инструмент PowerView.

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

Нас в первую очередь интересует возможность изменять атрибуты объекта, а значит, требуемый ActiveDirectoryRights будет WriteProperty. Нас также не интересуют права изменения атрибутов, которые уже собираются SharpHound: All, Validated-SPN, ms-DS-Key-Credential-Link, Self-Membership. Отсутствие GUID в атрибуте ACE ObjectAce предоставляет возможность изменять все атрибуты объекта, по сути, это GenericWrite, который SharpHound также собирает. И наконец, нас не интересуют права, предоставленные группам с высокими привилегиями Domain Admins, Enterprise Admins и др.

Следующий момент – нам необходимо подготовить наименование права, которое будет являться связью между двумя объектами. Параметр -ResolveGuids PowerView преобразует атрибут ObjectAce в читаемый вид ObjectAceType, в котором мы удалим все тире и префиксом поставим слово Write.

База данных Neo4j умеет импортировать данные из CSV-файлов, и нам нужно выделить основные атрибуты для сбора: объект, субъект, связь, – и экспортировать результат в CSV-файл.

 Собирая все вместе, получим следующую команду (ее нужно собрать в одну строку):

Get-DomainObject|Get-ObjectAcl -ResolveGUIDs| 
where {($_.ObjectAceType -notmatch "All|Validated-SPN|ms-DS-Key-Credential-Link|Self-Membership")
-and ($_.ActiveDirectoryRights -match "WriteProperty")
-and ($_.ObjectAceType -ne $null)
-and ($_.SecurityIdentifier -notmatch "S-1-5-32-561|S-1-5-10|-517$|-512$|-519$")}|
Foreach-Object {$_ |
Add-Member -NotePropertyName NewLink
-NotePropertyValue ("Write"+$_.ObjectAceType.replace("-","")) -Force; $_} |
 select ObjectSID,NewLink,SecurityIdentifier|Export-Csv -NoTypeInformation ace.csv

Чем больше объектов, тем больше времени займет сбор данных. Для экономии времени можно заменить общий сбор Get-DomainObject на конкретные типы объектов Get-DomainUser или Get-DomainComputer и др. Или использовать другой инструмент, который поддерживает многопоточность.

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

Данные из моей лаборатории выглядят вот так:

Следующим шагом является импорт CSV файл в Neo4j. Для этого нужно переложить файл в папку import в Neo4j (в моем случае этот путь выглядит так C:\Tools\Neo4j\import ), открыть браузер Neo4j и выполнить следующие запросы Cypher:

LOAD CSV WITH HEADERS FROM 'file:///ace.csv' as line

WITH line WHERE line.NewLink = "WriteUserAccountControl"

MATCH (s) where s.objectid = line.SecurityIdentifier

MATCH (o) where o.objectid = line.ObjectSID

MERGE (s)-[r:WriteUserAccountControl]->(o) ON CREATE SET r.isacl = true

В данном запросе Neo4j загружает файл ace.csv, выбирает все строки, где встречается WriteUserAccountControl. Затем идет поиск в базе данных объектов по полю ObjectID (он же SID). В завершение создается связь (если она еще не существует), а также добавляется свойство для связи, что она является ACL.

Проверим, что импорт прошел удачно, выполнив запрос, который выведет всех пользователей, которые имеют права на изменение атрибута UserAссcountControl для других пользователей. В браузере Neo4j необходимо выполнить следующий запрос Cypher:

MATCH p=((u1:User)-[r:WriteUserAccountControl]->(u2:User)) WHERE u1<>u2 RETURN p

 В результате получим граф, как показано на рисунке ниже:

Метод рабочий, но не очень удобный. Нужно руками изменять параметр связи. И если таких записей будет много, то придется потратить время на импорт данных. Чтобы упростить ввод данных, можно воспользоваться API Neo4j и загрузить данные в автоматическом режиме. Я буду использовать PowerShell для этой задачи.

Для начала определяем сервер базы Neo4j и учетные данные для подключения:

$server=http://localhost:7474/db/data/transaction/commit

$secPasswd = ConvertTo-SecureString "<пароль>" -AsPlainText -Force

$neo4jCreds = New-Object System.Management.Automation.PSCredential ('neo4j', $secPasswd)

Следующим шагом загрузим данные из файла ace.csv в переменную, пропуская первую строку, так как в ней содержатся только заголовки:

$data = Get-Content .\ace.csv |select -Skip 1

Далее создаем цикл, в котором разбираем каждую строку на элементы, формируем запрос из этих элементов и выполняем этот его. При необходимости можно выводить ответ на запрос:

foreach($line in $data)
{
$object = $line.Split(",")[0].Replace('"', '')
$subject = $line.Split(",")[2].Replace('"', '')
$newlink = $line.Split(",")[1].Replace('"', '')
$query=@"
{"statements" : [ { "statement" : "MATCH (s) where s.objectid = \"$subject\" MATCH (o) where o.objectid = \"$object\" MERGE (s)-[r:$newlink]->(o) ON CREATE SET r.isacl = true"  } ]
        } "@
$response = Invoke-WebRequest -Uri $server -Method POST -Body $query -credential $neo4jCreds -ContentType "application/json" -UseBasicParsing
$response|select statuscode,content
}

Если в интерфейсе BloodHound выполнять запросы с помощью Cypher, то новые связи будут отображаться:

А если использовать форму для построения коротких путей, то интерфейс BloodHound ничего не узнает о новых созданных связях:

Чтобы исправить это, необходимо скачать исходники BloodHound, добавить новые связи в const fullEdgeList (31 строка) в файле AppContainer.jsx и заново скомпилировать инструмент:

 Повторно выполняем операцию, и теперь BloodHound отображает новые связи: 

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

В заключение хотелось бы сказать, что добавление новых данных и незначительные изменения в интерфейсе BloodHound расширяют возможности утилиты и могут предоставить новые, ранее упущенные вектора для проведения пентеста внутренней инфраструктуры. Администраторы могут использовать эту информацию, чтобы увидеть чрезмерные права над объектами Active Directory.

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

Теги:
Хабы:
+6
Комментарии0

Публикации

Информация

Сайт
rt-solar.ru
Дата регистрации
Дата основания
2015
Численность
1 001–5 000 человек
Местоположение
Россия