Adsisearcher – Get the Object of Interest: Search for specific users and computers

How to find a specific “Object of Interest” or even several objects that have certain properties? The answer to this question is as logical as it is simple: you have to know and specify the right search filters.

First of all, it is necessary to distinguish whether you are searching for a person or for a computer. Here it is useful to search for the attributes objectclass and objectcategory. While objectClass represents the classification of user objects in the class hierarchy of the Active Directory schema, objectCategory as an addition to the information of the object class only helps with the classification. objectClass here is an array that always looks like this for users:

and for computer still contains the additional value computer:

The class specified last in the array is the “structural class” (=main class) and represents the actual object class. If you look at the two attributes, you will notice that when searching for the object class User, as in the example, both computer objects and user objects will be contained in the SearchResultCollection (= the results).

For this reason, the objectCategory is used as an additional specification in the search filter. It is a single value property that corresponds to the data type of the distinguished name. The value is either the distinguished name of the class of which the object is an instance or one of its superclasses. When an object is created, the system sets its objectCategory to the value specified in the defaultObjectCategory property of the object class. The value cannot be changed. In the example you can see the objectCategory of a user:

It is interesting at this point that in the filter syntax directly the pure category name can be used as objectCategory value – so objectCategory=Person instead of objectCategory=CN=Person,CN=Schema,CN=Configuration,DC=example,DC=com. This is not possible with other attributes of the Distinguished Name data type. Therefore, the correct filter to find all users using objectClass and objectCategory would be:

For computers, you can use this search accordingly:

Searching for users with the filter (&(objectClass=user)(objectCategory=person)) is also often suggested when searching the Internet for ldap search filters. It works, but it is inefficient and consumes a relatively large amount of server power. This is because the filter criteria “objectClass” and “objectCategory” make the technical search in the AD database more complex for the server. The more users there are in a domain, the more relevant the search efficiency becomes. Alternatively, you can use the filter sAMAccountType=805306368. For the attribute sAMAccountName there are some hexadecimal values, each of which indicates an account type. For objects of type User (SAM_USER_OBJECT) this value is 0x30000000.[1] If you convert this value into a decimal value, you get the value 805306368. Therefore for User objects the sAMAccountType value is always 805306368 and is indexed in the Active Directory database for fast searches. So with the following command you can search more effectively for all users in the domain:

Often, however, you want to search for certain users with specific properties. This can include the time period in which a user was last logged in, the time period in which a user was created, or whether a user is an SPN (Service Principal Name) account, i.e. a service account. This can be done by querying the attributes assigned to the objects.

Object of Interest: Last Logon

If you want to know when a user logged in last, you can use the attribute lastLogon. The value of the attribute is given as Windows File Time, e.g..:

This is a 64-bit value that specifies the number of 100-nanosecond intervals that have elapsed since 12:00 midnight, January 1, 1601 (UTC).[2]

If this value is 0, the user has never been logged in to the DC. This can be used to identify unused accounts that should be checked to see if they should be deleted in order to minimize the attack surface. So to find all users who have never been logged in, you can simply search for the value lastLogon=0:

However, it may also be of interest to find all users who have not been logged in for 30 days, for example. To do this, you need to compare the value of the attribute. Here it is useful to convert the comparison value – a time value, which you can get with Get-Date – into the Windows File Time format, which you can do with ToFileTime(). First you have to specify the time period with (Get-Date).AddDays(-30). Since times in LDAP are stored as UTC time, you also have to use ToUniversalTime(). To convert the value to Windows File Time, you then use the ToFileTime() method. With the operator <= then only users are searched, whose lastLogon value is smaller – thus temporally before the indicated time lie.

A search for all users who have not been logged in for more than 30 days looks like this:

It is also possible to narrow this search by hours and minutes using AddHours() and AddMinutes() as well. An example would be all users who have not been logged in for one day, five hours and 30 minutes:

Of course, it can also be very useful to be able to easily read the last logon of a user, which might be a bit awkward for humans with the Windows File Time format. To get the value of the lastLogon of a certain user in a pleasant, human-readable format you can use the type accelerator DateTime as follows:

Example output:

Object of Interest: Time of Creation

Not only the last logon, but also the creation time of a user is stored as a value in the attribute whencreated and can be output with the following query:

In contrast to lastLogon, you even get the output here in a human-readable format. However, the value is actually stored as YMD LDAP-timestamp, so that a comparison here must be done differently. The YMD LDAP-timestamps start with the year and have the following format: YYYYMMDDHHMMSST. The value T at the end is the time zone, which is normally Z (Zulu Time Zone = UTC/GMT). To create a comparison value here, you can use the format operator (-f) which requires the following syntax:

The string with placeholders describes here then the YMD format {0:yyyyMMddHHmmss.0Z} and in the array with Get-Date a certain time value can be called, which is converted then into the indicated format. For comparison, the operators <= or >= can also be used here.

With the following query one can find all users that were created 7 days, one hour and five minutes ago:

And with this query, you can find all users created after that time:

You can even search for users whose creation took place in a certain period of time by simply setting two search filters. In the following example, the first whencreated search indicates the earliest and the second search the latest time of the searched period:

Object of Interest: SPN Account

Service Principal Names (SPNs) are used in Active Directory to include services in Kerberos authentication. Tickets for the SPNs can be requested via Kerberos. It is possible to break the encryption of the tickets offline, which is especially useful for attackers when SPNs are bound to user accounts – this is common with service accounts. So one should keep a good track of SPN accounts.

If an account is an SPN account, it has the servicePrincipalName attribute, which can be searched for. Since ordinary users don’t have this property, you can simply use =* in the search to check if the attribute exists for an account to identify it as an SPN account. The value of servicePrincipalName also often contains information about the service and may look like this: smtp/DC1.example.com:145

A search for all SPN accounts would look like this:

If you additionally want to exclude all computer accounts that typically end in $, you can use this search:

You should also keep an eye on service accounts that were once logged in and, if necessary, check whether these are authorized logins:

Object of Interest: Computers

As mentioned at the beginning, the computers connected in the domain can also be found by searching for object class and object category Computer ((&(objectClass=computer)(objectCategory=computer))). A second possibility is to search for the Primary Group ID. The Primary Group ID is used for POSIX compatibility, i.e. for a possible interaction with Unix systems and is not required by Windows itself. However, it is entered for each object. The POSIX standard requires that each user belongs to (exactly) one group. Windows represents this as “Primary Group”. The primary group is automatically stored directly in the object in the field “primaryGroupID”. Here not the name of the group, but the RID (Relative Identifier = the last section of the SID [Security Identifier]) is stored.

The following primary group IDs are relevant for computers:

  • 515 = Domain Computer
  • 516 = Domain Controller
  • 521 = read-only Domain Controller

The following searches can then be used to search specifically for computers, domain controllers, or read-only domain controllers in the domain:

If you want to get information about the operating systems of the computers connected in the domain
you can, for example, display all operating systems by searching for (&(objectClass=computer)(objectCategory=computer)) with the FindAll() method and displaying only the values for operatingSystem:

You can also search for specific operating systems:

It is also possible to search for operating systems containing a specific term using wildcard(s):

With the listed searches you can already gather a lot of information about users, which can help to get a good overview of an Active Directory, as well as to find “deadbeats”. But with adsisearcher you can find out even more, like group memberships. So stay curious and learn more about adsisearcher.

Series Overview

 

[1] 2.223 Attribute sAMAccountType: Microsoft Documentation, https://docs.microsoft.com/en-gb/openspecs/windows_protocols/ms-ada3/7879be50-7109-41e4-9a44-02f5a007b950

[2] File Times: Microsoft Documentation, https://docs.microsoft.com/en-us/windows/win32/sysinfo/file-times

Share post on:

XING
Twitter
LinkedIn

Nina Disterhoft • 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