Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Build/Build-Module.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ Build-Module -ModuleName 'Locksmith' {

# The scans to run. Defaults to 'All'.
[Parameter()]
[ValidateSet('Auditing', 'ESC1', 'ESC2', 'ESC3', 'ESC4', 'ESC5', 'ESC6', 'ESC7', 'ESC8', 'ESC11', 'ESC13', 'ESC15', 'EKUwu', 'ESC16', 'All', 'PromptMe')]
[ValidateSet('Auditing', 'ESC1', 'ESC2', 'ESC3', 'ESC4', 'ESC5', 'ESC6', 'ESC7', 'ESC8', 'ESC9', 'ESC11', 'ESC13', 'ESC15', 'EKUwu', 'ESC16', 'All', 'PromptMe')]
[array]$Scans = 'All'
)
}
Expand Down
651 changes: 472 additions & 179 deletions Invoke-Locksmith.ps1

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Locksmith.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
FunctionsToExport = 'Invoke-Locksmith'
GUID = 'b1325b42-8dc4-4f17-aa1f-dcb5984ca14a'
HelpInfoURI = 'https://raw.githubusercontent.com/jakehildreth/Locksmith/main/en-US/'
ModuleVersion = '2025.5.18'
ModuleVersion = '2025.5.26'
PowerShellVersion = '5.1'
PrivateData = @{
PSData = @{
Expand Down
8 changes: 5 additions & 3 deletions Private/Find-ESC1.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,14 @@ Get-ADObject `$Object | Set-ADObject -Replace @{'msPKI-Enrollment-Flag' = 0}
Technique = 'ESC1'
}

if ( $Mode -in @(1, 3, 4) ) {
Update-ESC1Remediation -Issue $Issue
}
if ($SkipRisk -eq $false) {
Set-RiskRating -ADCSObjects $ADCSObjects -Issue $Issue -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers
}

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

$Issue
}
}
Expand Down
2 changes: 1 addition & 1 deletion Private/Find-ESC3C1.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
$($entry.IdentityReference) can use this template to request an Enrollment Agent
certificate without Manager Approval.

The resulting certificate can be used to enroll in any template that requires
The resulting certificate can be used to enroll in any template that allows
an Enrollment Agent to submit the request.

More info:
Expand Down
8 changes: 5 additions & 3 deletions Private/Find-ESC4.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,14 @@ Set-Acl -Path 'AD:$($_.DistinguishedName)' -AclObject `$ACL
Technique = 'ESC4'
}

if ( $Mode -in @(1, 3, 4) ) {
Update-ESC4Remediation -Issue $Issue
}
if ($SkipRisk -eq $false) {
Set-RiskRating -ADCSObjects $ADCSObjects -Issue $Issue -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers
}

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

$Issue
}
}
Expand Down
1 change: 1 addition & 0 deletions Private/Find-ESC6.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
$Issue = [pscustomobject]@{
Forest = $_.CanonicalName.split('/')[0]
Name = $_.Name
CAFullname = $CAFullName
DistinguishedName = $_.DistinguishedName
Issue = $_.SANFlag
Fix = 'N/A'
Expand Down
110 changes: 58 additions & 52 deletions Private/Find-ESC7.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -34,74 +34,80 @@
[switch]$SkipRisk
)
process {
$ADCSObjects | Where-Object {
($_.objectClass -eq 'pKIEnrollmentService') -and $_.CAHostDistinguishedName -and
( ($_.CAAdministrator) -or ($_.CertificateManager) )
Write-Output $ADCSObjects -PipelineVariable object | Where-Object {
($object.objectClass -eq 'pKIEnrollmentService') -and $object.CAHostDistinguishedName -and
( ($object.CAAdministrator) -or ($object.CertificateManager) )
} | ForEach-Object {
$UnsafeCAAdministrators = Write-Output $_.CAAdministrator -PipelineVariable admin | ForEach-Object {
Write-Output $object.CAAdministrator -PipelineVariable admin | ForEach-Object {
$SID = Convert-IdentityReferenceToSid -Object $admin
if ($SID -notmatch $SafeUsers) {
$admin
}
}
$UnsafeCertificateManagers = Write-Output $_.CertificateManager -PipelineVariable manager | ForEach-Object {
$SID = Convert-IdentityReferenceToSid -Object $manager
if ($SID -notmatch $SafeUsers) {
$manager
}
}
if ($UnsafeCAAdministrators -or $UnsafeCertificateManagers) {
$Issue = [pscustomobject]@{
Forest = $_.CanonicalName.split('/')[0]
Name = $_.Name
DistinguishedName = $_.DistinguishedName
CAAdministrator = $_.CAAdministrator
CertificateManager = $_.CertificateManager
Issue = $null
Fix = $null
Revert = $null
Technique = 'ESC7'
}
if ($UnsafeCAAdministrators) {
$Issue.Issue = $Issue.Issue + @"
Unexpected principals are granted "CA Administrator" rights on this Certification Authority.
Unsafe CA Administrators: $($UnsafeCAAdministrators -join ', ').
$Issue = [pscustomobject]@{
Forest = $object.CanonicalName.split('/')[0]
Name = $object.Name
DistinguishedName = $object.DistinguishedName
IdentityReference = $admin
IdentityReferenceSID = $SID
Right = 'CA Administrator'
Issue = @"
$admin has been granted CA Administrator rights on this Certification Authority (CA).

"@
$Issue.Fix = $Issue.Fix + @"
Revoke CA Administrator rights from $($UnsafeCAAdministrators -join ', ')
$admin has full control over this CA.

"@
$Issue.Revert = $Issue.Revert + @"
Reinstate CA Administrator rights for $($UnsafeCAAdministrators -join ', ')
More info:
- https://posts.specterops.io/certified-pre-owned-d95910965cd2

"@
}
if ($UnsafeCertificateManagers) {
$Issue.Issue = $Issue.Issue + @"
expected principals are granted "Certificate Manager" rights on this Certification Authority.
Unexpected Principals: $($UnsafeCertificateManagers -join ', ')
Fix = "Revoke CA Administrator rights from ${admin}."
Revert = "Restore CA Administrator rights to ${admin}."
Technique = 'ESC7'
}

"@
$Issue.Fix = $Issue.Fix + @"
Revoke Certificate Manager rights from $($UnsafeCertificateManagers -join ', ')
if ($SkipRisk -eq $false) {
Set-RiskRating -ADCSObjects $ADCSObjects -Issue $Issue -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers
}

"@
$Issue.Revert = $Issue.Revert + @"
Reinstate Certificate Manager rights for $($UnsafeCertificateManagers -join ', ')
if ( $Mode -in @(1, 3, 4) ) {
Update-ESC7Remediation -Issue $Issue
}

"@
}
if ($SkipRisk -eq $false) {
Set-RiskRating -ADCSObjects $ADCSObjects -Issue $Issue -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers
$Issue
}
$Issue.Issue = $Issue.Issue + @"
}

Write-Output $object.CertificateManager -PipelineVariable admin | ForEach-Object {
$SID = Convert-IdentityReferenceToSid -Object $admin
if ($SID -notmatch $SafeUsers) {
$Issue = [pscustomobject]@{
Forest = $object.CanonicalName.split('/')[0]
Name = $object.Name
DistinguishedName = $object.DistinguishedName
IdentityReference = $admin
IdentityReferenceSID = $SID
Right = 'Certificate Manager'
Issue = @"
$admin has been granted Certificate Manager rights on this Certification Authority (CA).

$admin can approve pending certificate requests on this CA.

More info:
- https://posts.specterops.io/certified-pre-owned-d95910965cd2

"@
$Issue
Fix = "Revoke Certificate Manager rights from ${admin}."
Revert = "Restore Certificate Manager rights to ${admin}."
Technique = 'ESC7'
}

if ($SkipRisk -eq $false) {
Set-RiskRating -ADCSObjects $ADCSObjects -Issue $Issue -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers
}

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

$Issue
}
}
}
}
Expand Down
Loading