During red team engagements over the last few years, I’ve been curious whether it would be possible to authenticate to cloud services such as Office365 via a relay from New Technology Lan Manager (NTLM) to Active Directory Federation Services (ADFS). If possible, this would unlock an entirely new attack surface for NTLM relaying attacks as it would allow an attacker to pivot to cloud-hosted applications and services. In this article, I detail the process I used for investigating the feasibility of these attacks, share the ultimate result, and discuss the inner workings of NTLM and extended protection for authentication. Praetorian also has developed and is releasing an open source tool ADFSRelay and NTLMParse, which can be used for performing relaying attacks targeting ADFS and analyzing NTLM messages respectively.
Understanding ADFS Authentication Methods
ADFS supports a variety of authentication methods ranging from certificate and device-based to traditional forms-based . For internal users, ADFS also supports an authentication method called Windows Integrated Authentication (WIA). This particular option leverages NTLM along with the NTLM over HTTP protocol to perform authentication seamlessly without requiring the user to enter their username and password.
Several other factors compound the risk of this problem. Many companies do not require multi-factor authentication when the user authenticates from the internal network environment. At the same time, even though many companies leverage tiered accounts separation for Active Directory domain administrator accounts, they often grant the user’s standard account high-level administrative rights within cloud environments such as AWS or Azure.
Additionally, suppose the end-user is leveraging a web browser that uses the Microsoft WinHTTP library, such as Microsoft Edge or Google Chrome. In that case, their browser will automatically perform NTLM authentication to any site the browser classifies as being a trusted intranet site. Unfortunately, it is often trivial for an attacker with a foothold within the environment to create a scenario where they control a subdomain classified as a trusted site.
Ultimately, when combined, these factors prompted my interest in further researching the potential for ADFS relaying attacks. The following section discusses a scenario wherein an attacker could combine these issues to gain access to data within enterprise SaaS applications or cloud environments such as AWS or Azure.
Analyzing the Windows Integrated Authentication Flow
ADFS allows clients to authenticate using NTLM authentication through the WIA mechanism, which I discovered is identical to the MS-NTHT  (NTLM over HTTP) authentication protocol. The NTLM authentication process is quite simple and sends three types of messages as shown in Figure 1. First the client sends a “negotiate message” to the server to initiate authentication. The server then responds with a “challenge message” indicating a challenge for the client to complete. Finally, the client completes the challenge by sending an “authenticate message” to the server.
Figure 1: Diagram of NTLM’s simple authentication process.
Let’s begin by walking through the authentication process in an HTTP proxy to better understand how the ADFS sign-in flow works. First, we begin the authentication process by selecting “Sign in to this site” on the ADFS login page as shown in Figure 2:
Figure 2: ADFS sign in page.
The client’s web browser then sends a POST request to the /adfs/ls/idpinitiatedsignon.aspx endpoint with the parameters and request body shown in Figure 3.
Figure 3: POST request from the web browser to sign-in endpoint.
The ADFS server responds to this POST request by redirecting the client to /adfs/ls/wia?client-request-id=$GUID. The server returns a response of “HTTP/1.1 401 Unauthorized” with the “WWW-Authenticate” header set twice, once with the value NTLM and again with the value of Negotiate. Note that WIA can only be performed from internal systems and that ADFS determines when to use WIA by implementing a set of configurable rules that look at the client’s user agent. (See Figure 4.)
Figure 4: The client being redirected to the WIA authentication endpoint.
At this point, the client browser is aware that the server has requested NTLM authentication using MS-NTHT to access a given resource. However, this does not mean that the client will authenticate using that mechanism. Instead, the client follows some rules for security purposes to determine if it should automatically use NTLM authentication. For web browsers such as Google Chrome and Internet Explorer that leverage the Microsoft WinHTTP library, this happens automatically based on a trusted sites configuration and some built-in rules surrounding Intranet site classification. We’ve discussed this in detail in a previous article titled “How to Exploit Active Directory ACL Attack Paths Through LDAP Relaying Attacks”.
In this scenario, we assume the client trusts the site requesting authentication and sends an NTLM NEGOTIATE_MESSAGE through the “Authorization” header. Since NTLM is a binary protocol the message is both encoded with base64 so it can be transported over an HTTP connection and prefaced with NTLM to specify the authentication protocol used. The server responds with an NTLM CHALLENGE_MESSAGE encoded in the same manner, including the server challenge used in the challenge response authentication mechanism.
In figure 5, the client sends a NEGOTIATE_MESSAGE to the server:
Figure 5: Client’s NEGOTIATE_MESSAGE.
For the server’s response with a CHALLENGE_MESSAGE sent to the client, see figure 6:
Figure 6: Server’s CHALLENGE_MESSAGE.
Finally, the client completes the last part of the authentication handshake which involves computing the AUTHENTICATE_MESSAGE from the server challenge and a client challenge (if using NTLMv2) provided by the server. The generated AUTHENTICATE_MESSAGE is then encoded and again sent through the “Authorization” header in the same manner as the NEGOTIATE_MESSAGE sent at the beginning of the authentication process. At this point, the ADFS server can authenticate the client user. Figure 7 shows the AUTHENTICATE_MESSAGE sent by the client to the server:
Figure 7: Client’s AUTHENTICATE_MESSAGE.
Circumventing the Channel Binding Token
However, we see something unexpected in the response. The server responds with an HTTP 401 response. What went wrong? Authentication fails in this scenario because we are intercepting the requests to the ADFS server with Fiddler. The NTLM client adds a channel binding token to the AUTHENTICATE_MESSAGE when authenticating over a TLS connection. The ADFS server uses this channel binding token to compute the channel binding token for the current connection and realizes we are performing a man-in-the-middle attack. This is important to understand for later scenarios where we analyze the Extended Protection for Authentication mechanism which can be leveraged to prevent relaying attacks. Figure 8 shows the response returned by the ADFS server:
Figure 8: ADFS server’s response.
To investigate further I manually analyzed the captured NTLM handshake and then wrote a tool in Go (NTLMParse, included with ADFSRelay) to automatically decode an input NTLM message and display the corresponding fields and values present within the message. Within the AUTHENTICATE_MESSAGE message, the NtChallengeResponseFields includes a list of structures referred to as an AV_PAIR in the NTLM specification . The AV_PAIR structure is very simple and includes an AvId which specifies the type of data stored within the AV_PAIR, the length of the data within AvLen, and then the raw data appended after the structure in AvData.
One of the AvId options is MsvAvChannelBindings, a channel binding token leveraged to tie an NTLM authentication to a TLS channel . This is very similar to certificate pinning used within mobile applications. In this scenario, I was intercepting traffic with Fiddler and the ADFS server identified the presence of a channel binding token in the NTLM packet. Fiddler was MITMing the connection, so the security check failed as did authentication. Figure 9 shows the channel binding token specified within the message:
Figure 9: Channel binding token.
This functionality is used to implement the extended protection for authentication (EPA) functionality that prevents relaying attacks. We will discuss EPA in more detail in a subsequent section. To confirm my hypothesis on why the attack wasn’t working I temporarily disabled EPA completely on the ADFS server using PowerShell. (See Figure 10.)
Figure 10:Using PowerShell to completely disable EPA on the ADFS server.
Now, with EPA disabled, I can authenticate to the ADFS server successfully as shown in Figure 11. This test confirmed my hypothesis that channel binding was ultimately causing the authentication to fail.
Figure 11: Successful authentication to ADFS server.
The ADFS server returns some session cookies to the user and then redirects the user to the main page. Now we are authenticated successfully. (See Figure 12.)
Figure 12: Successful authentication.
In the previous section, we learned that EPA leverages the channel binding functionality within NTLMv2 to mitigate NTLM relaying attacks targeting HTTP services such as ADFS. EPA ultimately supports three settings, as follows:
- None: The None setting does not verify any channel binding tokens even if they are present within the NTLM AUTHENTICATE_MESSAGE sent by the client.
- Allow: The Allow setting verifies a channel binding token if it is specified within the NTLM AUTHENTICATE_MESSAGE sent by the client.
- Require: The Require setting requires a channel binding token if it is specified within the NTLM AUTHENTICATE_MESSAGE sent by the client and verifies the token.
Digging Further Into EPA
Next, I decided to develop a tool to perform an NTLM relaying attack targeting ADFS. This tool would use the previously analyzed sign-in flow to authenticate to ADFS and obtain session cookies to access any ADFS site. I assumed that as long as the NTLM authentication came from a client that did not connect over a TLS channel, I could relay this authentication to ADFS with the default EPA setting of “Allow” configured. Unfortunately, I later discovered a few barriers that significantly hindered the usefulness of this attack under the default “Allow” configuration.
Ultimately, I discovered that on Windows 10, the NTLM SSPI sets a channel binding token of all zeros when the authentication occurs over a non-TLS connection. From my research, I found that when we relay this authentication to the ADFS server, it triggers EPA and rejects the authentication.
Initially, I thought this wouldn’t be the case, as the NTLM specification mentions, “An all-zero value of the hash is used to indicate the absence of channel bindings” (see Figure 13). This sentence gave me the impression that if the client set the channel binding token to all zeros, the authentication would still be allowed under EPA’s “Allow” setting.
Figure 13: NTLM channel bindings documentation.
However, after doing some more research, I discovered an MSDN forum post  where a Microsoft employee states that the presence of a CBT token of all zeros is considered proof that the client is aware of EPA and must include CBT. (See Figure 14.) Unfortunately, this severely limits the usefulness of relaying attacks targeting ADFS under the default “Allow” configuration as modern clients are aware of CBT and include a CBT token of all zeros when the authentication does not occur over a TLS channel.
Figure 14: Response from Microsoft employee.
Analyzing the FireFox Native NTLM Implementation
At this point, I became curious about how non-Windows implementations of NTLM behaved. To accomplish this, I analyzed an NTLM AUTHENTICATE_MESSAGE generated when authenticating to ADFS using Firefox, which appears to leverage an internal implementation of NTLM on macOS. The client did not include a channel binding token, so relaying was possible in this scenario when I configured EPA with the default “Allow” setting.
Analyzing an SMB NTLM Authentication Message
I was also curious if non-HTTP uses of NTLM still included the CBT token. For example, would an attacker be able to relay an NTLM authentication over SMB to ADFS under the default allow configuration? Unsurprisingly, the client still sets a zero CBT token (since it is EPA/CBT aware), which prevents relaying under the default allow configuration.
How often is EPA completely disabled on ADFS?
These findings then beg the question of how often customers actually disable EPA for ADFS within their environments. In an attempt to answer this question, I performed some brief research and identified an article from AgileIT detailing instructions for disabling extended protection within ADFS . This article recommends disabling EPA when leveraging reverse proxies to access ADFS. I’ve included the relevant snippet from this article in Figure 15:
Figure 15: Guidance to disable EPA when using reverse proxies.
My research also uncovered another article from Paul Williams  indicating that EPA had to be disabled in one scenario because Google Chrome didn’t properly implement it. See Figure 16 for the relevant snippet. I hypothesize they disabled it as a temporary workaround and then never re-enabled within certain environments..
Figure 16: Guidance to disable EPA for ADFS in Google Chrome.
Yet another post indicates an organization disabled EPA on ADFS  when they leveraged an F5 load balancer with decryption. (See Figure 17.)
Figure 17: Guidance to disable EPA when leveraging an F5 load balancer.
Guide to Using ADFSRelay and NTLMParse
In this section we explain how to use our NTLMParse utility to analyze NTLM messages. We also provide instructions for performing NTLM relaying attacks targeting ADFS using the ADFSRelay utility we have developed. Please note that these tools are generally meant to be proof-of-concept grade utilities and not fully weaponized/operationalized tooling.
This tool simply needs to be passed a base64-encoded NTLM message and it will decode the relevant fields and structures within the message. (See Figure 18.)
Figure 18: Decoding an NTLM AUTHENTICATE_MESSAGE using NTLMParse
ADFSRelay’s single required argument is the URL of the ADFS server to target for an NTLM relaying attack. Three optional arguments are -debug to enable debugging mode, -port to define the port the service should listen on, and -help to display the help menu. Figure 19 shows an example help menu:
Figure 19: A help menu from ADFSRelay.
In this scenario we have configured EPA to None (see Figure 20), and are assuming one of the referenced scenarios applies. For example, perhaps the customer disabled EPA as a workaround for the 2015 Google Chrome bug mentioned previously and then never re-enabled EPA in the future.
Figure 20: EPA set to None.
Next, we execute the ADFSRelay utility and specify the -targetSite URL as our target ADFS server (e.g. https://sts.contoso.com). (See Figure 21.)
Figure 21: Invoking the ADFSRelay utility targeting my local ADFS server.
To simulate an authentication from a client we open our web browser, browse to http://localhost:8080, and enter some valid domain user credentials. After authenticating we see that the relaying attack was successful and we are provided with session cookies in a format which can be imported within the “Cookie Editor” browser extension available for Google Chrome and Firefox. See Figure 22 for the expected output:
Figure 22: Successful authentication yields session cookies.
Next, we browse to the ADFS login page and leverage the cookie editor extension to import the cookies. (See Figure 23.)
Figure 23: Importing cookies with the cookie editor extension.
After importing the cookies we refresh the page and see that we are now authenticated to the ADFS portal, as demonstrated in Figure 24.
Figure 24: Successful authentication to ADFS.
Next, we can browse to outlook.office365.com and enter the email address associated with our compromised user account session. This allows us to authenticate to Office365 and access the user’s email addresses. In this case, we can see an email I sent to my testing user account in Figure 25:
Figure 25: Viewing a message I sent to the victim’s email address.
The next phase of research involves delving into NTLM relaying attacks targeting services similar to ADFS. For example, Okta supports the IWA Web Agent which supports client authentication leveraging NTLM . We’ve observed this solution deployed within several customer environments.
Further additional research could involve collecting additional data surrounding how often users completely disable EPA within ADFS. In this article, we discussed several scenarios where systems administrators appear to have disabled ADFS for a variety of different reasons within their environments. However, we did not perform any data collection to determine how frequently this scenario occurs.
Separately, digging deeper into EPA and ADFS also could be worthwhile. Some additional exploitation vectors or flags could exist within the NTLM protocol that cause the client application not to include a channel binding token. In addition to design flaws, we may be able to exploit implementation flaws or vulnerabilities as well.
I’d also like to develop a one-off utility for checking ADFS servers to determine what setting is applied within EPA. I think I could accomplish this by writing a utility that attempts to authenticate to an ADFS server using Windows-integrated authentication with a custom NTLM implementation. The implementation would vary the CBT configuration within the AUTHENTICATE_MESSAGE to infer the EPA setting configured by the server. Figure 26 outlines how one could develop a client which infers the EPA setting by attempting to authenticate to the server without a CBT, an invalid CBT, and a valid CBT. Unfortunately, I’m not aware of a method to accomplish this without an existing valid set of domain user credentials.
Figure 26: Outcome matrix for inferring EPA setting.
In this article, we discussed how an attacker can perform an NTLM relaying attack targeting ADFS to authenticate to web applications as the relayed users leveraging single-sign-on under certain conditions. We have also released a set of open source tools for performing NTLM relaying attacks targeting ADFS and analyzing NTLM messages in detail. Disabling EPA within ADFS is incredibly dangerous as this opens up the possibility of one-click account compromise. Unfortunately, or fortunately, depending on your perspective, the risk of NTLM relaying attacks targeting ADFS are much lower than I originally anticipated within the default configuration.