New macOS vulnerability, Migraine, could bypass System Integrity Protection

A new vulnerability, which we refer to as “Migraine” for its involvement with macOS migration, could allow an attacker with root access to automatically bypass System Integrity Protection (SIP) in macOS and perform arbitrary operations on a device. We shared these findings with Apple through Coordinated Vulnerability Disclosure (CVD) via Microsoft Security Vulnerability Research (MSVR). A fix for this vulnerability, now identified as CVE-2023-32369, was included in the security updates released by Apple on May 18, 2023.

SIP is a security technology in macOS that restricts a root user from performing operations that may compromise system integrity. Bypassing SIP could lead to serious consequences, such as increasing the potential for attackers and malware authors to successfully install rootkits, create persistent malware, and expand the attack surface for additional techniques and exploits. The technique uncovered in this blog post was discovered during routine malware hunting and is similar to the one used in the Shrootless vulnerability (CVE-2021-30892) that we published in 2021. By focusing on system processes that are signed by Apple and have the entitlement, we found two child processes that could be tampered with to gain arbitrary code execution in a security context that bypasses SIP checks.

In this blog post, we share some information about the relationship between SIP and entitlements, and we detail how the “Migraine” vulnerability could be exploited to bypass the SIP security enforcements. We’re sharing this research with the larger security community to emphasize the importance of collaboration in the effort to secure platforms and devices.

As previously covered in our Shrootless vulnerability blog post, System Integrity Protection (SIP)—also known as “rootless”—was first introduced by Apple in macOS Yosemite. SIP essentially locks down the system from root by leveraging the Apple sandbox to protect the entire platform, conceptually similar to how SELinux protects Linux systems. One of the most dominant features of SIP is the filesystem restriction capability, which protects entire files and directories from being overridden. The files and directories that are protected by SIP by default are commonly ones that are related to the system’s integrity.

There is no way to turn off SIP on a live system—the user must use the recovery OS, which requires physical access to the device. A SIP bypass is a vulnerability that bypasses SIP restrictions, for example, bypassing restrictions to write to SIP-protected directories or create a SIP-protected file.

Another important macOS concept is entitlements. According to documentation, “an entitlement is a right or privilege that grants an executable particular capabilities”. As entitlements take part in the app signing process, there is no legitimate way of forging them. Apple uses entitlements extensively to enforce security on macOS, and Apple grants internal entitlements to very specific processes. Specifically, certain processes are assigned entitlements that allow the process to bypass System Integrity Protection checks by design. One particularly interesting entitlement is the entitlement that allows the process and the entire process tree rooted under it to bypass filesystem-based System Integrity Protection security enforcements.

Our research team regularly looks for malware and suspicious activity. During a routine malware hunt, we discovered the execution of a binary called drop_sip using the below advanced hunting query in Microsoft 365 Defender:

| where FileName =~ "drop_sip"
| project InitiatingProcessFileName, ProcessCommandLine, SHA256

Thinking that we found an exploit in the wild, we found that it’s an Apple-signed binary that resides natively under the /System/Library/PrivateFrameworks/SystemMigrationUtils.framework/Resources/Tools/drop_sip path.

Upon analysis, the file appears to invoke the csops system call (undocumented, but available here) and starts a child process. The operation flag for the csops call is 12 (CS_OPS_CLEARINSTALLER), which re-enables SIP checks by clearing codesigning flags, specifically the CS_EXEC_INHERIT_SIP flag:

Code displaying drop_sip’s functionality
Figure 1. drop_sip’s functionality is to change the code signing flags and execute a child process
Code displaying re-enabling SIP
Figure 2. Modification of the p_csflags member as a result of the csops system call – re-enables SIP

Because of this behavior, we concluded the drop_sip process assumes it can bypass SIP. However, since drop_sip is not entitled with any SIP-bypassing entitlements, we concluded that it must inherit that capability. We discovered its parent process is systemmigrationd, which is a daemon designed to handle migration scenarios, but most importantly, it’s entitled with the entitlement that allows its child processes to bypass SIP security checks:

Code displaying systemmigrationd entitlements
Figure 3. systemmigrationd entitled with SIP-bypassing capabilities

After discovering the parent process of drop_sip, we wondered if there are any other child processes of systemmigrationd. Just as before, we used the below advanced hunting query in Microsoft 365 Defender:

| where InitiatingProcessFileName =~ "systemmigrationd"
| summarize Hits=count(), Cmdline=any(ProcessCommandLine) by FileName

We found two interesting child processes of systemmigrationd:

FileName Hits Cmdline
bash 498 /bin/bash /System/Library/PrivateFrameworks/SystemMigration.framework/Resources/MigrationData/Scripts/firstbootDirectoryServer
perl 171 /usr/bin/perl /usr/libexec/migrateLocalKDC –source “/Volumes/REDACTED/Backups.backupdb/REDACTED/Macintosh HD – Data” –source-REDACTED

The bash and perl binaries are interesting because they are both interpreters. Similar to how we tampered with the zsh codeflow back in 2021, we found similar ways to tamper with the code flow of bash and perl:

Code displaying running arbitrary commands in bash instances
Figure 4. The bash manual page states BASH_ENV as a way to run arbitrary commands in bash instances
Code displaying running arbitrary commands in perl instances
Figure 5. The “perlrun” manual page states PERL5OPT as a way to run arbitrary commands in perl instances

Assuming an attacker first gains code execution capabilities as root, setting environment variables that affect systemmigrationd and its child processes is straightforward using the launchctl utility. For instance, to make perl run our arbitrary code that resides under /private/tmp/, we use:

launchctl setenv PERL5OPT '-Mwarnings;system("/private/tmp/")'

And indeed, after triggering systemmigrationd to run perl, we were able to bypass SIP:

Code displaying SIP protections making a file undeletable
Figure 6. Creating an undeletable file due to its SIP protection.

Exploitation approach

Triggering migration normally requires using the Migration Assistant utility, which involves a complete sign-out from the system. While this works well for attackers with physical access (hands-on-keyboard), we wished to demonstrate that remote attackers can achieve a SIP bypass using this exploit. Therefore, we decided to research the migration flow and the interplay between the Migration Assistant and systemmigrationd.

Migration is a complicated procedure that involves several components. Here is the flow of key events:

  1. Migration Assistant uses a utility called Setup Assistant to help start migration. However, it does so indirectly by using XPC between itself and another process called MBSystemAdministration. It also signs out by invoking a method named SACLOStartLogoutWithOptions.
  2. The MBSystemAdministration utility proxies requests from Migration Assistant to Setup Assistant and also verifies that the caller (Migration Assistant) has the entitlement. Otherwise, it refuses serving migration requests. Additionally, MBSystemAdministration runs as the hidden user _mbsetupuser, which allows migration to perform GUI interactions after sign out.
  3. Setup Assistant gets requests through MBSystemAdministration and performs XPC to several Mach services that are served by the launch daemon systemmigrationd. The systemmigrationd daemon enforces that the caller (Setup Assistant) has the entitlement. Otherwise, it refuses serving migration requests. The systemmigrationd daemon uses the private framework SystemMigration.framework and listens to new migration requests by invoking a method called startListeningForConnections. Interestingly, the daemon examines the contents of the directory /Library/SystemMigration/Queue (which is protected by SIP)—requests appear as files in that directory. Once a file is dropped, systemmigrationd renames the file to “In-Flight” and serves it, including running required scripts, which can cause perl or bash to run.

This complex flow can be illustrated with the following schematic:

Flow diagram of macOS migration
Figure 7. Flow diagram of the macOS migration
Code displaying systemmigrationd listening to incoming connections
Figure 8. systemmigrationd using the private SystemMigration framework to listen to incoming connections

Our first attempt at automating the exploit focused on patching Migration Assistant to prevent user sign-out:

Code displaying SACLOStartLogoutWithOptions
Figure 9. Reverse engineering the Migration Assistant reveals the SACLOStartLogoutWithOptions function,c which signs out

Simply patching Migration Assistant does not work due to codesign failure. Stripping the binary of signing information results in error (Figure 10) due to a kernel feature related to Pointer Authentication Codes (PAC) that’s available for the latest Apple Silicone architecture. If an arm64e binary with pointer authentication is not a code-signed platform binary, the kernel prevents execution, as shown in Figure 9. Extracting, stripping, and patching the x64 portion of the multiarchitecture binary avoids the arm64e issue, but it’s not functional due to losing the required entitlement (

Code displaying PAC requirements
Figure 10. Pointer Authentication Code requirements
Code displaying the failed patch and run attempt of the Migration Assistant
Figure 11. Attempting to patch and run the Migration Assistant fails

After reaching an impasse with patching Migration Assistant, we wondered if we could initiate later stages in the flow diagram, thus avoiding user sign-out. We continued to map and reverse-engineer the system behavior, including using an in-house researcher tool which leverages the Endpoint Security Framework that logs all relevant process and file events during migration, inspired by Patrick Wardle’s FileMonitor and ProcessMonitor tools for investigating system behaviors.

While mapping the sequence of events for Migration Assistant, MBSystemAdministration, Setup Assistant, and systemmigrationd, we noticed xpcproxy executing Setup Assistant with the argument ‑MiniBuddyYes.

Running Setup Assistant with that argument had no effect on the UI layout or its functionality, but it did highlight the usage of arguments within Setup Assistant. Closely examining Setup Assistant, we discovered other interesting command-line arguments:

Code displaying Setup Assistant's usage of -MiniBuddyYes
Figure 12. Setup Assistant’s usage of -MiniBuddyYes within useDebugParameters

Additionally, we discovered a function called useDebugParameters that parses an interesting command-line parameter ‑MBDebug.

Code displaying Setup Assistant –MBDebug
Figure 13. Setup Assistant –MBDebug

Running the Setup Assistant with the ‑MBDebug parameter results in a successful migration with no sign out. We further used the -ResumeBuddyYes parameter in conjunction with ‑MBDebug to automatically skip a few welcome screens.

Successful migration run without signing out
Figure 14. Running a migration without signing out

Since performing migration requires UI interaction, but no sign-out, we used AppleScript to automate the exploit.

Our final exploit does the following:

  1. Prepares a small 1GB Time Machine backup and attaches it with hdiutil.
  2. Prepares an arbitrary payload that is designed to run without SIP filesystem restrictions.
  3. Sets the environment variable PERL5OPT using launchctl to run the payload once perl starts.
  4. Runs Setup Assistant with the -MBDebug and -ResumeBuddyYes command-line flags.
  5. Uses AppleScript to automate the Setup Assistant screens to migrate “From a Mac, Time Machine backup or Startup disk”, followed by automatically clicking “continue”.

The implications of arbitrary SIP bypasses are serious, as the potential for malware authors is significant. Code that maliciously bypasses SIP could have considerable consequences, such as:

  1. Create undeletable malware: The most straight-forward implication of a SIP bypass is that, by assigning files with the extended attribute (or overriding existing ones), an attacker can create files that are protected by SIP and therefore undeletable by ordinary means. This is quite important for security solutions, such as Microsoft Defender for Endpoint, that are required to quarantine malware but cannot quarantine files protected by SIP.
  2. Expand the attack surface for userland and kernel attacker techniques: As pointed out by Mickey Jin’s blog post on a different SIP bypass, it’s possible for attackers to gain arbitrary kernel code execution. As Apple slowly disallows third party kernel extensions and transitions the Mac ecosystem towards their Endpoint Security framework, security solutions will no longer be able to monitor the kernel for malicious activity, including malicious code executions.
  3. Tamper with the integrity of the system, effectively enabling rootkits: This is a derivation of arbitrary kernel code execution—once kernel code execution is established by an attacker, certain rootkit techniques are possible, such as hiding processes or files from all monitoring tools. These techniques might also include bypassing tamper protection, which is important for Microsoft Defender for Endpoint to protect against threats.
  4. Full TCC bypass: As pointed out by Mickey Jin’s blog post on a different SIP bypass, attackers could replace databases that control Transparency, Consent, and Control (TCC) policies (TCC.db), effectively granting arbitrary applications access to private data and peripherals. For further explanation about the implications, we’ve demonstrated a TCC bypass in the past called “Powerdir”.

Attackers continue to seek new footholds into increasingly secure devices and networks, oftentimes by leveraging unpatched vulnerabilities and misconfigurations to access valuable systems and data. Gaining the ability to bypass SIP and similar security technology in macOS devices can be an attractive and even necessary capability for adversaries. Given SIP’s position as both a device’s built-in baseline protection and the last line of defense against malware and other threats, bypassing SIP can have considerable consequences for users. As such, it’s crucial that we strive to enrich our protection technologies across platforms against such issues through research-driven protection and collaboration with partners, customers, and industry experts.

This case displays how collaborative research and responsible vulnerability disclosure informs our comprehensive protection capabilities across platforms to provide organizations a complete picture of their security posture. Microsoft Defender Vulnerability Management quickly discovers and remediates such vulnerabilities while Microsoft Defender for Endpoint detects and alerts on anomalous device activities, including setting perl and bash environment variables through the launchctl utility, as shown below in Figure 15. Additionally, Defender for Endpoint has similar detections for sensitive file access, including system launch daemons, various sensitive configuration files, and many more.

Microsoft Defender for Endpoint detecting the PERL5OPT environment variable being suspiciously set
Figure 15. Microsoft Defender for Endpoint detecting the PERL5OPT environment variable being suspiciously set

This case further emphasizes the need for responsible vulnerability disclosures and expert cross-platform collaboration to mitigate issues such as CVE-2023-32369, regardless of the vulnerable device or platform in use. We wish to thank the Apple product security team again for their efforts and responsiveness in addressing the issue.

Defending against the evolving threat landscape requires the ability to protect and secure users’ computing experiences, whatever the platform. As cross-platform threats continue to grow, we will continue to share vulnerability discoveries and threat intelligence in addition to working with the security community to improve upon solutions that protect users and organizations each day.

Jonathan Bar Or, Michael Pearse, Anurag Bohra

Microsoft Threat Intelligence Community