Beacon Object File for Active Directory LDAP enumeration.
Connects to a domain controller using the current session's Kerberos token (LDAP_AUTH_NEGOTIATE) and dumps AD objects — users, computers, groups, trusts, delegation configurations, and more. No new process, no PowerShell, runs inside Beacon's memory.
Full writeup: [coming soon]
The BOF uses wldap32.dll (already loaded in every Windows process) to bind to the target DC using the current session credentials. For each query it runs an LDAP search and walks every attribute the DC returns dynamically — no hardcoded attribute lists, output is equivalent to Get-ADUser -Properties *.
Binary attribute values (GUIDs, SIDs, objectGUID, nTSecurityDescriptor) are printed as hex pairs. Text values are printed as-is.
| Mode | What it returns |
|---|---|
users |
Enabled domain user accounts |
allusers |
All user accounts including disabled |
admins |
Domain Admins — recursive memberOf expansion |
computers |
Domain computers |
groups |
All groups |
ous |
Organizational Units |
domain |
Domain object + password policy |
trusts |
Domain trusts |
gpos |
Group Policy Objects |
spns |
Kerberoastable accounts (SPN set, enabled) |
asrep |
AS-REP roastable accounts (pre-auth disabled) |
unconstrained |
Unconstrained delegation — excluding DCs |
constrained |
Constrained delegation (msDS-AllowedToDelegateTo) |
rbcd |
Resource-Based Constrained Delegation |
acl |
Protected users (adminCount=1) — ACL abuse targets |
laps |
Computers with LAPS password attribute readable |
gmsa |
Group Managed Service Accounts |
all |
Run every query above in sequence |
dump |
Raw query — pass any LDAP filter as the 4th argument |
loader.exe ldap_enum.o str:<mode> str:<dc> str:<domain>
loader.exe ldap_enum.o str:users str:fvs-dc.fvs.lab str:fvs.lab
loader.exe ldap_enum.o str:spns str:fvs-dc.fvs.lab str:fvs.lab
loader.exe ldap_enum.o str:trusts str:fvs-dc.fvs.lab str:fvs.lab
loader.exe ldap_enum.o str:all str:fvs-dc.fvs.lab str:fvs.lab
loader.exe ldap_enum.o str:dump str:fvs-dc.fvs.lab str:fvs.lab str:"(sAMAccountName=Administrator)"
inline-execute ldap_enum.o str:users str:dc.corp.local str:corp.local
inline-execute ldap_enum.o str:spns str:dc.corp.local str:corp.local
inline-execute ldap_enum.o str:all str:dc.corp.local str:corp.local
Requires mingw-w64.
make # builds ldap_enum.o + loader.exe
make cleanManual BOF compile:
x86_64-w64-mingw32-gcc -o ldap_enum.o -c ldap_enum.c \
-masm=intel -O0 -mno-stack-arg-probe -fno-stack-checkOpen ldap_queries.h and add one row to QUERIES[]:
{
"myquery",
"(&(objectClass=user)(department=Engineering))",
"Engineering Users"
},{BASE} anywhere in the filter is replaced at runtime with the domain's base DN. Rebuild — ldap_enum.c picks it up automatically.
| File | Description |
|---|---|
ldap_enum.c |
BOF entry point — argument parsing, query dispatch |
ldap_core.h |
LDAP session, connection, attribute printer, query engine |
ldap_queries.h |
Query definitions — filters, headers, mode names |
beacon.h |
Cobalt Strike BOF API |
loader.c |
Standalone COFF loader for testing outside a C2 |
Makefile |
Build rules |
- Windows x64 — BOF and loader are x64 only
- Domain-joined context — connection uses
LDAP_AUTH_NEGOTIATE(current Kerberos token) - mingw-w64 for building:
x86_64-w64-mingw32-gcc
- Paged results are not implemented — very large domains (10k+ objects) may hit the DC's size limit on a single search. The DC will return a partial result with no error.
- Binary attributes (nTSecurityDescriptor, objectGUID) are printed as hex pairs, not decoded.
- LDAPS (port 636) is not supported — uses plaintext LDAP port 389.
MIT — see LICENSE