Tales of the CVE-2023-42931

Introduction

As a pentester who almost never put his hands on a Mac since Apple mac OS X in the 2000's...

I was in a situation where I had to find a local privilege escalation (LPE) on a macOS 13 Ventura.image-png-Dec-12-2023-04-54-27-9113-PM-1

As the saying goes, Apple macOS is basically a "fancy" Linux, so I naturally looked at technics I'm used to seeking on Linux systems, including issues related to setuid and mounting options.

 

Findings

I quickly learned that on macOS system, all local users (including the "guest") can mount filesystems using the "diskutil" command line utility.

This command is accepting mount options through the "-mountOptions" arguments. Looking at the manpage, two mount options may be interesting to trigger a privilege escalation:

1. owners/noowners: it enables/disables support for users ownership, so in "noowners" mode: it acts as if all files were belonging to the current user (UID=99), while "owners" mode preserves original ownership of each file. This option does not affect permissions which are preserved between both modes; new files created in "noowners" mode will be owned by their creator, but files modified in "noowners" mode will preserve their original ownership while mounted back in "owners" mode;
2. suid/nosuid: this enables/disables the support for setuid/setgid bits.

So I should be able to escalate to root if I can:

1. Mount a filesystem with "noowners";
2. Modify a root owned file into an arbitraty binary;
3. Add the setuid bit to it, then remount it in "owners" mode.

 

However, modern macOS disk/filesystem hierarchy is quite weird. Plus, I'm doing my research inside a QEMU VM running macOS from my Linux, and that doesn’t help here either…

Anyway, my root filesystem ("/") comes from /dev/disk3s4s1, which is a snapshot of /dev/disk3s4, which is not mounted by default.

The good news is that I can mount /dev/disk3s4 with the "noowners" flag:

The bad news is that lots of files/folders are still owned by root, instead of being owned by my current user "test" despite the "noowners" flag being set…

But I just need one file after all, so let's modify one that is considered as self-owned in "noowners" mode:

WTF can’t I write a file I own!?!

It turns out that there is a thing called SIP (for "System Integrity Protection") which prevents the modification of sensitive system files and folders at a kernel level, so that even the root user can’t modify those.

 

So I need to find a file that is:

1. Owned by root when mounted in "owners" mode;
2. Considered owned by myself when mounted in "noowners" mode;
3. Not protected by SIP.

After running tones of "ls" (to check ownerships) and "touch" (to test for SIP protection), trying some weird "find –exec" formulae to automate it, I found the one I should have seen quickly: there is a ".file" placeholder file in the root filesystem ("/") that matches the 3 requirements.

image-png-Dec-12-2023-04-55-22-4764-PM-1

 

How to exploit

1. Prepare a payload

So let's write a simple setuid shell payload and compile it with Xcode into a suidshell binary.

image-png-Dec-13-2023-01-26-33-3623-PM-1

2. Run the exploit

1. Mount the targeted filesystem with the "noowners" flag:

2. Make ".file" writable (even its owner can't write it by default):

3. Copy the suidshell binary into ".file":

4. Set ".file" permissions including execution for all and setuid bit:

5. Remount the filesyem in "owners" and "suid" mode (which is the default here):

6. Run the suidshell et voilà!

 

Affected assets

MacOS Sonoma before 14.2

MacOS Ventura before 13.6.3

MacOS Monterey before 12.7.2

Note: I did not personally test this on macOS 12, but Apple considered it vulnerable and patched it so I assume macOS 12 (and probably previous ones which are no longer supported by Apple) was vulnerable.

 

In Ventura (and probably before), this exploit can be achieved from any user (including the "guest").

In Sonoma, if you try exploiting from a user which is not in the "admin" group, you will be asked for an admin password, so you will not be able to elevate your privilege. This vulnerability is however still relevant on Sonoma as it allows an "admin" user to go root without typing their password (whereas when a user in the admin group tries to make an action requiring root privileges, like running sudo, their password is asked).

 

Timeline

  • 24/10/2023: Initial finding

  • 26/10/2023: Vulnerability reported to Apple

  • 31/10/2023: Apple tagged it as "Reproduced"

  • 04/12/2023: Apple associated CVE-2023-42931 to the vulnerability

  • 11/12/2023: Vulnerability fixed in macOS versions 14.2, 13.6.3 and 12.7.2

  • 23/03/2024: Entry added in macOS security advisories

Capture-Mar-25-2024-08-51-11-3390-AM

Source: https://support.apple.com/en-us/HT214036

 

The patch

Apple patched this vulnerability by ignoring the "noowners" mount option while mounting internal storage with diskutil (even when launched as root using "sudo").

 

Conclusion

This vulnerability does not require any reverse engineering skills to be found, understood or exploited. It turns out to be a local privilege escalation with an easy, stable and reliable exploit.

Its impact is that anyone with an access to a local account (including the "guest") can elevate his privilege to root. Even if it works only from an "admin" user account on macOS 14 Sonoma, it still can cause lot of harms, e.g. if the exploit is ran silently by a malicious unsandboxed App. It may be even more impactful when associated with a sandbox escape, allowing a sandboxed App to escape to root. So patch your macOS ASAP!

 

Share this article