-
Table of Contents
By Yonatan Khen, Threat Hunting Expert at Team Axon
Overview
Active Directory Federation Services, also known as AD FS, is an on-premise identity provider solution (IdP) developed by Microsoft to allow secure SSO authentication and establish trust between the on-premise Active Directory environment and 3rd party SaaS applications. AD FS uses a claims-based access control model to maintain application security and implement federated identity. In other words, it allows you to customize the required attributes to access an object.
Being an internally managed identity solution, AD FS is open to an extensive attack surface, which has been exploited in the wild with a variety of different methods by state-sponsored APT groups such as NOBELIUM.
In 2022, Team Axon researched attack vectors relevant to AD FS and developed detection methods and threat-hunting practices for them. In this article, we’ll cover and explain a variety of attack vectors for the Active Directory Federation. This part of the series will focus on explaining the basics of AD FS and its authentication flow, as well as memory adapter attacks on the service. In the next part, we’ll focus more on security token abuse attacks. By the end of this two-part series, you will learn to effectively hunt, detect, and understand all relevant attacks on AD FS.
First Things First: What is AD FS?
In the early 2000s, as the usage of IT and cloud products increased, there was a growing need for an identity solution that could provide a central location for managing and auditing employee identities and authentications.
To meet this need, Microsoft introduced Active Directory Federation Services (AD FS) in 2003, which was well-suited for the widespread use of Active Directory at the time. AD FS enables users within an organization to access third-party applications with their standard Active Directory credentials. It uses a claims-based access control authorization model to maintain application security and implement federated identity - I’ll explain in a minute.
Figure 1: AD FS relationships
In the years following its release, Microsoft also introduced managed SaaS solutions such as Azure AD (now known as Entra ID), which is now the standard for "low touch" identity management products. Keep in mind that if you’re using Azure AD, the attack vectors discussed here aren’t relevant to you. However, since using them in parallel is not uncommon in large organizations, it's always recommended to perform internal research to find out if you’re using AD FS in your organization.
Before we move on, let’s go over some important AD FS terms that will accompany us heavily in this article.
Service provider / relying party: Service providers, also known as relying parties, are applications that do not reside within the on-premises active directory and require external authentication through an Identity Provider (IdP). These third-party applications are configured to be authenticated through the federation service, and thus are ‘relying’ on the service. It is important to note that a service provider is simply an object that comprises various identifiers and rules necessary for authentication.
Claims: Statements about a user, e.g. a user’s email address, UPN, etc. Claims can be conformed to logical rules (claim rules) to adjust them to the relevant target object.
Federation: A pair of realms or domains that have established a federation trust. In other words, it enables an authentication trust on two different components.
Security token: A cryptographically signed data unit that contains one or more claims. In AD FS, a signed security token indicates that the federation server that issued it has verified the authenticity of the federated user.
AD FS Authentication Flow
Now that you have a conceptual understanding of Active Directory Federation Services, let’s dive into the AD FS authentication flow. Understanding this concept will help us build the foundations required to understand the related attack vectors, and later build detection logic, threat hunting measures, and incident investigation knowledge.
Figure 2: High level AD FS authentication flow
Step 1: Authenticating with service provider
An HTTPS request to the relevant service provider (e.g. O365, Gsuite, etc.) is made with the federated domain user who is configured to use AD FS. At this point, the service provider itself doesn't have any idea whether the user is authorized to access a certain object or not, as it does not have the password.
The only record the service provider has is the relevant AD FS endpoint and reverse proxy which is associated with the relevant federated domain object in their application.
Step 2: Authenticating with AD FS reverse proxy
As explained in the summary above, AD FS provides an SSO solution for SaaS and Cloud applications that lives outside the on-premises Active Directory. In order to securely receive and send packets from the on-premise server, Microsoft developed a reverse proxy which basically provides an external facing solution without the need to expose the AD FS server itself to the outside world.
At this step, the service provider will redirect the authentication request to the relevant AD FS reverse proxy in order to authenticate with the on-premises Active Directory in a secure way.
Figure 3: AD FS reverse proxy redirected from Microsoftonline
Step 3: Claims generation
After providing the authentication details, including the on-premises credentials, and an MFA (in this case) is configured with an external adapter, the user will be verified against Active Directory, and AD FS begins the claims-gathering process. This involves collecting information about the user from Active Directory and creating a set of claims that represent this information. This information can be basic information such as username or UPN, or it can be more complex information such as group membership or role. It all depends on the specific application or object the user tries to authenticate with.
Once the claims are generated, they are sent to the claims pipeline, which is a series of logical rules that determine how the claims are processed. The claims pipeline starts with accepting the incoming claims and their source, adding additional claims or removing claims as necessary, and finally generating issuance claims to be included in the security token provided to the relying party. The claims pipeline is an important feature of AD FS because it allows the administrator to add rules and conditions to authenticate and authorize the user, thus enabling complete customization in the authentication process.
Figure 4: AD FS claims pipeline
A claim rule specifies a set of conditions that must be met in order for the rule to be executed. Let’s see an example:
Figure 5: Claim object example
Condition (red): Specifies the criteria that must be met for the claim rule to be executed. In this example, the condition is that the claim type must be "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname" and the issuer must be "AD AUTHORITY".
Action (yellow): Specifies what the claim rule should do when the condition is met. In other words, what will be the claim issued out of the pipeline. The action will issue a new claim of type "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress". The claim's object will be retrieved from Active Directory using a query that is built by using the query parameter. In this case, the query will be ";mail;{0}" and the parameter to replace the {0} value is the value of the matched claim (c.Value)
In short, we received a windowsaccountname claim and translated it to an emailaddress claim using the pipeline. These are the blocks that will build the security token provided to the relying party.
Step 4: Security token generation
At this step, the ADFS starts to build the security token that will be provided to the relying party. The token is built using the issuing claims from the previous step, that are now translated into the formalized security token based on the relying party’s configuration.
Currently, ADFS supports two different versions of assertions:
- SAML 1.1
- SAML 2.0
Using a common assertion standard is highly important for the relying parties and the adjudication of the AD FS as a commonly used IdP solution, as it allows the relying party to develop to a standardized assertion format.
In the following example, we can see the process of the claim generation pipeline transforming the claim type and claim value into a standardized assertion object.
Figure 6: Claims convert to a SAML object
After the completion of the security token generation, the assertion object is encrypted using the AD FS certificate that originated in AD CS (Active Directory Certificate Services). This will allow the relying party to know that the token was authorized by the AD FS server. In the next part of the series, we’ll deep dive into how this encryption happens, how attackers can leverage that, and even more importantly, how we can detect it.
Step 5: User authenticates to the service
After the relevant service has received the assertion security token (whether WS-FED or SAML 2.0), it knows how to properly decrypt it as it has a trust with AD FS and AD CS. It then verifies the relevant claims inside the assertion and as a result, lets the user authenticate to the desired object by providing them with a relevant auth cookie.
Adapters Attack Techniques
Overview
Now that we know the different authentication steps of Active Directory Federation Services, we can examine each step closely and identify relevant attack techniques. In this part of the series, we will focus on memory adapter attacks, while the next chapter will focus on security token abuse, specifically on the Golden SAML technique.
To understand these attacks on AD FS, we need to delve deeper into their objectives and how they are implemented in the AD FS service.
In short, AD FS adapters are responsible for adding additional functionality to the Identity Provider (IdP) process. This can be built-in AD FS functionality, such as transferring input from the AD FS proxy to the claim pipeline process, or external vendor functionality, such as enabling Azure AD to provide Multi-Factor Authentication (MFA). Adapters allow external IdP and Relying Party vendors to increase their support for AD FS.
When the AD FS service starts, it loads a binary named Microsoft.IdentityServer.Servicehost.exe. This process is responsible for all activities of the AD FS service, including receiving claims from the proxy, generating new claims, and creating security tokens that are then provided to the relying party.
Figure 7: AD FS service process Microsoft.IdentityServer.Servicehost.exe loaded to memory
So what actually are adapters? Adapters are DLLs that are loaded by the Microsoft.IdentityServer.Servicehost.exe process when the service starts, and are responsible for a majority of the functionality provided by AD FS. These DLLs are loaded from the Global Assembly Cache (GAC). The GAC can be thought of as a repository for .NET assemblies that are shared across multiple applications in the operating system, allowing code to be shared in a unified way. The GAC can be modified with local admin privileges and doesn’t require special high domain privileges.
Figure 8: AD FS adapter DLLs loaded from GAC
You might be surprised to see that all of the AD FS source files are written in .NET (or perhaps not, since I just said the DLLs are on the GAC directory...), which makes the life of actors (and ourselves) a lot easier in terms of both understanding the functionality of the service, and also manipulating it.
Now, let’s dive into several attack techniques around adapter DLL manipulation.
(Persistence) Code Execution Using Microsoft.IdentityServer.Web.dll
When thinking about quality persistence, the main goals are to have a stable method to execute a payload and an easy way to execute it.
Microsoft.IdentityServer.Web.dll is responsible for reviewing and processing input from the AD FS proxy. The technique was originally presented by Mandiant and allows an attacker to execute code on the behalf of the AD FS service remotely, as the AD FS proxy is publicly exposed.
Let’s look at the method LoginPage.VerifyInput() under the namespace Microsoft.IdentityServer.Web.UI, the method received three input variables from the AD FS authentication page: UserName which is declared as text, Password which is declared as pinnedString, and KMSI, which is basically the “Keep me signed in” option and declared as value.
Figure 9: LoginPage.VerifyInput method
We can manipulate the inputs with a condition to trigger a process execution or any other desired activity.
For example, trigger a cmd.exe command execution for receiving a user name “executeme@axoncorporations.com” as a user input string in the AD FS proxy. This persistence method is so strong because it allows us to execute our payload from a reliable source, the AD FS service process itself, and because it can be triggered remotely since the AD FS proxy is publicly available.
Figure 10: Manipulating LoginPage.VerifyInput method within Microsoft.IdentityServer.Web.UI namespace
Manipulating Azure AD Adapter For MFA Bypass
In the previous attack, we discussed manipulating the AD FS registered modules. However, AD FS native DLLs aren’t the only adapter modules used by the service to establish the authentication process and functionality.
AD FS supports external module developments, primarily to allow other IdP and authentication services, like Okta and Azure AD, to work in harmony. These external adapters mostly provide an external layer of authentication, for example, MFA.
The Azure Multi-Factor Authentication adapter allows the addition of an extra layer of security to the AD FS by using Azure MFA as the secondary authentication method. When a user attempts to log in to an application that is protected by AD FS, the Azure MFA adapter intercepts the authentication request and sends a push notification, phone call, or text message to the user's mobile device. The user must then provide the verification code that is received on their device in order to complete the authentication process.
As you might have guessed, the external adapter is loaded from the GAC, and can be manipulated as well.
Figure 11: Microsoft.IdentityServer.Adapter.AzureMfa DLL loaded from GAC
We can manipulate the extended functionality of the adapters to gain a persistence mechanism and bypass MFA implementation. In this example, we’re manipulating BeginAuthentication() which is the default method called by the AD FS when MFA is required.
Figure 12: Manipulating BeginAuthentication() method to skip MFA validation
In this example, we took an Azure AD adapter, but in theory, it can be any external adapter configured to AD FS.
Let's go hunting
When you understand how it works, it’s relatively easy to hunt and detect backdooring activity using AD FS adapters.
Tampering IdentityServer Config
In this blog post focused on AD FS adapter exploitation, we’ve learned that the AD FS service process loads shared .NET assemblies which can be manipulated for malicious activity. However, in order to switch the relevant modules, the actor would need to update the AD FS configuration file with the relevant public key token. This configuration is loaded by the AD FS service process from a config file located at C:\Windows\ADFS\Microsoft.IdentityServer.Servicehost.exe.config.
Tampering and re-writing of the file is a strong indicator of suspicious activity on your AD FS server, and could potentially point to an actor who is trying to confuse the AD FS service by loading malicious .NET DLLs instead of the original code.
Figure 13: Microsoft.IdentityServer.Servicehost.exe.config AD FS public key token
Recommended investigation flow:
- Was the AD FS service stopped or restarted before the modification, and if so, how was the activity performed and by whom?
- Inspect the modified IdentityServer Config, and review the edits. Has the public key token been changed? If so, to what DLL modules?
- Review the DLL whose public token has been changed
Creation of unknown DLLs under the AD FS GAC
Since we understand that the IdentityServer adapters can basically be manipulated and used for malicious actions, we should extend our monitoring on changes made to the DLLs. Since editing the Global Assembly Cache has to be made on the disk level, we can leverage that for efficient hunting.
However, multiple .NET softwares are using the GAC for shared assemblies. In order to hunt for relevant AD FS DLLs, whether in internal modules or external adapters, we’ll need to look for a unique prefix that identifies them. All AD FS modules start with a prefix of Microsoft.IdentityServer. The hunting thesis would be looking for new DLLs with that prefix under the Windows\Microsoft.NET\assembly\GAC_ path.
Hunting query can be found here.
Figure 14: AD FS Microsoft.IdentityServer’s DLLs loaded from GAC
Figure 15: A forged AD FS Microsoft.IdentityServer.Web DLL has been written to a new public token directory within the GAC
Recommended investigation flow:
- Was the AD FS service stopped or restarted before the modification, and if so, how was the activity performed and by who?
- Review the DLL that was written as part of the activity.
- Is the DLL signed by Microsoft?
- When was the last time the DLL was modified? Is the time different than for other DLLs?
- In case the DLL indeed wasn’t signed by MSFT, consider decompiling the .NET and look for the differences made to the DLL in order to understand what persistence was planted.
Microsoft.IdentityServer.ServiceHost Child Execution
As shown above, the service process of AD FS Microsoft.IdentityServer.ServiceHost.exe can be manipulated to execute payloads for persistence activity. By researching all the core functionality of the ServiceHost.exe we couldn’t find any programmatic child processes under the process. A possible threat-hunting thesis would be to detect anomaly child process execution under the AD FS service host process.
Figure 16: Microsoft.IdentityServer.ServiceHost.exe execute cmd.exe using persistence within Microsoft.IdentityServer.Web
Recommended investigation flow:
- Review the target process execution and its command line parameters.
- Review outbound connections from the target process execution.
- In case the activity is confirmed as malicious, acquire Microsoft.IdentityServer.Web.dll for further analysis.
Axon tip: It's reasonable to spot a WerFault.exe execution under the service process if the service has crashed. In this scenario, the most effective and hermetic way to confirm the legitimacy of the activity is to compare the target PID under “-p” parameter to the OS PID of the Microsoft.IdentityServer.ServiceHost process before the execution.
Figure 17: False positive execution of werfault.exe under Microsoft.IdentityServer.ServiceHost.exe due to a service crash. The -p parameter is with AD FS service PID.
Hunting query can be found here.
Conclusion
The first part of this AD FS Threat Hunting Series has provided an in-depth explanation of AD FS and its authentication flow, including adapter hijacking attack concepts and effective hunting and detection strategies. In the upcoming installment, the focus will shift to exploring security token attacks on AD FS, with a specific emphasis on the Golden SAML attack.
See you next time!
~ Axon
Further Reading
- MSDN: Active Directory Federation Services
- I am AD FS and so can you by Doug Bienstock and Austin Baker
- AADinternals by Nestori Syynimaa
- FoggyWeb: Targeted NOBELIUM malware leads to persistent backdoor
To stay updated on threat hunting research, activities, and queries, follow Team Axon’s Twitter account (@team__axon).