Persistence via a Hidden Plist Filename
Identifies the creation of a hidden launch agent or daemon property list file. An adversary may establish persistence by installing a new launch agent or daemon which executes at login. Hidden plist files with filenames starting with a dot are particularly suspicious.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2026/01/30"
3integration = ["endpoint"]
4maturity = "production"
5updated_date = "2026/01/30"
6
7[rule]
8author = ["Elastic"]
9description = """
10Identifies the creation of a hidden launch agent or daemon property list file. An adversary may establish
11persistence by installing a new launch agent or daemon which executes at login. Hidden plist files with
12filenames starting with a dot are particularly suspicious.
13"""
14from = "now-9m"
15index = ["logs-endpoint.events.file-*"]
16language = "eql"
17license = "Elastic License v2"
18name = "Persistence via a Hidden Plist Filename"
19references = [
20 "https://www.welivesecurity.com/2022/07/19/i-see-what-you-did-there-look-cloudmensis-macos-spyware/",
21 "https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html"
22]
23risk_score = 73
24rule_id = "e3f5a566-df31-40cc-987c-24bc4bb94ba5"
25severity = "high"
26tags = [
27 "Domain: Endpoint",
28 "OS: macOS",
29 "Use Case: Threat Detection",
30 "Tactic: Persistence",
31 "Tactic: Defense Evasion",
32 "Data Source: Elastic Defend",
33 "Resources: Investigation Guide"
34]
35timestamp_override = "event.ingested"
36type = "eql"
37note = """## Triage and analysis
38
39> **Disclaimer**:
40> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
41
42### Investigating Persistence via a Hidden Plist Filename
43
44LaunchAgents and LaunchDaemons are macOS persistence mechanisms that automatically execute programs at login or system startup. Files with names starting with a dot (.) are hidden from standard directory listings in macOS, making them less visible to users and administrators. Threat actors combine these techniques by creating hidden plist files in LaunchAgent/LaunchDaemon directories to establish stealthy persistence that survives reboots while evading casual inspection. This behavior was notably observed in the CloudMensis macOS spyware campaign.
45
46### Possible investigation steps
47
48- Examine the file.path to identify the full path of the hidden plist file and determine whether it is in a user-specific or system-wide LaunchAgent/LaunchDaemon directory.
49- Use plutil or defaults to read the plist contents and identify the executable path, arguments, and execution conditions configured in the ProgramArguments or Program keys.
50- Locate the binary or script referenced in the plist file and calculate its hash for threat intelligence lookups.
51- Analyze the binary's code signature using codesign -dvvv to determine if it is signed, and by whom.
52- Review the process.executable that created the plist file to understand the initial delivery mechanism.
53- Check file creation timestamps to determine when the hidden plist was created and correlate with other security events.
54- Search for other hidden files in LaunchAgent and LaunchDaemon directories across the system.
55
56### False positive analysis
57
58- Chef configuration management may create hidden plists matching .chef-com* patterns. These are already excluded in the query.
59- Some legitimate applications may temporarily create dot-prefixed files during installation. Verify the process that created the file and its signature.
60- Backup and synchronization tools occasionally create hidden configuration files. Confirm the tool's legitimacy and expected behavior.
61- System processes like sed may create temporary hidden files during in-place editing operations. These are partially excluded in the query.
62
63### Response and remediation
64
65- Immediately unload the hidden LaunchAgent or LaunchDaemon using launchctl unload with the plist path.
66- Remove the hidden plist file from the LaunchAgent or LaunchDaemon directory.
67- Locate and remove the malicious binary or script referenced in the plist's Program or ProgramArguments keys.
68- Search for related hidden files, configuration files, or staging directories that may be part of the same malware deployment.
69- Review system logs for evidence of the hidden persistence mechanism executing and what actions it performed.
70- Check for data exfiltration or command and control communication if the behavior matches known spyware patterns like CloudMensis.
71- Reset credentials that may have been accessed while the persistence mechanism was active.
72- Monitor for recreation of hidden plist files in LaunchAgent and LaunchDaemon directories.
73"""
74query = '''
75file where host.os.type == "macos" and event.type != "deletion" and
76 file.path like~ (
77 "/System/Library/LaunchAgents/.*.plist",
78 "/Library/LaunchAgents/.*.plist",
79 "/Users/*/Library/LaunchAgents/.*.plist",
80 "/System/Library/LaunchDaemons/.*.plist",
81 "/Library/LaunchDaemons/.*.plist"
82 ) and
83 not (file.name like ".chef-com*.plist" and process.executable like "/opt/chef/embedded/bin/ruby") and
84 not (process.executable in ("/usr/bin/sed", "/bin/bash") and file.name like ".!*!*.plist")
85'''
86
87[[rule.threat]]
88framework = "MITRE ATT&CK"
89
90 [rule.threat.tactic]
91 name = "Persistence"
92 id = "TA0003"
93 reference = "https://attack.mitre.org/tactics/TA0003/"
94
95 [[rule.threat.technique]]
96 name = "Boot or Logon Autostart Execution"
97 id = "T1547"
98 reference = "https://attack.mitre.org/techniques/T1547/"
99
100 [[rule.threat.technique.subtechnique]]
101 name = "Plist Modification"
102 id = "T1547.011"
103 reference = "https://attack.mitre.org/techniques/T1547/011/"
104
105 [[rule.threat.technique]]
106 name = "Create or Modify System Process"
107 id = "T1543"
108 reference = "https://attack.mitre.org/techniques/T1543/"
109
110 [[rule.threat.technique.subtechnique]]
111 name = "Launch Agent"
112 id = "T1543.001"
113 reference = "https://attack.mitre.org/techniques/T1543/001/"
114
115[[rule.threat]]
116framework = "MITRE ATT&CK"
117
118 [rule.threat.tactic]
119 name = "Defense Evasion"
120 id = "TA0005"
121 reference = "https://attack.mitre.org/tactics/TA0005/"
122
123 [[rule.threat.technique]]
124 name = "Hide Artifacts"
125 id = "T1564"
126 reference = "https://attack.mitre.org/techniques/T1564/"
127
128 [[rule.threat.technique.subtechnique]]
129 name = "Hidden Files and Directories"
130 id = "T1564.001"
131 reference = "https://attack.mitre.org/techniques/T1564/001/"
Triage and analysis
Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
Investigating Persistence via a Hidden Plist Filename
LaunchAgents and LaunchDaemons are macOS persistence mechanisms that automatically execute programs at login or system startup. Files with names starting with a dot (.) are hidden from standard directory listings in macOS, making them less visible to users and administrators. Threat actors combine these techniques by creating hidden plist files in LaunchAgent/LaunchDaemon directories to establish stealthy persistence that survives reboots while evading casual inspection. This behavior was notably observed in the CloudMensis macOS spyware campaign.
Possible investigation steps
- Examine the file.path to identify the full path of the hidden plist file and determine whether it is in a user-specific or system-wide LaunchAgent/LaunchDaemon directory.
- Use plutil or defaults to read the plist contents and identify the executable path, arguments, and execution conditions configured in the ProgramArguments or Program keys.
- Locate the binary or script referenced in the plist file and calculate its hash for threat intelligence lookups.
- Analyze the binary's code signature using codesign -dvvv to determine if it is signed, and by whom.
- Review the process.executable that created the plist file to understand the initial delivery mechanism.
- Check file creation timestamps to determine when the hidden plist was created and correlate with other security events.
- Search for other hidden files in LaunchAgent and LaunchDaemon directories across the system.
False positive analysis
- Chef configuration management may create hidden plists matching .chef-com* patterns. These are already excluded in the query.
- Some legitimate applications may temporarily create dot-prefixed files during installation. Verify the process that created the file and its signature.
- Backup and synchronization tools occasionally create hidden configuration files. Confirm the tool's legitimacy and expected behavior.
- System processes like sed may create temporary hidden files during in-place editing operations. These are partially excluded in the query.
Response and remediation
- Immediately unload the hidden LaunchAgent or LaunchDaemon using launchctl unload with the plist path.
- Remove the hidden plist file from the LaunchAgent or LaunchDaemon directory.
- Locate and remove the malicious binary or script referenced in the plist's Program or ProgramArguments keys.
- Search for related hidden files, configuration files, or staging directories that may be part of the same malware deployment.
- Review system logs for evidence of the hidden persistence mechanism executing and what actions it performed.
- Check for data exfiltration or command and control communication if the behavior matches known spyware patterns like CloudMensis.
- Reset credentials that may have been accessed while the persistence mechanism was active.
- Monitor for recreation of hidden plist files in LaunchAgent and LaunchDaemon directories.
References
Related rules
- Dylib Injection via Process Environment Variables
- Unusual Process Modifying GenAI Configuration File
- Node.js Pre or Post-Install Script Execution
- Creation of Hidden Launch Agent or Daemon
- Suspicious Hidden Child Process of Launchd