Skip to content

Commit

Permalink
2024.8 Release
Browse files Browse the repository at this point in the history
  • Loading branch information
jakehildreth authored Aug 3, 2024
2 parents 1828749 + 72832f1 commit e75bc26
Show file tree
Hide file tree
Showing 24 changed files with 901 additions and 215 deletions.
1 change: 1 addition & 0 deletions Build/Build-Module.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Build-Module -ModuleName 'Locksmith' {
'Microsoft.PowerShell.Utility'
'Microsoft.PowerShell.LocalAccounts'
'Microsoft.PowerShell.Management'
'Microsoft.PowerShell.Security'
'CimCmdlets'
'Dism'
)
Expand Down
6 changes: 3 additions & 3 deletions Docs/Flowcharts/ESC1.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ flowchart LR
UserType -- User --> UserPriority(High);
PrincipalType -->|Group| GroupType("Group Type");
GroupType -- AD Admins --> ADASize(No Finding);
GroupType -- Builtin/PKI Admins --> BIASize(Group Size);
GroupType -- Builtin/PKI Admins --> BIASize(BIA Group Size);
BIASize -- Empty/Small --> BIAEGPriority(Low);
BIASize -- Medium/Large --> BIAMGPriority(Medium);
GroupType -- Regular Users --> UsersSize(Group Size);
GroupType -- Regular Users --> UsersSize(User Group Size);
UsersSize -- Empty/Small --> UsersEGPriority(High);
UsersSize -- Medium/Large --> UsersMGPriority(Critical);
PrincipalType -->|gMSA| gMSAType(gMSA Type);
gMSAType -- Any --> gMSAPriority((No Finding));
```
```
6 changes: 3 additions & 3 deletions Docs/Flowcharts/ESC2.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ flowchart LR
UserType -- User --> UserPriority(High);
PrincipalType -->|Group| GroupType("Group Type");
GroupType -- AD Admins --> ADASize(No Finding);
GroupType -- Builtin/PKI Admins --> BIASize(Group Size);
GroupType -- Builtin/PKI Admins --> BIASize(BIA Group Size);
BIASize -- Empty/Small --> BIAEGPriority(Info);
BIASize -- Medium/Large --> BIAMGPriority(Low);
GroupType -- Regular Users --> UsersSize(Group Size);
GroupType -- Regular Users --> UsersSize(User Group Size);
UsersSize -- Empty/Small --> UsersEGPriority(Medium);
UsersSize -- Medium/Large --> UsersMGPriority(High);
PrincipalType -->|gMSA| gMSAType(gMSA Type);
gMSAType -- Any --> gMSAPriority(No Finding);
```
```
6 changes: 3 additions & 3 deletions Docs/Flowcharts/ESC3.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ flowchart LR
UserType -- User --> UserPriority(High);
PrincipalType -->|Group| GroupType("Group Type");
GroupType -- AD Admins --> ADASize(No Finding);
GroupType -- Builtin/PKI Admins --> BIASize(Group Size);
GroupType -- Builtin/PKI Admins --> BIASize(BIA Group Size);
BIASize -- Empty/Small --> BIAEGPriority(No Info);
BIASize -- Medium/Large --> BIAMGPriority(Low);
GroupType -- Regular Users --> UsersSize(Group Size);
GroupType -- Regular Users --> UsersSize(User Group Size);
UsersSize -- Empty/Small --> UsersEGPriority(Low);
UsersSize -- Medium/Large --> UsersMGPriority(Medium);
PrincipalType -->|gMSA| gMSAType(gMSA Type);
gMSAType -- Any --> gMSAPriority(No Finding);
```
```
6 changes: 3 additions & 3 deletions Docs/Flowcharts/ESC4.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ flowchart LR
UserType -- User --> UserPriority(High);
PrincipalType -->|Group| GroupType("Group Type");
GroupType -- AD Admins --> ADASize(No Finding);
GroupType -- Builtin/PKI Admins --> BIASize(Group Size);
GroupType -- Builtin/PKI Admins --> BIASize(BIA Group Size);
BIASize -- Empty/Small --> BIAEGPriority(Info);
BIASize -- Medium/Large --> BIAMGPriority(Low);
GroupType -- Regular Users --> UsersSize(Group Size);
GroupType -- Regular Users --> UsersSize(User Group Size);
UsersSize -- Empty/Small --> UsersEGPriority(Medium);
UsersSize -- Medium/Large --> UsersMGPriority(High);
PrincipalType -->|gMSA| gMSAType(gMSA Type);
gMSAType -- Any --> gMSAPriority(No Finding);
```
```
534 changes: 451 additions & 83 deletions Invoke-Locksmith.ps1

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions Locksmith.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
Description = 'A small tool to find and fix common misconfigurations in Active Directory Certificate Services.'
FunctionsToExport = @('*')
GUID = 'b1325b42-8dc4-4f17-aa1f-dcb5984ca14a'
ModuleVersion = '2024.3'
ModuleVersion = '2024.8'
PowerShellVersion = '5.1'
PrivateData = @{
PSData = @{
ExternalModuleDependencies = @('ActiveDirectory', 'ServerManager', 'Microsoft.PowerShell.Utility', 'Microsoft.PowerShell.LocalAccounts', 'Microsoft.PowerShell.Management', 'CimCmdlets', 'Dism')
ExternalModuleDependencies = @('ActiveDirectory', 'ServerManager', 'Microsoft.PowerShell.Utility', 'Microsoft.PowerShell.LocalAccounts', 'Microsoft.PowerShell.Management', 'Microsoft.PowerShell.Security', 'CimCmdlets', 'Dism')
IconUri = 'https://raw.githubusercontent.com/TrimarcJake/Locksmith/main/Images/locksmith.ico'
ProjectUri = 'https://github.com/TrimarcJake/Locksmith'
Tags = @('Windows', 'Locksmith', 'CA', 'PKI', 'ActiveDirectory', 'CertificateServices', 'ADCS')
}
}
RequiredModules = @('ActiveDirectory', 'ServerManager', 'Microsoft.PowerShell.Utility', 'Microsoft.PowerShell.LocalAccounts', 'Microsoft.PowerShell.Management', 'CimCmdlets', 'Dism')
RequiredModules = @('ActiveDirectory', 'ServerManager', 'Microsoft.PowerShell.Utility', 'Microsoft.PowerShell.LocalAccounts', 'Microsoft.PowerShell.Management', 'Microsoft.PowerShell.Security', 'CimCmdlets', 'Dism')
RootModule = 'Locksmith.psm1'
}
14 changes: 12 additions & 2 deletions Private/Find-AuditingIssue.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,18 @@
DistinguishedName = $_.DistinguishedName
Technique = 'DETECT'
Issue = "Auditing is not fully enabled on $($_.CAFullName). Current value is $($_.AuditFilter)"
Fix = "certutil.exe -config `'$($_.CAFullname)`' -setreg `'CA\AuditFilter`' 127; Invoke-Command -ComputerName `'$($_.dNSHostName)`' -ScriptBlock { Get-Service -Name `'certsvc`' | Restart-Service -Force }"
Revert = "certutil.exe -config $($_.CAFullname) -setreg CA\AuditFilter $($_.AuditFilter); Invoke-Command -ComputerName `'$($_.dNSHostName)`' -ScriptBlock { Get-Service -Name `'certsvc`' | Restart-Service -Force }"
Fix = @"
certutil.exe -config `'$($_.CAFullname)`' -setreg `'CA\AuditFilter`' 127
Invoke-Command -ComputerName `'$($_.dNSHostName)`' -ScriptBlock {
Get-Service -Name `'certsvc`' | Restart-Service -Force
}
"@
Revert = @"
certutil.exe -config $($_.CAFullname) -setreg CA\AuditFilter $($_.AuditFilter)
Invoke-Command -ComputerName `'$($_.dNSHostName)`' -ScriptBlock {
Get-Service -Name `'certsvc`' | Restart-Service -Force
}
"@
}
if ($_.AuditFilter -match 'CA Unavailable') {
$Issue.Issue = $_.AuditFilter
Expand Down
12 changes: 9 additions & 3 deletions Private/Find-ESC1.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
$ADCSObjects | Where-Object {
($_.objectClass -eq 'pKICertificateTemplate') -and
($_.pkiExtendedKeyUsage -match $ClientAuthEKUs) -and
($_.'msPKI-Certificate-Name-Flag' -eq 1) -and
($_.'msPKI-Certificate-Name-Flag' -band 1) -and
!($_.'msPKI-Enrollment-Flag' -band 2) -and
( ($_.'msPKI-RA-Signature' -eq 0) -or ($null -eq $_.'msPKI-RA-Signature') )
} | ForEach-Object {
Expand All @@ -52,8 +52,14 @@
IdentityReference = $entry.IdentityReference
ActiveDirectoryRights = $entry.ActiveDirectoryRights
Issue = "$($entry.IdentityReference) can enroll in this Client Authentication template using a SAN without Manager Approval"
Fix = "Get-ADObject `'$($_.DistinguishedName)`' | Set-ADObject -Replace @{'msPKI-Certificate-Name-Flag' = 0}"
Revert = "Get-ADObject `'$($_.DistinguishedName)`' | Set-ADObject -Replace @{'msPKI-Certificate-Name-Flag' = 1}"
Fix = @"
`$Object = `'$($_.DistinguishedName)`'
Get-ADObject `$Object | Set-ADObject -Replace @{'msPKI-Certificate-Name-Flag' = 0}
"@
Revert = @"
`$Object = `'$($_.DistinguishedName)`'
Get-ADObject `$Object | Set-ADObject -Replace @{'msPKI-Certificate-Name-Flag' = 1}
"@
Technique = 'ESC1'
}
$Issue
Expand Down
12 changes: 9 additions & 3 deletions Private/Find-ESC2.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
$ADCSObjects | Where-Object {
($_.ObjectClass -eq 'pKICertificateTemplate') -and
( (!$_.pkiExtendedKeyUsage) -or ($_.pkiExtendedKeyUsage -match '2.5.29.37.0') )-and
($_.'msPKI-Certificate-Name-Flag' -eq 1) -and
($_.'msPKI-Certificate-Name-Flag' -band 1) -and
!($_.'msPKI-Enrollment-Flag' -band 2) -and
( ($_.'msPKI-RA-Signature' -eq 0) -or ($null -eq $_.'msPKI-RA-Signature') )
} | ForEach-Object {
Expand All @@ -52,8 +52,14 @@
IdentityReference = $entry.IdentityReference
ActiveDirectoryRights = $entry.ActiveDirectoryRights
Issue = "$($entry.IdentityReference) can request a SubCA certificate without Manager Approval"
Fix = "Get-ADObject `'$($_.DistinguishedName)`' | Set-ADObject -Replace @{'msPKI-Certificate-Name-Flag' = 0}"
Revert = "Get-ADObject `'$($_.DistinguishedName)`' | Set-ADObject -Replace @{'msPKI-Certificate-Name-Flag' = 1}"
Fix = @"
`$Object = `'$($_.DistinguishedName)`'
Get-ADObject `$Object | Set-ADObject -Replace @{'msPKI-Certificate-Name-Flag' = 0}
"@
Revert = @"
`$Object = `'$($_.DistinguishedName)`'
Get-ADObject `$Object | Set-ADObject -Replace @{'msPKI-Certificate-Name-Flag' = 1}
"@
Technique = 'ESC2'
}
$Issue
Expand Down
10 changes: 8 additions & 2 deletions Private/Find-ESC3Condition1.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,14 @@
IdentityReference = $entry.IdentityReference
ActiveDirectoryRights = $entry.ActiveDirectoryRights
Issue = "$($entry.IdentityReference) can enroll in this Enrollment Agent template without Manager Approval"
Fix = "Get-ADObject `'$($_.DistinguishedName)`' | Set-ADObject -Replace @{'msPKI-Certificate-Name-Flag' = 0}"
Revert = "Get-ADObject `'$($_.DistinguishedName)`' | Set-ADObject -Replace @{'msPKI-Certificate-Name-Flag' = 1}"
Fix = @"
`$Object = `'$($_.DistinguishedName)`'
Get-ADObject `$Object | Set-ADObject -Replace @{'msPKI-Certificate-Name-Flag' = 0}
"@
Revert = @"
`$Object = `'$($_.DistinguishedName)`'
Get-ADObject `$Object | Set-ADObject -Replace @{'msPKI-Certificate-Name-Flag' = 1}
"@
Technique = 'ESC3'
}
$Issue
Expand Down
12 changes: 9 additions & 3 deletions Private/Find-ESC3Condition2.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
$ADCSObjects | Where-Object {
($_.objectClass -eq 'pKICertificateTemplate') -and
($_.pkiExtendedKeyUsage -match $ClientAuthEKU) -and
($_.'msPKI-Certificate-Name-Flag' -eq 1) -and
($_.'msPKI-Certificate-Name-Flag' -band 1) -and
!($_.'msPKI-Enrollment-Flag' -band 2) -and
($_.'msPKI-RA-Application-Policies' -eq '1.3.6.1.4.1.311.20.2.1') -and
( ($_.'msPKI-RA-Signature' -eq 1) )
Expand All @@ -53,8 +53,14 @@
IdentityReference = $entry.IdentityReference
ActiveDirectoryRights = $entry.ActiveDirectoryRights
Issue = "$($entry.IdentityReference) can enroll in this Client Authentication template using a SAN without Manager Approval"
Fix = "Get-ADObject `'$($_.DistinguishedName)`' | Set-ADObject -Replace @{'msPKI-Certificate-Name-Flag' = 0}"
Revert = "Get-ADObject `'$($_.DistinguishedName)`' | Set-ADObject -Replace @{'msPKI-Certificate-Name-Flag' = 1}"
Fix = @"
`$Object = `'$($_.DistinguishedName)`'
Get-ADObject `$Object | Set-ADObject -Replace @{'msPKI-Certificate-Name-Flag' = 0}
"@
Revert = @"
`$Object = `'$($_.DistinguishedName)`'
Get-ADObject `$Object | Set-ADObject -Replace @{'msPKI-Certificate-Name-Flag' = 1}
"@
Technique = 'ESC3'
}
$Issue
Expand Down
69 changes: 62 additions & 7 deletions Private/Find-ESC4.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,44 @@
.PARAMETER SafeUsers
Specifies the list of SIDs of safe users who are allowed to have specific rights on the objects. This parameter is mandatory.
.PARAMETER SafeObjectTypes
Specifices a list of ObjectTypes which are not a security concern. 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-ADCSObjects
$ADCSObjects = Get-ADCSObject
# GenericAll, WriteDacl, and WriteOwner all permit full control of an AD object.
# WriteProperty may or may not permit full control depending the specific property and AD object type.
$DangerousRights = @('GenericAll', 'WriteProperty', 'WriteOwner', 'WriteDacl')
# -512$ = Domain Admins group
# -519$ = Enterprise Admins group
# -544$ = Administrators group
# -18$ = SYSTEM
# -517$ = Cert Publishers
# -500$ = Built-in Administrator
$SafeOwners = '-512$|-519$|-544$|-18$|-517$|-500$'
# -512$ = Domain Admins group
# -519$ = Enterprise Admins group
# -544$ = Administrators group
# -18$ = SYSTEM
# -517$ = Cert Publishers
# -500$ = Built-in Administrator
# -516$ = Domain Controllers
# -9$ = Enterprise Domain Controllers
# -526$ = Key Admins
# -527$ = Enterprise Key Admins
# S-1-5-10 = SELF
$SafeUsers = '-512$|-519$|-544$|-18$|-517$|-500$|-516$|-9$|-526$|-527$|S-1-5-10'
$Results = $ADCSObjects | Find-ESC4 -DangerousRights $DangerousRights -SafeOwners $SafeOwners -SafeUsers $SafeUsers
# The well-known GUIDs for Enroll and AutoEnroll rights on AD CS templates.
$SafeObjectTypes = '0e10c968-78fb-11d2-90d4-00c04f79dc55|a05b8cc2-17bc-4802-a710-e7c15ab866a2'
$Results = $ADCSObjects | Find-ESC4 -DangerousRights $DangerousRights -SafeOwners $SafeOwners -SafeUsers $SafeUsers -SafeObjectTypes $SafeObjectTypes
$Results
#>
[CmdletBinding()]
Expand All @@ -40,7 +69,10 @@
[Parameter(Mandatory = $true)]
$SafeOwners,
[Parameter(Mandatory = $true)]
$SafeUsers
$SafeUsers,
[Parameter(Mandatory = $true)]
$SafeObjectTypes,
[int]$Mode
)
$ADCSObjects | ForEach-Object {
$Principal = New-Object System.Security.Principal.NTAccount($_.nTSecurityDescriptor.Owner)
Expand All @@ -56,8 +88,18 @@
Name = $_.Name
DistinguishedName = $_.DistinguishedName
Issue = "$($_.nTSecurityDescriptor.Owner) has Owner rights on this template"
Fix = "`$Owner = New-Object System.Security.Principal.SecurityIdentifier(`'$PreferredOwner`'); `$ACL = Get-Acl -Path `'AD:$($_.DistinguishedName)`'; `$ACL.SetOwner(`$Owner); Set-ACL -Path `'AD:$($_.DistinguishedName)`' -AclObject `$ACL"
Revert = "`$Owner = New-Object System.Security.Principal.SecurityIdentifier(`'$($_.nTSecurityDescriptor.Owner)`'); `$ACL = Get-Acl -Path `'AD:$($_.DistinguishedName)`'; `$ACL.SetOwner(`$Owner); Set-ACL -Path `'AD:$($_.DistinguishedName)`' -AclObject `$ACL"
Fix = @"
`$Owner = New-Object System.Security.Principal.SecurityIdentifier(`'$PreferredOwner`')
`$ACL = Get-Acl -Path `'AD:$($_.DistinguishedName)`'
`$ACL.SetOwner(`$Owner)
Set-ACL -Path `'AD:$($_.DistinguishedName)`' -AclObject `$ACL
"@
Revert = @"
`$Owner = New-Object System.Security.Principal.SecurityIdentifier(`'$($_.nTSecurityDescriptor.Owner)`')
`$ACL = Get-Acl -Path `'AD:$($_.DistinguishedName)`'
`$ACL.SetOwner(`$Owner)
Set-ACL -Path `'AD:$($_.DistinguishedName)`' -AclObject `$ACL
"@
Technique = 'ESC4'
}
$Issue
Expand All @@ -74,7 +116,7 @@
($SID -notmatch $SafeUsers) -and
($entry.AccessControlType -eq 'Allow') -and
($entry.ActiveDirectoryRights -match $DangerousRights) -and
($entry.ActiveDirectoryRights.ObjectType -notmatch $SafeObjectTypes)
($entry.ObjectType -notmatch $SafeObjectTypes)
) {
$Issue = [pscustomobject]@{
Forest = $_.CanonicalName.split('/')[0]
Expand All @@ -83,10 +125,23 @@
IdentityReference = $entry.IdentityReference
ActiveDirectoryRights = $entry.ActiveDirectoryRights
Issue = "$($entry.IdentityReference) has $($entry.ActiveDirectoryRights) rights on this template"
Fix = "`$ACL = Get-Acl -Path `'AD:$($_.DistinguishedName)`'; foreach ( `$ace in `$ACL.access ) { if ( (`$ace.IdentityReference.Value -like '$($Principal.Value)' ) -and ( `$ace.ActiveDirectoryRights -notmatch '^ExtendedRight$') ) { `$ACL.RemoveAccessRule(`$ace) | Out-Null ; Set-Acl -Path `'AD:$($_.DistinguishedName)`' -AclObject `$ACL } }"
Fix = @"
`$ACL = Get-Acl -Path `'AD:$($_.DistinguishedName)`'
foreach ( `$ace in `$ACL.access ) {
if ( (`$ace.IdentityReference.Value -like '$($Principal.Value)' ) -and ( `$ace.ActiveDirectoryRights -notmatch '^ExtendedRight$') ) {
`$ACL.RemoveAccessRule(`$ace) | Out-Null
}
}
Set-Acl -Path `'AD:$($_.DistinguishedName)`' -AclObject `$ACL
"@
Revert = '[TODO]'
Technique = 'ESC4'
}

if ( $Mode -in @(1,3,4) ) {
Update-ESC4Remediation -Issue $Issue
}

$Issue
}
}
Expand Down
Loading

0 comments on commit e75bc26

Please sign in to comment.