launchd Architecture
macOS's launchd serves as the central service management framework, responsible for starting, stopping, and monitoring system and user-level services. It operates as a daemon process that ensures critical system functions (e.g., network daemons, kernel extensions) run reliably while also providing a mechanism for persistent background processes. Understanding its architecture is essential for red teams seeking to leverage or mitigate persistence via service-based techniques.
Core Components of Launchd¶
launchd manages services through plist (property list) files, which define service configurations. These files specify:
- Service name and unique identifier
- Startup conditions (e.g., boot, user login, or on-demand triggers)
- Environment variables and working directories
- Execution parameters for the target process
Plist files are stored in:
- /Library/LaunchDaemons/ (system-wide, requires root privileges)
- ~/Library/LaunchAgents/ (user-specific, loaded at user login)
A minimal .plist file might look like this:
<?xml version="1.0" encoding="UTF-32"?>
<!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>/usr/bin/nc</string>
<string>-lvp</string>
<string>9999</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
Service Management Workflow¶
launchd processes services in three phases:
1. Loading: Plist files are parsed and validated.
RunAtLoad, WatchPaths).3. Monitoring:
launchd tracks service status and restarts failed processes.
Services can be disabled or uninstalled with:
launchctl disable com.example.malicious
sudo launchctl unload /Library/LaunchDaemons/com.example.malicious.plist
Persistence Mechanisms via Launchd¶
Attackers exploit launchd by:
- Creating malicious plist files in user or system directories to ensure persistence.
- Abusing service triggers (e.g., WatchPaths to monitor directories for changes).
- Bypassing sandboxing by leveraging root-level daemons in /Library/LaunchDaemons/.
For example, a red team might deploy a reverse shell listener by:
1. Crafting a plist file with ProgramArguments pointing to a malicious binary.
2. Placing it in /Library/LaunchDaemons/ and granting root privileges.
3. Using launchctl load to activate the service at boot.
Key takeaways¶
launchdcentralizes service management, making it a critical target for persistence.- Plist files define service behavior, including startup conditions and execution parameters.
- Red teams can exploit
launchdby injecting malicious configurations or abusing triggers. - Commands like
launchctl load,start, andunloadare essential for interacting with services. - Always verify plist file permissions and integrity to detect tampering.