Description
Query GUID
1d9c6ae3-38fc-4089-b5ad-fc3be0fa8eec
Query content
MATCH p=(n:Base)-[r:GenericAll|GenericWrite|WriteOwner|WriteDacl|ForceChangePassword|AllExtendedRights|AddMember|AllowedToDelegate|AllowedToAct|AdminTo|CanPSRemote|CanRDP|ExecuteDCOM|AddSelf|DCSync|ReadLAPSPassword|ReadGMSAPassword|DumpSMSAPassword|AddAllowedToAct|WriteSPN|AddKeyCredentialLink|SyncLAPSPassword|WriteAccountRestrictions|WriteGPLink|ADCSESC1|ADCSESC3|ADCSESC4|ADCSESC6a|ADCSESC6b|ADCSESC9a|ADCSESC9b|ADCSESC10a|ADCSESC10b|ADCSESC13]->(:Base)
WHERE (n:User OR n:Computer)
RETURN p
LIMIT 1000
Issue description
First off - top notch query. Great way to check if RBAC is implemented correctly. Kudos to you guys.
However, if I run the query as is, I get 1000 (due to the Limit in line four) different objects, including groups etc, which made no sense to me. After checking it, there seems to be a typo in there.
When I change the third line to "RETURN n", I get a bunch of users and computers, that either have some sort of execution privileges or outbound object control directly assigned to them. This seems to be the output as intended I assume.
I also included a check for enabled users and computers only, since I usually get too many results otherwise. It's optional however, feel free to remove it if you don't see the need.
So the query that works great for me looks like this:
MATCH p=(n:Base)-[r:GenericAll|GenericWrite|WriteOwner|WriteDacl|ForceChangePassword|AllExtendedRights|AddMember|AllowedToDelegate|AllowedToAct|AdminTo|CanPSRemote|CanRDP|ExecuteDCOM|AddSelf|DCSync|ReadLAPSPassword|ReadGMSAPassword|DumpSMSAPassword|AddAllowedToAct|WriteSPN|AddKeyCredentialLink|SyncLAPSPassword|WriteAccountRestrictions|WriteGPLink|ADCSESC1|ADCSESC3|ADCSESC4|ADCSESC6a|ADCSESC6b|ADCSESC9a|ADCSESC9b|ADCSESC10a|ADCSESC10b|ADCSESC13]->(:Base)
WHERE (n:User OR n:Computer)
AND n.enabled = TRUE
RETURN n
LIMIT 1000
Cheers guys
BloodHound version
latest version
BloodHound DB
default Neo4j
Activity
martinsohn commentedon Oct 30, 2025
Hi @kaasimir, thank you, that makes sense.
What do you think of the full .yml below
WriteOwnerLimitedRights|OwnsLimitedRights|CanApplyGPO|ManageCA|ManageCertificatesDo you think there should be a second .yml file for a query that can
RETURN p, or just add some lines to this query that are commented by default like below?kaasimir commentedon Oct 30, 2025
Hi @martinsohn ,
thx for the reply!
Your fleshed out query looks good too me. I tested it and it delivers the same result as my proposed one, seems great :)
From my point of view this could be implemented like you suggested it.
Regarding your question:
I'm not 100% sure I understand your point, however to me it seems like this feature is already implemented, since you can always just check for inbound control on an object. So if the query would deliver a similar result, I'm not sure an extra query is needed. However if I misunderstood I hope no hard feelings. Just let me know in case and I'll have another look.
Cheers,
kaasimir
Rename & improve 'Direct Principal Rights Assignment'
martinsohn commentedon Jan 3, 2026
Hi @kaasimir, I will close this issue with #43
We decided to keep most of the original query by having
RETURN pbecause that behavior is what we use in similar pre-built queries:By returning the path, the user is immediately able to see the directly assigned rights. The user cannot rely on Outbound Object Control as it also returns indirect rights.
Query updates - bugfixes & improvements (#43)
fix: Query updates for owned clauses (#47)