Back around April 2024, I found race conditions in WorkflowKit (the backend to Shortcuts) with regards to how it handles AEA files. Later on, I realized that there is a high possibility that other software using libAppleArchive may have very similar race conditions. Thus, I began searching for things that used libAppleArchive, which lead me to ArchiveService.xpc, the XPC service that Archive Utility (and other utilities, e.g. ClipServices) uses to unarchive Apple Archive files. This lead me to realize that _unarchiveAppleArchiveWithItemURL:destinationURL:progress:passphrases:addToKeychain:formats:error: had a very similar race condition to WorkflowKit.

A malicious app can exploit this to replace archives that are awaiting extraction with a different, potentially malicious archive.

The Vulnerability

_unarchiveAppleArchiveWithItemURL:destinationURL:progress:passphrases:addToKeychain:formats:error: calls AAExtractArchiveOutputStreamOpen, which gets the realpath() of the destination path passed in and opens it. Then, AAArchiveStreamProcess is called to extract the archive to the temporary directory. Subsequently, Archive Utility's _decompressMoveCopyResults moves the temporary directory to where the user wants the directory to be.

HOWEVER, Archive Utility does not account for the case in which the file is modified right after extraction, but before it gets copied over. This means that a malicious app can modify the directory or file in time and have Archive Utility output a different directory, also allowing the malicious app to read the directory.

Initially during the creation of the exploit, I thought it would be a good idea to have an AAR with just 5 bytes. However, this was extracted far too quickly for my exploit to win the race. This lead me to increase the size of the AAR to 10KB, after which it successfully raced the extraction. I am running this on a MacBook Air (Retina, 13-inch 2020) Core i5, so reliability may differ accross different macs with differing levels of CPU performance.

While this writeup talks about this as an Archive Utility vulnerability, technically it is an ArchiveService.xpc vulnerability, so it affects other things that use it as well. I'm choosing to talk about this as relating to Archive Utility to showcase one possible method of exploitation.

Creating an Exploit

This vulnerability was very similar to the previous one I found in WorkflowKit, so I decided to copy and paste my previous WorkflowKit exploit. To summarize the previous exploit, I open a kernel queue to scan the Shortcuts temporary directory while Shortcuts has it open, thus I decided to replicate this for Archive Utility as well.

After testing it on my machine, I wanted to make it work on Monterey as well, so I tested it on Monterey, did some quick fixes, and submitted it to Apple. However, I later realized that I accidentally kept the temporary path from Monterey's Archive Utility without also keeping the modern Ventura/Sonoma path. On top of this, I discovered a much, much stranger issue.

Turns out, stage_0 did not handle certain scenarios. I deleted the temporary directory so that Archive Utility would reconstruct it again, to allow me to get a feel for what the normal state of operations are like, and discovered that it did not let me open the temporary directory. However, for some, strange reason, when I ran stat -f "%OLp" on it to check it's permissions, it suddenly started working (????). It seemed that executing any terminal command (e.g. cat or xattr) on it, even unprivileged ones, allowed for the directory to once again be opened. To be honest, I have no idea why this happens; my best guess is that it's something to do with the SIP or Sandbox not allowing it, but I don't understand why anything in terminal running under the same permissions as the PoC would then allow it to work.

If anyone knows why this is happening, please send me a message, I would love to know!

However, thankfully I did find a way around this strange quirk: Even though TemporaryItems is protected by Archive Utility by default, the folder containing it, com.apple.fileprovider.ArchiveService, is not. We can verify this by deleting com.apple.fileprovider.ArchiveService and extracting the archive normally; the PoC won't be able to opendir(), remove(), or rename() com.apple.fileprovider.ArchiveService/TemporaryItems, but it can rename() com.apple.fileprovider.ArchiveService itself. So even though our PoC cannot access TemporaryItems directly, we can just remove com.apple.fileprovider.ArchiveService, then create the directory structure ourselves. This allows our app to access com.apple.fileprovider.ArchiveService/TemporaryItems, which Archive Utility appears to be fine with, leaving TemporaryItems unprotected. I'm not sure if this is another vulnerability by itself or not, but it allows the PoC to work. This applies to Ventura and above with com.apple.desktopservices.ArchiveService as well. After fixing these issues and resubmitting the PoC to Apple, I got credited in the macOS 15 Security Release Notes under Core Services, which I'm very happy with.

archiveExtractionTest.aar is the AAR I used for testing interception; you don't need to use it, you can just use your own AAR if you wish. output.txt is the file that I used in tests to replace the output. Be aware that I currently have hardcoded links to it in the poc.m, so you will need to change and recompile it to affect where it will be on your file system.