At Root3 we always focus on bringing the best Apple user experience while also making sure users and data stay secure. Also we contribute to the Mac Admins community, for example with our Support App for macOS to bring IT and end-users closer together. The Support App is an open source project so we are fully transparent in how the tool is built and what it does. Last month we received a report from a security researcher and made us aware of an issue in Z shell scripts used in the postinstall script for the Support App installer. In this blog we would like to tell you more about what this means, how we resolved this for our products/services and our recommendations for fellow developers and Mac Admins.

Since we updated the Support App to version 2.5.2 and published the security report on GitHub, it was quickly picked up in the community and got a lot of people thinking where to put this ‘issue’. Should developers and Mac Admins do something about it? Or should Apple release a patch for this?

During our development cycles we start with the principles ‘secure by design’ and ‘privacy by design’, but of course there may always be some vulnerabilities in a product which we don’t know about. It exists in every single software product and we just have to accept this may happen sometimes. When we first read the private report, we didn’t think it would lead to the attention we received after we published the update.

The issue

So what is the issue? A brief summary of the vulnerability as reported to us by Carlos Polop, a Spanish senior security researcher:

“It’s possible to abuse a vulnerability inside the postinstall installer script to make the installer execute arbitrary code as root. The cause of the vulnerability is the fact that the shebang #!/bin/zsh is being used. When the installer is executed it asks for the users password to be executed as root. However, it’ll still be using the $HOME of the user and therefore loading the file $HOME/.zshenv when the postinstall script is executed. An attacker could add malicious code to $HOME/.zshenv and it will be executed when the app is installed.”

First, why would we be using Z shell in our post install script, or use Z shell in general? Well, primarily because this is the default login shell on macOS since macOS Catalina was released in 2019 and replaced bash. Z shell also provides additional features which we sometimes use in our scripts such as the function is-at-least as a very simple example to compare macOS versions and create conditions around it. Bash is still present in macOS and we could have also used Bash as a postinstall script. But years ago after this change, we decided to use Z shell scripts by default and leverage its features whenever we need to. Apple even has a knowledge base article about the change and how to verify scripts compatibility: https://support.apple.com/en-us/102360

Of course we wanted to verify the Proof of Concept before doing anything about it, but quickly we found this was easily reproducible. Also we were realizing, this has nothing to do with our Support App specifically. But because the installer package is using a Z shell postinstall script, our app was vulnerable to this issue. This also means any other installer package using a Z shell script is vulnerable. We then exchanged some information with Carlos and when we told him this is a general issue for all installer packages with Z shell scripts, he confirmed. We were curious and checked some other open source projects to see if those are perhaps also impacted, which was the case. Apparently Carlos already contacted some other project owners and asked them to implement a fix in order to get some real-world examples and fixes to be able to convince Apple and improve this logic in the macOS installer.

Because the issue was reported using GitHub’s feature to private report a security issue, we were able to request a CVE number for this and GitHub granted us one. As the fix (we’ll come to that later) for this is relatively easy and Carlos asked us to publish the security advisory, we implemented this and released version 2.5.2 together with the mentioning of the fix of CVE-2024-27301.

Apparently Root3 was the first to release a public fix and mention the issue which led to some opinions in the community about openly talking about this. We think an important question is: who should be fixing this or is this just ‘as designed’ within Z shell (not even by Apple) and should we be making fellow developers and Mac Admins aware of this and improve best practices?

The impact

Even though privilege escalation to root sounds very scary, the general opinion is that if an attacker is able to abuse this, there is already some form of persistence on the device and the attacker has to wait for an event to happen and also needs to be triggered with administrative privileges. But in addition to installer packages, we have also found that running Z shell scripts using MDM solutions are also impacted, but only in certain scenarios. A very simple example allowed us to be a ‘bad’ user with standard permissions and put code in the .zshenv file to elevate the user account to an administrator by just running a Z shell based utility from the Jamf Pro Self Service application without requiring any administrative authorization. That is why we think this issue is especially more ‘interesting’ for clever end-users with standard permissions to bypass IT and do all sorts of local administrative tasks. In our tests we could not reproduce with a Jamf Pro policy triggering at check-in so it appears there must always be a user initiated action, which matches the Z shell theory. But again, some MDM scenarios can be abused and the user would only need an item with a Z shell script behind it. At this time, we haven’t tested all MDM solutions but we might see similar results there.

How to fix?

The simplest fix we found is basically changing the shebang inside the Z shell script from:

#!/bin/zsh

To:

#!/bin/zsh --no-rcs

This makes sure to tell the script not to load any user configuration files and code set in the .zshenv file in the user’s home folder. Of course to fully prevent the issue from triggering, all Z shell scripts and packages that run should change the shebang to either the updated version or change to Bash or Bourne shell.

A more technically detailed and excellent post was also published last week on Scripting OS X: https://scriptingosx.com/2024/03/zsh-scripts-and-root-escalations/

How is Root3 handling this?

Without pointing any fingers where and how other parties should bring a permanent fix, we think it is good that as many developers and Mac Admins are aware of this and implement the fix mentioned earlier. And when we continue to use Z shell scripts, we would be adopting the updated shebang as the new best practice in the industry.

That’s exactly what we did and we updated all of our scripts being used for our customers across MDM solutions and applications to make sure our solutions will not trigger the issue. Also our automated patch management solution, App Catalog, received an update to version 1.3.1 with this fix implemented.

If you’d like to learn more or discuss the potential impact for your organization, please contact us at [email protected] or +31 85 400 30 30.