Active Directory, LDAP and adsisearcher – Driving on sight, or having perspective?

Definition of Active Directory

Microsoft itself defines Active Directory in a technical documentation as follows:

“Active Directory: The Windows implementation of a general-purpose directory service, which uses LDAP as its primary access protocol. Active Directory stores information about a variety of objects in the network such as user accounts, computer accounts, groups, and all related credential information […]. Active Directory is either deployed as Active Directory Domain Services (AD DS) or Active Directory Lightweight Directory Services (AD LDS) […].”[i]

Architecturally, Active Directory consists of four main components: Lightweight Directory Access Protocol (LDAP), Kerberos, Common Internet File System (CIFS) and Domain Name System (DNS).

LDAP is a network protocol that can be used to make queries (e.g. about users) and changes in a distributed directory service using a specific syntax. For this purpose, transmission must be possible on all systems involved. By default, LDAP traffic is transmitted unsecured over TCP port 389. However, it is also possible to use the LDAP data traffic with a secured TLS connection via TCP port 636.

The Kerberos protocol is used for authentication in Active Directory. Here, a user who authenticates himself with a password, for example, receives a ticket granting ticket (TGT), which he can then use to request tickets for other services within the network. It is therefore possible to use different services without having to authenticate again for each action.

DNS is responsible for name resolution in Active Directory and is defined as such by Microsoft:

“Domain Name System (DNS): A hierarchical, distributed database that contains mappings of domain names to various types of data, such as IP addresses. DNS enables the location of computers and services by user-friendly names, and it also enables the discovery of other information stored in the database.”[ii]

Among other things, DNS ensures that the domain controllers (DC) that provide the directory service can communicate with each other and that clients can search for these DCs.

CIFS is a protocol that allows files and documents to be stored on the network and on central components such as printers. DNS is again used to locate individual computer systems and service information (SRV Resource Record).

The structure of Active Directory

In Active Directory, domains are used to emulate organizational structures; a domain is always an organizational unit with a unique name, which contains, among other things, specific security policies and settings. Objects such as users or devices of a network including their attributes are stored in the domain. Within the domain, it is possible to group these objects via further organizational units (OU). Several domains can each form a domain tree, in which one domain represents the root domain, to which the other domains are subordinate. All domains of a domain tree form a continuous name, where the subordinate domain contains the name of the parent domain.

Example:

  • Root domain = secuinfra.com
    • Subordinate domain = cyberdefense.secuinfra.com
    • Subordinate domain = sales.secuinfra.com

Furthermore, it is also possible to connect two completely independent domains or domaintrees via a trust position. The combination of different domains is then called a forest. This creates the possibility of accessing the resources of a completely different domain, which has a completely different namespace. For example, it is possible for users of one domain to log on to the computers of another domain, provided that a trust relationship exists with this domain that allows this.

Active Directory contains an enormous amount of information about the managed resources. This includes users and their group memberships, but also information about the devices in the network (e.g. operating system versions of computers). This information can be very interesting for an attacker, as he can use it as a basis to find worthwhile targets and easy entry points such as outdated operating systems with known vulnerabilities. This allows him to plan his next steps and adapt his approach so that he can move around the infrastructure as undetected as possible.

Tools such as Bloodhound automate and facilitate the acquisition of this information by analyzing Active Directory environments and revealing often unintended relationships within an Active Directory environment. Potential attack paths can thus be identified and then mapped using graph theory. Here, the rights of any Active Directory user are sufficient to query almost all required information.

Therefore, it is also important for the defense of the corporate network to have a good overview of Active Directory and to be able to access the information from the directory service. This is especially true if, for example, there is insufficient or incomplete documentation or if you want to use the data to enrich log data from a SIEM system. But how can one proceed here?

Of course, you can also use tools such as Bloodhound, or take a look at the data manually via the GUI of a domain controller (DC). Basically, there are also a variety of tools that allow you to retrieve the data stored in Active Directory and do not necessarily require access with a privileged account to the DC.

However, many of these tools are third-party tools that need to be downloaded and installed first, which is not always possible. At this point, one can fall back on a .NET Framework class. The .NET Framework has been installed with the operating system since Windows Vista. For PowerShell 2.0, the .NET class System.DirectoryServices, which provides easy access to Active Directory Domain Services and enables queries against an AD domain using PowerShell with the component class DirectorySearcher, was developed.

The queries are performed using the Lightweight Directory Access Protocol (LDAP) implemented in Active Directory. One of the main advantages of using PowerShell is the ability to automate processes and adapt them to individual needs. Predefined queries can be saved in the form of a PowerShell script, which can be executed regularly as a task.

The use of System.DirectoryServices.DirectorySearcher

The prerequisites to use System.DirectoryServices.DirectorySearcher can be dealt with quickly:

  • A computer in the domain with a Windows operating system newer than Windows 7 / Windows Server 2008, including PowerShell.

The query itself consists of calling the class specifying the search and the method to be used to search:

The use of System.DirectoryServices.DirectorySearcher

([System.DirectoryServices.DirectorySearcher]'(searchquery)’).Methode()

But this query can be kept simpler – with less typing and a bit easier to remember – because for System.DirectoryServices.DirectorySearcher there is a type accelerator: adsisearcher. Type accelerators are aliases for .NET Framework classes and facilitate, or rather speed up, the use of these classes mainly by being shorter and thus saving time. The above search query can also be executed with adsisearcher as follows:

([adsisearcher]'(searchquery)’).Methode()

Adsisearcher provides numerous ways to query information from an Active Directory using the properties and methods of an LDAP query. It is beneficial to understand the basic logic of filters in LDAP queries, for example, when a query is equal (unique), logically equal or not equal:

  • Equal to (the search finds only results that match the query):
    (sAMAccountName=Knut)
  • Wildcard:
    (sAMAccountName=*Knut*)
  • greater/smaller operators (compares not only numerical values, also checks lexicographic attribute values – so letters and other patterns can be used as well):
    (sAMAccountName>=Kn*)
    (sAMAccountName<=Kn*)
  • Logical equal to AND (the search finds only results that match both search parameters of the query):
    (&(objectclass=user)(sAMAccountName=Knut))
  • Logical equal to OR (the search finds only results that match both search parameters of the query):
    (|(sAMAccountName=icebear)(sAMAccountName=Knut))
  • Not equal to (the search finds only results that do not contain the parameter specified in the query):
    (!sAMAccountName=Knut)

In addition, one must also specify a method with which the search is to be executed. Here you can choose between FindAll() (returns a collection of all found entries) and FindOne() (returns only the first found entry).

Relatively simple queries can be performed for users with certain names, for example. To do this, you need to know that the sAMAccountName attribute of an object stores the logon name for a user’s account, in the form of an “NT Logon Name”, just as it is composed in the Domain\LogonName name specification. A search for the default Administrator account can be done with a filter that searches for the sAMAccountName Administrator:

([adsisearcher]'(sAMAccountName=Administrator)’).FindAll()

If you want to find all users whose username starts with th, you can do this with a wildcard search:

([adsisearcher]'(sAMAccountName=th*)’).FindAll()

For example, this search would return objects with the sAMAccountName thorsten.mustermann or thomas.testuser. For each search you get a SearchResultCollection, which contains several objects. Each object in turn contains the path name of the object, as well as a ResultPropertyCollection, in which the attributes of the object are contained:

If you want to view these attributes, you can call them with FindAll().properties or FindOne().properties:

([adsisearcher]'(sAMAccountName=th*)’).FindAll().properties

The search result is the ResultPropertyCollection of the objects, represented in an assignment with name to value:

With a high number of results, however, this quickly becomes confusing, since the attributes in PowerShell are output continuously without optical separation of the individual objects. Each of the attributes contained in the ResultPropertyCollection can be searched for with a corresponding search filter. In addition to these relatively simple queries, adsisearcher can also be used to resolve groups recursively – to find all members, explicit and implicit, of the privileged Domain Admins group, for example – or to perform bitmask queries for specific attributes. Bitmasks are used to store various account settings. For example, a bitmask query of the userAccountControl attribute can be used to find out if an account is disabled or if a user cannot change his password. Therefore it is worth to understand and deal with LDAP and adsisearcher.

Series Overview

 

[i] [MS-KILE] – v20210625 Kerberos Protocol Extensions, Copyright © 2021 Microsoft Corporation Release: June 25, 2021, Seite 8 (https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-KILE/%5bMS-KILE%5d.pdf)

[ii] [MS-KILE] – v20210625 Kerberos Protocol Extensions, Copyright © 2021 Microsoft Corporation Release: June 25, 2021, Seite 9 (https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-KILE/%5bMS-KILE%5d.pdf)

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