LDAP

Lightweight Directory Access Protocol | AD | User information | User accounts

Lightweight Directory Access Protocol (LDAP) is an integral part of Active Directory (AD). LDAP is open source and used for authentication against directory services such as Active Directory.

LDAP is the language that applications use to communicate with services like Active Directory and with other server that provide directory services as well. LDAP lets systems in the network talk with the AD.

2 types of LDAP authentication:

  1. Simple authentication including anonymous authentication, unauthenticated authentication, and username/password authentication. It will create a BIND request to LDAP server.
  2. SASL authentication. SASL using authentication services like Kerberos to bind to the LDAP server. The LDAP protocol sends LDAP message which starts challenge and response messages.

LDAP authentication messages are sent in cleartext.

LDAP queries<

Communicating with directory services using LDAP is done with queries.

Query Result
(objectCategory=computer) find all workstations in a network
((&(objectCategory=person)(objectClass=user)) searches for all users
(objectClass=group) searches for all groups

More queries: computers, users, groups.

Example queries

Find disabled users

Get-ADObject -LDAPFilter '(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))' -Properties * | select samaccountname,useraccountcontrol

Find out how many users, computers and groups

PS C:\Users\mczen> (Get-ADUser -Filter *).Count

# Or specify a group
(Get-ADGroupMember -Identity "IT").Count

Powershell Filters

Filters in PowerShell allows us to get better output and retreive data we are looking for. It can be used to narrow down specific data in large result.

This would filter out all Microsoft software making the list of search results a lot smaller.

PS C:\zen> get-ciminstance win32_product -Filter "NOT Vendor like '%Microsoft%'" | fl

IdentifyingNumber : {748D3A12-9B82-4B08-A0FF-CFDE83612E87}
Name              : VMware Tools
Vendor            : VMware, Inc.
Version           : 10.3.2.9925305
Caption           : VMware Tools
Meaning
-eq         Equal to
-le         Less than or equal to
-ge         Greater than or equal to
-ne         Not equal to
-lt         Less than
-gt         Greater than
-approx         Approximately equal to
-bor            Bitwise OR
-band           Bitwise AND
-recursivematch Recursive match
-like           Like
-notlike    Not like
-and            Boolean AND
-or         Boolean OR
-not            Boolean NOT

Find users with DoesNotRequirePreAuth who's accounts can be ASREPRoasted.

# Administrative groups
Get-ADUser -Filter {adminCount -eq '1' -and DoesNotRequirePreAuth -eq 'True'}

# All users
Get-ADUser -Filter {DoesNotRequirePreAuth -eq 'True'}

# Get group members
Get-ADGroupMember -Identity "Protected Users"

Get info about a host

# Get basic information
Get-ADComputer WS01

# Get detailed information, including operating system, last logon time, etc.
Get-ADComputer WS01 -Properties *

# Get specific properties
Get-ADComputer WS01 -Properties OperatingSystem, LastLogonDate, Description

LDAP Search Filters

The -LDAPFilter enables us to use LDAP search filters. LDAP filters must have 1 or more criteria, when using more we use AND or OR to concatenate.

Operator Function
& and
| or
! not

Search criteria

When using an LDAP search filter we need to specifiy rules, like (displayName=mczen).

CriteraRuleExample
Equal to(attribute=123)(&(objectclass=user)(displayName=Smith)
Not equal to(!(attribute=123))!objectClass=group)
Present(attribute=*)(department=*)

Object Identifiers (OIDs)

Object Identifiers (OIDs) are unique identifiers used to name objects. We can use machting rule OIDs with LDAP filters, found here. This query will return all administratively disabled user accounts, or ACCOUNTDISABLE (2) with matching rule: 1.2.840.113556.1.4.803

Get-ADUser -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=2)' | select name
  • 1.2.840.113556.1.4.803 is the Object Identifier (OID) for a bitwise AND operation.
  • :=2 checks if account is disbabled

Find all groups

Get-ADGroup -LDAPFilter '(member:1.2.840.113556.1.4.1941:=CN=Harry Jones,OU=Network Ops,OU=IT,OU=Employees,DC=ZENCORP,DC=LOCAL)' | select Name
  • 1.2.840.113556.1.4.1941 This OID find all groups that the user is a member off
  • :=: Specifies the equality match.

LDAP Queriy - Description Field

Get-ADUser -Properties * -LDAPFilter '(&(objectCategory=user)(description=*))' | select samaccountname,description
  • objectCategory=user: Ensures that only user objects are retrieved.
  • description=*: Ensures that only users with a non-empty description field are retrieved.

LDAP Query - Find Trusted Users

This filter "(userAccountControl:1.2.840.113556.1.4.803:=524288)" can be used to find all users or computers marked as trusted for delegation, or unconstrained delegation. Trusted users can act on behalf of other users in AD.

# Get users
Get-ADUser -Properties * -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=524288)' | select Name,memberof, servicePrincipalName,TrustedForDelegation | fl

# Get computers
Get-ADComputer -Properties * -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=524288)' | select DistinguishedName,servicePrincipalName,TrustedForDelegation | fl
  • 1.2.840.113556.1.4.803 is the Object Identifier (OID) for a bitwise AND operation
  • :=524288 checks if the bit corresponding to the TRUSTED_FOR_DELEGATION

LDAP Query - Users With Blank Password

Get-AdUser -LDAPFilter '(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=32))(adminCount=1)' -Properties * | select name,memberof | fl
  • (userAccountControl:1.2.840.113556.1.4.803:=32): Checks if the bit corresponding to the PASSWD_NOTREQD flag is set in the userAccountControl attribute. This indicates that a password is not required for the account.

LDAP Anonymous Bind

LDAP anonymous binds allow unauthenticated attackers to retrieve information from the domain, this can be used to list users, groups, computers, account attributes and password policies.

A anonymous bind is a request where the username and password fields are left empty.

We can use python to interact LDAP:

Python 3.8.5 (default, Aug  2 2020, 15:09:07) 
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldap3 import *
>>> s = Server('10.129.1.207',get_info = ALL)
>>> c =  Connection(s, '', '')
>>> c.bind()
True
>>> s.info

Ldapsearch

We can use tools suchas windapsearch and ldapsearch to enumerate a domain.

# ldapsearch
ldapsearch -H ldap://10.129.1.111 -x -b "dc=zencorp,dc=local"

# Info
python3 ldapsearch-ad.py -l 10.129.1.207 -t info

# Discover users in domain
ldapsearch -H ldap://10.129.86.8 -x -b "DC=ZENCORP,DC=LOCAL" -s sub "(&(objectclass=user))" | grep sAMAccountName: | cut -f2 -d" "

Windapsearch

# Check for bind
python3 windapsearch.py --dc-ip 10.129.1.111 -u "" --functionality

# Get domain users
python3 windapsearch.py --dc-ip 10.129.1.207 -u "" -U

# Show groups
python3 windapsearch.py --dc-ip 10.129.42.188 -u "" -G

# Unconstrained delegation
python3 windapsearch.py --dc-ip 10.129.42.188 -u "" -U --unconstrained-users

Credentialed Enumeration

When having domain credentials we get retrieve all kinds for information from LDAP.

python3 windapsearch.py --dc-ip 10.129.1.207 -u zencorpo\\john.doe --da

Of checking for users with unconstrained delegations.

python3 windapsearch.py --dc-ip 10.129.1.207 -d zencorp.local -u zencorp\\john.doe --unconstrained-users

Or using ldapsearch

# Check password policy
ldapsearch -l 10.129.1.207 -d zencorp -u john.doe -p pass123 -t pass-pols

# Check for Kerberoastable users
ldapsearch -l 10.129.1.207 -d zencorp -u john.doe -p pass123 -t kerberoast | grep servicePrincipalName

# Check ofr ASREPRoastable users
ldapsearch -l 10.129.1.207 -d zencorp -u john.doe -p pass123 -t asreproast

Properties here