Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the SyncLAPSPassword edge with its documentation #564

Merged
merged 1 commit into from
Aug 1, 2022
Merged

Added the SyncLAPSPassword edge with its documentation #564

merged 1 commit into from
Aug 1, 2022

Conversation

simondotsh
Copy link
Contributor

#555

This edge requires to diverge from the typical way edges are built, due to how when a principal has DS-Replication-Get-Changes and DS-Replication-Get-Changes-In-Filtered-Set on a domain object, we wish to add a relationship between that principal and LAPS-enabled computers of the same domain. The ACE DS-Replication-Get-Changes-In-Filtered-Set is not currently collected, but a pull request has been opened on the SharpHoundCommon library to retrieve it (SpecterOps/SharpHoundCommon#35).

Without restructuring the project, the easiest way that I could find to implement it was through executing Cypher queries after an import in the postProcessUpload function, since the edge involves different types of objects. Here are the creation queries:

MATCH (n)-[:GetChangesInFilteredSet]->(m:Domain) WHERE (n)-[:GetChanges]->(m) AND NOT (n)-[:GetChangesAll]->(m) AND NOT n.objectid ENDS WITH '-S-1-5-9' 
MATCH (o:Computer {haslaps: true, domainsid: m.domainsid}) 
CREATE (n)-[:SyncLAPSPassword {isacl: true, isinherited: false}]->(o)

We gather all objects n that have GetChangesInFilteredSet on the domain object. Then, we make sure that these n objects also have GetChanges, but not GetChangesAll on the domain. The latter is excluded because if a principal also has it, they can perform DCSync, and drawing SyncLAPSPassword in that case would only generate noise in the graph, in my opinion. Similarly, we make sure that n is not Enterprise Domain Controllers because it meets the previous requirements, but domain controllers are also members of the group Domain Controllers, awarding them GetChangesAll. As such, this would also induce noise.

Then, we filter on all computer objects of the same domain that have LAPS, and end with creating the relation SyncLAPSPassword between n and those computers. I set isacl to true because the edge is a combination of two ACEs, but feel free to adjust.

A last query is executed:

MATCH ()-[r:GetChangesInFilteredSet]->(:Domain) DELETE r

GetChangesInFilteredSet is not meant to be shown to users when they are querying the data. Currently, its only purpose is to build the SyncLAPSPassword edge; otherwise, it would be shown as a link to domain objects, and induce false positives. For this reason, we make sure to delete it.

While this is far from perfect, I believe it should be good enough as a first iteration. Do not hesitate to provide feedback, and do as you wish with this code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants