Detect Plist File Modification in Splunk
This detection identifies adversarial modification of macOS property list (plist) files to enable persistence, evade defenses, or alter application behavior. Attackers use tools such as plutil, PlistBuddy, and the defaults command to insert or modify keys like LSUIElement (hide app from UI), LSEnvironment (inject environment variables for dynamic linker hijacking), RunAtLoad, and ProgramArguments in LaunchAgent or LaunchDaemon plists. Known malware families including XCSSET and Cuckoo Stealer abuse plist modification to persist across reboots and conceal malicious processes. The detection monitors process execution of common plist editing utilities with arguments targeting sensitive keys and system persistence paths.
MITRE ATT&CK
- Tactic
- Defense Evasion
- Technique
- T1647 Plist File Modification
- Canonical reference
- https://attack.mitre.org/techniques/T1647/
SPL Detection Query
index=* (sourcetype="macos:unified_log" OR sourcetype="macos_security" OR sourcetype="crowdstrike:events:ProcessRollup2" OR sourcetype="carbon_black:edr:json" OR sourcetype="jamf:pro:inventory")
| where (process_name IN ("plutil", "PlistBuddy", "defaults") OR (process_name IN ("python3", "python", "perl", "ruby", "osascript") AND like(process_cmdline, "%.plist%")))
| where like(process_cmdline, "%-insert%") OR like(process_cmdline, "%-replace%") OR like(process_cmdline, "%-set%") OR like(process_cmdline, "%write%") OR like(process_cmdline, "%-convert%") OR like(process_cmdline, "%add%") OR like(process_cmdline, "%-extract%")
| eval suspicious_key=case(
match(process_cmdline, "LSUIElement|LSEnvironment|LSBackgroundOnly"), "ui_suppression_key",
match(process_cmdline, "RunAtLoad|ProgramArguments|StartCalendarInterval|KeepAlive"), "launch_persistence_key",
match(process_cmdline, "LaunchAgents|LaunchDaemons"), "persistence_directory",
match(process_cmdline, "com\\.apple\\.dock|loginwindow|loginitems"), "system_preference_key",
match(process_cmdline, "DFBundleDisplayName|CFBundleIdentifier"), "bundle_identity_key",
1=1, "generic_plist_modification"
)
| eval suspicious_parent=case(
match(parent_process_name, "bash|zsh|sh|csh|curl|wget|python3|perl|ruby"), "true",
1=1, "false"
)
| eval risk_score=case(
suspicious_key IN ("ui_suppression_key", "launch_persistence_key") AND suspicious_parent="true", 90,
suspicious_key="persistence_directory" AND suspicious_parent="true", 80,
suspicious_key IN ("ui_suppression_key", "launch_persistence_key"), 70,
suspicious_key="persistence_directory", 60,
suspicious_parent="true", 50,
1=1, 35
)
| where risk_score >= 50
| table _time, host, user, process_name, process_cmdline, parent_process_name, suspicious_key, suspicious_parent, risk_score
| sort - risk_score, - _time Detects plist modification activity on macOS endpoints using endpoint agent telemetry. The query identifies execution of plutil, PlistBuddy, and the defaults command with write/modify arguments targeting sensitive plist keys associated with UI hiding (LSUIElement), environment variable injection (LSEnvironment), and persistence mechanisms (RunAtLoad, ProgramArguments). Risk scoring elevates alerts when a shell or scripting interpreter is the parent process.
Data Sources
Required Sourcetypes
False Positives & Tuning
- Application installers using plutil or PlistBuddy to write configuration during first-run setup
- MDM enrollment workflows (Jamf, Kandji, Mosyle) that configure LaunchAgent plists for management agents
- Developer build systems modifying Info.plist keys (CFBundleIdentifier, CFBundleDisplayName) during app compilation
- Homebrew formulae post-install scripts that write launchd service plists for background services
- IT automation scripts legitimately using the defaults command to enforce organizational preferences
Other platforms for T1647
Testing Methodology
Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1Modify LSUIElement to hide macOS application via plutil
Expected signal: DeviceProcessEvents: plutil process with -insert LSUIElement argument targeting a .plist file path; InitiatingProcessFileName will be the shell (bash/zsh)
- Test 2Write malicious LaunchAgent plist for persistence via PlistBuddy
Expected signal: DeviceProcessEvents: PlistBuddy with multiple Add command invocations targeting ~/Library/LaunchAgents/; DeviceFileEvents: .plist file creation in LaunchAgents directory
- Test 3Inject LSEnvironment with DYLD_INSERT_LIBRARIES for dynamic linker hijacking setup
Expected signal: DeviceProcessEvents: PlistBuddy with 'Add :LSEnvironment dict' and 'Add :LSEnvironment:DYLD_INSERT_LIBRARIES' command arguments; high-fidelity process args containing both LSEnvironment and DYLD_INSERT_LIBRARIES strings
References (7)
- https://attack.mitre.org/techniques/T1647/
- https://objective-see.org/blog.html
- https://www.sentinelone.com/blog/cuckoo-stealer-macos-malware/
- https://www.welivesecurity.com/2012/03/02/the-flashback-files-a-closer-look-at-the-osx-flashback-malware-family/
- https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Introduction/Introduction.html
- https://www.kandji.io/blog/cuckoo-malware
- https://www.microsoft.com/en-us/security/blog/2022/01/27/evolved-phishing-device-registration-trick-adds-to-phishers-toolbox-for-victims-without-mfa/
Unlock Pro Content
Get the full detection package for T1647 including response playbook, investigation guide, and atomic red team tests.