LDAPHunter - LDAP Enumeration Tool for Pentesters

Featured image

Why I Built It

If you have run a few Active Directory engagements, you already know the rhythm. You land on the internal network, you fire up a handful of enumeration commands, and ten minutes later you are staring at five terminal windows, pasting filters into ldapsearch, re-running crackmapexec with slightly different flags, and copying output into a notes file that grows scarier by the hour.

Most of that is mechanical. Same queries, same attributes, same tables. I got tired of doing it by hand, so I built LDAPHunter: a Python tool that runs the common LDAP enumeration checks against Active Directory and prints the results as clean tables you can paste straight into a report.

ldaphunter Repository: https://github.com/GhnimiWael/LDAPHunter


What It Does

LDAPHunter targets the information you actually care about on a pentest:

It is not meant to replace BloodHound or PowerView. It runs before them, gives you a snapshot of what is in the directory, and feeds the next steps of the engagement.


Installation

Requirements are light. Python 3 plus two libraries:

pip install ldap3 prettytable

Then clone the repo:

git clone https://github.com/GhnimiWael/LDAPHunter.git
cd LDAPHunter

That is it. No Docker, no virtualenv gymnastics. It runs on Kali, on a WSL shell, on a jumpbox.


Usage

LDAPHunter supports three authentication modes. Pick the one that matches what you have.

Authenticated bind

If you already have creds (phished, sprayed, found in a file share), pass them in:

python ldap_hunter.py -s 10.10.10.100 -d domain.lab -u 'domain\user' -P 'Password123!'

The -u flag accepts both DOMAIN\user and [email protected] formats. If one fails, try the other. Some DCs prefer one style over the other depending on how they are configured.

Anonymous bind

Not every DC allows this, but when it does, it can save you an hour during the first phase of an internal pentest:

python ldap_hunter.py -s 10.10.10.100 -d domain.lab --no-auth

If the server refuses the bind, you will see it quickly and move on to credential acquisition.

LDAPS (encrypted)

When port 389 is filtered but 636 is open, use LDAPS:

python ldap_hunter.py -s 10.10.10.100 -d domain.lab -u 'domain\user' -P 'Password123!' --ssl

What You Get

Output is tabular. Users, groups, OUs, password policies, and delegation findings are printed as readable tables. A few notes on what the tool highlights:


Troubleshooting

Common issues I have hit, and what to check:


Roadmap

Things on the backlog that I want to ship:

If you hit a bug or want a feature, the issue tracker is open.


Get It

If it saves you five minutes on your next engagement, it has paid for itself.