Private/Find-ESC2.ps1

function Find-ESC2 {
    <#
        .SYNOPSIS
        Filters ESC2 issues to those that apply to a specific principal or the current user.
 
        .DESCRIPTION
        Takes ESCalatorIssue objects from Find-ESC2Issue (Any Purpose EKU / no EKU templates
        enrollable by a non-safe principal without manager approval) and further filters to
        issues that apply to the target principal. ESC2 issues are directly exploitable via
        Invoke-EOBOAttack - no combo needed.
 
        .PARAMETER Issues
        Array of ESCalatorIssue objects from Find-ESC2Issue (after Expand-Issue).
 
        .PARAMETER Principal
        Optional DirectoryEntry for a specific principal. Defaults to current user.
 
        .INPUTS
        ESCalatorIssue[]
 
        .OUTPUTS
        PSCustomObject[] grouped by principal with ESC2 issue details.
 
        .EXAMPLE
        $ESC2Issues = Find-ESC2Issue -AdcsObjects $AdcsObjects
        $ExpandedIssues = $ESC2Issues | Expand-Issue
        $ApplicableESC2 = Find-ESC2 -Issues ($ESC2Issues + $ExpandedIssues)
 
        .LINK
        https://posts.specterops.io/certified-pre-owned-d95910965cd2
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory, ValueFromPipeline)]
        [ValidateNotNull()]
        [object[]]$Issues,

        [Parameter()]
        [System.DirectoryServices.DirectoryEntry]$Principal
    )

    begin {
        Write-Verbose "[$(Get-Date -Format 'yyyy-MM-dd hh:mm:ss')] Starting $($MyInvocation.MyCommand) on $env:COMPUTERNAME..."

        $matchedIssues = @()

        if ($Principal) {
            $targetSid = $null
            $targetName = $null
            if ($Principal.Properties['objectSid'].Value) {
                $targetSid = (New-Object System.Security.Principal.SecurityIdentifier($Principal.Properties['objectSid'].Value, 0)).Value
            }
            if ($Principal.Properties['sAMAccountName'].Value) {
                $targetName = $Principal.Properties['sAMAccountName'].Value
            } elseif ($Principal.Properties['name'].Value) {
                $targetName = $Principal.Properties['name'].Value
            }
            Write-Verbose "Analyzing ESC2 issues for principal: $targetName"
        } else {
            $currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent()
            $targetSid = $currentUser.User.Value
            $targetName = $currentUser.Name
            Write-Verbose "Analyzing ESC2 issues for current user: $targetName"
        }
    }

    process {
        foreach ($issue in $Issues) {
            if ($issue.PSObject.TypeNames[0] -ne 'ESCalatorIssue') { continue }
            if ($issue.Technique -ne 'ESC2') { continue }

            # Check if issue applies to target principal
            $applies = $false

            # Check by SID
            if ($targetSid -and $issue.IdentityReferenceSID -eq $targetSid) {
                $applies = $true
            }

            # Check by name
            if (-not $applies -and $targetName -and $issue.IdentityReference) {
                $shortName = $targetName -replace '^.*\\', ''
                if ($issue.IdentityReference -like "*$targetName*" -or $issue.IdentityReference -like "*$shortName*") {
                    $applies = $true
                }
            }

            # Well-known implicit-membership SIDs
            if (-not $applies -and $issue.IdentityReferenceSID -in @('S-1-5-11', 'S-1-1-0')) {
                $applies = $true
            }

            if ($applies) {
                Write-Verbose "ESC2 issue applies: $($issue.Name) - $($issue.IdentityReference)"
                $matchedIssues += $issue
            }
        }
    }

    end {
        Write-Verbose "Found $($matchedIssues.Count) applicable ESC2 issue(s)"

        # Group by principal
        $principalGroups = @{}
        foreach ($issue in $matchedIssues) {
            $key = $issue.IdentityReferenceSID -or $issue.IdentityReference -or "Unknown"
            if (-not $principalGroups[$key]) {
                $principalGroups[$key] = @{
                    PrincipalSID  = $issue.IdentityReferenceSID
                    PrincipalName = $issue.IdentityReference
                    Issues        = @()
                }
            }
            $principalGroups[$key].Issues += $issue
        }

        $results = @()
        foreach ($key in $principalGroups.Keys) {
            $group = $principalGroups[$key]
            $results += [PSCustomObject]@{
                PSTypeName          = 'ESC2_Result'
                PrincipalSID        = $group.PrincipalSID
                PrincipalName       = $group.PrincipalName
                ESC2Count           = $group.Issues.Count
                ESC2Issues          = $group.Issues
                VulnerableTemplates = ($group.Issues | ForEach-Object {
                    if ($_.DirectoryEntry -and $_.DirectoryEntry.Properties['name'].Value) {
                        $_.DirectoryEntry.Properties['name'].Value
                    }
                } | Sort-Object -Unique)
                RiskLevel           = "High"
                Attack              = "Enroll On Behalf Of (ESC2)"
                Technique           = "ESC2"
            }
        }

        return $results
    }
}