Digital Certificates
Adversaries may create self-signed SSL/TLS certificates that can be used during targeting. SSL/TLS certificates are designed to instill trust and include key information, owner identity, and a digital signature from a verifying entity. In the case of self-signing, these certificates lack third-party CA trust but remain functional for encrypting traffic. Adversaries create self-signed certificates to encrypt C2 communications (as seen with APT29/WellMess using mutual TLS authentication), to enable adversary-in-the-middle attacks if installed as a trusted root certificate, or to impersonate legitimate services. PROMETHIUM used self-signed certificates for HTTPS C2, Gamaredon Group reused the same TLS certificate across infrastructure clusters, and Storm-0501 spoofed a 'Microsoft IT TLS CA 5' self-signed certificate. Detection must focus on observable side-effects: certificate generation tool execution on compromised hosts, suspicious certificate store modifications, and network TLS connections bearing anomalous certificate properties.
// T1587.003 — Self-Signed Certificate Creation and Suspicious Certificate Operations
// Branch 1: Known certificate generation tool execution
let CertGenTools = dynamic(["openssl.exe", "openssl", "makecert.exe", "pvk2pfx.exe", "certmgr.exe"]);
let OpenSSLCertPatterns = dynamic(["req -new", "x509 -req", "genrsa", "genpkey", "pkcs12 -export", "-newkey rsa", "-newkey ec", "req -x509", "gencert", "-selfsign"]);
let CertToolExec = DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName in~ (CertGenTools)
or (FileName =~ "openssl" and ProcessCommandLine has_any (OpenSSLCertPatterns))
| extend DetectionBranch = "CertGenToolExecution"
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine,
InitiatingProcessFileName, InitiatingProcessCommandLine, DetectionBranch;
// Branch 2: PowerShell certificate creation via .NET or cmdlet
let PSCertPatterns = dynamic(["New-SelfSignedCertificate", "X509Certificate2", "System.Security.Cryptography.X509Certificates", "CertificateRequest", "RSACryptoServiceProvider", "ECDsaCng"]);
let PSCertCreate = DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName in~ ("powershell.exe", "pwsh.exe")
| where ProcessCommandLine has_any (PSCertPatterns)
| extend DetectionBranch = "PSCertificateCreation"
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine,
InitiatingProcessFileName, InitiatingProcessCommandLine, DetectionBranch;
// Branch 3: certutil certificate import/store modification
let CertUtilImportPatterns = dynamic(["-addstore", "-addrepo", "-MergePFX", "-importpfx", "-p12", "-importcert"]);
let CertStorePaths = dynamic(["Root", "AuthRoot", "TrustedPublisher", "TrustedPeople", "CA"]);
let CertUtilOps = DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName =~ "certutil.exe"
| where ProcessCommandLine has_any (CertUtilImportPatterns)
| extend TargetsRootStore = ProcessCommandLine has_any (CertStorePaths)
| extend DetectionBranch = "CertUtilStoreImport"
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine,
InitiatingProcessFileName, InitiatingProcessCommandLine, DetectionBranch, TargetsRootStore;
// Branch 4: .pfx/.pem/.cer file creation in suspicious locations
let SuspiciousCertPaths = dynamic(["\\Temp\\", "\\AppData\\Local\\Temp\\", "\\Users\\Public\\", "\\ProgramData\\", "\\Windows\\Temp\\"]);
let CertFileCreate = DeviceFileEvents
| where Timestamp > ago(24h)
| where FileName endswith ".pfx" or FileName endswith ".pem" or FileName endswith ".cer" or FileName endswith ".crt" or FileName endswith ".p12" or FileName endswith ".key"
| where FolderPath has_any (SuspiciousCertPaths)
| extend DetectionBranch = "SuspiciousCertFileCreation"
| project Timestamp, DeviceName, AccountName = InitiatingProcessAccountName, FileName = FileName,
ProcessCommandLine = InitiatingProcessCommandLine,
InitiatingProcessFileName, InitiatingProcessCommandLine, DetectionBranch;
union CertToolExec, PSCertCreate, CertUtilOps, CertFileCreate
| sort by Timestamp desc Data Sources
Required Tables
False Positives
- Development teams using openssl or New-SelfSignedCertificate to generate local development HTTPS certificates for localhost testing
- PKI administrators and IT operations staff managing internal certificate authority infrastructure and importing trusted root certificates from enterprise CAs
- DevOps pipelines (Jenkins, GitLab CI, GitHub Actions runners on Windows) that generate ephemeral self-signed certificates for containerized test environments
- Security penetration testers and red team operators running authorized exercises involving certificate-based C2 simulation
- Web server configuration scripts (IIS setup, Nginx automation) that auto-generate self-signed certificates during initial service configuration
- Monitoring and observability agents (Datadog, Elastic Agent) that manage their own TLS certificates for encrypted data shipping
References (10)
- https://attack.mitre.org/techniques/T1587/003/
- https://www.splunk.com/en_us/blog/security/tall-tales-of-hunting-with-tls-ssl-certificates.html
- https://www.pwc.co.uk/cyber-security/pdf/pwc-cyber-threats-2020-a-year-in-retrospect.pdf
- https://blog.talosintelligence.com/2020/06/promethium-extends-with-strongpity3.html
- https://www.mandiant.com/resources/blog/storm-0501-ransomware
- https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/certutil
- https://learn.microsoft.com/en-us/powershell/module/pki/new-selfsignedcertificate
- https://learn.microsoft.com/en-us/defender-endpoint/advanced-hunting-devicefileevents-table
- https://learn.microsoft.com/en-us/defender-endpoint/advanced-hunting-deviceregistryevents-table
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1587.003/T1587.003.md
Unlock Pro Content
Get the full detection package for T1587.003 including response playbook, investigation guide, and atomic red team tests.