T1647

Plist File Modification

Defense Evasion Last updated:

This detection identifies adversarial modification of macOS property list (plist) files to enable persistence, evade defenses, or alter application behavior. Attackers use tools such as plutil, PlistBuddy, and the defaults command to insert or modify keys like LSUIElement (hide app from UI), LSEnvironment (inject environment variables for dynamic linker hijacking), RunAtLoad, and ProgramArguments in LaunchAgent or LaunchDaemon plists. Known malware families including XCSSET and Cuckoo Stealer abuse plist modification to persist across reboots and conceal malicious processes. The detection monitors process execution of common plist editing utilities with arguments targeting sensitive keys and system persistence paths.

What is T1647 Plist File Modification?

Plist File Modification (T1647) maps to the Defense Evasion tactic — the adversary is trying to avoid being detected in MITRE ATT&CK.

This page provides production-ready detection logic for Plist File Modification, covering the data sources and telemetry it touches: Microsoft Defender for Endpoint. The queries below are rated high severity at medium confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.

MITRE ATT&CK

Tactic
Defense Evasion
Technique
T1647 Plist File Modification
Canonical reference
https://attack.mitre.org/techniques/T1647/
Microsoft Sentinel / Defender
kusto
let SuspiciousPlistKeys = dynamic(["LSUIElement", "LSEnvironment", "RunAtLoad", "ProgramArguments", "StartCalendarInterval", "KeepAlive", "DFBundleDisplayName", "CFBundleIdentifier", "LSBackgroundOnly"]);
let PersistencePaths = dynamic(["LaunchAgents", "LaunchDaemons", "com.apple.dock", "com.apple.loginwindow", "com.apple.loginitems"]);
let PlistEditors = dynamic(["plutil", "PlistBuddy", "defaults"]);
let SuspiciousParents = dynamic(["bash", "zsh", "sh", "python3", "perl", "ruby", "osascript", "curl", "wget"]);
// Primary: direct plist editor execution with suspicious arguments
let DirectEdits = DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName in~ (PlistEditors)
| where ProcessCommandLine has ".plist"
| where ProcessCommandLine has_any ("-insert", "-replace", "-set", "-remove", "write", "-convert", "-extract", "add", "delete")
| extend MatchedKey = case(
    ProcessCommandLine has_any (SuspiciousPlistKeys), "SuspiciousPlistKey",
    ProcessCommandLine has_any (PersistencePaths), "PersistencePath",
    true, "GenericPlistEdit"
)
| extend DetectionType = "DirectPlistEdit";
// Secondary: scripting language modifying plist files directly
let ScriptEdits = DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName in~ ("python3", "python", "perl", "ruby", "osascript", "node")
| where ProcessCommandLine has ".plist"
| where ProcessCommandLine has_any ("writePlist", "plistlib", "NSUserDefaults", "CFPreferences", "PropertyList", "plist.write")
| extend MatchedKey = "ScriptingLanguagePlistWrite"
| extend DetectionType = "ScriptPlistEdit";
// Combine and enrich
DirectEdits
| union ScriptEdits
| extend SuspiciousParentContext = InitiatingProcessFileName in~ (SuspiciousParents)
| extend SuspiciousPathContext = FolderPath has_any ("tmp", ".hidden", "Downloads", "Library/Application Support")
| extend RiskScore = case(
    MatchedKey == "SuspiciousPlistKey" and SuspiciousParentContext, 90,
    MatchedKey == "PersistencePath" and SuspiciousParentContext, 80,
    MatchedKey == "SuspiciousPlistKey", 70,
    MatchedKey == "PersistencePath", 65,
    SuspiciousParentContext, 50,
    40
)
| where RiskScore >= 50
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, MatchedKey, DetectionType, RiskScore, FolderPath
| order by RiskScore desc, Timestamp desc

Detects execution of macOS plist editing utilities (plutil, PlistBuddy, defaults) and scripting language invocations that write to plist files. The query prioritizes modifications targeting high-risk keys (LSUIElement, LSEnvironment, RunAtLoad, ProgramArguments) and persistence paths (LaunchAgents, LaunchDaemons) while scoring alerts based on parent process context and invocation patterns consistent with malware behavior.

high severity medium confidence

Data Sources

Microsoft Defender for Endpoint

Required Tables

DeviceProcessEvents

False Positives

  • Legitimate macOS application installers using plutil or PlistBuddy to configure app preferences during setup
  • System administrators using the defaults command to manage enterprise preferences and MDM profiles
  • Developer tooling such as Xcode build scripts or CocoaPods that modify Info.plist during compilation
  • Homebrew package manager modifying application plist files during install or upgrade operations
  • IT management tools (Jamf, Munki, Chef) that programmatically write LaunchAgent plists for legitimate automation

Sigma rule & cross-platform mapping

The detection logic for Plist File Modification (T1647) above is provided in a vendor-neutral form so you can deploy it on any SIEM. The same logic is shipped here as native KQL (Microsoft Sentinel / Defender), SPL (Splunk), Elastic (Elastic Security (EQL)), QRadar (IBM QRadar (AQL)), Sumo (Sumo Logic CSE), YARA-L (Google Chronicle / SecOps), LogScale (CrowdStrike LogScale (CQL)) queries. In Sigma terms, this detection targets the following logsource:

logsource:
  category: process_creation
  product: windows

Browse the community-maintained Sigma rules for this technique:


Testing Methodology

Validate this detection against 3 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 1Modify LSUIElement to hide macOS application via plutil

    Expected signal: DeviceProcessEvents: plutil process with -insert LSUIElement argument targeting a .plist file path; InitiatingProcessFileName will be the shell (bash/zsh)

  2. Test 2Write malicious LaunchAgent plist for persistence via PlistBuddy

    Expected signal: DeviceProcessEvents: PlistBuddy with multiple Add command invocations targeting ~/Library/LaunchAgents/; DeviceFileEvents: .plist file creation in LaunchAgents directory

  3. Test 3Inject LSEnvironment with DYLD_INSERT_LIBRARIES for dynamic linker hijacking setup

    Expected signal: DeviceProcessEvents: PlistBuddy with 'Add :LSEnvironment dict' and 'Add :LSEnvironment:DYLD_INSERT_LIBRARIES' command arguments; high-fidelity process args containing both LSEnvironment and DYLD_INSERT_LIBRARIES strings

Unlock Pro Content

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

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections