Оператор сравненияДля указания точного вхождения используется оператор сравнения
=.
Например, найти всех членов группы администраторов домена:
MATCH (u: User)-[r: MemberOf*0..]->(g: Group) g.name = "DOMAIN ADMINS@DOMAIN.LOCAL" RETURN u.name
Кроме строковых значений могут приниматься булевы значения
FALSE
и TRUE
или числовые. Например, найти все незаблокированные учетные записи компьютеров:MATCH (c: Computer) WHERE c.enabled = TRUE return c
Другой способ использовать точное вхождение – это указать фильтр запроса в узлах. Фильтр задается в фигурных скобках по шаблону
<свойство>:<значение>
. Например, определить, на каких машинах используется LAPS, можно следующим образом:MATCH (c: Computer {haslaps: true}) return c
Можно добавить несколько условий. В таком случае они разделяются запятой. Например, выбрать только незаблокированные объекты и компьютеры, на которых используется LAPS.
MATCH (c: Computer {enabled: true, haslaps: true}) return c
Если мы хотим указать метку в операторе
WHERE
, то вместо знака равенства используется двоеточие.MATCH (c) WHERE c: User RETURN c
Имя связи тоже можно указывать в
WHERE
. В данном случае используется type()
, так как у связи нет свойства имени.MATCH p=(c: Computer)-[r]->(u: User) WHERE type(r) = "HasSession" RETURN p
Как и узлы, связь может иметь свойства, и фильтрация по ним будет иметь точно такой же принцип. Например, найти все связи между пользователями и компьютерами, где связь имеет свойство
isacl
в значении TRUE
:MATCH p=(u: User)-[r]-(c: Computer) WHERE r.isacl = TRUE RETURN p
Оператор «не равно»Оператор не равно
<>
противоположен предыдущему оператору. Например, найти все группы, которые не являются контроллерами домена:MATCH (g: Group) WHERE g.name <>"DOMAIN CONTROLLERS@DOMAIN.LOCAL" RETURN g.name
Операторы арифметического сравненияОператоры арифметического сравнения
>
(больше чем), >=
(больше или равно), <
(меньше чем) и <=
(меньше или равно) используются для сравнения чисел. В BloodHound, наверное, нет числовых значений, кроме результатов работы с датами или сложных запросов с использованием подсчета. Примеры работы с датами будут рассмотрены далее.Оператор NOTЛогический оператор отрицания
NOT
инвертирует условие. Например, при анализе атрибута description
было обнаружено, что некоторые учетные записи имеют описание, связанное с заявками в Help Desk. Заявки имеют идентификационный номер, который администраторы иногда вносят в этот атрибут. Идентификационный номер часто имеет буквенный префикс (например, HDQ), задача состоит в том, чтобы исключить из вывода все такие записи.MATCH(u: User) WHERE (NOT(u.description CONTAINS "HDQ")) RETURN u.name, u.description
Оператор
NOT
может применяться в сочетании с другими операторами. Например, с оператором сравнения:MATCH (g: Group) WHERE NOT g.name = "DOMAIN CONTROLLERS@DOMAIN.LOCAL" RETURN g.name
Оператор IS NULLОператор нулевого значения
IS NULL
проверяет, что свойство не имеет значения. В качестве примера выполним поиск потенциальных пресозданных машин, часто такие машины имеют пустой атрибут operatingsystem
:MATCH (c: Computer) WHERE c.operatingsystem IS NULL RETURN c.name
Оператор IS NOT NULLОператор проверки на ненулевое значение
IS NOT NULL
противоположен предыдущему оператору и проверяет наличие значения в свойстве. По факту это объединение двух операторов – NOT
и IS NULL
. В качестве примера можно выполнить проверку непустого атрибута description
для поиска в нем полезной информации:MATCH (u: User) WHERE u.description IS NOT NULL RETURN u.name
Оператор CONTAINSОператор проверки вхождения
CONTAINS
проверяет наличие передаваемого значения в свойстве. Например, найти доменные группы, в имени которых встречается слово DBA (администраторы баз данных):MATCH (g: Group) WHERE g.name CONTAINS "DBA" RETURN g.name
Другой пример – найти все хосты, где установлен Windows Server:
MATCH (c: Computer) WHERE c.operatingsystem CONTAINS 'Server' RETURN c.name
Оператор STARTS WITHСтроковый оператор
STARTS WITH
позволяет указывать префикс для значения свойства. Имеет смысл использовать для свойств имени – например, найти все учетные записи с префиксом ADM:MATCH (u: User) WHERE u.name STARTS WITH "ADM" RETURN u.name
Оператор ENDS WITHСтроковый оператор
ENDS WITH
аналогичен предыдущему, но с указанием постфикса. Этот оператор удобно использовать для указания имени домена или RID. В качестве примера требуется подсчитать, столько учетных записей пользователей есть в домене CHILD.DOMAIN.LOCAL
. Запрос в Cypher будет следующим:MATCH (u: User) WHERE u.name ENDS WITH "CHILD.DOMAIN.LOCAL" RETURN count(u)
Или найти всех пользователей, входящих в группу доменных администраторов. В данном случае будем указывать не имя, а RID, который всегда одинаков и имеет значение 512:
MATCH (u: User)-[r: MemberOf]->(g: Group) WHERE g.objectid ENDS WITH '-512' RETURN u.name, g.name
Можно использовать для любой группы, пользователя или компьютера, главное – знать RID. В некоторых случаях этот способ сокращает ввод данных.
Логические операторы OR и ANDПри объединении условий фильтрации запросов можно использовать логические операторы
AND
и OR
. Например, необходимо проверить, какие активные учетные записи будут входить в группу доменных администраторов. Запрос в Cypher будет следующим:MATCH (u: User)-[r: MemberOf*0..]->(g: Group)
WHERE u.enabled=TRUE
AND g.name = "DOMAIN ADMINS@DOMAIN.LOCAL" RETURN u.name
Другой пример – узнать, какие пользователи входят в группу администраторов или доменных администраторов:
MATCH (u: User)-[r: MemberOf*0..]->(g: Group)
WHERE g.name = "ADMINISTRATORS@DOMAIN.LOCAL" OR g.name = "DOMAIN ADMINS@DOMAIN.LOCAL"
RETURN u.name, g.name
Можно группировать логические операторы с помощью круглых скобок. Например, нужно получить все скомпрометированные объекты домена, и неважно, будет это пользователь или компьютер:
MATCH (n) WHERE n.owned = TRUE AND (n: User OR n: Computer) RETURN n
Оператор EXISTSОператор
EXISTS
может использоваться для проверки существования свойства или связи. Например, получить всех пользователей, у которых есть свойство hasspn
, для выполнения техники Kerberoasting. Запрос в Cypher будет выглядеть следующим образом:MATCH (u: User) WHERE EXISTS(u.password) RETURN u
Информация
Браузер neo4j считает использование
EXISTS
устаревшим, этот оператор будет удален в будущих версиях neo4j. Вместо EXISTS
предлагается использовать IS NULL.
В качестве условия может выступать шаблон. Например, проверить, есть ли пользователи, которые имеют членство в группе доменных администраторов:
MATCH (u: User) WHERE EXISTS {(u)-[r: GenericAll]->(g: Group)} RETURN u.name
Использование регулярных выраженийОператор регулярных выражений
=~
позволяет использовать регулярные выражения в запросах. Например, чтобы не писать полное название группы, можно задать только определенное значение.MATCH (g: Group) WHERE g.name =~ '(?i)domain user.*' RETURN g
Параметр
(?i)
сообщает, что регистр не учитывается.В регулярном выражении можно использовать логическое ИЛИ в виде символа |, чтобы искать по нескольким значениям. Например, нужно посмотреть, есть ли в атрибуте
description
слова «пароль» или «password», тогда запрос в Cypher может иметь следующий вид: