plist Structure
macOS relies heavily on property list (plist) files to store configuration data for system services, user preferences, and launchd job definitions. Understanding the structure and syntax of these files is critical for red teams seeking to inject malicious configurations for persistence. Plist files are XML-based and often used to define launch agents, system services, or hidden process configurations. This section covers the fundamentals of plist syntax, common use cases, and techniques for parsing/modifying them.
Basic Syntax and Elements¶
Plist files are structured as nested dictionaries (<dict>), arrays (<array>), or strings/numbers. Key-value pairs are defined using <key> and <string>/<integer> tags.
Example: Simple Dictionary
<?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>Program</key>
<string>/path/to/malicious_binary</string>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
Key Elements Explained:
- <key>: Defines a configuration parameter (e.g., Label, Program).
- <string>: Stores textual values (e.g., binary paths).
- <true/>/<false/>: Boolean flags (e.g., RunAtLoad).
- <integer>: Numeric values (e.g., StartInterval).
Common Plist Use Cases for Persistence¶
Launchd plists are a primary target for persistence. By modifying these files, attackers can ensure their payloads run at system boot or under specific triggers.
Example: Launchd Agent for Persistence
<dict>
<key>Label</key>
<string>com.attacker.persist</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/python3</string>
<string>/Users/attacker/malicious.py</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
Parsing and Modifying Plist Files¶
Use tools like plutil (command-line) or plutil (Python library) to parse and edit plists.
Convert Plist to JSON for Editing
# Convert plist to JSON
plutil -convert json /path/to/valid.plist -o /path/to/output.json
# Edit JSON file manually (e.g., add new keys)
nano /path/to/output.json
Reconvert to Plist Format
Manual XML Editing
Use a text editor (e.g., vim, nano) to directly modify XML syntax. Ensure proper nesting and closing tags to avoid parsing errors.
Advanced Techniques and Pitfalls¶
- Obfuscation: Use hex editors or base64 encoding to hide malicious payloads within plist values.
- Validation: Always verify the plist structure with
plutil -validateto avoid system rejections. - Permissions: Ensure modified plists have appropriate ownership (
root:wheel) and permissions (644).
Example: Hidden Process via Plist
<dict>
<key>Label</key>
<string>com.apple.systemhelper</string>
<key>Program</key>
<string>/System/Library/CoreServices/ActivityMonitor.app/Contents/MacOS/ActivityMonitor</string>
<key>EnvironmentVariables</key>
<dict>
<key>LD_LIBRARY_PATH</key>
<string>/Users/attacker/lib</string>
</dict>
</dict>
Key takeaways¶
- Plist files are XML-based and structured with dictionaries, arrays, and key-value pairs.
- Launchd plists are ideal for persistence, enabling payloads to run at boot or on-demand.
- Use
plutilto convert between formats, and validate syntax to avoid errors. - Obfuscate payloads and leverage environment variables for stealthier execution.
- Always ensure proper permissions and ownership when deploying modified plists.