Private/Show-ESCAnalysisMenu.ps1
|
function Show-ESCAnalysisMenu { <# .SYNOPSIS Displays ESC vulnerability analysis results in a simple menu format. .DESCRIPTION This function accepts ESCalator issue objects, runs Find-ESC4e1, Find-ESC4p5Combo, and Find-ESC5p5Combo analysis functions, and presents the results in a menu showing attack descriptions. .PARAMETER Issues Mandatory array of one or more ESCalatorIssue objects to analyze. .PARAMETER Principal Optional DirectoryEntry object representing a specific security principal to analyze. If not provided, analyzes for the current user. .INPUTS ESCalatorIssue[] - Array of ESCalatorIssue objects System.DirectoryServices.DirectoryEntry - Optional principal object .OUTPUTS None - Interactive menu display .EXAMPLE Show-ESCAnalysisMenu -Issues $AllIssues Analyzes all issues for the current user and displays results menu. .EXAMPLE Show-ESCAnalysisMenu -Issues $AllIssues -Principal $userPrincipal Analyzes all issues for a specific principal and displays results menu. .NOTES This function provides a simplified interface for ESC vulnerability analysis, focusing on attack descriptions rather than detailed technical information. #> [CmdletBinding()] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [object[]]$Issues, [Parameter()] [System.DirectoryServices.DirectoryEntry]$Principal ) # PowerShell 5.1 has no `e escape; use the ESC character directly for ANSI sequences. $esc = [char]0x1b Write-Verbose "[$(Get-Date -Format 'yyyy-MM-dd hh:mm:ss')] Starting $($MyInvocation.MyCommand) on $env:COMPUTERNAME..." # Initialize result collections $esc4e1Results = @() $esc4p5ComboResults = @() $esc5p5ComboResults = @() try { # Run Find-ESC4e1 Write-Verbose "Running Find-ESC4e1..." if ($Principal) { $esc4e1Results = Find-ESC4e1 -Issues $Issues -Principal $Principal } else { $esc4e1Results = Find-ESC4e1 -Issues $Issues } Write-Verbose "Find-ESC4e1 found $($esc4e1Results.Count) results" # Run Find-ESC4p5Combo Write-Verbose "Running Find-ESC4p5Combo..." if ($Principal) { $esc4p5ComboResults = Find-ESC4p5Combo -Issues $Issues -Principal $Principal } else { $esc4p5ComboResults = Find-ESC4p5Combo -Issues $Issues } Write-Verbose "Find-ESC4p5Combo found $($esc4p5ComboResults.Count) results" # Run Find-ESC5p5Combo Write-Verbose "Running Find-ESC5p5Combo..." if ($Principal) { $esc5p5ComboResults = Find-ESC5p5Combo -Issues $Issues -Principal $Principal } else { $esc5p5ComboResults = Find-ESC5p5Combo -Issues $Issues } Write-Verbose "Find-ESC5p5Combo found $($esc5p5ComboResults.Count) results" } catch { Write-Error "Error occurred during ESC analysis: $($_.Exception.Message)" return } # Calculate totals $totalVulnerabilities = $esc4e1Results.Count + $esc4p5ComboResults.Count + $esc5p5ComboResults.Count # Display analysis header Write-Host "" Write-Host "=== ESC Vulnerability Analysis Results ===" -ForegroundColor Cyan if ($Principal) { $principalName = $null if ($Principal.Properties['sAMAccountName'].Value) { $principalName = $Principal.Properties['sAMAccountName'].Value } elseif ($Principal.Properties['name'].Value) { $principalName = $Principal.Properties['name'].Value } else { $principalName = "Unknown Principal" } Write-Host "Principal: $principalName" -ForegroundColor White } else { $currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent() Write-Host "Principal: $($currentUser.Name) (Current User)" -ForegroundColor White } Write-Host "Analysis Date: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Gray Write-Host "" # Check if any vulnerabilities were found if ($totalVulnerabilities -eq 0) { Write-Host "[+] No ESC vulnerabilities found for this principal!" -ForegroundColor Green Write-Host "" Write-Host "The analyzed principal does not have any of the following vulnerability combinations:" -ForegroundColor Gray Write-Host " - ESC4e1: ESC4 (enabled templates)" -ForegroundColor Gray Write-Host " - ESC4p5: ESC4 (disabled templates) + ESC5 (pKIEnrollmentService certificateTemplates attribute) combinations" -ForegroundColor Gray Write-Host " - ESC5p5: ESC5 (Certificate Templates container) + ESC5 (pKIEnrollmentService certificateTemplates attribute) combinations" -ForegroundColor Gray Write-Host "" Read-Host "Press Enter to continue" return } # Build attack description menu $attackDescriptions = @() if ($esc4e1Results.Count -gt 0) { $attackDescriptions += "ESC4e1: Immediate template modification attack`n - Can modify one or more enabled certificate templates for instant privilege escalation" } if ($esc4p5ComboResults.Count -gt 0) { $attackDescriptions += "ESC4p5: Combined template control attack`n - Can modify one or more disabled certificate templates AND enable disabled templates" } if ($esc5p5ComboResults.Count -gt 0) { $attackDescriptions += "ESC5p5: Full PKI infrastructure control`n - Can create new certificate templates AND enabled disabled templates" } do { # Display attack descriptions Write-Host "Available Attacks:" -ForegroundColor Yellow Write-Host "" for ($i = 0; $i -lt $attackDescriptions.Count; $i++) { $optionNumber = $i + 1 Write-Host "$optionNumber. $($attackDescriptions[$i])" -ForegroundColor White } Write-Host "" Write-Host "q. Quit" -ForegroundColor Red Write-Host "" # Get user choice Write-Host "${esc}[1mSelect an attack to explore${esc}[0m" -NoNewline Write-Host " (1-$($attackDescriptions.Count), q=quit): " -NoNewline $choice = Read-Host $choice = $choice.Trim().ToLower() if ($choice -eq 'q') { Write-Host "" Write-Host "Goodbye!" -ForegroundColor Green return } # Try to parse as integer $numericChoice = 0 if ([int]::TryParse($choice, [ref]$numericChoice)) { if ($numericChoice -ge 1 -and $numericChoice -le $attackDescriptions.Count) { Write-Host "" # Show detailed information based on selection switch ($numericChoice) { 1 { if ($esc4e1Results.Count -gt 0) { Show-ESC4e1AttackDetails -Results $esc4e1Results -Principal $Principal } elseif ($esc4p5ComboResults.Count -gt 0) { Show-ESC4p5AttackDetails -Results $esc4p5ComboResults Invoke-InteractiveAttack -AttackType "ESC4p5" -AttackResult $esc4p5ComboResults[0] -Principal $Principal } elseif ($esc5p5ComboResults.Count -gt 0) { Show-ESC5p5AttackDetails -Results $esc5p5ComboResults Invoke-InteractiveAttack -AttackType "ESC5p5" -AttackResult $esc5p5ComboResults[0] -Principal $Principal } } 2 { if ($esc4p5ComboResults.Count -gt 0) { Show-ESC4p5AttackDetails -Results $esc4p5ComboResults Invoke-InteractiveAttack -AttackType "ESC4p5" -AttackResult $esc4p5ComboResults[0] -Principal $Principal } elseif ($esc5p5ComboResults.Count -gt 0) { Show-ESC5p5AttackDetails -Results $esc5p5ComboResults Invoke-InteractiveAttack -AttackType "ESC5p5" -AttackResult $esc5p5ComboResults[0] -Principal $Principal } } 3 { if ($esc5p5ComboResults.Count -gt 0) { Show-ESC5p5AttackDetails -Results $esc5p5ComboResults Invoke-InteractiveAttack -AttackType "ESC5p5" -AttackResult $esc5p5ComboResults[0] -Principal $Principal } } } Write-Host "" Read-Host "Press Enter to continue" } else { Write-Host "${esc}[38;5;196m[x] Invalid choice. Please enter a number between 1 and $($attackDescriptions.Count) or 'q' to quit.${esc}[0m" -ForegroundColor Red Write-Host "" } } else { Write-Host "${esc}[38;5;196m[x] Invalid input. Please enter a number (1-$($attackDescriptions.Count)) or 'q' to quit.${esc}[0m" -ForegroundColor Red Write-Host "" } } while ($choice -ne 'q') Write-Verbose "[$(Get-Date -Format 'yyyy-MM-dd hh:mm:ss')] Finishing $($MyInvocation.MyCommand) on $env:COMPUTERNAME..." } |