# Ad Recon

> Active Directory reconnaissance skill — host discovery and comprehensive AD enumeration. Activate when the user wants to map an AD environment, enumerate users, groups, shares, trusts, SPNs, or BloodHound data before attacking. Also activate for phrases like "map the domain", "enumerate AD", "find AD users", "collect BloodHound data", or any variation of "start an AD pentest" on a domain target. Outputs feed directly into the ad-exploitation skill.

- Skill: `douglasrao/ad-recon` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add douglasrao/ad-recon`
- Raw SKILL.md: https://api.skillmd.com/api/skills/douglasrao/ad-recon/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Product & Planning
- Author: DouglasRao (https://skillmd.com/u/douglasrao)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/douglasrao/ad-recon

---


# AD Recon — Host Discovery & Enumeration Kill Chain

## Architecture

```
scripts/
├── common_ad.sh    # Shared functions (logging, has_tool, phase_done, emit_summary)
└── ad_enum.sh      # PHASES 1-2: host discovery + unauthenticated + authenticated enumeration
```

Each script:
- Accepts `<DC_IP> <DOMAIN> <OUT> [USERNAME] [PASSWORD_OR_HASH] [--phase=N]` as args
- Uses checkpoints (`.phase_X.done`) — re-run safely without repeating completed phases
- Emits a JSON summary via `---AD_SUMMARY_JSON---` markers for Claude to parse
- Handles missing tools gracefully — skips with warning, never crashes

---

## Initial Setup — Gather Required Information

Before running anything, ensure you have:

```
DC_IP    = IP of the Domain Controller (e.g., 192.168.1.10)
DOMAIN   = FQDN of the domain (e.g., corp.local)
USERNAME = domain user (optional — Phases 1 and 2 work unauthenticated)
PASSWORD = plaintext password (optional)
NTLM_HASH = LM:NT hash (optional, alternative to password)
```

If any of these are unknown, ask the user before proceeding.

```bash
DC_IP="10.10.10.100"
DOMAIN="corp.local"
USERNAME=""        # leave empty for unauthenticated phases
PASSWORD=""        # leave empty if using hash
NTLM_HASH=""       # format: LM:NT or just :NT

PROJECT=$(echo "$DOMAIN" | sed 's/\./-/g' | tr '[:upper:]' '[:lower:]')
OUT="$(pwd)/$PROJECT"
SCRIPTS="$HOME/.claude/skills/ad-recon/scripts"

mkdir -p "$OUT"/{enum,hashes,bloodhound}
```

Create progress tasks with TaskCreate:
```
"PHASE 1 — Host Discovery & Service Scan"
"PHASE 2 — Unauthenticated Enumeration (null sessions, LDAP, kerbrute)"
"PHASE 2auth — Authenticated Enumeration (ldapdomaindump, BloodHound, SPN/AS-REP lists)"
"PHASE 3 — Report & Attack Surface Summary"
```

Mark each task `in_progress` when starting, `completed` when done.

---

## Tool Priority

### 1. CLI — always first
```
nmap / rustscan          — host and port discovery
enum4linux-ng            — SMB/LDAP null session enumeration (preferred over enum4linux)
rpcclient                — null session: user/group enumeration
smbclient                — null session: share listing
ldapsearch               — anonymous LDAP bind, base DN discovery
kerbrute                 — user enumeration via Kerberos pre-auth (no account needed)
crackmapexec / netexec   — credential validation, SMB/LDAP/WinRM enumeration
ldapdomaindump           — full LDAP dump (requires valid creds)
bloodhound-python        — AD graph data collection (requires valid creds)
impacket-GetNPUsers      — identify AS-REP roastable accounts
impacket-GetUserSPNs     — identify Kerberoastable SPNs
```

### 2. MCPs (when available)
```
mcp__hexstrike-ai__*     — nmap_scan, enum4linux_ng_advanced, netexec_scan, rpcclient_enumeration, nbtscan_netbios
mcp__Notion__*           — publish final recon report
```

### 3. Manual fallbacks (no tools required)
```bash
rpcclient -U "" -N <DC_IP> -c "enumdomusers"
ldapsearch -x -H ldap://<DC_IP> -b "" -s base namingContexts
smbclient -L //<DC_IP> -N
```

---

## Operational Rules

- **Never install tools** without explicit permission
- **Connectivity first**: always verify `ping -c 1 $DC_IP` before running scripts
- **Lockout awareness**: kerbrute user enumeration does NOT attempt passwords — safe to run
- **Password spraying is NOT part of this skill** — that belongs in ad-exploitation
- **BloodHound collection** can be noisy — warn user before running in sensitive environments
- **Kerberos time skew**: if Kerberos errors occur, sync clock with `sudo ntpdate $DC_IP`
- **Windows commands**: PowerShell/net/cmd commands run on Windows targets only — present clearly labeled as "run on target"

---

## PHASE 1 — Host Discovery & Service Scan

```bash
bash "$SCRIPTS/ad_enum.sh" "$DC_IP" "$DOMAIN" "$OUT" --phase=1
```

**What it runs:**
- `ping -c 1 $DC_IP` — connectivity check
- nmap ping sweep of `/24` around DC_IP (finds other DCs, servers, workstations)
- nmap service scan of DC_IP on AD-critical ports: `53, 88, 135, 139, 389, 445, 464, 593, 636, 1433, 3268, 3269, 3389, 5985, 5986, 9389`
- rustscan fast full port scan if available

Read JSON summary. Flag key ports and note potential attack paths:

| Port | Service | Attack implication |
|------|---------|-------------------|
| 88 | Kerberos | AS-REP Roasting, Kerberoasting |
| 389/636 | LDAP/LDAPS | enumeration, BloodHound |
| 445 | SMB | null sessions, pass-the-hash, relay |
| 5985/5986 | WinRM | evil-winrm lateral movement |
| 3389 | RDP | xfreerdp/rdesktop |
| 1433 | MSSQL | xp_cmdshell, linked servers |

Output: `$OUT/enum/nmap_dc.txt`, `$OUT/enum/live_hosts.txt`

---

## PHASE 2 — Unauthenticated Enumeration

```bash
bash "$SCRIPTS/ad_enum.sh" "$DC_IP" "$DOMAIN" "$OUT" --phase=2
```

**What it runs:**

### Null sessions
- `enum4linux-ng -A` — users, groups, shares, password policy, OS info
- `rpcclient -U "" -N` — `enumdomusers`, `enumdomgroups`, `querydominfo`
- `smbclient -L //<DC_IP> -N` — list shares
- Extract usernames → `$OUT/enum/users_rpcclient.txt`

### LDAP anonymous bind
- `ldapsearch -x -H ldap://$DC_IP -b "" -s base namingContexts`
- Identify base DN, available naming contexts
- Output: `$OUT/enum/ldap_anon.txt`

### Kerbrute user enumeration
- Searches common SecLists userlist paths automatically
- `kerbrute userenum -d $DOMAIN --dc $DC_IP <userlist>`
- Extracts valid usernames → `$OUT/enum/users.txt`
- **Note:** this only checks if users exist — no password attempts

Read JSON summary. Report total users found and password policy (lockout threshold matters for Phase 1 of ad-exploitation).

Output: `$OUT/enum/users.txt` — this file feeds directly into ad-exploitation Phase 1 (AS-REP Roasting).

---

## PHASE 2auth — Authenticated Enumeration

Requires `USERNAME` + `PASSWORD` or `NTLM_HASH`.

```bash
bash "$SCRIPTS/ad_enum.sh" "$DC_IP" "$DOMAIN" "$OUT" "$USERNAME" "$PASSWORD" --phase=2auth
# OR with hash:
bash "$SCRIPTS/ad_enum.sh" "$DC_IP" "$DOMAIN" "$OUT" "$USERNAME" "$NTLM_HASH" --phase=2auth
```

**What it runs:**

### Credential validation
- crackmapexec/netexec: `smb $DC_IP -u $USERNAME -p $PASSWORD`
- Confirms creds are valid before proceeding

### Full LDAP data collection
- `ldapdomaindump` — dumps all users, groups, computers, GPOs, trusts to `$OUT/enum/ldap/`
- Key files: `domain_users.html`, `domain_groups.html`, `domain_computers.html`, `domain_trusts.html`

### BloodHound data collection
- `bloodhound-python -d $DOMAIN -u $USERNAME -p $PASSWORD -dc $DC_IP -c All --zip`
- Output: `$OUT/bloodhound/*.zip` — import into BloodHound GUI for attack path analysis
- If bloodhound-python not available → suggest SharpHound.exe on Windows target

### Attack candidate identification
- `impacket-GetNPUsers` — accounts with `UF_DONT_REQUIRE_PREAUTH` (AS-REP roastable) → `$OUT/hashes/asrep_hashes.txt`
- `impacket-GetUserSPNs` — accounts with SPNs (Kerberoastable) → `$OUT/hashes/kerberoast_hashes.txt`

Read JSON summary. Flag:
- Number of AS-REP roastable accounts (exploitable without knowing any password)
- Number of Kerberoastable SPNs
- BloodHound zip ready for import

---

## PHASE 3 — Report & Attack Surface Summary

Consolidate all output into a structured report:

```
## AD RECON REPORT — [DOMAIN] — [DATE]
## DC: $DC_IP  |  Output: $OUT

### Environment
- Domain FQDN: [domain]
- DC IP: [ip]
- Additional DCs/servers found: [list from nmap sweep]
- Trust relationships: [from ldapdomaindump/enum4linux]

### Attack Surface
- Users enumerated: [count] → $OUT/enum/users.txt
- Password policy: [lockout threshold, min length, duration]
- Accessible shares (null session): [list]
- SMB signing: [enabled/disabled — disabled = relay attack possible]

### Exploitation Candidates (hand off to ad-exploitation)
1. [CRITICAL] AS-REP roastable accounts: [count] — no creds required
2. [HIGH] Kerberoastable SPNs: [count, accounts]
3. [HIGH] BloodHound data collected → import and run: Shortest Path to Domain Admins
4. [MEDIUM] Null session access — password policy retrieved (lockout: [N] attempts)
5. [INFO] Open ports suggesting attack paths: [list]

### Next Step
Load ad-exploitation skill with:
  DC_IP="$DC_IP"
  DOMAIN="$DOMAIN"
  RECON_OUT="$OUT"
  USERNAME="<user if any found/known>"
```

If Notion MCP is available, publish with `mcp__Notion__notion-create-pages`.

---

## Evidence Capture

Save evidence from each recon phase to `$OUT/evidence/`. Essential for documenting the attack surface found.

```bash
mkdir -p "$OUT/evidence"

# Terminal screenshot (macOS)
screencapture -x "$OUT/evidence/recon_$(date +%Y%m%d_%H%M%S)_$DESCRIPTION.png"

# Terminal screenshot (Linux)
scrot "$OUT/evidence/recon_$(date +%Y%m%d_%H%M%S)_$DESCRIPTION.png"
```

**What to capture per phase:**
- **Phase 1 (Host Discovery)**: nmap output with open ports on DC + live host list
- **Phase 2 (Unauth Enum)**: enum4linux-ng output (shares, users, password policy) + rpcclient user list
- **Phase 2auth (Auth Enum)**: ldapdomaindump — open HTML in browser and screenshot `domain_users.html` + `domain_computers.html`; BloodHound — capture "Shortest Paths to Domain Admins" graph before closing the GUI

**BloodHound GUI:**
```
1. Import $OUT/bloodhound/*.zip
2. Click "Shortest Paths to Domain Admins"
3. Right-click the graph → Export → save as $OUT/evidence/bloodhound_path_to_DA.png
```

**Submit to Notion:**
```
mcp__Notion__notion-create-pages  — create AD recon page with attack surface
mcp__Notion__notion-update-page   — attach nmap output, user list, BloodHound screenshot
```

---

## MCP Integration (when available)

### hexstrike-ai / Kali MCP (`mcp__hexstrike-ai__*`)
Use for: `nmap_scan`, `nmap_advanced_scan`, `enum4linux_ng_advanced`, `netexec_scan`,
`rpcclient_enumeration`, `nbtscan_netbios`, `smbmap_scan`.

### Notion (`mcp__Notion__*`)
Publish recon report. Create a subpage for exploitation candidates.

---

## Execution Modes

| Mode | When to use | What runs |
|------|-------------|-----------|
| `--quick` | Fast initial footprint | Phase 1 + Phase 2 (unauthenticated only) |
| `--full` | Full recon | Phases 1 + 2 + 2auth |
| `--unauth` | No credentials — OSINT only | Phases 1 + 2 only |
| `--authenticated` | Already have creds | Phase 2auth only |

---

## Operational Notes

- **Output linkage**: `$OUT/enum/users.txt` and `$OUT/hashes/asrep_hashes.txt` feed directly into ad-exploitation — point `RECON_OUT="$OUT"` when loading that skill
- **BloodHound import**: after collection, open BloodHound GUI → Database Info → Upload Data → select `$OUT/bloodhound/*.zip`
- **Token efficiency**: scripts emit only JSON summaries — do not read full tool output into Claude context
- **Kerberos clock skew**: if impacket errors with `KRB_AP_ERR_SKEW`, run `sudo ntpdate $DC_IP`

