I was lucky enough to get a great tip from MalwareBytes’ Thomas Reed this week on the possibilities of code hijacking.
Thomas was kind enough to share details of a talk he gave at MacTech last year, in which he demonstrated how some 3rd party apps are susceptible to having their binaries replaced by a fake binary even when the original application is properly code signed with a valid developer’s signature.
The vulnerability lies not so much in the code signing itself, but in the mechanism for when and why it gets checked. In short, code signing is checked when an app is first launched, but after that, except in a few special situations, macOS’s security mechanisms pretty much ignore it. That means once an app has passed GateKeeper, it’s a ripe target for attackers to come in and replace the binary with one of their own.
In order to ensure the app on disk is still in fact the app that was downloaded and first launched, developers need to implement a check on each launch.
The key to it is what you specify in the entitlement constant. In this example, I’ve specified three things: that the code is signed by Apple, that is has the app’s bundle identifier and that it has the developer’s Team ID. Don’t forget to change my dummy values for your real ones in the code! You can get all these details for your app by running this in Terminal:
codesign --display -r- <path to your app>
With that information, the function verifies that the application in memory meets the requirements specified in the entitlement.
Call the function at some point after launch (e.g, when your main nib has loaded) and handle the boolean result appropriately. For example, if the function returns false, you might throw an alert like this one from DetectX Swift telling the user that the app is damaged and needs to be re-downloaded, and then terminate the app when they hit “OK”:
Let’s keep our code (and users!) safe everybody. 🙂
The quickest way to get out of a persistent popup that won’t go away (unless you do what it demands!) is to quit or force quit* the browser then restart Safari holding down the ‘Shift’ key.
Holding down Shift allows Safari (or any other app) to restart without resuming its last state.
While this is a great, fast way to solve the problem, it can be annoying if you had other tabs open, and you don’t want to loose those too (or any unsaved data they may contain).
1. Go to Terminal and paste this command (it’s all one line):
2. Reopen Safari
You’ll get all your tabs back including the hijacked tab, but the pop up won’t appear, and you can now close the hijacked tab.
(alternatively you can do that in Terminal).
Don’t forget this step, or you’ll think the web is broken!
*You can force quit an app by pressing the following keys in combination on your keyboard <command><option><esc> then choosing the app you want to quit.