SNIcat: Circumventing the guardians

How the security features in state-of-the-art TLS inspection solutions can be exploited for covert data exfiltration

Written by Morten Marstrander and Matteo Malvica, Security Researchers, mnemonic

 

TL;DR

This blog post describes how we discovered a new stealthy method of data exfiltration that specifically bypasses network security solutions such as web proxies, next generation firewalls (NGFW), and dedicated solutions for TLS interception and inspection. Our testing validates that this is a widespread issue that affects different types of security solutions as well as solutions from a variety of vendors. We successfully tested our technique against products from F5 Networks, Palo Alto Networks and Fortinet, and speculate that many other vendors also are susceptible.

By using our exfiltration method SNIcat, we found that we can bypass a security solution performing TLS inspection, even when the Command & Control (C2) domain we use is blocked by common reputation and threat prevention features built into the security solutions themselves. In short, we found that solutions designed to protect users, introduced them to a new vulnerability.

We have also developed mitigation techniques, including signatures available for download, as described below.

 

Auditing the guardians

For many years both of us have designed security architecture around network man-in-the-middle devices such as web proxies, firewalls and load balancers. This playground often piques our curiosity, and this time it made us want to look at a few solutions from an attacker’s perspective.

We decided to investigate how network security solutions handled the TLS’ Server Name Indication (SNI) field for categorising and blocking bad URLs/hostnames (more on the SNI field later). Our initial goal was to simply test if we could bypass these security solutions by inserting a legitimate hostname in the SNI field and sending the traffic to a domain categorised as a bad domain.

However, this didn’t pan out as all the security solutions we tested verified that the subject-cn of the server certificate matched the value in the SNI sent by the client. If it didn’t match, the traffic was blocked. It was worth trying, at least.

This initial experiment made us aware that the TLS Client Hello packet always reached the destination server, even if it was categorised as a bad URL/domain by the security solution. The solution only blocked the session after the TLS handshake had been completed, but not earlier.

We then decided to play with the idea that we could leverage this unidirectional stream to exfiltrate data and bypass network security features, and therefore be able to send data to a known bad domain/host.

 

Decryption mirrors or Funhouse mirrors?

Modern network security solutions that perform TLS inspection often have a functionality called decryption mirroring. Basically, the security solution can forward a copy of the decrypted traffic to a mirror port, which is commonly connected to an IDS that can now inspect the once encrypted traffic. This is all well and good from a security monitoring perspective. However, we discovered that devices connected to the mirror port do not receive the TLS handshake at all, opening up a new way of performing stealthy exfiltration utilising the TLS Client Hello.

 

'I don't know why you say goodbye, I say Hello' - A digression on the TLS Hello packet

Because of the way the security solutions described above behaved, we realised that we could exfiltrate data utilising extensions of the Client Hello of the TLS protocol. We chose the SNI field as an exfiltration container because it was the one extension that was never manipulated or changed by any of the in-line security solutions.

During the handshake process, the SNI is populated by a value provided by the client and instructs the server which hostname the client is trying to connect to, and what certificate it should present to the client.

When utilising a security solution to actively allow or deny traffic based on what domain/URL the client is connecting to, this is usually how it works:

 

We then conducted a quick proof of concept which proved we could misuse this field by injecting arbitrary data and successfully employing this once legitimate extension as a “smuggling container” through the security solutions, without the traffic being copied to a decryption mirror port.

So far so good. We had demonstrated how we could send data out from a client. The next step was to find a way to control the client using a RAT (Remote Access Trojan) that could, in turn, leverage this new communication channel. As mentioned earlier, at this stage of testing the channel was only working one-way since every tested solution was blocking the returning traffic coming back from the server and that was obviously not an optimal scenario. We were stuck, and in need of a new way of letting the control server’s data pass back through the security solution.

 

Commands, but who controls them?

To overcome this hurdle, we built an interim out of band C2 based on Instagram, which employed embedded C2 control commands inside Instagram’s own comments section. This was enough to get a working demo which proved our theory correct, functional and hopefully extensible: we were able to remotely control the compromised host and selectively exfiltrate data.

This result encouraged us to continue testing. Our next goal was to replace the Instagram component since social media websites are easily and often blocked by internal security policies, which would have interfered with our C2 communication. We continued pursuing an in-band alternative of establishing an end-to-end communication between the agent and the Command & Control server.

After some more tinkering, we discovered a common denominator in every solution we tested. As long as the server presents a valid and trusted certificate during the TLS handshake, the security solution will always present an emulated version of that certificate to the client, signed by the solution’s built-in CA. This behaviour occurs even if the domain used is blacklisted by a reputation database (URL/domain categorisation). In addition, by serving a self-signed certificate from a server, the security solution either presents the client with an emulated self-signed certificate, or a simple TCP reset.

On a very primitive communication channel, a basic response would only require a binary YES/NO capability, and we now have it: a valid, trusted certificate gives us a “YES”, and an untrusted, self-signed certificate gives us “NO”. We implemented this logic into our SNIcat tool.

 

Putting it all together – enter SNIcat

SNIcat comprises of two separate but interdependent components:

  • A passive agent that should be dropped on the target and already compromised host. Its only goal is to connect back to the C2 and execute the provided commands.
  • A C2 server which controls the agent from anywhere on the Internet.

The passive agent is equipped with various commands, including the ability to exfiltrate (i.e. upload) files to the server. It constantly loops between all the available commands and waits for the C2 server to select the desired one by leveraging the binary YES/NO capability mentioned earlier. With SNIcat, we extended this logic so that we could provide a minimal but effective standalone Command Line Interface (CLI). The CLI can offer basic file system navigation commands such as jumping between folders, listing files and, obviously, exfiltration.

Here is the C2 CLI in action, where we use some of the built-in commands to navigate the file system and exfiltrate a file from the agent to the C2 server:

What about mitigations?

While developing this offensive tool, we also worked on developing different ways to mitigate and detect this kind of attack, both from the endpoint and the security perimeter solution. We have had a good dialogue with the vendors whose products we tested, and the following suggestions have been shared with them. As a result, a few of the vendors have provided their own security advisory with their suggested work-arounds and/or fixes. Links to the advisories can be found in our reference section below.

 

Detection in the security perimeter

  1. An Intrusion Detection System (IDS) could detect the anomalous SNI payload by redirecting the original TLS handshake, along with the decrypted traffic or as a separate stream, to any device configured to receive decrypted traffic (often called decryption mirroring).

  2. Performing heuristics on the Client Hello’s SNI: We have successfully used custom logic to perform an entropy check on the SNI field, and detect SNIcat by utilising this method. As long as the vulnerable products can log the SNI of every handshake, send it to a SIEM, or send the handshake itself to an IDS, one can detect SNIcat with good accuracy. Another mitigation we suggest is to reuse existing exfiltration signatures, such as DNS-signatures, on the SNI field. Also, by checking the length of the SNI field, one could check that it’s almost always 254 bytes during our misuse attacks (this is the maximum we were able to send per Client Hello, due to the limitations of a domain name character length). An alert could be generated when this value is matched.
  3. Before completing the server side’s TLS handshake, we recommend changing the blocked URL categories’ logic to match the SNI field and thus block/allow any session in case of a match occurring. This way the data in the malicious SNI will not be passed to the C2 if the site is already restricted by a blocked URL category or if it is not matching an explicit whitelist.

 

Detection on the Endpoint

We also developed a very early-stage proof of concept of a ‘passiveSNI’ detection tool, conceptually similar to the well-known PassiveDNS application.

It works by constantly monitoring and logging every TLS/Hello packet sent through any network socket interface. These generated logs can be gathered and analysed through a SIEM solution against any well-known signature or behavioural analytics.

 

Conclusions

We speculate that more vendors than those mentioned in this blog post are susceptible to our SNIcat approach. Even though it would have been interesting to test every network security solution on the market, we had limited resources and scope this time around. We therefore advise vendors to test if their products are vulnerable to SNIcat. In addition, end users and enterprises may find it helpful to test their solutions with our PoC code that you can find on GitHub.

 

Disclosure Timeline

Responsible disclosure procedures were followed per vendor policy.

Date Event Comments
24/2/2020 Disclosed to F5 Networks Followed disclosure procedures per https://f5.com/support/self-solve/report-a-vulnerability

25/2/2020

Disclosed to Palo Alto Networks

Followed disclosure procedures per https://www.paloaltonetworks.com/security-disclosure

26/2/2020

F5 Networks confirmed they received our report

 

27/2/2020

Palo Alto Networks confirmed they received our report

 

3/4/2020

Disclosed to Fortinet

Followed disclosure procedures per https://hackerone.com/fortinet?type=team

8/4/2020

Fortinet confirmed they received our report

 

16/4/2020

Received suggested work-around from F5 Networks

Received a working iRule from F5 Networks, in order to mitigate SNIcat when used with known bad domains.

17/6/2020

Informed all vendors of the date we intended to publish.

 

12/8/2020

Published GitHub repo and blog post

 

 

PRODUCTS SUCCESSFULLY BYPASSED WITH SNICAT

SNIcat was successfully able to bypass the following products and their respective software versions:

  • F5 BIG-IP running TMOS 14.1.2, with SSL Orchestrator 5.5.8
  • Palo Alto NGFW running PAN-OS 9.1.1
  • Fortigate NGFW running FortiOS 6.2.3

 

References

PoC code: https://github.com/mnemonic-no/SNIcat

F5 Networks: Security advisory can be found here https://support.f5.com/csp/article/K20105555

Palo Alto Networks: Security advisory can be found here https://security.paloaltonetworks.com/CVE-2020-2035

Fortinet: The vulnerability will be fixed in 6.4.3 GA, with a tentative release in September. An advisory will be published by FortiGuard Labs after the release.

 

CVE

CVE-2020-2035

CVE-2020-15936