Detection rules › Elastic

Elastic rules: 3b

AWS IAM AdministratorAccess Policy Attached to Role

#
Status
production
Severity
medium
Time window
6m
Author
Elastic
Source
github.com/elastic/detection-rules

An adversary with access to a set of compromised credentials may attempt to persist or escalate privileges by attaching additional permissions to compromised IAM roles. This rule looks for use of the IAM AttachRolePolicy API operation to attach the highly permissive AdministratorAccess AWS managed policy to an existing IAM role.

Known False Positives

  • While this can be normal behavior, it should be investigated to ensure validity. Verify whether the user identity should be using the IAM `AttachRolePolicy` API operation to attach the `AdministratorAccess` policy to the target role.

MITRE ATT&CK Coverage

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2024/05/31"
integration = ["aws"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
An adversary with access to a set of compromised credentials may attempt to persist or escalate privileges by attaching
additional permissions to compromised IAM roles. This rule looks for use of the IAM AttachRolePolicy API operation to
attach the highly permissive AdministratorAccess AWS managed policy to an existing IAM role.
"""
false_positives = [
    """
    While this can be normal behavior, it should be investigated to ensure validity. Verify whether the user identity
    should be using the IAM `AttachRolePolicy` API operation to attach the `AdministratorAccess` policy to the target
    role.
    """,
]
from = "now-6m"
index = ["logs-aws.cloudtrail-*"]
language = "eql"
license = "Elastic License v2"
name = "AWS IAM AdministratorAccess Policy Attached to Role"
note = """## Triage and analysis

### Investigating AWS IAM AdministratorAccess Policy Attached to Role

The `AdministratorAccess` managed policy grants unrestricted privileges.  
When attached to a role, it can enable privilege escalation or persistence, especially if the role is assumable by other accounts or services.  
This rule detects `AttachRolePolicy` events where the `policyName` is `AdministratorAccess`.

#### Possible investigation steps

- **Identify both identities.**  
  Determine the calling user or role (`aws.cloudtrail.user_identity.arn`) and the target role (`aws.cloudtrail.request_parameters.roleName`).  
  Validate whether this change aligns with intended administrative actions.  

- **Review the target role’s trust policy.**  
  Examine who can assume the role (`AssumeRolePolicyDocument`).  
  If the role is assumable by external accounts, this may indicate a potential persistence or lateral movement path.  

- **Review CloudTrail details.**  
  Check `source.ip`, `user_agent.original`, and `source.geo` fields for anomalies.  
  Compare with historical operations by the same principal.  

- **Correlate with adjacent IAM events.**  
  Look for `UpdateAssumeRolePolicy`, `CreateAccessKey`, or `PassRole` calls.  
  These often accompany privilege escalation activity.  

- **Inspect downstream activity.**  
  Query CloudTrail for recent `AssumeRole` calls for the target role — determine if the newly elevated permissions were used.  

### False positive analysis

- **Delegated role management.**  
  Cloud administrators may legitimately grant temporary AdministratorAccess for troubleshooting. Confirm through tickets or change logs.  
- **Automation or service-linked roles.**  
  Some services attach policies automatically for setup; verify whether the target is a service-linked role.  

### Response and remediation

**Immediate containment**
- Detach the policy. Remove the `AdministratorAccess` policy from the target role.  
- Restrict access. Temporarily revoke the caller’s IAM privileges until the legitimacy of the action is confirmed.  
- Audit trust policies. Review the role’s trust relationships to ensure only approved principals can assume it.  
- Rotate credentials for any principals who assumed the affected role during the period of elevated privileges.  

**Evidence preservation**
- Export the triggering `AttachRolePolicy` event and related CloudTrail entries ±30 minutes from the alert.  
- Preserve AWS Config snapshots and GuardDuty findings for traceability.  

**Scoping and investigation**
- Identify if the elevated role was subsequently assumed.  
  Correlate by matching `aws.cloudtrail.eventName:AssumeRole` with the target role ARN.  
- Search for other recent IAM policy attachments or modifications by the same actor or IP.  

**Recovery and hardening**
- Apply least privilege policies; limit who can attach or modify administrative policies.  
- Enforce IAM Conditions such as `aws:PrincipalArn` or `aws:ResourceTag` to limit policy attachment scope.  
- Enable CloudTrail, GuardDuty, and Security Hub across all regions.  
- Implement SCPs at the organization level to restrict direct `AdministratorAccess` attachments.  

### Additional information
- **[AWS IR Playbooks](https://github.com/aws-samples/aws-incident-response-playbooks/blob/c151b0dc091755fffd4d662a8f29e2f6794da52c/playbooks/): response steps related to IAM policy modification and unauthorized privilege escalation..  
- **[AWS Customer Playbook Framework](https://github.com/aws-samples/aws-customer-playbook-framework/): for containment, analysis, and recovery guidance.
- **AWS Documentation:** [AdministratorAccess Policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html#jf_administrator).  
"""
references = [
    "https://docs.aws.amazon.com/IAM/latest/APIReference/API_AttachRolePolicy.html",
    "https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AdministratorAccess.html",
    "https://hackingthe.cloud/aws/exploitation/iam_privilege_escalation/",
]
risk_score = 47
rule_id = "dde13d58-bc39-4aa0-87fd-b4bdbf4591da"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Data Source: AWS",
    "Data Source: Amazon Web Services",
    "Data Source: AWS IAM",
    "Use Case: Identity and Access Audit",
    "Tactic: Privilege Escalation",
    "Tactic: Persistence",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
iam where data_stream.dataset == "aws.cloudtrail"
   and event.provider == "iam.amazonaws.com"
   and event.action == "AttachRolePolicy"
   and event.outcome == "success"
   and stringContains(aws.cloudtrail.request_parameters, "policyArn=arn:aws:iam::aws:policy/AdministratorAccess")
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[[rule.threat.technique.subtechnique]]
id = "T1098.003"
name = "Additional Cloud Roles"
reference = "https://attack.mitre.org/techniques/T1098/003/"



[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[[rule.threat.technique.subtechnique]]
id = "T1098.003"
name = "Additional Cloud Roles"
reference = "https://attack.mitre.org/techniques/T1098/003/"



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

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "user.name",
    "user_agent.original",
    "source.ip",
    "aws.cloudtrail.user_identity.arn",
    "aws.cloudtrail.user_identity.type",
    "aws.cloudtrail.user_identity.access_key_id",
    "event.action",
    "event.outcome",
    "cloud.account.id",
    "cloud.region",
    "aws.cloudtrail.request_parameters",
]

Stages and Predicates

Stage 1: iam

iam where data_stream.dataset == "aws.cloudtrail"
   and event.provider == "iam.amazonaws.com"
   and event.action == "AttachRolePolicy"
   and event.outcome == "success"
   and stringContains(aws.cloudtrail.request_parameters, "policyArn=arn:aws:iam::aws:policy/AdministratorAccess")

Indicators

These rows show field, operator, and value matches.

AWS STS GetFederationToken with AdministratorAccess in Request

#
Status
production
Severity
high
Time window
6m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies successful calls to AWS STS GetFederationToken where request parameters reference AdministratorAccess. This API returns temporary security credentials for a federated user with permissions bounded by the calling IAM user and any inline session policy passed in the request. Supplying or referencing the AWS managed AdministratorAccess policy (or an equivalent string in the policy payload) can grant broadly privileged temporary credentials and may indicate privilege abuse or dangerous automation.

Known False Positives

  • Highly unusual for legitimate workflows to embed or reference full administrator access in GetFederationToken session policies; if found, it is often legacy or misconfigured tooling. Confirm with the owning team and replace with least-privilege session policies. Tune only after documented approval.

MITRE ATT&CK Coverage

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2026/04/08"
integration = ["aws"]
maturity = "production"
updated_date = "2026/04/08"

[rule]
author = ["Elastic"]
description = """
Identifies successful calls to AWS STS GetFederationToken where request parameters reference AdministratorAccess. This API
returns temporary security credentials for a federated user with permissions bounded by the calling IAM user and any
inline session policy passed in the request. Supplying or referencing the AWS managed AdministratorAccess policy (or an
equivalent string in the policy payload) can grant broadly privileged temporary credentials and may indicate privilege
abuse or dangerous automation.
"""
false_positives = [
    """
    Highly unusual for legitimate workflows to embed or reference full administrator access in GetFederationToken session
    policies; if found, it is often legacy or misconfigured tooling. Confirm with the owning team and replace with
    least-privilege session policies. Tune only after documented approval.
    """,
]
from = "now-6m"
index = ["filebeat-*", "logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS STS GetFederationToken with AdministratorAccess in Request"
note = """## Triage and analysis

### Investigating AWS STS GetFederationToken with AdministratorAccess in Request

`GetFederationToken` issues temporary credentials (typically up to 36 hours) for a **federated user name** you specify.
The effective permissions are the **intersection** of the IAM user’s permissions and the optional session policy in the
request. Including `AdministratorAccess` in `Policy` (or a policy ARN / JSON that names it) is almost always
over-privileged for federation use cases. For first-time `GetFederationToken` usage without this policy signal, see
**AWS First Occurrence of STS GetFederationToken Request by User**.

**Note:** AWS documents that `GetFederationToken` must be called with **long-term IAM user credentials** (not role
temporary credentials). Pivot on `aws.cloudtrail.user_identity.arn` and `access_key_id` accordingly.

#### Possible investigation steps

- Parse `aws.cloudtrail.request_parameters` for `name`, `policy`, and `durationSeconds`.
- Confirm whether the IAM user should perform federation or if the key may be compromised.
- Search CloudTrail for subsequent events using `response_elements.credentials.accessKeyId` from the same response (if
  logged).
- Correlate with IAM changes, data-plane access, or other STS calls from the same `source.ip` in a ±30 minute window.

### False positive analysis

- Typos or test accounts in non-production: still validate and narrow session policies.

### Response and remediation

- Revoke or rotate the IAM user access keys involved; enforce least privilege on the user and replace broad session
  policies.
- [GetFederationToken](https://docs.aws.amazon.com/STS/latest/APIReference/API_GetFederationToken.html)

### Additional information

- [AWS STS temporary security credentials](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html)
"""
references = [
    "https://docs.aws.amazon.com/STS/latest/APIReference/API_GetFederationToken.html",
    "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html",
]
risk_score = 73
rule_id = "f2a3b4c5-d6e7-4f89-a012-b3c4d5e6f789"
severity = "high"
tags = [
    "Domain: Cloud",
    "Domain: Identity",
    "Data Source: AWS",
    "Data Source: Amazon Web Services",
    "Data Source: AWS STS",
    "Use Case: Threat Detection",
    "Tactic: Privilege Escalation",
    "Tactic: Lateral Movement",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
event.dataset: "aws.cloudtrail"
    and event.provider: "sts.amazonaws.com"
    and event.action: "GetFederationToken"
    and event.outcome: "success"
    and aws.cloudtrail.request_parameters: *AdministratorAccess*
'''

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "user.name",
    "user_agent.original",
    "source.ip",
    "aws.cloudtrail.user_identity.arn",
    "aws.cloudtrail.user_identity.type",
    "aws.cloudtrail.user_identity.access_key_id",
    "event.action",
    "event.outcome",
    "cloud.account.id",
    "cloud.region",
    "aws.cloudtrail.request_parameters",
    "aws.cloudtrail.response_elements",
]

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

[[rule.threat.technique]]
id = "T1548"
name = "Abuse Elevation Control Mechanism"
reference = "https://attack.mitre.org/techniques/T1548/"

[[rule.threat.technique.subtechnique]]
id = "T1548.005"
name = "Temporary Elevated Cloud Access"
reference = "https://attack.mitre.org/techniques/T1548/005/"

[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"

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

[[rule.threat.technique]]
id = "T1550"
name = "Use Alternate Authentication Material"
reference = "https://attack.mitre.org/techniques/T1550/"

[[rule.threat.technique.subtechnique]]
id = "T1550.001"
name = "Application Access Token"
reference = "https://attack.mitre.org/techniques/T1550/001/"

[rule.threat.tactic]
id = "TA0008"
name = "Lateral Movement"
reference = "https://attack.mitre.org/tactics/TA0008/"

Stages and Predicates

Stage 1: query

event.dataset: "aws.cloudtrail"
    and event.provider: "sts.amazonaws.com"
    and event.action: "GetFederationToken"
    and event.outcome: "success"
    and aws.cloudtrail.request_parameters: *AdministratorAccess*

Indicators

These rows show field, operator, and value matches.

Azure VM Extension Deployment by User

#
Status
production
Severity
medium
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies the successful deployment of a high-risk Azure Virtual Machine extension by an interactive user principal. Attackers with privileged Azure RBAC roles can abuse VM extensions such as VMAccess, CustomScriptExtension, and RunCommand to execute arbitrary code, create backdoor accounts, harvest credentials, and establish persistence on Azure-hosted virtual machines without requiring direct network access to the VM.

Known False Positives

  • Legitimate administrators and automation may deploy Custom Script, Run Command, DSC, or monitoring extensions during provisioning, patching, or guest configuration. Baseline expected principals, VMs, and extension types before tuning exclusions.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2026/05/20"
integration = ["azure"]
maturity = "production"
updated_date = "2026/05/20"

[rule]
author = ["Elastic"]
description = """
Identifies the successful deployment of a high-risk Azure Virtual Machine extension by an interactive user principal.
Attackers with privileged Azure RBAC roles can abuse VM extensions such as VMAccess, CustomScriptExtension, and
RunCommand to execute arbitrary code, create backdoor accounts, harvest credentials, and establish persistence on
Azure-hosted virtual machines without requiring direct network access to the VM.
"""
false_positives = [
    """
    Legitimate administrators and automation may deploy Custom Script, Run Command, DSC, or monitoring extensions during
    provisioning, patching, or guest configuration. Baseline expected principals, VMs, and extension types before
    tuning exclusions.
    """,
]
from = "now-9m"
index = ["logs-azure.activitylogs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Azure VM Extension Deployment by User"
note = """## Triage and analysis

### Investigating Azure VM Extension Deployment by User

This rule flags successful `MICROSOFT.COMPUTE/VIRTUALMACHINES/EXTENSIONS/WRITE` operations performed by a user principal
where the extension resource ID matches high-risk extension families (VMAccess, Custom Script, Run Command, DSC,
Microsoft Monitoring Agent).

### Triage checklist

- Is the caller UPN a known admin or automation account?
- Is the source IP or ASN consistent with corporate infrastructure or a known VPN?
- Was this extension deployment preceded by a Run Command invocation on the same VM?
- Did the extension deployment coincide with new local account creation on the endpoint?
- Check `azure.activitylogs.identity.claims.authnmethodsreferences` — was MFA present?
- Correlate with endpoint telemetry: process events parented by `WaAppAgent.exe` or `walinuxagent` within 120 seconds of
  the extension write timestamp on the same host.

### Possible investigation steps

- Review `azure.activitylogs.identity.authorization.evidence.principal_id` and Entra sign-in logs for the caller.
- Examine `azure.resource.id` and `azure.resource.name` to identify the VM and extension type deployed.
- Pivot on the VM for `MICROSOFT.COMPUTE/VIRTUALMACHINES/RUNCOMMAND/ACTION` and endpoint Run Command or `waagent` activity.
- Review role assignments for the principal on the subscription or resource group.

### Response and remediation

- If unauthorized, remove the extension, rotate credentials, and review RBAC on the affected VM and scope.
- Isolate the VM and collect endpoint and activity log artifacts per incident procedures.
"""
references = ["https://docs.microsoft.com/en-us/azure/virtual-machines/extensions/overview"]
risk_score = 47
rule_id = "e842d39d-ead1-48c6-97f1-6b055476c2f3"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Domain: Endpoint",
    "Data Source: Azure",
    "Data Source: Azure Activity Logs",
    "Use Case: Threat Detection",
    "Tactic: Persistence",
    "Tactic: Defense Evasion",
    "Tactic: Execution",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:azure.activitylogs and
azure.activitylogs.operation_name:"MICROSOFT.COMPUTE/VIRTUALMACHINES/EXTENSIONS/WRITE" and
azure.activitylogs.identity.authorization.evidence.principal_type:User and
event.outcome:(success or Success) and
azure.resource.id:(
    *VMACCESSAGENT* or
    *CUSTOMSCRIPTEXTENSION* or
    *RUNCOMMANDWINDOWS* or
    *RUNCOMMANDLINUX* or
    */DSC/* or
    *MICROSOFTMONITORINGAGENT*
)
'''

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "event.outcome",
    "azure.activitylogs.operation_name",
    "azure.activitylogs.identity.authorization.evidence.principal_id",
    "azure.activitylogs.identity.authorization.evidence.principal_type",
    "azure.activitylogs.identity.claims_initiated_by_user.name",
    "azure.resource.id",
    "azure.resource.name",
    "source.ip",
    "source.geo.country_name",
    "source.as.organization.name",
    "azure.subscription_id",
    "azure.activitylogs.tenant_id",
]

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

[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"

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

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

[[rule.threat.technique]]
id = "T1651"
name = "Cloud Administration Command"
reference = "https://attack.mitre.org/techniques/T1651/"

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

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

[[rule.threat.technique]]
id = "T1578"
name = "Modify Cloud Compute Infrastructure"
reference = "https://attack.mitre.org/techniques/T1578/"

[[rule.threat.technique.subtechnique]]
id = "T1578.002"
name = "Create Cloud Instance"
reference = "https://attack.mitre.org/techniques/T1578/002/"

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

Stages and Predicates

Stage 1: query

data_stream.dataset:azure.activitylogs and
azure.activitylogs.operation_name:"MICROSOFT.COMPUTE/VIRTUALMACHINES/EXTENSIONS/WRITE" and
azure.activitylogs.identity.authorization.evidence.principal_type:User and
event.outcome:(success or Success) and
azure.resource.id:(
    *VMACCESSAGENT* or
    *CUSTOMSCRIPTEXTENSION* or
    *RUNCOMMANDWINDOWS* or
    *RUNCOMMANDLINUX* or
    */DSC/* or
    *MICROSOFTMONITORINGAGENT*
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
azure.activitylogs.identity.authorization.evidence.principal_typeeq
  • User corpus 2 (elastic 2)
field:"azure.activitylogs.identity.authorization.evidence.principal_type" kind:eq value:"User"
azure.activitylogs.operation_nameeq
  • MICROSOFT.COMPUTE/VIRTUALMACHINES/EXTENSIONS/WRITE
field:"azure.activitylogs.operation_name" kind:eq value:"MICROSOFT.COMPUTE/VIRTUALMACHINES/EXTENSIONS/WRITE"
azure.resource.idwildcard
  • */DSC/*
  • *CUSTOMSCRIPTEXTENSION*
  • *MICROSOFTMONITORINGAGENT*
  • *RUNCOMMANDLINUX*
  • *RUNCOMMANDWINDOWS*
  • *VMACCESSAGENT*
field:"azure.resource.id" kind:wildcard
data_stream.dataseteq
  • azure.activitylogs corpus 38 (elastic 38)
field:"data_stream.dataset" kind:eq value:"azure.activitylogs"
event.outcomein
  • Success corpus 306 (elastic 306)
  • success corpus 306 (elastic 306)
field:"event.outcome" kind:in

Dscl Execution via Osascript

#
Source
github.com/elastic/protections-artifacts

Detects the execution of the Dscl binary via Osascript in order to collect user information. The AMOS malware utilizes this technique in its AppleScripts in order to determine the current user.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[rule]
description = """
Detects the execution of the Dscl binary via Osascript in order to collect user information. The AMOS malware utilizes
this technique in its AppleScripts in order to determine the current user.
"""
id = "7a7b94ce-be0f-4e2b-8af8-606199b5256e"
license = "Elastic License v2"
name = "Dscl Execution via Osascript"
os_list = ["macos"]
version = "1.0.3"

query = '''
process where event.type == "start" and event.action == "exec" and process.name == "dscl" and process.parent.name == "osascript"
'''

min_endpoint_version = "8.7.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.002"
name = "AppleScript"
reference = "https://attack.mitre.org/techniques/T1059/002/"



[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1033"
name = "System Owner/User Discovery"
reference = "https://attack.mitre.org/techniques/T1033/"


[threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"

[internal]
min_endpoint_version = "8.7.0"

Stages and Predicates

Stage 1: process

process where event.type == "start" and event.action == "exec" and process.name == "dscl" and process.parent.name == "osascript"

Indicators

These rows show field, operator, and value matches.

Execution from Suspicious Directory

#
Time window
1m
Sequence by
process.entity_id
Source
github.com/elastic/protections-artifacts

Identifies process execution from directories that are often abused by malware such as roaming, public and programdata folders followed by a DNS lookup request.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies process execution from directories that are often abused by malware such as roaming, public and programdata
folders followed by a DNS lookup request.
"""
id = "9ba39516-651e-489f-8b6a-f5501e0c492d"
license = "Elastic License v2"
name = "Execution from Suspicious Directory"
os_list = ["windows"]
version = "1.0.31"

query = '''
sequence by process.entity_id with maxspan=1m
 [process where event.action == "start" and
  process.Ext.relative_file_name_modify_time < 500 and
  (
   process.executable :
         ("?:\\Users\\Public\\*",
          "?:\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\*",
          "?:\\Windows\\System32\\Tasks\\*",
          "?:\\Windows\\Tasks\\*",
          "?:\\PerfLogs\\*",
          "?:\\Windows\\Logs\\*",
          "?:\\windows\\Help\\*",
          "?:\\Windows\\INF\\*",
          "?:\\$Recycle.Bin\\*",
          "?:\\Windows\\System32\\spool\\drivers\\color\\*",
          "?:\\aaAntiRansomElastic-DO-NOT-TOUCH-*") or

   (process.executable : "?:\\Users\\*\\AppData\\Roaming\\*" and not process.executable : "?:\\Users\\*\\AppData\\Roaming\\*\\*") or

   (process.executable : "?:\\Users\\*\\AppData\\Local\\Temp\\RarSFX*" and process.code_signature.exists == false) or

   /* process name minus extension composed of numbers only */
   (process.executable : ("?:\\Users\\*\\AppData\\*", "?:\\Windows\\Temp\\*", "?:\\ProgramData\\*") and process.name regex~ """[0-9\.]+\.(exe|pif)""") or 

   (process.executable : "?:\\ProgramData\\*" and not process.executable : "?:\\ProgramData\\*\\*")
   ) and

   not process.executable :
              ("?:\\Users\\Public\\CSC\\WIC\\bin\\*.exe",
               "?:\\Users\\Public\\IBM\\ClientSolutions\\Start_Programs\\*.exe") and

   /* excluding code_sign trusted, can get noisy in certain env */
   not (process.executable : "?:\\Users\\*\\AppData\\Roaming\\*" and (process.code_signature.trusted == true or process.code_signature.status : ("errorExpired"))) and

   not process.hash.sha256 :
              ("4fbcc89b12101ed24053fec6a87b13bfdd48db0ff99a2d50d7a22e34fbd08374",
               "e967350e6ef2cfae1108e5b5c4357527d7046ad39d269b038d58f4e2f27534c9",
               "5d93774785807f0ad3890d6fa283ff78f3f98a980c8c3fc7e6bed6fa7fb8fd38",
               "997f113af57788b31020247bfda16cf204a0604aac9147aebf5d9ee49a50a522",
               "0c7a6fd57afcb8903e4d1b24fdcacd4777657a1cd7a49f418e17f055bf8def42",
               "8423445ee2bd12f9c450252b2b178f6065218328dffa43e6f6ef08482cd19251",
               "4337adaa6b26ea9ad6d7bd0871d49531442ba3d8a24aecc1a5a0f26378de4f78",
               "f97caae8172e3204538e855ee9a32f04fc41be0d67ff7e54c0c903e6dc1dbc26",
               "849b4a0d01c53a4c5f9d3eef9bc5ad2f2ffa6613b763b257a7f654596a5bbc33",
               "e0fb6d51e3a8de0e8db04d0e91517cc46f4d83a55c986b313fb333dc9e5bce83",
               "422aa4268713b6c99581365985d403a62f6ccd9f0b5a23f9d963d1947dc77aee",
               "c6a75b46eee11a5bb11f5f970b51464a34c6e007583e73f717dbfc74edb84300",
               "1333bac5283998a18f761816f0fd09028e50e89d7085f39338b57a01549e5015",
               "16a7047b0ad4873e36891c30a14bd567338be163239182d9f98647440e464320",
               "085093d8bd967ef291519b31df65a8a80dd1fc9a1d4d93140b6d3bbd34b95dd2") and

   not (process.code_signature.subject_name :
                               ("Daybreak Game Company LLC", "Prusa Research a.s.", "RHUB Communications, Inc.",
                                "Bedford, Freeman & Worth Publishing Group, LLC", "RICOH COMPANY,LTD.",
                                "NortonLifeLock Inc.") and process.code_signature.trusted == true)]
 [dns where
   dns.question.name : "*.*" and
   process.executable :
         ("?:\\Users\\Public\\*",
          "?:\\Users\\*\\AppData\\Roaming\\*",
          "?:\\Windows\\System32\\Tasks\\*",
          "?:\\Windows\\Tasks\\*",
          "?:\\ProgramData\\*",
          "?:\\PerfLogs\\*",
          "?:\\Windows\\Logs\\*",
          "?:\\windows\\Help\\*",
          "?:\\Windows\\INF\\*",
          "?:\\aaAntiRansomElastic-DO-NOT-TOUCH-*") and

   not dns.question.name :
              ("*.in-addr.arpa.",
               "www.google-analytics.com",
               "fonts.googleapis.com",
               "update.googleapis.com",
               "www.google.com",
               "ocsp.*.com",
               "ocsp.*.net",
               "dl.dell.com",
               "*.symcd.com",
               "www.hpsmart.com",
               "*.liquidnet.biz",
               "stats.norton.com",
               "ctldl.windowsupdate.com",
               "datapipeline.logitech.io")]
'''

min_endpoint_version = "8.10.0"
reputation = true
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1204"
name = "User Execution"
reference = "https://attack.mitre.org/techniques/T1204/"
[[threat.technique.subtechnique]]
id = "T1204.002"
name = "Malicious File"
reference = "https://attack.mitre.org/techniques/T1204/002/"



[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1036"
name = "Masquerading"
reference = "https://attack.mitre.org/techniques/T1036/"


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

[internal]
min_endpoint_version = "8.10.0"

Stages and Predicates

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

Stage 1: process

[process where event.action == "start" and
  process.Ext.relative_file_name_modify_time < 500 and
  (
   process.executable :
         ("?:\\Users\\Public\\*",
          "?:\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\*",
          "?:\\Windows\\System32\\Tasks\\*",
          "?:\\Windows\\Tasks\\*",
          "?:\\PerfLogs\\*",
          "?:\\Windows\\Logs\\*",
          "?:\\windows\\Help\\*",
          "?:\\Windows\\INF\\*",
          "?:\\$Recycle.Bin\\*",
          "?:\\Windows\\System32\\spool\\drivers\\color\\*",
          "?:\\aaAntiRansomElastic-DO-NOT-TOUCH-*") or
   (process.executable : "?:\\Users\\*\\AppData\\Roaming\\*" and not process.executable : "?:\\Users\\*\\AppData\\Roaming\\*\\*") or
   (process.executable : "?:\\Users\\*\\AppData\\Local\\Temp\\RarSFX*" and process.code_signature.exists == false) or
   (process.executable : ("?:\\Users\\*\\AppData\\*", "?:\\Windows\\Temp\\*", "?:\\ProgramData\\*") and process.name regex~ """[0-9\.]+\.(exe|pif)""") or
   (process.executable : "?:\\ProgramData\\*" and not process.executable : "?:\\ProgramData\\*\\*")
   ) and
   not process.executable :
              ("?:\\Users\\Public\\CSC\\WIC\\bin\\*.exe",
               "?:\\Users\\Public\\IBM\\ClientSolutions\\Start_Programs\\*.exe") and
   not (process.executable : "?:\\Users\\*\\AppData\\Roaming\\*" and (process.code_signature.trusted == true or process.code_signature.status : ("errorExpired"))) and
   not process.hash.sha256 :
              ("4fbcc89b12101ed24053fec6a87b13bfdd48db0ff99a2d50d7a22e34fbd08374",
               "e967350e6ef2cfae1108e5b5c4357527d7046ad39d269b038d58f4e2f27534c9",
               "5d93774785807f0ad3890d6fa283ff78f3f98a980c8c3fc7e6bed6fa7fb8fd38",
               "997f113af57788b31020247bfda16cf204a0604aac9147aebf5d9ee49a50a522",
               "0c7a6fd57afcb8903e4d1b24fdcacd4777657a1cd7a49f418e17f055bf8def42",
               "8423445ee2bd12f9c450252b2b178f6065218328dffa43e6f6ef08482cd19251",
               "4337adaa6b26ea9ad6d7bd0871d49531442ba3d8a24aecc1a5a0f26378de4f78",
               "f97caae8172e3204538e855ee9a32f04fc41be0d67ff7e54c0c903e6dc1dbc26",
               "849b4a0d01c53a4c5f9d3eef9bc5ad2f2ffa6613b763b257a7f654596a5bbc33",
               "e0fb6d51e3a8de0e8db04d0e91517cc46f4d83a55c986b313fb333dc9e5bce83",
               "422aa4268713b6c99581365985d403a62f6ccd9f0b5a23f9d963d1947dc77aee",
               "c6a75b46eee11a5bb11f5f970b51464a34c6e007583e73f717dbfc74edb84300",
               "1333bac5283998a18f761816f0fd09028e50e89d7085f39338b57a01549e5015",
               "16a7047b0ad4873e36891c30a14bd567338be163239182d9f98647440e464320",
               "085093d8bd967ef291519b31df65a8a80dd1fc9a1d4d93140b6d3bbd34b95dd2") and
   not (process.code_signature.subject_name :
                               ("Daybreak Game Company LLC", "Prusa Research a.s.", "RHUB Communications, Inc.",
                                "Bedford, Freeman & Worth Publishing Group, LLC", "RICOH COMPANY,LTD.",
                                "NortonLifeLock Inc.") and process.code_signature.trusted == true)]

Stage 2: dns

[dns where
   dns.question.name : "*.*" and
   process.executable :
         ("?:\\Users\\Public\\*",
          "?:\\Users\\*\\AppData\\Roaming\\*",
          "?:\\Windows\\System32\\Tasks\\*",
          "?:\\Windows\\Tasks\\*",
          "?:\\ProgramData\\*",
          "?:\\PerfLogs\\*",
          "?:\\Windows\\Logs\\*",
          "?:\\windows\\Help\\*",
          "?:\\Windows\\INF\\*",
          "?:\\aaAntiRansomElastic-DO-NOT-TOUCH-*") and

   not dns.question.name :
              ("*.in-addr.arpa.",
               "www.google-analytics.com",
               "fonts.googleapis.com",
               "update.googleapis.com",
               "www.google.com",
               "ocsp.*.com",
               "ocsp.*.net",
               "dl.dell.com",
               "*.symcd.com",
               "www.hpsmart.com",
               "*.liquidnet.biz",
               "stats.norton.com",
               "ctldl.windowsupdate.com",
               "datapipeline.logitech.io")]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
dns.question.namewildcard
  • *.* corpus 6 (elastic 3, kusto 2, splunk 1)
field:"QueryName" kind:wildcard value:"*.*"
event.actioneq
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq value:"start"
process.Ext.relative_file_name_modify_timelt
  • 500 transforms: number
field:"process.Ext.relative_file_name_modify_time" kind:lt value:"500"
process.code_signature.existseq
  • false transforms: boolean corpus 118 (elastic 118)
field:"process.code_signature.exists" kind:eq value:"false"
process.executablewildcard
  • ?:\$Recycle.Bin\*
  • ?:\PerfLogs\*
  • ?:\ProgramData\* corpus 18 (elastic 18)
  • ?:\ProgramData\* corpus 17 (elastic 17)
  • ?:\Users\*\AppData\* corpus 12 (elastic 12)
  • ?:\Users\*\AppData\Local\Temp\RarSFX* corpus 2 (elastic 2)
  • ?:\Users\*\AppData\Roaming\* corpus 5 (elastic 5)
  • ?:\Users\*\AppData\Roaming\Microsoft\Windows\*
  • ?:\Users\Public\* corpus 22 (elastic 22)
  • ?:\Windows\INF\*
  • ?:\Windows\Logs\*
  • ?:\Windows\System32\Tasks\* corpus 3 (elastic 3)
  • ?:\Windows\System32\spool\drivers\color\*
  • ?:\Windows\Tasks\* corpus 7 (elastic 7)
  • ?:\Windows\Temp\* corpus 7 (elastic 7)
  • ?:\aaAntiRansomElastic-DO-NOT-TOUCH-*
  • ?:\windows\Help\*
field:"Image" kind:wildcard
process.nameregex_match
  • [0-9.]+.(exe|pif)
field:"process_basename" kind:regex_match value:"[0-9.]+.(exe|pif)"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.code_signature.statuseqerrorExpiredexcludes:process.code_signature.status field:"process.code_signature.status" value:"errorExpired"
process.code_signature.trustedeqtrueexcludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true"
process.executablewildcard?:\Users\*\AppData\Roaming\*excludes:process.executable field:"process.executable" value:"?:\Users\*\AppData\Roaming\*"
process.code_signature.subject_nameeqDaybreak Game Company LLC, Prusa Research a.s., RHUB Communications, Inc., Bedford, Freeman & Worth Publishing Group, LLC, RICOH COMPANY,LTD., NortonLifeLock Inc.excludes:process.code_signature.subject_name
process.executablewildcard?:\Users\Public\CSC\WIC\bin\*.exe, ?:\Users\Public\IBM\ClientSolutions\Start_Programs\*.exeexcludes:process.executable field:"process.executable" value:"?:\Users\Public\CSC\WIC\bin\*.exe" field:"process.executable" value:"?:\Users\Public\IBM\ClientSolutions\Start_Programs\*.exe"
process.hash.sha256eq4fbcc89b12101ed24053fec6a87b13bfdd48db0ff99a2d50d7a22e34fbd08374, e967350e6ef2cfae1108e5b5c4357527d7046ad39d269b038d58f4e2f27534c9, 5d93774785807f0ad3890d6fa283ff78f3f98a980c8c3fc7e6bed6fa7fb8fd38, 997f113af57788b31020247bfda16cf204a0604aac9147aebf5d9ee49a50a522, 0c7a6fd57afcb8903e4d1b24fdcacd4777657a1cd7a49f418e17f055bf8def42, 8423445ee2bd12f9c450252b2b178f6065218328dffa43e6f6ef08482cd19251, 4337adaa6b26ea9ad6d7bd0871d49531442ba3d8a24aecc1a5a0f26378de4f78, f97caae8172e3204538e855ee9a32f04fc41be0d67ff7e54c0c903e6dc1dbc26, 849b4a0d01c53a4c5f9d3eef9bc5ad2f2ffa6613b763b257a7f654596a5bbc33, e0fb6d51e3a8de0e8db04d0e91517cc46f4d83a55c986b313fb333dc9e5bce83, 422aa4268713b6c99581365985d403a62f6ccd9f0b5a23f9d963d1947dc77aee, c6a75b46eee11a5bb11f5f970b51464a34c6e007583e73f717dbfc74edb84300, 1333bac5283998a18f761816f0fd09028e50e89d7085f39338b57a01549e5015, 16a7047b0ad4873e36891c30a14bd567338be163239182d9f98647440e464320, 085093d8bd967ef291519b31df65a8a80dd1fc9a1d4d93140b6d3bbd34b95dd2excludes:process.hash.sha256
dns.question.namewildcard*.in-addr.arpa., www.google-analytics.com, fonts.googleapis.com, update.googleapis.com, www.google.com, ocsp.*.com, ocsp.*.net, dl.dell.com, *.symcd.com, www.hpsmart.com, *.liquidnet.biz, stats.norton.com, ctldl.windowsupdate.com, datapipeline.logitech.ioexcludes:dns.question.name

Execution of a Windows Script File Written by a Suspicious Process

#
Time window
5m
Sequence by
user.id
Source
github.com/elastic/protections-artifacts

Identifies the execution of a script file written by a suspicious application. Script interpreters are often launched during exploitation of Office applications or from documents containing malicious macros.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the execution of a script file written by a suspicious application. Script interpreters are often launched
during exploitation of Office applications or from documents containing malicious macros.
"""
id = "dc9c8c7c-f398-401f-804a-325570a5f167"
license = "Elastic License v2"
name = "Execution of a Windows Script File Written by a Suspicious Process"
os_list = ["windows"]
version = "1.0.34"

query = '''
sequence by user.id with maxspan=5m

 [file where event.action == "creation" and file.path : "C:\\*" and

   file.extension : ("hta", "vbs", "js", "wsf", "vbe", "jse") and not user.id : "S-1-5-18" and

   not (process.code_signature.subject_name :
            ("AUTO/MATE, INC.", "TeamViewer*", "KOBIL Systems GmbH", "Ratiborus MSFree Inc.",
             "Canon Electronics Inc.", "Johannes Schindelin", "Bomgar Corporation", "PFU LIMITED",
             "Learnpulse", "Azul Systems, Inc.") and
        process.code_signature.trusted == true) and
   not process.executable :
              ("?:\\ProgramData\\Microsoft\\VisualStudio\\Packages\\*.exe",
               "?:\\Program Files\\SWSetup\\SP100309\\Lexus FW Upgrade 0007.exe", 
               "?:\\Program Files (x86)\\Imprivata\\OneSign Agent\\x64\\ISXAgent.exe") and

   not (process.executable : "?:\\Users\\*\\AppData\\Roaming\\zozi-rpa-engine\\openjdk\\bin\\java.exe" and
        file.path : "C:\\Project\\*.vbs") and

   not file.path : "C:\\WINDOWS\\TEMP\\*.vbs" and

   not file.Ext.header_bytes :
                 ("0d0a272d2d2d2d2d2d2d2d2d2d2d2d2d", "272a2a2a2a2a2a2a2a2a2a2a2a2a2a2a",
                  "4966204e6f742049734f626a65637428", "4f6e204572726f7220526573756d6520",
                  "53657420554143203d20437265617465", "53006500740020006f0062006a004600",
                  "53006500740020005500410043002000", "4f4e204552524f5220524553554d4520",
                  "4372656174654f626a65637428225773") and

   (
     process.name : ("winword.exe", "excel.exe", "outlook.exe", "powerpnt.exe", "eqnedt32.exe", "fltldr.exe",
                     "mspub.exe", "msaccess.exe", "certutil.exe", "tar.exe", "CertReq.exe", "xcopy.exe", 
                     "cmd.exe", "powershell.exe", "mshta.exe", "curl.exe", "pwsh.exe", "rundll32.exe", 
                     "regsvr32.exe") or

     (process.code_signature.trusted == false or process.code_signature.exists == false) or

     process.executable : ("?:\\Users\\*\\AppData\\*", "?:\\ProgramData\\*", "?:\\Users\\Public\\*")
   )] as event0

 [process where event.action == "start" and
  process.name : ("wscript.exe", "mshta.exe") and
  startswith~(process.args, event0.file.path) and
  not (process.args : ("?:\\Program Files\\*", "?:\\Program Files (x86)\\*") and process.args_count <= 3) and
  not (process.name : "wscript.exe" and process.parent.name : "cmd.exe" and
       process.parent.command_line : ("*Desktop\\PROTECTAgentInstaller.bat*", "*cleanupSetup.vbs Shell_*.log*")) and
  not process.parent.executable :
                    ("?:\\Program Files (x86)\\Virus Chaser\\pcms\\patch\\_incomming_files\\KDB_Trellix_Agent_BG.sfx.exe",
                     "?:\\Program Files (x86)\\UPS\\CrossWare\\CrossWare.exe",
                     "?:\\Program Files\\UPS\\CrossWare\\CrossWare.exe",
                     "?:\\Program Files (x86)\\Common Files\\InstallShield\\Driver\\8\\Intel 32\\IDriver.exe") and
  not (process.parent.args : "-no_selfdeleter" and process.parent.args : "-IS_temp") and
  not (process.parent.args : "-removeonly" and process.parent.args : "-runfromtemp") and
  not (process.name : "wscript.exe" and process.parent.name : "cmd.exe" and
       process.parent.args : ("?:\\PROGRA~2\\Baxter\\*\\REGIST~1.BAT", "PrepStation\\registerCameraStand.bat", "?:\\Program Files (x86)\\Baxter\\*")) and
  not (process.parent.args : "http*://*:8282/dataloader/*" and process.args : "?:\\Windows\\TEMP\\Spiceworks\\spiceworks_upload.vbs") and
  not (process.parent.args : "C:\\XperCon\\_Xtra\\PDF_Rename\\pdf_rename.bat" and process.args : "C:\\XperCon\\_Xtra\\PDF_Rename\\transform.vbs") and
  not (process.parent.args : "C:\\CSM Infopath Templates\\Register CSM InfoPath Templates.exe" and process.args : "C:\\CSM Infopath Templates\\installAllTemplates.vbs") and
  not (process.parent.name : "cmd.exe" and process.parent.args : "%TEMP%\\Spiceworks\\*") and
  not (process.name : "mshta.exe" and process.parent.name : "mshta.exe"  and process.parent.args : "\\\\*\\netlogon\\ADSelfService_Enroll.hta") and
  not (process.parent.name : "JustWareSmartClient.exe" and process.executable : "C:\\Windows\\SysWOW64\\wscript.exe") and

  /* FP - contentACCESS (TECH-ARROW) Outlook email archiving add-in */
  not process.args : "?:\\Users\\*\\AppData\\Local\\Temp\\contentACCESSForm\\RunAction.vbs" and

  /* FP - domain login scripts dropping uacinstall.vbs via netlogon */
  not (process.parent.name : "cmd.exe" and process.parent.args : "\\\\*\\netlogon\\*" and
       process.args : "*\\uacinstall.vbs")
  ]
'''

min_endpoint_version = "8.4.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"

[[threat.technique.subtechnique]]
id = "T1059.005"
name = "Visual Basic"
reference = "https://attack.mitre.org/techniques/T1059/005/"

[[threat.technique.subtechnique]]
id = "T1059.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"



[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"
[[threat.technique.subtechnique]]
id = "T1218.005"
name = "Mshta"
reference = "https://attack.mitre.org/techniques/T1218/005/"



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

[internal]
min_endpoint_version = "8.4.0"

Stages and Predicates

Ordered sequence: each step below must occur in order within 5m, correlated by user.id.

Stage 1: file

[file where event.action == "creation" and file.path : "C:\\*" and

   file.extension : ("hta", "vbs", "js", "wsf", "vbe", "jse") and not user.id : "S-1-5-18" and

   not (process.code_signature.subject_name :
            ("AUTO/MATE, INC.", "TeamViewer*", "KOBIL Systems GmbH", "Ratiborus MSFree Inc.",
             "Canon Electronics Inc.", "Johannes Schindelin", "Bomgar Corporation", "PFU LIMITED",
             "Learnpulse", "Azul Systems, Inc.") and
        process.code_signature.trusted == true) and
   not process.executable :
              ("?:\\ProgramData\\Microsoft\\VisualStudio\\Packages\\*.exe",
               "?:\\Program Files\\SWSetup\\SP100309\\Lexus FW Upgrade 0007.exe", 
               "?:\\Program Files (x86)\\Imprivata\\OneSign Agent\\x64\\ISXAgent.exe") and

   not (process.executable : "?:\\Users\\*\\AppData\\Roaming\\zozi-rpa-engine\\openjdk\\bin\\java.exe" and
        file.path : "C:\\Project\\*.vbs") and

   not file.path : "C:\\WINDOWS\\TEMP\\*.vbs" and

   not file.Ext.header_bytes :
                 ("0d0a272d2d2d2d2d2d2d2d2d2d2d2d2d", "272a2a2a2a2a2a2a2a2a2a2a2a2a2a2a",
                  "4966204e6f742049734f626a65637428", "4f6e204572726f7220526573756d6520",
                  "53657420554143203d20437265617465", "53006500740020006f0062006a004600",
                  "53006500740020005500410043002000", "4f4e204552524f5220524553554d4520",
                  "4372656174654f626a65637428225773") and

   (
     process.name : ("winword.exe", "excel.exe", "outlook.exe", "powerpnt.exe", "eqnedt32.exe", "fltldr.exe",
                     "mspub.exe", "msaccess.exe", "certutil.exe", "tar.exe", "CertReq.exe", "xcopy.exe", 
                     "cmd.exe", "powershell.exe", "mshta.exe", "curl.exe", "pwsh.exe", "rundll32.exe", 
                     "regsvr32.exe") or

     (process.code_signature.trusted == false or process.code_signature.exists == false) or

     process.executable : ("?:\\Users\\*\\AppData\\*", "?:\\ProgramData\\*", "?:\\Users\\Public\\*")
   )] as event0

Stage 2: process

[process where event.action == "start" and
  process.name : ("wscript.exe", "mshta.exe") and
  startswith~(process.args, event0.file.path) and
  not (process.args : ("?:\\Program Files\\*", "?:\\Program Files (x86)\\*") and process.args_count <= 3) and
  not (process.name : "wscript.exe" and process.parent.name : "cmd.exe" and
       process.parent.command_line : ("*Desktop\\PROTECTAgentInstaller.bat*", "*cleanupSetup.vbs Shell_*.log*")) and
  not process.parent.executable :
                    ("?:\\Program Files (x86)\\Virus Chaser\\pcms\\patch\\_incomming_files\\KDB_Trellix_Agent_BG.sfx.exe",
                     "?:\\Program Files (x86)\\UPS\\CrossWare\\CrossWare.exe",
                     "?:\\Program Files\\UPS\\CrossWare\\CrossWare.exe",
                     "?:\\Program Files (x86)\\Common Files\\InstallShield\\Driver\\8\\Intel 32\\IDriver.exe") and
  not (process.parent.args : "-no_selfdeleter" and process.parent.args : "-IS_temp") and
  not (process.parent.args : "-removeonly" and process.parent.args : "-runfromtemp") and
  not (process.name : "wscript.exe" and process.parent.name : "cmd.exe" and
       process.parent.args : ("?:\\PROGRA~2\\Baxter\\*\\REGIST~1.BAT", "PrepStation\\registerCameraStand.bat", "?:\\Program Files (x86)\\Baxter\\*")) and
  not (process.parent.args : "http*://*:8282/dataloader/*" and process.args : "?:\\Windows\\TEMP\\Spiceworks\\spiceworks_upload.vbs") and
  not (process.parent.args : "C:\\XperCon\\_Xtra\\PDF_Rename\\pdf_rename.bat" and process.args : "C:\\XperCon\\_Xtra\\PDF_Rename\\transform.vbs") and
  not (process.parent.args : "C:\\CSM Infopath Templates\\Register CSM InfoPath Templates.exe" and process.args : "C:\\CSM Infopath Templates\\installAllTemplates.vbs") and
  not (process.parent.name : "cmd.exe" and process.parent.args : "%TEMP%\\Spiceworks\\*") and
  not (process.name : "mshta.exe" and process.parent.name : "mshta.exe"  and process.parent.args : "\\\\*\\netlogon\\ADSelfService_Enroll.hta") and
  not (process.parent.name : "JustWareSmartClient.exe" and process.executable : "C:\\Windows\\SysWOW64\\wscript.exe") and
  not process.args : "?:\\Users\\*\\AppData\\Local\\Temp\\contentACCESSForm\\RunAction.vbs" and
  not (process.parent.name : "cmd.exe" and process.parent.args : "\\\\*\\netlogon\\*" and
       process.args : "*\\uacinstall.vbs")
  ]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • creation corpus 50 (elastic 50)
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq
file.extensionwildcard
  • hta corpus 20 (elastic 20)
  • js corpus 22 (elastic 22)
  • jse corpus 18 (elastic 18)
  • vbe corpus 18 (elastic 18)
  • vbs corpus 19 (elastic 19)
  • wsf corpus 10 (elastic 10)
field:"file.extension" kind:wildcard
file.pathwildcard
  • C:\* corpus 2 (elastic 2)
field:"TargetFilename" kind:wildcard value:"C:\*"
process.argsstarts_with
  • event0.file.path (field reference)
field:"process.args" kind:starts_with value:"event0.file.path"
process.code_signature.existseq
  • false transforms: boolean corpus 118 (elastic 118)
field:"process.code_signature.exists" kind:eq value:"false"
process.code_signature.trustedeq
  • false transforms: boolean corpus 114 (elastic 114)
field:"process.code_signature.trusted" kind:eq value:"false"
process.executablewildcard
  • ?:\ProgramData\* corpus 18 (elastic 18)
  • ?:\Users\*\AppData\* corpus 12 (elastic 12)
  • ?:\Users\Public\* corpus 22 (elastic 22)
field:"Image" kind:wildcard
process.namewildcard
  • CertReq.exe corpus 20 (elastic 20)
  • certutil.exe corpus 45 (elastic 39, splunk 6)
  • cmd.exe corpus 122 (elastic 93, splunk 29)
  • curl.exe corpus 34 (elastic 32, splunk 2)
  • eqnedt32.exe corpus 8 (elastic 8)
  • excel.exe corpus 34 (elastic 34)
  • fltldr.exe corpus 8 (elastic 8)
  • msaccess.exe corpus 19 (elastic 19)
  • mshta.exe corpus 84 (elastic 80, splunk 4)
  • mspub.exe corpus 15 (elastic 15)
  • outlook.exe corpus 9 (elastic 7, splunk 2)
  • powerpnt.exe corpus 31 (elastic 31)
  • powershell.exe corpus 187 (elastic 140, splunk 44, kusto 3)
  • pwsh.exe corpus 78 (elastic 49, splunk 29)
  • regsvr32.exe corpus 74 (elastic 69, splunk 5)
  • rundll32.exe corpus 123 (elastic 100, splunk 23)
  • tar.exe corpus 6 (elastic 6)
  • winword.exe corpus 35 (elastic 35)
  • wscript.exe corpus 84 (elastic 82, splunk 1, kusto 1)
  • xcopy.exe corpus 10 (elastic 10)
field:"process_basename" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
file.pathwildcardC:\Project\*.vbsexcludes:file.path field:"file.path" value:"C:\Project\*.vbs"
process.executablewildcard?:\Users\*\AppData\Roaming\zozi-rpa-engine\openjdk\bin\java.exeexcludes:process.executable field:"process.executable" value:"?:\Users\*\AppData\Roaming\zozi-rpa-engine\openjdk\bin\java.exe"
process.code_signature.subject_namewildcardAUTO/MATE, INC., TeamViewer*, KOBIL Systems GmbH, Ratiborus MSFree Inc., Canon Electronics Inc., Johannes Schindelin, Bomgar Corporation, PFU LIMITED, Learnpulse, Azul Systems, Inc.excludes:process.code_signature.subject_name
process.code_signature.trustedeqtrueexcludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true"
file.Ext.header_byteseq0d0a272d2d2d2d2d2d2d2d2d2d2d2d2d, 272a2a2a2a2a2a2a2a2a2a2a2a2a2a2a, 4966204e6f742049734f626a65637428, 4f6e204572726f7220526573756d6520, 53657420554143203d20437265617465, 53006500740020006f0062006a004600, 53006500740020005500410043002000, 4f4e204552524f5220524553554d4520, 4372656174654f626a65637428225773excludes:file.Ext.header_bytes
file.pathwildcardC:\WINDOWS\TEMP\*.vbsexcludes:file.path field:"file.path" value:"C:\WINDOWS\TEMP\*.vbs"
process.executablewildcard?:\ProgramData\Microsoft\VisualStudio\Packages\*.exe, ?:\Program Files\SWSetup\SP100309\Lexus FW Upgrade 0007.exe, ?:\Program Files (x86)\Imprivata\OneSign Agent\x64\ISXAgent.exeexcludes:process.executable field:"process.executable" value:"?:\ProgramData\Microsoft\VisualStudio\Packages\*.exe" field:"process.executable" value:"?:\Program Files\SWSetup\SP100309\Lexus FW Upgrade 0007.exe" field:"process.executable" value:"?:\Program Files (x86)\Imprivata\OneSign Agent\x64\ISXAgent.exe"
user.ideqS-1-5-18excludes:user.id field:"user.id" value:"S-1-5-18"
process.argsends_with\uacinstall.vbsexcludes:process.args field:"process.args" value:"\uacinstall.vbs"
process.parent.argswildcard\\*\netlogon\*excludes:process.parent.args field:"process.parent.args" value:"\\*\netlogon\*"
process.parent.nameeqcmd.exeexcludes:process.parent.name field:"process.parent.name" value:"cmd.exe"
process.argseq?:\Windows\TEMP\Spiceworks\spiceworks_upload.vbsexcludes:process.args field:"process.args" value:"?:\Windows\TEMP\Spiceworks\spiceworks_upload.vbs"
process.parent.argswildcardhttp*://*:8282/dataloader/*excludes:process.parent.args field:"process.parent.args" value:"http*://*:8282/dataloader/*"
process.argseqC:\CSM Infopath Templates\installAllTemplates.vbsexcludes:process.args field:"process.args" value:"C:\CSM Infopath Templates\installAllTemplates.vbs"
process.parent.argseqC:\CSM Infopath Templates\Register CSM InfoPath Templates.exeexcludes:process.parent.args field:"process.parent.args" value:"C:\CSM Infopath Templates\Register CSM InfoPath Templates.exe"
process.argseqC:\XperCon\_Xtra\PDF_Rename\transform.vbsexcludes:process.args field:"process.args" value:"C:\XperCon\_Xtra\PDF_Rename\transform.vbs"
process.parent.argseqC:\XperCon\_Xtra\PDF_Rename\pdf_rename.batexcludes:process.parent.args field:"process.parent.args" value:"C:\XperCon\_Xtra\PDF_Rename\pdf_rename.bat"
process.argsstarts_with?:\Program Files\, ?:\Program Files (x86)\excludes:process.args field:"process.args" value:"?:\Program Files\" field:"process.args" value:"?:\Program Files (x86)\"
process.args_countle3excludes:process.args_count field:"process.args_count" value:"3"
process.executableeqC:\Windows\SysWOW64\wscript.exeexcludes:process.executable field:"process.executable" value:"C:\Windows\SysWOW64\wscript.exe"
process.parent.nameeqJustWareSmartClient.exeexcludes:process.parent.name field:"process.parent.name" value:"JustWareSmartClient.exe"
process.nameeqmshta.exeexcludes:process.name field:"process.name" value:"mshta.exe"
process.parent.argswildcard\\*\netlogon\ADSelfService_Enroll.htaexcludes:process.parent.args field:"process.parent.args" value:"\\*\netlogon\ADSelfService_Enroll.hta"
process.parent.nameeqmshta.exeexcludes:process.parent.name field:"process.parent.name" value:"mshta.exe"
process.nameeqwscript.exeexcludes:process.name field:"process.name" value:"wscript.exe"
process.parent.argswildcard?:\PROGRA~2\Baxter\*\REGIST~1.BAT, PrepStation\registerCameraStand.bat, ?:\Program Files (x86)\Baxter\*excludes:process.parent.args field:"process.parent.args" value:"?:\PROGRA~2\Baxter\*\REGIST~1.BAT" field:"process.parent.args" value:"PrepStation\registerCameraStand.bat" field:"process.parent.args" value:"?:\Program Files (x86)\Baxter\*"
process.parent.command_linewildcard*Desktop\PROTECTAgentInstaller.bat*, *cleanupSetup.vbs Shell_*.log*excludes:process.parent.command_line field:"process.parent.command_line" value:"*Desktop\PROTECTAgentInstaller.bat*" field:"process.parent.command_line" value:"*cleanupSetup.vbs Shell_*.log*"
process.parent.argseq-IS_tempexcludes:process.parent.args field:"process.parent.args" value:"-IS_temp"
process.parent.argseq-no_selfdeleterexcludes:process.parent.args field:"process.parent.args" value:"-no_selfdeleter"
process.parent.argseq-removeonlyexcludes:process.parent.args field:"process.parent.args" value:"-removeonly"
process.parent.argseq-runfromtempexcludes:process.parent.args field:"process.parent.args" value:"-runfromtemp"
process.parent.argsstarts_with%TEMP%\Spiceworks\excludes:process.parent.args field:"process.parent.args" value:"%TEMP%\Spiceworks\"
process.argswildcard?:\Users\*\AppData\Local\Temp\contentACCESSForm\RunAction.vbsexcludes:process.args field:"process.args" value:"?:\Users\*\AppData\Local\Temp\contentACCESSForm\RunAction.vbs"
process.parent.executableeq?:\Program Files (x86)\Virus Chaser\pcms\patch\_incomming_files\KDB_Trellix_Agent_BG.sfx.exe, ?:\Program Files (x86)\UPS\CrossWare\CrossWare.exe, ?:\Program Files\UPS\CrossWare\CrossWare.exe, ?:\Program Files (x86)\Common Files\InstallShield\Driver\8\Intel 32\IDriver.exeexcludes:process.parent.executable

File Creation or Modification via (Memory) File Descriptor

#
Source
github.com/elastic/protections-artifacts

This rule detects when a process creates a (memory) file descriptor and creates, or modifies, a file. This behavior may indicate the creation of a second stage payload, after the first fileless stage has executed.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
This rule detects when a process creates a (memory) file descriptor and creates, or modifies, a file. This behavior may
indicate the creation of a second stage payload, after the first fileless stage has executed.
"""
id = "8cc1c545-7cd2-42c0-964c-1e6731b26647"
license = "Elastic License v2"
name = "File Creation or Modification via (Memory) File Descriptor"
os_list = ["linux"]
reference = ["https://man7.org/linux/man-pages/man2/memfd_create.2.html"]
version = "1.0.3"

query = '''
file where event.type != "deletion" and (
  process.executable regex """/proc/(self|[0-9]{1,7})/fd/[0-9]{1,7}""" or
  process.executable like ("memfd:*", "?memfd:*")
) and
file.path like (
  "/tmp/*", "/var/tmp/*", "/dev/shm/*", "/run/user/*", "/var/run/user/*", "/boot/*",
  "/lost+found/*", "/var/mail/*", "/var/www/*", "/home/*/*", "/root/*"
) and
not (
  process.executable like ("?memfd:/sophos-subprocess-*-exec*", "memfd:/sophos-subprocess-*-exec*") or
  process.executable in (
    "memfd:spawn_worker_trampoline", "memfd:buildah-chroot-runtime", "memfd:lxc-attach",
    "memfd:teleport-sessionhelper", "memfd:buildah-chroot-exec"
  ) or
  (process.executable == "/memfd: (deleted)" and file.path like "/var/tmp/etilqs_*") or
  file.path like (
    "/tmp/tmp.*", "/tmp/syft-cataloger-*/*", "/home/*/.local/state/wireplumber/*",
    "/run/user/0/systemd/units/invocation:gpg-agent.socket", "/run/user/0/systemd/units/invocation:ssh-agent.socket"
  )
)
'''

min_endpoint_version = "9.1.4"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1106"
name = "Native API"
reference = "https://attack.mitre.org/techniques/T1106/"


[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"
[[threat.technique.subtechnique]]
id = "T1055.009"
name = "Proc Memory"
reference = "https://attack.mitre.org/techniques/T1055/009/"


[[threat.technique]]
id = "T1620"
name = "Reflective Code Loading"
reference = "https://attack.mitre.org/techniques/T1620/"


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

[internal]
min_endpoint_version = "9.1.4"

Stages and Predicates

Stage 1: file

file where event.type != "deletion" and (
  process.executable regex """/proc/(self|[0-9]{1,7})/fd/[0-9]{1,7}""" or
  process.executable like ("memfd:*", "?memfd:*")
) and
file.path like (
  "/tmp/*", "/var/tmp/*", "/dev/shm/*", "/run/user/*", "/var/run/user/*", "/boot/*",
  "/lost+found/*", "/var/mail/*", "/var/www/*", "/home/*/*", "/root/*"
) and
not (
  process.executable like ("?memfd:/sophos-subprocess-*-exec*", "memfd:/sophos-subprocess-*-exec*") or
  process.executable in (
    "memfd:spawn_worker_trampoline", "memfd:buildah-chroot-runtime", "memfd:lxc-attach",
    "memfd:teleport-sessionhelper", "memfd:buildah-chroot-exec"
  ) or
  (process.executable == "/memfd: (deleted)" and file.path like "/var/tmp/etilqs_*") or
  file.path like (
    "/tmp/tmp.*", "/tmp/syft-cataloger-*/*", "/home/*/.local/state/wireplumber/*",
    "/run/user/0/systemd/units/invocation:gpg-agent.socket", "/run/user/0/systemd/units/invocation:ssh-agent.socket"
  )
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.typene
  • deletion
field:"event.type" kind:ne value:"deletion"
file.pathwildcard
  • /boot/*
  • /dev/shm/*
  • /home/*/*
  • /lost+found/*
  • /root/*
  • /run/user/*
  • /tmp/*
  • /var/mail/*
  • /var/run/user/*
  • /var/tmp/*
  • /var/www/*
field:"TargetFilename" kind:wildcard
process.executableregex_match
  • /proc/(self|[0-9]{1,7})/fd/[0-9]{1,7}
field:"Image" kind:regex_match value:"/proc/(self|[0-9]{1,7})/fd/[0-9]{1,7}"
process.executablewildcard
  • ?memfd:*
  • memfd:*
field:"Image" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
file.pathstarts_with/var/tmp/etilqs_excludes:file.path field:"file.path" value:"/var/tmp/etilqs_"
process.executableeq/memfd: (deleted)excludes:process.executable field:"process.executable" value:"/memfd: (deleted)"
file.pathwildcard/tmp/tmp.*, /tmp/syft-cataloger-*/*, /home/*/.local/state/wireplumber/*, /run/user/0/systemd/units/invocation:gpg-agent.socket, /run/user/0/systemd/units/invocation:ssh-agent.socketexcludes:file.path
process.executableinmemfd:buildah-chroot-exec, memfd:buildah-chroot-runtime, memfd:lxc-attach, memfd:spawn_worker_trampoline, memfd:teleport-sessionhelperexcludes:process.executable
process.executablewildcard?memfd:/sophos-subprocess-*-exec*, memfd:/sophos-subprocess-*-exec*excludes:process.executable field:"process.executable" value:"?memfd:/sophos-subprocess-*-exec*" field:"process.executable" value:"memfd:/sophos-subprocess-*-exec*"

Full Disk Access Permission Check

#
Status
production
Severity
medium
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Detects suspicious access to the /Library/Preferences/com.apple.TimeMachine.plist file, indicating a potential attempt to verify or exploit Full Disk Access (FDA) permissions. This file is often checked by malware to confirm FDA privileges, which allow unrestricted access to sensitive user data.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2026/01/30"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
Detects suspicious access to the /Library/Preferences/com.apple.TimeMachine.plist file, indicating a potential 
attempt to verify or exploit Full Disk Access (FDA) permissions. This file is often checked by malware to 
confirm FDA privileges, which allow unrestricted access to sensitive user data.
"""
from = "now-9m"
index = ["logs-endpoint.events.file-*"]
language = "eql"
license = "Elastic License v2"
name = "Full Disk Access Permission Check"
note = """ ## Triage and analysis

> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

### Investigating Full Disk Access Permission Check

This rule detects suspicious reads of the Time Machine preferences plist that adversaries use as a quick litmus test for Full Disk Access, a permission that unlocks broad visibility into user and system data. Attackers commonly launch a scriptable or unsigned helper (for example via Python or AppleScript) to open this file, confirm FDA is present, then proceed to enumerate and collect protected artifacts like browser stores, messages, or backups.

### Possible investigation steps

- Validate the opening process lineage (parent/child chain, launch method, user session) to determine whether the access originated from an interactive admin action or an unexpected background helper.  
- Review the process code-signing identity (signer, notarization, team ID) and binary provenance (download attributes, install source, first-seen time) to distinguish legitimate tooling from potentially dropped or trojanized executables.  
- Pivot to other file and directory access by the same process around the alert time to identify follow-on discovery/collection of protected user data (e.g., browser profiles, keychain-related paths, Messages, Mail, backups).  
- Check recent and concurrent macOS privacy permission changes and TCC/FDA-related events for the user and process to see if FDA was newly granted, prompted, or bypassed preceding the access.  
- Correlate with network activity from the same process or host after the check (new outbound connections, uploads, DNS to uncommon domains) to assess whether the FDA verification preceded staging or exfiltration.

### False positive analysis

- An administrator or power user running an interactive shell (Terminal, bash/sh, python) executes a local audit or troubleshooting script that reads /Library/Preferences/com.apple.TimeMachine.plist to confirm Time Machine configuration and permissions.  
- A developer or IT engineer uses a scripting runtime (osascript, node, ruby, perl, python) during endpoint diagnostics to check whether the current session/app context has Full Disk Access by attempting to open the Time Machine preference plist.

### Response and remediation

- Isolate the Mac from the network or apply host firewall blocks if the plist access comes from an unexpected/unsigned process or occurs outside an active user session to prevent follow-on collection and exfiltration.  
- Terminate the offending process and remove its persistence (LaunchAgents/LaunchDaemons, cron, login items) and any newly dropped executables or scripts found in user-writable paths that launched the plist check.  
- Revoke Full Disk Access for the suspicious app in Privacy & Security settings, reset TCC permissions if tampering is suspected, and rotate credentials/tokens exposed on the host (browser sessions, SSH keys, API keys) if protected data access is likely.  
- Collect and preserve evidence (the binary and its hash, quarantine/xattr info, parent process, relevant unified logs, and a copy of the accessed plist) before cleanup, then run a full endpoint malware scan and validate no additional sensitive files were accessed immediately after the check.  
- Restore system integrity by updating macOS and security tools, reinstalling or re-imaging if core components were modified, and confirm normal Time Machine configuration after remediation to ensure operational recovery.  
- Escalate to IR/SECOPS immediately if the process is unsigned/notarization-missing, shows persistence, or makes outbound connections after the plist read, and harden by enforcing MDM controls that restrict FDA grants and block execution of untrusted scripting runtimes where feasible.
"""
risk_score = 47
rule_id = "e26c0f76-2e80-445b-9e98-ab5532ccc46f"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: macOS",
    "Use Case: Threat Detection",
    "Tactic: Discovery",
    "Data Source: Elastic Defend",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
file where host.os.type == "macos" and event.action == "open" and
  file.path == "/Library/Preferences/com.apple.TimeMachine.plist" and
  (process.name in ("osascript", "perl", "node", "ruby", "bash", "sh", "Terminal") or
   process.name like "python*" or
   process.code_signature.trusted == false or
   process.code_signature.exists == false)
'''

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

[[rule.threat.technique]]
id = "T1083"
name = "File and Directory Discovery"
reference = "https://attack.mitre.org/techniques/T1083/"

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

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

[[rule.threat.technique]]
id = "T1548"
name = "Abuse Elevation Control Mechanism"
reference = "https://attack.mitre.org/techniques/T1548/"

[[rule.threat.technique.subtechnique]]
id = "T1548.006"
name = "TCC Manipulation"
reference = "https://attack.mitre.org/techniques/T1548/006/"

[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 = "T1548"
name = "Abuse Elevation Control Mechanism"
reference = "https://attack.mitre.org/techniques/T1548/"

[[rule.threat.technique.subtechnique]]
id = "T1548.006"
name = "TCC Manipulation"
reference = "https://attack.mitre.org/techniques/T1548/006/"

[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"

Stages and Predicates

Stage 1: file

file where host.os.type == "macos" and event.action == "open" and
  file.path == "/Library/Preferences/com.apple.TimeMachine.plist" and
  (process.name in ("osascript", "perl", "node", "ruby", "bash", "sh", "Terminal") or
   process.name like "python*" or
   process.code_signature.trusted == false or
   process.code_signature.exists == false)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • open corpus 49 (elastic 49)
field:"EventType" kind:eq value:"open"
file.patheq
  • /Library/Preferences/com.apple.TimeMachine.plist
field:"TargetFilename" kind:eq value:"/Library/Preferences/com.apple.TimeMachine.plist"
process.code_signature.existseq
  • false transforms: boolean corpus 118 (elastic 118)
field:"process.code_signature.exists" kind:eq value:"false"
process.code_signature.trustedeq
  • false transforms: boolean corpus 114 (elastic 114)
field:"process.code_signature.trusted" kind:eq value:"false"
process.namein
  • Terminal corpus 2 (elastic 2)
  • bash corpus 181 (elastic 181)
  • node corpus 25 (elastic 25)
  • osascript corpus 12 (elastic 12)
  • perl corpus 4 (elastic 4)
  • ruby corpus 4 (elastic 4)
  • sh corpus 180 (elastic 180)
field:"process_basename" kind:in
process.namewildcard
  • python* corpus 55 (elastic 55)
field:"process_basename" kind:wildcard value:"python*"

GenAI or MCP Server Child Process Execution

#
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

Detects child process execution from GenAI tools or MCP (Model Context Protocol) servers. Adversaries exploit AI agents to execute system commands, exfiltrate data, or establish persistence. MCP servers provide LLMs direct access to execute shell commands, read files, and interact with external services. This building block provides visibility into AI-initiated process execution for correlation with other suspicious activity.

MITRE ATT&CK Coverage

MITRE ATLAS Coverage

Adversarial-ML threat framework (not MITRE ATT&CK).

Rule Body

[metadata]
creation_date = "2025/12/04"
integration = ["endpoint", "windows", "sentinel_one_cloud_funnel", "m365_defender"]
maturity = "production"
updated_date = "2026/08/10"

[rule]
author = ["Elastic"]
building_block_type = "default"
description = """
Detects child process execution from GenAI tools or MCP (Model Context Protocol) servers. Adversaries exploit AI agents
to execute system commands, exfiltrate data, or establish persistence. MCP servers provide LLMs direct access to execute
shell commands, read files, and interact with external services. This building block provides visibility into
AI-initiated process execution for correlation with other suspicious activity.
"""
from = "now-119m"
index = [
    "logs-endpoint.events.process-*",
    "logs-windows.sysmon_operational-*",
    "logs-m365_defender.event-*",
    "logs-sentinel_one_cloud_funnel.*",
]
interval = "60m"
language = "eql"
license = "Elastic License v2"
name = "GenAI or MCP Server Child Process Execution"
risk_score = 21
rule_id = "b2c3d4e5-f6a7-8901-bcde-f23456789012"
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "OS: macOS",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Execution",
    "Data Source: Elastic Defend",
    "Data Source: Sysmon",
    "Data Source: Microsoft Defender XDR",
    "Data Source: SentinelOne",
    "Rule Type: BBR",
    "Domain: LLM",
    "Mitre Atlas: T0053",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
process where event.type == "start" 
  and (
    // GenAI clients
    process.parent.name in (
      "Cursor", "Cursor.exe", "cursor",
      "Cursor Helper", "Cursor Helper (Plugin)", "Cursor Helper (GPU)", "Cursor Helper (Renderer)",
      "Claude", "Claude.exe", "claude",
      "Claude Helper", "Claude Helper (Plugin)", "Claude Helper (GPU)", "Claude Helper (Renderer)",
      "Windsurf", "Windsurf.exe", "windsurf",
      "Windsurf Helper", "Windsurf Helper (Plugin)", "Windsurf Helper (GPU)", "Windsurf Helper (Renderer)",
      "Code", "Code.exe", "code",
      "Code Helper", "Code Helper (Plugin)", "Code Helper (GPU)", "Code Helper (Renderer)",
      "codex", "codex.exe",
      "Copilot", "Copilot.exe", "copilot",
      "Jan", "Jan.exe", "jan",
      "Jan Helper", "Jan Helper (Plugin)", "Jan Helper (GPU)", "Jan Helper (Renderer)",
      "LM Studio", "LM Studio.exe", "lmstudio",
      "Ollama", "Ollama.exe", "ollama",
      "GPT4All", "gpt4all", "gpt4all.exe",
      "textgen.exe", "textgen", "text-generation-webui.exe", "oobabooga.exe",
      "gemini-cli.exe", "gemini-cli",
      "genaiscript.exe", "genaiscript",
      "grok.exe", "grok",
      "qwen.exe", "qwen",
      "koboldcpp.exe", "koboldcpp", "KoboldCpp",
      "llama-server", "llama-cli",
      "OpenClaw", "openclaw", "openclaw.exe",
      "Moltbot", "moltbot", "moltbot.exe",
      "Clawdbot", "clawdbot", "clawdbot.exe"
    ) or
    // OpenClaw/Moltbot/Clawdbot via Node.js
    (process.parent.name in ("node", "node.exe") and
     process.parent.command_line like~ ("*openclaw*", "*moltbot*", "*clawdbot*")) or
    // Package managers running MCP servers
    (process.parent.name in ("npx", "npx.exe", "pnpm", "pnpm.exe", "yarn", "yarn.exe", "bunx", "bunx.exe") and
     process.parent.command_line like~ ("*@modelcontextprotocol/*", "*mcp-server-*", "*mcp_server*")) or
    
    // Node/Deno/Bun running MCP servers
    (process.parent.name in ("node", "node.exe", "deno", "deno.exe", "bun", "bun.exe") and
     process.parent.command_line like~ ("*@modelcontextprotocol/*", "*mcp-server-*", "*mcp_server*")) or
    
    // Python MCP servers
    (process.parent.name like~ "python*" and
     process.parent.command_line like~ ("*-m mcp_server*", "*mcp-server-*", "*mcp_server*")) or
    
    // MCP server binaries
    process.parent.name like~ ("mcp-server*", "*-mcp-server", "*_mcp_server*") or
    process.parent.name in ("mcp-server", "mcp-server-elastic-cloud", "github-mcp-server")
  )
  and process.name != null
  // Exclusions
  and not (
    // Runtime self-spawns
    (process.parent.name in ("node", "node.exe") and process.name in ("node", "node.exe")) or
    (process.parent.name like~ "python*" and process.name like~ "python*") or
    (process.parent.name in ("deno", "deno.exe") and process.name in ("deno", "deno.exe")) or
    (process.parent.name in ("bun", "bun.exe") and process.name in ("bun", "bun.exe")) or
    
    // Electron helper noise: app -> helper, and helper -> helper
    (process.parent.name like~ ("Cursor", "Cursor.exe", "Cursor Helper*") and
     process.name like~ "Cursor Helper*") or
    (process.parent.name like~ ("Claude", "Claude.exe", "Claude Helper*") and
     process.name like~ "Claude Helper*") or
    (process.parent.name like~ ("Windsurf", "Windsurf.exe", "Windsurf Helper*") and
     process.name like~ "Windsurf Helper*") or
    (process.parent.name like~ ("Code", "Code.exe", "Code Helper*") and
     process.name like~ "Code Helper*") or
    (process.parent.name like~ ("Jan", "Jan.exe", "Jan Helper*") and
     process.name like~ "Jan Helper*") or
    (process.parent.name like~ ("LM Studio", "LM Studio.exe", "LM Studio Helper*") and
     process.name like~ ("LM Studio", "LM Studio.exe", "LM Studio Helper*")) or
    (process.parent.name like~ ("Ollama", "Ollama.exe", "Ollama Helper*") and
     process.name like~ "Ollama Helper*") or

    // GenAI client same-name self-spawns (explicit pairs; no field-to-field compare)
    (process.parent.name like~ ("cursor", "cursor.exe") and
     process.name like~ ("cursor", "cursor.exe")) or
    (process.parent.name like~ ("claude", "claude.exe") and
     process.name like~ ("claude", "claude.exe")) or
    (process.parent.name like~ ("windsurf", "windsurf.exe") and
     process.name like~ ("windsurf", "windsurf.exe")) or
    (process.parent.name like~ ("code", "code.exe") and
     process.name like~ ("code", "code.exe")) or
    (process.parent.name like~ ("codex", "codex.exe") and
     process.name like~ ("codex", "codex.exe")) or
    (process.parent.name like~ ("copilot", "copilot.exe") and
     process.name like~ ("copilot", "copilot.exe")) or
    (process.parent.name like~ ("jan", "jan.exe") and
     process.name like~ ("jan", "jan.exe")) or
    (process.parent.name like~ ("ollama", "ollama.exe") and
     process.name like~ ("ollama", "ollama.exe")) or

    // docker
    (process.name in ("docker", "docker.exe") and process.args == "context" and process.args == "ls") or
    // env probes: ps/getconf/lsb_release by name; neighbor/arp/which by args or /bin/sh -c
    (
      process.name in ("ps", "getconf", "lsb_release") or
      process.args in (
        "ip neigh show",
        "arp -a -n -l",
        "ip neighbor show dev wlan0",
        "ip neighbor show dev eth0",
        "arp -a | findstr /C:---"
      ) or
      process.command_line in (
        "/bin/sh -c ip neigh show",
        "/bin/sh -c arp -a -n -l",
        "/bin/sh -c /bin/ps -ax -o pid=,ppid=,pcpu=,pmem=,command=",
        "/bin/sh -c which ps"
      )
    ) or
    // git
    (process.name in ("git", "git.exe") and (
      (process.args == "remote" and process.args == "get-url" and process.args == "origin") or
      (process.args == "symbolic-ref" and process.args == "refs/remotes/origin/HEAD" and process.args == "--short") or
      (process.args == "rev-parse" and process.args == "--abbrev-ref" and process.args == "HEAD") or
      (process.args == "status" and process.args == "-z" and process.args == "-uall") or
      (process.args == "config" and process.args == "--get" and process.args == "commit.template") or
      (process.args == "config" and process.args == "user.email") or
      (process.args == "rev-parse" and process.args == "--show-toplevel")
    )) or
    // version / help
    process.args in ("--version", "--help", "-v", "-h", "-V", "version", "help")
  )
'''


[[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.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"

Stages and Predicates

Stage 1: process

process where event.type == "start"
  and (
    process.parent.name in (
      "Cursor", "Cursor.exe", "cursor",
      "Cursor Helper", "Cursor Helper (Plugin)", "Cursor Helper (GPU)", "Cursor Helper (Renderer)",
      "Claude", "Claude.exe", "claude",
      "Claude Helper", "Claude Helper (Plugin)", "Claude Helper (GPU)", "Claude Helper (Renderer)",
      "Windsurf", "Windsurf.exe", "windsurf",
      "Windsurf Helper", "Windsurf Helper (Plugin)", "Windsurf Helper (GPU)", "Windsurf Helper (Renderer)",
      "Code", "Code.exe", "code",
      "Code Helper", "Code Helper (Plugin)", "Code Helper (GPU)", "Code Helper (Renderer)",
      "codex", "codex.exe",
      "Copilot", "Copilot.exe", "copilot",
      "Jan", "Jan.exe", "jan",
      "Jan Helper", "Jan Helper (Plugin)", "Jan Helper (GPU)", "Jan Helper (Renderer)",
      "LM Studio", "LM Studio.exe", "lmstudio",
      "Ollama", "Ollama.exe", "ollama",
      "GPT4All", "gpt4all", "gpt4all.exe",
      "textgen.exe", "textgen", "text-generation-webui.exe", "oobabooga.exe",
      "gemini-cli.exe", "gemini-cli",
      "genaiscript.exe", "genaiscript",
      "grok.exe", "grok",
      "qwen.exe", "qwen",
      "koboldcpp.exe", "koboldcpp", "KoboldCpp",
      "llama-server", "llama-cli",
      "OpenClaw", "openclaw", "openclaw.exe",
      "Moltbot", "moltbot", "moltbot.exe",
      "Clawdbot", "clawdbot", "clawdbot.exe"
    ) or
    (process.parent.name in ("node", "node.exe") and
     process.parent.command_line like~ ("*openclaw*", "*moltbot*", "*clawdbot*")) or
    (process.parent.name in ("npx", "npx.exe", "pnpm", "pnpm.exe", "yarn", "yarn.exe", "bunx", "bunx.exe") and
     process.parent.command_line like~ ("*@modelcontextprotocol/*", "*mcp-server-*", "*mcp_server*")) or
    (process.parent.name in ("node", "node.exe", "deno", "deno.exe", "bun", "bun.exe") and
     process.parent.command_line like~ ("*@modelcontextprotocol/*", "*mcp-server-*", "*mcp_server*")) or
    (process.parent.name like~ "python*" and
     process.parent.command_line like~ ("*-m mcp_server*", "*mcp-server-*", "*mcp_server*")) or
    process.parent.name like~ ("mcp-server*", "*-mcp-server", "*_mcp_server*") or
    process.parent.name in ("mcp-server", "mcp-server-elastic-cloud", "github-mcp-server")
  )
  and process.name != null
  and not (
    (process.parent.name in ("node", "node.exe") and process.name in ("node", "node.exe")) or
    (process.parent.name like~ "python*" and process.name like~ "python*") or
    (process.parent.name in ("deno", "deno.exe") and process.name in ("deno", "deno.exe")) or
    (process.parent.name in ("bun", "bun.exe") and process.name in ("bun", "bun.exe")) or
    (process.parent.name like~ ("Cursor", "Cursor.exe", "Cursor Helper*") and
     process.name like~ "Cursor Helper*") or
    (process.parent.name like~ ("Claude", "Claude.exe", "Claude Helper*") and
     process.name like~ "Claude Helper*") or
    (process.parent.name like~ ("Windsurf", "Windsurf.exe", "Windsurf Helper*") and
     process.name like~ "Windsurf Helper*") or
    (process.parent.name like~ ("Code", "Code.exe", "Code Helper*") and
     process.name like~ "Code Helper*") or
    (process.parent.name like~ ("Jan", "Jan.exe", "Jan Helper*") and
     process.name like~ "Jan Helper*") or
    (process.parent.name like~ ("LM Studio", "LM Studio.exe", "LM Studio Helper*") and
     process.name like~ ("LM Studio", "LM Studio.exe", "LM Studio Helper*")) or
    (process.parent.name like~ ("Ollama", "Ollama.exe", "Ollama Helper*") and
     process.name like~ "Ollama Helper*") or
    (process.parent.name like~ ("cursor", "cursor.exe") and
     process.name like~ ("cursor", "cursor.exe")) or
    (process.parent.name like~ ("claude", "claude.exe") and
     process.name like~ ("claude", "claude.exe")) or
    (process.parent.name like~ ("windsurf", "windsurf.exe") and
     process.name like~ ("windsurf", "windsurf.exe")) or
    (process.parent.name like~ ("code", "code.exe") and
     process.name like~ ("code", "code.exe")) or
    (process.parent.name like~ ("codex", "codex.exe") and
     process.name like~ ("codex", "codex.exe")) or
    (process.parent.name like~ ("copilot", "copilot.exe") and
     process.name like~ ("copilot", "copilot.exe")) or
    (process.parent.name like~ ("jan", "jan.exe") and
     process.name like~ ("jan", "jan.exe")) or
    (process.parent.name like~ ("ollama", "ollama.exe") and
     process.name like~ ("ollama", "ollama.exe")) or
    (process.name in ("docker", "docker.exe") and process.args == "context" and process.args == "ls") or
    (
      process.name in ("ps", "getconf", "lsb_release") or
      process.args in (
        "ip neigh show",
        "arp -a -n -l",
        "ip neighbor show dev wlan0",
        "ip neighbor show dev eth0",
        "arp -a | findstr /C:---"
      ) or
      process.command_line in (
        "/bin/sh -c ip neigh show",
        "/bin/sh -c arp -a -n -l",
        "/bin/sh -c /bin/ps -ax -o pid=,ppid=,pcpu=,pmem=,command=",
        "/bin/sh -c which ps"
      )
    ) or
    (process.name in ("git", "git.exe") and (
      (process.args == "remote" and process.args == "get-url" and process.args == "origin") or
      (process.args == "symbolic-ref" and process.args == "refs/remotes/origin/HEAD" and process.args == "--short") or
      (process.args == "rev-parse" and process.args == "--abbrev-ref" and process.args == "HEAD") or
      (process.args == "status" and process.args == "-z" and process.args == "-uall") or
      (process.args == "config" and process.args == "--get" and process.args == "commit.template") or
      (process.args == "config" and process.args == "user.email") or
      (process.args == "rev-parse" and process.args == "--show-toplevel")
    )) or
    process.args in ("--version", "--help", "-v", "-h", "-V", "version", "help")
  )

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.nameis_not_null
  • (no value, null check)
field:"process_basename" kind:is_not_null
process.parent.command_linewildcard
  • *-m mcp_server*
  • *@modelcontextprotocol/*
  • *clawdbot* corpus 2 (elastic 2)
  • *mcp-server-*
  • *mcp_server*
  • *moltbot* corpus 2 (elastic 2)
  • *openclaw* corpus 2 (elastic 2)
field:"ParentCommandLine" kind:wildcard
process.parent.namein
  • Claude corpus 3 (elastic 3)
  • Claude Helper
  • Claude Helper (GPU)
  • Claude Helper (Plugin)
  • Claude Helper (Renderer)
  • Claude.exe
  • Clawdbot
  • Code
  • Code Helper
  • Code Helper (GPU)
  • Code Helper (Plugin)
  • Code Helper (Renderer)
  • Code.exe
  • Copilot corpus 3 (elastic 3)
  • Copilot.exe
  • Cursor corpus 4 (elastic 4)
  • Cursor Helper corpus 3 (elastic 3)
  • Cursor Helper (GPU)
  • Cursor Helper (Plugin) corpus 3 (elastic 3)
  • Cursor Helper (Renderer)
  • Cursor.exe
  • GPT4All corpus 3 (elastic 3)
  • Jan corpus 3 (elastic 3)
  • Jan Helper corpus 3 (elastic 3)
  • Jan Helper (GPU)
  • Jan Helper (Plugin)
  • Jan Helper (Renderer)
  • Jan.exe
  • KoboldCpp corpus 3 (elastic 3)
  • LM Studio corpus 3 (elastic 3)
  • LM Studio.exe
  • Moltbot
  • Ollama corpus 3 (elastic 3)
  • Ollama.exe
  • OpenClaw
  • Windsurf
  • Windsurf Helper corpus 2 (elastic 2)
  • Windsurf Helper (GPU) corpus 2 (elastic 2)
  • Windsurf Helper (Plugin) corpus 2 (elastic 2)
  • Windsurf Helper (Renderer) corpus 2 (elastic 2)
  • +52 more values (see full rule source)
field:"parent_process_basename" kind:in
process.parent.namewildcard
  • *-mcp-server
  • *_mcp_server*
  • mcp-server*
  • python* corpus 19 (elastic 19)
field:"parent_process_basename" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argseq--abbrev-refexcludes:process.args field:"process.args" value:"--abbrev-ref"
process.argseqHEADexcludes:process.args field:"process.args" value:"HEAD"
process.argseqrev-parseexcludes:process.args field:"process.args" value:"rev-parse"
process.argseq--getexcludes:process.args field:"process.args" value:"--get"
process.argseqcommit.templateexcludes:process.args field:"process.args" value:"commit.template"
process.argseqconfigexcludes:process.args field:"process.args" value:"config"
process.argseq--shortexcludes:process.args field:"process.args" value:"--short"
process.argseqrefs/remotes/origin/HEADexcludes:process.args field:"process.args" value:"refs/remotes/origin/HEAD"
process.argseqsymbolic-refexcludes:process.args field:"process.args" value:"symbolic-ref"
process.argseq--show-toplevelexcludes:process.args field:"process.args" value:"--show-toplevel"
process.argseq-uallexcludes:process.args field:"process.args" value:"-uall"
process.argseq-zexcludes:process.args field:"process.args" value:"-z"
process.argseqstatusexcludes:process.args field:"process.args" value:"status"
process.argsequser.emailexcludes:process.args field:"process.args" value:"user.email"
process.argseqget-urlexcludes:process.args field:"process.args" value:"get-url"
process.argseqoriginexcludes:process.args field:"process.args" value:"origin"
process.argseqremoteexcludes:process.args field:"process.args" value:"remote"
process.nameingit, git.exeexcludes:process.name field:"process.name" value:"git" field:"process.name" value:"git.exe"
process.argseqcontextexcludes:process.args field:"process.args" value:"context"
process.argseqlsexcludes:process.args field:"process.args" value:"ls"
process.nameindocker, docker.exeexcludes:process.name field:"process.name" value:"docker" field:"process.name" value:"docker.exe"
process.nameeqclaude, claude.exeexcludes:process.name field:"process.name" value:"claude" field:"process.name" value:"claude.exe"
process.parent.nameeqclaude, claude.exeexcludes:process.parent.name field:"process.parent.name" value:"claude" field:"process.parent.name" value:"claude.exe"
process.nameeqcode, code.exeexcludes:process.name field:"process.name" value:"code" field:"process.name" value:"code.exe"
process.parent.nameeqcode, code.exeexcludes:process.parent.name field:"process.parent.name" value:"code" field:"process.parent.name" value:"code.exe"
process.nameeqcodex, codex.exeexcludes:process.name field:"process.name" value:"codex" field:"process.name" value:"codex.exe"
process.parent.nameeqcodex, codex.exeexcludes:process.parent.name field:"process.parent.name" value:"codex" field:"process.parent.name" value:"codex.exe"
process.nameeqcopilot, copilot.exeexcludes:process.name field:"process.name" value:"copilot" field:"process.name" value:"copilot.exe"
process.parent.nameeqcopilot, copilot.exeexcludes:process.parent.name field:"process.parent.name" value:"copilot" field:"process.parent.name" value:"copilot.exe"
process.nameeqcursor, cursor.exeexcludes:process.name field:"process.name" value:"cursor" field:"process.name" value:"cursor.exe"
process.parent.nameeqcursor, cursor.exeexcludes:process.parent.name field:"process.parent.name" value:"cursor" field:"process.parent.name" value:"cursor.exe"
process.nameeqjan, jan.exeexcludes:process.name field:"process.name" value:"jan" field:"process.name" value:"jan.exe"
process.parent.nameeqjan, jan.exeexcludes:process.parent.name field:"process.parent.name" value:"jan" field:"process.parent.name" value:"jan.exe"
process.nameeqollama, ollama.exeexcludes:process.name field:"process.name" value:"ollama" field:"process.name" value:"ollama.exe"
process.parent.nameeqollama, ollama.exeexcludes:process.parent.name field:"process.parent.name" value:"ollama" field:"process.parent.name" value:"ollama.exe"
process.nameeqwindsurf, windsurf.exeexcludes:process.name field:"process.name" value:"windsurf" field:"process.name" value:"windsurf.exe"
process.parent.nameeqwindsurf, windsurf.exeexcludes:process.parent.name field:"process.parent.name" value:"windsurf" field:"process.parent.name" value:"windsurf.exe"
process.nameinbun, bun.exeexcludes:process.name field:"process.name" value:"bun" field:"process.name" value:"bun.exe"
process.parent.nameinbun, bun.exeexcludes:process.parent.name field:"process.parent.name" value:"bun" field:"process.parent.name" value:"bun.exe"
process.nameindeno, deno.exeexcludes:process.name field:"process.name" value:"deno" field:"process.name" value:"deno.exe"
process.parent.nameindeno, deno.exeexcludes:process.parent.name field:"process.parent.name" value:"deno" field:"process.parent.name" value:"deno.exe"
process.nameinnode, node.exeexcludes:process.name field:"process.name" value:"node" field:"process.name" value:"node.exe"
process.parent.nameinnode, node.exeexcludes:process.parent.name field:"process.parent.name" value:"node" field:"process.parent.name" value:"node.exe"
process.namestarts_withClaude Helperexcludes:process.name field:"process.name" value:"Claude Helper"
process.parent.namewildcardClaude, Claude.exe, Claude Helper*excludes:process.parent.name field:"process.parent.name" value:"Claude" field:"process.parent.name" value:"Claude.exe" field:"process.parent.name" value:"Claude Helper*"
process.namestarts_withCode Helperexcludes:process.name field:"process.name" value:"Code Helper"
process.parent.namewildcardCode, Code.exe, Code Helper*excludes:process.parent.name field:"process.parent.name" value:"Code" field:"process.parent.name" value:"Code.exe" field:"process.parent.name" value:"Code Helper*"
process.namestarts_withCursor Helperexcludes:process.name field:"process.name" value:"Cursor Helper"
process.parent.namewildcardCursor, Cursor.exe, Cursor Helper*excludes:process.parent.name field:"process.parent.name" value:"Cursor" field:"process.parent.name" value:"Cursor.exe" field:"process.parent.name" value:"Cursor Helper*"
process.namestarts_withJan Helperexcludes:process.name field:"process.name" value:"Jan Helper"
process.parent.namewildcardJan, Jan.exe, Jan Helper*excludes:process.parent.name field:"process.parent.name" value:"Jan" field:"process.parent.name" value:"Jan.exe" field:"process.parent.name" value:"Jan Helper*"
process.namestarts_withOllama Helperexcludes:process.name field:"process.name" value:"Ollama Helper"
process.parent.namewildcardOllama, Ollama.exe, Ollama Helper*excludes:process.parent.name field:"process.parent.name" value:"Ollama" field:"process.parent.name" value:"Ollama.exe" field:"process.parent.name" value:"Ollama Helper*"
process.namestarts_withWindsurf Helperexcludes:process.name field:"process.name" value:"Windsurf Helper"
process.parent.namewildcardWindsurf, Windsurf.exe, Windsurf Helper*excludes:process.parent.name field:"process.parent.name" value:"Windsurf" field:"process.parent.name" value:"Windsurf.exe" field:"process.parent.name" value:"Windsurf Helper*"
process.namestarts_withpythonexcludes:process.name field:"process.name" value:"python"
process.parent.namestarts_withpythonexcludes:process.parent.name field:"process.parent.name" value:"python"
process.namewildcardLM Studio, LM Studio.exe, LM Studio Helper*excludes:process.name field:"process.name" value:"LM Studio" field:"process.name" value:"LM Studio.exe" field:"process.name" value:"LM Studio Helper*"
process.parent.namewildcardLM Studio, LM Studio.exe, LM Studio Helper*excludes:process.parent.name field:"process.parent.name" value:"LM Studio" field:"process.parent.name" value:"LM Studio.exe" field:"process.parent.name" value:"LM Studio Helper*"
process.argsin--help, --version, -V, -h, -v, help, versionexcludes:process.args
process.argsinarp -a -n -l, arp -a | findstr /C:---, ip neigh show, ip neighbor show dev eth0, ip neighbor show dev wlan0excludes:process.args
process.command_linein/bin/sh -c /bin/ps -ax -o pid=,ppid=,pcpu=,pmem=,command=, /bin/sh -c arp -a -n -l, /bin/sh -c ip neigh show, /bin/sh -c which psexcludes:process.command_line
process.nameingetconf, lsb_release, psexcludes:process.name field:"process.name" value:"getconf" field:"process.name" value:"lsb_release" field:"process.name" value:"ps"

ICMP Redirect Message from Internal Host

#
Status
production
Severity
high
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies ICMP Redirect messages (type 5 for IPv4, type 137 for IPv6) sourced from an internal IPv4 or IPv6 address. Legitimate redirects are normally sent only by on-path routers. A workstation or server emitting redirects can indicate route manipulation for adversary-in-the-middle activity.

MITRE ATT&CK Coverage

TacticTechniques
Credential Access

Rule Body

[metadata]
creation_date = "2026/06/25"
integration = ["network_traffic"]
maturity = "production"
updated_date = "2026/06/25"

[rule]
author = ["Elastic"]
description = """
Identifies ICMP Redirect messages (type 5 for IPv4, type 137 for IPv6) sourced from an internal IPv4 or IPv6 address.
Legitimate redirects are normally sent only by on-path routers. A workstation or server emitting redirects can indicate
route manipulation for adversary-in-the-middle activity.
"""
from = "now-9m"
index = ["logs-network_traffic.icmp-*"]
language = "kuery"
license = "Elastic License v2"
name = "ICMP Redirect Message from Internal Host"
note = """## Triage and analysis

> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

### Investigating ICMP Redirect Message from Internal Host

ICMP Redirect instructs a host to send traffic for a destination through a different next hop. On most enterprise
segments, only infrastructure routers should emit redirects; a user workstation or server doing so is a strong
adversary-in-the-middle indicator.

### Possible investigation steps

- Identify the redirect source in `source.ip` and locate the asset on the VLAN. Confirm whether it is an authorized
  router or gateway.
- Review the redirect target and affected destination in ICMP fields and adjacent flow records to see which routes or
  resolvers were being manipulated.
- Check whether affected clients show DNS, gateway, or VPN routing changes around the alert time.
- Correlate with DHCP, ARP, or LLMNR/NBT-NS alerts on the same segment for combined MITM activity.

### False positive analysis

- Some legacy network appliances, hypervisor gateways, or misconfigured Linux hosts with IP forwarding enabled may
  emit redirects. Maintain exceptions for known router and gateway IPs after validation.
- Lab networks that intentionally test route injection should be scoped out by source subnet.

### Response and remediation

- Isolate the emitting host if it is not an authorized router.
- Disable ICMP redirect acceptance on affected clients where policy allows, and block redirect-generating hosts at the
  access layer.
- Review segment routing, default gateways, and DHCP options for unauthorized changes."""
references = [
    "https://www.rfc-editor.org/rfc/rfc792",
    "https://www.rfc-editor.org/rfc/rfc4443",
    "https://zimperium.com/blog/doubledirect-zimperium-discovers-full-duplex-icmp-redirect-attacks-in-the-wild",
]
risk_score = 73
rule_id = "2014ebd8-b847-4cc0-a827-d0d61ec88680"
setup = """## Setup

This rule requires ICMP transaction telemetry from the Elastic network_traffic integration (`network_traffic.icmp`
data stream). Flow-only exporters that do not record ICMP type/code will not satisfy this rule.
"""
severity = "high"
tags = [
    "Domain: Network",
    "Tactic: Credential Access",
    "Use Case: Threat Detection",
    "Use Case: Network Security Monitoring",
    "Data Source: Network Traffic",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset:network_traffic.icmp
  and (network_traffic.icmp.request.type:(5 or 137) or icmp.request.type:(5 or 137))
  and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 or "FC00::/7" or "FE80::/10")
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1557"
name = "Adversary-in-the-Middle"
reference = "https://attack.mitre.org/techniques/T1557/"


[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"

Stages and Predicates

Stage 1: query

data_stream.dataset:network_traffic.icmp
  and (network_traffic.icmp.request.type:(5 or 137) or icmp.request.type:(5 or 137))
  and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16 or "FC00::/7" or "FE80::/10")

Indicators

These rows show field, operator, and value matches.

Kill Command Executed from Binary in Unusual Location

#
Source
github.com/elastic/protections-artifacts

This rule detects the execution of the "kill" or "pkill" command from a binary located in an unusual location. Miners and other types of malware may attempt to kill competing processes to maintain control of the system.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[rule]
description = """
This rule detects the execution of the "kill" or "pkill" command from a binary located in an unusual location. Miners
and other types of malware may attempt to kill competing processes to maintain control of the system.
"""
id = "b9935dcc-e885-4954-9999-3c016b990737"
license = "Elastic License v2"
name = "Kill Command Executed from Binary in Unusual Location"
os_list = ["linux", "macos"]
reference = ["https://blog.xlab.qianxin.com/8220-k4spreader-new-tool-en/"]
version = "1.0.18"

query = '''
process where event.type == "start" and event.action == "exec" and process.name in ("kill", "pkill", "killall") and
(process.parent.executable like ("/tmp/*", "/var/tmp/*", "/dev/shm/*", "./.*") or process.parent.name like ".*") and
  not (
  process.parent.executable like (
    "/tmp/newroot/*", "/tmp/JobScheduler-Agent-start_rib-*", "/tmp/ubuntu-release-upgrader-*", "/tmp/.criu*",
    "/tmp/home-manager-build*/generation/activate", "/tmp/wpsupgrade.prerm", "/tmp/.mount_Cursor*", "/var/tmp/buildah*",
    "/tmp/JackettUpdate*/Jackett/JackettUpdater", "/tmp/.*.ansible/ansible-tmp-*", "/tmp/user/*/ubuntu-release-upgrader-*/noble",
    "/tmp/snap.rootfs_*/snap/zoom-client/*/zoom/zoom", "/tmp/B1ServerTools.*/opt/sap/SAPBusinessOne/Common/*/bin/java",
    "/nix/store/*", "/var/lib/containers/storage/overlay/nix/store/*/bin/.hyprshot-wrapped"
  ) or
  process.executable like "./merged/*" or
  process.parent.name like ("check_openvpnauthentication", "python*", "vmis-launcher", "nessuscli", "AppRun", ".", ".azotebg") or
  process.command_line in ("pkill -f /nop", "killall -e -9 lmgrd", "killall steam-runtime-launcher-service") or
  (process.parent.executable == "/tmp/o.chaban/devpod/agent" and process.command_line == "pkill -HUP dockerd") or
  (process.parent.name == "upgrade-execute.sh" and process.command_line == "pkill -SIGHUP -f acconsole")
)
'''

min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"



[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[[threat.technique.subtechnique]]
id = "T1562.006"
name = "Indicator Blocking"
reference = "https://attack.mitre.org/techniques/T1562/006/"



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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Stage 1: process

process where event.type == "start" and event.action == "exec" and process.name in ("kill", "pkill", "killall") and
(process.parent.executable like ("/tmp/*", "/var/tmp/*", "/dev/shm/*", "./.*") or process.parent.name like ".*") and
  not (
  process.parent.executable like (
    "/tmp/newroot/*", "/tmp/JobScheduler-Agent-start_rib-*", "/tmp/ubuntu-release-upgrader-*", "/tmp/.criu*",
    "/tmp/home-manager-build*/generation/activate", "/tmp/wpsupgrade.prerm", "/tmp/.mount_Cursor*", "/var/tmp/buildah*",
    "/tmp/JackettUpdate*/Jackett/JackettUpdater", "/tmp/.*.ansible/ansible-tmp-*", "/tmp/user/*/ubuntu-release-upgrader-*/noble",
    "/tmp/snap.rootfs_*/snap/zoom-client/*/zoom/zoom", "/tmp/B1ServerTools.*/opt/sap/SAPBusinessOne/Common/*/bin/java",
    "/nix/store/*", "/var/lib/containers/storage/overlay/nix/store/*/bin/.hyprshot-wrapped"
  ) or
  process.executable like "./merged/*" or
  process.parent.name like ("check_openvpnauthentication", "python*", "vmis-launcher", "nessuscli", "AppRun", ".", ".azotebg") or
  process.command_line in ("pkill -f /nop", "killall -e -9 lmgrd", "killall steam-runtime-launcher-service") or
  (process.parent.executable == "/tmp/o.chaban/devpod/agent" and process.command_line == "pkill -HUP dockerd") or
  (process.parent.name == "upgrade-execute.sh" and process.command_line == "pkill -SIGHUP -f acconsole")
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • exec corpus 547 (elastic 547)
field:"EventType" kind:eq value:"exec"
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.namein
  • kill corpus 3 (elastic 3)
  • killall corpus 5 (elastic 5)
  • pkill corpus 5 (elastic 5)
field:"process_basename" kind:in
process.parent.executablewildcard
  • ./.*
  • /dev/shm/* corpus 11 (elastic 11)
  • /tmp/* corpus 13 (elastic 13)
  • /var/tmp/* corpus 11 (elastic 11)
field:"ParentImage" kind:wildcard
process.parent.namewildcard
  • .* corpus 7 (elastic 7)
field:"parent_process_basename" kind:wildcard value:".*"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.command_lineeqpkill -HUP dockerdexcludes:process.command_line field:"process.command_line" value:"pkill -HUP dockerd"
process.parent.executableeq/tmp/o.chaban/devpod/agentexcludes:process.parent.executable field:"process.parent.executable" value:"/tmp/o.chaban/devpod/agent"
process.command_lineeqpkill -SIGHUP -f acconsoleexcludes:process.command_line field:"process.command_line" value:"pkill -SIGHUP -f acconsole"
process.parent.nameequpgrade-execute.shexcludes:process.parent.name field:"process.parent.name" value:"upgrade-execute.sh"
process.command_lineinkillall -e -9 lmgrd, killall steam-runtime-launcher-service, pkill -f /nopexcludes:process.command_line field:"process.command_line" value:"killall -e -9 lmgrd" field:"process.command_line" value:"killall steam-runtime-launcher-service" field:"process.command_line" value:"pkill -f /nop"
process.executablestarts_with./merged/excludes:process.executable field:"process.executable" value:"./merged/"
process.parent.executablewildcard/tmp/newroot/*, /tmp/JobScheduler-Agent-start_rib-*, /tmp/ubuntu-release-upgrader-*, /tmp/.criu*, /tmp/home-manager-build*/generation/activate, /tmp/wpsupgrade.prerm, /tmp/.mount_Cursor*, /var/tmp/buildah*, /tmp/JackettUpdate*/Jackett/JackettUpdater, /tmp/.*.ansible/ansible-tmp-*, /tmp/user/*/ubuntu-release-upgrader-*/noble, /tmp/snap.rootfs_*/snap/zoom-client/*/zoom/zoom, /tmp/B1ServerTools.*/opt/sap/SAPBusinessOne/Common/*/bin/java, /nix/store/*, /var/lib/containers/storage/overlay/nix/store/*/bin/.hyprshot-wrappedexcludes:process.parent.executable
process.parent.namewildcardcheck_openvpnauthentication, python*, vmis-launcher, nessuscli, AppRun, ., .azotebgexcludes:process.parent.name

Memory Allocation from a High Entropy Module

#
Source
github.com/elastic/protections-artifacts

Identifies the load of a signed DLL followed by calling VirtualAlloc API to allocate writable and executable memory. This may indicate an attempt to perform code injection from a signed library.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the load of a signed DLL followed by calling VirtualAlloc API to allocate writable and executable memory.
This may indicate an attempt to perform code injection from a signed library.
"""
id = "8f9a6523-fa8f-46d1-b2de-72ef18e85f52"
license = "Elastic License v2"
name = "Memory Allocation from a High Entropy Module"
os_list = ["windows"]
version = "1.0.6"

query = '''
sequence
[file where event.type in ("creation", "change") and user.id != "S-1-5-18" and process.pid != 4 and
 file.Ext.header_bytes : "4d5a*" and file.Ext.entropy >= 6 and
 not file.path : ("?:\\Windows\\Installer\\*",
                  "?:\\Windows\\System32\\DriverStore\\FileRepository\\*",
                  "?:\\Windows\\SysWOW64\\DriverStore\\FileRepository\\*",
                  "?:\\Windows\\assembly\\*",
                  "?:\\Program Files\\*",
                  "?:\\Program Files (x86)\\*")] as event0
[api where
  process.Ext.api.name : ("VirtualAlloc*", "MapViewOfFile*") and process.Ext.api.parameters.protection == "RWX" and
  process.Ext.api.metadata.target_address_name == "Unbacked" and
  process.Ext.token.integrity_level_name in ("medium", "high") and
  process.thread.Ext.call_stack_final_user_module.hash.sha256 != null and
  _arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature, $entry, $entry.trusted == true and 
               not $entry.subject_name : ("College Board", "SEIKO EPSON CORPORATION", "EPADLINK", "Flexera Software, Inc. ", "Acresso Software Inc.", "Realtek Semiconductor Corp")) and
  stringcontains~(process.thread.Ext.call_stack_final_user_module.path, event0.file.path) and
  (
   endswith~(process.thread.Ext.call_stack_summary, concat("ntdll.dll|kernelbase.dll|", event0.file.name)) or
   endswith~(process.thread.Ext.call_stack_summary, concat("ntdll.dll|", event0.file.name))
   ) and
   not process.executable : ("?:\\Program Files\\*", "?:\\Program Files (x86)\\*") and
   not startswith~(process.thread.Ext.call_stack_final_user_module.name, process.name) and
   not (process.thread.Ext.call_stack_final_user_module.name in ("isrt.dll", "issetup.dll", "_isres.dll", "wow64.lmd") and
        process.thread.Ext.call_stack_summary in
                               ("ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|isrt.dll",
                                "ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|issetup.dll",
                                "ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|_isres.dll",
                                "ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|wow64.lmd")) and
   not (process.executable : "?:\\Windows\\SysWOW64\\msiexec.exe" and
        process.thread.Ext.call_stack_final_user_module.name like "msi*.tmp" and
        process.thread.Ext.call_stack_summary like "ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|msi*.tmp") and
   process.thread.Ext.call_stack_final_user_module.hash.sha256 != "b35e38071d8f32e1cfc51f7aa4c7f406461eb062123fd25ef746b3c75416c01a"
   ]
until [process where event.action == "end"]
'''

min_endpoint_version = "8.10.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"

[[threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"
[[threat.technique.subtechnique]]
id = "T1574.001"
name = "DLL"
reference = "https://attack.mitre.org/techniques/T1574/001/"



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

[internal]
min_endpoint_version = "8.10.0"

Stages and Predicates

Stage 1: file

[file where event.type in ("creation", "change") and user.id != "S-1-5-18" and process.pid != 4 and
 file.Ext.header_bytes : "4d5a*" and file.Ext.entropy >= 6 and
 not file.path : ("?:\\Windows\\Installer\\*",
                  "?:\\Windows\\System32\\DriverStore\\FileRepository\\*",
                  "?:\\Windows\\SysWOW64\\DriverStore\\FileRepository\\*",
                  "?:\\Windows\\assembly\\*",
                  "?:\\Program Files\\*",
                  "?:\\Program Files (x86)\\*")] as event0

Stage 2: api

[api where
  process.Ext.api.name : ("VirtualAlloc*", "MapViewOfFile*") and process.Ext.api.parameters.protection == "RWX" and
  process.Ext.api.metadata.target_address_name == "Unbacked" and
  process.Ext.token.integrity_level_name in ("medium", "high") and
  process.thread.Ext.call_stack_final_user_module.hash.sha256 != null and
  _arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature, $entry, $entry.trusted == true and 
               not $entry.subject_name : ("College Board", "SEIKO EPSON CORPORATION", "EPADLINK", "Flexera Software, Inc. ", "Acresso Software Inc.", "Realtek Semiconductor Corp")) and
  stringcontains~(process.thread.Ext.call_stack_final_user_module.path, event0.file.path) and
  (
   endswith~(process.thread.Ext.call_stack_summary, concat("ntdll.dll|kernelbase.dll|", event0.file.name)) or
   endswith~(process.thread.Ext.call_stack_summary, concat("ntdll.dll|", event0.file.name))
   ) and
   not process.executable : ("?:\\Program Files\\*", "?:\\Program Files (x86)\\*") and
   not startswith~(process.thread.Ext.call_stack_final_user_module.name, process.name) and
   not (process.thread.Ext.call_stack_final_user_module.name in ("isrt.dll", "issetup.dll", "_isres.dll", "wow64.lmd") and
        process.thread.Ext.call_stack_summary in
                               ("ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|isrt.dll",
                                "ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|issetup.dll",
                                "ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|_isres.dll",
                                "ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|wow64.lmd")) and
   not (process.executable : "?:\\Windows\\SysWOW64\\msiexec.exe" and
        process.thread.Ext.call_stack_final_user_module.name like "msi*.tmp" and
        process.thread.Ext.call_stack_summary like "ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|msi*.tmp") and
   process.thread.Ext.call_stack_final_user_module.hash.sha256 != "b35e38071d8f32e1cfc51f7aa4c7f406461eb062123fd25ef746b3c75416c01a"
   ]

Until: process

until [process where event.action == "end"]

Ends the sequence: the steps above must complete before an event matching this clause occurs.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • end corpus 13 (elastic 13)
field:"EventType" kind:eq value:"end"
event.typein
  • change corpus 18 (elastic 18)
  • creation corpus 17 (elastic 17)
field:"event.type" kind:in
file.Ext.entropyge
  • 6 transforms: number corpus 5 (elastic 5)
field:"file.Ext.entropy" kind:ge value:"6"
file.Ext.header_byteswildcard
  • 4d5a* corpus 45 (elastic 45)
field:"file.Ext.header_bytes" kind:wildcard value:"4d5a*"
process.Ext.api.metadata.target_address_nameeq
  • Unbacked corpus 8 (elastic 8)
field:"process.Ext.api.metadata.target_address_name" kind:eq value:"Unbacked"
process.Ext.api.namewildcard
  • MapViewOfFile* corpus 5 (elastic 5)
  • VirtualAlloc* corpus 4 (elastic 4)
field:"process.Ext.api.name" kind:wildcard
process.Ext.api.parameters.protectioneq
  • RWX corpus 8 (elastic 8)
field:"process.Ext.api.parameters.protection" kind:eq value:"RWX"
process.Ext.token.integrity_level_namein
  • high corpus 2 (elastic 2)
  • medium corpus 3 (elastic 3)
field:"process.Ext.token.integrity_level_name" kind:in
process.pidne
  • 4 transforms: number corpus 44 (elastic 44)
field:"process_id" kind:ne value:"4"
process.thread.Ext.call_stack_final_user_module.hash.sha256is_not_null
  • (no value, null check)
field:"process.thread.Ext.call_stack_final_user_module.hash.sha256" kind:is_not_null
process.thread.Ext.call_stack_final_user_module.hash.sha256ne
  • b35e38071d8f32e1cfc51f7aa4c7f406461eb062123fd25ef746b3c75416c01a
field:"process.thread.Ext.call_stack_final_user_module.hash.sha256" kind:ne value:"b35e38071d8f32e1cfc51f7aa4c7f406461eb062123fd25ef746b3c75416c01a"
process.thread.Ext.call_stack_final_user_module.pathcontains
  • event0.file.path (field reference)
field:"process.thread.Ext.call_stack_final_user_module.path" kind:contains value:"event0.file.path"
process.thread.Ext.call_stack_summaryends_with
  • concat("ntdll.dll|", event0.file.name) (expression)
  • concat("ntdll.dll|kernelbase.dll|", event0.file.name) (expression)
field:"process.thread.Ext.call_stack_summary" kind:ends_with
user.idne
  • S-1-5-18 corpus 37 (elastic 37)
field:"user.id" kind:ne value:"S-1-5-18"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
file.pathstarts_with?:\Windows\Installer\, ?:\Windows\System32\DriverStore\FileRepository\, ?:\Windows\SysWOW64\DriverStore\FileRepository\, ?:\Windows\assembly\, ?:\Program Files\, ?:\Program Files (x86)\excludes:file.path
process.executableeq?:\Windows\SysWOW64\msiexec.exeexcludes:process.executable field:"process.executable" value:"?:\Windows\SysWOW64\msiexec.exe"
process.thread.Ext.call_stack_final_user_module.namewildcardmsi*.tmpexcludes:process.thread.Ext.call_stack_final_user_module.name field:"process.thread.Ext.call_stack_final_user_module.name" value:"msi*.tmp"
process.thread.Ext.call_stack_summarywildcardntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|msi*.tmpexcludes:process.thread.Ext.call_stack_summary field:"process.thread.Ext.call_stack_summary" value:"ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|msi*.tmp"
process.thread.Ext.call_stack_final_user_module.namein_isres.dll, isrt.dll, issetup.dll, wow64.lmdexcludes:process.thread.Ext.call_stack_final_user_module.name
process.thread.Ext.call_stack_summaryinntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|_isres.dll, ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|isrt.dll, ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|issetup.dll, ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|wow64.lmdexcludes:process.thread.Ext.call_stack_summary
process.executablestarts_with?:\Program Files\, ?:\Program Files (x86)\excludes:process.executable field:"process.executable" value:"?:\Program Files\" field:"process.executable" value:"?:\Program Files (x86)\"
process.thread.Ext.call_stack_final_user_module.namestarts_withprocess.nameexcludes:process.thread.Ext.call_stack_final_user_module.name field:"process.thread.Ext.call_stack_final_user_module.name" value:"process.name"

MsBuild Making Network Connections

#
Status
production
Severity
medium
Time window
30s
Sequence by
process.entity_id
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies MsBuild.exe making outbound network connections. This may indicate adversarial activity as MsBuild is often leveraged by adversaries to execute code and evade detection.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2020/02/18"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/05/04"

[transform]
[[transform.osquery]]
label = "Osquery - Retrieve DNS Cache"
query = "SELECT * FROM dns_cache"

[[transform.osquery]]
label = "Osquery - Retrieve All Services"
query = "SELECT description, display_name, name, path, pid, service_type, start_type, status, user_account FROM services"

[[transform.osquery]]
label = "Osquery - Retrieve Services Running on User Accounts"
query = """
SELECT description, display_name, name, path, pid, service_type, start_type, status, user_account FROM services WHERE
NOT (user_account LIKE '%LocalSystem' OR user_account LIKE '%LocalService' OR user_account LIKE '%NetworkService' OR
user_account == null)
"""

[[transform.osquery]]
label = "Osquery - Retrieve Service Unsigned Executables with Virustotal Link"
query = """
SELECT concat('https://www.virustotal.com/gui/file/', sha1) AS VtLink, name, description, start_type, status, pid,
services.path FROM services JOIN authenticode ON services.path = authenticode.path OR services.module_path =
authenticode.path JOIN hash ON services.path = hash.path WHERE authenticode.result != 'trusted'
"""


[rule]
author = ["Elastic"]
description = """
Identifies MsBuild.exe making outbound network connections. This may indicate adversarial activity as MsBuild is often
leveraged by adversaries to execute code and evade detection.
"""
from = "now-9m"
index = ["logs-endpoint.events.process-*", "logs-endpoint.events.network-*"]
language = "eql"
license = "Elastic License v2"
name = "MsBuild Making Network Connections"
note = """## Triage and analysis

### Performance

The performance impact of this rule is expected to be low to medium because of the first sequence, which looks for MsBuild.exe process execution. The events for this first sequence may be noisy, consider adding exceptions.

### Investigating MsBuild Making Network Connections

By examining the specific traits of Windows binaries (such as process trees, command lines, network connections, registry modifications, and so on) it's possible to establish a baseline of normal activity. Deviations from this baseline can indicate malicious activity, such as masquerading and deserve further investigation.

The Microsoft Build Engine, also known as MSBuild, is a platform for building applications. This engine provides an XML schema for a project file that controls how the build platform processes and builds software, and can be abused to proxy code execution.

This rule looks for the `Msbuild.exe` utility execution, followed by a network connection to an external address. Attackers can abuse MsBuild to execute malicious files or masquerade as those utilities in order to bypass detections and evade defenses.

> **Note**:
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/current/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.

#### Possible investigation steps

- Investigate other alerts associated with the user/host during the past 48 hours.
- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.
  - Investigate any abnormal behavior by the subject process such as network connections, registry or file modifications, and any spawned child processes.
  - Investigate the file digital signature and process original filename, if suspicious, treat it as potential malware.
- Investigate the target host that the signed binary is communicating with.
  - Check if the domain is newly registered or unexpected.
  - Check the reputation of the domain or IP address.
- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.
- Examine the host for derived artifacts that indicate suspicious activities:
  - Analyze the process executable using a private sandboxed analysis system.
  - Observe and collect information about the following activities in both the sandbox and the alert subject host:
    - Attempts to contact external domains and addresses.
      - Use the Elastic Defend network events to determine domains and addresses contacted by the subject process by filtering by the process' `process.entity_id`.
      - Examine the DNS cache for suspicious or anomalous entries.
        - $osquery_0
    - Use the Elastic Defend registry events to examine registry keys accessed, modified, or created by the related processes in the process tree.
    - Examine the host services for suspicious or anomalous entries.
      - $osquery_1
      - $osquery_2
      - $osquery_3
  - Retrieve the files' SHA-256 hash values using the PowerShell `Get-FileHash` cmdlet and search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.

### False positive analysis

- If this activity is expected and noisy in your environment, consider adding exceptions — preferably with a combination of destination IP address and command line conditions.

### Response and remediation

- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- If the triage identified malware, search the environment for additional compromised hosts.
  - Implement temporary network rules, procedures, and segmentation to contain the malware.
  - Stop suspicious processes.
  - Immediately block the identified indicators of compromise (IoCs).
  - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that attackers could use to reinfect the system.
- Remove and block malicious artifacts identified during triage.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""

setup = """## Setup

This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.

Setup instructions: https://ela.st/install-elastic-defend
"""

references = ["https://riccardoancarani.github.io/2019-10-19-hunting-covenant-msbuild/"]
risk_score = 47
rule_id = "0e79980b-4250-4a50-a509-69294c14e84b"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Defense Evasion",
    "Resources: Investigation Guide",
    "Data Source: Elastic Defend",
]
type = "eql"

query = '''
sequence by process.entity_id with maxspan=30s

  /* Look for MSBuild.exe process execution */
  /* The events for this first sequence may be noisy, consider adding exceptions */
  [process where host.os.type == "windows" and event.type == "start" and
    (
      process.pe.original_file_name: "MSBuild.exe" or
      process.name: "MSBuild.exe"
    ) and
    not user.id == "S-1-5-18"]

  /* Followed by a network connection to an external address */
  /* Exclude domains that are known to be benign */
  [network where host.os.type == "windows" and
    event.action: ("connection_attempted", "lookup_requested") and
    not user.id == "S-1-5-18" and
    not cidrmatch(destination.ip, "127.0.0.1", "::1") and
    not dns.question.name : (
      "localhost",
      "dc.services.visualstudio.com",
      "vortex.data.microsoft.com",
      "api.nuget.org")]
'''


[[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 = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"

[rule.threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"

Stages and Predicates

Ordered sequence: each step below must occur in order within 30s, correlated by process.entity_id.

Stage 1: process

[process where host.os.type == "windows" and event.type == "start" and
    (
      process.pe.original_file_name: "MSBuild.exe" or
      process.name: "MSBuild.exe"
    ) and
    not user.id == "S-1-5-18"]

Stage 2: network

[network where host.os.type == "windows" and
    event.action: ("connection_attempted", "lookup_requested") and
    not user.id == "S-1-5-18" and
    not cidrmatch(destination.ip, "127.0.0.1", "::1") and
    not dns.question.name : (
      "localhost",
      "dc.services.visualstudio.com",
      "vortex.data.microsoft.com",
      "api.nuget.org")]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actionwildcard
  • connection_attempted corpus 3 (elastic 3)
  • lookup_requested corpus 3 (elastic 3)
field:"EventType" kind:wildcard
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.namewildcard
  • MSBuild.exe corpus 39 (elastic 36, splunk 3)
field:"process_basename" kind:wildcard value:"MSBuild.exe"
process.pe.original_file_namewildcard
  • MSBuild.exe corpus 16 (elastic 11, splunk 4, sigma 1)
field:"OriginalFileName" kind:wildcard value:"MSBuild.exe"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
user.ideqS-1-5-18excludes:user.id field:"user.id" value:"S-1-5-18"
destination.ipcidr_match127.0.0.1, ::1excludes:destination.ip field:"destination.ip" value:"127.0.0.1" field:"destination.ip" value:"::1"
dns.question.nameeqlocalhost, dc.services.visualstudio.com, vortex.data.microsoft.com, api.nuget.orgexcludes:dns.question.name

NTDLL Loaded from an Unusual Path

#
Source
github.com/elastic/protections-artifacts

Identifies when a process loads the Windows NTDLL image from an unusual path. This may be indicative of adversarial attempt to evade NTDLL syscall hooking by loading a clean (unhooked) copy of the same image.

MITRE ATT&CK Coverage

TacticTechniques
Stealth

Rule Body

[rule]
description = """
Identifies when a process loads the Windows NTDLL image from an unusual path. This may be indicative of adversarial
attempt to evade NTDLL syscall hooking by loading a clean (unhooked) copy of the same image.
"""
id = "3205274e-7eb0-4765-a712-5783361091ae"
license = "Elastic License v2"
name = "NTDLL Loaded from an Unusual Path"
os_list = ["windows"]
reference = [
    "https://www.elastic.co/security-labs/Hunting-for-Suspicious-Windows-Libraries-for-Execution-and-Evasion",
]
version = "1.0.39"

query = '''
library where dll.pe.original_file_name : "ntdll.dll" and
 dll.name != null and process.pid != 4 and process.executable != null and
 not dll.path : ("?:\\Windows\\SysWOW64\\ntdll.dll",
                 "?:\\Windows\\System32\\ntdll.dll",
                 "?:\\Windows\\System32\\ntdll.dll.???",
                 "?:\\Windows\\SyChpe32\\ntdll.dll",
                 "?:\\Windows\\WinSxS\\amd64_microsoft-windows-ntdll_*\\ntdll.dll",
                 "?:\\Windows\\WinSxS\\wow64_microsoft-windows-ntdll_*\\ntdll.dll",
                 "?:\\Windows\\WinSxS\\Temp\\InFlight\\*\\amd64_microsoft-windows-ntdll_*\\ntdll.dll",
                 "C:\\Windows\\SMSS-*.tmp",
                 "C:\\$Windows.~BT\\NewOS\\Windows\\SysWOW64\\ntdll.dll",
                 /* vsmbSharePrefix */
                 "\\Device\\vmsmb\\VSMB-{*}\\os\\windows\\*\\ntdll.dll",
                 "?:\\Windows\\WinSxS\\Temp\\PendingDeletes\\$$DeleteMe*",
                 "?:\\ProgramData\\Microsoft\\Windows\\Containers\\BaseImages\\*\\Files\\Windows\\System32\\ntdll.dll",
                 "?:\\Windows\\WinSxS\\Temp\\InFlight\\*\\ntdll.dll",
                 "?:\\$Windows.~BT\\NewOS\\Windows\\WinSxS\\amd64_microsoft-windows-ntdll_*\\ntdll.dll",
                 "C:\\ProgramData\\SecureWorks\\TaegisAgent\\{*}\\ntdll.x64.dll",
                 "C:\\$Windows.~BT\\NewOS\\Windows\\System32\\ntdll.dll") and
 not (process.code_signature.subject_name : ("INCA Internet Co.,Ltd.", "NEXON Korea Corporation.", "Acronis International GmbH", "Pearl abyss Corp") and
      process.code_signature.trusted == true) and
 not (process.executable : "C:\\Windows\\System32\\smss.exe" and dll.path : "?:\\ProgramData\\docker\\windowsfilter\\*\\Files\\Windows\\System32\\ntdll.dll")
'''

min_endpoint_version = "8.0.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"


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

[internal]
min_endpoint_version = "8.0.0"

Stages and Predicates

Stage 1: library

library where dll.pe.original_file_name : "ntdll.dll" and
 dll.name != null and process.pid != 4 and process.executable != null and
 not dll.path : ("?:\\Windows\\SysWOW64\\ntdll.dll",
                 "?:\\Windows\\System32\\ntdll.dll",
                 "?:\\Windows\\System32\\ntdll.dll.???",
                 "?:\\Windows\\SyChpe32\\ntdll.dll",
                 "?:\\Windows\\WinSxS\\amd64_microsoft-windows-ntdll_*\\ntdll.dll",
                 "?:\\Windows\\WinSxS\\wow64_microsoft-windows-ntdll_*\\ntdll.dll",
                 "?:\\Windows\\WinSxS\\Temp\\InFlight\\*\\amd64_microsoft-windows-ntdll_*\\ntdll.dll",
                 "C:\\Windows\\SMSS-*.tmp",
                 "C:\\$Windows.~BT\\NewOS\\Windows\\SysWOW64\\ntdll.dll",
                 "\\Device\\vmsmb\\VSMB-{*}\\os\\windows\\*\\ntdll.dll",
                 "?:\\Windows\\WinSxS\\Temp\\PendingDeletes\\$$DeleteMe*",
                 "?:\\ProgramData\\Microsoft\\Windows\\Containers\\BaseImages\\*\\Files\\Windows\\System32\\ntdll.dll",
                 "?:\\Windows\\WinSxS\\Temp\\InFlight\\*\\ntdll.dll",
                 "?:\\$Windows.~BT\\NewOS\\Windows\\WinSxS\\amd64_microsoft-windows-ntdll_*\\ntdll.dll",
                 "C:\\ProgramData\\SecureWorks\\TaegisAgent\\{*}\\ntdll.x64.dll",
                 "C:\\$Windows.~BT\\NewOS\\Windows\\System32\\ntdll.dll") and
 not (process.code_signature.subject_name : ("INCA Internet Co.,Ltd.", "NEXON Korea Corporation.", "Acronis International GmbH", "Pearl abyss Corp") and
      process.code_signature.trusted == true) and
 not (process.executable : "C:\\Windows\\System32\\smss.exe" and dll.path : "?:\\ProgramData\\docker\\windowsfilter\\*\\Files\\Windows\\System32\\ntdll.dll")

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
dll.pathwildcard?:\ProgramData\docker\windowsfilter\*\Files\Windows\System32\ntdll.dllexcludes:dll.path field:"dll.path" value:"?:\ProgramData\docker\windowsfilter\*\Files\Windows\System32\ntdll.dll"
process.executableeqC:\Windows\System32\smss.exeexcludes:process.executable field:"process.executable" value:"C:\Windows\System32\smss.exe"
process.code_signature.subject_nameeqINCA Internet Co.,Ltd., NEXON Korea Corporation., Acronis International GmbH, Pearl abyss Corpexcludes:process.code_signature.subject_name
process.code_signature.trustedeqtrueexcludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true"
dll.pathwildcard?:\Windows\SysWOW64\ntdll.dll, ?:\Windows\System32\ntdll.dll, ?:\Windows\System32\ntdll.dll.???, ?:\Windows\SyChpe32\ntdll.dll, ?:\Windows\WinSxS\amd64_microsoft-windows-ntdll_*\ntdll.dll, ?:\Windows\WinSxS\wow64_microsoft-windows-ntdll_*\ntdll.dll, ?:\Windows\WinSxS\Temp\InFlight\*\amd64_microsoft-windows-ntdll_*\ntdll.dll, C:\Windows\SMSS-*.tmp, C:\$Windows.~BT\NewOS\Windows\SysWOW64\ntdll.dll, \Device\vmsmb\VSMB-{*}\os\windows\*\ntdll.dll, ?:\Windows\WinSxS\Temp\PendingDeletes\$$DeleteMe*, ?:\ProgramData\Microsoft\Windows\Containers\BaseImages\*\Files\Windows\System32\ntdll.dll, ?:\Windows\WinSxS\Temp\InFlight\*\ntdll.dll, ?:\$Windows.~BT\NewOS\Windows\WinSxS\amd64_microsoft-windows-ntdll_*\ntdll.dll, C:\ProgramData\SecureWorks\TaegisAgent\{*}\ntdll.x64.dll, C:\$Windows.~BT\NewOS\Windows\System32\ntdll.dllexcludes:dll.path

Potential Data Exfiltration Activity to an Unusual ISO Code

#
Status
production
Severity
low
Author
Elastic
Source
github.com/elastic/detection-rules

A machine learning job has detected data exfiltration to a particular geo-location (by region name). Data transfers to geo-locations that are outside the normal traffic patterns of an organization could indicate exfiltration over command and control channels.

MITRE ATT&CK Coverage

TacticTechniques
Exfiltration

Rule Body

[metadata]
creation_date = "2023/09/22"
integration = ["ded", "endpoint", "network_traffic"]
maturity = "production"
updated_date = "2026/07/27"
min_stack_version = "9.4.0"
min_stack_comments = "Use EA (Entity Analytics) fields"

[rule]
anomaly_threshold = 75
author = ["Elastic"]
description = """
A machine learning job has detected data exfiltration to a particular geo-location (by region name). Data transfers to
geo-locations that are outside the normal traffic patterns of an organization could indicate exfiltration over command
and control channels.
"""
from = "now-6h"
interval = "15m"
license = "Elastic License v2"
machine_learning_job_id = "ded_high_sent_bytes_destination_geo_country_iso_code_ea"
name = "Potential Data Exfiltration Activity to an Unusual ISO Code"
references = [
    "https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html",
    "https://docs.elastic.co/en/integrations/ded",
    "https://www.elastic.co/blog/detect-data-exfiltration-activity-with-kibanas-new-integration",
]
risk_score = 21
rule_id = "e1db8899-97c1-4851-8993-3a3265353601"
setup = """## Setup

The rule requires the Data Exfiltration Detection integration assets to be installed, as well as network and file events collected by integrations such as Elastic Defend and Network Packet Capture (for network events only).

### Data Exfiltration Detection Setup
The Data Exfiltration Detection integration detects data exfiltration activity by identifying abnormalities in network and file events. Anomalies are detected using Elastic's Anomaly Detection feature.

#### Prerequisite Requirements:
- Fleet is required for Data Exfiltration Detection.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
- Network events collected by the [Elastic Defend](https://docs.elastic.co/en/integrations/endpoint) or [Network Packet Capture](https://docs.elastic.co/integrations/network_traffic) integration.
- To install Elastic Defend, refer to the [documentation](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
- To add the Network Packet Capture integration to an Elastic Agent policy, refer to [this](https://www.elastic.co/guide/en/fleet/current/add-integration-to-policy.html) guide.

#### The following steps should be executed to install assets associated with the Data Exfiltration Detection integration:
- Go to the Kibana homepage. Under Management, click Integrations.
- In the query bar, search for Data Exfiltration Detection and select the integration to see more details about it.
- Follow the instructions under the **Installation** section.
- For this rule to work, complete the instructions through **Add preconfigured anomaly detection jobs**.
"""
severity = "low"
tags = [
    "Data Source: Elastic Defend",
    "Data Source: Network Packet Capture",
    "Use Case: Data Exfiltration Detection",
    "Rule Type: ML",
    "Rule Type: Machine Learning",
    "Tactic: Exfiltration",
    "Resources: Investigation Guide",
]
type = "machine_learning"
note = """## Triage and analysis

> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

### Investigating Potential Data Exfiltration Activity to an Unusual ISO Code

Machine learning models analyze network traffic patterns to identify anomalies, such as data transfers to unexpected geo-locations. Adversaries exploit command and control channels to exfiltrate data to these unusual regions. The detection rule leverages ML to flag deviations from normal traffic, indicating potential exfiltration activities, thus aiding in early threat identification.

### Possible investigation steps

- Review the alert details to identify the specific unusual ISO code and geo-location involved in the data transfer.
- Analyze network logs to determine the volume and frequency of data transfers to the identified geo-location, comparing it against baseline traffic patterns.
- Investigate the source IP addresses and devices involved in the data transfer to assess whether they are legitimate or potentially compromised.
- Check for any recent changes or anomalies in user behavior or access patterns associated with the source devices or accounts.
- Correlate the alert with other security events or logs, such as authentication logs or endpoint detection alerts, to identify any related suspicious activities.
- Consult threat intelligence sources to determine if the unusual geo-location is associated with known malicious activities or threat actors.

### False positive analysis

- Legitimate business operations involving data transfers to new or infrequent geo-locations may trigger false positives. Users should review these activities and whitelist known safe destinations.
- Regularly scheduled data backups or transfers to international offices or cloud services can be mistaken for exfiltration. Implement exceptions for these routine operations by updating the model's baseline.
- Temporary projects or collaborations with partners in unusual regions might cause alerts. Document these activities and adjust the detection parameters to accommodate such temporary changes.
- Changes in business operations, such as expansion into new markets, can alter normal traffic patterns. Update the model to reflect these changes to prevent unnecessary alerts.
- Use historical data to identify patterns of benign traffic to unusual regions and adjust the model's sensitivity to reduce false positives while maintaining security vigilance.

### Response and remediation

- Immediately isolate the affected systems from the network to prevent further data exfiltration.
- Conduct a thorough analysis of the network traffic logs to identify the source and destination of the unusual data transfer, focusing on the specific geo-location flagged by the alert.
- Block the identified IP addresses or domains associated with the unusual ISO code in the organization's firewall and intrusion prevention systems.
- Review and update access controls and permissions to ensure that only authorized personnel have access to sensitive data, reducing the risk of unauthorized data transfers.
- Restore any compromised systems from clean backups, ensuring that all security patches and updates are applied before reconnecting to the network.
- Escalate the incident to the organization's security operations center (SOC) or incident response team for further investigation and to determine if additional systems or data were affected.
- Implement enhanced monitoring and alerting for similar anomalies in network traffic to improve early detection of potential exfiltration activities in the future."""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1041"
name = "Exfiltration Over C2 Channel"
reference = "https://attack.mitre.org/techniques/T1041/"


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

Potential Executable Stored in the Registry

#
Source
github.com/elastic/protections-artifacts

Identifies registry write modifications to hide an encoded portable executable. This could be indicative of adversary defense evasion by avoiding the storing of malicious content directly on disk.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies registry write modifications to hide an encoded portable executable. This could be indicative of adversary
defense evasion by avoiding the storing of malicious content directly on disk.
"""
id = "38386f44-1e2b-4c03-9d3b-d3bc63482616"
license = "Elastic License v2"
name = "Potential Executable Stored in the Registry"
os_list = ["windows"]
version = "1.0.24"

query = '''
registry where registry.data.strings : ("TVqQ*", "4d5a90000*") and not length(registry.data.strings) <= 100 and process.executable != null and
not (process.executable : "?:\\Program Files (x86)\\Schneider Electric\\Software Update\\SoftwareUpdate.exe" and registry.value : "FusTMP") and
not (process.executable : "C:\\Windows\\System32\\taskhostw.exe" and
     registry.path == "HKLM\\SYSTEM\\ControlSet001\\Services\\UCPD\\DR\\0000" and user.id == "S-1-5-18") and
not process.executable : "C:\\Program Files\\Tenable\\Nessus Agent\\nessusd.exe"
'''

min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1027"
name = "Obfuscated Files or Information"
reference = "https://attack.mitre.org/techniques/T1027/"

[[threat.technique]]
id = "T1112"
name = "Modify Registry"
reference = "https://attack.mitre.org/techniques/T1112/"


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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Stage 1: registry

registry where registry.data.strings : ("TVqQ*", "4d5a90000*") and not length(registry.data.strings) <= 100 and process.executable != null and
not (process.executable : "?:\\Program Files (x86)\\Schneider Electric\\Software Update\\SoftwareUpdate.exe" and registry.value : "FusTMP") and
not (process.executable : "C:\\Windows\\System32\\taskhostw.exe" and
     registry.path == "HKLM\\SYSTEM\\ControlSet001\\Services\\UCPD\\DR\\0000" and user.id == "S-1-5-18") and
not process.executable : "C:\\Program Files\\Tenable\\Nessus Agent\\nessusd.exe"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
process.executableis_not_null
  • (no value, null check)
field:"Image" kind:is_not_null
registry.data.stringswildcard
  • 4d5a90000*
  • TVqQ*
field:"Details" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

Potential Execution via ZIPExec

#
Time window
5m
Sequence by
process.entity_id, process.parent.entity_id
Source
github.com/elastic/protections-artifacts

Identifies the execution of file dropped via a compressed file (potentially password protected). This may indicate an attempt to bypass disk-based or anti-malware scanning mechanisms.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the execution of file dropped via a compressed file (potentially password protected). This may indicate an
attempt to bypass disk-based or anti-malware scanning mechanisms.
"""
id = "8eb74917-9363-4073-a09b-c47101f52c40"
license = "Elastic License v2"
name = "Potential Execution via ZIPExec"
os_list = ["windows"]
reference = ["https://github.com/Tylous/ZipExec"]
version = "1.0.28"

query = '''
sequence with maxspan=5m

  /* cmdkey invoking Windows Shell to open a compressed file */
 [process where event.action == "start" and
   process.pe.original_file_name : "cmdkey.exe" and
   process.command_line : "*Microsoft_Windows_Shell*Folder*filename*"] by process.parent.entity_id

 /* executable file creation by parent of cmdkey*/
 [file where event.action == "creation" and file.Ext.header_bytes : "4d5a*"] by process.entity_id

 /* execution from Explorer temp decompression directory by parent of cmdkey */
 [process where event.action == "start" and process.command_line : "*\\Temp\\Temp?_*"] by process.parent.entity_id
'''

min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 2

[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 2

[[optional_actions]]
action = "rollback"
field = "process.parent.entity_id"
state = 2

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.005"
name = "Visual Basic"
reference = "https://attack.mitre.org/techniques/T1059/005/"

[[threat.technique.subtechnique]]
id = "T1059.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"



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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

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

Stage 1: process

[process where event.action == "start" and
   process.pe.original_file_name : "cmdkey.exe" and
   process.command_line : "*Microsoft_Windows_Shell*Folder*filename*"] by process.parent.entity_id

Stage 2: file

[file where event.action == "creation" and file.Ext.header_bytes : "4d5a*"] by process.entity_id

Stage 3: process

[process where event.action == "start" and process.command_line : "*\\Temp\\Temp?_*"] by process.parent.entity_id

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • creation corpus 50 (elastic 50)
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq
file.Ext.header_byteswildcard
  • 4d5a* corpus 45 (elastic 45)
field:"file.Ext.header_bytes" kind:wildcard value:"4d5a*"
process.command_linewildcard
  • *Microsoft_Windows_Shell*Folder*filename*
  • *\Temp\Temp?_*
field:"CommandLine" kind:wildcard
process.pe.original_file_namewildcard
  • cmdkey.exe corpus 6 (splunk 3, sigma 2, elastic 1)
field:"OriginalFileName" kind:wildcard value:"cmdkey.exe"

Potential HawkEyes Stealer Infection

#
Source
github.com/elastic/protections-artifacts

Identifies the use of a browser to perform browser or internet location discovery from an unusual process. HawKEyes infostealer performs this action to assess potential targets.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the use of a browser to perform browser or internet location discovery from an unusual process. HawKEyes
infostealer performs this action to assess potential targets.
"""
id = "583448c6-986f-412b-8947-e3895bfc9426"
license = "Elastic License v2"
name = "Potential HawkEyes Stealer Infection"
os_list = ["windows"]
reference = ["https://malpedia.caad.fkie.fraunhofer.de/details/win.hawkeye_keylogger"]
version = "1.0.19"

query = '''
process where event.action == "start" and
 process.name : ("chrome.exe", "msedge.exe", "brave.exe", "browser.exe", "dragon.exe") and
 process.args : "--dump-dom" and process.args : "--headless" and process.args : "http*" and
 process.parent.executable != null and
 not process.parent.executable : 
                   ("?:\\Program Files\\*\\Endpoint Protection SDK\\endpointprotection.exe", 
                    "?:\\Program Files (x86)\\*\\Endpoint Protection SDK\\endpointprotection.exe",
                    "?:\\ProgramData\\CentraStage\\AEMAgent\\RMM.AdvancedThreatDetection\\dattoav\\Endpoint Protection SDK\\endpointprotection.exe")
'''

min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1016"
name = "System Network Configuration Discovery"
reference = "https://attack.mitre.org/techniques/T1016/"
[[threat.technique.subtechnique]]
id = "T1016.001"
name = "Internet Connection Discovery"
reference = "https://attack.mitre.org/techniques/T1016/001/"



[threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Stage 1: process

process where event.action == "start" and
 process.name : ("chrome.exe", "msedge.exe", "brave.exe", "browser.exe", "dragon.exe") and
 process.args : "--dump-dom" and process.args : "--headless" and process.args : "http*" and
 process.parent.executable != null and
 not process.parent.executable : 
                   ("?:\\Program Files\\*\\Endpoint Protection SDK\\endpointprotection.exe", 
                    "?:\\Program Files (x86)\\*\\Endpoint Protection SDK\\endpointprotection.exe",
                    "?:\\ProgramData\\CentraStage\\AEMAgent\\RMM.AdvancedThreatDetection\\dattoav\\Endpoint Protection SDK\\endpointprotection.exe")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq value:"start"
process.argswildcard
  • --dump-dom
  • --headless corpus 2 (elastic 2)
  • http* corpus 8 (elastic 8)
field:"process.args" kind:wildcard
process.namewildcard
  • brave.exe corpus 7 (elastic 7)
  • browser.exe corpus 7 (elastic 7)
  • chrome.exe corpus 16 (elastic 14, splunk 2)
  • dragon.exe corpus 7 (elastic 7)
  • msedge.exe corpus 12 (elastic 12)
field:"process_basename" kind:wildcard
process.parent.executableis_not_null
  • (no value, null check)
field:"ParentImage" kind:is_not_null

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.parent.executablewildcard?:\Program Files\*\Endpoint Protection SDK\endpointprotection.exe, ?:\Program Files (x86)\*\Endpoint Protection SDK\endpointprotection.exe, ?:\ProgramData\CentraStage\AEMAgent\RMM.AdvancedThreatDetection\dattoav\Endpoint Protection SDK\endpointprotection.exeexcludes:process.parent.executable field:"process.parent.executable" value:"?:\Program Files\*\Endpoint Protection SDK\endpointprotection.exe" field:"process.parent.executable" value:"?:\Program Files (x86)\*\Endpoint Protection SDK\endpointprotection.exe" field:"process.parent.executable" value:"?:\ProgramData\CentraStage\AEMAgent\RMM.AdvancedThreatDetection\dattoav\Endpoint Protection SDK\endpointprotection.exe"

Potential Linux Backdoor User Account Creation

#
Status
production
Severity
high
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies the attempt to create a new backdoor user by setting the user's UID to 0. Attackers may alter a user's UID to 0 to establish persistence on a system.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2023/03/07"
integration = ["endpoint", "auditd_manager", "crowdstrike", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2026/03/24"

[transform]
[[transform.osquery]]
label = "Osquery - Retrieve User Accounts with a UID of 0"
query = """
SELECT description, gid, gid_signed, shell, uid, uid_signed, username FROM users WHERE username != 'root' AND uid LIKE
'0'
"""

[[transform.osquery]]
label = "Osquery - Retrieve Running Processes by User"
query = "SELECT pid, username, name FROM processes p JOIN users u ON u.uid = p.uid ORDER BY username"

[[transform.osquery]]
label = "Osquery - Retrieve Information for a Specific User"
query = "SELECT * FROM users WHERE username = {{user.name}}"

[[transform.osquery]]
label = "Osquery - Investigate the Account Authentication Status"
query = "SELECT * FROM logged_in_users WHERE user = {{user.name}}"

[[transform.osquery]]
label = "Osquery - Retrieve Information for a Specific Group"
query = "SELECT * FROM groups WHERE groupname = {{group.name}}"

[rule]
author = ["Elastic"]
description = """
Identifies the attempt to create a new backdoor user by setting the user's UID to 0. Attackers may alter a user's UID to
0 to establish persistence on a system.
"""
from = "now-9m"
index = [
    "auditbeat-*",
    "endgame-*",
    "logs-auditd_manager.auditd-*",
    "logs-crowdstrike.fdr*",
    "logs-endpoint.events.process*",
    "logs-sentinel_one_cloud_funnel.*",
]
language = "eql"
license = "Elastic License v2"
name = "Potential Linux Backdoor User Account Creation"
note = """## Triage and analysis

### Investigating Potential Linux Backdoor User Account Creation

The `usermod` command is used to modify user account attributes and settings in Linux-based operating systems.

Attackers may create new accounts with a UID of 0 to maintain root access to target systems without leveraging the root user account.

This rule identifies the usage of the `usermod` command to set a user's UID to 0, indicating that the user becomes a root account. 

> **Note**:
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/current/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.
> This investigation guide uses [placeholder fields](https://www.elastic.co/guide/en/security/current/osquery-placeholder-fields.html) to dynamically pass alert data into Osquery queries. Placeholder fields were introduced in Elastic Stack version 8.7.0. If you're using Elastic Stack version 8.6.0 or earlier, you'll need to manually adjust this investigation guide's queries to ensure they properly run.

#### Possible investigation steps
- Investigate the user account that got assigned a uid of 0, and analyze its corresponding attributes.
  - $osquery_0
- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence and whether they are located in expected locations.
  - $osquery_1
- Identify the user account that performed the action, analyze it, and check whether it should perform this kind of action.
  - $osquery_2
- Investigate whether the user is currently logged in and active.
  - $osquery_3
- Identify if the account was added to privileged groups or assigned special privileges after creation.
  - $osquery_4
- Investigate other alerts associated with the user/host during the past 48 hours.

### False positive analysis

- This activity is unlikely to happen legitimately. Any activity that triggered the alert and is not inherently malicious must be monitored by the security team.

### Response and remediation

- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- If the triage identified malware, search the environment for additional compromised hosts.
  - Implement temporary network rules, procedures, and segmentation to contain the malware.
  - Stop suspicious processes.
  - Immediately block the identified indicators of compromise (IoCs).
  - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that attackers could use to reinfect the system.
- Remove and block malicious artifacts identified during triage.
- Review the privileges assigned to the involved users to ensure that the least privilege principle is being followed.
- Delete the created account.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Leverage the incident response data and logging to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
references = ["https://www.elastic.co/security-labs/primer-on-persistence-mechanisms"]
risk_score = 73
rule_id = "494ebba4-ecb7-4be4-8c6f-654c686549ad"
setup = """## Setup

This rule requires data coming in from Elastic Defend.

### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.

#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).

#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Persistence",
    "Data Source: Elastic Endgame",
    "Resources: Investigation Guide",
    "Data Source: Elastic Defend",
    "Data Source: Auditd Manager",
    "Data Source: Crowdstrike",
    "Data Source: SentinelOne",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "linux" and event.type == "start" and
event.action in ("exec", "exec_event", "start", "ProcessRollup2", "executed", "process_started") and
process.name == "usermod" and process.args in ("-u", "--uid") and process.args == "0" and
process.args in ("-o", "--non-unique")
'''

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

[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"

[[rule.threat.technique]]
id = "T1136"
name = "Create Account"
reference = "https://attack.mitre.org/techniques/T1136/"

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

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

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

[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"

[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"

Stages and Predicates

Stage 1: process

process where host.os.type == "linux" and event.type == "start" and
event.action in ("exec", "exec_event", "start", "ProcessRollup2", "executed", "process_started") and
process.name == "usermod" and process.args in ("-u", "--uid") and process.args == "0" and
process.args in ("-o", "--non-unique")

Indicators

These rows show field, operator, and value matches.

Potential Linux Credential Dumping via Unshadow

#
Source
github.com/elastic/protections-artifacts

Identifies the execution of the unshadow utility which is part of John the Ripper, a password-cracking tool on the host machine. Malicious actors can use the utility to retrieve the combined contents of the '/etc/shadow' and '/etc/password' files. Using the combined file generated from the utility, the malicious threat actors can use them as input for password-cracking utilities or prepare themselves for future operations by gathering credential information of the victim.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the execution of the unshadow utility which is part of John the Ripper, a password-cracking tool on the host
machine. Malicious actors can use the utility to retrieve the combined contents of the '/etc/shadow' and '/etc/password'
files. Using the combined file generated from the utility, the malicious threat actors can use them as input for
password-cracking utilities or prepare themselves for future operations by gathering credential information of the
victim.
"""
id = "05f95917-6942-4aab-a904-37c6db906503"
license = "Elastic License v2"
name = "Potential Linux Credential Dumping via Unshadow"
os_list = ["linux"]
reference = ["https://www.cyberciti.biz/faq/unix-linux-password-cracking-john-the-ripper/"]
version = "1.0.10"

query = '''
process where event.type == "start" and event.action == "exec" and
process.name == "unshadow" and process.args_count >= 2
'''

min_endpoint_version = "8.5.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true

[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
tree = true

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1003"
name = "OS Credential Dumping"
reference = "https://attack.mitre.org/techniques/T1003/"
[[threat.technique.subtechnique]]
id = "T1003.008"
name = "/etc/passwd and /etc/shadow"
reference = "https://attack.mitre.org/techniques/T1003/008/"



[threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"

[internal]
min_endpoint_version = "8.5.0"

Stages and Predicates

Stage 1: process

process where event.type == "start" and event.action == "exec" and
process.name == "unshadow" and process.args_count >= 2

Indicators

These rows show field, operator, and value matches.

Potential PowerShell Obfuscation via String Concatenation

#
Status
production
Severity
high
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Detects PowerShell scripts that repeatedly concatenate multiple quoted string literals with + to assemble commands or tokens at runtime. Attackers use string concatenation to fragment keywords or URLs and evade static analysis and AMSI.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2025/04/14"
integration = ["windows"]
maturity = "production"
updated_date = "2026/04/30"

[rule]
author = ["Elastic"]
description = """
Detects PowerShell scripts that repeatedly concatenate multiple quoted string literals with + to assemble commands
or tokens at runtime. Attackers use string concatenation to fragment keywords or URLs and evade static analysis
and AMSI.
"""
from = "now-9m"
language = "esql"
license = "Elastic License v2"
name = "Potential PowerShell Obfuscation via String Concatenation"
risk_score = 73
rule_id = "f6d8c743-0916-4483-8333-3c6f107e0caa"
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Defense Evasion",
    "Data Source: PowerShell Logs",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"

query = '''
from logs-windows.powershell_operational* metadata _id, _version, _index
| where event.code == "4104"

// Filter out smaller scripts that are unlikely to implement obfuscation using the patterns we are looking for
| eval Esql.script_block_length = length(powershell.file.script_block_text)
| where Esql.script_block_length > 500

// replace the patterns we are looking for with the 🔥 emoji to enable counting them
// The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1
| eval Esql.script_block_tmp = replace(
    powershell.file.script_block_text,
    """['"][A-Za-z0-9.]+['"](\s?\+\s?['"][A-Za-z0-9.,\-\s]+['"]){2,}""",
    "🔥"
)

// count how many patterns were detected by calculating the number of 🔥 characters inserted
| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "🔥", ""))

// keep the fields relevant to the query, although this is not needed as the alert is populated using _id
| keep
    Esql.script_block_pattern_count,
    Esql.script_block_length,
    Esql.script_block_tmp,
    powershell.file.*,
    file.path,
    powershell.sequence,
    powershell.total,
    _id,
    _version,
    _index,
    host.name,
    host.id,
    agent.id,
    user.id,
    process.pid

// Filter for scripts that match the pattern at least twice
| where Esql.script_block_pattern_count >= 2
'''

note = """## Triage and analysis

### Investigating Potential PowerShell Obfuscation via String Concatenation

#### Possible investigation steps

- What does the alert-local summary show about the concatenation pattern and where it appears in the preserved script block?
  - Focus: alert-local `Esql.script_block_pattern_count`, `Esql.script_block_length`, `Esql.script_block_tmp`, and `powershell.file.script_block_text`.
  - Implication: escalate sooner when repeated matches sit near execution, download, decode, or persistence logic; lower suspicion when they resolve to inert configuration or output text, but do not close until the full script block and origin are checked.
- Is the full script block reconstructed before interpretation?
  - Focus: source 4104 events in logs-windows.powershell_operational* for `host.id` and `powershell.file.script_block_id`, ordered by `powershell.sequence` against `powershell.total`. $investigate_2
  - Implication: escalate when fragments add hidden stages, payload material, or omitted execution context; missing sequence fragments are unresolved because omitted text may contain the decisive string use.
- What do the concatenated strings reconstruct to, and do they feed execution?
  - Focus: reconstructed `powershell.file.script_block_text`, quoted fragments around each match, and statistical cues from `powershell.file.script_block_entropy_bits` and `powershell.file.script_block_surprisal_stdev`.
  - Implication: escalate when strings reveal fragmented keywords, URLs or domains, paths, registry keys, encoded blobs, .NET reflection names, or decode inputs feeding invocation, download, file write, or persistence; lower suspicion when they remain inert data construction inside one stable script pattern.
- Does the source event and origin context explain who ran the script and from where?
  - Focus: recovered `file.path`, `user.id`, and `host.id`, plus whether `file.path` is absent.
  - Hint: absent `file.path` after source-event recovery reduces origin provenance because the script may be interactive, pasted, or memory-only; require stronger corroboration before benign closure.
  - Implication: escalate when execution is fileless or from temp, downloads, profiles, mounted shares, or other user-writable locations under an unexpected identity; lower suspicion only when origin, user, host, and string use match one recognized automation or build workflow.
- If endpoint process telemetry is available, does launch context support benign automation or abuse?
  - Focus: recover `process.pid` from the 4104 event, then match `host.id` and the alert window in endpoint process-start events for `process.entity_id`, `process.command_line`, and `process.parent.executable`. $investigate_3
  - Hint: anchor process starts to `@timestamp`; if PID reuse creates multiple or distant matches, keep launch context unresolved. Without endpoint process telemetry, bound downstream checks to `host.id`, `user.id` or `user.name`, and the alert window; missing launch telemetry is unresolved, not benign.
  - Implication: escalate when PowerShell starts from Office, a browser, an archive extractor, a LOLBin, a remote context, or a service context with encoded or fileless delivery; lower suspicion when the launch chain and command line match the same recognized automation workflow.
- Did the recovered process or host-window activity retrieve, stage, or execute follow-on content?
  - Focus: child process starts from the PowerShell PID and file, network, or DNS events for the same PID. $investigate_4 $investigate_5
  - Hint: if PID recovery failed in the prior step, scope follow-on review manually with `host.id`, `user.id`, and a tight alert window; that fallback is broader, so prioritize timestamps and script-linked paths or destinations. Missing file or network telemetry is unresolved, not benign.
  - Implication: escalate when scoped activity spawns shells, writes scripts or binaries, reaches rare destinations, or stages persistence; lower suspicion when telemetry shows no effects outside the same recognized script workflow.
- If local findings remain suspicious or unresolved, is this part of broader obfuscated PowerShell activity?
  - Focus: related alerts for `user.id` in the last 48 hours to test whether this obfuscation follows the actor. $investigate_0
  - Hint: if the user view is sparse or shared, pivot to `host.id` related alerts in the last 48 hours to test whether obfuscated PowerShell, encoded command, download, or persistence alerts stay localized to the asset. $investigate_1
  - Implication: escalate scope when the same user or host shows repeated obfuscated PowerShell or adjacent suspicious behavior; keep scope local when the alert is isolated and local evidence resolves to one recognized workflow.
- Based on script reconstruction, string use, origin, launch context, effects, and broader scope, what disposition is supported?
  - Escalate on string use supporting hidden execution, download, payload handling, persistence, or unresolved high-risk fragments. Close only when reconstruction, origin, launch/effects if available, and related-alert scope bind the alert to one exact recognized workflow; with mixed or incomplete evidence, preserve artifacts and escalate.

### False positive analysis

- Internal templating, packaging, or configuration-generation scripts may concatenate many string literals to build arguments, paths, or output text. Confirm recovered `powershell.file.script_block_text`, reconstructed string family, `file.path`, `user.id` plus `host.id` scope, and any launch context align with one recognized repository, build, deployment, or administrative workflow. Without repository or change context, do not rely on recurrence alone; close only when local telemetry proves the exact benign workflow.
- Compatibility wrappers or vendor-protected administrative scripts may fragment helper names, module paths, or destination strings at runtime. Confirm reconstructed strings map to recognized internal domains, script paths, module functions, or vendor helpers and side effects stay inside that workflow. Without vendor notes or admin records, do not rely on recurrence alone; close only when local telemetry proves the exact helper workflow.
- Before creating an exception, anchor it on stable `file.path`, reconstructed string family, `host.id` or `user.id`, and recovered launch context when available. Avoid exceptions on alert-local `Esql.script_block_pattern_count`, `Esql.script_block_length`, `Esql.script_block_tmp`, `user.name`, or `powershell.file.script_block_text` alone.

### Response and remediation

- If confirmed benign, record the evidence that proved the workflow: reconstructed strings, recovered `file.path`, user-host scope, launch context when available, and lack of contradictory side effects. Then reverse temporary containment. Create an exception only when that evidence pattern is narrow enough to avoid suppressing lookalike obfuscation; recurrence strengthens the case but is not required when local proof is complete.
- If suspicious but unconfirmed, preserve the alert record, source 4104 events, full `powershell.file.script_block_text`, `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`, reconstructed strings, `file.path`, `host.id`, `user.id`, and any recovered process, file, DNS, or destination artifacts before containment or cleanup.
- If suspicious but unconfirmed, apply reversible containment tied to the findings, such as heightened monitoring, outbound restrictions, or temporary PowerShell controls on the affected host or account. Escalate to host isolation only when launch context or follow-on activity indicates likely payload execution or spread.
- If confirmed malicious, record recovered process identifiers, command lines, parent context, script fragments, reconstructed strings, staged files, and destination indicators before isolation, process termination, or suspension. Then isolate the endpoint when host role allows and restrict the affected account if identity misuse is evident.
- Review related hosts and users for the same reconstructed string family, `file.path`, origin pattern, and destination indicators before removing artifacts so scoping completes before evidence is destroyed.
- Remove only the unauthorized scripts, dropped payloads, and persistence artifacts identified during the investigation, then remediate the delivery path or administrative-control gap that allowed the obfuscated PowerShell execution.
- Post-incident hardening: retain Script Block Logging and endpoint telemetry that enabled reconstruction, restrict PowerShell where it is not required, and record any telemetry gaps that limited reconstruction or containment."""

setup = """## Setup

PowerShell Script Block Logging must be enabled to generate the events used by this rule (e.g., 4104).
Setup instructions: https://ela.st/powershell-logging-setup
"""

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "host.name",
    "host.id",
    "user.id",
    "file.path",
    "process.pid",
    "powershell.file.script_block_text",
    "powershell.file.script_block_id",
    "powershell.sequence",
    "powershell.total",
    "powershell.file.script_block_entropy_bits",
    "powershell.file.script_block_surprisal_stdev",
    "Esql.script_block_length",
    "Esql.script_block_pattern_count"
]

[transform]

[[transform.investigate]]
label = "Alerts associated with the user"
description = ""
providers = [
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
  ]
]
relativeFrom = "now-48h/h"
relativeTo = "now"

[[transform.investigate]]
label = "Alerts associated with the host"
description = ""
providers = [
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
  ]
]
relativeFrom = "now-48h/h"
relativeTo = "now"

[[transform.investigate]]
label = "Script block fragments for the same script"
description = ""
providers = [
  [
    { excluded = false, field = "powershell.file.script_block_id", queryType = "phrase", value = "{{powershell.file.script_block_id}}", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

[[transform.investigate]]
label = "Process start events for the PowerShell PID"
description = ""
providers = [
  [
    { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

[[transform.investigate]]
label = "Child process activity from the PowerShell instance"
description = ""
providers = [
  [
    { excluded = false, field = "process.parent.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
    { excluded = false, field = "event.type", queryType = "phrase", value = "start", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

[[transform.investigate]]
label = "File, network, and DNS events for the PowerShell PID"
description = ""
providers = [
  [
    { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
  ],
  [
    { excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
  ],
  [
    { excluded = false, field = "event.category", queryType = "phrase", value = "dns", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

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

[[rule.threat.technique]]
id = "T1027"
name = "Obfuscated Files or Information"
reference = "https://attack.mitre.org/techniques/T1027/"

[[rule.threat.technique.subtechnique]]
id = "T1027.010"
name = "Command Obfuscation"
reference = "https://attack.mitre.org/techniques/T1027/010/"

[[rule.threat.technique]]
id = "T1140"
name = "Deobfuscate/Decode Files or Information"
reference = "https://attack.mitre.org/techniques/T1140/"

[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.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"

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

Stages and Predicates

Stage 1: from

from logs-windows.powershell_operational* metadata _id, _version, _index

Stage 2: where

| where event.code == "4104"

Stage 3: eval

| eval Esql.script_block_length = length(powershell.file.script_block_text)

Stage 4: where

| where Esql.script_block_length > 500

Stage 5: eval

| eval Esql.script_block_tmp = replace(
    powershell.file.script_block_text,
    """['"][A-Za-z0-9.]+['"](\s?\+\s?['"][A-Za-z0-9.,\-\s]+['"]){2,}""",
    "🔥"
)

Stage 6: eval

| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "🔥", ""))

Stage 7: keep

| keep
    Esql.script_block_pattern_count,
    Esql.script_block_length,
    Esql.script_block_tmp,
    powershell.file.*,
    file.path,
    powershell.sequence,
    powershell.total,
    _id,
    _version,
    _index,
    host.name,
    host.id,
    agent.id,
    user.id,
    process.pid

Stage 8: where

| where Esql.script_block_pattern_count >= 2

Indicators

These rows show field, operator, and value matches.

Output Fields

These fields are emitted when the rule matches.

FieldSource
Esql.script_block_pattern_countKEEP Esql.script_block_pattern_count
Esql.script_block_lengthKEEP Esql.script_block_length
Esql.script_block_tmpKEEP Esql.script_block_tmp
powershell.file.*KEEP powershell.file.*
file.pathKEEP file.path
powershell.sequenceKEEP powershell.sequence
powershell.totalKEEP powershell.total
_idKEEP _id
_versionKEEP _version
_indexKEEP _index
host.nameKEEP host.name
host.idKEEP host.id
agent.idKEEP agent.id
user.idKEEP user.id
process.pidKEEP process.pid

Rare Connection to WebDAV Target

#
Status
production
Severity
medium
Time window
8h
Group by
Esql.server_webdav_server
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies rare connection attempts to a Web Distributed Authoring and Versioning (WebDAV) resource. Attackers may inject WebDAV paths in files or features opened by a victim user to leak their NTLM credentials via forced authentication.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2025/04/28"
integration = ["endpoint", "system", "windows", "m365_defender", "crowdstrike"]
maturity = "production"
updated_date = "2026/08/18"

[rule]
author = ["Elastic"]
description = """
Identifies rare connection attempts to a Web Distributed Authoring and Versioning (WebDAV) resource. Attackers may
inject WebDAV paths in files or features opened by a victim user to leak their NTLM credentials via forced
authentication.
"""
from = "now-8h"
interval="1h"
language = "esql"
license = "Elastic License v2"
name = "Rare Connection to WebDAV Target"
note = """## Triage and analysis

### Investigating Rare Connection to WebDAV Target

### Possible investigation steps

- Examine the reputation of the destination domain or IP address.
- Verify if the target user opened any attachments or clicked links pointing to the same target within seconds from the alert timestamp.
- Correlate the findings with other security logs and alerts to identify any patterns or additional indicators of compromise related to the potential relay attack.

### False positive analysis

- User accessing legit WebDAV resources.

### Response and remediation

- Conduct a password reset for the target account that may have been compromised or are at risk, ensuring the use of strong, unique passwords.
- Verify whether other users were targeted but did not open the lure..
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine the full scope of the breach.
- Conduct a post-incident review to identify any gaps in security controls and update policies or procedures to prevent recurrence, ensuring lessons learned are applied to improve overall security posture."""
references = ["https://attack.mitre.org/techniques/T1187/"]
risk_score = 47
rule_id = "6756ee27-9152-479b-9b73-54b5bbda301c"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Data Source: Elastic Defend",
    "Data Source: Windows Security Event Logs",
    "Data Source: Microsoft Defender XDR",
    "Data Source: Crowdstrike",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"

query = '''
from logs-endpoint.events.process-*, logs-windows.sysmon_operational-*, logs-system.security-*, logs-windows.*, winlogbeat-*, logs-crowdstrike.fdr*, logs-m365_defender.event-* METADATA _id, _version, _index
| where
    event.category == "process" and
    event.type == "start" and
    process.name == "rundll32.exe" and
    process.command_line like "*DavSetCookie*"
| keep host.id, process.command_line, user.name, user.id
// extract the host from the WebDAV URL authority, excluding optional credentials and port
| grok process.command_line """(?i:https?)://(?:[^/@\s]+@)?(?<Esql.server_webdav_server>[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*)"""
| eval Esql.server_webdav_server = TO_LOWER(Esql.server_webdav_server)
| where
    Esql.server_webdav_server is not null and
    not Esql.server_webdav_server in ("www.google.com", "www.elastic.co", "google.com", "github.com", "www.github.com", "sharepoint.com", "live.net") and
    not Esql.server_webdav_server like ("*.live.net", "*.sharepoint.com") and
    // excludes private IP ranges
    not Esql.server_webdav_server rlike """(10\.(\d{1,3}\.){2}\d{1,3}|172\.(1[6-9]|2\d|3[0-1])\.(\d{1,3}\.)\d{1,3}|192\.168\.(\d{1,3}\.)\d{1,3})"""
| stats
    Esql.event_count = count(*),
    Esql.host_id_count_distinct = count_distinct(host.id),
    Esql.host_id_values = values(host.id),
    Esql.user_name_values = values(user.name)
  by Esql.server_webdav_server
| where
    Esql.host_id_count_distinct == 1 and Esql.event_count <= 3
| eval host.id = MV_MIN(Esql.host_id_values), user.name = MV_MIN(Esql.user_name_values), destination.domain = MV_MIN(Esql.server_webdav_server)
| KEEP host.id, user.name, destination.domain, Esql.*
'''

setup = """## Setup

This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.

Setup instructions: https://ela.st/install-elastic-defend

### Additional data sources

This rule also supports the following third-party data sources. For setup instructions, refer to the links below:

- [CrowdStrike](https://ela.st/crowdstrike-integration)
- [Microsoft Defender XDR](https://ela.st/m365-defender)
- [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
- [Windows Process Creation Logs](https://ela.st/audit-process-creation)
"""


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

[[rule.threat.technique]]
id = "T1187"
name = "Forced Authentication"
reference = "https://attack.mitre.org/techniques/T1187/"

[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"

[[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.011"
name = "Rundll32"
reference = "https://attack.mitre.org/techniques/T1218/011/"

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

Stages and Predicates

Stage 1: from

from logs-endpoint.events.process-*, logs-windows.sysmon_operational-*, logs-system.security-*, logs-windows.*, winlogbeat-*, logs-crowdstrike.fdr*, logs-m365_defender.event-* METADATA _id, _version, _index

Stage 2: where

| where
    event.category == "process" and
    event.type == "start" and
    process.name == "rundll32.exe" and
    process.command_line like "*DavSetCookie*"

Stage 3: keep

| keep host.id, process.command_line, user.name, user.id

Stage 4: grok

| grok process.command_line """(?i:https?)://(?:[^/@\s]+@)?(?<Esql.server_webdav_server>[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*)"""

Stage 5: eval

| eval Esql.server_webdav_server = TO_LOWER(Esql.server_webdav_server)

Stage 6: where

| where
    Esql.server_webdav_server is not null and
    not Esql.server_webdav_server in ("www.google.com", "www.elastic.co", "google.com", "github.com", "www.github.com", "sharepoint.com", "live.net") and
    not Esql.server_webdav_server like ("*.live.net", "*.sharepoint.com") and
    not Esql.server_webdav_server rlike """(10\.(\d{1,3}\.){2}\d{1,3}|172\.(1[6-9]|2\d|3[0-1])\.(\d{1,3}\.)\d{1,3}|192\.168\.(\d{1,3}\.)\d{1,3})"""

Stage 7: stats

| stats
    Esql.event_count = count(*),
    Esql.host_id_count_distinct = count_distinct(host.id),
    Esql.host_id_values = values(host.id),
    Esql.user_name_values = values(user.name)
  by Esql.server_webdav_server

Stage 8: where

| where
    Esql.host_id_count_distinct == 1 and Esql.event_count <= 3

Stage 9: eval

| eval host.id = MV_MIN(Esql.host_id_values), user.name = MV_MIN(Esql.user_name_values), destination.domain = MV_MIN(Esql.server_webdav_server)

Stage 10: keep

| KEEP host.id, user.name, destination.domain, Esql.*

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
Esql.server_webdav_serverends_with.live.net, .sharepoint.comexcludes:Esql.server_webdav_server field:"Esql.server_webdav_server" value:".live.net" field:"Esql.server_webdav_server" value:".sharepoint.com"
Esql.server_webdav_serveringithub.com, google.com, live.net, sharepoint.com, www.elastic.co, www.github.com, www.google.comexcludes:Esql.server_webdav_server
Esql.server_webdav_serverregex_match(10.(\d{1,3}.){2}\d{1,3}|172.(1[6-9]|2\d|3[0-1]).(\d{1,3}.)\d{1,3}|192.168.(\d{1,3}.)\d{1,3})excludes:Esql.server_webdav_server field:"Esql.server_webdav_server" value:"(10.(\d{1,3}.){2}\d{1,3}|172.(1[6-9]|2\d|3[0-1]).(\d{1,3}.)\d{1,3}|192.168.(\d{1,3}.)\d{1,3})"

Output Fields

These fields are emitted when the rule matches.

FieldSource
host.idKEEP host.id
user.nameKEEP user.name
destination.domainKEEP destination.domain
Esql.*KEEP Esql.*

Scriptlet Proxy Execution via PubPrn

#
Source
github.com/elastic/protections-artifacts

Adversaries may use the trusted PubPrn script to proxy execution of malicious files. This behavior may bypass signature validation restrictions and application control solutions that do not account for use of these scripts.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Adversaries may use the trusted PubPrn script to proxy execution of malicious files. This behavior may bypass signature
validation restrictions and application control solutions that do not account for use of these scripts.
"""
id = "0d4454a7-c682-4085-995c-300973c5bdea"
license = "Elastic License v2"
name = "Scriptlet Proxy Execution via PubPrn"
os_list = ["windows"]
reference = ["https://lolbas-project.github.io/lolbas/Scripts/Pubprn/"]
version = "1.0.31"

query = '''
process where event.action == "start" and
 process.pe.original_file_name in ("cscript.exe", "wscript.exe") and process.args_count >= 4 and
 /* Issue 259 - additional rule strictness */
 process.command_line : ("*localhost*script:http*", "*127.0.0.*script:http*")
'''

min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.005"
name = "Visual Basic"
reference = "https://attack.mitre.org/techniques/T1059/005/"

[[threat.technique.subtechnique]]
id = "T1059.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"



[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1216"
name = "System Script Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1216/"
[[threat.technique.subtechnique]]
id = "T1216.001"
name = "PubPrn"
reference = "https://attack.mitre.org/techniques/T1216/001/"



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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Stage 1: process

process where event.action == "start" and
 process.pe.original_file_name in ("cscript.exe", "wscript.exe") and process.args_count >= 4 and
 process.command_line : ("*localhost*script:http*", "*127.0.0.*script:http*")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq value:"start"
process.args_countge
  • 4 transforms: number corpus 8 (elastic 8)
field:"process.args_count" kind:ge value:"4"
process.command_linewildcard
  • *127.0.0.*script:http*
  • *localhost*script:http*
field:"CommandLine" kind:wildcard
process.pe.original_file_namein
  • cscript.exe corpus 9 (elastic 9)
  • wscript.exe corpus 9 (elastic 9)
field:"OriginalFileName" kind:in

Service Installed by an Unusual Microsoft Signed Process

#
Source
github.com/elastic/protections-artifacts

Identifies the install of a new service by an unusual Microsoft signed program or an executable from a world user writable path. Adversaries may use this technique to maintain persistence or run with System privileges.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the install of a new service by an unusual Microsoft signed program or an executable from a world user
writable path. Adversaries may use this technique to maintain persistence or run with System privileges.
"""
id = "07f2c66e-46e3-4ce2-aca1-291172fc88fc"
license = "Elastic License v2"
name = "Service Installed by an Unusual Microsoft Signed Process"
os_list = ["windows"]
version = "1.0.3"

query = '''
any where event.category == "configuration" and event.action == "service_installed" and user.id != "S-1-5-18" and
  process.code_signature.subject_name == "Microsoft Windows" and
  not winlog.event_data.ServiceStartType in ("Manual", "Disabled") and
  not process.executable : ("?:\\Windows\\Sys?????\\sc.exe",
                             "C:\\Program Files (x86)\\Microsoft Visual Studio\\Installer\\setup.exe",
                             "C:\\Windows\\Microsoft.NET\\Framework\\v*\\InstallUtil.exe",
                             "C:\\Program Files\\Microsoft SQL Server\\*\\ScenarioEngine.exe",
                             "C:\\Windows\\System32\\wsmprovhost.exe",
                             "C:\\Windows\\Sys?????\\msiexec.exe",
                             "C:\\Program Files\\Microsoft\\AzureAttestService\\AzureAttestServiceInstaller.exe",
                             "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell_ise.exe",
                             "C:\\Program Files\\Common Files\\microsoft shared\\ClickToRun\\OfficeClickToRun.exe",
                             "C:\\Program Files\\Microsoft Office\\root\\Integration\\Addons\\OneDriveSetup.exe",
                             "C:\\Program Files (x86)\\AOMEI Cyber Backup\\x64\\InstallUtil.exe",
                             "C:\\Windows\\Microsoft.NET\\Framework64\\*\\InstallUtil.exe",
                             "C:\\Program Files (x86)\\AOMEI Cyber Backup\\x64\\iscsi\\InstallUtil.exe",
                             "C:\\Program Files (x86)\\Microsoft\\EdgeUpdate\\MicrosoftEdgeUpdate.exe") and
   not (process.parent.executable : ("C:\\Windows\\Sys?????\\msiexec.exe", "C:\\Program Files\\Wireshark\\USBPcapSetup-*.exe", "C:\\Program Files (x86)\\AOMEI Cyber Backup\\x64\\AOMEIImgService.exe") and
        process.executable : "?:\\Windows\\Sys?????\\rundll32.exe") and
   not process.parent.executable : ("F:\\setup.exe") and
   not process.command_line : ("\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" ",
                               "\"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -ExecutionPolicy UnRestricted -File *") and 
   not (process.executable : "?:\\Windows\\System32\\dllhost.exe" and
        process.command_line :  "C:\\Windows\\system32\\dllhost.exe /Processid:{02D4B3F1-FD88-11D1-960D-00805FC79235}" and
        process.parent.executable : "C:\\Windows\\System32\\services.exe")
'''

min_endpoint_version = "9.0.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"
[[threat.technique.subtechnique]]
id = "T1543.003"
name = "Windows Service"
reference = "https://attack.mitre.org/techniques/T1543/003/"



[threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"

[internal]
min_endpoint_version = "9.0.0"

Stages and Predicates

Stage 1: any

any where event.category == "configuration" and event.action == "service_installed" and user.id != "S-1-5-18" and
  process.code_signature.subject_name == "Microsoft Windows" and
  not winlog.event_data.ServiceStartType in ("Manual", "Disabled") and
  not process.executable : ("?:\\Windows\\Sys?????\\sc.exe",
                             "C:\\Program Files (x86)\\Microsoft Visual Studio\\Installer\\setup.exe",
                             "C:\\Windows\\Microsoft.NET\\Framework\\v*\\InstallUtil.exe",
                             "C:\\Program Files\\Microsoft SQL Server\\*\\ScenarioEngine.exe",
                             "C:\\Windows\\System32\\wsmprovhost.exe",
                             "C:\\Windows\\Sys?????\\msiexec.exe",
                             "C:\\Program Files\\Microsoft\\AzureAttestService\\AzureAttestServiceInstaller.exe",
                             "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell_ise.exe",
                             "C:\\Program Files\\Common Files\\microsoft shared\\ClickToRun\\OfficeClickToRun.exe",
                             "C:\\Program Files\\Microsoft Office\\root\\Integration\\Addons\\OneDriveSetup.exe",
                             "C:\\Program Files (x86)\\AOMEI Cyber Backup\\x64\\InstallUtil.exe",
                             "C:\\Windows\\Microsoft.NET\\Framework64\\*\\InstallUtil.exe",
                             "C:\\Program Files (x86)\\AOMEI Cyber Backup\\x64\\iscsi\\InstallUtil.exe",
                             "C:\\Program Files (x86)\\Microsoft\\EdgeUpdate\\MicrosoftEdgeUpdate.exe") and
   not (process.parent.executable : ("C:\\Windows\\Sys?????\\msiexec.exe", "C:\\Program Files\\Wireshark\\USBPcapSetup-*.exe", "C:\\Program Files (x86)\\AOMEI Cyber Backup\\x64\\AOMEIImgService.exe") and
        process.executable : "?:\\Windows\\Sys?????\\rundll32.exe") and
   not process.parent.executable : ("F:\\setup.exe") and
   not process.command_line : ("\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" ",
                               "\"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -ExecutionPolicy UnRestricted -File *") and 
   not (process.executable : "?:\\Windows\\System32\\dllhost.exe" and
        process.command_line :  "C:\\Windows\\system32\\dllhost.exe /Processid:{02D4B3F1-FD88-11D1-960D-00805FC79235}" and
        process.parent.executable : "C:\\Windows\\System32\\services.exe")

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.command_lineeqC:\Windows\system32\dllhost.exe /Processid:{02D4B3F1-FD88-11D1-960D-00805FC79235}excludes:process.command_line field:"process.command_line" value:"C:\Windows\system32\dllhost.exe /Processid:{02D4B3F1-FD88-11D1-960D-00805FC79235}"
process.executableeq?:\Windows\System32\dllhost.exeexcludes:process.executable field:"process.executable" value:"?:\Windows\System32\dllhost.exe"
process.parent.executableeqC:\Windows\System32\services.exeexcludes:process.parent.executable field:"process.parent.executable" value:"C:\Windows\System32\services.exe"
process.executableeq?:\Windows\Sys?????\rundll32.exeexcludes:process.executable field:"process.executable" value:"?:\Windows\Sys?????\rundll32.exe"
process.parent.executablewildcardC:\Windows\Sys?????\msiexec.exe, C:\Program Files\Wireshark\USBPcapSetup-*.exe, C:\Program Files (x86)\AOMEI Cyber Backup\x64\AOMEIImgService.exeexcludes:process.parent.executable field:"process.parent.executable" value:"C:\Windows\Sys?????\msiexec.exe" field:"process.parent.executable" value:"C:\Program Files\Wireshark\USBPcapSetup-*.exe" field:"process.parent.executable" value:"C:\Program Files (x86)\AOMEI Cyber Backup\x64\AOMEIImgService.exe"
process.command_linewildcard"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" , "C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy UnRestricted -File *excludes:process.command_line
process.executablewildcard?:\Windows\Sys?????\sc.exe, C:\Program Files (x86)\Microsoft Visual Studio\Installer\setup.exe, C:\Windows\Microsoft.NET\Framework\v*\InstallUtil.exe, C:\Program Files\Microsoft SQL Server\*\ScenarioEngine.exe, C:\Windows\System32\wsmprovhost.exe, C:\Windows\Sys?????\msiexec.exe, C:\Program Files\Microsoft\AzureAttestService\AzureAttestServiceInstaller.exe, C:\Windows\System32\WindowsPowerShell\v1.0\powershell_ise.exe, C:\Program Files\Common Files\microsoft shared\ClickToRun\OfficeClickToRun.exe, C:\Program Files\Microsoft Office\root\Integration\Addons\OneDriveSetup.exe, C:\Program Files (x86)\AOMEI Cyber Backup\x64\InstallUtil.exe, C:\Windows\Microsoft.NET\Framework64\*\InstallUtil.exe, C:\Program Files (x86)\AOMEI Cyber Backup\x64\iscsi\InstallUtil.exe, C:\Program Files (x86)\Microsoft\EdgeUpdate\MicrosoftEdgeUpdate.exeexcludes:process.executable
process.parent.executableeqF:\setup.exeexcludes:process.parent.executable field:"process.parent.executable" value:"F:\setup.exe"
winlog.event_data.ServiceStartTypeinDisabled, Manualexcludes:winlog.event_data.ServiceStartType field:"winlog.event_data.ServiceStartType" value:"Disabled" field:"winlog.event_data.ServiceStartType" value:"Manual"

Suspicious File Downloaded by Curl/Wget and Piped to Interpreter

#
Time window
1s
Sequence by
process.parent.entity_id, process.working_directory
Source
github.com/elastic/protections-artifacts

This rule detects when a suspicious file is downloaded via curl or wget, and piped to an interpreter. Attackers may use this technique to download and execute payloads for various malicious purposes, such as establishing persistence or exfiltrating data.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
This rule detects when a suspicious file is downloaded via curl or wget, and piped to an interpreter. Attackers may use
this technique to download and execute payloads for various malicious purposes, such as establishing persistence or
exfiltrating data.
"""
id = "7bc702f7-1f1a-49d1-ad8d-c0fa1f4fe324"
license = "Elastic License v2"
name = "Suspicious File Downloaded by Curl/Wget and Piped to Interpreter"
os_list = ["linux"]
version = "1.0.10"

query = '''
sequence by process.parent.entity_id, process.working_directory with maxspan=1s
  [process where event.type == "start" and event.action == "exec" and process.name in ("curl", "wget") and
  (
    /* IP address and path */
    process.command_line regex ".*[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}(:[0-9]{1,5})?\\/[^ ]+.*" or
    /* URL and path */
    process.command_line regex ".*(http|ftp|ftps)\\://[A-Za-z0-9][A-Za-z0-9\\-]*(\\.[A-Za-z0-9][A-Za-z0-9\\-]*)+(:[0-9]{1,5})?\\/[^ ]+.*"
  ) and
  process.args_count <= 3 and (
    process.parent.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox", "node", "deno") or
    process.parent.name like (".*", "python*", "perl*", "ruby*", "lua*", "php*") or
    process.parent.executable like (
      "/tmp/*", "/var/tmp/*", "/dev/shm/*", "./*", "/run/*", "/var/run/*", "/boot/*", "/sys/*", "/lost+found/*",
      "/proc/*", "/var/mail/*", "/var/www/*"
    )
  ) and
  not (
    process.args in ("-h", "--help", "-V", "--version", "--output", "-O") or
    process.args like (
      "--output*", "-o*", "--remote-name*", "https://*:10257/metrics", "http://*:8000/api/job_status/*",
      "http://*:9200/_cluster/health?pretty*", "http://*:8985/solr/mysg_collection/schema/fields",
      "http://*:8985/solr/mysg_collection/schema/fieldtypes", "http://169.254.169.254/latest/meta-data/instance-id",
      "http://*:9010/metrics", "http://*/api/v1/account", "http://*:6820/slurmdb/*", "http://*:8001/api/health_check",
      "http://*:8080/ws/allocationLevelMatchingConfig/update/counterpartyFlowId/*/maxWaitTimeMinutes/*",
      "http://192.168.*", "http://10.*", "http://172.16.*", "http://192.168.*.*", "http://172.16.*.*", "http://*/",
      "http://docker-registry.connect-*.5000*", "http://169.254.169.254/*", "http://*.com:8083/api", "http://*.local*/api/v1/*",
      "http://*.local:9100/metrics", "http://*/oe-ui-logintest", "http://ftp.de.debian.org/debian/pool/main/*",
      "http://*.local*/ws/EoD/createToken/all", "http://*.local*/portfolio", "http://*/DmMethods/servlet/DoMethod"
    ) or
    process.working_directory like (
      "/builds/*", "/var/lib/amagent/*", "/etc/amagent/*", "/jenkins/workspace/*", "/var/lib/docker/overlay2/*",
      "/opt/fwiebe/workspace", "/opt/rchopra/*", "/opt/code/*", "/usr/scratch/tibor/src/systems-lib"
    ) or
    process.parent.executable like "/tmp/newroot/*" or
    process.command_line like (
      "*dl.cloudsmith.io*", "*127.0.0.1*", "*localhost*", "*nginx.org/download/nginx*", "*geoip.elastic.dev*",
      "*artifacts.elastic.co*", "*ela.st*", "*elastic.co*", "*192.168.*.*:*", "*172.16.*", "*conda-condaforge-remote*",
      "*downloads.mariadb.com*", "*pkg.cloudflare.com*", "*packages.microsoft.com*"
    ) or
    process.parent.command_line == "bash --login"
  )]
  [process where event.type == "end" and event.action == "end" and
   process.name like (
     "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish",
     "python*", "perl*", "ruby*", "lua*", "php*", "node"
   ) and process.args_count == 1 and
   process.args like (
    "-bash", "-dash", "-sh", "-tcsh", "-csh", "-zsh", "-ksh", "-fish",
    "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish",
    "/bin/bash", "/bin/dash", "/bin/sh", "/bin/tcsh", "/bin/csh",
    "/bin/zsh", "/bin/ksh", "/bin/fish",
    "/usr/bin/bash", "/usr/bin/dash", "/usr/bin/sh", "/usr/bin/tcsh",
    "/usr/bin/csh", "/usr/bin/zsh", "/usr/bin/ksh", "/usr/bin/fish",
    "python*", "/bin/python*", "/usr/bin/python*", "/usr/local/bin/python*",
    "perl*", "/bin/perl*", "/usr/bin/perl*", "/usr/local/bin/perl*",
    "ruby*", "/bin/ruby*", "/usr/bin/ruby*", "/usr/local/bin/ruby*",
    "lua*", "/bin/lua*", "/usr/bin/lua*", "/usr/local/bin/lua*",
    "php*", "/bin/php*", "/usr/bin/php*", "/usr/local/bin/php*",
    "node", "/bin/node", "/usr/bin/node", "/usr/local/bin/node",
    "/dev/fd/*"
  )
  ]
'''

min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1

[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0

[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 1

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"



[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"

[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"


[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

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

Stage 1: process

[process where event.type == "start" and event.action == "exec" and process.name in ("curl", "wget") and
  (
    process.command_line regex ".*[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}(:[0-9]{1,5})?\\/[^ ]+.*" or
    process.command_line regex ".*(http|ftp|ftps)\\://[A-Za-z0-9][A-Za-z0-9\\-]*(\\.[A-Za-z0-9][A-Za-z0-9\\-]*)+(:[0-9]{1,5})?\\/[^ ]+.*"
  ) and
  process.args_count <= 3 and (
    process.parent.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox", "node", "deno") or
    process.parent.name like (".*", "python*", "perl*", "ruby*", "lua*", "php*") or
    process.parent.executable like (
      "/tmp/*", "/var/tmp/*", "/dev/shm/*", "./*", "/run/*", "/var/run/*", "/boot/*", "/sys/*", "/lost+found/*",
      "/proc/*", "/var/mail/*", "/var/www/*"
    )
  ) and
  not (
    process.args in ("-h", "--help", "-V", "--version", "--output", "-O") or
    process.args like (
      "--output*", "-o*", "--remote-name*", "https://*:10257/metrics", "http://*:8000/api/job_status/*",
      "http://*:9200/_cluster/health?pretty*", "http://*:8985/solr/mysg_collection/schema/fields",
      "http://*:8985/solr/mysg_collection/schema/fieldtypes", "http://169.254.169.254/latest/meta-data/instance-id",
      "http://*:9010/metrics", "http://*/api/v1/account", "http://*:6820/slurmdb/*", "http://*:8001/api/health_check",
      "http://*:8080/ws/allocationLevelMatchingConfig/update/counterpartyFlowId/*/maxWaitTimeMinutes/*",
      "http://192.168.*", "http://10.*", "http://172.16.*", "http://192.168.*.*", "http://172.16.*.*", "http://*/",
      "http://docker-registry.connect-*.5000*", "http://169.254.169.254/*", "http://*.com:8083/api", "http://*.local*/api/v1/*",
      "http://*.local:9100/metrics", "http://*/oe-ui-logintest", "http://ftp.de.debian.org/debian/pool/main/*",
      "http://*.local*/ws/EoD/createToken/all", "http://*.local*/portfolio", "http://*/DmMethods/servlet/DoMethod"
    ) or
    process.working_directory like (
      "/builds/*", "/var/lib/amagent/*", "/etc/amagent/*", "/jenkins/workspace/*", "/var/lib/docker/overlay2/*",
      "/opt/fwiebe/workspace", "/opt/rchopra/*", "/opt/code/*", "/usr/scratch/tibor/src/systems-lib"
    ) or
    process.parent.executable like "/tmp/newroot/*" or
    process.command_line like (
      "*dl.cloudsmith.io*", "*127.0.0.1*", "*localhost*", "*nginx.org/download/nginx*", "*geoip.elastic.dev*",
      "*artifacts.elastic.co*", "*ela.st*", "*elastic.co*", "*192.168.*.*:*", "*172.16.*", "*conda-condaforge-remote*",
      "*downloads.mariadb.com*", "*pkg.cloudflare.com*", "*packages.microsoft.com*"
    ) or
    process.parent.command_line == "bash --login"
  )]

Stage 2: process

[process where event.type == "end" and event.action == "end" and
   process.name like (
     "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish",
     "python*", "perl*", "ruby*", "lua*", "php*", "node"
   ) and process.args_count == 1 and
   process.args like (
    "-bash", "-dash", "-sh", "-tcsh", "-csh", "-zsh", "-ksh", "-fish",
    "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish",
    "/bin/bash", "/bin/dash", "/bin/sh", "/bin/tcsh", "/bin/csh",
    "/bin/zsh", "/bin/ksh", "/bin/fish",
    "/usr/bin/bash", "/usr/bin/dash", "/usr/bin/sh", "/usr/bin/tcsh",
    "/usr/bin/csh", "/usr/bin/zsh", "/usr/bin/ksh", "/usr/bin/fish",
    "python*", "/bin/python*", "/usr/bin/python*", "/usr/local/bin/python*",
    "perl*", "/bin/perl*", "/usr/bin/perl*", "/usr/local/bin/perl*",
    "ruby*", "/bin/ruby*", "/usr/bin/ruby*", "/usr/local/bin/ruby*",
    "lua*", "/bin/lua*", "/usr/bin/lua*", "/usr/local/bin/lua*",
    "php*", "/bin/php*", "/usr/bin/php*", "/usr/local/bin/php*",
    "node", "/bin/node", "/usr/bin/node", "/usr/local/bin/node",
    "/dev/fd/*"
  )
  ]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • end
  • exec
field:"EventType" kind:eq
event.typeeq
  • end
  • start
field:"event.type" kind:eq
process.argswildcard
  • -bash
  • -csh
  • -dash
  • -fish
  • -ksh
  • -sh
  • -tcsh
  • -zsh
  • /bin/bash
  • /bin/csh
  • /bin/dash
  • /bin/fish
  • /bin/ksh
  • /bin/lua*
  • /bin/node
  • /bin/perl*
  • /bin/php*
  • /bin/python*
  • /bin/ruby*
  • /bin/sh
  • /bin/tcsh
  • /bin/zsh
  • /dev/fd/*
  • /usr/bin/bash
  • /usr/bin/csh
  • /usr/bin/dash
  • /usr/bin/fish
  • /usr/bin/ksh
  • /usr/bin/lua*
  • /usr/bin/node
  • /usr/bin/perl*
  • /usr/bin/php*
  • /usr/bin/python*
  • /usr/bin/ruby*
  • /usr/bin/sh
  • /usr/bin/tcsh
  • /usr/bin/zsh
  • /usr/local/bin/lua*
  • /usr/local/bin/node
  • /usr/local/bin/perl*
  • /usr/local/bin/php*
  • /usr/local/bin/python*
  • /usr/local/bin/ruby*
  • bash
  • csh
  • dash
  • fish
  • ksh
  • lua*
  • node
  • perl*
  • php*
  • python*
  • ruby*
  • sh
  • tcsh
  • zsh
field:"process.args" kind:wildcard
process.args_counteq
  • 1 transforms: number
field:"process.args_count" kind:eq value:"1"
process.args_countle
  • 3 transforms: number
field:"process.args_count" kind:le value:"3"
process.command_lineregex_match
  • .*(http|ftp|ftps)\://[A-Za-z0-9][A-Za-z0-9\-]*(.[A-Za-z0-9][A-Za-z0-9\-]*)+(:[0-9]{1,5})?\/[^ ]+.*
  • .*[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}(:[0-9]{1,5})?\/[^ ]+.*
field:"CommandLine" kind:regex_match
process.namein
  • curl
  • wget
field:"process_basename" kind:in
process.namewildcard
  • bash
  • csh
  • dash
  • fish
  • ksh
  • lua*
  • node
  • perl*
  • php*
  • python*
  • ruby*
  • sh
  • tcsh
  • zsh
field:"process_basename" kind:wildcard
process.parent.executablewildcard
  • ./*
  • /boot/*
  • /dev/shm/*
  • /lost+found/*
  • /proc/*
  • /run/*
  • /sys/*
  • /tmp/*
  • /var/mail/*
  • /var/run/*
  • /var/tmp/*
  • /var/www/*
field:"ParentImage" kind:wildcard
process.parent.namein
  • bash
  • busybox
  • csh
  • dash
  • deno
  • fish
  • ksh
  • node
  • sh
  • tcsh
  • zsh
field:"parent_process_basename" kind:in
process.parent.namewildcard
  • .*
  • lua*
  • perl*
  • php*
  • python*
  • ruby*
field:"parent_process_basename" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argsin--help, --output, --version, -O, -V, -hexcludes:process.args
process.argswildcard--output*, -o*, --remote-name*, https://*:10257/metrics, http://*:8000/api/job_status/*, http://*:9200/_cluster/health?pretty*, http://*:8985/solr/mysg_collection/schema/fields, http://*:8985/solr/mysg_collection/schema/fieldtypes, http://169.254.169.254/latest/meta-data/instance-id, http://*:9010/metrics, http://*/api/v1/account, http://*:6820/slurmdb/*, http://*:8001/api/health_check, http://*:8080/ws/allocationLevelMatchingConfig/update/counterpartyFlowId/*/maxWaitTimeMinutes/*, http://192.168.*, http://10.*, http://172.16.*, http://192.168.*.*, http://172.16.*.*, http://*/, http://docker-registry.connect-*.5000*, http://169.254.169.254/*, http://*.com:8083/api, http://*.local*/api/v1/*, http://*.local:9100/metrics, http://*/oe-ui-logintest, http://ftp.de.debian.org/debian/pool/main/*, http://*.local*/ws/EoD/createToken/all, http://*.local*/portfolio, http://*/DmMethods/servlet/DoMethodexcludes:process.args
process.command_linewildcard*dl.cloudsmith.io*, *127.0.0.1*, *localhost*, *nginx.org/download/nginx*, *geoip.elastic.dev*, *artifacts.elastic.co*, *ela.st*, *elastic.co*, *192.168.*.*:*, *172.16.*, *conda-condaforge-remote*, *downloads.mariadb.com*, *pkg.cloudflare.com*, *packages.microsoft.com*excludes:process.command_line
process.parent.command_lineeqbash --loginexcludes:process.parent.command_line field:"process.parent.command_line" value:"bash --login"
process.parent.executablestarts_with/tmp/newroot/excludes:process.parent.executable field:"process.parent.executable" value:"/tmp/newroot/"
process.working_directorywildcard/builds/*, /var/lib/amagent/*, /etc/amagent/*, /jenkins/workspace/*, /var/lib/docker/overlay2/*, /opt/fwiebe/workspace, /opt/rchopra/*, /opt/code/*, /usr/scratch/tibor/src/systems-libexcludes:process.working_directory

Unusual Child Processes of RunDLL32

#
Status
production
Severity
high
Time window
1h
Sequence by
process.entity_id, process.parent.entity_id
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies a no-argument or malformed Rundll32 launch followed by child process execution. This unusual sequence can indicate Rundll32 abuse for proxy execution or payload handoff.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2020/09/02"
integration = ["endpoint", "windows", "crowdstrike"]
maturity = "production"
updated_date = "2026/04/30"

[rule]
author = ["Elastic"]
description = """
Identifies a no-argument or malformed Rundll32 launch followed by child process execution. This unusual sequence can
indicate Rundll32 abuse for proxy execution or payload handoff.
"""
from = "now-60m"
index = ["logs-endpoint.events.process-*", "winlogbeat-*", "logs-windows.sysmon_operational-*", "logs-crowdstrike.fdr*"]
interval = "30m"
language = "eql"
license = "Elastic License v2"
name = "Unusual Child Processes of RunDLL32"
risk_score = 73
rule_id = "f036953a-4615-4707-a1ca-dc53bf69dcd5"
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Defense Evasion",
    "Data Source: Elastic Defend",
    "Data Source: Sysmon",
    "Data Source: Crowdstrike",
    "Resources: Investigation Guide",
]
type = "eql"

query = '''
sequence with maxspan=1h
  [process where host.os.type == "windows" and event.type == "start" and
     (process.name : "rundll32.exe" or process.pe.original_file_name == "RUNDLL32.EXE") and
      (process.args_count == 1 and
        /* Excludes bug where a missing closing quote sets args_count to 1 despite extra args */
        not process.command_line regex~ """\".*\.exe[^\"].*""")
  ] by process.entity_id
  [process where host.os.type == "windows" and event.type == "start" and process.parent.name : "rundll32.exe"
  ] by process.parent.entity_id
'''

note = """## Triage and analysis

### Investigating Unusual Child Processes of RunDLL32

#### Possible investigation steps

- Which source events define the no-argument "rundll32.exe" parent and the spawned child?
  - Why: this asymmetric sequence has no single safe process identity; recover source events before interpreting grouped meaning or pivoting.
  - Focus: Timeline source events for the sequence, recording parent and child `process.entity_id`, child `process.parent.entity_id`, `host.id`, and `user.id`.
  - Implication: escalate when recovered events show one no-argument "rundll32.exe" handing off to an unexpected child; lower suspicion only when recovery shows a parser/quoting artifact and the child is signed, stable, and path-consistent for the same user and host.

- Does the recovered "rundll32.exe" event truly lack a DLL, export, or Control_RunDLL-style target?
  - Why: normal Rundll32 proxy execution names a DLL/export, ordinal, script target, or Control Panel handler; this rule covers empty or malformed invocation that still spawns a child.
  - Focus: parent `process.command_line`, `process.args_count`, `process.executable`, and `process.pe.original_file_name`.
  - Implication: escalate when `process.args_count` and `process.command_line` confirm only the image path or a malformed target; lower suspicion only when source recovery proves a quoting/parser artifact and the exact parent-child command pattern is stable.

- What did the recovered child process do, and does its identity fit that parent chain?
  - Focus: child `process.executable`, `process.command_line`, `process.pe.original_file_name`, code signature, and descendant process starts.
  - Hint: after recovering the child `process.entity_id` from source events, pivot manually on that ID for descendants; the final sequence alert may not preserve a child-specific entity ID.
  - Implication: escalate when the child is a shell, script host, network utility, unsigned payload, user-writable binary, or mismatched original file name; lower suspicion when the child is signed, path-consistent, and matches the exact recovered wrapper pattern. Identity alone does not clear the behavior.

- What launched "rundll32.exe", and does the user-host context explain the handoff?
  - Focus: parent `process.parent.executable`, `process.parent.command_line`, `process.Ext.ancestry`, `user.name`, and `user.domain`.
  - Implication: escalate when the launcher is Office, a browser, archive utility, script host, temp-path executable, or a lineage unusual for that `user.id` and `host.id`; lower suspicion only when the same parent executable, command line, child path, signer, and host/user scope recur without artifact or network contradictions.

- If library telemetry is available after source-event recovery, did the recovered process load a hidden or recently staged DLL?
  - Focus: library events for recovered `host.id` and each `process.entity_id`, checking `dll.path`, `dll.hash.sha256`, signer, trust, and `dll.Ext.relative_file_creation_time`.
  - Hint: query library events separately for the recovered parent and child IDs; missing library telemetry limits DLL corroboration but does not clear the process evidence.
  - Implication: escalate when a DLL loads from a user-writable, unrelated, unsigned, or recently created path; lower suspicion when library identity, signer, and path relationship fit the recovered parent-child workflow.

- If file or network telemetry is available after source-event recovery, did the chain stage payloads or reach suspicious infrastructure?
  - Focus: file and network events for recovered `host.id` and each `process.entity_id`, checking `file.path`, `file.Ext.windows.zone_identifier`, DNS `dns.question.name`, connection `destination.ip`, and `destination.port`.
  - Hint: separate DNS lookup events from connection events before interpreting them. Missing network telemetry is unresolved, not benign.
  - Implication: escalate when the chain writes executable or scriptable artifacts, carries internet provenance, or connects to rare external infrastructure; lower suspicion when optional activity stays inside the recovered parent-child workflow.

- If local evidence remains suspicious or unresolved, do related alerts show the same user, host, or child-process pattern?
  - Focus: recent alerts for `user.id`, `host.id`, child `process.executable`, child `process.hash.sha256`, or a distinctive `process.command_line` fragment.
  - Hint: use only after source recovery keeps the case suspicious or unresolved.
    - $investigate_0
    - $investigate_1
  - Implication: broaden response when the same user or host repeats Rundll32 proxy-execution, child payload, or related defense-evasion alerts; keep scope local when the suspicious pattern remains isolated and the recovered workflow is tightly explained.

- Escalate when source recovery, invocation shape, child identity, launcher lineage, DLL/file/network evidence, or recurrence shows "rundll32.exe" proxying unauthorized child execution or payload delivery; close only when recovered process evidence and corroborators tightly bind one exact signed workflow on this host; if evidence is mixed or incomplete, preserve artifacts and escalate.

### False positive analysis

- No-argument "rundll32.exe" spawning a child is an operational anti-pattern. Close as benign only when source recovery proves a parser/quoting artifact or authorized reproduction, the child is signed and path-consistent, and no DLL, file, or network evidence contradicts that workflow. Align available inventory, vendor, or test records; otherwise treat prior recurrence for the same `host.id` and stable parent-child anchors as supporting evidence only.
- Build exceptions from the minimum confirmed workflow: parent `process.parent.executable`, child `process.executable`, stable `process.code_signature.subject_name`, command-line shape, host/user scope, and recovered artifact anchors when present. Do not except a first occurrence, unresolved source recovery, missing contradictory-telemetry checks, or "rundll32.exe" alone.

### Response and remediation

- If confirmed benign:
  - Reverse temporary containment and document the recovered parent-child workflow, source-event IDs, signer, command-line pattern, and corroborating inventory, vendor record, or recurrence that established it.
- If suspicious but unconfirmed:
  - Preserve a case export of Timeline source events, recovered process identifiers and command lines, child binary hash, and any recovered DLL, file, or network artifacts before cleanup.
  - Apply reversible containment such as temporary network restrictions or heightened monitoring on the affected `host.id` and `user.id`; use host isolation only when child-process or artifact evidence indicates active payload execution and the host role can tolerate isolation.
- If confirmed malicious:
  - Preserve the recovered source events, process IDs, command lines, child hashes, DLL or file artifacts, and network indicators, then isolate the host or restrict the account based on the child execution, launcher lineage, artifact, or network evidence.
  - Block confirmed malicious child hashes, DLL hashes, staged payload paths, domains, and destination IPs, then review other hosts and users for the same parent-child or artifact pattern before eradication.
  - Remove only the malicious DLLs, scripts, or child payloads identified during investigation, remediate the parent launcher or delivery path that invoked "rundll32.exe", and investigate credential exposure if follow-on behavior suggests collection or lateral movement.
- Post-incident hardening:
  - Keep process telemetry for "rundll32.exe" and child processes enabled, and enable file, network, or library telemetry where missing evidence limited the case.
  - Restrict unusual "rundll32.exe" child-process patterns where the business does not require them, and record any adjacent DLL/export, ordinal, Control Panel, or script-target variants observed in the case.
"""

setup = """## Setup

This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.

Setup instructions: https://ela.st/install-elastic-defend

### Additional data sources

This rule also supports the following third-party data sources. For setup instructions, refer to the links below:

- [CrowdStrike](https://ela.st/crowdstrike-integration)
- [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
"""

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "host.name",
    "host.id",
    "user.id",
    "event.category",
    "event.type",
]

[transform]

[[transform.investigate]]
label = "Alerts associated with the user"
description = ""
providers = [
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
  ]
]
relativeFrom = "now-48h/h"
relativeTo = "now"

[[transform.investigate]]
label = "Alerts associated with the host"
description = ""
providers = [
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
  ]
]
relativeFrom = "now-48h/h"
relativeTo = "now"

[[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.011"
name = "Rundll32"
reference = "https://attack.mitre.org/techniques/T1218/011/"

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

Stages and Predicates

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

Stage 1: process

[process where host.os.type == "windows" and event.type == "start" and
     (process.name : "rundll32.exe" or process.pe.original_file_name == "RUNDLL32.EXE") and
      (process.args_count == 1 and
        not process.command_line regex~ """\".*\.exe[^\"].*""")
  ] by process.entity_id

Stage 2: process

[process where host.os.type == "windows" and event.type == "start" and process.parent.name : "rundll32.exe"
  ] by process.parent.entity_id

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.args_counteq
  • 1 transforms: number corpus 50 (elastic 50)
field:"process.args_count" kind:eq value:"1"
process.namewildcard
  • rundll32.exe corpus 123 (elastic 100, splunk 23)
field:"process_basename" kind:wildcard value:"rundll32.exe"
process.parent.namewildcard
  • rundll32.exe corpus 20 (elastic 20)
field:"parent_process_basename" kind:wildcard value:"rundll32.exe"
process.pe.original_file_nameeq
  • RUNDLL32.EXE corpus 7 (elastic 7)
field:"OriginalFileName" kind:eq value:"RUNDLL32.EXE"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.command_lineregex_match\".*.exe[^\"].*excludes:process.command_line

Unusual Execution from /dev Parent

#
Source
github.com/elastic/protections-artifacts

This rule detects suspicious executions from /dev parent directories. Attackers may execute binaries from /dev parent directories to evade detection and execute malicious payloads.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
This rule detects suspicious executions from /dev parent directories. Attackers may execute binaries from /dev parent
directories to evade detection and execute malicious payloads.
"""
id = "eb575588-dce7-4934-966c-c0e9ebc456c5"
license = "Elastic License v2"
name = "Unusual Execution from /dev Parent"
os_list = ["linux"]
version = "1.0.6"

query = '''
process where event.type == "start" and event.action == "exec" and process.parent.executable like "/dev/*" and
process.executable like ("/tmp/*", "/var/tmp/*", "/var/www/*", "/bin/*", "/usr/bin/*", "/usr/local/bin/*") and
not (
  process.args like "/dev/shm/*" or
  process.parent.executable like ("/dev/fd/*", "/dev/null/*", "/dev/shm/*") or
  process.parent.command_line == "runc init" or
  process.name in ("buildkitd", "uname") or
  process.executable == "/usr/bin/fusermount"
)
'''

min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"



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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Stage 1: process

process where event.type == "start" and event.action == "exec" and process.parent.executable like "/dev/*" and
process.executable like ("/tmp/*", "/var/tmp/*", "/var/www/*", "/bin/*", "/usr/bin/*", "/usr/local/bin/*") and
not (
  process.args like "/dev/shm/*" or
  process.parent.executable like ("/dev/fd/*", "/dev/null/*", "/dev/shm/*") or
  process.parent.command_line == "runc init" or
  process.name in ("buildkitd", "uname") or
  process.executable == "/usr/bin/fusermount"
)

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

Unusual Windows Process Calling the Metadata Service

#
Status
production
Severity
low
Author
Elastic
Source
github.com/elastic/detection-rules

Looks for anomalous access to the metadata service by an unusual process. The metadata service may be targeted in order to harvest credentials or user data scripts containing secrets.

Known False Positives

  • A newly installed program or one that runs very rarely as part of a monthly or quarterly workflow could trigger this detection rule.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2020/09/22"
integration = ["endpoint", "windows"]
maturity = "production"
min_stack_version = "9.4.0"
min_stack_comments = "Use EA (Entity Analytics) fields"
updated_date = "2026/07/27"

[rule]
anomaly_threshold = 50
author = ["Elastic"]
description = """
Looks for anomalous access to the metadata service by an unusual process. The metadata service may be targeted in order
to harvest credentials or user data scripts containing secrets.
"""
false_positives = [
    """
    A newly installed program or one that runs very rarely as part of a monthly or quarterly workflow could trigger this
    detection rule.
    """,
]
from = "now-45m"
interval = "15m"
license = "Elastic License v2"
machine_learning_job_id = ["v3_windows_rare_metadata_process_ea"]
name = "Unusual Windows Process Calling the Metadata Service"
note = """## Triage and analysis

> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

### Investigating Unusual Windows Process Calling the Metadata Service

In cloud environments, the metadata service provides essential instance information, including credentials and configuration data. Adversaries may exploit this by using atypical Windows processes to access the service, aiming to extract sensitive information. The detection rule leverages machine learning to identify anomalies in process behavior, flagging potential credential access attempts by unusual processes.

### Possible investigation steps

- Review the process name and command line arguments associated with the alert to identify any unusual or suspicious activity.
- Check the parent process of the flagged process to understand the context of how it was initiated and assess if it aligns with expected behavior.
- Investigate the user account under which the process was executed to determine if it has legitimate access to the metadata service or if it has been compromised.
- Analyze network logs to identify any outbound connections to the metadata service from the flagged process, noting any unusual patterns or destinations.
- Cross-reference the process and user activity with recent changes or deployments in the environment to rule out false positives related to legitimate administrative actions.
- Consult threat intelligence sources to see if the process or command line arguments have been associated with known malicious activity or campaigns.

### False positive analysis

- Routine system updates or maintenance scripts may trigger the rule. Review the process details and verify if they align with scheduled maintenance activities. If confirmed, consider adding these processes to an exception list.
- Legitimate software or security tools that access the metadata service for configuration purposes might be flagged. Identify these tools and create exceptions for their known processes to prevent future alerts.
- Automated backup or monitoring solutions that interact with the metadata service could be misidentified as threats. Validate these processes and exclude them if they are part of authorized operations.
- Custom scripts developed in-house for cloud management tasks may access the metadata service. Ensure these scripts are documented and, if safe, add them to the list of exceptions to reduce false positives.

### Response and remediation

- Isolate the affected system from the network to prevent further unauthorized access or data exfiltration.
- Terminate the unusual process accessing the metadata service to stop any ongoing credential harvesting attempts.
- Conduct a thorough review of the system's event logs and process history to identify any additional indicators of compromise or related malicious activity.
- Change all credentials that may have been exposed or accessed through the metadata service to mitigate the risk of unauthorized access.
- Implement network segmentation to limit access to the metadata service, ensuring only authorized processes and users can interact with it.
- Escalate the incident to the security operations center (SOC) for further analysis and to determine if the threat is part of a larger attack campaign.
- Update and enhance endpoint detection and response (EDR) solutions to improve monitoring and alerting for similar anomalous process behaviors in the future."""
risk_score = 21
rule_id = "abae61a8-c560-4dbd-acca-1e1438bff36b"
setup = """## Setup

This rule requires the installation of associated Machine Learning jobs, as well as data coming in from one of the following integrations:
- Elastic Defend
- Windows

### Anomaly Detection Setup

Once the rule is enabled, the associated Machine Learning job will start automatically. You can view the Machine Learning job linked under the "Definition" panel of the detection rule. If the job does not start due to an error, the issue must be resolved for the job to commence successfully. For more details on setting up anomaly detection jobs, refer to the [helper guide](https://www.elastic.co/guide/en/kibana/current/xpack-ml-anomalies.html).

### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.

#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).

#### The following steps should be executed in order to add the Elastic Defend integration to your system:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/current/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).

### Windows Integration Setup
The Windows integration allows you to monitor the Windows OS, services, applications, and more.

#### The following steps should be executed in order to add the Elastic Agent System integration "windows" to your system:
- Go to the Kibana home page and click “Add integrations”.
- In the query bar, search for “Windows” and select the integration to see more details about it.
- Click “Add Windows”.
- Configure the integration name and optionally add a description.
- Review optional and advanced settings accordingly.
- Add the newly installed “windows” to an existing or a new agent policy, and deploy the agent on your system from which windows log files are desirable.
- Click “Save and Continue”.
- For more details on the integration refer to the [helper guide](https://docs.elastic.co/integrations/windows).
"""
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Data Source: Elastic Defend",
    "Data Source: Windows Security Event Logs",
    "Use Case: Threat Detection",
    "Rule Type: ML",
    "Rule Type: Machine Learning",
    "Tactic: Credential Access",
    "Resources: Investigation Guide",
]
type = "machine_learning"
[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1552"
name = "Unsecured Credentials"
reference = "https://attack.mitre.org/techniques/T1552/"

[[rule.threat.technique.subtechnique]]
id = "T1552.005"
name = "Cloud Instance Metadata API"
reference = "https://attack.mitre.org/techniques/T1552/005/"

[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"

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

[[rule.threat.technique]]
id = "T1580"
name = "Cloud Infrastructure Discovery"
reference = "https://attack.mitre.org/techniques/T1580/"

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

Windows API via Work Callback

#
Source
github.com/elastic/protections-artifacts

Identifies the call of Memory Windows APIs indirectly via a callback function. This may be the result of an evasion attempt to hide the origin of the API call from the call stack such as unbacked memory region.

MITRE ATT&CK Coverage

TacticTechniques
Stealth

Rule Body

[rule]
description = """
Identifies the call of Memory Windows APIs indirectly via a callback function. This may be the result of an evasion
attempt to hide the origin of the API call from the call stack such as unbacked memory region.
"""
id = "d0759e87-16c1-45ed-ac8f-b2ad6e4fdddc"
license = "Elastic License v2"
name = "Windows API via Work Callback"
os_list = ["windows"]
reference = [
    "https://www.elastic.co/security-labs/doubling-down-etw-callstacks",
    "https://0xdarkvortex.dev/hiding-in-plainsight/",
]
version = "1.0.3"

query = '''
api where
 process.Ext.api.name in ("VirtualAlloc", "VirtualProtect", "WriteProcessMemory", "VirtualProtectEx", "VirtualAllocEx", "MapViewOfFile", "MapViewOfFile2", "SetThreadContext", "SuspendThread", "ReadProcessMemory", "connect") and
 process.thread.Ext.call_stack_summary == "ntdll.dll|kernel32.dll|ntdll.dll" and
 _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info : ("*ntdll.dll!TppWorkpExecuteCallback*", "*ntdll.dll!TppWorkerThread*"))
'''

min_endpoint_version = "8.10.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"


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

[internal]
min_endpoint_version = "8.10.0"

Stages and Predicates

Stage 1: api

api where
 process.Ext.api.name in ("VirtualAlloc", "VirtualProtect", "WriteProcessMemory", "VirtualProtectEx", "VirtualAllocEx", "MapViewOfFile", "MapViewOfFile2", "SetThreadContext", "SuspendThread", "ReadProcessMemory", "connect") and
 process.thread.Ext.call_stack_summary == "ntdll.dll|kernel32.dll|ntdll.dll" and
 _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info : ("*ntdll.dll!TppWorkpExecuteCallback*", "*ntdll.dll!TppWorkerThread*"))

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
process.Ext.api.namein
  • MapViewOfFile corpus 24 (elastic 24)
  • MapViewOfFile2 corpus 24 (elastic 24)
  • ReadProcessMemory corpus 9 (elastic 9)
  • SetThreadContext corpus 14 (elastic 14)
  • SuspendThread corpus 12 (elastic 12)
  • VirtualAlloc corpus 27 (elastic 27)
  • VirtualAllocEx corpus 22 (elastic 22)
  • VirtualProtect corpus 35 (elastic 35)
  • VirtualProtectEx corpus 29 (elastic 29)
  • WriteProcessMemory corpus 23 (elastic 23)
  • connect corpus 8 (elastic 8)
field:"process.Ext.api.name" kind:in
process.thread.Ext.call_stack_summaryeq
  • ntdll.dll|kernel32.dll|ntdll.dll corpus 3 (elastic 3)
field:"process.thread.Ext.call_stack_summary" kind:eq value:"ntdll.dll|kernel32.dll|ntdll.dll"

WRITEDAC Access on Active Directory Object

#
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 the access on an object with WRITEDAC permissions. With the WRITEDAC permission, the user can perform a Write Discretionary Access Control List (WriteDACL) operation, which is used to modify the access control rules associated with a specific object within Active Directory. Attackers may abuse this privilege to grant themselves or other compromised accounts additional rights, ultimately compromising the target object, resulting in privilege escalation, lateral movement, and persistence.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2023/08/15"
integration = ["system", "windows"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
building_block_type = "default"
description = """
Identifies the access on an object with WRITEDAC permissions. With the WRITEDAC permission, the user can perform a Write
Discretionary Access Control List (WriteDACL) operation, which is used to modify the access control rules associated
with a specific object within Active Directory. Attackers may abuse this privilege to grant themselves or other
compromised accounts additional rights, ultimately compromising the target object, resulting in privilege escalation,
lateral movement, and persistence.
"""
from = "now-119m"
index = ["winlogbeat-*", "logs-system.security*", "logs-windows.*"]
interval = "60m"
language = "kuery"
license = "Elastic License v2"
name = "WRITEDAC Access on Active Directory Object"
references = [
    "https://www.blackhat.com/docs/us-17/wednesday/us-17-Robbins-An-ACE-Up-The-Sleeve-Designing-Active-Directory-DACL-Backdoors.pdf",
]
risk_score = 21
rule_id = "f5861570-e39a-4b8a-9259-abd39f84cb97"
setup = """## Setup

The 'Audit Directory Service Access' logging policy must be configured for (Success, Failure).
Steps to implement the logging policy with Advanced Audit Configuration:

```
Computer Configuration >
Policies >
Windows Settings >
Security Settings >
Advanced Audit Policies Configuration >
Audit Policies >
DS Access >
Audit Directory Service Access (Success,Failure)
```
"""
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Defense Evasion",
    "Data Source: Active Directory",
    "Use Case: Active Directory Monitoring",
    "Rule Type: BBR",
    "Data Source: Windows Security Event Logs",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
host.os.type: "windows" and event.action : ("Directory Service Access" or "object-operation-performed") and
  event.code : "4662" and winlog.event_data.AccessMask:"0x40000"
'''


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

[[rule.threat.technique]]
id = "T1222"
name = "File and Directory Permissions Modification"
reference = "https://attack.mitre.org/techniques/T1222/"

[[rule.threat.technique.subtechnique]]
id = "T1222.001"
name = "Windows File and Directory Permissions Modification"
reference = "https://attack.mitre.org/techniques/T1222/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 = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"

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

Stages and Predicates

Stage 1: query

host.os.type: "windows" and event.action : ("Directory Service Access" or "object-operation-performed") and
  event.code : "4662" and winlog.event_data.AccessMask:"0x40000"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actionin
  • Directory Service Access
  • object-operation-performed
field:"EventType" kind:in
winlog.event_data.AccessMaskeq
  • 0x40000 corpus 2 (sigma 1, elastic 1)
field:"AccessMask" kind:eq value:"0x40000"

Back to all Elastic rules