Friday, April 28, 2023

Bypassing Little Snitch With Empty TCP Packets

Jeff Johnson:

When you look at the implementation of Little Snitch, the interpretation of the word “data” becomes crucial. Technically, unless you allow the connection, Little Snitch does indeed prevent HTTP data from getting sent. Nonetheless, Little Snitch does not prevent TCP (Transmission Control Protocol) data from getting sent. This TCP data includes your IP address, which can often be used to personally identify you. The server knows that you, i.e., your IP address, tried to connect to the server, even when Little Snitch “denies” the connection.


Objective Development told me that Little Snitch uses deep packet inspection to try to get a name for the connection.


An HTTP connection over TCP has to initiate a 3-step “handshake” before any actual data—such as HTTP headers—can be sent over the connection. Every TCP packet, including any packet involved in the handshake, contains the IP addresses of the sender and the receiver.

Ryan Gerstenkorn:

If you set up a TCP connection and close it before sending any data, an alert will not be triggered by Little Snitch.


This behavior is enough to enable two-way communications between a server and a client running behind Little Snitch without being detected by using the destination port to encode data.


To demonstrate exfiltrating data we will be encoding it across eight ports where each port maps to a bit in memory. All bits default to zero, when a connection is established to port X, the associated bit X is set to one. Once we have made all the connections needed, and the bits are set correctly in memory, we can then send a connection to a ninth port, indicating to the server that the current cycle is complete. The current byte is read, flushed to stdout, and the server state is then reset.

Jeff Johnson:

The addendum of the blog post notes that I had briefly tested LuLu and saw some of the same behavior. After I published my blog post, I sent a link to Patrick Wardle, the developer of LuLu, who has been very responsive and helpful. Moreover, LuLu is open source, so I was able to examine how it works exactly. On further testing with LuLu, I came to believe that there’s actually a bug in the macOS network filter extension implementation. I’ve now filed FB12088655 with Apple: Privacy: Network filter extension TCP connection and IP address leak.

Update (2023-06-09): Christian Bender:

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?”


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 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. […] We therefore assume that it’s hard, even for Apple, to inspect the first data packet without allowing at least the initial handshake.


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. […] 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 would be naive to think that Little Snitch alone can protect you from [targeted attacks].

Update (2023-06-13): Jeff Johnson (Mastodon):

I’m not persuaded that performance over privacy is a good tradeoff for network extension users. And we don’t even get the choice. Apple is imposing its decision on everyone, with no options. And speaking of performance, do you know what else can degrade it? iCloud Private Relay! […] Additional latency may be the price of protecting your privacy, and that’s a price I’m willing to pay.


Safari is never waiting on the content blocking extension to provide a verdict on individual URL loads.

It seems to me that Apple could do network content filter extensions the same way. Why couldn’t Little Snitch provide its rules to the kernel in advance and let the kernel itself do all of the filtering, without having to switch contexts?


One of the questions I raised in my blog posts was not answered by Objective Development: why does Little Snitch leak your IP address on every TCP connection attempt, when LuLu and my own sample network filter extension do not?

8 Comments RSS · Twitter · Mastodon

That one-bit-per-request scheme is odd. Why not just use the whole TCP port range to send 16 bits per request? (or 15.98 bits if you exclude the privileged ports).

"On further testing [...], [it's] actually a bug in the macOS network filter extension implementation. I've now filed [a bug report] with Apple"

so (as anyone familiar with Apple's bug tracker knows) it's likely never gonna get fixed.

@Nick I think the idea was to keep it simple as a proof of concept to get the point across. You can certainly optimize with fancier encodings and more ports.

If Little Snitch weren't VoiceOver-hostile by choice, I'd consider it. Even so, I confess I can't and don't really grok the appeal of an app that, even if it worked perfectly as described and didn't require leaky name resolution (that's very silly for a firewall), operates on a platform that actively conspires against the user by establishing connections to remote hosts that the user can't directly control. I mean, don't you think you've got bigger problems, really?

What’s the upshot here? Should we be using Lulu instead?

@Sean No, LuLu suffers from the same issue, though seemingly to a lesser extent. I continue to use and endorse Little Snitch, despite this. The power and ease of use are unmatched.

@Jeff Any experience with

Does it have the same issue too?

Am a user of Lulu myself

> And we don’t even get the choice. Apple is imposing its decision on everyone, with no options.

Use a Packet Filter Provider if you want to block packets without having any application context?

Leave a Comment