Adsisearcher – Resolve groups recursively

First of all, it is therefore important to understand why groups and group memberships are relevant.

In Active Directory, groups are used to group user accounts and computer accounts into entities that are then easier to manage. There are 2 types of groups: Distribution groups, which can be used only with email applications to create email distribution lists, and security groups, by means of which the assignment of permissions to shared resources can be handled. In addition, groups are further distinguished by their scope, which specifies the extent to which the group is applied in the domain structure or forest. The scope defines where the group or its members can be granted permissions. In Active Directory there are the following three scopes:

  • Universal: can grant permissions in any domain in the same forest or in trusted forests.
  • Global: can grant permissions in any domain in the same forest or in trusted domains or forests.
  • Domain Local: can grant permissions within the same domain[1].

Fig. 1: Options when creating a group

Security groups are of particular interest because the user rights assigned to them can be used to determine what members of this group can do in the domain or forest. During the installation of Active Directory, user rights are automatically assigned to some security groups. This allows, for example, to define the administrator role of a person in the domain. Users added to the Domain Admins group are given administrative rights in the domain. The Domain Admins group is assigned user rights for administrative activities by default, and members of the group inherit these rights. When another group becomes a member of the Domain Admins group, all members of that other group also receive administrative rights. So it is important not only to be able to read direct group members, but also to be able to resolve groups recursively to really capture every effective member.

Direct group membership

A direct group membership is stored directly in the attributes of the respective group. Direct membership means that a user is directly a member of a group and not a member of the group. Basically, it is first useful to know how to search for all groups. This can be done with the attribute objectClass in the search filter, as is already the case with user or computer searches:

When a group is assigned members, it has the attribute member – in this attribute all direct members of the group are listed with their respective distinguished name. You can therefore search for all groups that have members:

as well as all groups that have no members:

If you want to query all direct members of a group, you can do this simply by filtering for the distinguishedName or the sAMAccountName of a group, for example, and then using .properties.member to output the contents of the member attribute:

It is also possible to check for a particular user which groups he directly belongs to by querying the user’s memberof attribute:

Admin or not?

It is always an advantage to know – or to know how to find out – who has administrative rights in an Active Directory. This can of course be done with the right search filters via adsisearcher. If you search the Internet for a simple solution, relatively simple searches like the one for direct group membership are often suggested, but as already mentioned, this only covers direct members. Another approach that is encountered is to determine whether someone is an administrator based on the adminCount attribute. A search for it looks like this:

AdminCount indicates whether an account is a so-called protected object. If this is the case, the attribute is present with the value 1.

Example:

Protected Objects are highly privileged administrative groups (e.g. Domain Admins, Schema Admins, etc.) and their members. Here, indirect members are also Protected Objects. Protected Objects are specially protected in that their permissions cannot be easily changed. A background process protects them by periodically searching for and applying a specific security descriptor – located on the AdminSDHolder object. The descriptor contains security information about the protected object, and if unauthorized changes are made to the object, the process overwrites the settings with the information contained in the descriptor. If one wants to change permissions on a Protected Object, one must change the security descriptor for the AdminSDHolder object so that it is then applied consistently.

Care must be taken at this point. Searching for adminCount may return a result that does not contain the accounts you are actually looking for, or expecting. This is due to the fact that adminCount does not only indicate the current status of an account, but also that of the past. When administrative privileges are assigned to an account (e.g. by adding it to the Domain Admins group), the account is assigned the attribute adminCount=1 – the account is now a protected object. If these privileges are revoked again (e.g. account is removed from group), the attribute is still present in the account.

If you want to search for all administrators, a recursive search of the group memberships is better suited instead of searching with the adminCount filter. To do this, you need to know which group to search for. At this point, accounts should be searched that have administrative privileges in the domain. In principle, the groups Administrators, Domain Admins and Enterprise Admins are of interest. The groups differ in some points and are partly nested with each other. To find all members, you have to perform a recursive query.

Resolve group memberships recursively

To find out which users are members of groups that are in turn contained in other groups, one could write a script that queries direct members of groups, checks which of them are in turn groups again, and then retrieves the direct members again, and so on, until one has queried the last subgroup as well. Fortunately this is not necessary, because in LDAP there are so called OID (Object Identifier) Matching Rules. In LDAP 3 different OID Matching Rules are implemented, which can be seen in the following table:

Matching rule OID String identifier (von Ntldap.h) Beschreibung
1.2.840.113556.1.4.803 LDAP_MATCHING_RULE_BIT_AND A match is found if all bits from the attribute match the value. This rule is equivalent to a bitwise AND operator.
1.2.840.113556.1.4.804 LDAP_MATCHING_RULE_BIT_OR A match is found if any bits of the attribute match the value. This rule is equivalent to a bitwise OR operator.
1.2.840.113556.1.4.1941 LDAP_MATCHING_RULE_IN_CHAIN This rule is limited to filters that refer to the DN (Distinguished Name). It is a special “extended” match operator that traverses the lineage chain in objects up to the root until it finds a match.

For a recursive query of the group membership, one uses the matching rule IN CHAIN and needs the distinguished name of the group. A clear list of the Common Names and corresponding Distinguished Names of all groups with members can easily be displayed with the following command:

Example output:

The matching rule is used in the search filter as follows:

It is important to remember that you want to have user objects as a result. This means that you are looking for the sAMAccountType=805306368 again and want to know if it is a member of a group. So the matching rule is applied to the memberOf attribute. A search for the members of the Domain Admins group from the sample output would look like this:

If you want to make it a bit easier, you can also store the value of the distinguishedname attribute in a variable and then call this in the search filter:

The same principle can be used to resolve which groups a specific user is in. You need the distinguished name of the user and use the OID matching rule IN CHAIN with the member attribute. For an assumed example user John Doe, one would make the following query:

The described searches show that the use of matching rules in the search filter are enormously useful if you know how and with which attributes to use them. You can also use matching rules to query information in bitmasks, but that will be covered in the next adsisearcher blogpost.

Series Overview

[1] Active Directory Security Groups, Microsoft Documentation, https://docs.microsoft.com/en-gb/windows/security/identity-protection/access-control/active-directory-security-groups

Share post on:

XING
Twitter
LinkedIn

Nina Fasel • Autor

Cyber Defense Analyst

Nina is passionate about challenging security projects. After initially entering the IT security industry as a pentester on the attacker side, she now applies her acquired knowledge to the detection, analysis and defense of cyber attacks.

> all articles
Cookie Consent with Real Cookie Banner