Skip to content

Header

Finding Vulnerabilities in Apple Packages at Scale

September 9, 2025

Csaba Fitzl Csaba Fitzl

This article summarizes work we performed in 2024, which we shared in our “Finding Vulnerabilities in Apple Packages at Scale” talk at MacDevOpsYVR and SecurityFest conferences earlier this year. You can watch the full presentation below: 

MacDevOpsYVR Conference:

SecurityFest Conference:

We’ve written about package vulnerabilities before, but let’s revisit why vulnerabilities in Apple-signed packages can be devastating.

Why System Installers Are Powerful

In macOS, two daemons handle package installer installation: installd and system_installd. The first is invoked when we install third-party packages, the second is for Apple-signed packages. We’ll focus on system_installd, which is more frequently abused. 

Inspecting its code signature will help us understand why it’s an interesting target. Running this command:

codesign -dv --entitlements - /System/Library/PrivateFrameworks/PackageKit.framework/Versions/A/Resources/system_installd

generates a long batch of output about that installer:

Executable=/System/Library/PrivateFrameworks/PackageKit.framework/Versions/A/Resources/system_installd
Identifier=com.apple.system_installd
Format=Mach-O universal (x86_64 arm64e)
CodeDirectory v=20400 size=754 flags=0x0(none) hashes=13+7 location=embedded
Platform identifier=15
Signature size=4523
Signed Time=Dec 21, 2023 at 04:09:49
(...)

One key in that output is particularly interesting:

[Key]com.apple.rootless.install.heritable
[Value]
  [Bool] true

The com.apple.rootless.install.heritable entitlement is very strong. It not only grants the  process access to system areas protected by System Integrity Protection (SIP), but its child processes inherit that permission as well. For an installer, this means any embedded installer scripts - typically bash or perl - will run with those special privileges.

If such a script has an exploitable vulnerability or if we can subvert the installation process in any way, attackers could bypass SIP. Because of this, Apple-signed installers have historically been targets for abuse.

The Inspiration

In 2024, Michael Cowell published a blog post titled “Breaking SIP with Apple-signed Packages,” which detailed research examining the entire Apple Software Catalog for package vulnerabilities. This caught our attention and we thought it would be worth taking a second look ourselves to see if we could discover other problems.

Getting Packages

There are several ways to obtain Apple-signed packages. Two websites allow us to download various installers:

Unfortunately, what we can find here is very limited, and it’s a manually intensive process to download everything one by one, especially since the first site requires user login.

The third option is getting a list of packages from the Apple Software Catalog. This is a software repository available from Apple, which is a big XML property list file containing a list of downloadable software. Each macOS version has its own catalog, following a format similar to this: https://swscan.apple.com/content/catalogs/others/index-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz

Let’s take a look at the key information it contains.

Vulnerabilities in Apple Packages_1

Each entry has an ID which is a 3 digit number followed by a dash and then 4 digits, in the example above, it’s 061-5569. There’s also a list of associated packages, where each entry has a Size and URL. Finally we can find PostDate, which indicates when this package was published.

Since processing this massive XML file can be intensive, along with analyzing all the packages we can download, we decided to use AI, specifically ChatGPT to help with developing some automation.

Automation

We started with a script which helped us determine the scope of work. By analyzing the entire catalog, we found approximately 10,000 packages with a total size of 1.3TB.

Next, we needed scripts to reduce the number of packages we had to inspect manually. Since we were looking specifically for vulnerabilities in the installer script files, we ruled out every package which didn’t contain any. The below bash script did just that.

#!/bin/bash

# Define log file
log_file="3_delete_no_script.log"
# Iterate through all directories and subdirectories
find ./downloads/ -type f -name "*.pkg" | while read -r pkg_file; do
  # Check the contents of the .pkg file
  contents=$(tar -tf "$pkg_file" 2>/dev/null)
  
  # Check if "Scripts" directory is present in the contents
  if ! echo "$contents" | grep -q "Scripts"; then
    # Record the filename with its full path and its contents in the log file
    echo "Deleting: $pkg_file" >> "$log_file"
    echo "Contents:" >> "$log_file"
    echo "$contents" >> "$log_file"
    echo "---------------------------------" >> "$log_file"
    
    # Delete the .pkg file
    rm "$pkg_file"
  fi
done

We also found it important to log deleted packages, in case we need to restore some later.

The next step was deleting old, unsupported packages. Up to macOS Catalina, packages could install files under /System/ or other SIP protected locations. Since Signed System Volume was introduced in macOS Big Sur, this is no longer possible. Packages containing files which would go into these locations simply aren’t installed by the operating system. Therefore, we can delete all of these as well, because they won’t run on modern macOS anyway.

#!/bin/bash

# Directory to search for .pkg files
SEARCH_DIR=$1

# Log file to store the payload contents
LOG_FILE="4_delete_pkg_with_system.log"

# Check if a directory is provided
if [ -z "$SEARCH_DIR" ]; then
  echo "Usage: $0 <directory>"
  exit 1
fi

# Clear the log file
#> $LOG_FILE

# Find all .pkg files in the directory
find "$SEARCH_DIR" -name "*.pkg" | while read -r pkg; do
  echo "Processing $pkg" >> $LOG_FILE
  # Check the contents of the package
  PAYLOAD_FILES=$(pkgutil --payload-files "$pkg" 2>/dev/null)
  if [ $? -ne 0 ]; then
    echo "Failed to read payload files from $pkg" >> $LOG_FILE
    continue
  fi
  #echo "$PAYLOAD_FILES" >> $LOG_FILE

  # Check if any payload file starts with "./System/"
  if echo "$PAYLOAD_FILES" | grep -q "^./System/"; then
    echo "Deleting $pkg as it contains files in the System directory" >> $LOG_FILE
    rm -f "$pkg"
  fi
  echo "---------------------------------" >> "$LOG_FILE"
done

echo "Processing complete. Log file is located at $LOG_FILE"


Next, many of the packages contain only default pre and postinstall scripts, that perform basic logging. This is the same across all installers, and since we didn’t find them vulnerable, we deleted all packages containeing these defaults only.

The SUCatalog also contained many non package installer files, like TAR, ZIP archives, which we could also safely ignore.

Finally, there were specific printer installers which only contained PostScript Printer Description (PPD) files, which could also be removed.

At the end, we had about 300-400 packages to manually inspect. Among these, we found three new vulnerabilities, which we’ll detail below.

General Exploitation Strategy

Since these vulnerabilities allow us to bypass SIP, our goal is to drop a custom TCC database, which is generically SIP protected. However we will do it with a twist, instead of targeting the main TCC.db file, we’ll target:

/Library/Apple/Library/Bundles/TCC_Compatibility.bundle/Contents/Resources/AllowApplicationsList.plist. 

This file is essentially another TCC database, but in a property list format. Although this file is now empty, it used to contain TCC exceptions for third party apps. If we add any entry here that will be processed by the tcc daemon.

NOTE: This file has been discontinued in macOS Sequoia (15), thus this technique no longer works.

CVE-2024-27883 - iDVDExtraContent.pkg - Full SIP bypass

The iDVDExtraContent.pkg installer contains two scripts: nowMoveThemesAside and nowCopyThemesBack, which backup and restore iDVD themes. The issue is that themes are stored in a user (root) controllable location: /Library/Application Support/iDVD/. 

Let’s review the two scripts in more detail, starting with nowMoveThemesAside

Vulnerabilities in Apple Packages_2

The script creates a temporary directory in /Library/Application Support/iDVD/ThemesHolder.XXXX and moves (renames) the existing Themes directory here. This is basically the backup, and it’s fully under our control. Now let’s review the second script.

Vulnerabilities in Apple Packages_3

Here the files are restored at the end of the script from the temporary directory to the original location. This ensures that if the user has any custom themes, they are retained after the installation completes.

Exploiting this is straightforward. We replace the $iDVDThemesFolder directory (which is the target of the ditto copy operation) with symlink pointing to /Library/Apple/Library/Bundles/TCC_Compatibility.bundle/Contents/Resources and drop our AllowApplicationsList.plist into $iDVDMoveAsideFolder so it will be copied by ditto.

CVE-2024-44196 - CanonLaser_FCore.pkg - Arbitrary SIP File Overwrite

The second vulnerability we found is in the CanonLaser_FCore.pkg installer. Although we couldn’t achieve a full SIP bypass this time, it still allowed us to perform an arbitrary file overwrite, which could be used as a DOS attack against various system components, like XProtect. Let’s take a look at the script.

Vulnerabilities in Apple Packages_4

At the last line, we can see that the process list retrieved using the “ps -axw” command is written into a tempfile. Since this temporary file is fixed and is in a user controllable location - /tmp/jp.co.canon.maccups_installer_ps_kill - we can simply place a symbolic link here and point it to our location of our choice. The script will follow the symbolic link, and we can achieve arbitrary file overwrite.

CVE-2024-44253 - RecoveryHDUpdate.pkg - Full SIP Bypass

This is another vulnerability that allowed us to fully bypass SIP, and we again weaponized it to bypass TCC with it. The vulnerability is in the RecoveryHDUpdate.pkg installer, in the replaceRecovery script. Here follows the script with important highlights.

Vulnerabilities in Apple Packages_5

Similarly to previous issues, the main problem is again that the script works on a user-controllable location, /tmp/. It will create a directory, /tmp/recoveryHDUpdatePackage.$$ then extract the package into this folder, locate a DMG (disk image) file and mount it at /tmp/recoveryHDUpdate.$$. Since everything happens inside /tmp/, we can manipulate both the disk image, which is extracted and the mountpoint.

Since we have limited time to manipulate these items, we can pause/start the perl script process as needed. At a high level, in order to exploit the vulnerability, we need to perform the following steps:

  1. Look for the launched perl script process and if found, pause it.
  2. Once stopped, the mount point will be replaced by a symlink, and the DMG will be also replaced by our own DMG. Our DMG will contain a custom AllowApplicationsList.plist file, while the symbolic link will point to /Library/Apple/Library/Bundles/TCC_Compatibility.bundle/Contents/Resources.
  3. Continue the perl process.
  4. Once we find the hdiutil process running, perl will be terminated to avoid unmounting at the end of that script.
  5. Finally, restart the user mode tccd process 

Fixes

In our previous article, we wrote about how Apple is mitigating installer vulnerabilities by using the InstallScriptActions.plist and InstallScriptMutations.plist configuration files in /System/Library/PrivateFrameworks/PackageKit.framework/Resources/. These property list files tell the installer to drop SIP bypass privileges for specific installer - script pairs or even allow dynamic script content replacement. Since we wrote about this, Apple introduced a third file: InstallScriptTries.plist.

This configuration file only lists installer IDs for which SIP will be dropped entirely, not just for specific scripts. If we look into it, we will find the package IDs of all three installers we exploited.

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<plist version="1.0">

<dict>

<key>DropSIP</key>

<array>

(...)

<string>com.apple.pkg.Canon</string>

<string>com.apple.pkg.RecoveryHDUpdate</string>

<string>com.apple.pkg.iDVD</string>

(...)

</array>

</dict>

</plist>

This means that SIP privileges will be dropped for all these installers, and we can no longer exploit the installation process.

Wrap Up

We reviewed how we reviewed Apple’s entire software catalog in order to find vulnerabilities in installers. We used AI to help with automation to reduce the amount of packages we needed to manually inspect. We then reviewed our three different findings, provided a brief summary of how an attacker could exploit each issue, and finally reviewed how Apple fixed the vulnerabilities.

This research reinforces the critical importance of ongoing security analysis of privileged system components. As the threat landscape evolves, systematic approaches like ours - combining automation with targeted manual analysis - will continue to be essential for identifying and addressing potential security risks before they can be exploited in the wild.