-
Notifications
You must be signed in to change notification settings - Fork 89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ESC11 Detections #177
ESC11 Detections #177
Changes from 6 commits
0f3f5b9
5e20602
7f48fd5
d008524
f184d8a
b43fc3e
cf29817
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
function Find-ESC11 { | ||
<# | ||
.SYNOPSIS | ||
This script finds AD CS (Active Directory Certificate Services) objects that have the ESC11 vulnerability. | ||
|
||
.DESCRIPTION | ||
The script takes an array of ADCS objects as input and filters them based on objects that have the objectClass | ||
'pKIEnrollmentService' and the InterfaceFlag set to 'No'. For each matching object, it creates a custom object with | ||
properties representing various information about the object, such as Forest, Name, DistinguishedName, Technique, | ||
Issue, Fix, and Revert. | ||
|
||
.PARAMETER ADCSObjects | ||
Specifies the array of ADCS objects to be processed. This parameter is mandatory. | ||
|
||
.OUTPUTS | ||
The script outputs an array of custom objects representing the matching ADCS objects and their associated information. | ||
|
||
.EXAMPLE | ||
$ADCSObjects = Get-ADCSObject -Target (Get-Target) | ||
Find-ESC11 -ADCSObjects $ADCSObjects | ||
$Results | ||
#> | ||
[CmdletBinding()] | ||
param( | ||
[Parameter(Mandatory = $true)] | ||
$ADCSObjects | ||
) | ||
process { | ||
$ADCSObjects | Where-Object { | ||
($_.objectClass -eq 'pKIEnrollmentService') -and | ||
($_.InterfaceFlag -ne 'Yes') | ||
} | ForEach-Object { | ||
[string]$CAFullName = "$($_.dNSHostName)\$($_.Name)" | ||
$Issue = [pscustomobject]@{ | ||
Forest = $_.CanonicalName.split('/')[0] | ||
Name = $_.Name | ||
DistinguishedName = $_.DistinguishedName | ||
Technique = 'ESC11' | ||
Issue = $_.AuditFilter | ||
Fix = 'N/A' | ||
Revert = 'N/A' | ||
} | ||
if ($_.InterfaceFlag -eq 'No') { | ||
$Issue.Issue = 'IF_ENFORCEENCRYPTICERTREQUEST is disabled.' | ||
$Issue.Fix = @" | ||
certutil -config $CAFullname -setreg CA\InterfaceFlags +IF_ENFORCEENCRYPTICERTREQUEST | ||
Invoke-Command -ComputerName `"$($_.dNSHostName)`" -ScriptBlock { | ||
Get-Service -Name `'certsvc`' | Restart-Service -Force | ||
} | ||
"@ | ||
$Issue.Revert = @" | ||
certutil -config $CAFullname -setreg CA\InterfaceFlags -IF_ENFORCEENCRYPTICERTREQUEST | ||
Invoke-Command -ComputerName `"$($_.dNSHostName)`" -ScriptBlock { | ||
Get-Service -Name `'certsvc`' | Restart-Service -Force | ||
} | ||
"@ | ||
} | ||
$Issue | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,9 @@ function Invoke-Remediation { | |
.PARAMETER ESC6 | ||
A PS Object containing all necessary information about ESC6 issues. | ||
|
||
.PARAMETER ESC6 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Copy/paste fix needed here for "ESC11." There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. |
||
A PS Object containing all necessary information about ESC11 issues. | ||
|
||
.INPUTS | ||
PS Objects | ||
|
||
|
@@ -42,15 +45,16 @@ function Invoke-Remediation { | |
$ESC3, | ||
$ESC4, | ||
$ESC5, | ||
$ESC6 | ||
$ESC6, | ||
$ESC11 | ||
) | ||
|
||
Write-Host "`nExecuting Mode 4 - Attempting to fix identified issues!`n" -ForegroundColor Green | ||
Write-Host 'Creating a script (' -NoNewline | ||
Write-Host 'Invoke-RevertLocksmith.ps1' -ForegroundColor White -NoNewline | ||
Write-Host ") which can be used to revert all changes made by Locksmith...`n" | ||
try { | ||
Export-RevertScript -AuditingIssues $AuditingIssues -ESC1 $ESC1 -ESC2 $ESC2 -ESC3 $ESC3 -ESC4 $ESC4 -ESC5 $ESC5 -ESC6 $ESC6 | ||
Export-RevertScript -AuditingIssues $AuditingIssues -ESC1 $ESC1 -ESC2 $ESC2 -ESC3 $ESC3 -ESC4 $ESC4 -ESC5 $ESC5 -ESC6 $ESC6 -ESC11 $ESC11 | ||
} catch { | ||
Write-Warning 'Creation of Invoke-RevertLocksmith.ps1 failed.' | ||
Write-Host "Continue with this operation? [Y] Yes " -NoNewline | ||
|
@@ -253,6 +257,39 @@ function Invoke-Remediation { | |
} | ||
} | ||
|
||
if ($ESC11) { | ||
$ESC11 | ForEach-Object { | ||
$FixBlock = [scriptblock]::Create($_.Fix) | ||
Write-Host 'ISSUE:' -ForegroundColor White | ||
Write-Host "The Certification Authority `"$($_.Name)`" has the IF_ENFORCEENCRYPTICERTREQUEST flag disabled.`n" | ||
Write-Host 'TECHNIQUE:' -ForegroundColor White | ||
Write-Host "$($_.Technique)`n" | ||
Write-Host 'ACTION TO BE PERFORMED:' -ForegroundColor White | ||
Write-Host "Locksmith will attempt to enable the IF_ENFORCEENCRYPTICERTREQUEST flag on Certifiction Authority `"$($_.Name)`".`n" | ||
Write-Host 'COMMAND(S) TO BE RUN' -ForegroundColor White | ||
Write-Host 'PS> ' -NoNewline | ||
Write-Host "$($_.Fix)`n" -ForegroundColor Cyan | ||
$WarningError = 'n' | ||
Write-Host 'OPERATIONAL IMPACT:' -ForegroundColor White | ||
Write-Host "WARNING: This change could cause some services to stop working.`n" -ForegroundColor Yellow | ||
Write-Host "If you continue, Locksmith will attempt to fix this issue.`n" -ForegroundColor Yellow | ||
Write-Host "Continue with this operation? [Y] Yes " -NoNewline | ||
Write-Host "[N] " -ForegroundColor Yellow -NoNewline | ||
Write-Host "No: " -NoNewLine | ||
$WarningError = '' | ||
$WarningError = Read-Host | ||
if ($WarningError -like 'y') { | ||
try { | ||
Invoke-Command -ScriptBlock $FixBlock | ||
} catch { | ||
Write-Error 'Could not enable the IF_ENFORCEENCRYPTICERTREQUEST flag. Are you an Active Directory or AD CS admin?' | ||
} | ||
} else { | ||
Write-Host "SKIPPED!`n" -ForegroundColor Yellow | ||
} | ||
} | ||
} | ||
|
||
Write-Host "Mode 4 Complete! There are no more issues that Locksmith can automatically resolve.`n" -ForegroundColor Green | ||
Write-Host 'If you experience any operational impact from using Locksmith Mode 4, use ' -NoNewline | ||
Write-Host 'Invoke-RevertLocksmith.ps1 ' -ForegroundColor White | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,16 +13,17 @@ function Invoke-Scans { | |
- ESC5 | ||
- ESC6 | ||
- ESC8 | ||
- ESC11 | ||
- All | ||
- PromptMe | ||
|
||
.PARAMETER Scans | ||
Specifies the type of scans to perform. Multiple scan options can be provided as an array. The default value is 'All'. | ||
The available scan options are: 'Auditing', 'ESC1', 'ESC2', 'ESC3', 'ESC4', 'ESC5', 'ESC6', 'ESC8', 'All', 'PromptMe'. | ||
The available scan options are: 'Auditing', 'ESC1', 'ESC2', 'ESC3', 'ESC4', 'ESC5', 'ESC6', 'ESC8', 'ESC11', 'All', 'PromptMe'. | ||
|
||
.NOTES | ||
- The script requires the following functions to be defined: Find-AuditingIssue, Find-ESC1, Find-ESC2, Find-ESC3Condition1, | ||
Find-ESC3Condition2, Find-ESC4, Find-ESC5, Find-ESC6, Find-ESC8. | ||
Find-ESC3Condition2, Find-ESC4, Find-ESC5, Find-ESC6, Find-ESC8, Find-ESC8. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Copy/paste fix for "Find-ESC11" needed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. |
||
- The script uses Out-GridView or Out-ConsoleGridView for interactive selection when the 'PromptMe' scan option is chosen. | ||
- The script returns a hash table containing the results of the scans. | ||
|
||
|
@@ -41,17 +42,17 @@ function Invoke-Scans { | |
|
||
[CmdletBinding()] | ||
[OutputType([hashtable])] | ||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', 'Invoke-Scans', Justification='Performing multiple scans.')] | ||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', 'Invoke-Scans', Justification = 'Performing multiple scans.')] | ||
param ( | ||
# Could split Scans and PromptMe into separate parameter sets. | ||
[Parameter()] | ||
# Could split Scans and PromptMe into separate parameter sets. | ||
[Parameter()] | ||
$ClientAuthEkus, | ||
$DangerousRights, | ||
$EnrollmentAgentEKU, | ||
[int]$Mode, | ||
$SafeObjectTypes, | ||
$SafeOwners, | ||
[ValidateSet('Auditing','ESC1','ESC2','ESC3','ESC4','ESC5','ESC6','ESC8','All','PromptMe')] | ||
[ValidateSet('Auditing', 'ESC1', 'ESC2', 'ESC3', 'ESC4', 'ESC5', 'ESC6', 'ESC8', 'ESC11', 'All', 'PromptMe')] | ||
[array]$Scans = 'All', | ||
$UnsafeOwners, | ||
$UnsafeUsers, | ||
|
@@ -68,12 +69,10 @@ function Invoke-Scans { | |
|
||
# Check for Out-GridView or Out-ConsoleGridView | ||
if ((Get-Command Out-ConsoleGridView -ErrorAction SilentlyContinue) -and ($PSVersionTable.PSVersion.Major -ge 7)) { | ||
[array]$Scans = ($Dictionary | Select-Object Name,Category,Subcategory | Out-ConsoleGridView -OutputMode Multiple -Title $GridViewTitle).Name | Sort-Object -Property Name | ||
} | ||
elseif (Get-Command -Name Out-GridView -ErrorAction SilentlyContinue) { | ||
[array]$Scans = ($Dictionary | Select-Object Name,Category,Subcategory | Out-GridView -PassThru -Title $GridViewTitle).Name | Sort-Object -Property Name | ||
} | ||
else { | ||
[array]$Scans = ($Dictionary | Select-Object Name, Category, Subcategory | Out-ConsoleGridView -OutputMode Multiple -Title $GridViewTitle).Name | Sort-Object -Property Name | ||
} elseif (Get-Command -Name Out-GridView -ErrorAction SilentlyContinue) { | ||
[array]$Scans = ($Dictionary | Select-Object Name, Category, Subcategory | Out-GridView -PassThru -Title $GridViewTitle).Name | Sort-Object -Property Name | ||
} else { | ||
# To Do: Check for admin and prompt to install features/modules or revert to 'All'. | ||
Write-Information "Out-GridView and Out-ConsoleGridView were not found on your system. Defaulting to `'All`'." | ||
$Scans = 'All' | ||
|
@@ -99,21 +98,25 @@ function Invoke-Scans { | |
[array]$ESC3 += Find-ESC3Condition2 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers | ||
} | ||
ESC4 { | ||
Write-Host 'Identifying AD CS template and other objects with poor access control (ESC4)...' | ||
Write-Host 'Identifying AD CS templates with poor access control (ESC4)...' | ||
[array]$ESC4 = Find-ESC4 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -DangerousRights $DangerousRights -SafeOwners $SafeOwners -SafeObjectTypes $SafeObjectTypes | ||
} | ||
ESC5 { | ||
Write-Host 'Identifying AD CS template and other objects with poor access control (ESC5)...' | ||
Write-Host 'Identifying AD CS objects with poor access control (ESC5)...' | ||
[array]$ESC5 = Find-ESC5 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -DangerousRights $DangerousRights -SafeOwners $SafeOwners -SafeObjectTypes $SafeObjectTypes | ||
} | ||
ESC6 { | ||
Write-Host 'Identifying AD CS template and other objects with poor access control (ESC6)...' | ||
Write-Host 'Identifying Issuing CAs with EDITF_ATTRIBUTESUBJECTALTNAME2 enabled (ESC6)...' | ||
[array]$ESC6 = Find-ESC6 -ADCSObjects $ADCSObjects | ||
} | ||
ESC8 { | ||
Write-Host 'Identifying HTTP-based certificate enrollment interfaces (ESC8)...' | ||
[array]$ESC8 = Find-ESC8 -ADCSObjects $ADCSObjects | ||
} | ||
ESC6 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Copy/paste fix "ESC6" to "ESC11" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed! |
||
Write-Host 'Identifying Issuing CAs with IF_ENFORCEENCRYPTICERTREQUEST disabled (ESC11)...' | ||
[array]$ESC6 = Find-ESC6 -ADCSObjects $ADCSObjects | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Copy/paste fix "ESC6" to "ESC11" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed! |
||
} | ||
All { | ||
Write-Host 'Identifying auditing issues...' | ||
[array]$AuditingIssues = Find-AuditingIssue -ADCSObjects $ADCSObjects | ||
|
@@ -124,35 +127,39 @@ function Invoke-Scans { | |
Write-Host 'Identifying AD CS templates with dangerous ESC3 configurations...' | ||
[array]$ESC3 = Find-ESC3Condition1 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers | ||
[array]$ESC3 += Find-ESC3Condition2 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers | ||
Write-Host 'Identifying AD CS template and other objects with poor access control (ESC4)...' | ||
Write-Host 'Identifying AD CS templates with poor access control (ESC4)...' | ||
[array]$ESC4 = Find-ESC4 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -DangerousRights $DangerousRights -SafeOwners $SafeOwners -SafeObjectTypes $SafeObjectTypes -Mode $Mode | ||
Write-Host 'Identifying AD CS template and other objects with poor access control (ESC5)...' | ||
Write-Host 'Identifying AD CS objects with poor access control (ESC5)...' | ||
[array]$ESC5 = Find-ESC5 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -DangerousRights $DangerousRights -SafeOwners $SafeOwners -SafeObjectTypes $SafeObjectTypes | ||
Write-Host 'Identifying Certificate Authorities configured with dangerous flags (ESC6)...' | ||
Write-Host 'Identifying Certificate Authorities with EDITF_ATTRIBUTESUBJECTALTNAME2 enabled v (ESC6)...' | ||
[array]$ESC6 = Find-ESC6 -ADCSObjects $ADCSObjects | ||
Write-Host 'Identifying HTTP-based certificate enrollment interfaces (ESC8)...' | ||
[array]$ESC8 = Find-ESC8 -ADCSObjects $ADCSObjects | ||
Write-Host 'Identifying Certificate Authorities with IF_ENFORCEENCRYPTICERTREQUEST disabled (ESC11)...' | ||
[array]$ESC11 = Find-ESC11 -ADCSObjects $ADCSObjects | ||
Write-Host | ||
} | ||
} | ||
|
||
[array]$AllIssues = $AuditingIssues + $ESC1 + $ESC2 + $ESC3 + $ESC4 + $ESC5 + $ESC6 + $ESC8 | ||
[array]$AllIssues = $AuditingIssues + $ESC1 + $ESC2 + $ESC3 + $ESC4 + $ESC5 + $ESC6 + $ESC8 + $ESC11 | ||
|
||
# If these are all empty = no issues found, exit | ||
if ((!$AuditingIssues) -and (!$ESC1) -and (!$ESC2) -and (!$ESC3) -and (!$ESC4) -and (!$ESC5) -and (!$ESC6) -and (!$ESC8) ) { | ||
if ((!$AuditingIssues) -and (!$ESC1) -and (!$ESC2) -and (!$ESC3) -and (!$ESC4) -and (!$ESC5) -and (!$ESC6) -and (!$ESC8) -and ($ESC11) ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. new segment should be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed! |
||
Write-Host "`n$(Get-Date) : No ADCS issues were found." -ForegroundColor Green | ||
break | ||
} | ||
|
||
# Return a hash table of array names (keys) and arrays (values) so they can be directly referenced with other functions | ||
Return @{ | ||
AllIssues = $AllIssues | ||
AllIssues = $AllIssues | ||
AuditingIssues = $AuditingIssues | ||
ESC1 = $ESC1 | ||
ESC2 = $ESC2 | ||
ESC3 = $ESC3 | ||
ESC4 = $ESC4 | ||
ESC5 = $ESC5 | ||
ESC6 = $ESC6 | ||
ESC8 = $ESC8 | ||
ESC1 = $ESC1 | ||
ESC2 = $ESC2 | ||
ESC3 = $ESC3 | ||
ESC4 = $ESC4 | ||
ESC5 = $ESC5 | ||
ESC6 = $ESC6 | ||
ESC8 = $ESC8 | ||
ESC11 = $ESC11 | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -125,15 +125,15 @@ function New-Dictionary { | |
# FixIt = {Write-Output 'Add code to fix the vulnerable configuration.'} | ||
# ReferenceUrls = '' | ||
# }, | ||
# [VulnerableConfigurationItem]@{ | ||
# Name = 'ESC11' | ||
# Category = 'Escalation Path' | ||
# Subcategory = '' | ||
# Summary = '' | ||
# FindIt = {Find-ESC11} | ||
# FixIt = {Write-Output 'Add code to fix the vulnerable configuration.'} | ||
# ReferenceUrls = '' | ||
# }, | ||
[VulnerableConfigurationItem]@{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changes to the dictionary should include a bump in the dictionary version attribute on line 24, which is currently: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed! |
||
Name = 'ESC11' | ||
Category = 'Escalation Path' | ||
Subcategory = 'IF_ENFORCEENCRYPTICERTREQUEST' | ||
Summary = '' | ||
FindIt = {Find-ESC11} | ||
FixIt = {Write-Output 'Add code to fix the vulnerable configuration.'} | ||
ReferenceUrls = 'https://blog.compass-security.com/2022/11/relaying-to-ad-certificate-services-over-rpc/' | ||
}, | ||
[VulnerableConfigurationItem]@{ | ||
Name = 'Auditing' | ||
Category = 'Server Configuration' | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just double checking because I haven't run and tested results yet: is
$_.AuditFilter
right? What should that return?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch. I also updated the ESC6 logic which does the same check!