SharpHound3
SharpHound3 copied to clipboard
GPOLocalGroup not returning data without including All
Good morning,
While working through Rastamouse's CRTO course, it was identified that running GPOLocalGroup alone as a Sharphound query was not returning full GPOLocalGroup data. Him and I worked through the issue for some time before realizing that GPOLocalGroup wasn't querying the appropriate data from the execution.
The following was ran in domain user context - sharphound.exe -c gpolocalgroup
And the contents of the json file below -
{"groups":[{"Properties":{"name":"ENTERPRISE DOMAIN [email protected]","domain":"CYBERBOTIC.IO"},"Members":[{"MemberId":"S-1-5-21-3865823697-1816233505-1834004910-1000","MemberType":"Computer"}],"ObjectIdentifier":"CYBERBOTIC.IO-S-1-5-9","Aces":[]},{"Properties":{"name":"[email protected]","domain":"CYBERBOTIC.IO"},"Members":[{"MemberId":"S-1-5-21-3865823697-1816233505-1834004910-515","MemberType":"Group"},{"MemberId":"S-1-5-21-3865823697-1816233505-1834004910-513","MemberType":"Group"}],"ObjectIdentifier":"CYBERBOTIC.IO-S-1-1-0","Aces":[]},{"Properties":{"name":"AUTHENTICATED [email protected]","domain":"CYBERBOTIC.IO"},"Members":[{"MemberId":"S-1-5-21-3865823697-1816233505-1834004910-515","MemberType":"Group"},{"MemberId":"S-1-5-21-3865823697-1816233505-1834004910-513","MemberType":"Group"}],"ObjectIdentifier":"CYBERBOTIC.IO-S-1-5-11","Aces":[]}],"meta":{"count":3,"type":"groups","version":3}}
Running with the all flag appended ran from a domain context, the results were appropriate and as follows -
sharphound.exe -c all gpolocalgroup
Resolved Collection Methods: Group, Sessions, LoggedOn, Trusts, ACL, ObjectProps, LocalGroups, SPNTargets, Container, GPOLocalGroup [+] Creating Schema map for domain CYBERBOTIC.IO using path CN=Schema,CN=Configuration,DC=cyberbotic,DC=io [+] Cache File not Found: 0 Objects in cache [+] Pre-populating Domain Controller SIDS Status: 0 objects finished (+0) -- Using 34 MB RAM Status: 197 objects finished (+197 6.793103)/s -- Using 46 MB RAM Status: 198 objects finished (+1 6)/s -- Using 50 MB RAM Enumeration finished in 00:00:33.3755922 Compressing data to .\20210331180317_BloodHound.zip You can upload this file directly to the UI SharpHound Enumeration Completed at 18:04 on 31/03/2021! Happy Graphing!
This execution included the appropriate GPOLocalGroup data as expected, but required the All flag to do so.
In the end, I'm not sure if it's intended that the GPOLocalGroup flag require the All flag as well. I appreciate you looking in to this.
Thank you!
I also came across this issue during the OSEP course!
I had a similar need (to only inspect GPO data). I saw the same problem as described above and work around like this:
sharphound.exe -c GPOLocalGroup,Container
Maybe this will help if users don't want to use the "All" option.
The issue seems to be the flags=*
filter on some queries.
In LdapBuilder
file, there are all the LDAP queries to filter results. The Container
query is here: https://github.com/BloodHoundAD/SharpHound3/blob/master/SharpHound3/LdapBuilder.cs#L81
ldapFilterParts.Add("(|
(&(&(objectcategory=groupPolicyContainer)(flags=*))(name=*)(gpcfilesyspath=*)) // Either this
(objectcategory=organizationalUnit)(objectClass=domain) // Or this
)");
The second filter is way more permissive, and doesn't contain the flag=*
restriction.
The GPOLocalGroup
LDAP query is the following https://github.com/BloodHoundAD/SharpHound3/blob/master/SharpHound3/LdapBuilder.cs#L90
ldapFilterParts.Add("(&(|(objectcategory=organizationalUnit)(objectclass=domain))(gplink=*)(flags=*))");
The queries filters out all objects with LDAP attribute flags
unset.
In my AD, all my OU and Domain objects have this attribute unset.
I'm not sure what is this attribute used for, and if it's really necessary, but in my experience, it's not used.
I wrote a PR for this: https://github.com/BloodHoundAD/SharpHound3/pull/45
So this change was actually made because of this: https://github.com/BloodHoundAD/SharpHound2/pull/65
I'm going to have to figure out how to reconcile this, maybe make it a flag
That's interesting, I was wondering why this flag was checked. In my environment (default AD install), this attribute exists, but is always unset.
In the request you linked, @Crypt0-M3lon says:
The patch just add a check for the flags attribute existence
I'm not sure if attribute existence
means that the versioned GPO doesn't have this attribute at all, or if it's unset.
I suspect the attribute always exists, and is always unset, except when using Group Policy Admin. What I read is that this flag is never used by MS, only by third party whenever they need to store some flags somewhere. So my guess is that "Group Policy Admin" uses this attribute to allow multiple versioned GPOs.
(https://social.technet.microsoft.com/Forums/ie/en-US/82ee9319-3ced-4be8-8110-d708a0f019ca/active-directory-attribute-can-we-use-the-flags-attribute?forum=winserverDS It is for admins to use as desired
)
In the meantime, I'd say that the code shouldn't break for default install (meaning this flag shouldn't be checked), and we should think of a solution to have valid result for third party software like "Group Policy Admin".
edit: maybe make it a flag
, yes that could be a solution. By default, there's no filter, but by specifying something on the CLI, it would add the filter.
Oh sorry to hear you had issues with my old fix :( Unfortunately I have no more access to the domain with GPA to try to find a decent solution.
Oh I realized that the line was not changed in my commit but in this one: https://github.com/BloodHoundAD/SharpHound3/commit/15733d74a28233e4736fcea3b19b3a4ad68e6ce2#diff-795fcb0de4314b310b193b37cf9de3ac816711cdf1153a0feb66ec7fe68aacafR90 and I'm pretty sure that there were no regression with my fix back in time. GPO MUST have a flags (https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-gpod/d360d288-d7d5-49a9-83be-603805da1379), a grouppolicycontainer
without a flag is not a valid, probably from a versioning tools. But you are looking for the flag attribute on a organizationalUnit
which is not attended, should not the fix be to remove the extra flags
checks from ldapFilterParts.Add("(&(|(objectcategory=organizationalUnit)(objectclass=domain))(gplink=*)(flags=*))");
?
Yes, it should. Now I understand: this flags
attribute must be set on GPC, but not on OU. The filter was added on OU and Domain objects, which is not correct.
My PR related to this issue removes this flag from all queries when used alongside OU & Domain, so I guess it's a valid fix.
Thank you @Crypt0-M3lon for details! :)
FWIW, this isn't an issue in the new common library
https://github.com/BloodHoundAD/SharpHoundCommon/blob/master/src/CommonLib/LDAPQueries/LDAPFilter.cs
Looks like I got the filters right there.
I'm currently working on a new SH version using this with release date TBA
Ok, seems good indeed. Thank you @rvazarkar If you need beta-testing, I'm available ;)