Escaping Citrix Workspace and Getting Shells

Background

On a recent web application penetration test I performed, the scoped application was a thick-client .NET application that was accessed via Citrix Workspace. I was able to escape the Citrix environment in two different ways and get a shell on the underlying system. From there I was able to evade two common AV/EDR products and get a Meterpreter shell by leveraging GreatSCT and the “living off the land” binary msbuild.exe. I have of course obfuscated any identifying names/URLs/IPs etc.

What is Citrix Workspace?

Citrix makes a lot of different software products, and in this case I was dealing with Workspace. So what is Citrix Workspace exactly? Here’s what the company says it is:

To realize the agility of cloud without complexity and security slowing you down, you need the flexibility and control of digital workspaces. Citrix Workspace integrates diverse technologies, platforms, devices, and clouds, so it’s flexible and easy to deploy. Adopt new technology without disrupting your existing infrastructure. IT and users can co-create a context-aware, software-defined perimeter that protects and proactively addresses security threats across today’s distributed, multi-device, hybrid- and multi-cloud environments. Unified, contextual, and secure, Citrix is building the workspace of the future so you can operationalize the technology you need to drive business forward.

With the marketing buzzwords out of the way, Workspace is essentially a network-accessible application virtualization platform. Think of it like Remote Desktop, but instead of accessing the entire desktop of a machine, it only presents specific desktop applications. Like the .NET app I was testing, or Office products like Excel. These applications are made available via a web dashboard, which is why it was in scope for the application test I was performing.

Prior Work on Exploiting Citrix

Citrix escapes are nothing new, and there is an excellent and comprehensive blog post on the subject by Pentest Partners. This was my starting point when I discovered I was facing Citrix. It’s absolutely worth a read if you find yourself working with Citrix, and the two exploit ideas I leveraged came from there.

Escape 1: Excel/VBA

Upon authenticating to the application, this is the dashboard I saw.

Citrix dashboard

The blue “E” is the thick-client app, and you can see that Excel is installed as well. The first step is to click on the Excel icon and open a .ICA (Independent Computing Architecture) file. This is similar to and RDP file, and is opened locally with Citrix Connection Manager. Once the .ica file loads, we are presented with a remote instance of Excel presented over the network onto our desktop. Time to see if VBA is accessible.

Excel VBA

Pressing Alt + F11 in Excel will open the VBA editor, which we see open here. I click on the default empty sheet named Sheet1, and I’m presented with a VBA editor console:

Excel VBA editor

Now let’s get a shell! A quick Duck Duck Go search and we have a VB one-liner to run Powershell:

1
2
3
Sub X()
    Shell "CMD /K/ %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe", vbNormalFocus
End Sub

VBA payload

Press F5 to execute the code:

first shell

Shell yeah! We have a Powershell instance on the remote machine. Note that I initially tried cmd.exe, which was blocked the by the Citrix configuration.

Escape 2: Local file creation/Powershell ISE

The second escape I discovered was a little more involved, and made use of Save As dialogs to navigate the underlying file system and create Powershell script file. I started by opening the .NET thick-client application, shown here on the web dashboard with a blue “E”:

E dashboard

We click on it, open the .ICA file as before, and are presented with the application, running on a remote machine and presented to us locally over the network.

E opened

I start by clicking on the Manuals tab and opening a manual PDF with Adobe Reader:

E manual

Adobe manual

As discussed in the Pentest Partners post, I look at the Save As dialog and see if I can enumerate the file system:

save as

I can tell from the path in the dialog box that we are looking at a non-local file system, which is good news. Let’s open a different folder in a new window so we can browse around a bit and maybe create files of our own:

save as

Here I open Custom Office Templates in a new Explorer window, and create a new text document. I enter a Powershell command, Get-Process, and save it as a .ps1 file:

new file

Once the Powershell file is created, I leverage the fact that Powershell files are usually edited with Powershell ISE, or Integrated Scripting Environment. This just so happens to have a built-in Powershell instance for testing code as you write it. Let’s edit it and see what it opens with:

edit ps1 ISE

Shell yeah! We have another shell.

Getting C2, and a copy pasta problem

Once I gained a shell on the underlying box, I started doing some enumeration and discovered that outbound HTTP traffic was being filtered, presumably by an enterprise web proxy. So downloading tools or implants directly was out of the question, and not good OPSEC either. However, many C2 frameworks use HTTP for communication, so I needed to try something that worked over TCP, like Meterpreter. But how to get a payload on the box? HTTP was out, and dragging and dropping files does not work, just as it wouldn’t over RDP normally. But Citrix provides us a handy feature: a shared clipboard.

Here’s the gist: create a payload in a text format or a Base64 encoded binary and use the Powershell cmdlet Set-Clipboard to copy it into our local clipboard. Then on the remote box, save the contents of the clipboard to a file with Get-Clipboard > file. I wanted to avoid dropping a binary Meterpreter payload, so I opted for GreatSCT. This is a slick tool that lets you embed a Meterpreter payload within an XML file that can be parsed and run via msbuild.exe. MSbuild is a so-called “living off the land” binary, a Microsoft-signed executable that already exists on the box. It’s used by Visual Studio to perform build actions, as defined by an XML file or C# project file. Let’s see how it went.

I started by downloading GreatSCT on Kali Linux and creating an msbuild/meterpreter/rev_tcp payload:

GreatSCT

Here’s what the resulting XML payload looks like:

payload.xml

As I mentioned above, I copy the contents of the payload.xml file into the shared clipboard:

payload.xml

Then on the victim machine I copy it from the clipboard to the local file system:

payload.xml

I then start a MSF handler and execute the payload with msbuild.exe:

payload.xml

payload.xml

Shell yeah! We have a Meterpreter session, and the AV/EDR products haven’t given us any trouble.

Conclusions

There were a couple things I took away from this engagement, mostly revolving around the difficulty of providing partial access to Windows.

  • Locking down Windows is hard, so locking down Citrix is hard.

Citrix has security features designed to prevent access to the underlying operating system, but they inherently involve providing access to Windows applications while trying to prevent all the little ways of getting shells, accessing the file system, and exploiting application functionality. Reducing the attack surface of Windows is difficult, and by permitting partial access to the OS via Citrix, you inherit all of that attack surface.

  • Don’t allow access to dangerous features.

This application could have prevented the escapes I used by not allowing Excel’s VBA feature and blocking access to powershell.exe, as was done with cmd.exe. However I was informed that both features were vital to the operation of the .NET application. Without some very careful re-engineering of the application itself, application whitelisting, and various other hardening techniques, none of which are guaranteed to be 100% effective, it is very hard or impossible to present VB and Powershell functionality without allowing inadvertent shell access.

- Solomon Sklash