Post

1.2 LDAP the AD

Definition :

The Lightweight Directory Access Protocol (LDAP) is a directory service protocol that runs on a layer above the TCP/IP stack. It provides a mechanism used to connect to, search, and modify Internet directories.

The LDAP directory service is based on a client-server model. The function of LDAP is to enable access to an existing directory.

What is directory services ?

Directory services is a database for storing and maintaining information about users and resources (Objects).

LDAP ObjectClass :

  • cn: Common name
  • description: Human-readable description of the entry
  • seeAlso: Reference to related entries
  • sn: Surname
  • telephoneNumber: A telephone number
  • userPassword: A password for the user
  • OU: Organizational unit

Enumeration :

System.DirectoryServices.DirectorySearcher

This is what LDAP path looks like "LDAP://<ServerName>/CN=Users,CN=LDAP,DC=SharePoint,DC=COM"

Using System.DirectoryServices.DirectorySearcher class :

1
2
3
4
5
6
7
8
9
10
11
#Getting All users
PS C:\> (New-Object DirectoryServices.DirectorySearcher ObjectClass=user).FindAll() | Select path

					Path
					-
LDAP://CN=Administrator,CN=Users,DC=m19oARSENAL,DC=com
LDAP://CN=Guest,CN=Users,DC=m19oARSENAL,DC=com
LDAP://CN=CAIRO,OU=Domain Controllers,DC=m19oARSENAL,DC=com
LDAP://CN=krbtgt,CN=Users,DC=m19oARSENAL,DC=com
LDAP://CN=VISTA,CN=Computers,DC=m19oARSENAL,DC=com
LDAP://CN=VistaAdmin,OU=Students,DC=m19oARSENAL,DC=com

[ADSISearcher]

Using [ADSISearcher] shortcut of System.DirectoryServices.DirectorySearcher class

1
2
3
4
5
6
7
8
#Searching for terminator user
PS C:\> ([ADSISearcher]"Name=terminator").FindAll() | Select Path

Path
-
LDAP://OU=terminator,DC=m19oARSENAL,DC=com
#Using PSremoting 
PS C:\> Invoke-Command -ComputerName machine.m19oARSENAL.Com -ScriptBlock {([ADSISearcher]"L=Cairo").Findall()}

Get-LDAP

For using LDAP you need to import NETcmdlets module

1
2
3
4
5
#Get a list of all groups
Get-LDAP -Server $server -Credential $mycred -DN $basedn -Search "(&(objectclass=group)(cn=*admin*))"

#Get a list of all members of a group
Get-LDAP -Server $server -Credential $mycred -DN $groupdn -Search "objectClass=*"

Ldapsearch

Using LDAPsearch

1
2
3
4
5
6
7
8
9
10
11
#Get all users
m19o@arsenal[/REDZON3]$ ldapsearch -h 10.5.4.2 -x -b "DC=m19oARSENAL,DC=LOCAL" -s sub "(&(objectclass=user))"  | grep sAMAccountName: | cut -f2 -d" "
guest
machine1
machine12
machine14
student
sutart
shaun
alex
roney

windapsearch

This is easier than building an LDAP query

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
m19o@arsenal[/REDZON3]$ ./windapsearch.py --dc-ip 10.5.4.2 -u "" -U

[+] No username provided. Will try anonymous bind.
[+] Using Domain Controller at: 10.5.4.2
[+] Getting defaultNamingContext from Root DSE
[+]	Found: DC=m19oARSENAL,DC=LOCAL
[+] Attempting bind
[+]	...success! Binded as: 
[+]	 None
[+] Enumerating all AD users
[+]	Found 2906 users: 

cn: Guest
cn: Student
userPrincipalName: student@m19oARSENAL.local
cn: sutart malcom
userPrincipalName: s.malcom@m19oARSENAL.local
cn: alex will
userPrincipalName: a.will@m19oARSENAL.local
cn: roney coleman
userPrincipalName: r.coleman@m19oARSENAL.local
cn: Walter white
userPrincipalName: w.white@m19oARSENAL.local

LdapFilter

Using LdapFilter

1
2
3
4
5
PS C:\> Get-ADObject -LdapFilter "(&(objectClass=user)(cn=*Terminator*))"

DistinguishedName                    Name   ObjectClass ObjectGUID
-----------------                    ----   ----------- ----------
CN=Terminator,CN=Users,DC=m19oARSENAL,DC=local Terminator user        90275385-55fc-4eec-834a-7eb39510ea11

DSquery

Using DSquery

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
PS C:\> dsquery * DC=m19oARSENAL,DC=local -attr *
objectClass: top
objectClass: domain
objectClass: domainDNS
distinguishedName: DC=m19oARSENAL,DC=local
instanceType: 5
whenCreated: 07/21/2022 07:40:03
whenChanged: 02/18/2023 04:20:32
subRefs: DC=ForestDnsZones,DC=m19oARSENAL,DC=local
subRefs: DC=DomainDnsZones,DC=m19oARSENAL,DC=local
subRefs: CN=Configuration,DC=m19oARSENAL,DC=local
uSNCreated: 4099
uSNChanged: 20164633
name: m19oARSENAL
objectGUID: {221EFDF0-41DD-4191-8615-9039C1647D92}
creationTime: 133211676324673321
forceLogoff: 461C9309-5168-1914-DD14-0FDFE122{ :DIUGtcejbo
lockoutDuration: objectGUID: {221EFDF0-41DD-4191-8615-9039C164600000000
lockOutObservationWindow: 461C9309-5168-1914-DD14-0FDFE122{ :DIUGtcejbo600000000
lockoutThreshold: 0
maxPwdAge: -4191-8615-9039C164 :wodniWnoitavresbOtuOkcol36288000000000
minPwdAge: lockOutObservationWindow: 461C9309-5168-1914-864000000000

Conclusion :

In red team activates we trying as much as we can to avoid public tools because every antivirus have a signatures for these tools, Living Off the Land techniques will be very useful to be un-detected, LDAP protocol is part of Active directory and every tool use it in enumeration, here in this blog i mentioned a lot of ways to enumerate the active directory with built-in tools and using .NET classes.

References :

  1. https://www.digitalocean.com/community/tutorials/understanding-the-ldap-protocol-data-hierarchy-and-entry-components
  2. https://adamtheautomator.com/ldap-filter/
This post is licensed under CC BY 4.0 by the author.