Detect Launchd in Google Chronicle
Adversaries may abuse the launchd daemon to perform task scheduling for initial or recurring execution of malicious code on macOS. The launchd daemon is responsible for loading and maintaining services within the operating system. It processes property list (plist) files found in /System/Library/LaunchDaemons, /Library/LaunchDaemons (system-wide daemons run as root), /Library/LaunchAgents (user agents run for all users), and ~/Library/LaunchAgents (user agents run for the specific user). Adversaries may install malicious plist files in these directories to achieve persistence, privilege escalation (via LaunchDaemons running as root), or execution at system startup or login. This technique is noted as deprecated by MITRE due to inaccurate original characterization, but the underlying abuse of launchd-controlled directories remains a valid and observed persistence mechanism on macOS.
MITRE ATT&CK
- Canonical reference
- https://attack.mitre.org/techniques/T1053/004/
YARA-L Detection Query
rule t1053_004_launchd_plist_by_suspicious_process {
meta:
author = "df00tech Detection Engineering"
description = "Detects plist file creation in macOS LaunchDaemon or LaunchAgent directories initiated by a shell, interpreter, or downloader process (T1053.004)"
mitre_attack_tactic = "Persistence, Privilege Escalation"
mitre_attack_technique = "T1053.004"
severity = "HIGH"
confidence = "MEDIUM"
events:
$e.metadata.event_type = "FILE_CREATION"
re.regex($e.target.file.full_path, `/Library/Launch(Daemons|Agents)/.*\.plist$`)
re.regex($e.principal.process.file.full_path, `/(bash|sh|zsh|python3?|ruby|perl|curl|wget|osascript|node)$`)
$e.principal.hostname = $hostname
condition:
$e
}
rule t1053_004_suspicious_launchctl_execution {
meta:
author = "df00tech Detection Engineering"
description = "Detects suspicious launchctl load/bootstrap/submit/start commands on macOS from shell or interpreter parents, or targeting staging paths (T1053.004)"
mitre_attack_tactic = "Persistence, Privilege Escalation, Execution"
mitre_attack_technique = "T1053.004"
severity = "HIGH"
confidence = "MEDIUM"
events:
$e.metadata.event_type = "PROCESS_LAUNCH"
re.regex($e.target.process.file.full_path, `/usr/bin/launchctl$`)
re.regex($e.target.process.command_line, `\b(load|bootstrap|submit|start)\b`)
(
re.regex($e.principal.process.file.full_path, `/(bash|sh|zsh|python3?|ruby|perl|curl|wget|osascript|node)$`) or
re.regex($e.target.process.command_line, `(/tmp/|/var/tmp/|\.hidden|/Users/Shared/)`)
)
$e.principal.hostname = $hostname
condition:
$e
} Two YARA-L 2.0 Chronicle detection rules for T1053.004. The first rule identifies plist file creation events in LaunchDaemon or LaunchAgent directories where the creating process is a known shell, interpreter, or downloader. The second rule identifies launchctl load/bootstrap/submit/start process launch events spawned from shells or interpreters, or where the command line references a suspicious staging path. Both rules bind by hostname for downstream pivot context.
Data Sources
Required Tables
False Positives & Tuning
- MDM solutions such as Jamf Pro or Mosyle executing post-enrollment shell scripts that create plist files in LaunchDaemons as part of managed device configuration.
- macOS package managers (Homebrew, MacPorts) installing launch agents from zsh or bash during brew install or port install operations, particularly for services like nginx or postgresql.
- Corporate IT automation scripts using launchctl bootstrap to register network monitoring or endpoint security agents during provisioning workflows.
Other platforms for T1053.004
Testing Methodology
Validate this detection against 4 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 1Create Malicious LaunchAgent Plist for User Persistence
Expected signal: File creation event for ~/Library/LaunchAgents/com.argus.test.persistence.plist and /tmp/argus_test_payload.sh. Process creation event for launchctl with arguments 'load ~/Library/LaunchAgents/com.argus.test.persistence.plist'. macOS Unified Log entry for launchd registering the new service with label 'com.argus.test.persistence'. Subsequent execution of /bin/bash with /tmp/argus_test_payload.sh as argument, initiated by launchd.
- Test 2Create Root LaunchDaemon Plist for System-Level Persistence
Expected signal: File creation event for /Library/LaunchDaemons/com.argus.test.daemon.plist with initiating process sudo/bash running as root. Process creation events for sudo and launchctl with 'load /Library/LaunchDaemons/com.argus.test.daemon.plist'. macOS Unified Log entry from launchd registering system daemon. The IsDaemon flag in the KQL query should be set to true.
- Test 3Launchctl Load from Suspicious Temp Directory Path
Expected signal: File creation event for /tmp/com.argus.tmppersist.plist. Process creation event for launchctl with command line containing 'load /tmp/com.argus.tmppersist.plist' — the /tmp path is a key indicator. macOS Unified Log entries for launchd service registration from a temp path.
- Test 4Simulate Adversary Plist Drop via curl and Shell
Expected signal: Process creation for bash with the dropper script as command. File creation event for ~/Library/LaunchAgents/com.argus.dropper.test.plist with InitiatingProcessFileName=bash — the suspicious parent detection fires. Process creation for launchctl initiated by bash. macOS Unified Log shows the full execution chain: bash → file write → launchctl → launchd registration.
References (10)
- https://attack.mitre.org/techniques/T1053/004/
- https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html
- https://www.virusbulletin.com/uploads/pdf/conference/vb2014/VB2014-Wardle.pdf
- https://objective-see.org/blog.html
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1053.004/T1053.004.md
- https://www.sentinelone.com/blog/how-malware-persists-on-macos/
- https://www.crowdstrike.com/blog/how-to-detect-and-prevent-mac-malware/
- https://managingosx.wordpress.com/2015/10/15/launchd-is-not-a-valid-way-to-run-a-job-at-a-scheduled-time/
- https://support.apple.com/guide/terminal/apdc6c1077b-5d5d-4d35-9c19-60f2397b2369/mac
- https://github.com/SigmaHQ/sigma/tree/master/rules/macos
Unlock Pro Content
Get the full detection package for T1053.004 including response playbook, investigation guide, and atomic red team tests.