Из непроходимых ребер в проходимые
В статье мы уже обсуждали ребра LocalToComputer и MemberOfLocalGroup и научились включать и исключать их в Cypher запрос для получения проходимого графа. Запрос выполняет свою задачу, но получается достаточно громоздким. Чтобы сделать запрос более удобным мы можем вернуться к привычным ребрам AdminTo, CanRDP и так далее.
Ниже представлен запрос, который создает связь AdminTo между двумя узлами через поиск членства в локальных группах:
MATCH (g)-[:LocalToComputer]->(c:Computer) WHERE g.objectid ENDS WITH '-544'
MATCH (p)-[:MemberOfLocalGroup]->(g) WHERE NOT (p)-[:AdminTo]->(c)
MERGE (p)-[:AdminTo {isacl:false}]->(c);В этом запросе мы сначала ищем локальную группу с определенным RID (в данном случае это группа Administrators на компьютере), и которая связана с компьютерами, второй MATCH ищет всех прямых членов этой группы, но при этом между этим объектом и компьютером нет прямой связи. И последним шагом мы создаем новую связь AdminTo. В результате мы получим уже прямую связь от одного узла до другого.
По аналогии можно добавить ребра для других встроенных групп, которые предоставляют возможность получить доступ на хост:
Можно пойти другим путем и объединить все в один Cypher запрос:
MATCH (g:ADLocalGroup)-[:LocalToComputer]->(c:Computer)
WHERE g.objectid =~ '(?i).*(-544$|-555$|-562$|-580$)'
MATCH (p)-[:MemberOfLocalGroup]->(g)
WITH p, c, g,
CASE
WHEN g.objectid ENDS WITH '-544' THEN 'AdminTo'
WHEN g.objectid ENDS WITH '-555' THEN 'CanRDP'
WHEN g.objectid ENDS WITH '-562' THEN 'ExecuteDCOM'
WHEN g.objectid ENDS WITH '-580' THEN 'CanPSRemote'
END AS relType
FOREACH (_ IN CASE WHEN relType = 'AdminTo' THEN [1] ELSE [] END |
MERGE (p)-[:AdminTo {isacl:false}]->(c)
)
FOREACH (_ IN CASE WHEN relType = 'CanRDP' THEN [1] ELSE [] END |
MERGE (p)-[:CanRDP {isacl:false}]->(c)
)
FOREACH (_ IN CASE WHEN relType = 'ExecuteDCOM' THEN [1] ELSE [] END |
MERGE (p)-[:ExecuteDCOM {isacl:false}]->(c)
)
FOREACH (_ IN CASE WHEN relType = 'CanPSRemote' THEN [1] ELSE [] END |
MERGE (p)-[:CanPSRemote {isacl:false}]->(c)
)Таким образом мы возвращаемся к привычным ребрам удаленного доступа без дополнительной фильтрации локальных групп.