Hacktricks-skills macos-library-injection
macOS library injection and dylib hijacking analysis. Use this skill whenever the user needs to analyze macOS binaries for library injection vulnerabilities, check DYLD_INSERT_LIBRARIES restrictions, find weak linked libraries, examine rpath configurations, or test for privilege escalation via library loading. Trigger on any request about macOS dyld, library injection, dylib hijacking, dlopen hijacking, or binary security analysis.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/macos-library-injection/SKILL.MDmacOS Library Injection Analysis
A skill for analyzing macOS binaries for library injection vulnerabilities and understanding dyld behavior.
When to Use This Skill
Use this skill when:
- Analyzing macOS binaries for library injection vulnerabilities
- Checking if
will work on a binaryDYLD_INSERT_LIBRARIES - Finding weak linked libraries that could be hijacked
- Examining rpath configurations in Mach-O binaries
- Testing for privilege escalation via library loading
- Understanding macOS dyld restrictions and protections
- Auditing binaries for hardened runtime and library validation
Core Concepts
DYLD_INSERT_LIBRARIES
Similar to
LD_PRELOAD on Linux, this environment variable allows loading a custom library into a process. However, Apple has significantly restricted this since 2012.
Restrictions that block DYLD_INSERT_LIBRARIES:
- Binary is setuid/setgid
- Binary has
/__RESTRICT
section__restrict - Binary has hardened runtime without
entitlementcom.apple.security.cs.allow-dyld-environment-variables
Library Validation
Even if
DYLD_INSERT_LIBRARIES is allowed, the binary may check library signatures. To load a custom library, the binary needs:
entitlementcom.apple.security.cs.disable-library-validation
entitlementcom.apple.private.security.clear-library-validation- OR no hardened runtime flag
- OR the library is signed with the same certificate as the binary
Quick Checks
Check Binary Restrictions
# Check for hardened runtime codesign --display --verbose <binary> # Look for flags=0x10000(runtime) in CodeDirectory # Check entitlements codesign -dv --entitlements :- <binary> # Check for setuid/setgid ls -l <binary> # Look for 's' in permissions # Check runtime flags at execution time csops -status <pid> # Flag 0x800 indicates CS_RESTRICT
Find Weak Linked Libraries
# Find LC_LOAD_WEAK_DYLIB entries otool -l <binary> | grep LC_LOAD_WEAK_DYLIB -A 5 # These libraries can be hijacked if they don't exist # and the attacker can write to the expected path
Find RPATH Configurations
# Find rpath and load commands otool -l <binary> | grep -E "LC_RPATH|LC_LOAD_DYLIB" -A 5 # Look for @rpath references that could be hijacked # @executable_path = directory containing main executable # @loader_path = directory containing the Mach-O binary
Attack Vectors
1. DYLD_INSERT_LIBRARIES Injection
Works when:
- Binary is NOT setuid/setgid
- Binary has NO
section__RESTRICT - Binary has
entitlement OR no hardened runtimecom.apple.security.cs.allow-dyld-environment-variables - Library validation is disabled OR library is properly signed
Test:
DYLD_INSERT_LIBRARIES=/path/to/inject.dylib ./binary
2. Weak Linked Library Hijacking
Works when:
- Binary has
for a missing libraryLC_LOAD_WEAK_DYLIB - Attacker can write to the expected library path
- Library validation restrictions are satisfied
Find targets:
otool -l <binary> | grep LC_LOAD_WEAK_DYLIB -A 5
3. RPATH Hijacking
Works when:
- Binary uses
in@rpathLC_LOAD_DYLIB - One of the rpath directories is writable by attacker
- Library validation restrictions are satisfied
Note: macOS searches rpath directories in order. If a library exists in multiple paths, the first match wins.
4. Dlopen Hijacking
Search order for dlopen (no slash in name):
$DYLD_LIBRARY_PATH
directoriesLC_RPATH- Current working directory (if unrestricted)
$DYLD_FALLBACK_LIBRARY_PATH
(if unrestricted)/usr/local/lib//usr/lib/
Works when:
- Binary is unrestricted (no setuid, no CS_RESTRICT)
- Attacker can write to one of the search paths
- Library validation restrictions are satisfied
5. Relative Path Hijacking
Works when:
- Privileged binary loads library via relative path (
,@executable_path
)@loader_path - Library validation is disabled
- Attacker can move the binary or write to the relative path
Testing Scripts
Use the bundled scripts for automated analysis:
- Check all restriction flagsscripts/check_binary_restrictions.sh
- Find weak linked librariesscripts/find_weak_libraries.sh
- Find rpath configurationsscripts/find_rpath_configs.sh
- Test DYLD_INSERT_LIBRARIESscripts/test_dyld_injection.sh
Common Patterns
SUID Binary Testing
# Make binary setuid sudo chown root <binary> sudo chmod +s <binary> # Test injection (won't work on setuid) DYLD_INSERT_LIBRARIES=inject.dylib ./binary # Remove setuid sudo chmod -s <binary>
Hardened Runtime Testing
# Apply runtime protection codesign -s <cert-name> --option=runtime ./binary # Apply library validation codesign -f -s <cert-name> --option=library ./binary # Sign library with same certificate codesign -f -s <cert-name> inject.dylib # Apply CS_RESTRICT codesign -f -s <cert-name> --option=restrict ./binary
Creating Test Binary with __RESTRICT Section
gcc -sectcreate __RESTRICT __restrict /dev/null hello.c -o hello-restrict
Important Notes
-
Environment Variable Pruning:
andDYLD_*
are removed for restricted binaries byLD_LIBRARY_PATH
in dyldpruneEnvironmentVariables() -
Library Validation: Even if injection is allowed, library signatures may be checked. The library must be signed with the same certificate as the binary, or the binary must have library validation disabled
-
Universal Binaries: macOS uses universal files combining 32-bit and 64-bit libraries. There are no separate search paths for different architectures
-
Dyld Cache: Most OS dylibs are combined into the dyld cache and don't exist on disk. Use
instead ofdlopen_preflight()
to check if a dylib existsstat() -
Setuid/SGID: These binaries always have environment variables pruned and are highly restricted
-
CS_RESTRICT Flag: Can be applied dynamically at execution time even if not present in the binary's signature