ADCS-014: ESC13 - Issuance Policy OID Group Link

Platform
Active Directory
Category
AD Certificate Services
Severity
High
Zero Trust pillar
Identity (weight 2)
Golden fixtures
3
Branch coverage
Observed: fixtures prove the verdicts they exercise
Provenance
baseline

What it checks

Guerrilla enumerates the OID container at CN=OID,CN=Public Key Services,CN=Services,CN=Configuration,DC=<forest-root> and inspects every msPKI-Enterprise-Oid object for a populated msDS-OIDToGroupLink attribute. For each linked group, the check resolves the target SID, reads the group scope (groupType bit 0x00000008 indicates universal), and tests group membership against the tier zero principal set (Domain Admins RID 512, Enterprise Admins RID 519, Schema Admins RID 518, the BUILTIN Administrators group, the Domain Controllers OU computer accounts, any group flagged adminCount=1, and any group nested into one of the foregoing). The check then locates every certificate template (pKICertificateTemplate object) whose msPKI-Certificate-Policy attribute references the linked OID, reads the template enrollment ACL (msPKI-Certificate-Application-Policy, certificate-enrollment and certificate-autoenrollment extended rights), and reports the cartesian product of (enrollable principal) x (linked group) for every linked OID that maps to a sensitive group.

Why it matters

The OID-to-group link feature was introduced for authorization scenarios where a smartcard policy needed to grant elevated rights without standing group membership, but in practice it is rarely used safely. When an OID is linked to a privileged universal group, the link acts as a hidden delegation that bypasses every control that monitors group membership: there is no member added, no AdminSDHolder propagation, no replication of group changes for an auditor to see. The enrollee obtains a Kerberos TGT whose PAC asserts membership in the linked group, which means resources that authorize on group SID (file shares, SQL roles, RBAC checks in custom apps, even Domain Admins ACEs on DCs) treat the certificate holder as a member. Because the certificate is portable and persists across user password resets, the link is also a high quality persistence primitive. Real world exploitation has been observed by SpecterOps, Mandiant, and red teams since the 2024 publication of the technique, and the misconfiguration is easy for an unaware administrator to create because the link is set on the OID rather than the template, hiding it from template-centric audits.

Attack path

1. Attacker establishes a foothold as any low-privileged domain user. 2. Attacker enumerates certificate templates and OID linkages with certipy: certipy find -u user@corp.local -p Pass -dc-ip 10.0.0.10 -text -enabled. The output lists every template, its issuance policies, and any OIDs whose msDS-OIDToGroupLink attribute references a group. 3. Attacker identifies a template flagged [+] ESC13: enrollee can act as a member of <Group>. The template must be enabled, must offer Client Authentication EKU (or a superset such as Any Purpose), must reference an issuance policy whose OID has a non-empty msDS-OIDToGroupLink, and the linked group must be a universal group that is currently empty (universal groups cannot have populated membership when used as OID-link targets). 4. Attacker enrolls in the template: certipy req -u user@corp.local -p Pass -ca CORP-CA -template ESC13Template. The CA issues a certificate whose Application Policies extension contains the linked issuance policy OID. 5. Attacker performs PKINIT against the KDC: certipy auth -pfx user.pfx. The KDC consults the OID-to-group link, resolves the linked group SID, and writes that SID into the PAC of the issued TGT under ExtraSids or directly into Groups. 6. Attacker uses the TGT against any service that authorizes on the linked group SID. If the linked group is Domain Admins or any group with DCSync, the attacker performs secretsdump and dumps the domain. The certificate remains valid until expiry or revocation, so the attacker retains the privilege even if the original user account is disabled, password reset, or removed from every group.

How Guerrilla assesses it

Guerrilla performs an LDAP search with base CN=OID,CN=Public Key Services,CN=Services,CN=Configuration,DC=<forest-root>, scope subtree, filter (&(objectClass=msPKI-Enterprise-Oid)(msDS-OIDToGroupLink=*)), attributes msPKI-Cert-Template-OID, displayName, msDS-OIDToGroupLink, flags. For each hit the linked DN is resolved and the target object is read for objectSid, groupType, adminCount, and recursive membership. Templates that reference the OID are found by searching CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=<forest-root> with filter (&(objectClass=pKICertificateTemplate)(msPKI-Certificate-Policy=<oid>)). Enrollment principals are read from nTSecurityDescriptor on each template and filtered to ACEs granting the Certificate-Enrollment (0e10c968-78fb-11d2-90d4-00c04f79dc55) or Certificate-AutoEnrollment (a05b8cc2-17bc-4802-a710-e7c15ab866a2) extended rights. The check emits one finding per (template, linked group, enrollment principal) triple, with severity escalated to Critical when the linked group is tier zero. Optional event-based detection reads Security event 4886 and 4887 from CA servers for certificates issued with the linked policy OID present in the Application Policies extension.

Recommended value

No issuance policy OIDs linked to privileged security groups; msDS-OIDToGroupLink only on non-sensitive groups

Remediation

Query all OID objects in CN=OID,CN=Public Key Services,CN=Services,CN=Configuration for the msDS-OIDToGroupLink attribute. Identify any OIDs linked to privileged groups (Domain Admins, Enterprise Admins, etc.). Remove the msDS-OIDToGroupLink attribute from OIDs linked to sensitive groups. If the linkage is operationally required, restrict enrollment on templates using the issuance policy to authorized principals only.

Fixture-proven verdicts

Every verdict below is proven by a golden fixture in the module's gating test suite. This table derives from the last green run; it cannot be edited by hand.

Verdict scenarios for ADCS-014
ScenarioExpected verdict
cleanPASS
known-badFAIL
throttledNot Assessed

Framework mappings

NIST SP 800-53
AC-6, IA-5(2), CM-6
ANSSI
vuln_adcs_esc13
MITRE ATT&CK
T1649, T1098