Skip to content

Code Signing Bypasses

macOS applications are protected by code signing, which ensures binaries are signed by trusted developers. Red teams often target this mechanism to execute unsigned payloads or bypass integrity checks. This section explores techniques to modify Mach-O binaries to bypass code signing enforcement, including direct binary patching and signature spoofing.


Patching Mach-O Headers to Bypass Code Signing

Mach-O binaries contain headers that describe the file's structure and signing status. By modifying these headers, you can trick the system into treating the binary as unsigned or signed by a trusted entity.

1. Removing Code Signature

Use codesign to remove the signature from a binary:

codesign --remove-signature /path/to/binary
This removes the signature but leaves the binary intact. However, macOS may still enforce signature checks for certain operations (e.g., launching via open). To fully bypass this, further patching is required.

2. Modifying Mach-O Headers

Use otool and MachOEditor (or mh_fat tools) to alter the Mach-O header. For example, change the __TEXT segment's LC_CODE_SIGNATURE load command to point to a non-existent signature:

# Inspect load commands
otool -l /path/to/binary | grep LC_CODE_SIGNATURE
Edit the header to remove or redirect the signature reference. This requires low-level manipulation of the binary's structure.


Code Signing Bypass via Dynamic Linking

Exploiting dynamic linking can bypass code signing checks by injecting malicious code into trusted processes.

1. DYLD_INSERT_LIBRARIES Bypass

Launch a signed binary with a custom library to inject payload:

DYLD_INSERT_LIBRARIES=/path/to/malicious.dylib /path/to/signed_app
The malicious .dylib will execute before the main binary, allowing code execution without signing the entire binary.

2. Replacing __dyld or dyld_stub_binder

Patch the binary to replace the dynamic linker stubs with a custom implementation that loads your payload. This requires recompiling the binary with modified linker flags:

# Example: Link with custom dylib
clang -dynamiclib -o payload.dylib payload.c


Code Signature Spoofing

Spoofing a valid signature involves forging the code signature to mimic a trusted developer. This requires:
1. Generating a fake certificate using security tools.
2. Signing the binary with a private key (requires access to the signing infrastructure).
3. Patching the binary to reference the forged signature.

Example:

# Generate a fake certificate (requires macOS SDK)
security create-certificate -s "Fake Developer" -a identity -k /path/to/private.key -o /path/to/cert.pem


Key takeaways

  • Header manipulation can bypass code signing by altering Mach-O metadata.
  • Dynamic linking allows payload injection without full binary signing.
  • Spoofing signatures requires access to trusted certificate infrastructure.
  • Always test in controlled environments; macOS security updates may invalidate these techniques.