Private/Set/Set-AuthenticationEKUExist.ps1
|
function Set-AuthenticationEKUExist { <# .SYNOPSIS Adds an AuthenticationEKUExist property to AD CS certificate template objects. .DESCRIPTION Examines the pKIExtendedKeyUsage attribute of Active Directory Certificate Services certificate template objects to determine if they can be used for authentication purposes. The function checks for the presence of authentication-related Extended Key Usage (EKU) OIDs: - 1.3.6.1.5.5.7.3.2: Client Authentication - 1.3.6.1.5.2.3.4: PKINIT Client Authentication (Kerberos) - 1.3.6.1.4.1.311.20.2.2: Smart Card Logon This is a critical check for ESC1 vulnerability detection in AD CS auditing, as templates that allow authentication combined with other risky settings can lead to privilege escalation. The function adds a boolean AuthenticationEKUExist property to each input object indicating whether the template can be used for authentication. .PARAMETER AdcsObject One or more DirectoryEntry objects representing AD CS certificate templates. These objects may contain the pKIExtendedKeyUsage attribute. .PARAMETER AuthenticationEKU An array of EKU OIDs that are considered authentication-related. Default includes Client Authentication, PKINIT Client Authentication, and Smart Card Logon. .INPUTS System.DirectoryServices.DirectoryEntry[] You can pipe certificate template DirectoryEntry objects to this function. .OUTPUTS System.DirectoryServices.DirectoryEntry[] Returns the input objects with an added AuthenticationEKUExist boolean property. .EXAMPLE $templates = Get-AdcsObject -RootDSE $rootDSE | Where-Object { $_.objectClass -contains 'pKICertificateTemplate' } $templates | Set-AuthenticationEKUExist Processes all certificate templates and adds the AuthenticationEKUExist property to each. .EXAMPLE Get-AdcsObject -RootDSE $rootDSE | Set-AuthenticationEKUExist | Where-Object AuthenticationEKUExist Retrieves all AD CS objects, adds AuthenticationEKUExist property, and filters to only authentication templates. .EXAMPLE $template = Get-AdcsObject -RootDSE $rootDSE | Where-Object Name -eq 'WebServer' $template | Set-AuthenticationEKUExist if ($template.AuthenticationEKUExist) { Write-Host "Template can be used for authentication" } Checks a specific template for authentication capability. .EXAMPLE $customEKUs = @('1.3.6.1.5.5.7.3.2', '1.3.6.1.4.1.311.20.2.2') Get-AdcsObject -RootDSE $rootDSE | Set-AuthenticationEKUExist -AuthenticationEKU $customEKUs Uses a custom list of authentication EKUs to check templates. .LINK https://posts.specterops.io/certified-pre-owned-d95910965cd2 .LINK https://learn.microsoft.com/en-us/windows/win32/seccrypto/extended-key-usage #> [CmdletBinding()] [OutputType([System.DirectoryServices.DirectoryEntry[]])] param ( [Parameter(Mandatory, ValueFromPipeline)] [System.DirectoryServices.DirectoryEntry[]]$AdcsObject, [Parameter()] [string[]]$AuthenticationEKU = @( '1.3.6.1.5.5.7.3.2', # Client Authentication '1.3.6.1.5.2.3.4', # PKINIT Client Authentication '1.3.6.1.4.1.311.20.2.2' # Smart Card Logon ) ) #requires -Version 5.1 begin { Write-Verbose "Identifying templates that create authentication certificates..." } process { $AdcsObject | Where-Object SchemaClassName -eq pKICertificateTemplate | ForEach-Object { try { $objectName = if ($_.Properties.displayName.Count -gt 0) { $_.Properties.displayName[0] } elseif ($_.Properties.name.Count -gt 0) { $_.Properties.name[0] } else { $_.Properties.distinguishedName[0] } Write-Verbose "Processing template: $objectName" $authenticationEKUExist = $false # Check if pKIExtendedKeyUsage attribute exists and has values if ($_.Properties.pKIExtendedKeyUsage.Count -gt 0) { $ekuList = $_.Properties.pKIExtendedKeyUsage Write-Verbose "pKIExtendedKeyUsage contains $($ekuList.Count) EKU(s): $($ekuList -join ', ')" # Check if any of the Authentication EKUs are present foreach ($eku in $ekuList) { if ($eku -in $AuthenticationEKU) { $authenticationEKUExist = $true Write-Verbose "Authentication EKU found: $eku" break # No need to check remaining EKUs } } if (-not $authenticationEKUExist) { Write-Verbose "No authentication EKUs found in template" } } else { Write-Verbose "pKIExtendedKeyUsage is empty. Template can be used for Any Purpose." } # Update the AdcsObjectStore with the AuthenticationEKUExist property $dn = $_.Properties.distinguishedName[0] if ($script:AdcsObjectStore.ContainsKey($dn)) { $script:AdcsObjectStore[$dn] | Add-Member -NotePropertyName AuthenticationEKUExist -NotePropertyValue $authenticationEKUExist -Force Write-Verbose "Updated AD CS Object Store for $dn with AuthenticationEKUExist = $authenticationEKUExist" } # Also add to the pipeline object for backward compatibility $_ | Add-Member -NotePropertyName AuthenticationEKUExist -NotePropertyValue $authenticationEKUExist -Force # Return the modified object $_ } catch { $errorRecord = [System.Management.Automation.ErrorRecord]::new( $_.Exception, 'AuthenticationEKUProcessingFailed', [System.Management.Automation.ErrorCategory]::InvalidOperation, $_ ) $PSCmdlet.WriteError($errorRecord) # Still return the object even if processing failed $_ } } } end { Write-Verbose "Done identifying templates that create authentication certificates." } } |