Detection rules › Elastic

Execution via MS VisualStudio Pre/Post Build Events

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

Identifies the execution of a command via Microsoft Visual Studio Pre or Post build events. Adversaries may backdoor a trusted visual studio project to execute a malicious command during the project build process.

MITRE ATT&CK coverage

Event coverage

Rule body elastic

[metadata]
creation_date = "2023/09/26"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
building_block_type = "default"
description = """
Identifies the execution of a command via Microsoft Visual Studio Pre or Post build events. Adversaries may backdoor a
trusted visual studio project to execute a malicious command during the project build process.
"""
from = "now-119m"
index = ["logs-endpoint.events.process-*"]
interval = "60m"
language = "eql"
license = "Elastic License v2"
name = "Execution via MS VisualStudio Pre/Post Build Events"
references = [
    "https://docs.microsoft.com/en-us/visualstudio/ide/reference/pre-build-event-post-build-event-command-line-dialog-box?view=vs-2022",
    "https://www.pwc.com/gx/en/issues/cybersecurity/cyber-threat-intelligence/threat-actor-of-in-tur-est.html",
    "https://blog.google/threat-analysis-group/new-campaign-targeting-security-researchers/",
    "https://github.com/sbousseaden/EVTX-ATTACK-SAMPLES/blob/master/Execution/execution_evasion_visual_studio_prebuild_event.evtx",
]
risk_score = 21
rule_id = "fec7ccb7-6ed9-4f98-93ab-d6b366b063a0"
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Defense Evasion",
    "Tactic: Execution",
    "Rule Type: BBR",
    "Data Source: Elastic Defend",
]
type = "eql"

query = '''
sequence with maxspan=1m
  [process where host.os.type == "windows" and event.action == "start" and
   process.name : "cmd.exe" and process.parent.name : "MSBuild.exe" and
   process.args : "?:\\Users\\*\\AppData\\Local\\Temp\\tmp*.exec.cmd"] by process.entity_id
  [process where host.os.type == "windows" and event.action == "start" and
    process.name : (
      "cmd.exe", "powershell.exe",
      "MSHTA.EXE", "CertUtil.exe",
      "CertReq.exe", "rundll32.exe",
      "regsvr32.exe", "MSbuild.exe",
      "cscript.exe", "wscript.exe",
      "installutil.exe"
    ) and
    not 
    (
      process.name : ("cmd.exe", "powershell.exe") and
      process.args : (
        "*\\vcpkg\\scripts\\buildsystems\\msbuild\\applocal.ps1",
        "HKLM\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS?",
        "process.versions.node*",
        "?:\\Program Files\\nodejs\\node.exe",
        "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\*",
        "*Get-ChildItem*Tipasplus.css*",
        "Build\\GenerateResourceScripts.ps1",
        "Shared\\Common\\..\\..\\BuildTools\\ConfigBuilder.ps1\"",
        "?:\\Projets\\*\\PostBuild\\MediaCache.ps1"
      )
    ) and
    not process.executable : "?:\\Program Files*\\Microsoft Visual Studio\\*\\MSBuild.exe" and
    not (process.name : "cmd.exe" and
         process.command_line :
                  ("*vswhere.exe -property catalog_productSemanticVersion*",
                   "*git log --pretty=format*", "*\\.nuget\\packages\\vswhere\\*",
                   "*Common\\..\\..\\BuildTools\\*"))
  ] by process.parent.entity_id
'''


[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1127"
name = "Trusted Developer Utilities Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1127/"

[[rule.threat.technique.subtechnique]]
id = "T1127.001"
name = "MSBuild"
reference = "https://attack.mitre.org/techniques/T1127/001/"

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

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"

[[rule.threat.technique.subtechnique]]
id = "T1059.003"
name = "Windows Command Shell"
reference = "https://attack.mitre.org/techniques/T1059/003/"

[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"

Stages and Predicates

Ordered sequence: each step below must occur in order within 1m, correlated by process.entity_id, process.parent.entity_id.

Stage 1: process

[process where host.os.type == "windows" and event.action == "start" and
   process.name : "cmd.exe" and process.parent.name : "MSBuild.exe" and
   process.args : "?:\\Users\\*\\AppData\\Local\\Temp\\tmp*.exec.cmd"]

Stage 2: process

[process where host.os.type == "windows" and event.action == "start" and
    process.name : (
      "cmd.exe", "powershell.exe",
      "MSHTA.EXE", "CertUtil.exe",
      "CertReq.exe", "rundll32.exe",
      "regsvr32.exe", "MSbuild.exe",
      "cscript.exe", "wscript.exe",
      "installutil.exe"
    ) and
    not 
    (
      process.name : ("cmd.exe", "powershell.exe") and
      process.args : (
        "*\\vcpkg\\scripts\\buildsystems\\msbuild\\applocal.ps1",
        "HKLM\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS?",
        "process.versions.node*",
        "?:\\Program Files\\nodejs\\node.exe",
        "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\*",
        "*Get-ChildItem*Tipasplus.css*",
        "Build\\GenerateResourceScripts.ps1",
        "Shared\\Common\\..\\..\\BuildTools\\ConfigBuilder.ps1\"",
        "?:\\Projets\\*\\PostBuild\\MediaCache.ps1"
      )
    ) and
    not process.executable : "?:\\Program Files*\\Microsoft Visual Studio\\*\\MSBuild.exe" and
    not (process.name : "cmd.exe" and
         process.command_line :
                  ("*vswhere.exe -property catalog_productSemanticVersion*",
                   "*git log --pretty=format*", "*\\.nuget\\packages\\vswhere\\*",
                   "*Common\\..\\..\\BuildTools\\*"))
  ]

Exclusions

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

FieldKindExcluded values
process.argswildcard*\vcpkg\scripts\buildsystems\msbuild\applocal.ps1, HKLM\SOFTWARE\Microsoft\VisualStudio\SxS\VS?, process.versions.node*, ?:\Program Files\nodejs\node.exe, HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\*, *Get-ChildItem*Tipasplus.css*, Build\GenerateResourceScripts.ps1, Shared\Common\..\..\BuildTools\ConfigBuilder.ps1", ?:\Projets\*\PostBuild\MediaCache.ps1
process.nameeqcmd.exe, powershell.exe
process.command_linematchvswhere.exe -property catalog_productSemanticVersion, git log --pretty=format, \.nuget\packages\vswhere\, Common\..\..\BuildTools\
process.nameeqcmd.exe
process.executablewildcard?:\Program Files*\Microsoft Visual Studio\*\MSBuild.exe

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
  • ?:\Users\*\AppData\Local\Temp\tmp*.exec.cmd
process.namewildcard
  • CertReq.exe corpus 7 (elastic 7)
  • CertUtil.exe corpus 22 (elastic 16, splunk 6)
  • MSHTA.EXE corpus 31 (elastic 26, splunk 5)
  • MSbuild.exe corpus 16 (elastic 13, splunk 3)
  • cmd.exe corpus 77 (elastic 48, splunk 29)
  • cscript.exe corpus 25 (elastic 23, splunk 2)
  • installutil.exe corpus 18 (elastic 13, splunk 5)
  • powershell.exe corpus 104 (elastic 60, splunk 44)
  • regsvr32.exe corpus 25 (elastic 19, splunk 6)
  • rundll32.exe corpus 60 (elastic 34, splunk 26)
  • wscript.exe corpus 29 (elastic 28, splunk 1)
process.parent.namewildcard
  • MSBuild.exe