SNIcat: Circumventing the guardians
How the security features in state-of-the-art TLS inspection solutions can be exploited for covert data exfiltration
Updated 19.08.2021: mnemonic's Morten Marstrander and Alvaro Gutierrez successfully tested SNIcat on Cisco WSA. Cisco has released an advisory, stating that multiple products are vulnerable to SNIcat, including WSA, FTD, ISAs and some versions of Snort.
Update 08.10.2020: After publishing, the researchers have been invited to present these findings at Black Hat Europe, read more here.
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
- 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).
- 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.
- 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.
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.
Products succesfully 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
- 3000 Series Industrial Security Appliances (ISAs)
- FTD Software
- WSA Software
- Snort project releases earlier than Release 2.9.18
- PoC code on GitHub
- F5 Networks security advisory
- Palo Alto Networks Security Advisory
- Fortinet: Fortinet has published a security advisory and signatures for detecting and blocking SNIcat https://www.fortiguard.com/psirt/FG-IR-20-091
- Check Point: Check Point has published signatures for detecting and blocking SNIcat in both their EDR solution and their NGFW (Updated 30.11.2020)
- Sandblast Agent
- Threat Emulation
- Sandblast Agent
- Cisco security advisory
Responsible disclosure procedures were followed per vendor policy.
|24/2/2020||Disclosed to F5 Networks||Followed disclosure per vendor disclosure guidelines|
|25/2/2020||Disclosed to Palo Alto Networks||Followed disclosure per vendor disclosure guidelines|
|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 vendor disclosure guidelines|
|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|
|31/5/2021||Disclosed to Cisco|
|18/8/2021||Cisco published an advisory||Cisco security advisory|