macOS launchd deep audit LaunchAgent / LaunchDaemon plist deep audit (L1-L7) — what the generic persistence detector misses.

The generic persistence_outlier detector flags launchd plists whose programs live in writable temp dirs. MacosLaunchdDetector covers the macOS-launchd-specific patterns it doesn't.

How it works

The macos.launchd collector already emits one Artifact per plist (parsing ProgramArguments / RunAtLoad / KeepAlive / WatchPaths / QueueDirectories / Label / etc); this detector runs deeper rules against those fields. Apple's /System/Library/Launch{Daemons,Agents}/* plists with a com.apple.* Label are SIP-protected and skipped.

Detection layers (L1–L7)

IDSeverityWhat it catchesMITRE
L1high → criticalNetwork-fetch in ProgramArguments. Critical when piped to shell. The Silver Sparrow / Shlayer / OSAMiner / BundloreRunner downloader pattern.T1543.001
L2mediumLong base64 / hex blob in arguments. Common hiding place for shellcode or a one-line Python downloader.T1027
L3mediumLabel / filename mismatch. Plist file com.evil.malware.plist declares Label = com.apple.softwareupdate — documented masquerade in OSX/Silver Sparrow, OSX/Cocyer, JaskaGO.T1036
L4highWatchPaths or QueueDirectories on user-writable dir. Anyone with write access to that path fires the payload — "drop a file, get RCE" persistence chain.T1546
L5mediumEmpty or missing Label key. Most legitimate plists set Label; missing is a malware-behavior signature.T1543.001
L6highInterpreter (/bin/sh, /bin/bash, python, perl, ruby) + KeepAlive=true = launchd respawn loop = daemon-shaped malware.T1059.004
L7mediumPlist runs osascript. AppleScript can drive other apps via AppleEvents, prompt for credentials, scrape browser state — privilege-escalation primitive. Legit users exist (Bartender, Hammerspoon) but rare in a daemon.T1059.002

No new CLI needed

The existing macos.launchd collector already runs as part of digger collect; the detector runs at digger scan time.