On December 30, NetSPI Managing Director Florindo Gallicchio was featured in SC Magazine:
As companies of all sizes prepare for more challenges tied to the pandemic, as well as an expected transition to a permanent hybrid workforce, security plans will need to adapt. So what kind of strategic shifts might we see in 2021? More sophisticated phishing campaigns will probably mean enhanced email security. Digital identities may grow more appealing. And a surge in M&A could introduce new security considerations.
At least, that’s some of what we heard from the experts. As part of our year in review, which looked at critical events during the last year and how they might influence 2021, SC Media collected predictions across a range of categories from cybersecurity experts. Here, the cyber community reads the tea leaves on evolving strategies of the enterprise.
Security budgets are not necessarily going to increase but will be reprioritized, says Florindo Gallicchio, managing director at NetSPI:
“More dollars will be specifically allocated to cloud security budgets due to the prolonged and, in many cases permanent, remote work opportunities – in other words, a distributed workforce. One exception to stagnant budgets is regulatory drivers. Certain states (e.g. California) and industries (e.g. health care) may need to increase budgets to comply with new or changing regulatory expectations.”
On December 28, NetSPI Managing Director Florindo Gallicchio was featured in SC Magazine:
What might 2021 bring in term of technology?
Community and market experts found consensus on a few areas. First, cloud security will dominate strategies and investments even more that it did during 2020, as organizations big and small go all in on digital transformation. And second, technologies once deemed “on the horizon” – think automation, 5G and even the much hyped artificial intelligence – will officially arrive.
Automation continues to be a priority, but human context will be the key to security program management and success, says Florindo Gallicchio, managing director at NetSPI:
“By now, we all understand the value automation brings to any security tool. Yet, in 2021, the human element will be pushed to the forefront of security innovation, specifically for our intellect and ability to add context to security findings. Contextualizing security findings will be an invaluable tool to boost remediation efforts in the new year, as the number of vulnerabilities remains exponential and context is key to helping us prioritize.”
As we write this post, you’ve likely heard about the FireEye and U.S. government agency breaches that occurred over the past week. We know now the breaches have been linked back to a supply chain attack on the SolarWinds Orion Platform, a software platform that manages IT operations and products for over 300,000 organizations, including over 425 of the Fortune 500, all ten of the top U.S. telecommunications companies, all five branches of the U.S. Military, all five of the top U.S. accounting firms, and many, many more.
While FireEye, the U.S. Treasury, and National Telecommunications and Information Administration (NTIA) were the first to report a security breach, the breadth of SolarWinds’ customer base is an indicator that the breaches are seemingly the tip of the iceberg.
For the sake of information sharing, here is an overview of the attacks, immediate steps you can take to identify whether you have fallen victim, and tips for protecting your organization as communicated by FireEye, SolarWinds, and NetSPI. For the full technical deep-dive, we highly recommend the FireEye blog post.
On December 13, SolarWinds issued a security advisory alerting to a manual supply chain attack on its Orion Platform software builds for versions 2019.4 HF 5 through 2020.2.1, released between March 2020 and June 2020.
FireEye discovered the attack and suggests it is a state-sponsored global intrusion campaign by a group named UNC2452 – though many industry experts are attributing the attack to APT29, a group of hackers associated with the Russian Foreign Intelligence Service.
Attack Origin: UNC2452 gained access to victims via trojan-based updates to SolarWinds’ Orion IT monitoring and management software, distributing malware called SUNBURST. Multiple trojanized updates were digitally signed and subsequently deployed via this URL: hxxps://downloads.solarwinds[.]com/solarwinds/CatalogResources/Core/2019.4/2019.4.5220.20574 /SolarWinds-Core-v2019.4.5220-Hotfix5.msp. The downloaded file is a standard Windows Installer Patch file, which includes the trojanized SolarWinds.Orion.Core.BusinessLayer.dll component.
How It Works: The digitally signed SolarWinds.Orion.Core.BusinessLayer.dll file is a component of the Orion Improvement Program (OIP) software framework that contains a backdoor that communicates with third party servers via the HTTP protocol. The malicious DLL gets loaded into the legitimate SolarWinds.BusinessLayerHost.exe or SolarWinds.BusinessLayerHostx64.exe executables and can run dormant for up to two weeks before beaconing to a subdomain of avsvmcloud[.]com. To avoid possible detection, the C2 traffic between the beaconing server and the victim is made to resemble legitimate SolarWinds communications. This includes HTTP GET, HEAD, POST and PUT requests with JSON payloads in their bodies. The HTTP responses from the C2 server communicating with the victim contain XML data that resembles .NET assembly data used for normal SolarWinds operations. Within the XML, however, is obfuscated command information that is deobfuscated and then executed by the SolarWinds process on the victim’s system.
Impact/Result: Following the initial compromise and deployment of SUNBURST, a variety of more capable payloads can be deployed to facilitate lateral movement and data theft. Common payloads include TEARDROP and Cobalt Strike BEACON, both of which can be loaded into memory to improve stealth of operations.
Known breaches include:
FireEye: On December 8, FireEye communicated a state-sponsored security breach through which the attackers accessed FireEye’s Red Team assessment tools used to test customers’ security. Following the breach, the company made its list of countermeasures public. FireEye has now confirmed that this attack was a result of the SolarWinds Orion supply chain attack.
U.S. Treasury and the National Telecommunications and Information Administration (NTIA): On December 13, Reuters reported that Russian-associated hackers broke into the U.S. Treasury and Commerce department’s Microsoft 365 software and have been monitoring internal email traffic. Following a National Security Council meeting at the White House over the weekend, the Cybersecurity and Infrastructure Security Agency (CISA) issued an emergency directive for all federal agencies to power down SolarWinds Orion.
Organizations are frantically working to figure out if they have been a victim of the attack and how to protect themselves. Here are the immediate steps to take, according to SolarWinds, FireEye, and NetSPI’s team of offensive security experts:
First, determine if SolarWinds Orion is deployed within your environment. If unsure, NetSPI recommends performing a network scan to identify the Orion agent. For example, this can be performed with Nmap by running: nmap –open -sT -p 17778,17790 x.x.x.x/xx, where x.x.x.x is the network address and xx is the subnet mask. If the Orion agent is found, follow SolarWinds’ recommendations.
SolarWinds recommends customers upgrade to Orion Platform version 2020.2.1 HF 1 as soon as possible. It also asks customers with any of the products listed on the security advisory for Orion Platform v2019.4 HF 5 to update to 2019.4 HF 6. Additional suggestions can be found in the security advisory. While upgrading Orion will prevent future backdoored deployments from occurring, it will not remediate the potentially infected deployments that have already taken place via the Orion Platform.
On December 11, NetSPI Managing Director Nabil Hannan was featured in TechTarget:
At the end of the day, cybersecurity is a financial issue. Breaches can result in significant financial loss and reputational damage. Consider these statistics:
The global average cost of a data breach is $3.86 million, according to the
“Cost of a Data Breach Report 2020,” with the U.S. having the highest average at $8.64 million.
Another report found that insider threats are the most expensive category of attack to resolve, costing an average of $243,101. And this number is increasing.
Lastly, in just the first six months of 2020, 3.2 million records were exposed in the 10 biggest breaches – eight of the breaches occurred at medical or healthcare organizations. Healthcare was deemed the costliest industry by the “Cost of a Data Breach Report” with the average cost of a breach reaching $7.13 million.
Now forget those statistics; push them aside. While it’s important to understand the financial aftermath of a breach, security teams need to uncover more proactive methods for communicating the value of their investments with organizational leadership to get buy-in (and funding) upfront. However, communicating the return on investment (ROI) of a security program, in which the results are not always tangible, has proven to be a challenge for security leadership.
The shift to a more proactive security program assessment can only occur if the chief information security officer (CISO) first has a greater voice at the table in the boardroom. As the individual most responsible for ensuring information assets and technologies are adequately protected, the CISO can serve as a bridge between the highly technical voices in infosec and other C-suite executives who are more financially, operationally or innovation focused.
And who among the C-suite can make this shift a reality? The chief financial officer (CFO). CISOs need to establish a stronger relationship with their CFO and financial team to better communicate the value of existing, and future, security investments. Here are three ways – and reasons why – the CISO and CFO should work more closely together.
This article attempts to summarize the key details of the attack and provide some expanded information and potential attack scenarios, including how Active Directory could be compromised leveraging this attack method.
On December 10, NetSPI Security Consultant Jake Karnes was featured in Bleeping Computer:
Proof-of-concept exploit code and full details on a Windows Kerberos security bypass vulnerability have been published earlier this week by Jake Karnes, the NetSPI security consultant and penetration tester who reported the security bug to Microsoft.
The security bug tracked as CVE-2020-17049 and patched by Microsoft during November 2020’s Patch Tuesday can be exploited in what the researcher has named as Kerberos Bronze Bit attacks.
On December 10, NetSPI Security Consultant Jake Karnes was featured in ZDNet:
Proof-of-concept exploit code has been published this week for a new attack technique that can bypass the Kerberos authentication protocol in Windows environments and let intruders access sensitive network-connected services.
Named the Bronze Bit attack, or CVE-2020-17049, patching this bug caused quite the issue for Microsoft already.
The OS maker delivered an initial fix for Bronze Bit attacks in the November 2020 Patch Tuesday, but the patch caused authentication issues for Microsoft’s customers, and a new update had to be deployed this month to fix the previous issues.
On Wednesday, a day after Microsoft delivered the final patches, Jake Karnes, a security engineer at NetSPI, published a technical breakdown of the vulnerability so network defenders can understand how they are vulnerable and why they need to update, despite the patching process’ rocky start.
With the release of Microsoft’s patch to fix CVE-2020-17049, I’m excited to share details about this vulnerability and how it could be exploited. This post is only a very high-level overview, and I strongly encourage readers who are interested to check out my follow-up posts which provide much more depth:
This could be classic constrained delegation (with either the “– Use Kerberos only” or the “- Use any authentication protocol” setting).
This could also be resource-based constrained delegation.
With these prerequisites met, the attacker can authenticate to the second service as any user. This includes members of the Protected Users group and any other users explicitly configured as “sensitive and cannot be delegated.” The second service will accept and process the attacker’s requests as if they came from the impersonated user.
This attack uses the S4U2self and S4U2proxy protocols introduced by Microsoft as extensions to the Kerberos protocol used by Active Directory. The attack uses the S4U2self protocol to obtain a service ticket for a targeted user to the compromised service, using the service’s password hash.
The attack then manipulates this service ticket by ensuring its forwardable flag is set (flipping the “Forwardable” bit to 1). The tampered service ticket is then used in the S4U2proxy protocol to obtain a service ticket for the targeted user to the targeted service. With this final service ticket in hand, the attacker can impersonate the targeted user, send requests to the targeted service, and the requests will be processed under the targeted user’s authority.
This attack is made possible because the forwardable flag is only protected by encrypting the service ticket with the first service’s password hash. Having already obtained the hash, the attacker is free to decrypt the service ticket, flip the bit to set the forwardable flag, and then re-encrypt the ticket. Unlike the PAC, targeted in the MS14-068 attack, there is no signature in this portion of the ticket to detect tampering.
This exploit bypasses 2 existing protections for Kerberos delegation, and provides an opportunity for impersonation, lateral movement, and privilege escalation. Because this is accomplished by flipping a single bit, and in the spirit of the Golden Ticket and Silver Ticket attacks, I’ve dubbed this the Bronze Bit attack.
If you’d like try the exploit in your own environment, it has been implemented as addition to the Impacket framework with a pull request pending. Of course, this will have to be tested in a controlled environment with an unpatched domain controller. I recommend checking out the Practical Exploitation post for further details on how the exploit can be used.
Of course, any new research is built on the great work of many others. I’d like to thank the following individuals in particular for publishing their own research and for helping me with this finding:
I’ll acknowledge upfront that Kerberos is a complex protocol with many extensions, options and details. Of course, all of these are very important when discussing a security system but they cannot all be captured in a blog post. The explanations below provide a simplified view of Kerberos and Active Directory, focusing on the key points to understand the discovered weakness and its exploit.
Kerberos is a protocol used in Windows Active Directory to authenticate users, servers and other resource to each other within a domain. Kerberos is based on symmetric key cryptography where each principal has a long-term secret key. This secret key is only known by the principal themselves and the Key Distribution Center (KDC). In an AD environment, the domain controller performs the role of the KDC. In the illustration below, we can see the KDC has a copy of the user’s key, the service’s key, and its own key.
With its knowledge of each principal’s secret key, the KDC facilitates authentication of one principal to another by issuing “tickets.” These tickets contain metadata, authorization information and additional secret keys which can be used with future tickets. Let’s explore how these tickets are created and used by principals to authenticate to each other.
Authentication Service Exchange
Before principals can authenticate to each other, they must authenticate themselves to the KDC. Let’s take look at the process of a user authenticating themselves to the KDC through the “Authentication Service Exchange.”
The user derives their secret key by hashing their password. The secret key is used to encrypt a timestamp, which is sent to the KDC along with their username. Based on the username, the KDC gets its copy of the secret key for that user. The KDC then decrypts the timestamp. If the decryption is successful, this proves that the user has access to the secret key. If the timestamp were encrypted with any other key, it wouldn’t decrypt successfully with the user’s key. And if the timestamp is recent, it proves that this isn’t a replay attack (i.e. the user isn’t sending some old, captured encrypted timestamp). If the user is using a smartcard or Windows Hello for Business instead of a password, the user and KDC will establish key agreement via ephemeral Diffie-Hellman instead of the encrypted timestamp, but the rest of the Kerberos process will remain the same.
Once the checks pass, the KDC will create a new random logon session key, and send back an “AS_REP” reply. This AS_REP is a pretty complex data structure, so let’s consider a simplified representation:
The “cname” field contains the username in plaintext. The rest of the data is split into two halves, each encrypted with a different key. The first “enc-part” section of the response is encrypted with the user’s secret key. Only the user themselves can read these contents. It contains some metadata (such as “flags” and “sname” fields), and the logon session key that the KDC generated.
The last section is called the “Ticket-Granting Ticket” or TGT. This is encrypted with the KDC’s secret key which means the user cannot read the contents of this section.
The user can extract the logon session key from the readable “enc-part” and the TGT from the AS_REP, and save these in their key cache for later user. The TGT can now serve as evidence that this user has already been authenticated by the KDC. I like to think of the TGT like the stamp you get on your hand when leaving an amusement park. The fact that your hand is stamped shows you were already allowed to be inside, so they’ll let you back in without buying another pass.
The TGT is a very powerful authentication artifact which enables the user to prove their identity and obtain access to other services within the domain. If an attacker had access to the KDC’s secret key, they could forge these tickets to impersonate any user to any other service. This is known as a Golden Ticket attack discovered by Benjamin Delpy.
Ticket-Granting Service Exchange
After obtaining the logon session key and TGT, the user can now obtain tickets for other specific services through the Ticket-Granting Exchange:
The user begins by encrypting another timestamp, but now using the logon session key rather than their secret key. This encrypted timestamp is sent to the KDC, along with the TGT and which service the user is requesting a ticket for. The KDC decrypts the TGT using its secret key and extracts the logon session key. The KDC then confirms the user’s encrypted timestamp using the logon session key and, if the checks pass, will generate a new random service session key. The KDC sends back a “TGS_REP” reply and the exchange is complete.
Let’s inspect that TGS_REP data structure as we did before:
The data structure is the same as the AS_REP, with some important differences in the values. The “enc-part” is now encrypted with the logon session key and contains the new service session key. The user can decrypt the “enc-part” using the logon session key from the key cache, extract the service session key and save it alongside the service ticket in the key cache.
The service ticket is encrypted with the service’s long-term secret key and therefore can only be read by the service and KDC who have the service’s secret key, not the user. You’ll notice that its structure looks the same as the TGT, and that’s no accident. The TGT is just a service ticket to the KDC’s Ticket Granting Service. Let’s take a closer look at those parts within the service ticket:
Session key: The service session key generated by the KDC which will be shared by both the user and the service.
Flags: A collection of binary values (only 0 or 1) which provide metadata for the ticket. The “Forwardable” flag is one of several available flags and will be discussed in detail later.
“cname”: The client name (i.e. an identifier for the user associated with this service ticket).
PAC: The user’s authorization data in a structure known as the privilege attribute certificate or PAC. This contains additional user metadata such as their group memberships. The PAC contains two cryptographic signatures. One signature created with the service’s key and the other created with the KDC’s key. Because of these dual signatures, the PAC is effectively tamper-proof.
It’s also worth noting that the “sname” field (which identifies the service’s name) is not in the encrypted service ticket. This allows for interesting sname substitution attacks as first described by Alberto Solino.
With a service ticket and a service session key, the user is finally ready to authenticate to the service.
I think we can see the familiar pattern here. A timestamp is encrypted with the service session key, and sent from the user to the service along with the service ticket. The service decrypts the ticket with its long-term key. This proves the ticket came from the KDC, since only the KDC and the service itself should have the long-term key to create such a service ticket. The service session key is extracted from the service ticket and used to validate the timestamp.
The service will then use its long-term key to check the signature of the PAC. This provides the user’s authorization upfront, so the service doesn’t need to fetch it from the KDC. Optionally, the service may choose to send the PAC to the KDC, so that the KDC may validate the second signature against the KDC’s key. If performed, this optional check verifies that the PAC has not been altered from when it was first created by the KDC and helps prevent attempts to forge the PAC and escalate privileges.
Once these checks are performed and passed, the user has successfully authenticated to the service, the service is aware of the user’s authorization, and the user may proceed with any requests.
Like the TGT, if an attacker can forge a valid service ticket to a particular service, then it can impersonate any user and authenticate to that service. This is known as a “Silver Ticket” attack and requires knowledge of the service’s secret key. A popular technique for obtaining a service’s secret key is “Kerberoasting” discovered by Tim Medin. However, this attack is thwarted if the service performs the optional step of sending the PAC to the KDC. The KDC will observe that its signature for the PAC is incorrect (because the attacker doesn’t have the KDC’s secret key), and it will report that error back to the service which will reject the service ticket.
Now that we understand the fundamentals of how Kerberos authenticates a user to a service, consider the following: what if that service wants to send requests to another service on the user’s behalf? A common scenario would be when a user authenticates to a web application, and that web application needs to access a database under the user’s authority. The database controls whether a given user is allowed to access a particular record. When the web application attempts to access a database record, it must carry the user’s authorization in the request to allow the database to determine if the request should be allowed or denied. This is sometimes referred to as the “double-hop” scenario.
For our examples going forward, “Service1” will be the service which the user is directly authenticated to, and “Service2” will be the additional service which needs to be accessed under the user’s authority.
This problem is addressed through “Kerberos delegation” which allows Service1 to impersonate the user and interact with Service2 as if the requests came directly from the user. There are several types of Kerberos delegation supported in Active Directory which will be discussed in detail below:
The following screenshot captures where most of the delegation configuration lives in Active Directory:
Although the vulnerability doesn’t impact this configuration, unconstrained delegation should be avoided. Let’s consider that Service1 has been configured for unconstrained delegation with the “Trust this computer for delegation to any service (Kerberos only)” setting above. When a user obtains a service ticket to Service1, the KDC will embed the user’s TGT into the service ticket. When the service ticket is passed to Service1, the service can extract the TGT. With access to the user’s TGT, Service1 can perform the Ticket-Granting Service Exchange, and obtain service tickets as the user to any other service. This allows complete impersonation of the user.
Issues arising from unconstrained delegation are well-known and have been discussed thoroughly by Will Schroederhere and Sean Metcalfhere. Since this is no longer recommended, may not even be supported, and not directly related to the vulnerability, I’ll refer you to those great resources for a deeper dive.
Due to the potential issues with unconstrained delegation, Microsoft introduced the concept of “constrained delegation” in its Windows Server 2003 release, and published [MS-SFU]: Service for User and Constrained Delegation Protocol as a public specification and Kerberos extension in 2007. Unlike unconstrained delegation, the extension would allow for services’ delegation targets to be predefined. Using our running example, it could be configured that Service1 is only allowed to delegate to Service2, instead of every service in the domain. When the user obtains a service ticket for Service1, the KDC would no longer embed the user’s TGT into the service ticket.
Constrained Delegation without Protocol Transition
Let’s consider that a user has authenticated to Service1 through Kerberos, passing their service ticket, and now Service1 needs to access Service2 under the user’s authority. Because the user’s service ticket is specific to Service1, it would be rejected if passed directly to Service2. Without the user’s TGT, Service1 cannot obtain a service ticket to Service2 from the KDC. So how does the Service1 authenticate to Service2 as the user?
The MS-SFU specification solves this problem through the “Service for User to Proxy” (S4U2proxy) protocol. The S4U2proxy protocol allows Service1 to obtain a service ticket to Service2 as the user, by sending the KDC the service ticket it received from the user, along with Service1’s own TGT. The KDC will reply with a “TGS_REP” including a service ticket which valid for Service2, authorized as the user. Once Service1 has a service ticket as the user to Service2, it can proceed with the same Client/Server exchange as before. After that exchange is complete, Service2 will process the requests from Service1 as if they came from the user themselves.
The S4U2proxy protocol allows for constrained delegation “without protocol transition” because the Kerberos protocol is used for every step. All principals are authenticated to each other through Kerberos and its ticket exchanges.
Constrained Delegation with Protocol Transition
What if the user authenticated to Service1 by a protocol other than Kerberos? For example, Service1 may have authenticated the user through NTLM v2 Authentication. If Service1 then needed to delegate that authentication to Service2, it would be unable to do so. The user never presented a service ticket to Service1, so Service1 cannot pass that service ticket to the KDC in the S4U2proxy protocol. In this case, Service1 would need to perform a “protocol transition” using the second protocol provided in the MS-SFU specification: the “Service for User to Self” (S4U2self) protocol.
The S4U2self protocol allows a service to obtain a service ticket to itself on behalf of any user. The protocol is a modification of the Ticket-Granting Exchange. Service1 presents its own TGT and timestamp encrypted with its logon session key to the KDC and specifies which user it would like a ticket for. The KDC processes the request, performing the same validations as before, and returns a service ticket for Service1 which identifies the specified user as the client in the “cname” field.
Now that Service1 has obtained a service ticket to itself, it can present this ticket as evidence to in the S4U2proxy exchange and obtain a service ticket to Service2 on the user’s behalf.
It’s important to note that a service can obtain a service ticket to itself on behalf of any user through the S4U2self protocol. The service is not required to present any evidence that the user has actually authenticated to the service.
Resource-Based Constrained Delegation (RBCD)
When Microsoft first introduced the concept of Kerberos constrained delegation, it was only possible to define a list of services which a specified service could delegate to. For example, a domain admin could specify that ServiceA is allowed to delegate Kerberos authentication to ServiceB, ServiceC and ServiceD. The list of delegation targets would be configured in the “AllowedToDelegateTo” property of ServiceA in Active Directory.
Resource-based Constrained Delegation flips this model. Introduced in Windows Server 2012, RBCD lets a service define which other services it accepts delegated Kerberos authentication from. For example, a privileged user (not necessarily a domain admin) could specify that ServiceW accepts delegated Kerberos authentication from ServiceX, ServiceY and ServiceZ. This list would configured in the “PrincipalsAllowedToDelegateToAccount” property of ServiceW in Active Directory.
After the introduction of RBCD, the existing constrained delegation became unofficially known as “classic” constrained delegation.
Protections Within Constrained Delegation
While the scope is more narrow than unconstrained delegation, constrained delegation still allows for the impersonation of users and therefore needs strong security controls to limit its potential impact if abused. Microsoft provides a variety of configuration options to balance security and functionality.
Allowing and Disallowing Protocol Transition
When using “classic” constrained delegation, the sysadmin must decide if the service is allowed to perform the “protocol transition” described previously. If so, the service will be permitted to impersonate users who haven’t already been authenticated through Kerberos. This trusts that the service will only impersonate users who it has authenticated through another mechanism.
If the service is trusted for constrained delegation with protocol transition, then the “TrustedToAuthForDelegation” property in Active Directory is enabled. This corresponds to the “Trust this computer for delegation to specified services only – Use any authentication protocol” option in the AD GUI.
If the service is trusted for constrained delegation without protocol transition, then the “TrustedToAuthForDelegation” property in Active Directory is not enabled but the AllowedToDelegateTo list is still populated with delegation targets. This corresponds to the “Trust this computer for delegation to specified services only – Use Kerberos only” option in the AD GUI. This restriction is enforced by the S4U2self protocol. While any service can perform the S4U2self exchange to obtain a service ticket to itself as any user, if protocol transition is not allowed then the resulting service ticket will have its Forwardable flag set to 0. When a service ticket with a Forwardable flag of 0 is passed in the subsequent S4U2proxy exchange, the exchange will fail.
Effectively, “TrustedToAuthForDelegation” allows a service to use both the S4U2self and the S4U2proxy protocols successfully. If a service is not “TrustedToAuthForDelegation” but has a non-empty AllowedToDelegateTo list, then the service may use S4U2self successfully, but the service can only pass forwardable tickets to S4U2proxy. The service should only obtain forwardable tickets from users that have already authenticated through Kerberos with the KDC directly, preventing impersonation.
Protected Users and Sensitive Accounts
Services aren’t the only principals with security restrictions applied. Users and other AD accounts can be configured to disallow delegation of their authentication. This means that even if a service is allowed to perform delegation (of any kind), the service cannot delegate and impersonate the user. There are two ways of protecting an account from delegation.
First, a sysadmin can enable the “Account is sensitive and cannot be delegated” setting in Active Directory for the account. The screenshot below shows how this is displayed in the AD GUI.
The second option is to add the account to the “Protected Users” security group in AD. Any members of this group may not have their authentication delegated, and there are other protections as well.
Like the “Use Kerberos only” restriction discussed in the previous section, this protection is enforced by ensuring that all tickets issued for these users are not forwardable. When a ticket is created for a user with the “account is sensitive and cannot be delegated” setting, or if the user is a member of the “Protected Users” group, then the Forwardable flag value will always be 0. A service can still obtain a ticket for these users to itself through the S4U2self protocol, but since the ticket is not forwardable, it cannot be successfully used in the S4U2proxy protocol to obtain a ticket for another service.
Enforcing Constrained Delegation Lists
Of course, the KDC must also enforce the constrained delegation lists discussed previously. This is only applicable during the S4U2proxy protocol. Let’s return to our example of Service1 attempting to delegate authentication to Service2. During the S4U2proxy protocol, the KDC will confirm that Service2 is in Service1’s “AllowedToDelegateTo” list (allowing “classic” constrained delegation) or that Service1 is in Service2’s “PrincipalsAllowedToDelegateToAccount” list (allowing resource-based constrained delegation). If neither of those conditions are met, then the exchange fails. This prevents a service from performing constrained delegation to another, unless one of them have been explicitly configured for that.
The Big Picture
Now that we’ve covered the fundamentals of Kerberos, constrained delegation, and its protections, let’s bring all of this together. Let’s consider that Service1 wants to authenticate to Service2 as another user, but the user has not already authenticated to Service1 through Kerberos.
Service1 starts with the standard Authentication Service exchange. Like before, it encrypts a timestamp with its long-term secret key to prove its identity. The KDC validates the timestamp, returns a logon session key and a ticket-grant ticket (TGT) in an AS_REP response.
Service1 extracts the logon session key and TGT from the AS_REP, then continues to the S4U2self exchange. Service1 encrypts another timestamp with the logon session key. Service1 sends the encrypted timestamp, its TGT and the target user’s name to the KDC, requesting a ticket to itself through the S4U2self protocol. The KDC will validate the incoming TGT and timestamp. If this passes, the KDC prepares a service ticket for the specified user to Service1. Initially, the service ticket’s forwardable flag is set (i.e. Forwardable=1).
The KDC will check if Service1 has the “TrustedToAuthForDelegation” property set. If not, the service’s ticket forwardable flag is set to 0. The KDC will also check if the target user is protected from delegation. If the user is a member of the “Protected Users” group or configured with the “Account is sensitive and cannot be delegated” setting, then the forwardable flag in the service ticket is set to 0.
The KDC returns the new service ticket to Service1. Service1 now has a valid ticket as the user to itself, which may or may not be forwardable.
Service1 is now ready for the final step: the S4U2proxy Exchange. Service1 presents the service ticket it received back to the KDC as proof of the user’s authentication to Service1, and Service1 requests a new service ticket to Service2 as the user. The KDC begins by confirming that there is a delegation trust relationship between Service1 and Service2. It checks if Service2 is in Service1’s “AllowedToDelegateTo” list. If so, a classic constrained delegation trust relationship is confirmed. If not, the KDC checks if Service1 is in Service2’s “PrincipalsAllowedToDelegateToAccount” list. If so, a resource-based constrained delegation trust relationship exists. If both checks fail, the exchange fails with an error.
After confirming that Service1 is allowed to delegate authentication to Service2, the KDC decrypts the received service ticket using Service1’s long-term secret key and checks the Forwardable flag. If the service ticket’s Forwardable flag is set to 0, the KDC will perform additional checks and exchange will fail with an error. If the Forwardable flag is set to 1, the KDC will return a new service ticket which is valid for Service2 as the target user.
Spot the Problem
There you go! You now have all the information necessary to spot what it wrong in this authentication protocol. If you’d like, take a second to review the information covered so far and see if you can find the vulnerability. When you’re ready, continue down to the next section.
Flipping Bits for Fun and for Profit
Let’s take a closer at the TGS_REP data structure returned by the KDC after the S4U2self exchange. Consider the scenario where Service1 is not “TrustedToAuthForDelegation” or the specified user is protected from delegation (because it is a member of the “Protected Users” group or it is configured with the “Account is sensitive and cannot be delegated” setting). Here’s how that TGS_REP could look:
Because of the protections in place, the Forwardable flag is not set (i.e. its value is 0). This means that the service ticket would be rejected if used as proof in the S4U2proxy exchange.
Look closely at where the Forwardable flag is located in the response. The service ticket’s Forwardable flag is encrypted with Service1’s long-term. The Forwardable flag is not in the signed PAC. Service1 is free to decrypt, set the Forwardable flag’s value to 1, and re-encrypt the service ticket. Because it’s not in the signed PAC, the KDC is unable to detect that the value has been tampered with.
Voila! We have converted a non-forwardable ticket into a forwardable ticket. This forwardable service ticket can be provided as proof in the S4U2proxy exchange, allowing us to delegate authentication to Service2, as any user of our choice.
We’ve bypassed the protection for TrustedToAuthForDelegation and the “Trust this computer for delegation to specified services only – Use Kerberos only” configuration. This protection is enforced by ensuring that any service ticket received in the S4U2self exchange is non-forwardable, unless the requesting service is TrustedToAuthForDelegation. By setting the forwardable flag ourselves, we’ve effectively removed this distinction and enabled the service to perform the protocol transition, as if the service were configured with the “Trust this computer for delegation to specified services only – Use any authentication protocol” option.
We’ve also bypassed the protection for accounts which do not allow delegation. Again, this is enforced by ensuring that any service ticket received in the S4U2self exchange on behalf of a protected account is non-forwardable. By converting this to a forwardable service ticket, the service can now delegate the account’s authentication as if there was no such protection.
Microsoft has released multiple patches throughout November and December 2020 to fix this vulnerability. The various patches can be found in the MSRC Security Update Guide for CVE-2020-17049 and their rollout plan and advice can be found here.
Because the “Service for User and Constrained Delegation Protocol” (MS-SFU) is an open specification, we can get a good idea of how the fix was implemented. MS-SFU revision 19.0 published on November 23, 2020 now contains the underlined addition to section 126.96.36.199.2:
Service 1’s KDC verifies both server ([MS-PAC] section 2.8.1) and KDC ([MS-PAC] section 2.8.2) signatures of the PAC. Because Service 1’s KDC is ingesting a service ticket rather than a TGT, it SHOULD also ensure the integrity of the service ticket by verifying the ticket signature ([MS-PAC] section 2.8.3). If Service 2 is in another domain, then its KDC verifies only the KDC signature of the PAC.
The specification now references a “ticket signature” which should be verified by the KDC along with the existing PAC. Let’s look at that referenced section of the MS-PAC specification. We can see that revision 20.0 was published on the same day and added Section 2.8.3. I think the following snippet of that section best captures the core change:
The ticket signature is used to detect tampering of tickets by parties other than the KDC. The ticket signature SHOULD be included in tickets that are not encrypted to the krbtgt account (including the change password service) or to a trust account. The KDC signature is a keyed hash [RFC4757] of the ticket being issued less the PAC itself.
The key takeaway for us is that the PAC now has an additional field which holds the “ticket signature.” When the service ticket is produced during the S4U2self exchange, the KDC signs the ticket contents with its secret key and inserts the signature into the PAC. As discussed previously, the PAC itself is also doubly signed with the KDC’s secret key and the service’s key. Later when the KDC receives the service ticket during the S4U2proxy exchange, the KDC can validate all three signatures to confirm that the PAC and the service ticket have not been modified. If the service ticket is modified (for example, if the the forwardable bit has changed), the KDC will detect the change and reject the request with an error such as “KRB_AP_ERR_MODIFIED(Message stream modified).”
During our penetration testing engagements, we frequently hear from clients that it is difficult to manage the large volume of vulnerabilities we discover. While on the one hand, this is what we are hired to do, for our clients, it poses some challenges. Now, with Penetration Testing as a Service (PTaaS) we’ve made it easier than ever to consume, understand, and manage the large number of results we deliver to our clients with our penetration tests. And with PTaaS+, we’ve extended those benefits by directly integrating with your ticketing systems and allowing you to perform the full remediation lifecycle inside of Resolve™, our threat and vulnerability management platform.
What are you supposed to do when NetSPI isn’t the only source of vulnerability discovery for your organization? It’s extremely important to correlate and deduplicate vulnerabilities from all your data sources, not only to reduce noise but to save frustration from your engineering teams by reducing duplicates and false positives, and providing consistent, up-to-date guidance.
PTaaS Pro solves this problem by providing Resolve’s full suite of Threat and Vulnerability Management capabilities to our penetration testing clients. PTaaS Pro is an extremely valuable tool for security programs of all sizes, and provides many benefits, including:
Manage Internal and Third-Party Vulnerabilities
PTaaS Pro gives you the ability to manage all your organization’s vulnerabilities, not just those that NetSPI discovers. Yes, that even means vulnerabilities discovered by our competition. Resolve can integrate with over 30 vulnerability scanners, your CMDBs, and all your internal ticketing systems to have a consolidated warehouse for all vulnerabilities.
Reduce In-house Penetration Testing Times by up to 30 Percent
Resolve is a powerful tool for internal penetration testing teams, allowing them to coordinate project management for tests, standardize and enforce processes through checklists, correlate and deduplicate their automated and manual findings, and generate reports with the click of a button. One of the reasons NetSPI performs the highest quality penetration testing in the industry is because Resolve removes the hassle from testing, allowing your team to focus on finding vulnerabilities.
We’re More Than a Vendor – We’re You’re Partner
When launching PTaaS Pro with your organization, NetSPI connects you with our team of industry experts, including former CISOs, vulnerability managers, and security experts. Together we work to integrate Resolve and NetSPI into your security processes. Every step of the way you’ll have access to first-hand experience and guidance on how to optimize and improve your security program.
Necessary cookies help make a website usable by enabling basic functions like page navigation and access to secure areas of the website. The website cannot function properly without these cookies.
YouTube session cookie.
Marketing cookies are used to track visitors across websites. The intention is to display ads that are relevant and engaging for the individual user and thereby more valuable for publishers and third party advertisers.
Analytics cookies help website owners to understand how visitors interact with websites by collecting and reporting information anonymously.
Preference cookies enable a website to remember information that changes the way the website behaves or looks, like your preferred language or the region that you are in.
Unclassified cookies are cookies that we are in the process of classifying, together with the providers of individual cookies.
Cookies are small text files that can be used by websites to make a user's experience more efficient. The law states that we can store cookies on your device if they are strictly necessary for the operation of this site. For all other types of cookies we need your permission. This site uses different types of cookies. Some cookies are placed by third party services that appear on our pages.