T1543.001 CrowdStrike LogScale · LogScale

Detect Launch Agent in CrowdStrike LogScale

Adversaries may create or modify launch agents to repeatedly execute malicious payloads as part of persistence on macOS. When a user logs in, a per-user launchd process loads parameters for each launch-on-demand user agent from property list (.plist) files in /System/Library/LaunchAgents, /Library/LaunchAgents, and ~/Library/LaunchAgents. Adversaries install Launch Agents by placing a .plist file into these directories with RunAtLoad or KeepAlive keys set to true, ensuring malicious payloads execute at every user login. Launch Agents execute with user-level permissions and are commonly disguised using Apple-like naming conventions (e.g., com.apple.softwareupdate.plist, com.apple.GrowlHelper.plist). This technique is used by Calisto, Proton, MacSpy, CrossRAT, Dok, OceanLotus, ThiefQuest, Dacls, macOS.OSAMiner, InvisibleFerret (Contagious Interview), CoinTicker, and Green Lambert malware families.

MITRE ATT&CK

Tactic
Persistence Privilege Escalation
Technique
T1543 Create or Modify System Process
Sub-technique
T1543.001 Launch Agent
Canonical reference
https://attack.mitre.org/techniques/T1543/001/

LogScale Detection Query

CrowdStrike LogScale (LogScale)
cql
// Branch 1: Plist file creation in LaunchAgent directories by suspicious initiating processes
#repo=base_sensor_telemetry
| #event_simpleName IN (MacFileCreationV1, MacFileWrittenV1)
| TargetPath = /\/Library\/LaunchAgents\/.+\.plist/
| SuspiciousWriter := match(field=ImageFileName, regex="/(bash|sh|zsh|python3|python|ruby|perl|curl|wget|osascript|node|npm|installer|pkgutil|xattr|mktemp)$")
| AppleNameSpoof := match(field=TargetPath, regex="com\.apple\.[a-z]+\.[a-z]+\.plist") AND NOT match(field=TargetPath, regex="^/System/Library/")
| RandomName := match(field=TargetPath, regex="com\.[a-z0-9]{4,10}\.[a-z0-9]{4,10}\.plist") AND NOT match(field=TargetPath, regex="(com\.apple\.|com\.microsoft\.|com\.adobe\.|com\.google\.)")
| AgentScope := if(TargetPath = /^\/System\/Library\/LaunchAgents\//, "System",
    if(TargetPath = /^\/Library\/LaunchAgents\//, "Global", "User"))
| RiskScore := if(SuspiciousWriter, 1, 0) + if(AppleNameSpoof, 1, 0) + if(RandomName, 1, 0)
| RiskScore > 0
| table([@timestamp, ComputerName, UserName, TargetPath, ImageFileName, CommandLine, AgentScope, SuspiciousWriter, AppleNameSpoof, RandomName, RiskScore])
| sort(RiskScore, order=desc)

// Branch 2: launchctl load or bootstrap targeting LaunchAgent paths
// Run as a separate query or union via saved searches
#repo=base_sensor_telemetry
| #event_simpleName IN (MacProcessRollup2, ProcessRollup2)
| ImageFileName=/\/launchctl$/
| (CommandLine=/\bload\b/ OR CommandLine=/\bbootstrap\b/)
| (CommandLine=/LaunchAgents/ OR CommandLine=/\.plist/)
| ParentBaseFileName := FileName(ParentImageFileName)
| SuspiciousParent := match(field=ParentBaseFileName, regex="^(bash|sh|zsh|python3|python|ruby|perl|curl|wget|osascript|node|npm|installer|pkgutil)$")
| AppleNameSpoof := match(field=CommandLine, regex="com\.apple\.[a-z]+\.[a-z]+\.plist") AND NOT match(field=CommandLine, regex="/System/Library/")
| AgentScope := if(CommandLine=/\/System\/Library\/LaunchAgents/, "System",
    if(CommandLine=/\/Library\/LaunchAgents/, "Global", "User"))
| table([@timestamp, ComputerName, UserName, CommandLine, ParentBaseFileName, AgentScope, SuspiciousParent, AppleNameSpoof])
| sort(@timestamp, order=desc)
high severity high confidence

Two CrowdStrike LogScale (Falcon) queries detecting macOS Launch Agent persistence. Query 1 identifies suspicious plist file writes into LaunchAgent directories by shells, interpreters, and download utilities, scoring by name-spoofing and process risk. Query 2 catches launchctl load/bootstrap commands targeting LaunchAgent paths when executed by high-risk parent processes.

Data Sources

CrowdStrike Falcon sensor (macOS)Falcon telemetry events: MacFileCreationV1, MacFileWrittenV1, MacProcessRollup2

Required Tables

base_sensor_telemetry (#event_simpleName: MacFileCreationV1, MacFileWrittenV1, MacProcessRollup2, ProcessRollup2)

False Positives & Tuning

  • Xcode command-line tools and CocoaPods post-install scripts write launch agents using sh or ruby during dependency installation on developer machines, generating frequent matches on the file creation branch
  • macOS system integrity protection (SIP) bypass testing tools and legitimate security research frameworks deliberately place test plists in LaunchAgent paths using curl or bash to validate endpoint detection coverage
  • Enterprise backup agents (Time Machine, Carbonite, Backblaze) and VPN clients (Cisco AnyConnect, GlobalProtect) install LaunchAgents via installer during initial deployment or version upgrades, matching on AgentScope=Global
Download portable Sigma rule (.yml)

Other platforms for T1543.001


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.

  1. Test 1Create Persistent Launch Agent via Bash

    Expected signal: DeviceFileEvents: FileCreated action for file 'com.df00tech.atomictest.plist' in '~/Library/LaunchAgents/', InitiatingProcessFileName='bash'. osquery_differential: action='added' in launchd table with label='com.df00tech.atomictest', run_at_load='1', program_arguments='/bin/bash -c date...'.

  2. Test 2Load Launch Agent with launchctl

    Expected signal: DeviceProcessEvents: FileName='launchctl', ProcessCommandLine contains 'load' and 'LaunchAgents/com.df00tech.launchctltest.plist', InitiatingProcessFileName='bash'. DeviceFileEvents: FileCreated for the plist in LaunchAgents directory.

  3. Test 3Apple Name Spoof Launch Agent (MacMa/Green Lambert Pattern)

    Expected signal: DeviceFileEvents: FileCreated for 'com.apple.softwareupdate.helper.plist' in ~/Library/LaunchAgents/, InitiatingProcessFileName='bash'. osquery_differential: action='added', label='com.apple.softwareupdate.helper', run_at_load='1', keep_alive='1', path contains '/Users/<user>/Library/LaunchAgents/'.

  4. Test 4KeepAlive Launch Agent with Randomly Named Plist (Dok/CoinTicker Pattern)

    Expected signal: DeviceFileEvents: FileCreated for 'com.<rand1>.<rand2>.plist' in ~/Library/LaunchAgents/, InitiatingProcessFileName='bash'. osquery_differential: action='added', label='com.<rand1>.<rand2>', run_at_load='1', keep_alive='1'.

Unlock Pro Content

Get the full detection package for T1543.001 including response playbook, investigation guide, and atomic red team tests.

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections