Cypher: Введение
На данный момент у меня закончились идеи с постами по тестированию инфраструктуры на базе Active Directory. Поэтому решил переключиться на BloodHound и Cypher.
Инструмент BloodHound состоит из трех частей:
• Sharphound – сборщик данных;
• BloodHound – веб приложение для работы и визуализации данных;
• Neo4j – база данных для хранения информации.
Обычно результаты запросов представляются в виде графов, что удобно для обнаружения связей между объектами. В BloodHound объекты домена являются вершинами графа, а ребра – отношениями между этими объектами. Так же в Neo4j вершины графа маркируются (label) по общему принципу это позволяет делать выборку только из необходимой группы объектов. Связи определяются по типу (type).
Для запросов информации из базы данных используется язык Cypher. Ниже представлен список некоторых операторов:
•
CREATE
и
MERGE
– создание нового элемента;
•
MATCH
- выполнение выборки;
•
SET
и
REMOVE
– добавление или удаление свойств;
•
WHERE
– условие;
•
RETURN
– возврат результата;
•
DELETE
– удаление элементов;
Принцип запросов выборки будет следующим:
MATCH (var1)-[:Тип связи]->(var2) WHERE … RETURN var1, var2
Можно заметить, что сам запрос похож на граф и это можно использовать для создания сложных запросов.
Стрелки определяют направление связи, в Neo4j нет двунаправленных связей, но могут быть запросы, где направление не указано. Cypher чувствителен к регистру и это необходимо учитывать при создании запросов, одна незначительная опечатка и результаты будут ошибочными.
Рассмотрим простой запрос Cypher в котором будут выбираться пользователи, у которых есть доступ по RDP:
MATCH (u:User)-[r:CanRDP]->(c:Computer) RETURN u,r,c
Здесь переменным
u
,
r
,
c
будут передаваться результаты выборки, это необязательно если не нужно выделять какие-то особые условия, но для возврата данных нужно все равно определить переменную:
MATCH p=(:User)-[CanRDP]->(:Computer) RETURN p
Результат будет аналогичным.
Указание
label
будет влиять на скорость выполнения запроса, но и результат может быть другим. Например, в запросе выше упускается тот факт, что группы тоже могут иметь связь
CanRDP
. Таким образом в запросе можно опустить указание
User
, и он будет выглядеть следующим образом:
MATCH p=(u)-[r:CanRDP]->(c:Computer) RETURN p
Самым интересным в Cypher является построение коротких путей между объектами. Для этого используются операторы
ShortestPath
и
AllShortestPaths
как можно догадаться разница между ними в том, что первый находит один короткий путь, а второй все (при наличии такой возможности). Формирование коротких путей будет занимать большое количество времени поэтому нужно добавлять условия для снижения нагрузки на базу данных. Пример запроса всех путей от пользователей до группы доменных администраторов будет выглядеть следующим образом:
MATCH p=allshortestpaths((u:User)-[*1..]->(g:Group)) where g.name = "DOMAIN ADMINS@DOMAIN.LOCAL" RETURN p
Стоит обратить внимание, что в запросе не указываются связи, только количество «прыжков» от 1 до конца (об этом будет рассказано позже). Это означает, что интересны все возможные варианты связей.
#BloodHound #Cypher