launchd Persistence
macOS utilizes launchd as its system and service management framework, enabling persistent execution of background processes. Attackers often exploit launchd by creating malicious .plist files to ensure persistence across reboots. This section details how to craft and deploy such payloads for red team testing, emphasizing defensive awareness and authorized use only.
Understanding Launchd.plist Structure¶
A valid launchd plist file defines a service with specific execution parameters. Key attributes include:
- Label: Unique identifier for the service (e.g., com.example.malicious).
- ProgramArguments: Array of arguments for the executable (e.g., /path/to/malicious.bin).
- RunAtLoad: Boolean to trigger the service on load (true).
- KeepAlive: Boolean to restart the service if it terminates (true).
- StandardOutPath/StandardErrorPath: Redirect output to log files (optional).
Example structure:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.example.malicious</string>
<key>ProgramArguments</key>
<array>
<string>/path/to/malicious.bin</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
Step-by-Step: Creating a Persistent Launchd Service¶
-
Generate the plist file
Save the above example asmalicious.plistin a secure location (e.g.,/tmp/malicious.plist). -
Place the plist in the correct directory
- User-specific persistence (requires user login):
-
System-wide persistence (requires root privileges):
-
Load the service
For system-wide services:
For user-specific services:
-
Verify the service
Check logs using:
Advanced Techniques: Evasion and Obfuscation¶
- Dynamic paths: Use environment variables or relative paths to avoid static detection.
- Base64 encoding: Embed payloads in the plist using base64 to bypass simple scanners.
- Hidden services: Store plists in non-standard locations (e.g.,
/private/var/db/launchd.db/), though this may trigger system scrutiny.
Key Takeaways¶
- Correct syntax: Ensure the plist adheres to XML standards and valid
launchdkeys. - Placement matters: User-specific services require login; system-wide services need root access.
- Testing is critical: Validate the service loads and executes without errors.
- Evasion tactics: Use obfuscation or dynamic paths to avoid detection by standard monitoring tools.
- Authorization: Always operate within legal and authorized testing boundaries.