Last active
May 22, 2025 18:23
-
-
Save norman-bauer/15acdf9cf1269ad0da1f911cc0312321 to your computer and use it in GitHub Desktop.
Search all available windows enterprise pki servers for issued certificate requested by a given user for a keyword in subject or san. This is helpful to trace creation of malicious certificates after a user has been compromised.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# CONFIGURATION | |
$keyword = "administrator" # SAN keyword to search for | |
$requester = "DOMAIN\requester" # Requester to filter by | |
Import-Module PSPKI | |
$cas = Get-CertificationAuthority | |
$results = @() | |
foreach ($ca in $cas) { | |
Write-Host "Searching CA: $($ca.DisplayName)" -ForegroundColor Cyan | |
$caServer = $ca.ComputerName | |
$issued = Get-IssuedRequest -CertificationAuthority $caServer |? Request.RequesterName -eq $requester | |
foreach ($req in $issued) { | |
$reqId = $req.RequestID | |
$caServer = $ca.ComputerName | |
$url = "https://$caServer/certsrv/certnew.cer?ReqID=$reqId&Enc=b64" | |
try { | |
$response = Invoke-WebRequest -Uri $url -UseBasicParsing -ErrorAction Stop -UseDefaultCredentials -AllowUnencryptedAuthentication | |
$ms = New-Object System.IO.MemoryStream | |
$response.RawContentStream.Position = 0 | |
$response.RawContentStream.CopyTo($ms) | |
$ms.Position = 0 | |
$certBytes = $ms.ToArray() | |
$cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($certBytes) | |
$sanExt = $cert.Extensions | Where-Object { $_.Oid.FriendlyName -eq "Subject Alternative Name" } | |
if (( $cert.Subject -like "*$keyword*") -or ($sanExt -and $sanExt.Format($true) -like "*$keyword*")) { | |
$results += [PSCustomObject]@{ | |
CA = $ca.DisplayName | |
RequestID = $reqId | |
Subject = $cert.Subject | |
SAN = $sanExt.Format($true) -replace "\r?\n", " " | |
NotBefore = $cert.NotBefore | |
NotAfter = $cert.NotAfter | |
} | |
} | |
} catch { | |
Write-Warning "Failed to retrieve certificate for Request ID $reqId from $($ca.DisplayName)" | |
} | |
} | |
} | |
$results | Format-Table -AutoSize |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment