An Exploit Chain Against Citrix SD-WAN

Chris Lyne
Jul 11 · 7 min read

While inspecting the patch for TRA-2019–18, I discovered multiple critical vulnerabilities in both Citrix SD-WAN Center (SDWC) and the SD-WAN appliance itself (formerly known as NetScaler SD-WAN). Both software packages can be compromised by a remote, unauthenticated attacker.

This means the attacker could theoretically pivot from node to node to compromise an entire SD-WAN. The product line is designed to allow organizations to have software-defined WAN capabilities spanning across geographic regions. According to the Citrix customer stories page, there are many SD-WAN customers across the globe.

Keep the network topology pictured below in mind as we go. Each node is either an SDWC (e.g. headend, collector) or an SD-WAN appliance (e.g. MCN, RCN, branch appliance).

Multiple Unauthenticated RCEs in SD-WAN Center

Citrix SD-WAN Center is a CakePHP web application designed to manage Citrix SD-WAN appliances. I wrote Intro to CakePHP for Bug Hunters, for those of you that want to brush up on tactics for examining applications like this.

For the most part, authentication is enforced within the application. However, there is a controller that essentially acts as a passthrough. CollectorController forwards requests to other controllers, effectively bypassing the authentication requirement of the target controller.

For example, normally, you can’t request the DiagnosticsController without an authenticated session. But CollectorController will happily forward a request straight to DiagnosticsController. Without this logic, all of my bugs would require authentication. Below are two screenshots of pre-authenticated requests. Notice the request to /Diagnostics results in an HTTP 302 response (to /login), but the request to /Collector results in a 200.

Let’s take a closer look. In CollectorController, the beforeFilter method explicitly gives pre-authenticated access to many actions. In this case, we will focus on diagnostics.

The code snippet below shows how the diagnostics action method is defined. Notice how a new instance of DiagnosticsController is created to handle the request.

Basically what happens here is CollectorController first handles the incoming HTTP request, and the diagnostics action is invoked. Then the request is passed off to DiagnosticsController, which will generate the response.

As depicted above, in DiagnosticsController, there is a ping action. This action method contains an OS command injection vulnerability. All three HTTP GET parameters are interpolated, unsanitized, into a command line, which is executed by the PHP exec function. Thanks to CollectorController, this vulnerability can be exploited without authentication to gain root access.

Below is a curl command you could use to pop a reverse shell, connecting back to IP on TCP port 4444.

To demonstrate proof of concept, here is a short video.

I mentioned that there are more RCE vulnerabilities. Take a look at our research advisory if you’re interested. Below is the topology diagram showing which SDWC nodes can be rooted so far.

Chaining Two Vulnerabilities to Root the SD-WAN Appliance

In the case of the SD-WAN appliance, I didn’t find an unauthenticated RCE vulnerability. I did, however, discover a way to bypass authentication, and I also found yet another OS command injection. Used in combination, you get root without credentials. Unlike SD-WAN Center, these vulnerabilities are in Perl CGI scripts.

Vuln 1: A SQL Injection to Bypass File-based Authentication

Often times, you’ll read about people bypassing authentication using SQL injection because the “login” query wasn’t properly sanitized (e.g. “ ‘ or 1=1 — ”). The bypass I’m describing here is totally different.

In cgi-bin/sdwanrestapi/getpackagefile.cgi, a JSON is expected in the POST data, and the site_name record is used to construct multiple SQL queries. Below is the first vulnerable query.

Notice above how $site_name_arg is concatenated into the query. Its value came straight out of the JSON, as shown below.

This is a classic SQL injection vulnerability. Unsanitized user input is concatenated into a SQL query. Boom! But what can be done with this vulnerability? I mentioned we could bypass authentication. If you’re paying attention, you probably notice that this query has nothing to do with authentication, so how can we bypass it? Let’s look at the auth scheme.

When a request is received, the check_session() function (defined in utils.cgi) is called to ensure there is an active authenticated session. One of the first checks is to see if the request is tied to a single sign-on session, by calling check_swc_sso().

The check_swc_sso() function checks to see if a token file exists in the /tmp directory. It does this by first grabbing the token value from the swc-token GET parameter. Next, the script looks for a file named “token_$sso_token” in the /tmp directory, where $sso_token contains the token value. If it exists, the request is granted level 1 access (admin).

With this in mind, let’s craft a SQL injection query to create a token file in the /tmp directory. Since the database is MySQL, we can write to a file using the “SELECT … INTO OUTFILE” syntax. The way I accomplished this was with a UNION. The injection looks like this:

By injecting this string into the JSON as the value of site_name, we can create a file named “token_01234” in the /tmp directory. This means the value “01234” is now a valid swc-token.

This is what the exploit looks like to generate the token file.

Vuln 2: Classic OS Command Injection

I found yet another OS command injection vulnerability. A GET parameter, installfile, is interpolated directly inside a call to the Perl system function.

You probably notice that this vulnerability can only be triggered if the call to check_session succeeds. This means the attacker has to be authenticated to exploit it. Fortunately, we have an authentication bypass at our fingertips. Here is an exploit to start a bind shell on the appliance. Notice the token value is used in the value for swc-token.

In the topology diagram below, I show the appliance nodes that can be rooted by exploiting these two vulnerabilities.

Here is a video to demonstrate the chained attack.

Pivoting from SDWC to an Appliance

Given the multi-branch topology, it’s possibly the case that an attacker could only reach a single node. However, since we can root SDWC and the appliance, an attacker can pivot from one machine to the next. Below is a final video to show this.

Looking back at the network diagram, the video demonstrates an attacker pivoting from SDWC to an appliance. The green nodes in the diagram are relevant to this scenario. However, the pivot potential is endless here. The attacker could move from SDWC to SDWC, appliance to appliance, or SDWC to appliance (in either direction).

Before I close out, I want to mention one thing. The exploits I’ve shown in this write-up all deliver a payload to get the attacker a shell; however, a different payload could be delivered to create a new admin account for the web interface. The following command adds an admin user named “eviladmin”.

Here is a screenshot to show the result. This works on both SDWC and the appliance.

Closing Remarks

I’ve shown you 3 vulnerabilities and exploits to compromise an entire Citrix SD-WAN. With WAN technologies becoming increasingly defined by software, it is imperative that strides are taken to secure this software. WANs define infrastructure that is critical to business continuity, so the need for secure underlying code is vital to ensure the confidentiality, integrity, and availability of these networks.

We have posted research advisories for both products along with PoC’s. If you’re interested, take a look at TRA-2019–31, TRA-2019–32, and our PoC GitHub repository. Also, for a more business-focused impact, I encourage you to read the related post on the Tenable blog. Finally, Citrix has released a security bulletin and patches to address the reported vulnerabilities.

Tenable TechBlog

Learn how Tenable finds new vulnerabilities and writes the software to help you find them

Chris Lyne

Written by

Chris is a security researcher at Tenable, focused on finding 0-day vulnerabilities. He is a former developer and aims to make the cyber world more secure.

Tenable TechBlog

Learn how Tenable finds new vulnerabilities and writes the software to help you find them