LDAP
Lightweight Directory Access Protocol | AD | User information | User accounts
Lightweight Directory Access Protocol (LDAP) is an integral part of Active Directory (AD). Latest version is RCF 4511. 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.

AD LDAP Authentication
There are 2 types of LDAP authentication:
Simple authentication including anonymous authentication, unauthenticated authentication, and username/password authentication. It will create a BIND request to LDAP server.
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 queries
Communicating with directory services using LDAP is done with queries.
(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
877
PS C:\Users\mczen> (Get-ADComputer -Filter *).Count
7
PS C:\Users\mczen> (Get-ADGroup -Filter *).Count
90
# 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
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 which syntax is defined here: https://datatracker.ietf.org/doc/html/rfc4515
LDAP filters must have 1 or more criteria, when using more we use AND or OR to concatenate.
&
and
|
or
!
not
Search criteria
When using an LDAP search filter we need to specifiy rules, like (displayName=mczen)
.
Equal to
(attribute=123)
(&(objectclass=user)(displayName=Smith)
Not equal to
(!(attribute=123))
!objectClass=group)
Present
(attribute=*)
(department=*)
More attributes https://docs.bmc.com/docs/fpsc121/ldap-attributes-and-associated-fields-495323340.html
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=INLANEFREIGHT,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 theTRUSTED_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 thePASSWD_NOTREQD
flag is set in theuserAccountControl
attribute. This indicates that a password is not required for the account.
Recursive Match
With RecursiveMatch we dcan find all of the groups an AD user is part of, both direct and inderect group memberships?
# Won't show nested groups
Get-ADUser -Identity harry.jones -Properties * | select memberof | ft -Wrap
# Will show all groups, including nested
Get-ADGroup -Filter 'member -RecursiveMatch "CN=Harry Jones,OU=Network Ops,OU=IT,OU=Employees,DC=INLANEFREIGHT,DC=LOCAL"' | select name
SearchBase and SearchScope Parameters
SearchScope
allows us to define how deep into the OU hierarchy we would like to search. This parameter has three levels:
Base
0
The object is specified as the SearchBase
. Base scope only looks at the OU itself, not at users within.
OneLevel
1
Searches for objects in the container defined by the SearchBase
but not in any sub-containers. Or 1 level deep.
SubTree
2
Entire subtree, including all levels of sub-containers and their children. Recursively all the way down the AD hierarchy.
Searchscope Base
# Count all AD users
PS C:\zen> (Get-ADUser -SearchBase "OU=Employees,DC=INLANEFREIGHT,DC=LOCAL" -Filter *).count
970
# Empty output
PS C:\zen> Get-ADUser -SearchBase "OU=Employees,DC=INLANEFREIGHT,DC=LOCAL" -SearchScope Base -Filter *
PS C:\zen>
# Search Base OU object
PS C:\zen> Get-ADObject -SearchBase "OU=Employees,DC=INLANEFREIGHT,DC=LOCAL" -SearchScope Base -Filter *
DistinguishedName Name ObjectClass ObjectGUID
----------------- ---- ----------- ----------
OU=Employees,DC=INLANEFREIGHT,DC=LOCAL Employees organizationalUnit 34f42767-8a2e-493f-afc6-556bdc0b1087
Searchscope OneLevel
# We get one user returned to us
PS C:\htb> Get-ADUser -SearchBase "OU=Employees,DC=INLANEFREIGHT,DC=LOCAL" -SearchScope OneLevel -Filter *
Searchscope Subtree
# Will count all objects
PS C:\zen> (Get-ADUser -SearchBase "OU=Employees,DC=INLANEFREIGHT,DC=LOCAL" -SearchScope Subtree -Filter *).count
# Or count all employees in IT
(Get-ADUser -SearchBase "OU=IT,OU=Employees,DC=INLANEFREIGHT,DC=LOCAL" -SearchScope Subtree -Filter *).count
PowerView
PowerView is a PowerShell tool for enumerationg AD's and gathering network information. It provides a set of functions to explore Active Directory, identify users, computers, and groups, and analyze their relationships. Use by Import-Module .\PowerView.ps1
.
# Show useraccountcontrol attributes.
Get-DomainUser * -AdminCount | select samaccountname,useraccountcontrol
# Find user in OU writers
Get-ADUser -SearchBase "OU=Writers,OU=Employees,DC=INLANEFREIGHT,DC=LOCAL" -Filter * | Select-Object SamAccountName
DS Tools
List the SAM account names of users whose passwords are set to never expire
dsquery user "OU=Employees,DC=inlanefreight,DC=local" -name * -scope subtree -limit 0 | dsget user -samid -
pwdneverexpires | findstr /V no
Windows Management Instrumentation (WMI)
Get-WmiObject -Class win32_group -Filter "Domain='INLANEFREIGHT'" | Select Caption,Name
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.
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
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
# Get domain computers
python3 windapsearch.py --dc-ip 10.129.1.207 -u "" -C
# Search for OU by user
python3 windapsearch.py --dc-ip 10.129.42.188 -u "" -s "john doe"
# 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
python3 ldapsearch-ad.py -l 10.129.1.207 -d zencorp -u john.doe -p pass123 -t pass-pols
# Check for Kerberoastable users
python3 ldapsearch-ad.py -l 10.129.1.207 -d zencorp -u john.doe -p pass123 -t kerberoast | grep servicePrincipalName
# Check ofr ASREPRoastable users
python3 ldapsearch-ad.py -l 10.129.1.207 -d zencorp -u john.doe -p pass123 -t asreproast
If we want to find users with smartcard_required
attribute set we can use the LDAP filter (userAccountControl:1.2.840.113556.1.4.803:=262144)
.
python3 ldapsearch-ad.py -l 10.129.42.188 -d zencorp -u john doe -p pass123 -t search -s "(userAccountControl:1.2.840.113556.1.4.803:=262144)"
userAccountControl
: LDAP attribute being queried:1.2.840.113556.1.4.803:
LDAP Matching Rule OID for bitwise matching:=
: bitwise AND operation262144
: corresponds to the SMARTCARD_REQUIRED flag

Last updated
Was this helpful?