Executing an app bundle after modifying its resources

Hi,

I am testing the behavior of my app if I change it's app bundle content.

I created an app with a script within it's Resources folder. I signed the app and verify that the code sign is accepted with the spctl command.

Then I modify the script within the app bundle and spctl gives me a sealed resource is missing or invalid which was expected.

However I thought that I wouldn't be able to launch the app bundle now that it is compromised but I was able to execute it.

Do I need to make it go through GateKeeper by first downloading the app from a server? In that case if I download an non-modified app, launch it successfully then modify it, would subsequent launch fail or not?

The app will be delivered through MDM and I think that GateKeeper does not verify MDM-delivered apps.

Is it possible to make the app non-launchable if the files within its Resources folder have been modify/compromised?

Edit: The app won't be installed to /Applications/ but to a specific folder

Thank you in advance!

Accepted Reply

What I am afraid of is if a malicious program modifies the script contained in our app bundle after it is being distributed with our MDM solution.

That’s a valid concern, but only up to a point. If an attacker can modify the script in your app bundle it’s likely that they’d be able to modify other, much-more-easily-exploited files (like ~/.zprofile).

Regardless, macOS does not currently protect your app from such modifications (after the initial Gatekeeper check). For information about what macOS does do, see Apple Platform Security. It wouldn’t surprise me if this changed at some point but I can’t speculate about The Future™.

At a technical level, this is quite hard to do given the flexibility that users expect from macOS. Validating your app’s code signature on launch is never going to fly performance-wise. Try this on your Mac and see how long it takes to come back:

% codesign -v -vvv --strict --deep /Applications/Xcode.app

You could use the code signing API to implement your own checks but that path isn’t great for your mental health. You start thinking “If an attacker can modify my app’s script, they could just as easily modify the code doing the actual check.” and things spiral out of control from there (-:

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • That's not a fair comparison. You are doing codesign on Xcode. 😄 Checking the code signature on a normal app takes a fraction of a second and can be done on a background thread.

    Things can spiral. In the past, there was a possibility that an attacker could modify the operating system itself. I don't know if this is even possible with the sealed volumes in Monterey. It is possible to check for unexpected dynamic libraries injecting code. One trick the pirates did was wrap my app with another app having an identical icon, inject changes between the OS and the app, and then run my app in the new environment. So my code signature was always valid. I had to check for a wrapping app and unexpected dylibs.

Add a Comment

Replies

Do I need to make it go through GateKeeper by first downloading the app from a server?

Yes.

Well, macOS may check code signatures under other circumstances. The exact details of when it runs such checks are not documented. However, it’s safe to say that it will happen as part of a full Gatekeeper check.

For specific advice on how to test this, see Testing a Notarised Product.

The app will be delivered through MDM and I think that GateKeeper does not verify MDM-delivered apps.

Honestly, I’m not 100% sure. However, I’m curious about your threat model here. What are you trying to protect yourself from? Because if your MDM infrastructure is installing malicious apps, you have bigger concerns.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thank you eskimo for your answer.

What I am afraid of is if a malicious program modifies the script contained in our app bundle after it is being distributed with our MDM solution.

From manual test I did it seems that the app will run even if the script has been compromised.

I thought that by code signing the app it would prevent the app launch when the content changed.

  • That behaviour would break several Household Name apps.

    You can implement your own stricter code signature checking. Don't forget to check for code injection.

    You don't really have to worry about malicious apps. That's more of a social media thing. It's the software pirates you have to worry about. That's your threat.

Add a Comment

What I am afraid of is if a malicious program modifies the script contained in our app bundle after it is being distributed with our MDM solution.

That’s a valid concern, but only up to a point. If an attacker can modify the script in your app bundle it’s likely that they’d be able to modify other, much-more-easily-exploited files (like ~/.zprofile).

Regardless, macOS does not currently protect your app from such modifications (after the initial Gatekeeper check). For information about what macOS does do, see Apple Platform Security. It wouldn’t surprise me if this changed at some point but I can’t speculate about The Future™.

At a technical level, this is quite hard to do given the flexibility that users expect from macOS. Validating your app’s code signature on launch is never going to fly performance-wise. Try this on your Mac and see how long it takes to come back:

% codesign -v -vvv --strict --deep /Applications/Xcode.app

You could use the code signing API to implement your own checks but that path isn’t great for your mental health. You start thinking “If an attacker can modify my app’s script, they could just as easily modify the code doing the actual check.” and things spiral out of control from there (-:

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • That's not a fair comparison. You are doing codesign on Xcode. 😄 Checking the code signature on a normal app takes a fraction of a second and can be done on a background thread.

    Things can spiral. In the past, there was a possibility that an attacker could modify the operating system itself. I don't know if this is even possible with the sealed volumes in Monterey. It is possible to check for unexpected dynamic libraries injecting code. One trick the pirates did was wrap my app with another app having an identical icon, inject changes between the OS and the app, and then run my app in the new environment. So my code signature was always valid. I had to check for a wrapping app and unexpected dylibs.

Add a Comment

That's not a fair comparison. You are doing codesign on Xcode.

Right. My point is that, if macOS were to check code signatures on every launch, it would have to deal with apps the size of Xcode.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • That is true, but you did specifically say, "Validating your app’s code signature on launch is never going to fly performance-wise." Unless gmorimoto is shipping an app of the scale of Xcode, then validating that app's code signature would be fast and easy.

Add a Comment

Thanks Eskimo! We will consider about using the codesigning API or another way to validate our script.

And thanks nk_kennedy for the comments!