MONTREAL — A serious flaw in how macOS handles code signatures can lead to the compromise of multiple applications on Apple computers. Worse, the issue is largely unknown to most Mac users, and even most Mac administrators.
“Because macOS checks code signatures very infrequently, it is easily possible to hijack a legitimate application that is already installed on the system without triggering any kind of code signature check,” said researcher Thomas Reed, director of Mac and mobile research at Malwarebytes.
In a talk at Virus Bulletin 2018 in Montreal on Wednesday, Reed explained that the Mac platform won’t run apps that aren’t code-signed; macOS will automatically block anything trying to execute without a valid signature. The upsides to this are obvious, he noted. “This approach gives Apple really good control over a Mac’s application environment. You can’t distribute an unsigned app, nor can you push out one that’s had its signature revoked,” he said.
However, the way Apple handles this process has a hole in it.
Apps are essentially quarantined when they’re downloaded by a Mac user; any executable is given an initial caution flag. The system then checks the code signature, and makes sure the application is not a known piece of malware. If it passes, the app is given clearance on the machine as a piece of trusted software.
That’s where the issue lies. At that point, macOS stops checking that application, once the quarantine flag is wiped out.
“From now on, it will open as an already-trusted app that never gets checked again by the gatekeeper,” said Reed.
And that means that malefactors can infect almost any application already running on the machine (if, of course, they’ve gained access to the user’s software libraries).
“An attacker would simply replace the legit executable in an app bundle with a malicious copy – and then rename the original to something else,” Reed explained. In a proof-of-concept that he developed, the malicious executable will then launch when the application is called – but it also launches the renamed legitimate file. This means the application will appear to have its usual functionality while the malicious functions launch in the background – so the user isn’t aware of anything being amiss.
“Most people are not at all suspicious of programs they have been using for some time without any issues,” Reed noted.
Reed said that some aspects of this attack have been seen in the wild in the past (and it should be noted that other code-signing problems with Apple have been observed). However, he said that all past incidents have involved altering the code prior to downloading — so doing it after-the-fact represents a new (or at least, very little-known) attack vector.
“We have seen malware using this flaw where the bad actors take a legitimate app, make changes, re-sign it with some other code certificate and redistribute it,” Reed said, noting that this was seen in the distribution of the KeRanger ransomware in 2016. “[But] there have been no modern cases of mac malware modifying a legitimate application that is already on the hard drive.”
Further, the issue is straightforward and easy to exploit. “It’s not rocket science in a way that’s kind of frightening,” he said. Accordingly, the researcher said he was able to take a “scriptkiddy” approach to developing the PoC for the flaw.
“A little basic shell scripting and AppleScripting knowledge, plus a rudimentary knowledge of Swift basics, was all that would be needed, with a little Googling to fill in the gaps,” Reed explained. “Anybody can do this, so this is a little scarier to me than some fancy CVE that an elite hacker would do.”
The resulting PoC consisted of 22 lines of Swift code for the malicious executable, 18 lines of AppleScript for the first part of the dropper, and 16 lines of shell script for the second part of the dropper.
In the PoC, if the dropper executes, it infects all of the applications in the app folder.
There are some silver linings to all of this. For one, there are potential giveaways for users.
For one, the PoC results in “double-dock” icons where the infected app has two icons stacked on top of each other – representing the malicious process and the legitimate one.
“The malicious executable won’t quit bouncing, like a kid on sugar, and the other one looks normal, so it’s immediately suspicious,” Reed said. This can however be rectified with coding changes.
Users can also use the osquery function to check the signatures of their applications.
“This treats the system like an SQL database, and you can do any number of queries,” explained Reed. “After infection, the app will show as unsigned and will have no team identifier, for instance, so you can scan for that. You can also monitor apps for changes.”
There’s also a preventative option, in the form of Santa, a Google tool. It literally determines what’s naughty and what’s nice in terms of code on machines.
And finally, there also are some exceptions when it comes to what’s vulnerable. All of Apple’s own apps and some third-party software do their own internal code-signing checks, and if they fail, they crash.
What’s almost certain is that Apple will be unlikely to address this anytime soon, since macOS is functioning how it’s meant to, Reed said.
“If Apple were checking code signatures on every single process every time one launches – and these systems have thousands of processes – this could be resource-intensive and a real drain on your system,” Reed said. “This will be a long-standing problem. My feeling is that this isn’t going away anytime soon.”
The best approach is for developers to build in checks for their own signatures when they run.
“It’s a shame but I think that’s the only practical way to address this in the short term,” Reed said. He added, “[Unfortunately], most developers are not aware of this, and do not add their own code signature self-checks. This means that there are countless vulnerable Mac applications in existence on the market.”