Two local root privesc bugs in Arq Backup <= 5.10

29 Jan 2018 06:33 | macOS | security | exploits

Last year I found a couple more privilege escalation vectors in Arq Backup
for Mac version 5.10. Both have now been fixed in the latest release.

The first is relatively simple - the arq_updater binary (which runs as root)
takes a path argument for the url to retrieve an Arq update from in the format
Arq.zip. We can simply specify an arbitrary path - eg file:///tmp/blah/Arq.zip -
on the local filesystem and this will get unzipped in the /Applications/
directory. Although we can't embed suid permissions into a zip file the updater
binary sets +s on a handful of binaries as part of the installation process
without validation.

This means we can simply substitute one of these binaries in an arbitrary
Arq.zip with a payload that will then receive the +s bit as well as root
ownership.

The second issue is a bit more involved and actually rather cool from an
exploitation point of view :)

The restorer binaries which were subject to direct privilege escalation in
versions prior to 5.10 run as root. This means that when restoring files the
process has privileges to write to anything that root can write to. The paths to
restore files to are set by the Arq UI application and are either the original
path of the backed up file or a computed path prefixed with "Restored by Arq"
that the application carefully ensures is unique.

However this path is passed to the restorer binary through the inter-app
protocol that I reversed in a previous exploit, which means if we know how to
talk to it we can specify an arbitrary restore path. So a local non-root user
can drop a file into their home directory and then with a specially crafted
payload, trigger the standardrestorer binary to restore it place of any file
on the system.

An interesting target for this is the root users crontab file at:

/var/at/tabs/root

It turns out that if a file appears at this path, even if it isn't root-owned,
it will be immediately processed by the cron system and any commands within will
be executed as root (this oversight was reported to Apple).

So, theoretically at this point we can create a cron file in the user's home
directory, wait for it to get backed up by Arq and then restore it in place of
the root crontab in order to escalate to root access.

The only thing in the way of this working is the HMAC validation. Every file
backed up by Arq has a computed HMAC hash stored with the file and the restorer
binaries validate this when restoring. There will typically be millions of files
in the backup and we need to know the exact HMAC of the file, which is derived
using a secret key stored in the login keychain.

To figure this out we can, before doing anything else, dump the list of HMACs
from the cache files in ~/Library/Arq/. The HMACs are sha1 hashes so simply
making a unique list of anything that looks like a sha1 hash will be sufficient.
We can then create our crontab file, wait for the next backup run and then scan
the cache files again. Discarding any hashes that we saw the first time will
give us a much smaller list of potential HMACs for the backed up file which we
can trivially brute-force.

After the cron file is restored we just wait up to 60 seconds for the minute
cron interval to arrive and our payload gets executed.

Both of these issues are fixed in the latest release of Arq.

CVE-2017-16928 backup/restore exploit PoC:

https://m4.rkw.io/arq_5.10.rb.txt
98428e05e5a4c1a289e1077787adffd97dd422dc0073bafdc25a07e5e6788cb8
------------------------------------------------------------------------------

CVE-2017-16945 update mechanism exploit PoC:

https://m4.rkw.io/arq_5.10.sh.txt
1557066028363d7961ec04d7af52cdab41a34234c5aa1e9fe22d0ca36ab651e1
------------------------------------------------------------------------------