MacOS Installer Package Spawns Network Eventedit

Detects the execution of a MacOS installer package with an abnormal child process (e.g bash) followed immediately by a network connection via a suspicious process (e.g curl). Threat actors will build and distribute malicious MacOS installer packages, which have a .pkg extension, many times imitating valid software in order to persuade and infect their victims often using the package files (e.g pre/post install scripts etc.) to download additional tools or malicious software. If this rule fires it should indicate the installation of a malicious or suspicious package.

Rule type: eql

Rule indices:

  • logs-endpoint.events.*

Severity: medium

Risk score: 47

Runs every: 5 minutes

Searches indices from: now-9m (Date Math format, see also Additional look-back time)

Maximum alerts per execution: 100

References:

Tags:

  • Elastic
  • Host
  • macOS
  • Threat Detection
  • Execution
  • Command and Control

Version: 100 (version history)

Added (Elastic Stack release): 7.12.0

Last modified (Elastic Stack release): 8.5.0

Rule authors: Elastic

Rule license: Elastic License v2

Potential false positivesedit

Custom organization-specific macOS packages that use .pkg files to run cURL could trigger this rule. If known behavior is causing false positives, it can be excluded from the rule.

Rule queryedit

sequence by host.id, user.id with maxspan=30s [process where
event.type == "start" and event.action == "exec" and
process.parent.name : ("installer", "package_script_service") and
process.name : ("bash", "sh", "zsh", "python", "osascript", "tclsh*")]
[network where event.type == "start" and process.name : ("curl",
"osascript", "wget", "python")]

Threat mappingedit

Framework: MITRE ATT&CKTM

Rule version historyedit

Version 100 (8.5.0 release)
  • Updated query, changed from:

    sequence by host.id, user.id with maxspan=30s [process where
    event.type == "start" and event.action == "exec" and
    process.parent.name : ("installer", "package_script_service") and
    process.name : ("bash", "sh", "zsh", "python", "osascript", "tclsh*")]
    [network where event.type == "start" and process.name : ("curl",
    "osascript", "wget", "python")]
Version 6 (8.4.0 release)
  • Rule name changed from: macOS Installer Spawns Network Event
  • Updated query, changed from:

    sequence by process.entity_id with maxspan=1m [process where
    event.type == "start" and host.os.family == "macos" and
    process.parent.executable in ("/usr/sbin/installer",
    "/System/Library/CoreServices/Installer.app/Contents/MacOS/Installer")
    ] [network where not cidrmatch(destination.ip, "10.0.0.0/8",
    "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24",
    "192.0.0.0/29", "192.0.0.8/32", "192.0.0.9/32", "192.0.0.10/32",
    "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24", "192.31.196.0/24",
    "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", "224.0.0.0/4",
    "100.64.0.0/10", "192.175.48.0/24", "198.18.0.0/15",
    "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1",
    "FE80::/10", "FF00::/8")]
Version 4 (8.2.0 release)
  • Formatting only
Version 3 (7.15.0 release)
  • Formatting only
Version 2 (7.14.0 release)
  • Updated query, changed from:

    sequence by process.entity_id with maxspan=1m [ process where
    event.type == "start" and host.os.family == "macos" and
    process.parent.executable in ("/usr/sbin/installer",
    "/System/Library/CoreServices/Installer.app/Contents/MacOS/Installer")
    ] [ network where not cidrmatch(destination.ip,
    "192.168.0.0/16", "10.0.0.0/8", "172.16.0.0/12",
    "224.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16",
    "::1", "FE80::/10", "FF00::/8") ]