Skip to content

Commit dfd495c

Browse files
authored
Merge pull request #179 from TrimarcJake/testing
Accelerated Release Schedule in Preparation for Antisyphon Training
2 parents 9035e90 + dfc0db3 commit dfd495c

26 files changed

+1605
-427
lines changed

Build/Build-Module.ps1

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
param (
2-
# A CalVer string if you need to manually override the default yyyy.M version string.
2+
# A CalVer string if you need to manually override the default yyyy.M.d version string.
33
[string]$CalVer
44
)
55

@@ -22,7 +22,7 @@ Import-Module -Name PSPublishModule -Force
2222
Build-Module -ModuleName 'Locksmith' {
2323
# Usual defaults as per standard module
2424
$Manifest = [ordered] @{
25-
ModuleVersion = if ($Calver) {$CalVer} else {(Get-Date -Format yyyy.M)}
25+
ModuleVersion = if ($Calver) {$CalVer} else {(Get-Date -Format yyyy.M.d)}
2626
CompatiblePSEditions = @('Desktop', 'Core')
2727
GUID = 'b1325b42-8dc4-4f17-aa1f-dcb5984ca14a'
2828
Author = 'Jake Hildreth'

Invoke-Locksmith.ps1

+720-133
Large diffs are not rendered by default.

Locksmith.psd1

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
Description = 'A small tool to find and fix common misconfigurations in Active Directory Certificate Services.'
88
FunctionsToExport = @('*')
99
GUID = 'b1325b42-8dc4-4f17-aa1f-dcb5984ca14a'
10-
ModuleVersion = '2024.10'
10+
ModuleVersion = '2024.11.10'
1111
PowerShellVersion = '5.1'
1212
PrivateData = @{
1313
PSData = @{

Private/ConvertFrom-IdentityReference.ps1

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function ConvertFrom-IdentityReference {
2222
#>
2323
[CmdletBinding()]
2424
param(
25-
[Parameter(Mandatory = $true)]
25+
[Parameter(Mandatory)]
2626
[array]$Object
2727
)
2828

Private/Export-RevertScript.ps1

+26-6
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,25 @@
3030
.PARAMETER ESC6
3131
An array of ESC6 changes to be reverted.
3232
33+
.PARAMETER ESC11
34+
An array of ESC11 changes to be reverted.
35+
36+
.PARAMETER ESC13
37+
An array of ESC13 changes to be reverted.
38+
3339
.EXAMPLE
34-
Export-RevertScript -AuditingIssues $auditingIssues -ESC1 $ESC1 -ESC2 $ESC2 -ESC3 $ESC3 -ESC4 $ESC4 -ESC5 $ESC5 -ESC6 $ESC6
40+
$params = @{
41+
AuditingIssues = $AuditingIssues
42+
ESC1 = $ESC1
43+
ESC2 = $ESC2
44+
ESC3 = $ESC3
45+
ESC4 = $ESC4
46+
ESC5 = $ESC5
47+
ESC6 = $ESC6
48+
ESC11 = $ESC11
49+
ESC13 = $ESC13
50+
}
51+
Export-RevertScript @params
3552
Reverts the changes performed by Locksmith using the specified arrays of objects.
3653
#>
3754

@@ -43,19 +60,22 @@
4360
[array]$ESC3,
4461
[array]$ESC4,
4562
[array]$ESC5,
46-
[array]$ESC6
63+
[array]$ESC6,
64+
[array]$ESC11,
65+
[array]$ESC13
4766
)
4867
begin {
4968
$Output = 'Invoke-RevertLocksmith.ps1'
50-
Set-Content -Path $Output -Value "<#`nScript to revert changes performed by Locksmith`nCreated $(Get-Date)`n#>" -Force
51-
$Objects = $AuditingIssues + $ESC1 + $ESC2 + $ESC3 + $ESC4 + $ESC5 + $ESC6
69+
$RevertScript = [System.Text.StringBuilder]::New()
70+
[void]$RevertScript.Append("<#`nScript to revert changes performed by Locksmith`nCreated $(Get-Date)`n#>`n")
71+
$Objects = $AuditingIssues + $ESC1 + $ESC2 + $ESC3 + $ESC4 + $ESC5 + $ESC6 + $ESC11 + $ESC13
5272
}
5373
process {
5474
if ($Objects) {
5575
$Objects | ForEach-Object {
56-
Add-Content -Path $Output -Value $_.Revert
57-
Start-Sleep -Seconds 5
76+
[void]$RevertScript.Append("$($_.Revert)`n")
5877
}
78+
$RevertScript.ToString() | Out-File -FilePath $Output
5979
}
6080
}
6181
}

Private/Find-AuditingIssue.ps1

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
[CmdletBinding()]
3434
param(
35-
[Parameter(Mandatory = $true)]
35+
[Parameter(Mandatory)]
3636
[array]$ADCSObjects
3737
)
3838

@@ -45,7 +45,7 @@
4545
Name = $_.Name
4646
DistinguishedName = $_.DistinguishedName
4747
Technique = 'DETECT'
48-
Issue = "Auditing is not fully enabled on $($_.CAFullName). Current value is $($_.AuditFilter)"
48+
Issue = "Auditing is not fully enabled on $($_.CAFullName). Important security events may go unnoticed."
4949
Fix = @"
5050
certutil.exe -config `'$($_.CAFullname)`' -setreg `'CA\AuditFilter`' 127
5151
Invoke-Command -ComputerName `'$($_.dNSHostName)`' -ScriptBlock {

Private/Find-ESC1.ps1

+29-11
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,27 @@
1414
.PARAMETER SafeUsers
1515
Specifies the list of SIDs of safe users who are allowed to have specific rights on the objects. This parameter is mandatory.
1616
17+
.PARAMETER ClientAuthEKUs
18+
A list of EKUs that can be used for client authentication.
19+
1720
.OUTPUTS
1821
The script outputs an array of custom objects representing the matching ADCS objects and their associated information.
1922
2023
.EXAMPLE
2124
$ADCSObjects = Get-ADCSObjects
2225
$SafeUsers = '-512$|-519$|-544$|-18$|-517$|-500$|-516$|-9$|-526$|-527$|S-1-5-10'
23-
$Results = $ADCSObjects | Find-ESC1 -SafeUsers $SafeUsers
26+
$ClientAuthEKUs = '1\.3\.6\.1\.5\.5\.7\.3\.2|1\.3\.6\.1\.5\.2\.3\.4|1\.3\.6\.1\.4\.1\.311\.20\.2\.2|2\.5\.29\.37\.0'
27+
$Results = $ADCSObjects | Find-ESC1 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -ClientAuthEKUs $ClientAuthEKUs
2428
$Results
2529
#>
2630
[CmdletBinding()]
2731
param(
28-
[Parameter(Mandatory = $true)]
32+
[Parameter(Mandatory)]
2933
[array]$ADCSObjects,
30-
[Parameter(Mandatory = $true)]
31-
[array]$SafeUsers
34+
[Parameter(Mandatory)]
35+
[array]$SafeUsers,
36+
[Parameter(Mandatory)]
37+
$ClientAuthEKUs
3238
)
3339
$ADCSObjects | Where-Object {
3440
($_.objectClass -eq 'pKICertificateTemplate') -and
@@ -37,30 +43,42 @@
3743
!($_.'msPKI-Enrollment-Flag' -band 2) -and
3844
( ($_.'msPKI-RA-Signature' -eq 0) -or ($null -eq $_.'msPKI-RA-Signature') )
3945
} | ForEach-Object {
46+
# Write-Host $_; continue
4047
foreach ($entry in $_.nTSecurityDescriptor.Access) {
4148
$Principal = New-Object System.Security.Principal.NTAccount($entry.IdentityReference)
4249
if ($Principal -match '^(S-1|O:)') {
4350
$SID = $Principal
4451
} else {
4552
$SID = ($Principal.Translate([System.Security.Principal.SecurityIdentifier])).Value
4653
}
47-
if ( ($SID -notmatch $SafeUsers) -and ($entry.ActiveDirectoryRights -match 'ExtendedRight') ) {
54+
if ( ($SID -notmatch $SafeUsers) -and ( ($entry.ActiveDirectoryRights -match 'ExtendedRight') -or ($entry.ActiveDirectoryRights -match 'GenericAll') ) ) {
4855
$Issue = [pscustomobject]@{
4956
Forest = $_.CanonicalName.split('/')[0]
5057
Name = $_.Name
5158
DistinguishedName = $_.DistinguishedName
5259
IdentityReference = $entry.IdentityReference
5360
ActiveDirectoryRights = $entry.ActiveDirectoryRights
54-
Issue = "$($entry.IdentityReference) can enroll in this Client Authentication template using a SAN without Manager Approval"
55-
Fix = @"
61+
Issue = @"
62+
$($entry.IdentityReference) can provide a Subject Alternative Name (SAN) while
63+
enrolling in this Client Authentication template, and enrollment does not require
64+
Manager Approval.
65+
66+
The resultant certificate can be used by an attacker to authenticate as any
67+
principal listed in the SAN up to and including Domain Admins, Enterprise Admins,
68+
or Domain Controllers.
69+
70+
"@
71+
Fix = @"
72+
# Enable Manager Approval
5673
`$Object = `'$($_.DistinguishedName)`'
57-
Get-ADObject `$Object | Set-ADObject -Replace @{'msPKI-Certificate-Name-Flag' = 0}
74+
Get-ADObject `$Object | Set-ADObject -Replace @{'msPKI-Enrollment-Flag' = 2}
5875
"@
59-
Revert = @"
76+
Revert = @"
77+
# Disable Manager Approval
6078
`$Object = `'$($_.DistinguishedName)`'
61-
Get-ADObject `$Object | Set-ADObject -Replace @{'msPKI-Certificate-Name-Flag' = 1}
79+
Get-ADObject `$Object | Set-ADObject -Replace @{'msPKI-Enrollment-Flag' = 0}
6280
"@
63-
Technique = 'ESC1'
81+
Technique = 'ESC1'
6482
}
6583
$Issue
6684
}

Private/Find-ESC11.ps1

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
function Find-ESC11 {
2+
<#
3+
.SYNOPSIS
4+
This script finds AD CS (Active Directory Certificate Services) objects that have the ESC11 vulnerability.
5+
6+
.DESCRIPTION
7+
The script takes an array of ADCS objects as input and filters them based on objects that have the objectClass
8+
'pKIEnrollmentService' and the InterfaceFlag set to 'No'. For each matching object, it creates a custom object with
9+
properties representing various information about the object, such as Forest, Name, DistinguishedName, Technique,
10+
Issue, Fix, and Revert.
11+
12+
.PARAMETER ADCSObjects
13+
Specifies the array of ADCS objects to be processed. This parameter is mandatory.
14+
15+
.OUTPUTS
16+
The script outputs an array of custom objects representing the matching ADCS objects and their associated information.
17+
18+
.EXAMPLE
19+
$ADCSObjects = Get-ADCSObject -Target (Get-Target)
20+
Find-ESC11 -ADCSObjects $ADCSObjects
21+
$Results
22+
#>
23+
[CmdletBinding()]
24+
param(
25+
[Parameter(Mandatory)]
26+
$ADCSObjects
27+
)
28+
process {
29+
$ADCSObjects | Where-Object {
30+
($_.objectClass -eq 'pKIEnrollmentService') -and
31+
($_.InterfaceFlag -ne 'Yes')
32+
} | ForEach-Object {
33+
[string]$CAFullName = "$($_.dNSHostName)\$($_.Name)"
34+
$Issue = [pscustomobject]@{
35+
Forest = $_.CanonicalName.split('/')[0]
36+
Name = $_.Name
37+
DistinguishedName = $_.DistinguishedName
38+
Technique = 'ESC11'
39+
Issue = $_.InterfaceFlag
40+
Fix = 'N/A'
41+
Revert = 'N/A'
42+
}
43+
if ($_.InterfaceFlag -eq 'No') {
44+
$Issue.Issue = @"
45+
The IF_ENFORCEENCRYPTICERTREQUEST flag is disabled on this Certification
46+
Authority (CA). It is possible to relay NTLM authentication to the RPC interface
47+
of this CA.
48+
49+
If the LAN Manager authentication level of any domain in this forest is 2 or
50+
less, an attacker can coerce authentication from a Domain Controller (DC) to
51+
receive a certificate which can be used to authenticate as that DC.
52+
53+
"@
54+
$Issue.Fix = @"
55+
# Enable the flag
56+
certutil -config $CAFullname -setreg CA\InterfaceFlags +IF_ENFORCEENCRYPTICERTREQUEST
57+
58+
# Restart the Ceritification Authority service
59+
Invoke-Command -ComputerName `'$($_.dNSHostName)`' -ScriptBlock {
60+
Get-Service -Name `'certsvc`' | Restart-Service -Force
61+
}
62+
"@
63+
$Issue.Revert = @"
64+
# Disable the flag
65+
certutil -config $CAFullname -setreg CA\InterfaceFlags -IF_ENFORCEENCRYPTICERTREQUEST
66+
67+
# Restart the Ceritification Authority service
68+
Invoke-Command -ComputerName `'$($_.dNSHostName)`' -ScriptBlock {
69+
Get-Service -Name `'certsvc`' | Restart-Service -Force
70+
}
71+
"@
72+
}
73+
$Issue
74+
}
75+
}
76+
}

Private/Find-ESC13.ps1

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
function Find-ESC13 {
2+
<#
3+
.SYNOPSIS
4+
This script finds AD CS (Active Directory Certificate Services) objects that have the ESC13 vulnerability.
5+
6+
.DESCRIPTION
7+
The script takes an array of ADCS objects as input and filters them based on the specified conditions.
8+
For each matching object, it creates a custom object with properties representing various information about
9+
the object, such as Forest, Name, DistinguishedName, IdentityReference, ActiveDirectoryRights, Issue, Fix, Revert, and Technique.
10+
11+
.PARAMETER ADCSObjects
12+
Specifies the array of ADCS objects to be processed. This parameter is mandatory.
13+
14+
.PARAMETER SafeUsers
15+
Specifies the list of SIDs of safe users who are allowed to have specific rights on the objects. This parameter is mandatory.
16+
17+
.PARAMETER ClientAuthEKUs
18+
A list of EKUs that can be used for client authentication.
19+
20+
.OUTPUTS
21+
The script outputs an array of custom objects representing the matching ADCS objects and their associated information.
22+
23+
.EXAMPLE
24+
$ADCSObjects = Get-ADCSObjects
25+
$SafeUsers = '-512$|-519$|-544$|-18$|-517$|-500$|-516$|-9$|-526$|-527$|S-1-5-10'
26+
$ClientAuthEKUs = '1\.3\.6\.1\.5\.5\.7\.3\.2|1\.3\.6\.1\.5\.2\.3\.4|1\.3\.6\.1\.4\.1\.311\.20\.2\.2|2\.5\.29\.37\.0'
27+
$Results = $ADCSObjects | Find-ESC13 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -ClientAuthEKUs $ClientAuthEKUs
28+
$Results
29+
#>
30+
[CmdletBinding()]
31+
param(
32+
[Parameter(Mandatory)]
33+
[Microsoft.ActiveDirectory.Management.ADEntity[]]$ADCSObjects,
34+
[Parameter(Mandatory)]
35+
[array]$SafeUsers,
36+
[Parameter(Mandatory)]
37+
$ClientAuthEKUs
38+
)
39+
40+
$ADCSObjects | Where-Object {
41+
($_.objectClass -eq 'pKICertificateTemplate') -and
42+
($_.pkiExtendedKeyUsage -match $ClientAuthEKUs) -and
43+
($_.'msPKI-Certificate-Policy')
44+
} | ForEach-Object {
45+
foreach ($policy in $_.'msPKI-Certificate-Policy') {
46+
if ($ADCSObjects.'msPKI-Cert-Template-OID' -contains $policy) {
47+
$OidToCheck = $ADCSObjects | Where-Object 'msPKI-Cert-Template-OID' -eq $policy
48+
if ($OidToCheck.'msDS-OIDToGroupLink') {
49+
foreach ($entry in $_.nTSecurityDescriptor.Access) {
50+
$Principal = New-Object System.Security.Principal.NTAccount($entry.IdentityReference)
51+
if ($Principal -match '^(S-1|O:)') {
52+
$SID = $Principal
53+
} else {
54+
$SID = ($Principal.Translate([System.Security.Principal.SecurityIdentifier])).Value
55+
}
56+
if ( ($SID -notmatch $SafeUsers) -and ($entry.ActiveDirectoryRights -match 'ExtendedRight') ) {
57+
$Issue = [pscustomobject]@{
58+
Forest = $_.CanonicalName.split('/')[0]
59+
Name = $_.Name
60+
DistinguishedName = $_.DistinguishedName
61+
IdentityReference = $entry.IdentityReference
62+
ActiveDirectoryRights = $entry.ActiveDirectoryRights
63+
LinkedGroup = $OidToCheck.'msDS-OIDToGroupLink'
64+
Issue = @"
65+
$($entry.IdentityReference) can enroll in this Client Authentication template
66+
which is linked to the group $($OidToCheck.'msDS-OIDToGroupLink').
67+
68+
If $($entry.IdentityReference) uses this certificate for authentication, they
69+
will gain the rights of the linked group while the group membership appears empty.
70+
71+
"@
72+
Fix = @"
73+
# Enable Manager Approval
74+
`$Object = `'$($_.DistinguishedName)`'
75+
Get-ADObject `$Object | Set-ADObject -Replace @{'msPKI-Enrollment-Flag' = 2}
76+
"@
77+
Revert = @"
78+
# Disable Manager Approval
79+
`$Object = `'$($_.DistinguishedName)`'
80+
Get-ADObject `$Object | Set-ADObject -Replace @{'msPKI-Enrollment-Flag' = 0}
81+
"@
82+
Technique = 'ESC13'
83+
}
84+
$Issue
85+
}
86+
}
87+
}
88+
}
89+
}
90+
}
91+
}

0 commit comments

Comments
 (0)