I was wondering if it's possible to build a Mach-O file, or modify an existing one and then re-sign it so that the code sections will be encrypted.
I know that there's a flag called cryptid that represent the encryption type (by values `EncryptionInfo32/64 for load commands LC_ENCRYPTION_INFO_32/64 respectively)
However, I couldn't find anywhere in Xcode for how it's done.
EDIT : I'm well aware that it can be done in iOS, but my question relate to macOS, does the platform support this encryption feature in Mach-O file ?
EDIT2: So after reading the other question I understood that the whole encryption thing can only be done by appStore which is after the Mach-O file is already left the developer side. So in this case, Apple actually controlled the encryption/decryption algo+key and it's completely outside the developer hand, right ?
Also, since the Mach-O is being changed during the encryption, so who's in charge to re-sign the application ?
Thanks
No, you cannot do this.
The only "supported" way of getting LC_ENCRYPTION_INFO added to your binary is by distributing through the iOS App Store. It is Apple who checks your binary for compliance with their rules, then encrypts the binary and re-signs it.
This is all backed by "FairPlay", Apple's proprietary DRM stack. Not much is known about it since the code is heavily obfuscated, but it is widely believed that it's built on features of Apple's custom hardware AES engine. Given this, it may or may not be possible to create an encryptor yourself, but it would require immense reverse engineering efforts to even find out.
Further, the entire FairPlay stack is only present on Apple's own chips. It is indeed available on M1 Macs, as you can install iOS apps off the shelf (so long as you leave SIP enabled), but it is not available at all on Intel Macs (the relevant kexts are IOTextEncryptionFamily.kext and FairPlayIOKit.kext, the latter of which is obfuscated).
Related
we have developed a kernel extension (KEXT) for a virtual file system (VFS) on macOS to integrate our software with external programs like Adobe InDesign or Microsoft Word. Our software and the KEXT are used by many of our customers.
As it looks like KEXTs are deprecated and may be removed completely in future versions of macOS, particularly on Apple Silicon based computers. See e.g. Apple's announcement in its security guide:
"This is why developers are being strongly encouraged to adopt system extensions before kext support is removed from macOS for future Mac computers with Apple silicon"
Therefore we are currently investigating in possible alternatives.
Apple suggests to migrate to System Extensions instead of KEXTs. However, the only VFS related API we found is to implement a File Provider that is based on an NSFileProviderReplicatedExtension.
Unfortunately that NSFileProviderReplicatedExtension has several flaws:
Files can either be in the cloud or downloaded. It is not possible to download/read only a portion of a file. This is a big performance problem for us, since we work with large images (> 1GB). The programs we integrate with typically only read a part of the image, e.g. the embedded preview. The API does not offer a way to access selected blocks of a file (random access file).
The File Provider learns about the file system content via enumerators. So everything that is inside a folder must be enumerated (listed) first. Otherwise it cannot be accessed. However, we cannot enumerate our VFS. Most of the content of our VFS is fully dynamic. It only exists when it is accessed by a client the first time. Such dynamic content also includes dynamic parameters like the client's locale or the size of a box where the image will be placed. Since we do not know those parameters in advance, we cannot enumerate the VFS's content in advance.
This means, an NSFileProviderReplicatedExtension in its current state isn't a replacement for a "real" VFS and therefore cannot be used by us as a replacement for our current VFS KEXT.
My questions:
Will Apple allow kernel extensions also in future versions of (Apple Silicon/M1 based) operating systems? Or is there at least a clear deadline?
If not, what is Apple's officially suggested replacement for KEXT based VFS solutions?
Will the API of an NSFileProviderReplicatedExtension be improved to behave like a "real" file system so that above mentioned flaws will no longer be an issue?
Many thanks for any answers or comments!
Best regards,
Michael
Will Apple allow kernel extensions also in future versions of (Apple Silicon/M1 based) operating systems? Or is there at least a clear deadline?
Apple doesn't really give timelines, and they also occasionally break promises of support.
However, this sort of hard API deprecation and removal usually is done as part of a major release, so you will typically get deprecation notice for it at WWDC one year, users might start seeing deprecation notices when the .0 of the OS release ships at the earliest, and sometimes the .3 or .4 revision. Then you'll typically be told at the next WWDC that the API is blocked in the upcoming release, so by that point you should have implemented a replacement.
If not, what is Apple's officially suggested replacement for KEXT based VFS solutions?
As far as I'm aware, NSFileProviderReplicatedExtension is currently the only one.
Will the API of an NSFileProviderReplicatedExtension be improved to behave like a "real" file system so that above mentioned flaws will no longer be an issue?
Other than via beta SDKs, Apple generally doesn't pre-announce future APIs.
My advice:
File issues for each of the file provider shortcomings you are hitting using Feedback Assistant. (Radar)
File an "enhancement request" feedback issue with Apple for a "real" file system API replacement for the VFS KPI.
If your vfs kext is critical to your business/product, I suggest additionally asking Apple's DTS via a TSI what they recommend for your situation. Reference the feedback IDs of the issues filed, otherwise they will recommend that you file issues.
This is a straightforward question that I was not able to determine with a bit of research.
In macOS, are binaries signed or are applications (e.g. *.app) signed? I have found evidence of the latter (and a tool called codesign that can check signatures and even show which files were modified), but am unsure of the former.
For example, are base user utilities (e.g. cp, grep, ls, etc) all signed? Or are they somehow bundled in with the Terminal.app that is itself signed? What about utilities that are not part of an .app bundle? Can they be individually signed? Where does this signature live?
In general, how does signing work in macOS and how is it enforced? Does the loader check and validate the signature, or does the kernel? It would seem the loader would also need a signature.
RTFM
Code Signing Guide
https://developer.apple.com/library/content/documentation/Security/Conceptual/CodeSigningGuide/Introduction/Introduction.html
Technical Note TN2206 / macOS Code Signing In Depth
https://developer.apple.com/library/content/technotes/tn2206/_index.html
Assuming you only have access to the final product (i.e. in form of the exe file), how would you go about finding out which libraries/components the developer used to create the application?
In my specific case the question is about an application developed in VC++ using a few third party components and I'm curious which those are.
But I think the question is generally valid, e.g. when it should be proven if a developer is in line with license requirements of a specific library.
So, what you're saying is that if I suspect that a binary is using a certain library, I could try to map the respective function calls and see if I get a result. But there is no shortcut to this and unless I am willing to try out hundreds of mappings or the dev left some information in some strings or other resources, I have little chance of finding this out. Yes?
There is small shortcut, here's what I'd do:
check executable for strings and constants, and try to find out what library is that.
IF used libraries are open-source, compile them on my own and create FLAIR signatures (IDA Pro).
Use generated flair signatures on target executable.
In some situations, that can really work like a charm and can let you distinguish actual code from used libraries.
The IDA Pro Book - Ch 12. Library Recognition Using FLIRT Signatures
After reading through the extensive App Store guidelines (mac app store specifically), I've noticed a contradiction....
On one hand, under functionality, it clearly states:
2.7 Apps that download code in any way or form will be rejected
2.8 Apps that install or launch other executable code will be rejected
Yet when you read up further about purchase types, it often refers to in App Purchase 'downloads' and I'm pretty sure I remember reading in the bundle development guide (specifically plugin development) that these could be considered as in app purchases?
in 2.7 and 2.8 above, do they refer to code that they haven't checked i.e myAppPurchase.bundle which wasn't submitted at the app submission time, or is this concrete that absolutely NO bundles checked or unchecked by apple can be downloaded at all?
So in short, should an app be created in it's entirety i.e. with all the 'in app purchase extras' or can it be done modular i.e. an in app purchase downloads an approved bundle from the app store?
Cheers,
A
Although you can download content for in-app purchase, you aren't allowed to download code for later incorporation into the application. There are some theoretical edge cases, as you might have your own interpreter and might be able to download some amount of interpretable code in that case, you cannot download native code which will be executed either as part of the application (plugin) or an externally launched application.
As for the question of why Apple would cover this in the docs, it's likely because its the way that OS X and iOS apps are stored in the file system. Until Apple decides to allow downloadable binary executables, we're stuck using Plugin bundles in OS X only, ditto for non-OS framework bundles, which would arguably be even more useful. In particular, we have some bundles that are iOS/OSX cross-platform that we have to statically link under iOS, which is a shame.
Apple's apparent take is that if we can load code dynamically, then it is an opportunity to circumvent their review process by downloading an offending code module after the initial (or subsequent) program load. Imagine, for example, an application that talks to a server to download code which violates one of Apple's guidelines. If the version that is making the request has not yet been "released" by the malicious developer, no code is returned, and it just looks like it's checking in for an informative message of some kind. However, once Apple approves the App, the developer tells the server to start sending back a dynamic library, framework, or plugin which is then executed at the appropriate time by the now-malicious code.
The difficulty is that to prevent this from happening (through dyld or similar), you need to either whitelist everything that can be loaded, or you need to just prevent its use by application code altogether.
There's certainly the possibility that some kind of approved code whitelist could be used in the future, but until then, Apple has apparently chosen the route of just preventing the use of dynamic linking of non-system frameworks.
I work on a vertical-market Mac application that uses a USB dongle to make sure users have paid for it. It's expensive enough, and in enough demand, that "black hats" have tried to crack the dongle scheme, so the app checks the executable and key resource files at runtime, and if something has been tampered with, the program won't run.
With PKI (Public Key Infrastructure) based code signing becoming more commonplace in the Mac world, I'm considering switching to using it to do this runtime verification, which would have the nice side effect of making Gatekeeper happy.
However, Apple's interest is very different from mine. Their focus is on making the user happy, so if an app has an incorrect signature, Mac OS X will simply ask the user if they want to run it anyway. My focus is on thwarting crackers, so if my app has an incorrect signature, I simply don't want it to do anything that's useful to an end-user.
So I want my app to be able to validate its own executable and resources, using Apple's signatures, at runtime.
Also, from what I've read of the libraries offered Mac OS X for doing validation, they simply give a "yes" or "no" answer to requests to validate an executable. It strikes me that this is susceptible to "black hat" attack in a number of ways - for instance, one could simply replace Apple's tools with ones that always say, "yes, this is valid", either in the system directories or by changing the search path for those tools. So I think it might be a good idea to build the complete set of signature validation code into my app.
So I have a few questions:
What PKI libraries/APIs are available to let an app validate its own executable and resources which have been signed using Apple's codesign system?
Do these libraries have source code available?
Are my security concerns about using the PKI libraries Apple ships with Mac OS X valid, or are they safer to use than I think?
Does anybody have experience with this kind of thing they'd be willing to share? Are there other gotchas or tips?
Thanks in advance for any help with this.
To answer #1 and #2 above, Apple has open-sourced its code for creating and verifying digital signatures as libsecurity_codesigning. So a developer could build that into their app to let it validate its own signature.
Alternatively, MacOS's version of this library can be used by an app - but the API is private, so that's a gotcha. There's a brief discussion at this link.