$t = Get-ADUser -Filter * -Properties *
# В цикле разобрать атрибуты пользователей
foreach($i in $t)
{
$sid = $i.objectSid.Value
$samaccountname = $i.samaccountname
$displayname = $i.displayname
$enabled = $i.enabled
# Проверка, пустой ли userprincipalname
if($i.userprincipalname)
{
$name = $i.userprincipalname
}
else
{
$name = $i.samaccountname + "@" + $domain
}
# Сформировать строку запроса Cypher и записать ее в файл
Add-Content $OutFile "MERGE (u: User {objectid:'$sid'}) ON CREATE SET u.name=toUpper('$name'), u.samaccountname='$samaccountname', u.displayname='$displayname', u.domain = toUpper('$domain'), u.enabled = $enabled;"
}
Если присмотреться внимательно, то Cypher-запрос точно такой же, как и при загрузке данных из CSV.
Запустим скрипт
GetADData.ps1
для получения информации из Active Directory на контроллере домена. Следующим шагом очистим базу через браузер neo4j.MATCH (n)
DETACH DELETE n
Перенесем файл с контроллера домена и запустим наш загрузчик данных.
..\neo4j_uploaddata.ps1
UploadData -file.\users.txt
Рис. 3.53. Загрузка данных с помощью скрипта
И теперь посмотрим на результаты нашей работы. Запрос выполним в BloodHound в Raw Query.
MATCH (u: User) RETURN u
Рис. 3.54. Результат загрузки данных
04. Учим старую собаку новым трюкам
Стандартной сборки BloodHound достаточно для выполнения работ, но чем больше вы будете работать с этим инструментом, тем чаще вас станут посещать мысли о том, что можно расширить функционал, который поможет более эффективно выполнять работу.
Теперь, когда есть понимание интерфейса BloodHound и языка запросов Cypher, можно перейти к добавлению новых меток, связей и их свойств.
Для дальнейшего изучения материала стоит очистить базу и заново загрузить результаты SharpHound или восстановить данные из резервной копии.
Настройка окружения и проверка сборки
Чтобы приступить к добавлению функционала, необходимо настроить окружение и проверить, что все работает корректно.
Настройка окруженияВ первую очередь необходимо установить node.js. Скачаем дистрибутив node.js с официального сайта[12] и запустим установщик. Во время установки будет предложено установить Chocolately, это избавит нас от установки всех зависимостей вручную.
Рис. 4.1. Установка зависимостей node.js
Запустим командную строку с правами администратора и установим electron-builder:
npm install -g electron-packager
Обычно сборка приложения electron выполняется так:
electron-packager. app -platform win32 -arch x64 -out dist/
Дополнительно установим git[13] для загрузки исходников BloodHound или с помощью winget:
winget install Git.Git
Первая сборка BloodHoundМожно приступить к первой сборке приложения BloodHound. Запустим powershell и перейдем в рабочую директорию
c: \Tools\
. Загрузим исходники с официального GitHub[14], в книге используется версия 4.3.1.git clone https://github.com/BloodHoundAD/BloodHound
Перейдем в директорию BloodHound и установим все необходимые зависимости для сборки. Для этого необходимо выполнить следующую команду:
npm install -force
Выполним тестовую сборку программы:
npm run build: win32
Если никаких ошибок не возникнет, то мы получим собранную версию BloodHound (рис. 4.2).
Совет
Если не требуются версии win32 и arm, то в файле
package.json
можно установить архитектуру только x64, для этого изменим параметр arch
на -arch=x64
.Рис. 4.2. Результат сборки приложения
Рис. 4.3. Ошибка при сборке приложения
Теперь перейдем в директорию
BloodHound-win32-x64
и запустим bloodhound.exe.
Если все было сделано правильно, BloodHound запустится, и мы увидим или окно авторизации, или основное поле.ОшибкиПри первой сборке может возникнуть ошибка
error:0308010C: digital envelope
routines::unsupported
, связанная с библиотеками SSL (рис. 4.3).Для решения этой проблемы нужно установить переменную окружения для node.js для поддержки старых алгоритмов шифрования:
$env: NODE_OPTIONS = "-openssl-legacy-provider"
Изменение информации о программе (About)
Начнем с простых вещей и для начала добавим информацию о себе в About.
С помощью редактора откроем файл
About.jsx
, который находится в \src\components\Modals
, и добавим перед лицензией строчку со своей информацией.…
@harmj0y
Modified by:{'Dmitry Neverov'}
LICENSE
{data}
…
Сохраним файл и соберем приложение:
npm run build: win32
После сборки запустим BloodHound и нажмем на кнопку i в меню. Теперь можно увидеть собственное имя (рис. 4.4).
Рис. 4.4. Изменение About
Изменение запроса в Shortest Path from Owned Principals
Использование установленного флага Debug Mode позволяет отслеживать запросы Cypher. Однажды я обратил внимание на запрос
Shortest Path from Owned Principals
, который устанавливал конечными точками только узлы с меткой Computer
. Посмотрим на этот запрос в исходном коде.Откроем в редакторе файл
PrebuildQueries.json
, который находится в директории \src\components\SearchContainer\Tabs\
, и найдем запрос Shortest Path from Owned Principals
(рис. 4.5).Нас интересует последний запрос в этом блоке:
MATCH p=shortestPath((a {name:$result})-[:{}*1..]->(b: Computer)) WHERE NOT a=b RETURN p
Рис. 4.5. Пресозданный запрос
Можно убедиться, что конечными узлами будут все объекты с меткой
Computer
. Этот запрос не очень правильный, так как у скомпрометированного ранее узла могут быть связи с другими узлами кроме компьютеров. Чтобы исправить эту ситуацию, удалим метку Computer
из запроса.MATCH p=shortestPath((a {name:$result})-[:{}*1..]->(b)) WHERE NOT a=b RETURN p
Сохраняем измененный файл и собираем приложение:
npm run build: win32
Запускаем обновленную версию BloodHound. Проверяем, что в настройках установлен флаг Debug Mode. Теперь выбираем любого пользователя, правой клавишей мыши вызываем контекстное меню и нажимаем на Set User as Owned. Переходим во вкладку Analysis и нажимаем на Shortest Path from Owned Principals. Даже если нет результатов в Raw Query, можно увидеть, что конечными узлами являются все другие узлы.
Добавление собственных запросов
Продолжаем работу с запросами. Со временем при частом использовании BloodHound будут накапливаться полезные запросы, некоторые из них можно добавить в BloodHound, чтобы каждый раз не вводить их вручную или не копировать.