Не все запросы Cypher можно использовать в BloodHound, например, некоторые данные мы получаем в виде таблиц, а BloodHound не поддерживает этот функционал.
В качестве примера будем выполнять поиск компьютеров, которые имеют привилегии локального администратора на других компьютерах. Мы рассмотрим два варианта – добавление запроса через форму и изменение исходного кода.
Настройка лабораторииДля начала проверим, существуют ли такие связи. Запрос Cypher будет следующим:
MATCH p=(n: Computer)-[: MemberOf|AdminTo*1..]->(m: Computer) RETURN p
Если результатов нет, то создадим такие связи, одну прямую, другую – через доменную группу
Domain Computers
:MATCH (c1:Computer {name: "DC.DOMAIN.LOCAL"})
MATCH (c2:Computer {name: "COMP.DOMAIN.LOCAL"})
MERGE (c1)-[: AdminTo]-(c2)
MATCH (g: Group {name: "DOMAIN COMPUTERS@DOMAIN.LOCAL"})
MATCH (c: Computer {name: "COMP.DOMAIN.LOCAL"})
MERGE (g)-[: AdminTo]-(c)
Повторим ранее созданный запрос и на этот раз получим результат.
Рис. 4.6. Компьютеры с правами локального администратора
Добавление собственных запросов через формуСначала добавим собственный запрос с помощью встроенной формы. При описании интерфейса BloodHound мы уже рассматривали эту форму. Открываем вкладку Analysis, пролистываем ее до Custom Queries и нажимаем на кнопку в виде карандаша. Заполняем форму, как на рисунке 4.7.
Рис. 4.7. Форма добавления собственных запросов
Запрос Cypher будет таким же, как и при настройке лаборатории. Название категории можно выбрать из списка или добавить свою. Название запроса можно сделать любым. Нажимаем на стрелку, чтобы выполнить запрос, и, если результат нас устраивает, сохраняем (Save).
Рис. 4.8. Результат добавления запроса
Хотя мы выбрали категорию из списка, в интерфейсе BloodHound категория будет отображаться отдельно от пресозданных запросов. Нажмем на этот запрос и получим результат, который видели раньше.
Рис. 4.9. Результат выполнения запроса
Если открыть файл
customqueries.json
, который находится в C: \Users\%USERNAME%\AppData\Roaming\bloodhound\
, можно увидеть результат добавления.
Рис. 4.10. Файл customqueries.json
На мой взгляд, такой метод полезен при повторном использовании запросов в рамках одного конкретного проекта. Чтобы поделиться своими запросами с коллегами, нужно переносить файл
customqueries.json
на другой компьютер или в профиль другого пользователя. Поэтому самые популярные запросы стоит записать прямо в приложение.Добавление собственных запросов в код приложенияРанее мы уже изменяли файл
PrebuildQueries.json
, теперь добавим свой запрос, который получили в предыдущей части. Если изучить внимательно этот файл, то можно обнаружить, что все запросы похожи друг на друга. Обычно они состоят из двух-трех частей, первая определяет домен, для которого будет осуществлена выборка, вторая – уже непосредственно сам запрос с учетом домена. В некоторых запросах второй частью является выбор пользователя.Откроем в редакторе файл
PrebuildQueries.json
, который находится в директории src\components\SearchContainer\Tabs\
, найдем запрос Find Domain Admin Logons to non-Domain Controllers
и после всего блока запроса добавим свой код.{
"name": "Find All Computers where Computers are Local Admin",
"category": "Dangerous Privileges",
"queryList":[
{
"final":false,
"title":"Select source domain…",
"query":"MATCH (n: Domain) RETURN n.name ORDER BY n.name DESC"
},
{
"final":true,
"query": "MATCH p=(n: Computer)-[: MemberOf|AdminTo*1..]->(m: Computer) WHERE n.domain = $result RETURN p",
"allowCollapse":true
}
]
},
По факту это тот же код, который мы получили в
customqueries.json.
Совет
Хотя запросы можно располагать где угодно, лучше собирать их в одной категории, так будет проще потом искать и исправлять.
Сохраняем измененный файл и собираем приложение.
npm run build: win32
Запускаем обновленную версию приложения, переходим во вкладку Analysis и находим наш добавленный запрос.
Рис. 4.11. Новый запрос во вкладке Analysis
Нажмем на добавленный запрос, получим результат:
Рис. 4.12. Результат добавления запроса
Теперь этот запрос всегда будет присутствовать в BloodHound вне зависимости от пользователя, который запускает приложение.
Локальная учетная запись с правами администратора
Доступ к серверу или рабочей станции с правами локального администратора позволяет проводить следующий этап работ: расширить права в сети или выполнять боковое перемещение. Такие локальные учетные записи могут быть обнаружены при проведении работ в различных источниках:
● Групповые политики
● Извлечение данных из LSA
● Общие файловые ресурсы
● Почтовые архивы
Если локальные учетные записи, обнаруженные в групповых политиках, самодостаточны и позволяют сразу обнаружить хосты, где они применяются, то остальные источники потребуют проведения техники распыления пароля или хэша.
Создание новой меткиСоздадим новую метку
LocalUser
и определим, что она будет обладать следующими свойствами: name
, password
и hash
. Если свойства name
, password
и hash
мы можем получить непосредственно из локальной учетной записи, то с objectid
придется определяться отдельно. Для доменных учетных записей пользователей BloodHound в качестве objectid
используется SID
, но для локальных учетных записей на каждом компьютере будет свой SID
. Поэтому в качестве значения objectid
будем генерировать значение guid
.Задачу можно решить двумя способами: воспользоваться внешним источником или использовать плагины neo4j.
Для первого способа можно использовать powershell:
[guid]::NewGuid()
А второй способ генерации
guid
– это использовать функцию randomUUID()
. Мы уже сталкивались с этой функцией при изучении Cypher. Запрос на генерацию guid
с помощью этой функции будет следующий:RETURN randomUUID() AS objectid;
Соберем все вместе и создадим новый узел с меткой
LocalUser
с помощью Cypher:MERGE (m: LocalUser {name: "LADMIN", objectid: toUpper(randomUUID()), password: "Qwerty123", hash: ToUpper("329b074c0058ccf1ba2e4705382963ff")})
Проверим, что создался новый узел с указанными параметрами:
MATCH (l: LocalUser) RETURN l
Рис. 4.13. Локальный пользователь
Если выполнить тот же самый запрос в BloodHound, то можно обнаружить только черный круг, который не отображает никаких свойств. Это связано с тем, что BloodHound ничего не знает о новой метке для узла. Поэтому следующим шагом будет добавление отображения в интерфейсе BloodHound.
Отображение метки в BloodHoundПереходим в директорию
src
и открываем файл index.js
на редактирование. Добавим информацию о том, как новая метка будет отображаться на графе. Находим строку global.AppStore
и вставляем следующий код после блока GPO
:…
global.appStore = {
dagre: true,
…
GPO:{
font: "'Font Awesome 5 Free'",
content:'\uF03A',
scale:1.25,
color:'#7F72FD',
},
LocalUser:{
font: "'Font Awesome 5 Free'",
content:'\uf007',
scale:1.5,
color:'