| name | ad-discovery |
| description | Enumerates Active Directory domains and maps attack surface for penetration testing.
|
| keywords | ["enumerate domain","AD recon","bloodhound","domain enumeration","active directory","find attack paths","domain controllers","kerberos","pre2k","pre-created computer accounts","machine account default password","netexec modules"] |
| tools | ["bloodhound-python","rusthound-ce","netexec","certipy","bloodyAD","kerbrute","Impacket","PowerView"] |
| opsec | medium |
AD Attack Discovery
You are helping a penetration tester enumerate an Active Directory domain and
identify attack paths. All testing is under explicit written authorization.
This skill works at three access levels:
- No credentials — network-level recon, poisoning, RID cycling
- Username only — AS-REP roasting, Kerberos user validation
- Valid credentials — full enumeration, BloodHound, ADCS, ACLs
Engagement Logging
Check for ./engagement/ directory. If absent, proceed without logging.
When an engagement directory exists:
- Print
[ad-discovery] Activated → <target> to the screen on activation.
- Evidence → save significant output to
engagement/evidence/ with
descriptive filenames (e.g., sqli-users-dump.txt, ssrf-aws-creds.json).
Scope Boundary
This skill covers Active Directory discovery — enumerating domain objects,
identifying misconfigurations, and reporting findings to the orchestrator.
When you confirm an exploitable finding — STOP.
Do not load or execute another skill. Do not continue past your scope boundary.
Instead, return to the orchestrator with:
- What was found (vulns, credentials, access gained)
- Detection details (finding type, affected objects, evidence)
- Context for technique execution (credentials, DC hostname, domain name, etc.)
The orchestrator decides what runs next. Your job is to execute this skill
thoroughly and return clean findings.
Stay in methodology. Only use techniques documented in this skill. If you
encounter a scenario not covered here, note it and return — do not improvise
attacks, write custom exploit code, or apply techniques from other domains.
The orchestrator will provide specific guidance or route to a different skill.
You MUST NOT:
- Perform Kerberoasting or AS-REP roasting beyond identifying targets
- Exploit delegation misconfigurations
- Exploit ACL misconfigurations
- Perform credential dumping
- Forge tickets
- Perform coercion or relay attacks
- Exploit ADCS beyond enumeration
When you find exploitable attack paths, present routing recommendations in
your return summary. Do not continue past enumeration.
State Management
Call get_state_summary() from the state MCP server to read current
engagement state. Use it to:
- Skip re-testing targets, parameters, or vulns already confirmed
- Leverage existing credentials or access for this technique
- Understand what's been tried and failed (check Blocked section)
State Writes
Write actionable findings immediately via state so the orchestrator
can react in real time (via event watcher) instead of waiting for your full
return summary. Use these tools as you discover findings:
add_credential() — valid credentials (pre-created computer accounts, gMSA readable, cleartext in descriptions/GPP/shares)
add_vuln() — ADCS misconfigs (ESC1-ESC8), Kerberoastable accounts, coercion vectors, SMB signing disabled, LDAP signing not required
add_pivot() — delegation paths, ACL abuse chains, trust relationships, new subnets from AD Sites
add_blocked() — techniques attempted and failed (so orchestrator doesn't re-route)
Your return summary must include:
- New targets/hosts discovered (with ports and services)
- New credentials or tokens found
- Access gained or changed (user, privilege level, method)
- Vulnerabilities confirmed (with status and severity)
- Pivot paths identified (what leads where)
- Blocked items (what failed and why, whether retryable)
Prerequisites
- Network access to the target domain (ports 88, 135, 389, 445, 636)
- For unauthenticated enumeration: just network access
- For authenticated enumeration: valid domain credentials (any privilege level)
- Tools:
netexec (nxc), bloodhound-python or rusthound-ce, certipy,
bloodyAD, kerbrute, Impacket suite (GetUserSPNs.py, GetNPUsers.py,
lookupsid.py)
Kerberos-first authentication (when credentials are available):
This skill may start unauthenticated. Once credentials are obtained, switch
to Kerberos authentication for all subsequent enumeration:
getTGT.py DOMAIN/user:'Password123'@dc.domain.local
getTGT.py DOMAIN/user@dc.domain.local -hashes :NTHASH
export KRB5CCNAME=user.ccache
Step 1: Initial Reconnaissance
Identify domain controllers and assess the network posture.
Find Domain Controllers
nslookup -type=srv _ldap._tcp.dc._msdcs.DOMAIN.LOCAL
nslookup -type=srv _kerberos._tcp.DOMAIN.LOCAL
nxc smb 10.10.10.0/24
nxc smb 10.10.10.0/24 --generate-hosts-file hosts
Check Signing and Relay Posture
nxc smb 10.10.10.0/24 | grep -i "signing:False"
nxc ldap DC01.DOMAIN.LOCAL
nxc ldap DC01.DOMAIN.LOCAL --port 636
Findings:
- SMB signing disabled on non-DCs -> note for coercion/relay
- LDAP signing not required -> note for relay to LDAP
- Domain name, DC hostnames, OS versions -> record in the engagement state
State writes:
- SMB signing disabled →
add_vuln(title="SMB signing disabled on <host>", host="<host>", vuln_type="smb-signing", severity="medium")
- LDAP signing not required →
add_vuln(title="LDAP signing not required on <host>", host="<host>", vuln_type="ldap-signing", severity="medium")
- Domain name/hostnames discovered →
add_pivot(source="AD discovery", destination="<domain>/<hostname>", method="DNS/SMB enumeration")
Step 2: Unauthenticated Enumeration
Use when no valid credentials are available yet.
Null Session / Guest Access
nxc smb DC01.DOMAIN.LOCAL -u '' -p ''
nxc smb DC01.DOMAIN.LOCAL -u 'guest' -p ''
enum4linux -a -u "" -p "" DC01.DOMAIN.LOCAL
rpcclient -U "" -N DC01.DOMAIN.LOCAL -c "enumdomusers;enumdomgroups;querydominfo"
RID Cycling (Unauthenticated User Enumeration)
nxc smb DC01.DOMAIN.LOCAL -u 'guest' -p '' --rid-brute 10000
lookupsid.py -no-pass 'guest@DC01.DOMAIN.LOCAL' 20000
nxc smb DC01.DOMAIN.LOCAL -u '' -p '' --rid-brute \
| awk -F'\\\\| ' '/SidTypeUser/ {print $3}' > users.txt
Kerberos Username Enumeration
kerbrute userenum -d DOMAIN.LOCAL --dc DC01.DOMAIN.LOCAL usernames.txt
Use output as username list for password spraying and AS-REP roasting checks.
Unauthenticated ADCS CA Enumeration
nxc smb DC01.DOMAIN.LOCAL -M enum_ca
If CAs found, note for authenticated ADCS enumeration in Step 3 (certipy).
LLMNR/NBT-NS/mDNS Poisoning Check
If network position allows, note LLMNR/NBT-NS traffic for Responder-based
hash capture. → STOP. Return to orchestrator with: DC IP, domain name, network
position, LLMNR/NBT-NS traffic details. Do not execute poisoning or relay
commands inline.
Step 3: BloodHound Collection
The single highest-value enumeration step. Requires valid domain credentials.
Linux (Remote Collection)
bloodhound-python -d DOMAIN.LOCAL -u 'user' -p 'Password123' \
-gc DC01.DOMAIN.LOCAL -c all -ns DC_IP
rusthound-ce -d DOMAIN.LOCAL -u 'user@DOMAIN.LOCAL' -p 'Password123' \
-o /tmp/bloodhound -z --adcs
export KRB5CCNAME=user.ccache
bloodhound-python -d DOMAIN.LOCAL -u 'user' -k -no-pass \
-gc DC01.DOMAIN.LOCAL -c all
Windows (On-Host Collection)
# SharpHound — full collection
.\SharpHound.exe -c all -d DOMAIN.LOCAL --searchforest
# Stealthier — DC-only mode (no host enumeration)
.\SharpHound.exe --CollectionMethod DCOnly
# OPSEC — throttle and randomize
.\SharpHound.exe -c all,GPOLocalGroup --throttle 10000 --jitter 23
# SOAPHound — uses ADWS instead of LDAP (avoids LDAP monitoring)
SOAPHound.exe --buildcache -c c:\temp\cache.txt
SOAPHound.exe -c c:\temp\cache.txt --bhdump -o c:\temp\bh-output
SOAPHound.exe -c c:\temp\cache.txt --certdump -o c:\temp\bh-output
ADCS Certificate Data
certipy find 'DOMAIN/user:Password123@DC01.DOMAIN.LOCAL' \
-output engagement/evidence/certipy-full-DOMAIN
certipy find 'DOMAIN/user:Password123@DC01.DOMAIN.LOCAL' -vulnerable -hide-admins \
-output engagement/evidence/certipy-vulnerable-DOMAIN
certipy find 'DOMAIN/user@DC01.DOMAIN.LOCAL' -k \
-output engagement/evidence/certipy-full-DOMAIN
State writes: Vulnerable ADCS templates found →
add_vuln(title="ADCS <ESC_type> on <template>", host="<CA_host>", vuln_type="adcs", severity="high").
Certipy output: Always use -output engagement/evidence/certipy-<label>
to write results to the evidence directory. Without -output, certipy writes
{timestamp}_Certipy.{json,txt} to CWD, polluting the working directory.
Certipy version notes:
- Certipy v5.0+ removed the
-bloodhound flag. Run certipy find without it
— v5 outputs JSON by default. Import the JSON into BloodHound CE manually.
- If
-vulnerable returns 0 results, re-run without it to get the full
template list. Some ESC variants (ESC9-15) require manual analysis of the
full output rather than certipy's built-in vulnerability checks.
BloodHound Analysis Priorities
After importing data, run these queries first:
- Shortest Paths to Domain Admins — identify the quickest win
- Kerberoastable Users — prioritize by blast radius and pwdLastSet age
- AS-REP Roastable Users — free hashes, no special access needed
- Unconstrained Delegation — TGT harvesting opportunities
- Dangerous ACLs — GenericAll/WriteDACL/WriteOwner on high-value targets
- ADCS Attack Paths — ESC1-ESC15 (requires certipy data import)
- Owned -> Domain Admins — mark owned principals and find chains
Step 4: Targeted Enumeration
Deeper enumeration beyond BloodHound. Run these based on what BloodHound reveals.
Password Policy
nxc smb DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' --pass-pol
enum4linux -u 'user' -p 'Password123' -P DC01.DOMAIN.LOCAL
(Get-DomainPolicy)."SystemAccess"
Record lockout threshold, observation window, complexity requirements. Report
for password spraying decisions.
Fine-Grained Password Policies (PSOs)
nxc ldap DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M pso
PSOs override default domain policy for specific groups. A service account
group may have no lockout while user accounts lock at 5 attempts. Report any
PSOs found — they affect password spraying decisions.
Pre-Windows 2000 Computer Accounts
High-value quick win. Pre-created computer accounts (created via "Pre-Windows
2000 Compatible" checkbox in ADUC or New-ADComputer) often have their password
set to the sAMAccountName in lowercase, minus the trailing $. For example,
MS01$ has password ms01. This is a common administrative oversight that
yields machine account credentials with zero noise.
nxc ldap DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M pre2k
What pre2k checks:
- Finds computer accounts in the "Pre-Windows 2000 Compatible Access" group
or with
userAccountControl flags indicating pre-creation
- Tests each account with
sAMAccountName.rstrip('$').lower() as the password
- Attempts to obtain a TGT — if successful, the password is confirmed
Why this matters:
- Machine accounts often have broad read rights (BloodHound "Owned" marking)
- Machine accounts in groups like "Domain Secure Servers" can read gMSA passwords
- Machine accounts may have constrained delegation, RBCD, or other privileges
- A pre2k computer account is functionally equivalent to a domain user credential
but with a machine account's group memberships and trust level
If pre2k finds valid machine credentials → write immediately:
add_credential(username="MACHINE$", secret="machine", source="pre2k module on <DC>").
Also record in your return summary: account name, confirmed password, and any
group memberships or privileges visible from LDAP.
NetExec Module Sweep
Run these modules as a batch during authenticated enumeration. They are all
non-destructive and low-privilege — any domain user can run them.
Quick-Win Credential Checks
nxc ldap DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M get-desc-users
nxc smb DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M gpp_password
nxc smb DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M gpp_autologin
User descriptions are a common source of cleartext passwords — admins often
document initial passwords or service account passwords in the AD description
field. Any result containing password-like strings is a credential finding.
Write immediately: add_credential(username=..., secret=..., source="AD description field").
Coercion & Relay Surface
nxc smb DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M webdav
nxc smb DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M spooler
nxc smb DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M coerce_plus
Note all coercion-eligible hosts. WebDAV is especially valuable — it enables
HTTP-based coercion that works even when SMB signing is enforced.
State writes: Coercion-eligible hosts →
add_vuln(title="Coercion: <type> on <host>", host="<host>", vuln_type="coercion", severity="medium").
Attack Surface Mapping
nxc smb DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M enum_av
nxc ldap DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M maq
nxc ldap DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M obsolete
nxc ldap DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M badsuccessor
Network Topology
nxc ldap DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M get-network
nxc ldap DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M subnets
nxc smb DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M ioxidresolver
SCCM and Infrastructure
nxc ldap DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M sccm
nxc ldap DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M entra-id
nxc ldap DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M dns-nonsecure
If SCCM found → note for SCCM exploitation. If Entra ID Connect server
found → high-value target (stores cleartext AD sync credentials). If
nonsecure DNS updates allowed → note for ADIDNS poisoning (enables
MITM/coercion without LLMNR).
ADIDNS Zone ACL Check
Standard in most AD environments. Authenticated Users have CreateChild on
AD-Integrated DNS zones by default, allowing any domain user to create new A
records. This enables ADIDNS poisoning: redirect hostnames that don't have DNS
records (or that you can overwrite) to the attackbox for credential capture.
dacledit.py -action read -target-dn \
'DC=DOMAIN.LOCAL,CN=MicrosoftDNS,DC=DomainDnsZones,DC=DOMAIN,DC=LOCAL' \
'DOMAIN/user:Password123@DC01.DOMAIN.LOCAL'
python3 /opt/krbrelayx/dnstool.py -u 'DOMAIN\user' -p 'Password123' \
-r '*' --action query DC01.DOMAIN.LOCAL
Cross-reference with engagement state: Check for unreachable hostnames in
the pivot map or blocked items — linked server data sources, SPN hostnames,
or service references that resolved to nothing. If an expected hostname has no
DNS A record and Authenticated Users can create records, this is a high-value
pivot: create an A record pointing to the attackbox, then capture credentials
when the service authenticates.
State writes: ADIDNS CreateChild confirmed →
add_vuln(title="ADIDNS: Authenticated Users can create DNS records", host="<DC>", vuln_type="adidns-poisoning", severity="critical").
Cross-reference with unreachable hostnames →
add_pivot(source="ADIDNS poisoning", destination="<hostname> → attackbox for credential capture", method="Create A record for <hostname> pointing to attackbox, trigger service authentication, capture with Responder").
SPN Enumeration (Kerberoasting Targets)
GetUserSPNs.py DOMAIN/user:'Password123' -dc-ip DC_IP
nxc ldap DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' --kerberoasting output.txt
.\Rubeus.exe kerberoast /stats
If SPNs found on user accounts → STOP. Report: DC IP, domain name, SPN list,
current credentials. Do not request or crack service tickets inline.
AS-REP Roastable Accounts
GetNPUsers.py DOMAIN/user:'Password123' -dc-ip DC_IP
bloodyAD -u user -p 'Password123' -d DOMAIN.LOCAL --host DC_IP \
get search --filter '(&(userAccountControl:1.2.840.113556.1.4.803:=4194304)(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))' \
--attr sAMAccountName
If found → STOP. Report: DC IP, domain name, AS-REP roastable user list,
current credentials. Do not request or crack AS-REP hashes inline.
Delegation Enumeration
bloodyAD -u user -p 'Password123' -d DOMAIN.LOCAL --host DC_IP \
get search --filter '(userAccountControl:1.2.840.113556.1.4.803:=524288)' \
--attr sAMAccountName,dNSHostName
bloodyAD -u user -p 'Password123' -d DOMAIN.LOCAL --host DC_IP \
get search --filter '(msDS-AllowedToDelegateTo=*)' \
--attr sAMAccountName,msDS-AllowedToDelegateTo
bloodyAD -u user -p 'Password123' -d DOMAIN.LOCAL --host DC_IP \
get search --filter '(msDS-AllowedToActOnBehalfOfOtherIdentity=*)' \
--attr sAMAccountName
Get-DomainComputer -Unconstrained
Get-DomainUser -TrustedToAuth
Get-DomainComputer -TrustedToAuth
State writes: Delegation paths found →
add_pivot(source="<account>", destination="<target_service>", method="<unconstrained|constrained|RBCD> delegation").
If found → STOP. Report: DC IP, domain name, delegation type and targets,
current credentials. Do not exploit delegation inline.
Privileged Group Membership
nxc ldap DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' --admin-count
bloodyAD -u user -p 'Password123' -d DOMAIN.LOCAL --host DC_IP \
get object "DNSAdmins" --attr msds-memberTransitive
bloodyAD -u user -p 'Password123' -d DOMAIN.LOCAL --host DC_IP \
get object "Backup Operators" --attr msds-memberTransitive
LAPS / gMSA / dMSA
nxc ldap DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M laps
nxc ldap DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' --gmsa
If readable → STOP. Report: DC IP, domain name, LAPS/gMSA target details,
current credentials. Do not extract managed passwords inline.
Trust Enumeration
nxc ldap DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -M enum_trust
nltest /domain_trusts /all_trusts /v
Get-DomainTrust
Get-NetForestDomain
Get-DomainForeignUser
Get-DomainForeignGroupMember
If trusts found → STOP. Report: DC IP, domain name, trust relationships
enumerated, trust types and directions, current credentials. Do not exploit
trust relationships inline.
Share Enumeration
nxc smb 10.10.10.0/24 -u 'user' -p 'Password123' --shares
manspider DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -d DOMAIN \
-c password passwd cred secret connectionstring
manspider DC01.DOMAIN.LOCAL -u 'user' -p 'Password123' -d DOMAIN \
-e '(password|passwd|pwd)\s*[=:]\s*\S+' -f xml conf config ini txt ps1 bat vbs kdbx
Check SYSVOL/NETLOGON for Group Policy Preferences (GPP) passwords, scripts
with embedded credentials, and configuration files.
High-value file patterns in shares — when spidering user home directories,
SYSVOL, or custom shares, look for:
| Pattern | Why |
|---|
*.xml (especially azure.xml, gpp.xml, *.runconfig.xml) | Azure AD credential exports (PSADPasswordCredential), GPP cpassword, deployment configs |
Groups.xml, Services.xml, Scheduledtasks.xml, DataSources.xml | GPP passwords (MS14-025) — in SYSVOL Policies/ subdirectories |
web.config, *.config | .NET connection strings, API keys |
*.ps1, *.bat, *.cmd, *.vbs | Scripts with hardcoded credentials |
*.kdbx, *.key | KeePass databases and key files |
*.pfx, *.p12, *.pem | Certificates and private keys |
unattend.xml, sysprep.xml | Deployment credentials |
Download and inspect any XML files found in user home directories — Azure AD
credential exports are a common source of cleartext domain passwords.
Session Enumeration
nxc smb 10.10.10.0/24 -u 'user' -p 'Password123' --sessions
nxc smb 10.10.10.0/24 -u 'user' -p 'Password123' --loggedon-users
Invoke-UserHunter -Stealth
Find-DomainUserLocation
Local Admin Access
nxc smb 10.10.10.0/24 -u 'user' -p 'Password123'
Find-LocalAdminAccess -Verbose
If local admin found → STOP. Report: target hostname, local admin
credentials, DC IP, domain name. Do not dump credentials inline.
SCCM / Deployment
python3 sccmhunter.py find -u 'user' -p 'Password123' -d DOMAIN.LOCAL -dc-ip DC_IP
If SCCM found → STOP. Report: DC IP, domain name, SCCM server details,
current credentials. Do not exploit SCCM inline.
Step 5: Prioritize and Return
After mapping the attack surface, STOP and return to the orchestrator with all
findings categorized by type and priority.
Priority Order
When multiple attack paths exist, prioritize by OPSEC and reliability:
- Pre-2k computer accounts / GPP passwords / description creds — instant
credentials, zero noise, no cracking needed
- Kerberos roasting / AS-REP roasting — offline cracking, low detection
- ADCS template abuse — certificate-based, stealthy, persistent
- ACL abuse — targeted, often unmonitored
- Delegation abuse — Kerberos-based, moderate detection
- Password spraying — risk of lockout, use as last resort for initial access
- Coercion/relay — requires network position, noisy
- Credential dumping — requires existing admin access
Return Summary
Present all findings with:
- Multiple paths identified: Present the top 3 paths ranked by OPSEC and reliability.
- No clear path: Recommend expanding enumeration scope (additional subnets,
different protocols), password spraying, or relay opportunities.
- Credentials found in shares/GPP: Report for deeper authenticated enumeration.
When returning, pass along:
- Target user/host/service
- Current credentials and access level
- Domain name and DC hostname
- Relevant enumeration output
Troubleshooting
BloodHound Collection Fails
- LDAP connection refused: Try port 636 (LDAPS) with
--ssl flag
- Access denied: Verify credentials; any domain user can run BloodHound
- Timeout: Use
--CollectionMethod DCOnly for stealthier, faster collection
- Missing ADCS data: Run
certipy find separately and import JSON into BH CE
Kerberos Errors
- KRB_AP_ERR_SKEW: Clock out of sync (> 5 minutes from DC). This is a
Clock Skew Interrupt — stop immediately and return to the orchestrator.
Do not retry or fall back to NTLM. Return to orchestrator — clock sync
requires sudo which subagents cannot run.
- KDC cannot find the name: Use FQDN hostnames, not IP addresses. If
hostnames don't resolve, return to orchestrator with the hostnames and IPs
— the orchestrator handles
/etc/hosts updates (requires sudo).
- Do NOT run
sudo or modify /etc/hosts — subagents lack sudo. Report
unresolvable hostnames in your return summary.
NetExec Connection Issues
- SMB SessionError STATUS_NOT_SUPPORTED: Target may require SMBv3 or
NTLMv2. Try
--smb2 flag
- Connection timed out: Host may be down or firewalled. Try different
protocols (LDAP, WinRM, RDP)
bloodyAD LDAP Filter Errors
LDAP filters with ! (NOT operator) can fail due to bash history expansion.
Always use single quotes around filters, not double quotes:
bloodyAD ... get search --filter '(!(userAccountControl:1.2.840.113556.1.4.803:=2))'
bloodyAD ... get search --filter "(!(userAccountControl...))"
If filters still fail, simplify by removing the NOT clause and filtering the
output with grep -v instead.
Impacket Tool Naming
Impacket tools may be installed under different names depending on the system:
| Packaged (pip/apt) | Script name | Both work |
|---|
impacket-getTGT | getTGT.py | Same tool |
impacket-GetUserSPNs | GetUserSPNs.py | Same tool |
impacket-GetNPUsers | GetNPUsers.py | Same tool |
impacket-secretsdump | secretsdump.py | Same tool |
Check which form is available before use:
which getTGT.py 2>/dev/null || which impacket-getTGT 2>/dev/null
The .py form is common on manually-installed Impacket; the impacket- prefix
comes from pip/apt packages.
NoPac Scanner False Positives
The nxc ldap -M nopac scanner compares TGT sizes with and without PAC. The
target is only vulnerable when tgt_no_pac < tgt_with_pac (different sizes).
If both sizes are equal (e.g., 1548 == 1548), the target is NOT vulnerable
— the PAC was not removed, meaning the patch is applied. Do not report equal
PAC sizes as a NoPac vulnerability.
No Credentials Available
Start with:
- RID cycling for username list
- AS-REP roasting against discovered usernames
- LLMNR/NBT-NS poisoning (if on-network)
- Password spraying with common passwords
- Check for anonymous LDAP bind (
nxc ldap DC -u '' -p '')