Can use launchctl to load a LaunchAgent for persistence.1
- Tactic
- Execution
- Platform
- macOS
- Version
- 1.3
- Created
- 10 March 2020
- Last modified
- 24 October 2025
Adversaries may abuse launchctl to execute commands or programs. Launchctl interfaces with launchd, the service management framework for macOS. Launchctl supports taking subcommands on the command-line, interactively, or even redirected from standard input.[1]
Launchctl MITRE reference T1569.001
6 software entries are documented implementing this technique. MITRE files each as a tool or as malware; newest first, then by how many groups carry them.
Has used launchctl to restart the Launch Agent.1
Loads a system level launchdaemon using the launchctl load -w command from /System/Librarby/LaunchDaemons/ssh.plist.1
Has loaded a plist file using the launchctl command.1
Launched the QEMU services in the /Library/LaunchDaemons/ folder using launchctl. It also uses launchctl to unload all Launch Daemons when updating to a newer version of LoudMiner.1
Uses launchctl to enable screen sharing on the victim’s machine.1
All 6 software entries for this technique
Offense vs defense T1569.001
Is defensive coverage keeping up with adversary use? Eight counts, each ranked against all 697 ATT&CK techniques. Attack sits left, defense right, so a shape leaning left means adversaries are better documented here than defenders are equipped. Hover any spoke for its percentile and the share of techniques that have more. The timeline below shows when each side arrived.
How it got here
Adversary activity (campaign spans) over cumulative rule output. Each source is plotted independently from zero, so neither line includes the other. Campaign dates are year-granularity.
Launchctl detection strategy DET0265
MITRE names one behaviour worth catching for this technique and breaks it into 1 analytic, one per platform. Each carries the log sources it needs and the fields you tune per environment.
Detection Strategy for System Services: Launchctl
AN0736 · macOS
Abuse of launchctl to execute or manage Launch Agents and Daemons. Defender perspective: correlation of suspicious plist file creation or modification in LaunchAgents/LaunchDaemons directories with subsequent execution of the launchctl command. Abnormal executable paths (e.g., /tmp, /Shared) or launchctl activity followed by network connections are highly suspicious.
Log sources
The data this analytic draws on. You do not need every component — each one you already collect covers part of it. Each links to its ATT&CK record.
| Data component | Name | Channel |
|---|---|---|
| Process CreationDC0032 | macos:unifiedlog | launchctl spawning new processes |
| Service CreationDC0060 | macos:unifiedlog | creation or loading of new launchd services |
| File ModificationDC0061 | macos:unifiedlog | write of plist files in /Library/LaunchAgents or /Library/LaunchDaemons |
| Command ExecutionDC0064 | macos:unifiedlog | execution of launchctl load/unload/start commands |
Tunable fields
MITRE calls these the analytic’s mutable elements: the thresholds and filters you set for your own environment.
| Field | What you tune |
|---|---|
| MonitoredPaths | Paths to monitor for suspicious plist files, such as /Library/LaunchAgents, /Library/LaunchDaemons, ~/Library/LaunchAgents. |
| SuspiciousExecPaths | Uncommon executable paths (e.g., /tmp, /Shared) that should raise alerts when associated with launchctl services. |
| TimeWindow | Correlation window for detecting plist file creation and subsequent launchctl execution. |
This detection is to identify a creation of "user mode service" where the service file path is located in non-common service folder in windows.
D3FEND techniques
The defensive countermeasure this analytic implements, in MITRE’s D3FEND ontology.
| ID | Name |
|---|---|
| D3-PSA | Process Spawn Analysis |
Data model references
The CAR data model objects, actions and fields the logic reads. Map these to your own schema before implementing.
| Object | Action | Field |
|---|---|---|
| service | create | image_path |
Implementations
Pseudocode is the canonical logic; the rest are CAR’s translations into vendor query languages.
Pseudocode implementation of the Splunk search below.
services = search Service:create suspicious_services = filter services where image_path = "*\.exe" AND image_path does not contain ["C:\\Windows\\*", "%windir%\\*", "C:\\Program File*", "C:\\Programdata\\*", "%systemroot%\\*"] ) output suspicious_services
To successfully implement this search, you need to be ingesting logs with the Service name, Service File Name Service Start type, and Service Type from your endpoints.
`wineventlog_system` EventCode=7045 Service_File_Name = "*\.exe" NOT (Service_File_Name IN ("C:\\Windows\\*", "%windir%\\*", "C:\\Program File*", "C:\\Programdata\\*", "%systemroot%\\*")) Service_Type = "user mode service" | stats count min(_time) as firstTime max(_time) as lastTime by EventCode Service_File_Name Service_Name Service_Start_Type Service_TypeUnit tests
CAR’s own validation procedures for this analytic.
Replay the detection [dataset](https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/malware/clop/clop_a/windows-system.log) using the Splunk attack range with the commands below
["python attack_range.py replay -dn data_dump [--dump NAME_OF_DUMP]"]
execute the atomic test [T1569.001](https://github.com/redcanaryco/atomic-red-team/tree/master/atomics/T1569.001) against a Windows target.
["Invoke-AtomicTest T1569.001"]
Prevent users from installing their own launch agents or launch daemons.
Tests from Atomic Red Team (MIT licence) · technique definition