Three-way handshake bypassing Little Snitch

There has been some discussion recently about the bypassing of Little Snitch by the first datagram of a three-way TCP handshake. The facts: When a deny-rule for a domain is set in Little Snitch, and a TCP connection is made to that domain, a TCP SYN data packet is sent to the remote server. Although this packet does not carry any payload, it does include crucial information such as your IP address, as well as the sending and receiving port numbers.

This raises two questions:

  1. Why does this happen?
  2. What are the consequences?

Let us first talk about the rationale behind this.

Why does Little Snitch allow these data packets?

First of all, it‘s not Little Snitch which is in charge to decide whether these packets leave the computer, it‘s Apple‘s NetworkExtension framework. Since we are no longer allowed to ship a kernel extension, we are required to code against this new programming interface. So the question transforms into: “Why does the Network Extension framework allow these data packets?”

This was a design decision made by Apple. The Network Extension framework puts the filter code outside of the operating system kernel. When a connection should be established, the data must be passed from the kernel to an Apple user space process and from this user space process to the respective Network Extension. The Network Extension makes a decision based on rules, sends back the result via to the original user space process which in turn sends it down to the kernel. A long path, isn‘t it?

When you open a web page in a browser, it‘s quite possible that 10 to 100 more connections are opened (to various trackers and ad servers, by the way) and delaying each connection only by a few milliseconds would degrade perceived performance. This is of course a red rag for Apple. They want to be the best and fastest and browser benchmarks are a common way to compare systems. That‘s the most relevant operation for most users, after all.

So Apple made a very clever move: Web traffic is usually sent over the TCP protocol. And TCP involves a handshake in order to open the connection: The client sends a SYN packet, the server responds with a SYN/ACK packet and the client then responds with ACK. This is known as the three-way handshake and it‘s the limiting factor for the load time of many web pages because it takes the time of at least two round-trips. You can check the round-trip time with ping from a Terminal. When you ping a server by name, data packets are sent to that server and the server immediately responds to them. So you can measure the time it takes for a data packet to travel to the server and back to you. In a local network, this time is usually around one millisecond. For Internet connections, it‘s often around 20 milliseconds or even more.

The clever move is to run two tasks in parallel: While the three-way handshake is in progress, Apple simultaneously asks all Network Extensions whether to allow or deny the connection. The Network Extensions have at least 20 milliseconds time to respond without degrading performance. That just enough to run complex filters and send responses back to the kernel. The downside is, of course, that the server receives the SYN packet. If it turns out that the packet should be denied, a RST (Reset) packet is sent instead of the SYN/ACK to abort the connection.

We consider this decision quite reasonable and have made a similar trade-off in Little Snitch 4 (which was based on a kernel extension): Little Snitch applies filters at a stage where only IP addresses are available, not computer names. Unfortunately, there is no one to one correspondence between IP addresses and computer names. Each name can resolve to multiple addresses and multiple names can resolve to the same address. We therefore had to expect that more than one name resolves to the IP address in question. So how should we single out one name from this set? Most application layer protocols such as TLS or HTTP transmit the actual intended computer name alongside the initial data packet. We therefore decided to permit the handshake, enabling the application layer to perceive a successful connection and transmit the first data packet (which we intentionally withheld but had an opportunity to examine). Based on this data packet we allowed or denied the connection, or we asked the user. This procedure (a lightweight version of Deep Packet Inspection) was only needed if there were multiple names known to resolve to the given IP address.

At that time, we had tried a lot to get hold of the first data packet without allowing the handshake. We tried to report a successful connect to the app, although the handshake packets were held back. This resulted in an inconsistency in the TCP/IP implementation of the kernel and triggered either a kernel panic or various other errors. Even if we had succeeded faking a successful connect, there had been no way (if the connection was finally allowed) to report back when the actual connect failed.

We therefore assume that it‘s hard, even for Apple, to inspect the first data packet without allowing at least the initial handshake.

How does this affect privacy and security?

The first data packet of a three-way handshake contains

  • protocol administrative data
  • originating IP address
  • destination IP address
  • local TCP port number
  • remote TCP port number

From all this info, only the local and remote TCP port numbers can be chosen by the sending process (with some limitations). A potential attacker can transfer up to 16 bits in each port number and automatically sends the local IP address, identifying the sender.

16 bits does not sound much, but an attacker can send multiple packets to form a longer message. So, what are the limitations with this approach? First of all, the attacker must be careful not to trigger various other alarms. If you send many SYN packets in a row, you become suspicous. Especially if this is done in large scale by more than one computer. If you send to more than one remote port number, your behavior may easily look like a port scan and you might even trigger an alarm at your own Internet provider. And even if you limit yourself to low count of port numbers, you will soon trigger a connection rate limit. Little Snitch 4 had such a limit and slowed down processes doing many denied connects. We assume that the Network Extension framework must do a similar thing in oder to keep the system responsive.

An attacker using this mechanism for a data transfer must expect that the computer goes to sleep at random times and that some packets are lost in transfer. In addition, there is no way for the receiver to request a retransmit because no information is sent back to the sending process. The attacker therefore needs to apply error correction to compensate lost packets and will try to send the data in one chunk, before the computer goes to sleep. This limits the amount of data which can be sent semi-reliably to several 10 kilobytes.

So, what does this mean for the attacker?

  1. Limited data transfer: Due to the restrictions and limitations mentioned, attackers can only send a relatively small amount of data. They must have prior knowledge of what to search for and what to send.
  2. Lack of back-channel communication: Since there is no back-channel for the attacker to send commands to the victim, the conventional approach of a command and control server server cannot be utilized.
  3. The limitations mentioned above render this approach unsuitable for running a botnet. Victims cannot receive commands or execute typical botnet commands.
  4. The approach may be more applicable for a targeted attack, where the attacker possesses extensive knowledge of the victim's infrastructure.

Is it likely that this will be used for attacks?

There are three kinds of attackers:

  1. Those who try to attack a large amount of computers in order to establish a botnet or install ransomware. They don‘t care about an individual computer, they just want to infect as many computers as possible.
  2. User tracking and analytics. These attackers usually define themselves as legitimate service providers, but the majority of people view them as privacy invaders or attackers.
  3. Targeted attacks, such as trojans introduced by law enforcement agencies, competitors, foreign secret services and similar.

Considering the different types of attackers, it is unlikely that exploiting the TCP SYN packet will be widely used for large-scale attacks targeting multiple computers. Attackers who encounter Little Snitch installed on a system are likely to move on to more vulnerable targets.

However, this method could be of interest to user tracking and analytics, allowing them to gather rough information about installations and some aspects of user behavior. It is important to note that even without the three-way handshake, similar analytics can be derived from DNS looukps. Using DNS, it is even possible to collect detailed analytics because the name may be chosen at will and might contain any information the attacker wants to collect.

And, finally, let‘s look at targeted attacks. Well. These are extremely hard to keep off and even highly secured organizations and exposed persons become victims of targeted attacks by e.g. foreign secret services. They use zero-day exploits and combinations of them in order to get control over your devices. It would be naive to think that Little Snitch alone can protect you from these. If you are an exposed person, consider Little Snitch as an instrument to possibly find out that you are hacked and choose options like lockdown mode in macOS to reduce your attack surface.

What are the future prospects?

Apple had to decide between two unpopular choices: bad performance or limited possibilities for privacy and security enhancers. They decided for the latter, probably because they thought that it would put off less users. And, honestly speaking, we think that this assumption is right and won‘t change in the near future.

If you think otherwise, please file a feedback to Apple using Feedback Assistant and share the feedback number and feedback text with us. Be sure to present a clear and solid argumentation why you would prefer a different trade-off. Otherwise your feedback is likely to be ignored.

If you have relevant information to add or if you can seriously propose a way to mitigate the problem, please contact our support.