Signing libraries in Mac App Store app - macos

I've just submitted an app to the Mac App Store that uses some external dynamic libraries.
I got an email from Apple saying that:
Invalid Signature - the executable something.app/Contents/Frameworks/some.dylib is not signed, the signature is invalid, or it is not signed with an Apple submission certificate. Refer to the Code Signing and Application Sandboxing Guide for more information.
The problem is of course caused by the fact that I only signed "my" executable, not the libraries.
Is it common/good practice to also sign the libraries, even though they're not written by me?

Think of digitally signing a file as:
A means of verifying the integrity of that file, thus making it possible to detect whether it’s been modified;
A means of verifying who published that file, which is not the same as writing the corresponding source code. You’re attesting that it was really you who’s shipped that file.
Since dynamic libraries contain executable code, it’s good practice (and in some cases, such as the MAS, mandatory) to digitally sign them for the same reason you sign the main executable file: guaranteeing that your application is exactly what you (and only you) have shipped from your build machine, no changes whatsoever. A running program includes the main executable file and all loaded libraries. If you sign the main executable file only, leaving the dynamic libraries unsigned, it would be possible to alter the dynamic libraries (or even replace them), thus changing what your program does.

Related

Mac hook function

I used to be able to use mach_override to hook any exported function on Mac OS including Catalina. However, now the target app crashed every time and I check the Console and find the following error:
CODE SIGNING: 30911[app] vm_map_protect can't have both write and exec at the same time
What's going on and is that possible I can bypass it without touching the target app's signature?
The hardened runtime is designed specifically to prevent that sort of hooking. The target app's entitlements would have to opt-in to allowing it. If you find a way around it, Apple would consider that a security hole bug and patch it in a future OS release.
It should work if you disable System Integrity Protection, but I don't know if that suits your purpose.

mach_override() function is failing in mojave OSX 10.14

I have a small project which implements function hooking in MAC using mach_override() by Jonathan 'Wolf' Rentzsch:https://github.com/rentzsch/mach_override
I have hooked one of the functions of kextstat process from mac.
So when I am executing
$kextstat
OSX is killing this process saying below error:
CODE SIGNING: process 2211[kextstat]: rejecting invalid page at
address 0x7fff5132d000 from offset 0xca53000 in file
"/private/var/db/dyld/dyld_shared_cache_x86_64h"
(cs_mtime:1531207073.366350606 == mtime:1531207073.366350606)
(signed:0 validated:0 tainted:0 nx:0 wpmapped:1 dirty:1 depth:2)
my dynamic library is code-signed.
In my initial observation, i could conclude that mach_override() function in failing in following code:
atomic_mov64((uint64_t *)originalFunctionPtr,
jumpRelativeInstruction);
above code could be found : mach_override.c:342
https://github.com/rentzsch/mach_override
Firstly, you should note that public discussion of Apple's Developer Beta software is a breach of Apple's terms and conditions. Such questions should be posted to Apple's forums, which has a specific section for Beta releases.
That being said, the technology and problem you're seeing is SIP, which includes denial of code injection, as well as protecting system files from being overwritten. The detail that follows is nothing new and exists in pre 10.14 macOS builds, though disabled (by default) in those versions.
When an application is signed, it creates a hash of each file page in the binary, and a super hash of all those hashes. During execution of a binary, when a page fault occurs, or a file (e.g. dylib) is mmap'd into the executing process, amfid (Apple Mobile File Integrity daemon) verifies that the new code is signed and that its signature matches that of the executing binary. If the signature or hashes do not match, then the code is denied loading, or in some cases, the process is killed.
In this case, kextstat contains an Apple certificate that does not match the certificate of your code that you're attempting to inject into kextstat. In addition, the certificate of kexstat includes the platform binary flag, which Developer certificates do not have.
Without a zero-day vulnerability, you're not going to be able to hook kextstat in a commercial environment. If it's just research you want to do, then you can either disable SIP, or remove the signature from the kextstat binary, causing amfid to ignore the certificate verification.

Does MacOS/X have a separated-debug-info mechanism similar to Windows' PDB files?

When developing and deploying an application under Windows, the developer has the option to store locally the .pdb files that are generated by the compiler as part of each build, and have his program call MiniDumpWriteDump in response to a crash to generate a .dmp file that can later be sent back to the developer. Then the developer can match the received .dmp to the appropriate .pdb file and executable and use that to do post-mortem debugging of the crash (i.e. see a stack trace, etc).
It's a pain to set up and manage, but the advantage is that it allows the developer to strip all the debug information out of his released program and yet still be able to debug crashes that occur in the field. This allows the program's install size to be much smaller, and perhaps makes the program less susceptible to reverse-engineering.
My question is, does MacOS/X have any kind of mechanism like .pdb? The only options I have seen for MacOS/X are to either "strip" your executable file (resulting in a small executable, but very little debug info if it ever crashes), or don't (resulting in an executable that provides a very helpful Crash Report when it crashes, but is much larger than it needs to be otherwise).
I think dsymutil is what you are looking for. It creates a .dSYM folder named after the binary it runs on which includes debug information.
To be honest I have never actually used it. And I'm not sure what kind of stack trace you need from the remote computer.

OS X .dmg signature lost after download

I'm signing a .dmg containing a .app with a valid Developer ID profile. Everything is signed, frameworks included. When I run codesign -dvvv, the right certificate appears and satisfies its Designated Requirement. The application runs fine.
However, when I upload and download the .dmg, the signature "disappears". When I run codesign -dvvv, it says code object is not signed at all. And GateKeeper naturally refuses to run the application.
Note: it sounds a lot like this issue but I'm definitely signing with the right Developer ID certificate, and the .dmg does not appear "damaged".
[Note: the situation changed significantly in OS X v10.11.5 and v10.12; this answer has been updated to reflect that.]
In general, the thing you really need to sign is the files (mainly the app) inside the disk image, not the image itself. After the image is downloaded, the signature on the individual items will be checked as they are used. Starting in OS X 10.11.5, signing disk images is properly supported and sometimes required, but that's in addition to signing the relevant items inside it.
Through OS X v10.11.4, you could sign the disk image itself (with codesign -s "Developer ID Application: [your company]" example.dmg), but the signature this creates is stored in the form of extended attributes attached to the image file. Actually, it creates three xattrs, named com.apple.cs.CodeDirectory, com.apple.cs.CodeRequirements, and com.apple.cs.CodeSignature. The critical thing to realize is that these attributes are filesystem metadata -- that is, they're attached to the file, not part of the file's contents. The HTTP protocol has very limited support for filesystem metadata, so when you upload or download via HTTP (or FTP or...), it only transfers the file's contents, and the xattrs are lost.
You can see the xattrs with the ls -l# command (and in even more detail with the xattr command):
$ ls -l# example.dmg
-rw-r--r--# 1 gordon staff 338590 Nov 13 2013 example.dmg
com.apple.cs.CodeDirectory 120
com.apple.cs.CodeRequirements 172
com.apple.cs.CodeSignature 8515
com.apple.diskimages.fsck 20
com.apple.diskimages.recentcksum 81
After downloading, the image will have lost those attributes (and probably gained com.apple.quarantine and com.apple.metadata:kMDItemWhereFroms from the download process), and hence will not be considered signed. The files contained in it, on the other hand, should still be properly signed (since their signatures are part of the image file's contents.)
Starting in OS X v10.11.5, codesign supports embedding the signature into the disk image itself, so that it will survive being downloaded over HTTP. Starting in v10.12, gatekeeper will enforce additional restrictions on apps in unsigned disk images that will prevent the app from loading additional content (mainly dynamic libraries) from the disk image, unless they're contained inside the app itself. If you don't know whether that's relevant to your app, go ahead and sign the disk image (actually, it's a good idea anyway), but be sure to run codesign under 10.11.5 or later or the signature won't be in a useful format!

Security of WinVerifyTrust, or verifying trust of a locked file

I have a process that loads an external DLL (sort of a plugin system) where I want to verify that the loaded DLL is signed correctly using Authenticode. After perusing the documentation for WinVerifyTrust and LoadLibrary (and friends) one thing that struck me as significant is that both operations work from a file path to the DLL.
It looks to me that its quite feasible to exploit this to cause my program to load an unsigned DLL, by presenting the program with a signed DLL, causing WinVerifyTrust() to succeed and immediately replacing the DLL with unsigned code before the LoadLibrary() call gets executed (this is a hard race condition, but it can be better controlled if the attacker has some control on the file system, for example when using a networked file system).
The API for WinVerifyTrust() seems to suggest that I can run the verification process on a handle to an open file. If I can open the file, verify the open file handle and then load the library from the same file handle - then I will be safe. Unfortunately LoadLibraryEx() - which would have been my prime suspect for implementing this - documents its hFile parameter as "reserved for future use".
My Next avenue of thought was to load the file contents into memory and then load the DLL from the memory, and I found the library MemoryModule that does this. I was wondering if there is some existing implementation that already goes and combines all this and allows the developer to securely verify and load a DLL, meaning I won't have to write it and maintain it myself.
Any suggestions?

Resources