Analyzers/Test-Esc2.ps1

function Test-Esc2 {
    <#
    .SYNOPSIS
        ESC2 - Any-Purpose EKU or no-EKU (SubCA-like) template open to low-priv enrollment.
    .DESCRIPTION
        Flags templates whose EKU set is Any-Purpose (2.5.29.37.0) OR completely
        empty (no EKU + no application policy, i.e. a subordinate-CA-style "use for
        anything" certificate), that a low-privileged principal can enroll in
        without manager approval or enrollment-agent signatures. Such a certificate
        can be repurposed for authentication (and more), similar to ESC1 but without
        needing enrollee-supplied SAN.

        Vulnerable (per template) =
          (EKU/AppPolicy contains 2.5.29.37.0 OR both EKU and AppPolicy empty)
          AND a low-priv principal holds Enroll/AutoEnroll
          AND ManagerApprovalRequired == $false
          AND RaSignaturesRequired -lt 1
          AND published on at least one CA.
    .PARAMETER Context
        AssessmentContext pscustomobject. Reads $Context.Templates.
    .PARAMETER ExtraLowPrivSid
        Extra SID strings to treat as low-privileged.
    .OUTPUTS
        Finding[]
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [pscustomobject] $Context,

        [Parameter(Mandatory = $false)]
        [string[]] $ExtraLowPrivSid = @()
    )

    $reference = 'SpecterOps "Certified Pre-Owned" (ESC2) / Certipy'
    $findings = @()

    $newFinding = {
        param($Title, $Severity, $Status, $Affected, $Evidence, $Principals, $Exploit, $Remediation)
        [pscustomobject]@{
            Id             = 'ESC2'
            Title          = $Title
            Severity       = $Severity
            Status         = $Status
            AffectedObject = $Affected
            Evidence       = $Evidence
            Principals     = @($Principals)
            Exploitability = $Exploit
            RiskScore      = 0
            Remediation    = $Remediation
            Reference      = $reference
        }
    }

    $templates = @()
    if ($null -ne $Context -and $null -ne $Context.Templates) { $templates = @($Context.Templates) }

    if ($templates.Count -eq 0) {
        return @(& $newFinding 'ESC2 - no certificate templates available' 'High' 'ManualReview' 'N/A' `
            ([pscustomobject]@{ Error = 'Context.Templates is empty or unavailable; could not evaluate ESC2.' }) `
            @() 'Theoretical' 'Collect certificate templates and re-run the assessment.')
    }

    foreach ($tpl in $templates) {
        $eku = @($tpl.EkuList)
        $appPol = @($tpl.ApplicationPolicies)
        $hasAnyPurpose = (($eku -contains '2.5.29.37.0') -or ($appPol -contains '2.5.29.37.0'))
        $noEku = (($eku.Count -eq 0) -and ($appPol.Count -eq 0))
        if (-not ($hasAnyPurpose -or $noEku)) { continue }

        if ($tpl.ManagerApprovalRequired) { continue }
        if ([int]$tpl.RaSignaturesRequired -ge 1) { continue }

        $lowPrivEnrollers = @($tpl.EnrollPrincipals | Where-Object {
            $_.AceType -eq 'Allow' -and $_.IsLowPriv -and (
                ($_.Rights -contains 'Enroll') -or ($_.Rights -contains 'GenericAll')
            )
        })
        if ($lowPrivEnrollers.Count -eq 0) { continue }

        $published = @($tpl.PublishedOnCAs)
        if ($published.Count -eq 0) { continue }

        $principalNames = @($lowPrivEnrollers | ForEach-Object {
            if ($_.PrincipalName) { $_.PrincipalName } else { $_.PrincipalSid }
        } | Select-Object -Unique)

        if ($hasAnyPurpose) { $kind = 'Any-Purpose EKU (2.5.29.37.0)' } else { $kind = 'No EKU / SubCA-like (empty EKU + Application Policy)' }

        $evidence = [pscustomobject]@{
            EkuKind                 = $kind
            EkuList                 = $eku
            ApplicationPolicies     = $appPol
            ManagerApprovalRequired = $false
            RaSignaturesRequired    = [int]$tpl.RaSignaturesRequired
            PublishedOnCAs          = $published
            LowPrivEnrollRights     = @($lowPrivEnrollers | ForEach-Object { '{0}:{1}' -f $_.PrincipalName, ($_.Rights -join '|') })
        }

        $findings += & $newFinding `
            ("ESC2 - template '{0}' is Any-Purpose/No-EKU and open to low-priv enrollment" -f $tpl.Name) `
            'High' 'Vulnerable' $tpl.Name $evidence $principalNames 'High' `
            'Constrain the template EKU to only the required purpose, require manager approval, and restrict enrollment to trusted principals.'
    }

    if ($findings.Count -eq 0) {
        return @(& $newFinding 'ESC2 - no Any-Purpose/No-EKU templates open to low-priv enrollment' 'High' 'NotVulnerable' 'N/A' `
            ([pscustomobject]@{ TemplatesEvaluated = $templates.Count }) @() 'Theoretical' 'No action required for ESC2.')
    }

    return $findings
}