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:
98428e05e5a4c1a289e1077787adffd97dd422dc0073bafdc25a07e5e6788cb8
CVE-2017-16945 update mechanism exploit PoC:
/static/scripts/arq_5.10.sh.txt
1557066028363d7961ec04d7af52cdab41a34234c5aa1e9fe22d0ca36ab651e1
