🛡️ Methodology Checklist
- Use built-in tools only — avoid dropping binaries
- WMI enum:
Get-WmiObject -Class Win32_Service | select Name,StartName - AD RSAT:
Get-ADUser -Filter * -Properties * - dsquery:
dsquery user -limit 0 - PowerShell ActiveDirectory module (if available)
- net commands:
net user /domain,net group "Domain Admins" /domain - LDAP queries via .NET:
[System.DirectoryServices.DirectorySearcher] - Avoid Mimikatz/SharpHound if EDR is present — use LOTL alternatives
🎯 Operational Context
Use when: PowerShell is blocked, binaries are monitored by AV/AppLocker, and you need to enumerate AD using only built-in Windows commands.
Think Dumber First: net user /domain, net group "Domain Admins" /domain, nltest /dclist:[DOMAIN] — these are built-in, always present, rarely alerted on. Master them before reaching for PowerView.
Skip when: Full PowerShell and tooling available — LOL techniques are slower and return less data.
⚡ Tactical Cheatsheet
| Command | Tactical Outcome |
|---|---|
systeminfo | OS version, patch level, domain membership |
Get-MpComputerStatus | Defender real-time protection status |
netsh advfirewall show allprofiles | Firewall rules across all profiles |
qwinsta | Check active sessions — who else is logged into this host |
powershell.exe -version 2 | Downgrade to PS v2 — bypasses Script Block Logging |
Get-host | Confirm current PowerShell version |
arp -a | ARP cache — other hosts this machine has talked to |
route print | Routing table — identify additional subnets |
wmic ntdomain get Caption,Description,DnsForestName,DomainName,DomainControllerAddress | WMI domain info |
net group /domain | List all domain groups |
net user [USER] /domain | Detailed info for a domain user |
net localgroup administrators | Local admins on current host |
net1 user /domain | Same as net user /domain — bypasses string-match AV on net.exe |
dsquery user | LDAP query for all user objects |
dsquery computer | LDAP query for all computer objects |
dsquery * -filter "(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=32))" -attr distinguishedName userAccountControl | Find accounts with “Password Not Required” UAC flag (value 32) |
dsquery * -filter "(userAccountControl:1.2.840.113556.1.4.803:=8192)" -limit 5 -attr sAMAccountName | Find Domain Controllers (UAC flag 8192) |
🔬 Deep Dive & Workflow
When to Use LOTL
Modern EDR, Windows Defender, and network IDS catch external tools instantly. LOTL uses built-in Windows administration binaries to enumerate the domain without triggering standard malware detection. Use when:
- External tooling is blocked by AppLocker/AV
- A low-noise approach is required
- Operating from a host with limited transfer capabilities
Recon Sequence
# 1. Host baseline
systeminfo
Get-MpComputerStatus # Defender status
netsh advfirewall show allprofiles # Firewall posture
# 2. OpSec check — other admins on this host?
qwinsta
# 3. Bypass PS logging (if needed)
Get-host # confirm version 5.x
powershell.exe -version 2 # downgrade
Get-host # confirm v2.0
# 4. Network reconnaissance
arp -a # adjacent hosts
route print # pivot subnets
# 5. Domain enumeration
wmic ntdomain get Caption,Description,DnsForestName,DomainName,DomainControllerAddress
net group /domain
net user wley /domain
net localgroup administratorsdsquery — Native LDAP Queries
dsquery invokes the dsquery.dll available on modern Windows — no external tools needed:
dsquery user # all user objects
dsquery computer # all computer objects
# UAC bitwise filter — accounts with "Password Not Required" (bit 32)
dsquery * -filter "(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=32))" -attr distinguishedName userAccountControl
# Find all Domain Controllers (UAC bit 8192)
dsquery * -filter "(userAccountControl:1.2.840.113556.1.4.803:=8192)" -limit 5 -attr sAMAccountNameLDAP OID reference:
1.2.840.113556.1.4.803— bit must match exactly (AND)1.2.840.113556.1.4.804— any bit in the chain matches (OR)
Common UAC bit values:
| Value | Meaning |
|---|---|
| 32 | PASSWD_NOTREQD — Password not required |
| 512 | NORMAL_ACCOUNT |
| 8192 | SERVER_TRUST_ACCOUNT — Domain Controller |
| 65536 | DONT_EXPIRE_PASSWORD |
Key LOTL Caveats
net1instead ofnetbypasses basic string-matching AV rules targetingnet.exe- PS v2 downgrade hides subsequent commands from Script Block Logging, but the downgrade command itself is recorded in Event Viewer — aware defenders will spot it
qwinstabefore noisy commands — running heavy enumeration while a DA is actively logged on increases detection risk
🛠️ Troubleshooting & Edge Cases
| Problem | Cause | Fix |
|---|---|---|
| net commands return ‘System error 5’ | Not domain joined or no network | Verify domain join: echo %USERDOMAIN%; check network connectivity to DC |
| dsquery returns ‘object not found’ | Wrong LDAP base DN | Use dsquery * -scope base -attr dnsHostName to find correct base DN first |
| wmic /node:[DC] commands fail | WMI port 135 filtered | Use nltest and net alternatives that use SMB port 445 |
| PowerShell ADSI queries blocked | Language mode restricted | Try [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() — bypasses some restrictions |
| nltest /dsgetdc returns wrong DC | Using cached result | Force rediscovery: nltest /dsgetdc:[DOMAIN] /force /kdc |
📝 Reporting Trigger
Finding Title: Active Directory Enumeration via Native Windows Commands
Impact: Built-in Windows commands used for AD enumeration generate minimal alerts and evade most EDR signatures, enabling full domain reconnaissance without deploying any external tools.
Root Cause: No alerting on bulk net command usage or LDAP queries from native Windows tools. LOL enumeration indistinguishable from legitimate admin activity.
Recommendation: Enable Command Line Auditing (Event ID 4688) and PowerShell Script Block Logging. Alert on abnormal frequency of net user, net group, nltest from non-admin accounts. Deploy Microsoft Defender for Identity behavioral analytics.