Detection rules › Elastic

Suspicious Execution via MSIEXEC

Status
production
Kind
building block (feeds higher-level correlation rules; not a standalone alert)
Severity
low
Time window
119m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies suspicious execution of the built-in Windows Installer, msiexec.exe, to install a package from usual paths or parent process. Adversaries may abuse msiexec.exe to launch malicious local MSI files.

MITRE ATT&CK coverage

Event coverage

Rule body elastic

[metadata]
creation_date = "2023/09/26"
integration = ["endpoint", "windows"]
maturity = "production"
updated_date = "2025/03/20"

[rule]
author = ["Elastic"]
building_block_type = "default"
description = """
Identifies suspicious execution of the built-in Windows Installer, msiexec.exe, to install a package from usual paths or
parent process. Adversaries may abuse msiexec.exe to launch malicious local MSI files.
"""
from = "now-119m"
index = ["logs-endpoint.events.process-*", "winlogbeat-*", "logs-windows.*", "endgame-*"]
interval = "60m"
language = "eql"
license = "Elastic License v2"
name = "Suspicious Execution via MSIEXEC"
references = [
    "https://lolbas-project.github.io/lolbas/Binaries/Msiexec/",
    "https://www.guardicore.com/labs/purple-fox-rootkit-now-propagates-as-a-worm/",
]
risk_score = 21
rule_id = "708c9d92-22a3-4fe0-b6b9-1f861c55502d"
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Defense Evasion",
    "Rule Type: BBR",
    "Data Source: Elastic Defend",
    "Data Source: Elastic Endgame",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
process where host.os.type == "windows" and event.action == "start" and
  process.name : "msiexec.exe" and user.id : ("S-1-5-21*", "S-1-12-*") and process.parent.executable != null and
  (
    (process.args : "/i" and process.args : ("/q", "/quiet") and process.args_count == 4 and
     process.args : ("?:\\Users\\*", "?:\\ProgramData\\*") and
     not process.parent.executable : ("?:\\Program Files (x86)\\*.exe",
                                      "?:\\Program Files\\*.exe",
                                      "?:\\Windows\\explorer.exe",
                                      "?:\\Users\\*\\Desktop\\*",
                                      "?:\\Users\\*\\Downloads\\*",
                                      "?:\\programdata\\*")) or

    (process.args_count == 1 and not process.parent.executable : ("?:\\Windows\\explorer.exe", "?:\\Windows\\SysWOW64\\explorer.exe")) or

    (process.args : "/i" and process.args : ("/q", "/quiet") and process.args_count == 4 and
     (process.parent.args : "Schedule" or process.parent.name : "wmiprvse.exe" or
     process.parent.executable : "?:\\Users\\*\\AppData\\*" or
     (process.parent.name : ("powershell.exe", "cmd.exe") and length(process.parent.command_line) >= 200))) or

    (process.args : "/i" and process.args : ("/q", "/quiet") and process.args_count == 4 and
     ?process.working_directory : "?:\\" and process.parent.name : ("cmd.exe", "powershell.exe"))
  ) and

  /* noisy pattern */
  not (process.parent.executable : "?:\\Users\\*\\AppData\\Local\\Temp\\*" and ?process.parent.args_count >= 2 and
       process.args : "?:\\Users\\*\\AppData\\Local\\Temp\\*\\*.msi") and

  not process.args : ("?:\\Program Files (x86)\\*", "?:\\Program Files\\*")
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"
[[rule.threat.technique.subtechnique]]
id = "T1218.007"
name = "Msiexec"
reference = "https://attack.mitre.org/techniques/T1218/007/"



[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

Stages and Predicates

Stage 1: process

process where host.os.type == "windows" and event.action == "start" and
  process.name : "msiexec.exe" and user.id : ("S-1-5-21*", "S-1-12-*") and process.parent.executable != null and
  (
    (process.args : "/i" and process.args : ("/q", "/quiet") and process.args_count == 4 and
     process.args : ("?:\\Users\\*", "?:\\ProgramData\\*") and
     not process.parent.executable : ("?:\\Program Files (x86)\\*.exe",
                                      "?:\\Program Files\\*.exe",
                                      "?:\\Windows\\explorer.exe",
                                      "?:\\Users\\*\\Desktop\\*",
                                      "?:\\Users\\*\\Downloads\\*",
                                      "?:\\programdata\\*")) or
    (process.args_count == 1 and not process.parent.executable : ("?:\\Windows\\explorer.exe", "?:\\Windows\\SysWOW64\\explorer.exe")) or
    (process.args : "/i" and process.args : ("/q", "/quiet") and process.args_count == 4 and
     (process.parent.args : "Schedule" or process.parent.name : "wmiprvse.exe" or
     process.parent.executable : "?:\\Users\\*\\AppData\\*" or
     (process.parent.name : ("powershell.exe", "cmd.exe") and length(process.parent.command_line) >= 200))) or
    (process.args : "/i" and process.args : ("/q", "/quiet") and process.args_count == 4 and
     ?process.working_directory : "?:\\" and process.parent.name : ("cmd.exe", "powershell.exe"))
  ) and
  not (process.parent.executable : "?:\\Users\\*\\AppData\\Local\\Temp\\*" and ?process.parent.args_count >= 2 and
       process.args : "?:\\Users\\*\\AppData\\Local\\Temp\\*\\*.msi") and
  not process.args : ("?:\\Program Files (x86)\\*", "?:\\Program Files\\*")

Exclusions

Top-level NOT(...) conjuncts: predicates this rule actively suppresses.

FieldKindExcluded values
process.argswildcard?:\Users\*\AppData\Local\Temp\*\*.msi
process.parent.args_countge2
process.parent.executablewildcard?:\Users\*\AppData\Local\Temp\*
process.argsstarts_with?:\Program Files (x86)\, ?:\Program Files\

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
event.actioneq
  • start corpus 16 (elastic 16)
process.argswildcard
  • /i corpus 2 (elastic 2)
  • /q corpus 3 (elastic 3)
  • /quiet corpus 3 (elastic 3)
  • ?:\ProgramData\*
  • ?:\Users\* corpus 2 (elastic 2)
process.args_counteq
  • 1 corpus 16 (elastic 16)
  • 4
process.namewildcard
  • msiexec.exe corpus 22 (elastic 17, splunk 5)
process.parent.argswildcard
  • Schedule corpus 2 (elastic 2)
process.parent.executableis_not_null
  • (no value, null check)
process.parent.executablewildcard
  • ?:\Users\*\AppData\*
process.parent.namewildcard
  • cmd.exe corpus 15 (elastic 10, splunk 4, kusto 1)
  • powershell.exe corpus 15 (elastic 12, kusto 2, splunk 1)
  • wmiprvse.exe corpus 11 (elastic 7, splunk 4)
process.working_directorywildcard
  • ?:\
user.idwildcard
  • S-1-12-* corpus 4 (elastic 4)
  • S-1-5-21* corpus 5 (elastic 5)