Detection rules › Elastic

Elastic rules: 0e

AWS IAM User Addition to Group

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

Identifies the addition of a user to a specified group in AWS Identity and Access Management (IAM). Any user added to a group automatically gains the permissions that are assigned to the group. If the target group carries elevated or admin privileges, this action can instantly grant high-risk permissions useful for credential misuse, lateral movement, or privilege escalation.

Known False Positives

  • Legitimate operations such as new user onboarding, role changes, or service account updates may trigger this event. Verify whether the user identity, user agent, and/or hostname should be making changes in your environment. User additions from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule.

MITRE ATT&CK Coverage

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2020/06/04"
integration = ["aws"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Identifies the addition of a user to a specified group in AWS Identity and Access Management (IAM). Any user added to a
group automatically gains the permissions that are assigned to the group. If the target group carries elevated or admin
privileges, this action can instantly grant high-risk permissions useful for credential misuse, lateral movement, or
privilege escalation.
"""
false_positives = [
    """
    Legitimate operations such as new user onboarding, role changes, or service account updates may trigger this event.
    Verify whether the user identity, user agent, and/or hostname should be making changes in your environment. User
    additions from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it
    can be exempted from the rule.
    """,
]
from = "now-6m"
index = ["filebeat-*", "logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS IAM User Addition to Group"
note = """## Triage and analysis

### Investigating AWS IAM User Addition to Group

This rule detects when an IAM user is added to an IAM group via the `AddUserToGroup` API call. If the target group holds elevated privileges, this action may immediately grant that user wide-ranging access useful for credential misuse or lateral movement. This rule helps detect unauthorized privilege escalation via group membership change. Treat as high-risk when the destination group has wide scope (e.g., AdministratorAccess or permissive inline policies).

#### Possible investigation steps

- **Identify the actor and target**  
  - Check `aws.cloudtrail.user_identity.arn` for who added the user.  
  - From `aws.cloudtrail.request_parameters`, capture `userName` (added user) and `groupName` (destination group).  
  - Check `source.ip`, `user_agent.original`, `cloud.region` for unusual patterns.

- **Examine the group’s privileges**  
  - Use `GetGroup`, `ListAttachedGroupPolicies` to see what policies the group holds. Look for `AdministratorAccess`, `iam:*`, `s3:*`, `ec2:*` or cross-account permissions.  
  - Check whether the group was recently created (`CreateGroup`) or recently escalated (`AttachGroupPolicy`). Common attacker pattern: create > attach policy > add user.

- **Correlate with surrounding activity**  
  - Look for preceding events by the actor: `AssumeRole`, `GetSessionToken`, `CreateAccessKey`, `AttachGroupPolicy`.  
  - Follow the added user’s activities after group membership. Look for sensitive operations (e.g., IAM actions, S3 policy changes, EC2 snapshot/AMI activity).


### False positive analysis

- Onboarding or role transitions may legitimately add users to groups.  
- Automated Identity-Management pipelines may add many users to service groups; validate know

### Response and remediation

- **Containment**:
  - If unapproved, remove the user from the group immediately (`RemoveUserFromGroup`) and rotate their access keys.
  - Temporarily restrict group policy changes while assessing blast radius.

- **Investigation and scoping**:
  - Review all actions executed by the newly added user since the change (ex: PutBucketPolicy, CreateAccessKey, PassRole).
  - Confirm whether other users were added to the same group within the same window. 

- **Recovery and hardening**: 
  - Enforce least privilege by redesigning large-group membership. 
  - Restrict `iam:AddUserToGroup` to only appropriate service principals with approval workflow. 
  - Create detections for AttachGroupPolicy to powerful policies and for mass AddUserToGroup patterns.

### Additional information
[AWS Security Best Practices](https://aws.amazon.com/premiumsupport/knowledge-center/security-best-practices/)
"""
references = ["https://docs.aws.amazon.com/IAM/latest/APIReference/API_AddUserToGroup.html"]
risk_score = 21
rule_id = "333de828-8190-4cf5-8d7c-7575846f6fe0"
severity = "low"
tags = [
    "Domain: Cloud",
    "Data Source: AWS",
    "Data Source: Amazon Web Services",
    "Use Case: Identity and Access Audit",
    "Tactic: Credential Access",
    "Tactic: Persistence",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset: aws.cloudtrail and 
    event.provider: iam.amazonaws.com and 
    event.action: AddUserToGroup and 
    event.outcome: success
'''


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

[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 = "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.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.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",
    "user.target.name",
    "event.action",
    "event.outcome",
    "cloud.account.id",
    "cloud.region",
    "aws.cloudtrail.request_parameters",
]

Stages and Predicates

Stage 1: query

data_stream.dataset: aws.cloudtrail and 
    event.provider: iam.amazonaws.com and 
    event.action: AddUserToGroup and 
    event.outcome: success

Indicators

These rows show field, operator, and value matches.

AWS S3 Credential File Retrieved from Bucket

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

Detects successful S3 GetObject calls targeting high-value credential and secret files commonly stored in S3 buckets: AWS credentials files (".aws/credentials", ".aws/config"), SSH private keys ("id_rsa", "id_ed25519", "id_ecdsa", "id_dsa"), environment files (".env"), PEM and PuTTY key files, and other private key patterns. These file types are high-yield targets for credential harvesting from S3. The rule excludes AWSService identity type to suppress S3 replication, Glacier restore, and other AWS-internal data movement that legitimately reads these files.

Known False Positives

  • Legitimate CI/CD pipelines, infrastructure tooling, or configuration management systems may retrieve secret files from S3 as part of their normal operation. Validate the calling identity, user agent, and source IP against known automation accounts and expected access patterns.

MITRE ATT&CK Coverage

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2026/05/27"
integration = ["aws"]
maturity = "production"
updated_date = "2026/05/27"

[rule]
author = ["Elastic"]
description = """
Detects successful S3 GetObject calls targeting high-value credential and secret files commonly
stored in S3 buckets: AWS credentials files (".aws/credentials", ".aws/config"), SSH private keys
("id_rsa", "id_ed25519", "id_ecdsa", "id_dsa"), environment files (".env"), PEM and PuTTY key files,
and other private key patterns. These file types are high-yield targets for credential harvesting
from S3. The rule excludes AWSService identity type to suppress S3 replication, Glacier restore,
and other AWS-internal data movement that legitimately reads these files.
"""
false_positives = [
    """
    Legitimate CI/CD pipelines, infrastructure tooling, or configuration management systems may retrieve
    secret files from S3 as part of their normal operation. Validate the calling identity, user agent,
    and source IP against known automation accounts and expected access patterns.
    """,
]
from = "now-6m"
index = ["filebeat-*", "logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS S3 Credential File Retrieved from Bucket"
note = """## Triage and analysis

### Investigating AWS S3 Credential File Retrieved from Bucket

S3 is frequently used to store configuration files, scripts, and secrets. When files with credential-like
names are accessed, it warrants investigation to ensure that the retrieval was authorized.

### Possible investigation steps

- **Identify the accessed file**: Review `aws.cloudtrail.request_parameters` for the bucket name and key.
  Determine whether the bucket is intended to store secrets.
- **Verify the caller**: Inspect `aws.cloudtrail.user_identity.arn` and `source.ip`. If the caller is not
  an approved automation role, escalate immediately.
- **Check bucket permissions**: Determine if the bucket is publicly accessible or if the key naming
  pattern was intentionally exposed.
- **Look for downstream actions**: Search for subsequent IAM, STS, or console actions from the same
  identity shortly after the object retrieval, which may indicate successful credential use.

### False positive analysis

- Legitimate backup or restore processes may access credential files stored in S3 as part of their
  workflow. Validate the calling identity and user agent against known automation accounts.
- CI/CD pipelines that retrieve secrets from S3 during deployment may trigger this rule. Verify the
  source IP and ARN match expected automation infrastructure.

### Response and remediation

- Immediately disable the access key identified in `aws.cloudtrail.user_identity.access_key_id` if
  the retrieval is determined to be unauthorized.
- Audit the S3 bucket for overly permissive policies or public access configurations.
- Rotate any credentials stored in the accessed object — treat them as compromised.
- Review all CloudTrail events from the same identity in the preceding 30 minutes for signs of
  lateral movement, IAM changes, or resource creation.
- Implement S3 bucket policies or IAM conditions restricting access to credential files to only
  authorized identities and source IPs.
"""
references = [
    "https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html",
]
risk_score = 47
rule_id = "2f0ee9fe-4529-4b9e-9f78-6c81ef33c6ba"
severity = "medium"
setup = """S3 data event logging is required for this rule. This rule detects S3 GetObject events,
which are data plane events not logged by default. To enable: CloudTrail console → Trails →
[trail name] → Data events → Add S3 → select the buckets to monitor (or all buckets with a wildcard).
Without this configuration, the rule produces no alerts.

Refer to the AWS documentation on
https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-data-events-with-cloudtrail.html[logging data events]
for detailed steps.
"""
tags = [
    "Domain: Cloud",
    "Data Source: AWS",
    "Data Source: Amazon Web Services",
    "Data Source: AWS S3",
    "Use Case: Identity and Access Audit",
    "Tactic: Credential Access",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset: "aws.cloudtrail" and
    event.provider: "s3.amazonaws.com" and
    event.action: "GetObject" and
    event.outcome: "success" and
    aws.cloudtrail.flattened.request_parameters.key: (
        */.aws/credentials or
        */.aws/config or
        */id_rsa or
        */id_ed25519 or
        */id_ecdsa or
        */id_dsa or
        */.env or
        */.env.* or
        *.ppk or
        *.pem or
        *.key or
        *private_key* or
        */.ssh/authorized_keys
    ) and
    not aws.cloudtrail.user_identity.type: "AWSService"
'''

[[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.001"
name = "Credentials In Files"
reference = "https://attack.mitre.org/techniques/T1552/001/"

[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 = "T1530"
name = "Data from Cloud Storage"
reference = "https://attack.mitre.org/techniques/T1530/"

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

[rule.alert_suppression]
group_by = ["source.ip", "cloud.account.id"]
duration = {value = 5, unit = "m"}
missing_fields_strategy = "suppress"

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

Stages and Predicates

Stage 1: query

data_stream.dataset: "aws.cloudtrail" and
    event.provider: "s3.amazonaws.com" and
    event.action: "GetObject" and
    event.outcome: "success" and
    aws.cloudtrail.flattened.request_parameters.key: (
        */.aws/credentials or
        */.aws/config or
        */id_rsa or
        */id_ed25519 or
        */id_ecdsa or
        */id_dsa or
        */.env or
        */.env.* or
        *.ppk or
        *.pem or
        *.key or
        *private_key* or
        */.ssh/authorized_keys
    ) and
    not aws.cloudtrail.user_identity.type: "AWSService"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
aws.cloudtrail.flattened.request_parameters.keywildcard
  • *.key
  • *.pem
  • *.ppk
  • */.aws/config
  • */.aws/credentials
  • */.env
  • */.env.*
  • */.ssh/authorized_keys
  • */id_dsa
  • */id_ecdsa
  • */id_ed25519
  • */id_rsa
  • *private_key*
field:"aws.cloudtrail.flattened.request_parameters.key" kind:wildcard
data_stream.dataseteq
  • aws.cloudtrail corpus 143 (elastic 143)
field:"data_stream.dataset" kind:eq value:"aws.cloudtrail"
event.actioneq
  • GetObject
field:"EventType" kind:eq value:"GetObject"
event.outcomeeq
  • success corpus 306 (elastic 306)
field:"event.outcome" kind:eq value:"success"
event.providereq
  • s3.amazonaws.com corpus 8 (elastic 8)
field:"Provider_Name" kind:eq value:"s3.amazonaws.com"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
aws.cloudtrail.user_identity.typeeqAWSServiceexcludes:aws.cloudtrail.user_identity.type field:"aws.cloudtrail.user_identity.type" value:"AWSService"

Behavior - Prevented - Elastic Defend

#

This is a third-party alert feed, not a detection over modeled telemetry. Another security product raised the finding; this rule forwards or reshapes it into the SIEM. It is searchable for reference but is excluded from the detection-rule browse and the ATT&CK coverage matrix.

Status
production
Severity
low
Time window
2m
Author
Elastic
Source
github.com/elastic/detection-rules

Generates a detection alert each time an Elastic Defend alert for malicious behavior is received. Enabling this rule allows you to immediately begin investigating your Endpoint behavior alerts. This rule identifies Elastic Defend behavior preventions only, and does not include detection only alerts.

Rule Body

[metadata]
creation_date = "2024/03/24"
integration = ["endpoint"]
maturity = "production"
promotion = true
updated_date = "2025/07/02"

[rule]
author = ["Elastic"]
description = """
Generates a detection alert each time an Elastic Defend alert for malicious behavior is received. Enabling this rule
allows you to immediately begin investigating your Endpoint behavior alerts. This rule identifies Elastic Defend
behavior preventions only, and does not include detection only alerts.
"""
enabled = false
from = "now-2m"
index = ["logs-endpoint.alerts-*"]
interval = "1m"
language = "kuery"
license = "Elastic License v2"
max_signals = 1000
name = "Behavior - Prevented - Elastic Defend"
note = """## Triage and analysis

### Investigating Behavior - Prevented - Elastic Defend

Malicious behavior protection is a foundational feature which can be used to protect against all manner of attacks on the endpoint. For example, it provides coverage against phishing such as malicious macros, many malware families based on their activities, privilege escalation attacks such as user account control bypasses (UAC), credential theft, and much more. It works by consuming an unfiltered feed of all events that are captured on the system (process, file, registry, network, dns, etc). These events are processed against a routinely updated set of rules written by Elastic threat experts. From there, malicious behaviors are identified and offending processes are terminated. The protection operates on the event stream asynchronously, but has been designed to be extremely efficient and typically requires just milliseconds (under standard load) to stop malicious activity.

### Possible investigation steps

- Assess whether this activity is prevalent in your environment by looking for similar occurrences across hosts.
- Verify the detailed activity of the process that triggered the alert (process tree, child process, process arguments, network, files, libraries and registry events).
- Verify the activity of the `user.name` associated with the alert (local or remote actity, privileged or standard user).
- Particular attention should be paid to instances where the same process is triggering multiple alerts (more than 2 or 3) within a short period of time.
- Even the the process is signed by a valid certificate, verify the if it's running from the expected location or if it's loading any suspicious libraries or any sign of code injection.


### False positive analysis

- Same alert observed on a high number of hosts with similar details.
- High count of the same alert on a specific host over a long period of time.

### Response and Remediation

- Initiate the incident response process based on the outcome of the triage.
  - If malicious activity is confirmed, perform a broader investigation to identify the scope of the compromise and determine the appropriate remediation steps.
- Implement Elastic Endpoint Security to detect and prevent further post exploitation activities in the environment.
   - Contain the affected system by isolating it from the network to prevent further spread of the attack.
- 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.
- Restore the affected system to its operational state by applying any necessary patches, updates, or configuration changes.
- 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.
- 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).
"""
references = [
    "https://github.com/elastic/protections-artifacts/tree/main/behavior",
    "https://docs.elastic.co/en/integrations/endpoint",
]
risk_score = 21
rule_id = "eb804972-ea34-11ee-a417-f661ea17fbce"
rule_name_override = "message"
setup = """## Setup

### Elastic Defend Alerts
This rule is designed to capture specific alerts generated by Elastic Defend.

To capture all the Elastic Defend alerts, it is recommended to use all of the Elastic Defend feature-specific protection rules:

Behavior - Detected - Elastic Defend (UUID: 0f615fe4-eaa2-11ee-ae33-f661ea17fbce)
Behavior - Prevented - Elastic Defend (UUID: eb804972-ea34-11ee-a417-f661ea17fbce)
Malicious File - Detected - Elastic Defend (UUID: f2c3caa6-ea34-11ee-a417-f661ea17fbce)
Malicious File - Prevented - Elastic Defend (UUID: f87e6122-ea34-11ee-a417-f661ea17fbce)
Memory Threat - Detected - Elastic Defend (UUID: 017de1e4-ea35-11ee-a417-f661ea17fbce)
Memory Threat - Prevented - Elastic Defend (UUID: 06f3a26c-ea35-11ee-a417-f661ea17fbce)
Ransomware - Detected - Elastic Defend (UUID: 0c74cd7e-ea35-11ee-a417-f661ea17fbce)
Ransomware - Prevented - Elastic Defend (UUID: 10f3d520-ea35-11ee-a417-f661ea17fbce)

To avoid generating duplicate alerts, you should enable either all feature-specific protection rules or the Endpoint Security (Elastic Defend) rule (UUID: 9a1a2dae-0b5f-4c3d-8305-a268d404c306).

### Additional notes

For information on troubleshooting the maximum alerts warning please refer to this [guide](https://www.elastic.co/guide/en/security/current/alerts-ui-monitor.html#troubleshoot-max-alerts).
"""
severity = "low"
tags = ["Data Source: Elastic Defend", "Resources: Investigation Guide"]
timestamp_override = "event.ingested"
type = "query"

query = '''
event.kind : alert and event.code : behavior and event.type : denied and event.outcome : success
'''


[[rule.exceptions_list]]
id = "endpoint_list"
list_id = "endpoint_list"
namespace_type = "agnostic"
type = "endpoint"

[[rule.risk_score_mapping]]
field = "event.risk_score"
operator = "equals"
value = ""

[[rule.severity_mapping]]
field = "event.severity"
operator = "equals"
severity = "low"
value = "21"

[[rule.severity_mapping]]
field = "event.severity"
operator = "equals"
severity = "medium"
value = "47"

[[rule.severity_mapping]]
field = "event.severity"
operator = "equals"
severity = "high"
value = "73"

[[rule.severity_mapping]]
field = "event.severity"
operator = "equals"
severity = "critical"
value = "99"


Stages and Predicates

Stage 1: query

event.kind : alert and event.code : behavior and event.type : denied and event.outcome : success

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.codeeq
  • behavior corpus 2 (elastic 2)
field:"EventID" kind:eq value:"behavior"
event.kindeq
  • alert corpus 35 (elastic 35)
field:"event.kind" kind:eq value:"alert"
event.outcomeeq
  • success corpus 306 (elastic 306)
field:"event.outcome" kind:eq value:"success"
event.typeeq
  • denied corpus 8 (elastic 8)
field:"event.type" kind:eq value:"denied"

Cloud Instance Metadata Credential Path HTTP Request

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

Detects HTTP GET requests to the link-local instance metadata service (169.254.169.254) for cloud credential or token paths on AWS, GCP, or Azure. Adversaries and vulnerable workloads use scripts, shells, or application runtimes to read IAM role credentials or OAuth tokens from the metadata API. Requires the Network Packet Capture integration with HTTP decoding on ports 80 and 443 and process enrichment enabled so "process.*" fields are present.

Known False Positives

  • Cloud agents (SSM, waagent, cloud-init, instance connect) and authorized scanners may reach the same paths during provisioning or health checks. Exclude known agent user agents, source hosts, or parent processes after baselining.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2026/05/23"
integration = ["network_traffic"]
maturity = "production"
updated_date = "2026/05/23"

[rule]
author = ["Elastic"]
description = """
Detects HTTP GET requests to the link-local instance metadata service (169.254.169.254) for cloud credential or token
paths on AWS, GCP, or Azure. Adversaries and vulnerable workloads use scripts, shells, or application runtimes to read
IAM role credentials or OAuth tokens from the metadata API. Requires the Network Packet Capture integration with HTTP
decoding on ports 80 and 443 and process enrichment enabled so "process.*" fields are present.
"""
false_positives = [
    """
    Cloud agents (SSM, waagent, cloud-init, instance connect) and authorized scanners may reach the same paths during
    provisioning or health checks. Exclude known agent user agents, source hosts, or parent processes after baselining.
    """,
]
from = "now-9m"
index = ["logs-network_traffic.http*", "packetbeat-*"]
language = "eql"
license = "Elastic License v2"
name = "Cloud Instance Metadata Credential Path HTTP Request"
note = """## Triage and analysis

### Investigating Cloud Instance Metadata Credential Path HTTP Request

This rule matches outbound HTTP GETs to `169.254.169.254` where the URL path requests IAM credentials or cloud OAuth
tokens, filtered to common scripting runtimes, suspicious executable paths, or tool-like user agents.

### Investigation steps

- Confirm `url.path` (AWS `security-credentials`, GCP `oauth2/access_token`, Azure `metadata/identity/oauth2/token`).
- Review `process.name`, `process.executable`, and `user_agent.original` — scripted tools and temp-path binaries are higher risk.
- Check `host.name` or `host.hostname` and whether the workload should run on a cloud VM with an instance profile or managed identity.
- Correlate with cloud audit or sign-in logs for role assumption or token use shortly after the request.
- If credentials may have been exposed, rotate the instance role or managed identity and review API activity from that principal.

### False positives

- Platform agents and bootstrap scripts on new instances; allowlist by user agent or host group where validated.

### Response

- Restrict IMDS access (IMDSv2 hop limit, network policy) and remove unnecessary instance permissions.
- Investigate the host for follow-on credential use or lateral movement.

## Setup

Deploy the [Network Packet Capture](https://www.elastic.co/docs/reference/integrations/network_traffic) integration via Fleet on cloud workloads.

- Enable **Capture HTTP Traffic** and include ports **80** and **443**.
- Enable **Monitor Processes** so network events include the process that initiated the connection.
- Prefer ECS field remapping (`map_to_ecs`) on integration data streams.
"""
references = [
    "https://www.elastic.co/docs/reference/integrations/network_traffic",
    "https://hackingthe.cloud/aws/general-knowledge/intro_metadata_service/"
]
risk_score = 47
rule_id = "73dd1f2c-3c24-4e13-a64b-dfd510e9fd98"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Domain: Network",
    "OS: Linux",
    "OS: Windows",
    "OS: macOS",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Data Source: Network Packet Capture",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
network where event.module == "network_traffic" and destination.ip == "169.254.169.254" and destination.port == 80 and
http.request.method == "GET" and url.path : (
  "/latest/meta-data/iam/security-credentials/*",
  "*computeMetadata/v1/instance/service-accounts/*/oauth2/access_token*",
  "*metadata/identity/oauth2/token*"
) and (
  ?process.name : (
    "curl", "wget", "python*", "node", "bun", "php*", "ruby", "perl", "bash", "dash", "sh", "tcsh", "tclsh", "wish",
    "csh", "zsh", "ksh", "fish", "mksh", "busybox",
    "bun.exe", "node.exe", "powershell.exe", "cmd.exe", "curl.exe", "wget.exe", "rundll32.exe", "w3wp.exe", "java*", 
    "go", "nc", "netcat", "nginx", "apache*", "httpd", "tomcat*", "catalina", "spring*", "dotnet", "gunicorn", "uwsgi", 
    ".*", "osascript"
  ) or ?process.executable : (
    "/tmp/*", "/var/tmp/*", "/dev/shm/*", "/home/*/*", "/var/run/*", "/run/*", "/boot/*", "/.*", "C:\\Users\\*", "?:\\ProgramData\\*"
  ) or user_agent.original : (
    "curl*", "wget*", "python*", "ruby*", "Go-http-client*", "node*", "axios*", "undici*", "java*", "php*", "Bun*",
    "Apache-HttpClient*", "okhttp*", "RestTemplate*", "*WindowsPowerShell*", "*roadtools*", "*fasthttp*", "*azurehound*", "*bloodhound*", "*aiohttp*"
  )
)
'''


[[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/"

Stages and Predicates

Stage 1: network

network where event.module == "network_traffic" and destination.ip == "169.254.169.254" and destination.port == 80 and
http.request.method == "GET" and url.path : (
  "/latest/meta-data/iam/security-credentials/*",
  "*computeMetadata/v1/instance/service-accounts/*/oauth2/access_token*",
  "*metadata/identity/oauth2/token*"
) and (
  ?process.name : (
    "curl", "wget", "python*", "node", "bun", "php*", "ruby", "perl", "bash", "dash", "sh", "tcsh", "tclsh", "wish",
    "csh", "zsh", "ksh", "fish", "mksh", "busybox",
    "bun.exe", "node.exe", "powershell.exe", "cmd.exe", "curl.exe", "wget.exe", "rundll32.exe", "w3wp.exe", "java*", 
    "go", "nc", "netcat", "nginx", "apache*", "httpd", "tomcat*", "catalina", "spring*", "dotnet", "gunicorn", "uwsgi", 
    ".*", "osascript"
  ) or ?process.executable : (
    "/tmp/*", "/var/tmp/*", "/dev/shm/*", "/home/*/*", "/var/run/*", "/run/*", "/boot/*", "/.*", "C:\\Users\\*", "?:\\ProgramData\\*"
  ) or user_agent.original : (
    "curl*", "wget*", "python*", "ruby*", "Go-http-client*", "node*", "axios*", "undici*", "java*", "php*", "Bun*",
    "Apache-HttpClient*", "okhttp*", "RestTemplate*", "*WindowsPowerShell*", "*roadtools*", "*fasthttp*", "*azurehound*", "*bloodhound*", "*aiohttp*"
  )
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
destination.ipeq
  • 169.254.169.254 corpus 2 (elastic 1, kusto 1)
field:"dest_ip" kind:eq value:"169.254.169.254"
destination.porteq
  • 80 transforms: number corpus 4 (elastic 4)
field:"DestinationPort" kind:eq value:"80"
event.moduleeq
  • network_traffic corpus 2 (elastic 2)
field:"event.module" kind:eq value:"network_traffic"
http.request.methodeq
  • GET corpus 5 (elastic 5)
field:"http.request.method" kind:eq value:"GET"
process.executablewildcard
  • /.* corpus 2 (elastic 2)
  • /boot/* corpus 8 (elastic 8)
  • /dev/shm/* corpus 14 (elastic 14)
  • /home/*/* corpus 9 (elastic 9)
  • /run/* corpus 9 (elastic 9)
  • /tmp/* corpus 17 (elastic 17)
  • /var/run/* corpus 5 (elastic 5)
  • /var/tmp/* corpus 16 (elastic 16)
  • ?:\ProgramData\* corpus 18 (elastic 18)
  • C:\Users\* corpus 2 (elastic 2)
field:"Image" kind:wildcard
process.namewildcard
  • .* corpus 8 (elastic 8)
  • apache* corpus 2 (elastic 2)
  • bash corpus 33 (elastic 33)
  • bun corpus 2 (elastic 2)
  • bun.exe corpus 3 (elastic 3)
  • busybox corpus 5 (elastic 5)
  • catalina
  • cmd.exe corpus 8 (elastic 8)
  • csh corpus 13 (elastic 13)
  • curl corpus 28 (elastic 28)
  • curl.exe corpus 7 (elastic 7)
  • dash corpus 16 (elastic 16)
  • dotnet
  • fish corpus 14 (elastic 14)
  • go
  • gunicorn corpus 3 (elastic 3)
  • httpd corpus 2 (elastic 2)
  • java* corpus 2 (elastic 2)
  • ksh corpus 16 (elastic 16)
  • mksh corpus 4 (elastic 4)
  • nc corpus 12 (elastic 12)
  • netcat corpus 12 (elastic 12)
  • nginx corpus 3 (elastic 3)
  • node corpus 11 (elastic 11)
  • node.exe corpus 8 (elastic 8)
  • osascript corpus 31 (elastic 31)
  • perl corpus 10 (elastic 10)
  • php* corpus 22 (elastic 22)
  • powershell.exe corpus 12 (elastic 12)
  • python* corpus 51 (elastic 51)
  • ruby corpus 11 (elastic 11)
  • rundll32.exe corpus 8 (elastic 8)
  • sh corpus 33 (elastic 33)
  • spring*
  • tclsh corpus 2 (elastic 2)
  • tcsh corpus 16 (elastic 16)
  • tomcat*
  • uwsgi corpus 3 (elastic 3)
  • w3wp.exe corpus 2 (elastic 2)
  • wget corpus 16 (elastic 16)
  • wget.exe corpus 2 (elastic 2)
  • wish
  • zsh corpus 31 (elastic 31)
field:"process_basename" kind:wildcard
url.pathwildcard
  • *computeMetadata/v1/instance/service-accounts/*/oauth2/access_token*
  • *metadata/identity/oauth2/token*
  • /latest/meta-data/iam/security-credentials/*
field:"url.path" kind:wildcard
user_agent.originalwildcard
  • *WindowsPowerShell*
  • *aiohttp*
  • *azurehound*
  • *bloodhound*
  • *fasthttp*
  • *roadtools*
  • Apache-HttpClient*
  • Bun*
  • Go-http-client*
  • RestTemplate*
  • axios*
  • curl*
  • java*
  • node*
  • okhttp*
  • php*
  • python*
  • ruby*
  • undici*
  • wget*
field:"aws::userAgent" kind:wildcard

Domain Password Policy Enumeration via LDAP

#
Source
github.com/elastic/protections-artifacts

Detects LDAP search queries commonly used to enumerate domain password policies. Adversaries may perform this activity to identify potential weaknesses that could be exploited for privilege escalation or lateral movement.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Detects LDAP search queries commonly used to enumerate domain password policies. Adversaries may perform this activity
to identify potential weaknesses that could be exploited for privilege escalation or lateral movement.
"""
id = "bbf68a5c-9346-40f4-8a9b-da3d9136f39f"
license = "Elastic License v2"
name = "Domain Password Policy Enumeration via LDAP"
os_list = ["windows"]
reference = ["https://attack.mitre.org/techniques/T1201/"]
version = "1.0.3"

query = '''
api where process.Ext.api.name == "ldap_search" and user.id != "S-1-5-18" and
not process.executable :
             ("?:\\Program Files\\Azure Advanced Threat Protection Sensor\\*\\Microsoft.Tri.Sensor.exe",
              "?:\\Windows\\ADFS\\Microsoft.IdentityServer.ServiceHost.exe",
              "?:\\Windows\\ADWS\\Microsoft.ActiveDirectory.WebServices.exe") and
(
  (process.Ext.api.parameters.search_filter : "*msDS-PasswordSettings*" and
   process.Ext.api.parameters.attribute_list == "msDS-MinimumPasswordLength" and process.Ext.api.parameters.attribute_list == "msDS-LockoutThreshold") or

  process.Ext.api.parameters.search_filter : "*(pwdlastset>=*(operatingSystem=*windows*))"
)
'''

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1087"
name = "Account Discovery"
reference = "https://attack.mitre.org/techniques/T1087/"
[[threat.technique.subtechnique]]
id = "T1087.002"
name = "Domain Account"
reference = "https://attack.mitre.org/techniques/T1087/002/"


[[threat.technique]]
id = "T1201"
name = "Password Policy Discovery"
reference = "https://attack.mitre.org/techniques/T1201/"


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

[internal]
min_endpoint_version = "9.1.0"

Stages and Predicates

Stage 1: api

api where process.Ext.api.name == "ldap_search" and user.id != "S-1-5-18" and
not process.executable :
             ("?:\\Program Files\\Azure Advanced Threat Protection Sensor\\*\\Microsoft.Tri.Sensor.exe",
              "?:\\Windows\\ADFS\\Microsoft.IdentityServer.ServiceHost.exe",
              "?:\\Windows\\ADWS\\Microsoft.ActiveDirectory.WebServices.exe") and
(
  (process.Ext.api.parameters.search_filter : "*msDS-PasswordSettings*" and
   process.Ext.api.parameters.attribute_list == "msDS-MinimumPasswordLength" and process.Ext.api.parameters.attribute_list == "msDS-LockoutThreshold") or

  process.Ext.api.parameters.search_filter : "*(pwdlastset>=*(operatingSystem=*windows*))"
)

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.executablewildcard?:\Program Files\Azure Advanced Threat Protection Sensor\*\Microsoft.Tri.Sensor.exe, ?:\Windows\ADFS\Microsoft.IdentityServer.ServiceHost.exe, ?:\Windows\ADWS\Microsoft.ActiveDirectory.WebServices.exeexcludes:process.executable field:"process.executable" value:"?:\Program Files\Azure Advanced Threat Protection Sensor\*\Microsoft.Tri.Sensor.exe" field:"process.executable" value:"?:\Windows\ADFS\Microsoft.IdentityServer.ServiceHost.exe" field:"process.executable" value:"?:\Windows\ADWS\Microsoft.ActiveDirectory.WebServices.exe"

Entra ID MFA TOTP Brute Force Attempted

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

Identifies brute force attempts against Azure Entra multi-factor authentication (MFA) Time-based One-Time Password (TOTP) verification codes. This rule detects high frequency failed TOTP code attempts for a single user in a short time-span with a high number of distinct session IDs. Adversaries may programmatically attemopt to brute-force TOTP codes by generating several sessions and attempt to guess the correct code.

Known False Positives

  • Based on the high-frequency threshold, it would be unlikely for a legitimate user to exceed the threshold for failed TOTP code attempts in a short time-span over multiple sessions.

MITRE ATT&CK Coverage

TacticTechniques
Credential Access

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2024/12/11"
integration = ["azure"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Identifies brute force attempts against Azure Entra multi-factor authentication (MFA) Time-based One-Time Password
(TOTP) verification codes. This rule detects high frequency failed TOTP code attempts for a single user in a short
time-span with a high number of distinct session IDs. Adversaries may programmatically attemopt to brute-force TOTP
codes by generating several sessions and attempt to guess the correct code.
"""
false_positives = [
    """
    Based on the high-frequency threshold, it would be unlikely for a legitimate user to exceed the threshold for failed
    TOTP code attempts in a short time-span over multiple sessions.
    """,
]
from = "now-9m"
language = "esql"
license = "Elastic License v2"
name = "Entra ID MFA TOTP Brute Force Attempted"
note = """## Triage and analysis

### Investigating Entra ID MFA TOTP Brute Force Attempted

This rule detects brute force attempts against Azure Entra multi-factor authentication (MFA) Time-based One-Time Password (TOTP) verification codes. It identifies high-frequency failed TOTP code attempts for a single user in a short time-span with a high number of distinct session IDs. Adversaries may programmatically attempt to brute-force TOTP codes by generating several sessions and attempting to guess the correct code.

#### Possible Investigation Steps:

    - Check the source addresses associated with the failed TOTP attempts.
    - Determine if the source IP address is consistent with the user’s typical login locations.
    - Look for unusual geographic patterns or anomalous IP addresses (e.g., proxies, VPNs, or locations outside the user’s normal activity).
    - Review the error code associated with the failed attempts. This can help identify if the failures are due to incorrect TOTP codes or other issues.
    - Verify that that auth metho reported is `OAth` as it indicates the use of TOTP codes.
    - Pivot into signin logs for the target user and check if auth via TOTP was successful which would indicate a successful brute force attempt.
    - Review conditional access policies applied to the user or group as reported by the sign-in logs.
    - Analyze the client application ID and display name to determine if the attempts are coming from a legitimate application or a potentially malicious script.
        - Adversaries may use legitimate FOCI applications to bypass security controls or make login attempts appear legitimate.
    - Review the resource ID access is being attempted against such as MyApps, Microsoft Graph, or other resources. This can help identify if the attempts are targeting specific applications or services.
    - The correlation IDs or session IDs can be used to trace the authentication attempts across different logs or systems. Note that for this specific behavior, unique session ID count is high and could be challenging to correlate.

#### False Positive Analysis:

    - Verify if the failed attempts could result from the user’s unfamiliarity with TOTP codes or issues with device synchronization.
    - Check if the user recently switched MFA methods or devices, which could explain multiple failures.
    - Determine if this is whitebox testing or a developer testing MFA integration.

#### Response and Remediation:

    - If proven malicious, lock the affected account temporarily to prevent further unauthorized attempts.
    - Notify the user of suspicious activity and validate their access to the account.
    - Reset passwords and MFA settings for the affected user to prevent unauthorized access while communicating with the user.
    - Ensure conditional access policies are configured to monitor and restrict anomalous login behavior.
    - Consider a different MFA method or additional security controls to prevent future bypass attempts.
    - Implement additional monitoring to track high-frequency authentication failures across the environment.
    - Audit historical logs for similar patterns involving other accounts to identify broader threats.
    - Provide guidance on the secure use of MFA and the importance of recognizing and reporting suspicious activity.
"""
references = [
    "https://www.oasis.security/resources/blog/oasis-security-research-team-discovers-microsoft-azure-mfa-bypass",
    "https://learn.microsoft.com/en-us/entra/identity/",
    "https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-sign-ins",
]
risk_score = 47
rule_id = "3fac01b2-b811-11ef-b25b-f661ea17fbce"
setup = """#### Required Entra ID Sign-In Logs
This rule requires the Entra ID sign-in logs via the Azure integration be enabled. In Entra ID, sign-in logs must be enabled and streaming to the Event Hub used for the Entra ID logs integration.
"""
severity = "medium"
tags = [
    "Domain: Cloud",
    "Domain: Identity",
    "Data Source: Azure",
    "Data Source: Entra ID",
    "Data Source: Entra ID Sign-in logs",
    "Use Case: Identity and Access Audit",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"

query = '''
from logs-azure.signinlogs-* metadata _id, _version, _index

| where
    // filter for Entra Sign-in Logs
    data_stream.dataset == "azure.signinlogs"
    and azure.signinlogs.operation_name == "Sign-in activity"
    and azure.signinlogs.properties.user_type == "Member"

    // filter for MFA attempts with OATH conditional access attempts or TOTP
    and azure.signinlogs.properties.mfa_detail.auth_method == "OATH verification code"

    // filter on failures only from brute-force attempts
    and (
            (
                azure.signinlogs.result_signature == "FAILURE" and
                azure.signinlogs.result_description == "Authentication failed during strong authentication request."
            ) or azure.signinlogs.properties.status.error_code == 500121
        )

| stats
    Esql.event_count = count(*),
    Esql.azure_signinlogs_properties_session_id_count_distinct = count_distinct(azure.signinlogs.properties.session_id),
    Esql.source_address_values = values(source.address),
    Esql.azure_tenant_id_valuues = values(azure.tenant_id),
    Esql_priv.azure_identity_values = values(azure.signinlogs.identity),
    Esql_priv.azure_signinlogs_properties_user_principal_name_values = values(azure.signinlogs.properties.user_principal_name),
    Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id),
    Esql.azure_signinlogs_properties_app_display_name_values = values(azure.signinlogs.properties.app_display_name),
    Esql.azure_signinlogs_properties_authentication_requirement_values = values(azure.signinlogs.properties.authentication_requirement),
    Esql.azure_signinlogs_properties_authentication_protocol_values = values(azure.signinlogs.properties.authentication_protocol),
    Esql.azure_signinlogs_properties_client_app_used_values = values(azure.signinlogs.properties.client_app_used),
    Esql.azure_signinlogs_properties_client_credential_type_values = values(azure.signinlogs.properties.client_credential_type),
    Esql.azure_signinlogs_properties_conditional_access_status_values = values(azure.signinlogs.properties.conditional_access_status),
    Esql.azure_signinlogs_properties_correlation_id_values = values(azure.signinlogs.properties.correlation_id),
    Esql.azure_signinlogs_properties_is_interactive_values = values(azure.signinlogs.properties.is_interactive),
    Esql.azure_signinlogs_properties_mfa_detail_auth_method_values = values(azure.signinlogs.properties.mfa_detail.auth_method),
    Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name),
    Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id),
    Esql.azure_signinlogs_properties_risk_state_values = values(azure.signinlogs.properties.risk_state),
    Esql.azure_signinlogs_properties_risk_detail_values = values(azure.signinlogs.properties.risk_detail),
    Esql.azure_signinlogs_properties_status_error_code_values = values(azure.signinlogs.properties.status.error_code),
    Esql.azure_signinlogs_properties_original_request_id_values = values(azure.signinlogs.properties.original_request_id),
    Esql.user_id_values = values(user.id)
    by user.id

| where Esql.event_count >= 20 and Esql.azure_signinlogs_properties_session_id_count_distinct >= 10

| keep
    Esql.event_count,
    Esql.azure_signinlogs_properties_session_id_count_distinct,
    Esql.source_address_values,
    Esql.azure_tenant_id_valuues,
    Esql_priv.azure_identity_values,
    Esql_priv.azure_signinlogs_properties_user_principal_name_values,
    Esql.azure_signinlogs_properties_app_id_values,
    Esql.azure_signinlogs_properties_app_display_name_values,
    Esql.azure_signinlogs_properties_authentication_requirement_values,
    Esql.azure_signinlogs_properties_authentication_protocol_values,
    Esql.azure_signinlogs_properties_client_app_used_values,
    Esql.azure_signinlogs_properties_client_credential_type_values,
    Esql.azure_signinlogs_properties_conditional_access_status_values,
    Esql.azure_signinlogs_properties_correlation_id_values,
    Esql.azure_signinlogs_properties_is_interactive_values,
    Esql.azure_signinlogs_properties_mfa_detail_auth_method_values,
    Esql.azure_signinlogs_properties_resource_display_name_values,
    Esql.azure_signinlogs_properties_resource_id_values,
    Esql.azure_signinlogs_properties_risk_state_values,
    Esql.azure_signinlogs_properties_risk_detail_values,
    Esql.azure_signinlogs_properties_status_error_code_values,
    Esql.azure_signinlogs_properties_original_request_id_values,
    Esql.user_id_values
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1110"
name = "Brute Force"
reference = "https://attack.mitre.org/techniques/T1110/"
[[rule.threat.technique.subtechnique]]
id = "T1110.001"
name = "Password Guessing"
reference = "https://attack.mitre.org/techniques/T1110/001/"



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

Stages and Predicates

Stage 1: from

from logs-azure.signinlogs-* metadata _id, _version, _index

Stage 2: where

| where
    data_stream.dataset == "azure.signinlogs"
    and azure.signinlogs.operation_name == "Sign-in activity"
    and azure.signinlogs.properties.user_type == "Member"
    and azure.signinlogs.properties.mfa_detail.auth_method == "OATH verification code"
    and (
            (
                azure.signinlogs.result_signature == "FAILURE" and
                azure.signinlogs.result_description == "Authentication failed during strong authentication request."
            ) or azure.signinlogs.properties.status.error_code == 500121
        )

Stage 3: stats

| stats
    Esql.event_count = count(*),
    Esql.azure_signinlogs_properties_session_id_count_distinct = count_distinct(azure.signinlogs.properties.session_id),
    Esql.source_address_values = values(source.address),
    Esql.azure_tenant_id_valuues = values(azure.tenant_id),
    Esql_priv.azure_identity_values = values(azure.signinlogs.identity),
    Esql_priv.azure_signinlogs_properties_user_principal_name_values = values(azure.signinlogs.properties.user_principal_name),
    Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id),
    Esql.azure_signinlogs_properties_app_display_name_values = values(azure.signinlogs.properties.app_display_name),
    Esql.azure_signinlogs_properties_authentication_requirement_values = values(azure.signinlogs.properties.authentication_requirement),
    Esql.azure_signinlogs_properties_authentication_protocol_values = values(azure.signinlogs.properties.authentication_protocol),
    Esql.azure_signinlogs_properties_client_app_used_values = values(azure.signinlogs.properties.client_app_used),
    Esql.azure_signinlogs_properties_client_credential_type_values = values(azure.signinlogs.properties.client_credential_type),
    Esql.azure_signinlogs_properties_conditional_access_status_values = values(azure.signinlogs.properties.conditional_access_status),
    Esql.azure_signinlogs_properties_correlation_id_values = values(azure.signinlogs.properties.correlation_id),
    Esql.azure_signinlogs_properties_is_interactive_values = values(azure.signinlogs.properties.is_interactive),
    Esql.azure_signinlogs_properties_mfa_detail_auth_method_values = values(azure.signinlogs.properties.mfa_detail.auth_method),
    Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name),
    Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id),
    Esql.azure_signinlogs_properties_risk_state_values = values(azure.signinlogs.properties.risk_state),
    Esql.azure_signinlogs_properties_risk_detail_values = values(azure.signinlogs.properties.risk_detail),
    Esql.azure_signinlogs_properties_status_error_code_values = values(azure.signinlogs.properties.status.error_code),
    Esql.azure_signinlogs_properties_original_request_id_values = values(azure.signinlogs.properties.original_request_id),
    Esql.user_id_values = values(user.id)
    by user.id

Stage 4: where

| where Esql.event_count >= 20 and Esql.azure_signinlogs_properties_session_id_count_distinct >= 10

Stage 5: keep

| keep
    Esql.event_count,
    Esql.azure_signinlogs_properties_session_id_count_distinct,
    Esql.source_address_values,
    Esql.azure_tenant_id_valuues,
    Esql_priv.azure_identity_values,
    Esql_priv.azure_signinlogs_properties_user_principal_name_values,
    Esql.azure_signinlogs_properties_app_id_values,
    Esql.azure_signinlogs_properties_app_display_name_values,
    Esql.azure_signinlogs_properties_authentication_requirement_values,
    Esql.azure_signinlogs_properties_authentication_protocol_values,
    Esql.azure_signinlogs_properties_client_app_used_values,
    Esql.azure_signinlogs_properties_client_credential_type_values,
    Esql.azure_signinlogs_properties_conditional_access_status_values,
    Esql.azure_signinlogs_properties_correlation_id_values,
    Esql.azure_signinlogs_properties_is_interactive_values,
    Esql.azure_signinlogs_properties_mfa_detail_auth_method_values,
    Esql.azure_signinlogs_properties_resource_display_name_values,
    Esql.azure_signinlogs_properties_resource_id_values,
    Esql.azure_signinlogs_properties_risk_state_values,
    Esql.azure_signinlogs_properties_risk_detail_values,
    Esql.azure_signinlogs_properties_status_error_code_values,
    Esql.azure_signinlogs_properties_original_request_id_values,
    Esql.user_id_values

Indicators

These rows show field, operator, and value matches.

Output Fields

These fields are emitted when the rule matches.

FieldSource
Esql.event_countKEEP Esql.event_count
Esql.azure_signinlogs_properties_session_id_count_distinctKEEP Esql.azure_signinlogs_properties_session_id_count_distinct
Esql.source_address_valuesKEEP Esql.source_address_values
Esql.azure_tenant_id_valuuesKEEP Esql.azure_tenant_id_valuues
Esql_priv.azure_identity_valuesKEEP Esql_priv.azure_identity_values
Esql_priv.azure_signinlogs_properties_user_principal_name_valuesKEEP Esql_priv.azure_signinlogs_properties_user_principal_name_values
Esql.azure_signinlogs_properties_app_id_valuesKEEP Esql.azure_signinlogs_properties_app_id_values
Esql.azure_signinlogs_properties_app_display_name_valuesKEEP Esql.azure_signinlogs_properties_app_display_name_values
Esql.azure_signinlogs_properties_authentication_requirement_valuesKEEP Esql.azure_signinlogs_properties_authentication_requirement_values
Esql.azure_signinlogs_properties_authentication_protocol_valuesKEEP Esql.azure_signinlogs_properties_authentication_protocol_values
Esql.azure_signinlogs_properties_client_app_used_valuesKEEP Esql.azure_signinlogs_properties_client_app_used_values
Esql.azure_signinlogs_properties_client_credential_type_valuesKEEP Esql.azure_signinlogs_properties_client_credential_type_values
Esql.azure_signinlogs_properties_conditional_access_status_valuesKEEP Esql.azure_signinlogs_properties_conditional_access_status_values
Esql.azure_signinlogs_properties_correlation_id_valuesKEEP Esql.azure_signinlogs_properties_correlation_id_values
Esql.azure_signinlogs_properties_is_interactive_valuesKEEP Esql.azure_signinlogs_properties_is_interactive_values
Esql.azure_signinlogs_properties_mfa_detail_auth_method_valuesKEEP Esql.azure_signinlogs_properties_mfa_detail_auth_method_values
Esql.azure_signinlogs_properties_resource_display_name_valuesKEEP Esql.azure_signinlogs_properties_resource_display_name_values
Esql.azure_signinlogs_properties_resource_id_valuesKEEP Esql.azure_signinlogs_properties_resource_id_values
Esql.azure_signinlogs_properties_risk_state_valuesKEEP Esql.azure_signinlogs_properties_risk_state_values
Esql.azure_signinlogs_properties_risk_detail_valuesKEEP Esql.azure_signinlogs_properties_risk_detail_values
Esql.azure_signinlogs_properties_status_error_code_valuesKEEP Esql.azure_signinlogs_properties_status_error_code_values
Esql.azure_signinlogs_properties_original_request_id_valuesKEEP Esql.azure_signinlogs_properties_original_request_id_values
Esql.user_id_valuesKEEP Esql.user_id_values

Entra ID User Sign-in with Unusual Authentication Type

#
Status
production
Severity
medium
Time window
9m
Group by
azure.signinlogs.properties.authentication_details.authentication_method, azure.signinlogs.properties.user_principal_name
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies rare instances of authentication methods for Microsoft Entra ID principal users. An adversary with stolen credentials may attempt to authenticate with an unusual method, which may indicate an attempt to bypass conditional access policies (CAP) and multi-factor authentication (MFA) requirements. The authentication method may not be commonly used by the user based on their historical sign-in activity.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2025/03/10"
integration = ["azure"]
maturity = "production"
updated_date = "2026/08/12"

[rule]
author = ["Elastic"]
description = """
Identifies rare instances of authentication methods for Microsoft Entra ID principal users. An adversary with stolen
credentials may attempt to authenticate with an unusual method, which may indicate an attempt to bypass conditional
access policies (CAP) and multi-factor authentication (MFA) requirements. The authentication method may not be commonly
used by the user based on their historical sign-in activity.
"""
from = "now-9m"
index = ["filebeat-*", "logs-azure.signinlogs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Entra ID User Sign-in with Unusual Authentication Type"
note = """## Triage and analysis

### Investigating Entra ID User Sign-in with Unusual Authentication Type

Identifies rare instances of authentication methods for Microsoft Entra ID principal users. An adversary with stolen credentials may attempt to authenticate with an unusual method, which may indicate an attempt to bypass conditional access policies (CAP) and multi-factor authentication (MFA) requirements. The authentication method may not be commonly used by the user based on their historical sign-in activity.

**This is a New Terms rule that focuses on the first occurrence of an Entra ID principal user `azure.signinlogs.properties.user_principal_name` and their authentication method `azure.signinlogs.properties.authentication_details.authentication_method` in the last 14 days.**

### Possible investigation steps

- Identify the source IP address by reviewing `source.ip`. Determine whether it is associated with known malicious activity, an unexpected location or hosting provider, or approved corporate infrastructure.
- Review `azure.signinlogs.properties.user_principal_name` to determine whether the account is privileged or otherwise high value, and compare the sign-in with the user's recent activity.
- Examine `azure.signinlogs.properties.authentication_details.authentication_method` and determine whether the method is expected for the user. Review recent authentication-method registration or modification events.
- Review `azure.signinlogs.properties.app_id`, `azure.signinlogs.properties.client_app_used`, and the target resource to determine whether the application and access pattern are expected.
- Examine device, browser, user-agent, authentication protocol, and token details for signs of an unfamiliar client or session.
- Review `azure.signinlogs.properties.authentication_requirement` and the applicable conditional access policies to determine why the sign-in did not require MFA.

## False positive analysis

### Common benign scenarios
- Users enrolling in or switching to a different authentication method may trigger this detection the first time the method is observed.
- Automated scripts or applications using non-interactive authentication may trigger this detection, particularly if they rely on legacy authentication protocols recorded in `azure.signinlogs.properties.authentication_protocol`.
- Changes to an organization's authentication or conditional access policies may cause a previously unseen authentication method to be recorded for a user.

### How to reduce false positives
- Exclude known trusted IPs, such as corporate infrastructure, from alerts by filtering `source.ip`.
- Exclude known custom applications from `azure.signinlogs.properties.app_id` that are authorized to use non-interactive authentication.
- Correlate alerts with approved authentication-method enrollment or policy changes before adding exceptions.

## Response and remediation

### Immediate actions
- Block the source IP address in `source.ip` if determined to be malicious.
- If the sign-in is unauthorized, disable the affected account, revoke active sessions and tokens, and reset its credentials.
- Ensure basic authentication is disabled for all applications using legacy authentication protocols listed in `azure.signinlogs.properties.authentication_protocol`.
- Enable multi-factor authentication (MFA) for impacted accounts to mitigate credential-based attacks.
- Review conditional access policies to enforce risk-based authentication and block unauthorized access recorded in `azure.signinlogs.properties.authentication_requirement`.

### Long-term mitigation
- Implement a zero-trust security model by enforcing least privilege access and continuous authentication.
- Regularly review and update conditional access policies to ensure they are effective against evolving threats.
- Restrict the use of legacy authentication protocols by disabling authentication methods listed in `azure.signinlogs.properties.client_app_used`.
- Regularly audit authentication logs in `azure.signinlogs` to detect abnormal login behavior and ensure early detection of potential attacks.
- Regularly rotate client credentials and secrets for applications using non-interactive authentication to reduce the risk of credential theft.
"""
risk_score = 47
rule_id = "9e11faee-fddb-11ef-8257-f661ea17fbcd"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Data Source: Azure",
    "Data Source: Microsoft Entra ID",
    "Data Source: Microsoft Entra ID Sign-in Logs",
    "Platform: Entra ID",
    "Use Case: Identity and Access Audit",
    "Use Case: Threat Detection",
    "Tactic: Initial Access",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"

query = '''
data_stream.dataset: "azure.signinlogs" and event.category: "authentication"
    and azure.signinlogs.properties.user_type: "Member"
    and not azure.signinlogs.properties.device_detail.browser: *
    and not source.as.organization.name: "MICROSOFT-CORP-MSN-AS-BLOCK"
    and not azure.signinlogs.properties.authentication_requirement: "multiFactorAuthentication"
    and azure.signinlogs.properties.authentication_details.authentication_method:*
    and event.outcome:success
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"
[[rule.threat.technique.subtechnique]]
id = "T1078.004"
name = "Cloud Accounts"
reference = "https://attack.mitre.org/techniques/T1078/004/"



[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[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]]
id = "T1556"
name = "Modify Authentication Process"
reference = "https://attack.mitre.org/techniques/T1556/"
[[rule.threat.technique.subtechnique]]
id = "T1556.006"
name = "Multi-Factor Authentication"
reference = "https://attack.mitre.org/techniques/T1556/006/"



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

[rule.new_terms]
field = "new_terms_fields"
value = [
    "azure.signinlogs.properties.user_principal_name",
    "azure.signinlogs.properties.authentication_details.authentication_method",
]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-14d"


Stages and Predicates

Stage 1: new_terms

data_stream.dataset: "azure.signinlogs" and event.category: "authentication"
    and azure.signinlogs.properties.user_type: "Member"
    and not azure.signinlogs.properties.device_detail.browser: *
    and not source.as.organization.name: "MICROSOFT-CORP-MSN-AS-BLOCK"
    and not azure.signinlogs.properties.authentication_requirement: "multiFactorAuthentication"
    and azure.signinlogs.properties.authentication_details.authentication_method:*
    and event.outcome:success

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
azure.signinlogs.properties.authentication_requirementeqmultiFactorAuthenticationexcludes:azure.signinlogs.properties.authentication_requirement field:"azure.signinlogs.properties.authentication_requirement" value:"multiFactorAuthentication"
azure.signinlogs.properties.device_detail.browseris_not_null(no value, null check)excludes:azure.signinlogs.properties.device_detail.browser
source.as.organization.nameeqMICROSOFT-CORP-MSN-AS-BLOCKexcludes:source.as.organization.name field:"source.as.organization.name" value:"MICROSOFT-CORP-MSN-AS-BLOCK"

Execution via Suspicious JavaScript Updates

#
Source
github.com/elastic/protections-artifacts

Identifies the execution of a Windows script with a file name following a phishing naming convention commonly used by SocGolish. SocGholish is an initial access threat that leverages drive-by-downloads masquerading as software updates.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the execution of a Windows script with a file name following a phishing naming convention commonly used by
SocGolish. SocGholish is an initial access threat that leverages drive-by-downloads masquerading as software updates.
"""
id = "28d4818c-7da1-4173-bb7c-4b7bb8f0976f"
license = "Elastic License v2"
name = "Execution via Suspicious JavaScript Updates"
os_list = ["windows"]
reference = ["https://malpedia.caad.fkie.fraunhofer.de/details/js.fakeupdates"]
version = "1.0.27"

query = '''
process where event.action == "start" and
 process.pe.original_file_name in ("cscript.exe", "wscript.exe") and
 (
  process.args :
        (
         /* Temp archive file */
         "?:\\Users\\*\\AppData\\Local\\Temp\\7z*\\*.Update.*.js",
         "?:\\Users\\*\\AppData\\Local\\Temp\\Rar$*\\*.Update.*.js",
         "?:\\Users\\*\\AppData\\Local\\Temp\\Temp?_*\\*.Update.*.js",
         "?:\\Users\\*\\AppData\\Local\\Temp\\BNZ.*",

         /* extracted by victim user to a random folder */
         "?:\\Users\\*\\chrome.update.*.js",
         "?:\\Users\\*\\firefox.update.*.js",
         "?:\\Users\\*\\Opera.update.*.js",
         "?:\\Users\\*\\Firefox.js",
         "?:\\Users\\*\\Chrome.js",
         "?:\\Users\\*\\Edge.js",
         "?:\\Users\\*\\Opera.js"
         ) or

  /* execution from mounted ISO or IMG  */
   (process.args regex~ """[D-Z]:\\[a-z0-9]+\.Update\.[a-z0-9]+\.js""" and process.working_directory : "?:\\" )
  )
'''

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 = "T1566"
name = "Phishing"
reference = "https://attack.mitre.org/techniques/T1566/"
[[threat.technique.subtechnique]]
id = "T1566.001"
name = "Spearphishing Attachment"
reference = "https://attack.mitre.org/techniques/T1566/001/"



[threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[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.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 = "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 = "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 :
        (
         "?:\\Users\\*\\AppData\\Local\\Temp\\7z*\\*.Update.*.js",
         "?:\\Users\\*\\AppData\\Local\\Temp\\Rar$*\\*.Update.*.js",
         "?:\\Users\\*\\AppData\\Local\\Temp\\Temp?_*\\*.Update.*.js",
         "?:\\Users\\*\\AppData\\Local\\Temp\\BNZ.*",
         "?:\\Users\\*\\chrome.update.*.js",
         "?:\\Users\\*\\firefox.update.*.js",
         "?:\\Users\\*\\Opera.update.*.js",
         "?:\\Users\\*\\Firefox.js",
         "?:\\Users\\*\\Chrome.js",
         "?:\\Users\\*\\Edge.js",
         "?:\\Users\\*\\Opera.js"
         ) or
   (process.args regex~ """[D-Z]:\\[a-z0-9]+\.Update\.[a-z0-9]+\.js""" and process.working_directory : "?:\\" )
  )

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq value:"start"
process.argsregex_match
  • [D-Z]:\[a-z0-9]+.Update.[a-z0-9]+.js
field:"process.args" kind:regex_match value:"[D-Z]:\[a-z0-9]+.Update.[a-z0-9]+.js"
process.argswildcard
  • ?:\Users\*\AppData\Local\Temp\7z*\*.Update.*.js
  • ?:\Users\*\AppData\Local\Temp\BNZ.* corpus 2 (elastic 2)
  • ?:\Users\*\AppData\Local\Temp\Rar$*\*.Update.*.js
  • ?:\Users\*\AppData\Local\Temp\Temp?_*\*.Update.*.js
  • ?:\Users\*\Chrome.js
  • ?:\Users\*\Edge.js
  • ?:\Users\*\Firefox.js
  • ?:\Users\*\Opera.js
  • ?:\Users\*\Opera.update.*.js
  • ?:\Users\*\chrome.update.*.js
  • ?:\Users\*\firefox.update.*.js
field:"process.args" kind:wildcard
process.pe.original_file_namein
  • cscript.exe corpus 9 (elastic 9)
  • wscript.exe corpus 9 (elastic 9)
field:"OriginalFileName" kind:in
process.working_directorywildcard
  • ?:\ corpus 8 (elastic 8)
field:"CurrentDirectory" kind:wildcard value:"?:\"

GCP IAM Custom Role Creation

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

Identifies an Identity and Access Management (IAM) custom role creation in Google Cloud Platform (GCP). Custom roles are user-defined, and allow for the bundling of one or more supported permissions to meet specific needs. Custom roles will not be updated automatically and could lead to privilege creep if not carefully scrutinized.

Known False Positives

  • Custom role creations may be done by a system or network administrator. Verify whether the user email, resource name, and/or hostname should be making changes in your environment. Role creations by unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2020/09/21"
integration = ["gcp"]
maturity = "production"
updated_date = "2026/07/08"

[rule]
author = ["Elastic"]
description = """
Identifies an Identity and Access Management (IAM) custom role creation in Google Cloud Platform (GCP). Custom roles are
user-defined, and allow for the bundling of one or more supported permissions to meet specific needs. Custom roles will
not be updated automatically and could lead to privilege creep if not carefully scrutinized.
"""
false_positives = [
    """
    Custom role creations may be done by a system or network administrator. Verify whether the user email, resource
    name, and/or hostname should be making changes in your environment. Role creations by unfamiliar users or hosts
    should be investigated. If known behavior is causing false positives, it can be exempted from the rule.
    """,
]
index = ["filebeat-*", "logs-gcp*"]
language = "kuery"
license = "Elastic License v2"
name = "GCP IAM Custom Role Creation"
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 GCP IAM Custom Role Creation

Google Cloud Platform's IAM custom roles allow users to define specific permissions tailored to their needs, offering flexibility in access management. However, adversaries can exploit this by creating roles with excessive permissions, leading to privilege escalation. The detection rule monitors audit logs for successful custom role creation events, helping identify potential unauthorized access attempts by flagging unusual role configurations.

### Possible investigation steps

- Review the audit logs for the specific event.action:google.iam.admin.v*.CreateRole to identify the user or service account responsible for creating the custom role.
- Examine the permissions assigned to the newly created custom role to determine if they are excessive or deviate from standard role configurations.
- Check the event.outcome:success field to confirm the successful creation of the role and cross-reference with any recent changes in IAM policies or permissions.
- Investigate the context around the role creation, such as the time of creation and any associated IP addresses or locations, to identify any unusual patterns or anomalies.
- Assess the necessity and justification for the custom role by consulting with the relevant team or individual who requested its creation, ensuring it aligns with organizational policies and needs.

### False positive analysis

- Routine administrative actions by authorized personnel can trigger alerts. Regularly review and document legitimate role creation activities to establish a baseline of expected behavior.
- Automated processes or scripts that create roles as part of deployment pipelines may cause false positives. Identify and whitelist these processes to prevent unnecessary alerts.
- Temporary roles created for short-term projects or testing purposes might be flagged. Implement a naming convention for such roles and exclude them from alerts based on this pattern.
- Changes in organizational structure or policy updates can lead to legitimate role creations. Ensure that these changes are communicated to the security team to adjust monitoring rules accordingly.
- Third-party integrations that require custom roles might be misidentified as threats. Maintain an inventory of these integrations and their role requirements to differentiate between legitimate and suspicious activities.

### Response and remediation

- Immediately review the audit logs to confirm the creation of the custom role and identify the user or service account responsible for the action.
- Revoke the custom role if it is determined to have excessive permissions or if it was created without proper authorization.
- Conduct a thorough review of the permissions assigned to the custom role to ensure they align with the principle of least privilege.
- Notify the security team and relevant stakeholders about the unauthorized role creation for further investigation and potential escalation.
- Implement additional monitoring on the identified user or service account to detect any further suspicious activities.
- Review and update IAM policies to prevent unauthorized role creation, ensuring that only trusted users have the necessary permissions to create custom roles.
- Enhance detection capabilities by setting up alerts for any future custom role creation events, especially those with high-risk permissions.

## Setup

The GCP Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
references = ["https://cloud.google.com/iam/docs/understanding-custom-roles"]
risk_score = 73
rule_id = "aa8007f0-d1df-49ef-8520-407857594827"
severity = "high"
tags = [
    "Domain: Cloud",
    "Data Source: GCP",
    "Data Source: Google Cloud Platform",
    "Use Case: Identity and Access Audit",
    "Tactic: Initial Access",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset:gcp.audit and event.action:google.iam.admin.v*.CreateRole and event.outcome:success
'''


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

[[rule.threat.technique]]
id = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"

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

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

[[rule.threat.technique]]
id = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"

[[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.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/"

Stages and Predicates

Stage 1: query

data_stream.dataset:gcp.audit and event.action:google.iam.admin.v*.CreateRole and event.outcome:success

Indicators

These rows show field, operator, and value matches.

GCP Service Account Creation

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

Identifies when a new service account is created in Google Cloud Platform (GCP). A service account is a special type of account used by an application or a virtual machine (VM) instance, not a person. Applications use service accounts to make authorized API calls, authorized as either the service account itself, or as G Suite or Cloud Identity users through domain-wide delegation. If service accounts are not tracked and managed properly, they can present a security risk. An adversary may create a new service account to use during their operations in order to avoid using a standard user account and attempt to evade detection.

Known False Positives

  • Service accounts can be created by system administrators. Verify that the behavior was expected. Exceptions can be added to this rule to filter expected behavior.

MITRE ATT&CK Coverage

TacticTechniques
Persistence

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2020/09/22"
integration = ["gcp"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Identifies when a new service account is created in Google Cloud Platform (GCP). A service account is a special type of
account used by an application or a virtual machine (VM) instance, not a person. Applications use service accounts to
make authorized API calls, authorized as either the service account itself, or as G Suite or Cloud Identity users
through domain-wide delegation. If service accounts are not tracked and managed properly, they can present a security
risk. An adversary may create a new service account to use during their operations in order to avoid using a standard
user account and attempt to evade detection.
"""
false_positives = [
    """
    Service accounts can be created by system administrators. Verify that the behavior was expected. Exceptions can be
    added to this rule to filter expected behavior.
    """,
]
index = ["filebeat-*", "logs-gcp*"]
language = "kuery"
license = "Elastic License v2"
name = "GCP Service Account Creation"
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 GCP Service Account Creation

In GCP, service accounts enable applications and VMs to interact with APIs securely. While essential for automation, they can be exploited if improperly managed. Adversaries might create service accounts to gain persistent access without detection. The detection rule monitors audit logs for successful service account creations, flagging potential unauthorized activities for further investigation.

### Possible investigation steps

- Review the audit logs for the specific event.action:google.iam.admin.v*.CreateServiceAccount to identify the time and source of the service account creation.
- Check the identity of the user or service that initiated the service account creation to determine if it aligns with expected administrative activities.
- Investigate the permissions and roles assigned to the newly created service account to assess if they are excessive or unusual for its intended purpose.
- Correlate the service account creation event with other recent activities in the environment to identify any suspicious patterns or anomalies.
- Verify if the service account is being used by any unauthorized applications or VMs by reviewing recent API calls and access logs associated with the account.

### False positive analysis

- Routine service account creation by automated deployment tools or scripts can trigger false positives. Identify and document these tools, then create exceptions in the monitoring system to exclude these known activities.
- Service accounts created by trusted internal teams for legitimate projects may also be flagged. Establish a process for these teams to notify security personnel of planned service account creations, allowing for pre-approval and exclusion from alerts.
- Scheduled maintenance or updates that involve creating temporary service accounts can result in false positives. Coordinate with IT operations to understand their schedules and adjust monitoring rules to accommodate these activities.
- Third-party integrations that require service accounts might be mistakenly flagged. Maintain an inventory of authorized third-party services and their associated service accounts to quickly verify and exclude these from alerts.

### Response and remediation

- Immediately disable the newly created service account to prevent any unauthorized access or actions.
- Review the IAM policy and permissions associated with the service account to ensure no excessive privileges were granted.
- Conduct a thorough audit of recent activities performed by the service account to identify any suspicious or unauthorized actions.
- Notify the security team and relevant stakeholders about the potential security incident for further investigation and coordination.
- Implement additional monitoring and alerting for service account creations to detect similar activities in the future.
- If malicious activity is confirmed, follow incident response procedures to contain and remediate any impact, including revoking access and conducting a security review of affected resources.
- Document the incident and response actions taken to improve future detection and response capabilities.

## Setup

The GCP Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
references = ["https://cloud.google.com/iam/docs/service-accounts"]
risk_score = 21
rule_id = "7ceb2216-47dd-4e64-9433-cddc99727623"
severity = "low"
tags = [
    "Domain: Cloud",
    "Data Source: GCP",
    "Data Source: Google Cloud Platform",
    "Use Case: Identity and Access Audit",
    "Tactic: Persistence",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset:gcp.audit and event.action:google.iam.admin.v*.CreateServiceAccount and event.outcome:success
'''


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

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

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

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

Stages and Predicates

Stage 1: query

data_stream.dataset:gcp.audit and event.action:google.iam.admin.v*.CreateServiceAccount and event.outcome:success

Indicators

These rows show field, operator, and value matches.

GenAI Process Performing Encoding/Chunking Prior to Network Activity

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

Detects when GenAI processes perform encoding or chunking (base64, gzip, tar, zip) followed by outbound network activity. This sequence indicates data preparation for exfiltration. Attackers encode or compress sensitive data before transmission to obfuscate contents and evade detection. Legitimate GenAI workflows rarely encode data before network communications.

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/04/07"

[rule]
author = ["Elastic"]
description = """
Detects when GenAI processes perform encoding or chunking (base64, gzip, tar, zip) followed by outbound network
activity. This sequence indicates data preparation for exfiltration. Attackers encode or compress sensitive data before
transmission to obfuscate contents and evade detection. Legitimate GenAI workflows rarely encode data before network
communications.
"""
from = "now-9m"
index = [
    "logs-endpoint.events.process-*",
    "logs-endpoint.events.network-*",
    "logs-windows.sysmon_operational-*",
    "winlogbeat-*",
    "logs-m365_defender.event-*",
    "logs-sentinel_one_cloud_funnel.*",
]
language = "eql"
license = "Elastic License v2"
name = "GenAI Process Performing Encoding/Chunking Prior to Network Activity"
note = """## Triage and analysis

### Investigating GenAI Process Performing Encoding/Chunking Prior to Network Activity

GenAI processes performing encoding or chunking operations followed by network activity is highly suspicious. This behavior indicates data preparation for exfiltration via GenAI prompts or agents, which is a strong indicator of malicious activity.

### Possible investigation steps

- Review the GenAI process that performed the encoding to identify which tool is running and verify if it's an expected/authorized tool.
- Examine the encoding/chunking command line arguments to understand what data is being processed.
- Review the network connection details to identify the destination and determine if it's expected.
- Investigate the user account associated with the GenAI process to determine if this activity is expected for that user.
- Review the data that was encoded to determine if it contains sensitive information.
- Determine whether the encoding was initiated by a GenAI agent or automation loop rather than a user action.
- Check whether the encoded data size or entropy suggests credential files, browser data, SSH keys, or cloud tokens.
- Validate that the GenAI tool is installed from a trusted source and has not been modified.

### False positive analysis

- Legitimate data processing workflows that use GenAI tools may trigger this rule if they encode data before transmission.
- Some local developer workflows may encode files before uploading training data or embeddings; confirm whether the host is a model-development workstation.

### Response and remediation

- Terminate the GenAI process and any spawned encoding/network processes to stop the malicious activity.
- Review and revoke any API keys, tokens, or credentials that may have been exposed or used by the GenAI tool.
- Investigate the encoded data and network destination to determine the scope of potential data exfiltration.
"""
references = [
    "https://atlas.mitre.org/techniques/AML.T0086",
    "https://glama.ai/blog/2025-11-11-the-lethal-trifecta-securing-model-context-protocol-against-data-flow-attacks",
    "https://www.elastic.co/security-labs/elastic-advances-llm-security",
]
risk_score = 47
rule_id = "c3d4e5f6-a7b8-9012-cdef-123456789abc"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "OS: macOS",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Exfiltration",
    "Tactic: Defense Evasion",
    "Data Source: Elastic Defend",
    "Data Source: Sysmon",
    "Data Source: Microsoft Defender XDR",
    "Data Source: SentinelOne",
    "Resources: Investigation Guide",
    "Domain: LLM",
    "Mitre Atlas: T0086",
]
timestamp_override = "event.ingested"
type = "eql"

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

  // Encoding/compression followed by network activity
  [process where event.type == "start"
     and event.type == "start"

     // Encoding/chunking tools
     and (
       // Native encoding tools
       process.name in ("base64", "gzip", "tar", "zip", "split", "7z", "7za", "7zr") or
       
       // PowerShell encoding
       (process.name in ("powershell.exe", "pwsh.exe") and
        process.command_line like~ ("*Compress-Archive*", "*[Convert]::ToBase64String*")) or
       
       // Python encoding
       (process.name like~ "python*" and
        process.command_line like~ ("*base64*", "*gzip*", "*zlib*", "*tarfile*", "*zipfile*")) or
       
       // Node.js encoding
       (process.name in ("node.exe", "node") and
        process.command_line like~ ("*Buffer.from*", "*zlib*", "*gzip*") and
        not process.command_line like~ ("*mcp*start*", "*mcp-server*", "*npm exec*mcp*"))
     )

     // GenAI parent process
     and (
       process.parent.name in (
         "ollama.exe", "ollama", "Ollama",
         "textgen.exe", "textgen", "text-generation-webui.exe", "oobabooga.exe",
         "lmstudio.exe", "lmstudio", "LM Studio",
         "claude.exe", "claude", "Claude",
         "cursor.exe", "cursor", "Cursor", "Cursor Helper", "Cursor Helper (Plugin)",
         "copilot.exe", "copilot", "Copilot",
         "codex.exe", "codex",
         "Jan", "jan.exe", "jan", "Jan Helper",
         "gpt4all.exe", "gpt4all", "GPT4All",
         "gemini-cli.exe", "gemini-cli",
         "genaiscript.exe", "genaiscript",
         "grok.exe", "grok",
         "qwen.exe", "qwen",
         "koboldcpp.exe", "koboldcpp", "KoboldCpp",
         "llama-server", "llama-cli"
       ) or
       
       // Node/Deno with GenAI frameworks
       (process.parent.name in ("node.exe", "node", "deno.exe", "deno") and
        process.parent.command_line like~ (
          "*ollama*", "*mcp-server*", "*@modelcontextprotocol*", "*langchain*", "*autogpt*",
          "*babyagi*", "*agentgpt*", "*crewai*", "*semantic-kernel*", "*llama-index*",
          "*haystack*", "*openai*", "*anthropic*", "*cohere*", "*mistral*"
        )) or
       
       // Python with GenAI frameworks
       (process.parent.name like~ "python*" and
        process.parent.command_line like~ (
          "*ollama*", "*mcp-server*", "*langchain*", "*autogpt*", "*babyagi*",
          "*agentgpt*", "*crewai*", "*semantic-kernel*", "*llama-index*", "*haystack*",
          "*openai*", "*anthropic*", "*cohere*", "*mistral*"
        ))
     )
  ] by process.entity_id

  // Outbound network connection (non-local)
  [network where event.type == "start"
     and event.action == "connection_attempted"
     and destination.ip != null
     and not cidrmatch(destination.ip, "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24", "192.0.0.0/29",
                       "192.0.0.8/32", "192.0.0.9/32", "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24",
                       "192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", "224.0.0.0/4", "100.64.0.0/10",
                       "192.175.48.0/24","198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1", "FE80::/10",
                       "FF00::/8")
     
  ] by process.entity_id
'''


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

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

[[rule.threat.technique]]
id = "T1560"
name = "Archive Collected Data"
reference = "https://attack.mitre.org/techniques/T1560/"

[[rule.threat.technique.subtechnique]]
id = "T1560.001"
name = "Archive via Utility"
reference = "https://attack.mitre.org/techniques/T1560/001/"

[[rule.threat.technique.subtechnique]]
id = "T1560.002"
name = "Archive via Library"
reference = "https://attack.mitre.org/techniques/T1560/002/"

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

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

[[rule.threat.technique]]
id = "T1030"
name = "Data Transfer Size Limits"
reference = "https://attack.mitre.org/techniques/T1030/"

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

Stages and Predicates

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

Stage 1: process

[process where event.type == "start"
     and event.type == "start"
     and (
       process.name in ("base64", "gzip", "tar", "zip", "split", "7z", "7za", "7zr") or
       (process.name in ("powershell.exe", "pwsh.exe") and
        process.command_line like~ ("*Compress-Archive*", "*[Convert]::ToBase64String*")) or
       (process.name like~ "python*" and
        process.command_line like~ ("*base64*", "*gzip*", "*zlib*", "*tarfile*", "*zipfile*")) or
       (process.name in ("node.exe", "node") and
        process.command_line like~ ("*Buffer.from*", "*zlib*", "*gzip*") and
        not process.command_line like~ ("*mcp*start*", "*mcp-server*", "*npm exec*mcp*"))
     )
     and (
       process.parent.name in (
         "ollama.exe", "ollama", "Ollama",
         "textgen.exe", "textgen", "text-generation-webui.exe", "oobabooga.exe",
         "lmstudio.exe", "lmstudio", "LM Studio",
         "claude.exe", "claude", "Claude",
         "cursor.exe", "cursor", "Cursor", "Cursor Helper", "Cursor Helper (Plugin)",
         "copilot.exe", "copilot", "Copilot",
         "codex.exe", "codex",
         "Jan", "jan.exe", "jan", "Jan Helper",
         "gpt4all.exe", "gpt4all", "GPT4All",
         "gemini-cli.exe", "gemini-cli",
         "genaiscript.exe", "genaiscript",
         "grok.exe", "grok",
         "qwen.exe", "qwen",
         "koboldcpp.exe", "koboldcpp", "KoboldCpp",
         "llama-server", "llama-cli"
       ) or
       (process.parent.name in ("node.exe", "node", "deno.exe", "deno") and
        process.parent.command_line like~ (
          "*ollama*", "*mcp-server*", "*@modelcontextprotocol*", "*langchain*", "*autogpt*",
          "*babyagi*", "*agentgpt*", "*crewai*", "*semantic-kernel*", "*llama-index*",
          "*haystack*", "*openai*", "*anthropic*", "*cohere*", "*mistral*"
        )) or
       (process.parent.name like~ "python*" and
        process.parent.command_line like~ (
          "*ollama*", "*mcp-server*", "*langchain*", "*autogpt*", "*babyagi*",
          "*agentgpt*", "*crewai*", "*semantic-kernel*", "*llama-index*", "*haystack*",
          "*openai*", "*anthropic*", "*cohere*", "*mistral*"
        ))
     )
  ] by process.entity_id

Stage 2: network

[network where event.type == "start"
     and event.action == "connection_attempted"
     and destination.ip != null
     and not cidrmatch(destination.ip, "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24", "192.0.0.0/29",
                       "192.0.0.8/32", "192.0.0.9/32", "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24",
                       "192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", "224.0.0.0/4", "100.64.0.0/10",
                       "192.175.48.0/24","198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1", "FE80::/10",
                       "FF00::/8")
     
  ] by process.entity_id

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
destination.ipis_not_null
  • (no value, null check)
field:"dest_ip" kind:is_not_null
event.actioneq
  • connection_attempted corpus 72 (elastic 72)
field:"EventType" kind:eq value:"connection_attempted"
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.command_linewildcard
  • *Buffer.from* corpus 4 (elastic 4)
  • *Compress-Archive*
  • *[Convert]::ToBase64String* corpus 2 (sigma 1, elastic 1)
  • *base64* corpus 18 (elastic 11, sigma 7)
  • *gzip* corpus 2 (elastic 2)
  • *tarfile*
  • *zipfile*
  • *zlib* corpus 4 (elastic 3, sigma 1)
field:"CommandLine" kind:wildcard
process.namein
  • 7z corpus 3 (elastic 3)
  • 7za
  • 7zr
  • base64 corpus 20 (elastic 20)
  • gzip corpus 9 (elastic 9)
  • node corpus 25 (elastic 25)
  • node.exe corpus 6 (elastic 6)
  • powershell.exe corpus 7 (elastic 7)
  • pwsh.exe corpus 5 (elastic 5)
  • split corpus 3 (elastic 3)
  • tar corpus 13 (elastic 13)
  • zip corpus 5 (elastic 5)
field:"process_basename" kind:in
process.namewildcard
  • python* corpus 55 (elastic 55)
field:"process_basename" kind:wildcard value:"python*"
process.parent.command_linewildcard
  • *@modelcontextprotocol* corpus 2 (elastic 2)
  • *agentgpt* corpus 2 (elastic 2)
  • *anthropic*
  • *autogpt* corpus 2 (elastic 2)
  • *babyagi* corpus 2 (elastic 2)
  • *cohere*
  • *crewai* corpus 2 (elastic 2)
  • *haystack* corpus 2 (elastic 2)
  • *langchain* corpus 2 (elastic 2)
  • *llama-index* corpus 2 (elastic 2)
  • *mcp-server* corpus 2 (elastic 2)
  • *mistral*
  • *ollama*
  • *openai*
  • *semantic-kernel* corpus 2 (elastic 2)
field:"ParentCommandLine" kind:wildcard
process.parent.namein
  • Claude corpus 3 (elastic 3)
  • Copilot corpus 3 (elastic 3)
  • Cursor corpus 4 (elastic 4)
  • Cursor Helper corpus 3 (elastic 3)
  • Cursor Helper (Plugin) corpus 3 (elastic 3)
  • GPT4All corpus 3 (elastic 3)
  • Jan corpus 3 (elastic 3)
  • Jan Helper corpus 3 (elastic 3)
  • KoboldCpp corpus 3 (elastic 3)
  • LM Studio corpus 3 (elastic 3)
  • Ollama corpus 3 (elastic 3)
  • claude corpus 4 (elastic 4)
  • claude.exe corpus 3 (elastic 3)
  • codex corpus 4 (elastic 4)
  • codex.exe corpus 4 (elastic 4)
  • copilot corpus 4 (elastic 4)
  • copilot.exe corpus 3 (elastic 3)
  • cursor corpus 4 (elastic 4)
  • cursor.exe corpus 3 (elastic 3)
  • deno corpus 5 (elastic 5)
  • deno.exe corpus 3 (elastic 3)
  • gemini-cli corpus 3 (elastic 3)
  • gemini-cli.exe corpus 4 (elastic 4)
  • genaiscript corpus 3 (elastic 3)
  • genaiscript.exe corpus 3 (elastic 3)
  • gpt4all corpus 3 (elastic 3)
  • gpt4all.exe corpus 3 (elastic 3)
  • grok corpus 3 (elastic 3)
  • grok.exe corpus 3 (elastic 3)
  • jan corpus 3 (elastic 3)
  • jan.exe corpus 2 (elastic 2)
  • koboldcpp corpus 3 (elastic 3)
  • koboldcpp.exe corpus 3 (elastic 3)
  • llama-cli corpus 3 (elastic 3)
  • llama-server corpus 3 (elastic 3)
  • lmstudio corpus 4 (elastic 4)
  • lmstudio.exe corpus 3 (elastic 3)
  • node corpus 14 (elastic 14)
  • node.exe corpus 8 (elastic 8)
  • ollama corpus 4 (elastic 4)
  • ollama.exe corpus 3 (elastic 3)
  • oobabooga.exe corpus 3 (elastic 3)
  • qwen corpus 3 (elastic 3)
  • qwen.exe corpus 3 (elastic 3)
  • text-generation-webui.exe corpus 3 (elastic 3)
  • textgen corpus 4 (elastic 4)
  • textgen.exe corpus 4 (elastic 4)
field:"parent_process_basename" kind:in
process.parent.namewildcard
  • python* corpus 19 (elastic 19)
field:"parent_process_basename" kind:wildcard value:"python*"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
destination.ipcidr_match10.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.0.0.0/24, 192.0.0.0/29, 192.0.0.8/32, 192.0.0.9/32, 192.0.0.10/32, 192.0.0.170/32, 192.0.0.171/32, 192.0.2.0/24, 192.31.196.0/24, 192.52.193.0/24, 192.168.0.0/16, 192.88.99.0/24, 224.0.0.0/4, 100.64.0.0/10, 192.175.48.0/24, 198.18.0.0/15, 198.51.100.0/24, 203.0.113.0/24, 240.0.0.0/4, ::1, FE80::/10, FF00::/8excludes:destination.ip

Inbound Connection to an Unsecure Elasticsearch Node

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

Identifies Elasticsearch nodes that do not have Transport Layer Security (TLS), and/or lack authentication, and are accepting inbound network connections over the default Elasticsearch port.

Known False Positives

  • If you have front-facing proxies that provide authentication and TLS, this rule would need to be tuned to eliminate the source IP address of your reverse-proxy.

MITRE ATT&CK Coverage

TacticTechniques
Reconnaissance
Initial Access

Rule Body

[metadata]
creation_date = "2020/08/11"
integration = ["network_traffic"]
maturity = "production"
updated_date = "2026/07/19"

[rule]
author = ["Elastic"]
description = """
Identifies Elasticsearch nodes that do not have Transport Layer Security (TLS), and/or lack authentication, and are
accepting inbound network connections over the default Elasticsearch port.
"""
false_positives = [
    """
    If you have front-facing proxies that provide authentication and TLS, this rule would need to be tuned to eliminate
    the source IP address of your reverse-proxy.
    """,
]
from = "now-9m"
index = ["packetbeat-*", "logs-network_traffic.*"]
language = "kuery"
license = "Elastic License v2"
name = "Inbound Connection to an Unsecure Elasticsearch Node"
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 Inbound Connection to an Unsecure Elasticsearch Node

Elasticsearch is a powerful search and analytics engine often used for log and data analysis. When improperly configured without TLS or authentication, it becomes vulnerable to unauthorized access. Adversaries can exploit these weaknesses to gain initial access, exfiltrate data, or disrupt services. The detection rule identifies unsecured nodes by monitoring inbound HTTP traffic on the default port, flagging connections lacking authentication headers, thus highlighting potential exploitation attempts.

### Possible investigation steps

- Review the source IP address of the inbound connection to determine if it is from a known or trusted entity. Cross-reference with internal asset inventories or threat intelligence sources.
- Examine the network traffic logs for any unusual patterns or repeated access attempts from the same source IP, which might indicate a brute force or scanning activity.
- Check for any data exfiltration attempts by analyzing outbound traffic from the Elasticsearch node, focusing on large data transfers or connections to unfamiliar external IPs.
- Investigate the absence of authentication headers in the HTTP requests to confirm if the Elasticsearch node is indeed misconfigured and lacks proper security controls.
- Assess the configuration of the Elasticsearch node to ensure that TLS is enabled and authentication mechanisms are properly implemented to prevent unauthorized access.
- Look for any other alerts or logs related to the same Elasticsearch node or source IP to identify potential coordinated attack activities or previous incidents.

### False positive analysis

- Internal monitoring tools or scripts that regularly check Elasticsearch node status without authentication can trigger false positives. Exclude these specific IP addresses or user agents from the rule to reduce noise.
- Automated backup systems that interact with Elasticsearch nodes without using authentication headers might be flagged. Identify these systems and create exceptions based on their IP addresses or network segments.
- Development or testing environments where Elasticsearch nodes are intentionally left unsecured for testing purposes can generate alerts. Use network segmentation or specific tags to differentiate these environments and exclude them from the rule.
- Security scans or vulnerability assessments conducted by internal teams may access Elasticsearch nodes without authentication, leading to false positives. Whitelist the IP ranges used by these security tools to prevent unnecessary alerts.

### Response and remediation

- Immediately isolate the affected Elasticsearch node from the network to prevent further unauthorized access or data exfiltration.
- Conduct a thorough review of access logs to identify any unauthorized access or data exfiltration attempts, focusing on connections lacking authentication headers.
- Implement Transport Layer Security (TLS) and enable authentication mechanisms on the Elasticsearch node to secure communications and restrict access to authorized users only.
- Reset credentials and API keys associated with the Elasticsearch node to prevent further unauthorized access using potentially compromised credentials.
- Notify the security team and relevant stakeholders about the incident, providing details of the unauthorized access and steps taken to contain the threat.
- Monitor the network for any signs of continued unauthorized access attempts or related suspicious activity, adjusting detection rules as necessary to capture similar threats.
- Document the incident, including the response actions taken, and conduct a post-incident review to identify any gaps in security controls and improve future response efforts.

## Setup

This rule requires the addition of port `9200` and `send_all_headers` to the `HTTP` protocol configuration in `packetbeat.yml`. See the References section for additional configuration documentation."""
references = [
    "https://www.elastic.co/guide/en/elasticsearch/reference/current/configuring-security.html",
    "https://www.elastic.co/guide/en/beats/packetbeat/current/packetbeat-http-options.html#_send_all_headers",
]
risk_score = 47
rule_id = "31295df3-277b-4c56-a1fb-84e31b4222a9"
severity = "medium"
tags = [
    "Use Case: Threat Detection",
    "Tactic: Initial Access",
    "Tactic: Reconnaissance",
    "Domain: Endpoint",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
(data_stream.dataset: network_traffic.http or (event.category: network_traffic and network.protocol: http)) and
http.response.status_code: 200 and destination.port: 9200 and network.direction: (inbound or ingress) and
not http.response.headers.content-type: "image/x-icon" and not http.request.headers.authorization: *
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1190"
name = "Exploit Public-Facing Application"
reference = "https://attack.mitre.org/techniques/T1190/"


[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1595"
name = "Active Scanning"
reference = "https://attack.mitre.org/techniques/T1595/"


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

Stages and Predicates

Stage 1: query

(data_stream.dataset: network_traffic.http or (event.category: network_traffic and network.protocol: http)) and
http.response.status_code: 200 and destination.port: 9200 and network.direction: (inbound or ingress) and
not http.response.headers.content-type: "image/x-icon" and not http.request.headers.authorization: *

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
http.request.headers.authorizationis_not_null(no value, null check)excludes:http.request.headers.authorization
http.response.headers.content-typeeqimage/x-iconexcludes:http.response.headers.content-type field:"http.response.headers.content-type" value:"image/x-icon"

Malicious File - Detected - Elastic Defend

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

Generates a detection alert each time an Elastic Defend alert for malicious files is received. Enabling this rule allows you to immediately begin investigating your Endpoint malicious file alerts. This rule identifies Elastic Defend malicious file detections only, and does not include prevention alerts.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2024/03/24"
integration = ["endpoint"]
maturity = "production"
promotion = true
updated_date = "2025/07/02"

[rule]
author = ["Elastic"]
description = """
Generates a detection alert each time an Elastic Defend alert for malicious files is received. Enabling this rule allows
you to immediately begin investigating your Endpoint malicious file alerts. This rule identifies Elastic Defend
malicious file detections only, and does not include prevention alerts.
"""
enabled = false
from = "now-2m"
index = ["logs-endpoint.alerts-*"]
interval = "1m"
language = "kuery"
license = "Elastic License v2"
max_signals = 1000
name = "Malicious File - Detected - Elastic Defend"
note = """## Triage and analysis

### Investigating Malicious File - Detected - Elastic Defend

Elastic Endpoint malware protection leverages a combination of supervised machine learning (ML) models (PE, MachO) and yara signatures. Our ML models are trained on hundreds of millions of executables and model updates are released approximately monthly. Our yara signatures are created with automated signature creation technologies built in-house along with  hand-written rules by our threat researchers.

Files are scanned on write or deletion, process executables are scanned on executions and libraries are scanned on load. You can differentiate these types by looking at the `event.action` field in the alert. It can be execution, `load`, `creation`, `modification`, or `deletion`. Scanning files written to disk is best effort, while execution or load scanning is done ‘in-line’ for true prevention.

### Possible investigation steps

- For machine learning (ML) malware alerts the `file.Ext.malware_classification.score` and `file.Ext.malware_classification.version` fields indicate which model version was used to classify the file and the classification score (0 to 1).
- For malware signature hits, `threat_name` is an important field which will guide the user on what malware family the sample belongs to.
- For Yara matches, Malware alerts do provide the specific binary content identified by the yara rule in the alert metadata (it is base64 encoded and stored in the `matches` field).
- A file can also hit on multiple Yara signatures. In the alert metadata, the `primary` signature (`malware_signature.primary`) will be whichever we determine to have the highest severity.
- Malicious file alerts for files in download directories or written by browsers, office applications, script interpreters or other lolbins are especially correlated with malicious activity.
- Particular attention should be paid to files located in suspicious directories like `Public` folder, `Downloads`, `Temp` and `ProgramData`.
- Verify if the file is signed or not using the `file.Ext.code_signature` field. Even if the file is signed with a valid certificate verify the global prevalance of that signed in your environment.
- Verify the malicious file timestamp metadata using `file.created`, `file.mtime` and `file.accessed` to asses exactly if it's an old or new infection.
- Investigate the activity of the process that created, modified or loaded the malicious file (parent process tree, process.command_line, child processes, network, registry and files events).
- Assess whether this file is prevalent in the environment by looking for similar occurrences across hosts by `file.hash.sha256` or by `file.name` patterns.
- Verify the activity of the `user.name` associated with Malware alert (local or remote actity, privileged or standard user).
- Verify if there are any other Alert types (Behavior or Memory Threat) associated with the same host or user or process within the same time.
### False positive analysis

- Other endpoint security vendors especially with their quarantine folders.
- Dynamically generated or compiled executables such as from csc.exe or other compilers. Due to the dynamic nature, each instance will likely have a unique hash and no signer

### Response and Remediation

- Initiate the incident response process based on the outcome of the triage.
  - If malicious activity is confirmed, perform a broader investigation to identify the scope of the compromise and determine the appropriate remediation steps.
- Implement Elastic Endpoint Security to detect and prevent further post exploitation activities in the environment.
   - Contain the affected system by isolating it from the network to prevent further spread of the attack.
- 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.
- Restore the affected system to its operational state by applying any necessary patches, updates, or configuration changes.
- 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.
- 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).
"""
references = [
    "https://github.com/elastic/protections-artifacts/tree/main/yara",
    "https://docs.elastic.co/en/integrations/endpoint",
]
risk_score = 47
rule_id = "f2c3caa6-ea34-11ee-a417-f661ea17fbce"
rule_name_override = "message"
setup = """## Setup

### Elastic Defend Alerts
This rule is designed to capture specific alerts generated by Elastic Defend.

To capture all the Elastic Defend alerts, it is recommended to use all of the Elastic Defend feature-specific protection rules:

Behavior - Detected - Elastic Defend (UUID: 0f615fe4-eaa2-11ee-ae33-f661ea17fbce)
Behavior - Prevented - Elastic Defend (UUID: eb804972-ea34-11ee-a417-f661ea17fbce)
Malicious File - Detected - Elastic Defend (UUID: f2c3caa6-ea34-11ee-a417-f661ea17fbce)
Malicious File - Prevented - Elastic Defend (UUID: f87e6122-ea34-11ee-a417-f661ea17fbce)
Memory Threat - Detected - Elastic Defend (UUID: 017de1e4-ea35-11ee-a417-f661ea17fbce)
Memory Threat - Prevented - Elastic Defend (UUID: 06f3a26c-ea35-11ee-a417-f661ea17fbce)
Ransomware - Detected - Elastic Defend (UUID: 0c74cd7e-ea35-11ee-a417-f661ea17fbce)
Ransomware - Prevented - Elastic Defend (UUID: 10f3d520-ea35-11ee-a417-f661ea17fbce)

To avoid generating duplicate alerts, you should enable either all feature-specific protection rules or the Endpoint Security (Elastic Defend) rule (UUID: 9a1a2dae-0b5f-4c3d-8305-a268d404c306).

### Additional notes

For information on troubleshooting the maximum alerts warning please refer to this [guide](https://www.elastic.co/guide/en/security/current/alerts-ui-monitor.html#troubleshoot-max-alerts).
"""
severity = "medium"
tags = ["Data Source: Elastic Defend", "Tactic: Execution", "Resources: Investigation Guide"]
timestamp_override = "event.ingested"
type = "query"

query = '''
event.kind : alert and event.code : malicious_file and (event.type : allowed or (event.type: denied and event.outcome: failure))
'''


[[rule.exceptions_list]]
id = "endpoint_list"
list_id = "endpoint_list"
namespace_type = "agnostic"
type = "endpoint"

[[rule.risk_score_mapping]]
field = "event.risk_score"
operator = "equals"
value = ""

[[rule.severity_mapping]]
field = "event.severity"
operator = "equals"
severity = "low"
value = "21"

[[rule.severity_mapping]]
field = "event.severity"
operator = "equals"
severity = "medium"
value = "47"

[[rule.severity_mapping]]
field = "event.severity"
operator = "equals"
severity = "high"
value = "73"

[[rule.severity_mapping]]
field = "event.severity"
operator = "equals"
severity = "critical"
value = "99"

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



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

Stages and Predicates

Stage 1: query

event.kind : alert and event.code : malicious_file and (event.type : allowed or (event.type: denied and event.outcome: failure))

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.codeeq
  • malicious_file corpus 2 (elastic 2)
field:"EventID" kind:eq value:"malicious_file"
event.kindeq
  • alert corpus 35 (elastic 35)
field:"event.kind" kind:eq value:"alert"
event.outcomeeq
  • failure corpus 14 (elastic 14)
field:"event.outcome" kind:eq value:"failure"
event.typeeq
  • allowed corpus 4 (elastic 4)
  • denied corpus 8 (elastic 8)
field:"event.type" kind:eq

Network Connection via Recently Compiled Executable

#
Status
production
Severity
medium
Time window
1m
Sequence by
file.name, host.id, process.args, process.name
Author
Elastic
Source
github.com/elastic/detection-rules

This rule monitors a sequence involving a program compilation event followed by its execution and a subsequent network connection event. This behavior can indicate the set up of a reverse tcp connection to a command-and-control server. Attackers may spawn reverse shells to establish persistence onto a target system.

MITRE ATT&CK Coverage

Rule Body

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

[rule]
author = ["Elastic"]
description = """
This rule monitors a sequence involving a program compilation event followed by its execution and a subsequent network
connection event. This behavior can indicate the set up of a reverse tcp connection to a command-and-control server.
Attackers may spawn reverse shells to establish persistence onto a target system.
"""
from = "now-9m"
index = ["logs-endpoint.events.file*", "logs-endpoint.events.network*", "logs-endpoint.events.process*"]
language = "eql"
license = "Elastic License v2"
name = "Network Connection via Recently Compiled Executable"
risk_score = 47
rule_id = "64cfca9e-0f6f-4048-8251-9ec56a055e9e"
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 = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Execution",
    "Data Source: Elastic Defend",
    "Resources: Investigation Guide",
]
type = "eql"
query = '''
sequence by host.id with maxspan=1m
  [process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and
   process.name like~ (
     "gcc*", "g++*", "c++", "cc", "c99", "c89", "cc1*", "cc1plus*", "clang*", "clang++*",
     "musl-gcc", "musl-clang", "*-linux-gnu-gcc*", "*-linux-gnu-g++*", "*-pc-linux-gnu-gcc*",
     "tcc", "zig", "ccache", "distcc"
   )] by process.args
  [file where host.os.type == "linux" and event.action == "creation" and process.name like~ (
    "ld", "ld.*", "lld", "ld.lld", "mold", "collect2", "*-linux-gnu-ld*", "*-pc-linux-gnu-ld*"
   )] by file.name
  [process where host.os.type == "linux" and event.type == "start" and event.action == "exec"] by process.name
  [network where host.os.type == "linux" and event.action == "connection_attempted" and destination.ip != null and not (
     cidrmatch(destination.ip, "127.0.0.0/8", "169.254.0.0/16", "224.0.0.0/4", "::1") or
     process.name in (
       "simpleX", "conftest", "ssh", "python", "ispnull", "pvtui", "npreal2d", "ruby", "source", "ssh", "git-remote-http",
       "sshd-session", "gendb", "sqlplus"
     )
   )] by process.name
'''
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 Network Connection via Recently Compiled Executable

In Linux environments, compiling and executing programs is routine for development. However, adversaries exploit this by compiling malicious code to establish reverse shells, enabling remote control. The detection rule identifies this threat by monitoring sequences of compilation, execution, and network activity, flagging unusual connections that deviate from typical patterns, thus indicating potential compromise.

### Possible investigation steps

- Review the process execution details to identify the compiler used (e.g., gcc, g++, cc) and examine the arguments passed during the compilation to understand the nature of the compiled code.
- Investigate the file creation event associated with the linker (ld) to determine the output executable file and its location on the system.
- Analyze the subsequent process execution to identify the newly compiled executable and verify its legitimacy by checking its hash against known malware databases.
- Examine the network connection attempt details, focusing on the destination IP address, to determine if it is associated with known malicious activity or command-and-control servers.
- Check the process name involved in the network connection attempt to ensure it is not a commonly used legitimate process, as specified in the query exclusions (e.g., simpleX, conftest, ssh, python, ispnull, pvtui).
- Correlate the timing of the compilation, execution, and network connection events to assess if they align with typical user behavior or indicate suspicious activity.

### False positive analysis

- Development activities involving frequent compilation and execution of new code can trigger false positives. To manage this, exclude specific user accounts or directories commonly used for legitimate development work.
- Automated build systems or continuous integration pipelines may compile and execute code regularly. Identify and exclude these processes or IP addresses from monitoring to prevent false alerts.
- Legitimate software updates or installations that involve compiling source code can be mistaken for malicious activity. Exclude known update processes or package managers from the rule.
- Network connections to internal or trusted IP addresses that are not part of the typical exclusion list might be flagged. Update the exclusion list to include these trusted IP ranges.
- Certain legitimate applications that compile and execute code as part of their normal operation, such as IDEs or scripting environments, should be identified and excluded from the rule to reduce noise.

### Response and remediation

- Immediately isolate the affected host from the network to prevent further unauthorized access or data exfiltration.
- Terminate any suspicious processes identified in the alert, especially those related to the recently compiled executable and any associated network connections.
- Conduct a forensic analysis of the affected system to identify any additional indicators of compromise, such as unauthorized user accounts or scheduled tasks.
- Remove any malicious executables or scripts identified during the investigation from the system to prevent re-execution.
- Reset credentials for any accounts that may have been compromised, focusing on those with elevated privileges.
- Update and patch the affected system to close any vulnerabilities that may have been exploited by the attacker.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if additional systems are affected."""

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

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

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

[[rule.threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"

[[rule.threat.technique]]
id = "T1095"
name = "Non-Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1095/"

[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 1m, correlated by file.name, host.id, process.args, process.name.

Stage 1: process

[process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and
   process.name like~ (
     "gcc*", "g++*", "c++", "cc", "c99", "c89", "cc1*", "cc1plus*", "clang*", "clang++*",
     "musl-gcc", "musl-clang", "*-linux-gnu-gcc*", "*-linux-gnu-g++*", "*-pc-linux-gnu-gcc*",
     "tcc", "zig", "ccache", "distcc"
   )] by process.args

Stage 2: file

[file where host.os.type == "linux" and event.action == "creation" and process.name like~ (
    "ld", "ld.*", "lld", "ld.lld", "mold", "collect2", "*-linux-gnu-ld*", "*-pc-linux-gnu-ld*"
   )] by file.name

Stage 3: process

[process where host.os.type == "linux" and event.type == "start" and event.action == "exec"] by process.name

Stage 4: network

[network where host.os.type == "linux" and event.action == "connection_attempted" and destination.ip != null and not (
     cidrmatch(destination.ip, "127.0.0.0/8", "169.254.0.0/16", "224.0.0.0/4", "::1") or
     process.name in (
       "simpleX", "conftest", "ssh", "python", "ispnull", "pvtui", "npreal2d", "ruby", "source", "ssh", "git-remote-http",
       "sshd-session", "gendb", "sqlplus"
     )
   )] by process.name

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
destination.ipis_not_null
  • (no value, null check)
field:"dest_ip" kind:is_not_null
event.actioneq
  • connection_attempted
  • creation
  • exec
field:"EventType" kind:eq
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
process.namewildcard
  • *-linux-gnu-g++*
  • *-linux-gnu-gcc*
  • *-linux-gnu-ld*
  • *-pc-linux-gnu-gcc*
  • *-pc-linux-gnu-ld*
  • c++
  • c89
  • c99
  • cc
  • cc1*
  • cc1plus*
  • ccache
  • clang*
  • clang++*
  • collect2
  • distcc
  • g++*
  • gcc*
  • ld
  • ld.*
  • ld.lld
  • lld
  • mold
  • musl-clang
  • musl-gcc
  • tcc
  • zig
field:"process_basename" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
destination.ipcidr_match127.0.0.0/8, 169.254.0.0/16, 224.0.0.0/4, ::1excludes:destination.ip
process.nameinconftest, gendb, git-remote-http, ispnull, npreal2d, pvtui, python, ruby, simpleX, source, sqlplus, ssh, sshd-sessionexcludes:process.name

Potential Okta MFA Bombing via Push Notifications

#
Status
production
Severity
high
Time window
10m
Sequence by
okta.actor.id
Author
Elastic
Source
github.com/elastic/detection-rules

Detects when an attacker abuses the Multi-Factor authentication mechanism by repeatedly issuing login requests until the user eventually accepts the Okta push notification. An adversary may attempt to bypass the Okta MFA policies configured for an organization to obtain unauthorized access.

MITRE ATT&CK Coverage

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2023/11/18"
integration = ["okta"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Detects when an attacker abuses the Multi-Factor authentication mechanism by repeatedly issuing login requests until the
user eventually accepts the Okta push notification. An adversary may attempt to bypass the Okta MFA policies configured
for an organization to obtain unauthorized access.
"""
event_category_override = "event.category"
index = ["filebeat-*", "logs-okta.system*"]
language = "eql"
license = "Elastic License v2"
name = "Potential Okta MFA Bombing via Push Notifications"
note = """## Triage and analysis

### Investigating Potential Okta MFA Bombing via Push Notifications

Multi-Factor Authentication (MFA) is an effective method to prevent unauthorized access. However, some adversaries may abuse the system by repeatedly sending MFA push notifications until the user unwittingly approves the access.

This rule detects when a user denies MFA Okta Verify push notifications twice, followed by a successful authentication event within a 10-minute window. This sequence could indicate an adversary's attempt to bypass the Okta MFA policy.

#### Possible investigation steps:

- Identify the user who received the MFA notifications by reviewing the `user.email` field.
- Identify the time, source IP, and geographical location of the MFA requests and the subsequent successful login.
- Review the `event.action` field to understand the nature of the events. It should include two `user.mfa.okta_verify.deny_push` actions and one `user.authentication.sso` action.
- Ask the user if they remember receiving the MFA notifications and subsequently logging into their account.
- Check if the MFA requests and the successful login occurred during the user's regular activity hours.
- Look for any other suspicious activity on the account around the same time.
- Identify whether the same pattern is repeated for other users in your organization. Multiple users receiving push notifications simultaneously might indicate a larger attack.

### False positive analysis:

- Determine if the MFA push notifications were legitimate. Sometimes, users accidentally trigger MFA requests or deny them unintentionally and later approve them.
- Check if there are known issues with the MFA system causing false denials.

### Response and remediation:

- If unauthorized access is confirmed, initiate your incident response process.
- Alert the user and your IT department immediately.
- If possible, isolate the user's account until the issue is resolved.
- Investigate the source of the unauthorized access.
- If the account was accessed by an unauthorized party, determine the actions they took after logging in.
- Consider enhancing your MFA policy to prevent such incidents in the future.
- Encourage users to report any unexpected MFA notifications immediately.
- Review and update your incident response plans and security policies based on the findings from the incident.
"""
references = [
    "https://www.mandiant.com/resources/russian-targeting-gov-business",
    "https://www.elastic.co/security-labs/testing-okta-visibility-and-detection-dorothy",
    "https://sec.okta.com/articles/2023/08/cross-tenant-impersonation-prevention-and-detection",
    "https://www.rezonate.io/blog/okta-logs-decoded-unveiling-identity-threats-through-threat-hunting/",
    "https://www.elastic.co/security-labs/monitoring-okta-threats-with-elastic-security",
    "https://www.elastic.co/security-labs/starter-guide-to-understanding-okta",
]
risk_score = 73
rule_id = "8a0fbd26-867f-11ee-947c-f661ea17fbcd"
severity = "high"
tags = [
    "Domain: Identity",
    "Use Case: Identity and Access Audit",
    "Tactic: Credential Access",
    "Data Source: Okta",
    "Data Source: Okta System Logs",
    "Resources: Investigation Guide",
]
type = "eql"

query = '''
sequence by okta.actor.id with maxspan=10m
  [ any
    where data_stream.dataset == "okta.system"
      and (
        okta.event_type == "user.mfa.okta_verify.deny_push"
        or (
          okta.event_type == "user.authentication.auth_via_mfa"
          and okta.debug_context.debug_data.factor == "OKTA_VERIFY_PUSH"
          and okta.outcome.reason == "INVALID_CREDENTIALS"
        )
      )
  ] with runs=5
  until
  [ any
    where data_stream.dataset == "okta.system"
      and okta.event_type in (
        "user.authentication.sso",
        "user.authentication.auth_via_mfa",
        "user.authentication.verify",
        "user.session.start"
      )
      and okta.outcome.result == "SUCCESS"
  ]
'''


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

[[rule.threat.technique]]
id = "T1621"
name = "Multi-Factor Authentication Request Generation"
reference = "https://attack.mitre.org/techniques/T1621/"

[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 = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"

[[rule.threat.technique.subtechnique]]
id = "T1078.004"
name = "Cloud Accounts"
reference = "https://attack.mitre.org/techniques/T1078/004/"

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

Stages and Predicates

Stage 1: any ×5

[ any
    where data_stream.dataset == "okta.system"
      and (
        okta.event_type == "user.mfa.okta_verify.deny_push"
        or (
          okta.event_type == "user.authentication.auth_via_mfa"
          and okta.debug_context.debug_data.factor == "OKTA_VERIFY_PUSH"
          and okta.outcome.reason == "INVALID_CREDENTIALS"
        )
      )
  ] with runs=5

Until: any

until
  [ any
    where data_stream.dataset == "okta.system"
      and okta.event_type in (
        "user.authentication.sso",
        "user.authentication.auth_via_mfa",
        "user.authentication.verify",
        "user.session.start"
      )
      and okta.outcome.result == "SUCCESS"
  ]

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
data_stream.dataseteq
  • okta.system corpus 13 (elastic 13)
field:"data_stream.dataset" kind:eq value:"okta.system"
okta.debug_context.debug_data.factoreq
  • OKTA_VERIFY_PUSH corpus 2 (elastic 2)
field:"okta::debugContext.debugData.factor" kind:eq value:"OKTA_VERIFY_PUSH"
okta.event_typeeq
  • user.authentication.auth_via_mfa corpus 4 (elastic 2, kusto 2)
  • user.mfa.okta_verify.deny_push corpus 3 (elastic 2, kusto 1)
field:"okta::eventType" kind:eq
okta.event_typein
  • user.authentication.auth_via_mfa corpus 2 (elastic 2)
  • user.authentication.sso corpus 3 (elastic 3)
  • user.authentication.verify corpus 2 (elastic 2)
  • user.session.start corpus 3 (elastic 3)
field:"okta::eventType" kind:in
okta.outcome.reasoneq
  • INVALID_CREDENTIALS corpus 3 (elastic 3)
field:"okta::outcome.reason" kind:eq value:"INVALID_CREDENTIALS"
okta.outcome.resulteq
  • SUCCESS corpus 7 (elastic 4, kusto 3)
field:"okta::outcome.result" kind:eq value:"SUCCESS"

Potential Privilege Escalation through Writable Docker Socket

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

This rule monitors for the usage of Docker runtime sockets to escalate privileges on Linux systems. Docker sockets by default are only be writable by the root user and docker group. Attackers that have permissions to write to these sockets may be able to create and run a container that allows them to escalate privileges and gain further access onto the host file system.

MITRE ATT&CK Coverage

TacticTechniques
Execution
Privilege Escalation

Rule Body

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

[rule]
author = ["Elastic"]
description = """
This rule monitors for the usage of Docker runtime sockets to escalate privileges on Linux systems. Docker sockets by
default are only be writable by the root user and docker group. Attackers that have permissions to write to these
sockets may be able to create and run a container that allows them to escalate privileges and gain further access onto
the host file system.
"""
from = "now-9m"
index = ["logs-endpoint.events.process*", "logs-crowdstrike.fdr*"]
language = "eql"
license = "Elastic License v2"
name = "Potential Privilege Escalation through Writable Docker Socket"
references = [
    "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation#automatic-enumeration-and-escape",
]
risk_score = 47
rule_id = "7acb2de3-8465-472a-8d9c-ccd7b73d0ed8"
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 = "medium"
tags = [
  "Domain: Endpoint",
  "OS: Linux",
  "Use Case: Threat Detection",
  "Tactic: Privilege Escalation",
  "Domain: Container",
  "Data Source: Elastic Defend",
  "Resources: Investigation Guide",
  "Data Source: Crowdstrike",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "ProcessRollup2") and
(
  (process.name == "docker" and process.args : "run" and process.args : "-it"  and
   process.args : ("unix://*/docker.sock", "unix://*/dockershim.sock")) or
  (process.name == "socat" and process.args : ("UNIX-CONNECT:*/docker.sock", "UNIX-CONNECT:*/dockershim.sock"))
) and not user.Ext.real.id : "0" and not group.Ext.real.id : "0"
'''
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 Privilege Escalation through Writable Docker Socket

Docker sockets facilitate communication between the Docker client and daemon, typically restricted to root or specific groups. Adversaries with write access can exploit these sockets to execute containers with elevated privileges, potentially accessing the host system. The detection rule identifies suspicious activities by monitoring processes like Docker and Socat for unauthorized socket interactions, focusing on non-root users attempting to execute commands, thus flagging potential privilege escalation attempts.

### Possible investigation steps

- Review the alert details to identify the specific process name (either "docker" or "socat") and the associated arguments that triggered the alert, focusing on the use of "unix://*/docker.sock" or "unix://*/dockershim.sock".
- Check the user and group IDs associated with the process to confirm they are non-root, as indicated by the exclusion of user.Ext.real.id and group.Ext.real.id being "0".
- Investigate the user account involved in the alert to determine if they should have access to Docker sockets and whether their permissions have been misconfigured or compromised.
- Examine the system logs and Docker daemon logs for any additional context or anomalies around the time of the alert to identify any unauthorized or suspicious activities.
- Assess the current state of the system for any unauthorized containers that may have been started, and inspect their configurations and running processes for signs of privilege escalation attempts.
- Verify the integrity and permissions of the Docker socket files to ensure they have not been altered to allow unauthorized access.

### False positive analysis

- Legitimate administrative tasks by non-root users with elevated permissions can trigger the rule. To manage this, identify trusted users or groups who regularly perform such tasks and create exceptions for their activities.
- Automated scripts or services that require Docker socket access for legitimate operations may be flagged. Review these scripts or services and whitelist their specific process names or arguments to prevent false positives.
- Development environments where developers frequently use Docker for testing might cause alerts. Consider creating a separate monitoring policy for development environments or exclude known development user accounts from this rule.
- Continuous integration/continuous deployment (CI/CD) pipelines that interact with Docker sockets can be mistakenly identified as threats. Ensure that these pipelines are running under specific service accounts and exclude these accounts from the rule.

### Response and remediation

- Immediately isolate the affected host from the network to prevent further unauthorized access or lateral movement.
- Terminate any unauthorized Docker containers that were started by non-root users, especially those interacting with Docker sockets.
- Review and revoke any unnecessary write permissions to Docker sockets for non-root users and groups, ensuring only trusted users have access.
- Conduct a thorough audit of user accounts and group memberships on the affected system to identify and remove any unauthorized or suspicious accounts.
- Restore the system from a known good backup if unauthorized changes or access to sensitive data are detected.
- Implement monitoring and alerting for any future unauthorized access attempts to Docker sockets, focusing on non-root user activities.
- Escalate the incident to the security operations team for further investigation and to assess potential impacts on other systems within the network."""


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

[[rule.threat.technique]]
id = "T1611"
name = "Escape to Host"
reference = "https://attack.mitre.org/techniques/T1611/"

[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 = "T1610"
name = "Deploy Container"
reference = "https://attack.mitre.org/techniques/T1610/"

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

Stages and Predicates

Stage 1: process

process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "ProcessRollup2") and
(
  (process.name == "docker" and process.args : "run" and process.args : "-it"  and
   process.args : ("unix://*/docker.sock", "unix://*/dockershim.sock")) or
  (process.name == "socat" and process.args : ("UNIX-CONNECT:*/docker.sock", "UNIX-CONNECT:*/dockershim.sock"))
) and not user.Ext.real.id : "0" and not group.Ext.real.id : "0"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actionin
  • ProcessRollup2
  • exec
field:"EventType" kind:in
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
process.argswildcard
  • -it
  • UNIX-CONNECT:*/docker.sock
  • UNIX-CONNECT:*/dockershim.sock
  • run
  • unix://*/docker.sock
  • unix://*/dockershim.sock
field:"process.args" kind:wildcard
process.nameeq
  • docker
  • socat
field:"process_basename" kind:eq

Exclusions

The rule actively suppresses these predicates.

Potential Remote Credential Access via Registry

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

Identifies remote access to the registry to potentially dump credential data from the Security Account Manager (SAM) registry hive in preparation for credential access and privileges elevation.

MITRE ATT&CK Coverage

Telemetry Coverage

ProviderRecord / event type
SysmonEvent ID 11: FileCreate

Rule Body

[metadata]
creation_date = "2022/03/01"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/04/27"

[rule]
author = ["Elastic"]
description = """
Identifies remote access to the registry to potentially dump credential data from the Security Account Manager (SAM)
registry hive in preparation for credential access and privileges elevation.
"""
from = "now-9m"
index = ["logs-endpoint.events.file-*"]
language = "eql"
license = "Elastic License v2"
name = "Potential Remote Credential Access via Registry"
references = [
    "https://github.com/fortra/impacket/blob/master/examples/secretsdump.py",
    "https://www.elastic.co/security-labs/detect-credential-access",
]
risk_score = 73
rule_id = "850d901a-2a3c-46c6-8b22-55398a01aad8"
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Lateral Movement",
    "Tactic: Credential Access",
    "Resources: Investigation Guide",
    "Data Source: Elastic Defend",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
file where host.os.type == "windows" and
  event.action == "creation" and process.name : "svchost.exe" and
  file.Ext.header_bytes : "72656766*" and user.id : ("S-1-5-21-*", "S-1-12-1-*") and file.size >= 30000 and
  file.path : ("?:\\Windows\\system32\\*.tmp", "?:\\WINDOWS\\Temp\\*.tmp")
'''

note = """## Triage and analysis

### Investigating Potential Remote Credential Access via Registry

#### Possible investigation steps

- Does the alert-local file prove a registry hive save?
  - Focus: `event.action`, `file.path`, `file.size`, `file.Ext.header_bytes`, and `process.name`.
  - Implication: escalate when svchost.exe writes a hive-sized Windows temp file with REGF header bytes; lower concern only when content or location contradicts hive export or matches a recognized hive-export workflow on this host.

- Does the svchost instance fit RemoteRegistry-backed collection?
  - Focus: `process.executable`, `process.command_line`, `process.parent.executable`, `process.Ext.session_info.logon_type`, and `process.Ext.session_info.authentication_package`.
  - Hint: if parent or session fields are absent, recover the endpoint process event with `host.id` and `process.entity_id`.
  - Implication: escalate when svchost is outside the Windows system path, lacks service-control lineage, uses an unusual service group, or runs under an unexpected remote/network session; lower concern when service context and session fields align with one recognized collection workflow.

- Did the same process create companion hive artifacts?
  - Why: secretsdump-style collection often saves SAM, SECURITY, and SYSTEM hives to target temp storage before parsing or retrieval.
  - Focus: file events on `host.id` scoped to `process.entity_id`: `file.path`, `file.name`, `file.size`, `file.Ext.header_bytes`, and `file.Ext.original.path`. $investigate_0
  - Implication: escalate when the same process creates multiple hive-sized REGF temp files, renamed copies, or cleanup artifacts; a single hive artifact narrows scope but does not clear the alert by itself.

- Does the account and logon session fit recognized collection on this host?
  - Focus: `user.id`, `user.name`, `user.domain`, `process.Ext.authentication_id`, and `process.Ext.token.elevation_level`.
  - Hint: if Windows Security telemetry exists, bridge `process.Ext.authentication_id` to same-host logon events and read source host/IP, logon type, and authentication package. Missing authentication telemetry is unresolved, not benign. $investigate_2
  - Implication: escalate when account, SID/domain, logon session, or elevation is not the identity used for recognized collection on this host; lower concern only when the same account and session context match that exact workflow.

- Did the same session leave local staging, cleanup, or follow-on credential-access activity?
  - Focus: endpoint process events on `host.id` scoped to `process.Ext.authentication_id`, then file events for matching `process.entity_id`: `process.command_line`, `process.parent.command_line`, `file.path`, and `file.Ext.original.path`. $investigate_1
  - Hint: if the alert lacks `process.Ext.authentication_id`, recover it from the endpoint process event before same-session review.
  - Implication: escalate when the same session starts service-control, scripting, copy, compression, cleanup, or additional credential-access activity around the hive write; a single visible hive file remains unresolved because missing follow-on endpoint evidence is not benign.

- If local evidence remains suspicious or incomplete, do related alerts widen scope?
  - Focus: related `user.id` alerts for credential dumping, remote-service abuse, hive saves, or archive staging. $investigate_3
  - Hint: if account ownership is shared or ambiguous, compare `host.id` alerts for remote execution, service abuse, or alternate collection paths. $investigate_4
  - Implication: broaden when the same user or host shows credential dumping, remote-service abuse, archive staging, or repeated hive-save alerts; keep local when related activity stays confined to one recognized collection case.

- Escalate on a valid hive save plus unexplained service context, account/session, companion artifacts, cleanup, or related-alert evidence; close only when endpoint evidence and any needed outside confirmation bind one exact recognized workflow on this host; preserve and escalate when evidence is mixed or incomplete.

### False positive analysis

- Incident-response, forensic acquisition, recovery, or credential-audit jobs can legitimately trigger only when they explicitly export registry hives. Confirm one exact workflow across svchost service context, `process.command_line`, `user.id`, `host.id`, session fields, hive-sized temp `file.path` values, and companion SAM, SECURITY, or SYSTEM artifacts. If telemetry cannot prove legitimacy, require case or owner confirmation; do not close if account, service context, artifact set, or host scope expands beyond that workflow.
- Before exceptioning, validate stable `process.command_line`, `process.executable`, parent context, `user.id`, `host.id`, hive temp-path pattern, and `file.Ext.header_bytes` across prior alerts. Avoid exceptions on svchost.exe, temp paths, or REGF header bytes alone.

### Response and remediation

- If confirmed benign, release temporary containment and document the recognized service context, `process.command_line`, account, session context, `host.id`, hive `file.path` values, and companion artifacts that matched the collection workflow. Create an exception only after the same evidence pattern is stable across prior alerts from this rule.
- If suspicious but unconfirmed, preserve a case export covering the alert file, same-process companion hives, same-session process and file activity, process tree, related-alert records, hive paths, sizes, and header bytes before containment. Record the re-query anchors `host.id`, `user.id`, `process.entity_id`, and `process.Ext.authentication_id` with the preserved case export. Apply reversible containment first, such as temporary RemoteRegistry restrictions, share restrictions, or heightened monitoring for the affected account and host; weigh server criticality before isolation.
- If confirmed malicious, first preserve the case export and record `process.entity_id`, `process.command_line`, parent context, companion hive paths, same-session activity, and affected `host.id`. Then isolate the host when artifact, service-context, session, or related-alert evidence establishes unauthorized hive collection. Kill or suspend the responsible process and disable or reset the involved account only after evidence capture and only when the `user.id` evidence supports compromise or unauthorized use.
- Treat companion SAM, SECURITY, and SYSTEM artifacts as exposure of local account material, cached secrets, machine secrets, and LSA secrets for the affected asset. Start credential hygiene appropriate to the host role and any accounts or services touched by the same session.
- After scoping, eradicate only artifacts and changes identified during triage: unauthorized hive copies, staging archives, dump tooling, cleanup scripts, and remote-service changes that enabled the access. Restore legitimate RemoteRegistry or backup configuration if it was altered, and remediate the entry path that allowed the hive save.
- Post-incident hardening: restrict RemoteRegistry-backed hive collection to controlled workflows, minimize accounts allowed to perform remote collection, and retain endpoint process and file telemetry needed to distinguish secretsdump-style, VSS-based, or WMI-based variants in future cases.
"""

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
"""

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "host.id",
    "user.name",
    "user.id",
    "process.executable",
    "process.command_line",
    "process.entity_id",
    "process.parent.executable",
    "process.Ext.authentication_id",
    "process.Ext.session_info.logon_type",
    "process.Ext.session_info.authentication_package",
    "process.Ext.token.elevation_level",
    "file.path",
    "file.size",
    "file.Ext.header_bytes",
]

[transform]

[[transform.investigate]]
label = "File activity for the same process"
description = ""
providers = [
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
    { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

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

[[transform.investigate]]
label = "Windows Security events for the local process session"
description = ""
providers = [
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "winlog.event_data.TargetLogonId", queryType = "phrase", value = "{{process.Ext.authentication_id}}", valueType = "string" },
    { excluded = false, field = "event.code", queryType = "phrase", value = "4624", valueType = "string" }
  ],
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "winlog.event_data.SubjectLogonId", queryType = "phrase", value = "{{process.Ext.authentication_id}}", valueType = "string" },
    { excluded = false, field = "event.code", queryType = "phrase", value = "4648", valueType = "string" }
  ]
]
relativeFrom = "now-24h"
relativeTo = "now"

[[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 = "T1003"
name = "OS Credential Dumping"
reference = "https://attack.mitre.org/techniques/T1003/"
[[rule.threat.technique.subtechnique]]
id = "T1003.002"
name = "Security Account Manager"
reference = "https://attack.mitre.org/techniques/T1003/002/"

[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 = "T1021"
name = "Remote Services"
reference = "https://attack.mitre.org/techniques/T1021/"

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

Stages and Predicates

Stage 1: file

file where host.os.type == "windows" and
  event.action == "creation" and process.name : "svchost.exe" and
  file.Ext.header_bytes : "72656766*" and user.id : ("S-1-5-21-*", "S-1-12-1-*") and file.size >= 30000 and
  file.path : ("?:\\Windows\\system32\\*.tmp", "?:\\WINDOWS\\Temp\\*.tmp")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • creation corpus 50 (elastic 50)
field:"EventType" kind:eq value:"creation"
file.Ext.header_byteswildcard
  • 72656766* corpus 2 (elastic 2)
field:"file.Ext.header_bytes" kind:wildcard value:"72656766*"
file.pathwildcard
  • ?:\WINDOWS\Temp\*.tmp
  • ?:\Windows\system32\*.tmp
field:"TargetFilename" kind:wildcard
file.sizege
  • 30000 transforms: number corpus 5 (elastic 5)
field:"file.size" kind:ge value:"30000"
process.namewildcard
  • svchost.exe corpus 21 (elastic 20, splunk 1)
field:"process_basename" kind:wildcard value:"svchost.exe"
user.idwildcard
  • S-1-12-1-* corpus 6 (elastic 6)
  • S-1-5-21-* corpus 6 (elastic 6)
field:"user.id" kind:wildcard

Privilege Escalation via NTLMRelay2Self

#
Source
github.com/elastic/protections-artifacts

Identifies attempt to coerce a local NTLM authentication via HTTP using Printer Spooler service as a target. An adversary may use this primitive in combination with others to elevate privileges on a compromised system.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies attempt to coerce a local NTLM authentication via HTTP using Printer Spooler service as a target. An
adversary may use this primitive in combination with others to elevate privileges on a compromised system.
"""
id = "cabd7f21-70ff-429b-8818-f210ba603461"
license = "Elastic License v2"
name = "Privilege Escalation via NTLMRelay2Self"
os_list = ["windows"]
reference = ["https://github.com/med0x2e/NTLMRelay2Self"]
version = "1.0.27"

query = '''
process where event.action == "start" and
  process.name : "rundll32.exe" and 
  
  /* Rundll32 WbeDav Client  */
  process.args : ("?:\\Windows\\System32\\davclnt.dll,DavSetCookie", "?:\\Windows\\SysWOW64\\davclnt.dll,DavSetCookie") and 
  
  /* Access to named pipe via http */
  process.args : ("http*/print/pipe/*", "http*/pipe/spoolss", "http*/pipe/srvsvc")
'''

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 = "T1068"
name = "Exploitation for Privilege Escalation"
reference = "https://attack.mitre.org/techniques/T1068/"


[threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1558"
name = "Steal or Forge Kerberos Tickets"
reference = "https://attack.mitre.org/techniques/T1558/"


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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Stage 1: process

process where event.action == "start" and
  process.name : "rundll32.exe" and
  process.args : ("?:\\Windows\\System32\\davclnt.dll,DavSetCookie", "?:\\Windows\\SysWOW64\\davclnt.dll,DavSetCookie") and
  process.args : ("http*/print/pipe/*", "http*/pipe/spoolss", "http*/pipe/srvsvc")

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
  • ?:\Windows\SysWOW64\davclnt.dll,DavSetCookie corpus 2 (elastic 2)
  • ?:\Windows\System32\davclnt.dll,DavSetCookie corpus 2 (elastic 2)
  • http*/pipe/spoolss corpus 2 (elastic 2)
  • http*/pipe/srvsvc corpus 2 (elastic 2)
  • http*/print/pipe/* corpus 2 (elastic 2)
field:"process.args" kind:wildcard
process.namewildcard
  • rundll32.exe corpus 123 (elastic 100, splunk 23)
field:"process_basename" kind:wildcard value:"rundll32.exe"

Shell Execution via Java Parent Process

#
Source
github.com/elastic/protections-artifacts

This rule detects shell executions spawned by Java parent processes in specific user directories, excluding Oracle SYSMAN schema and Enterprise Management Daemon (EMD) related working directories. Such behavior may indicate exploitation attempts or command execution.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
This rule detects shell executions spawned by Java parent processes in specific user directories, excluding Oracle
SYSMAN schema and Enterprise Management Daemon (EMD) related working directories. Such behavior may indicate
exploitation attempts or command execution.
"""
id = "565c5297-16f2-47aa-8537-2982475d30b2"
license = "Elastic License v2"
name = "Shell Execution via Java Parent Process"
os_list = ["linux"]
reference = [
    "https://www.oracle.com/security-alerts/alert-cve-2025-61882.html",
    "https://www.crowdstrike.com/en-us/blog/crowdstrike-identifies-campaign-targeting-oracle-e-business-suite-zero-day-CVE-2025-61882/",
]
version = "1.0.2"

query = '''
process where event.type == "start" and event.action == "exec" and process.parent.name == "java" and
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and process.args == "-c" and
process.working_directory like~ "/u0?/*" and user.id == 54321 and not (
  process.working_directory like~ ("/u0*/*/sysman/emd", "/u0?/app/oracle/product/*/dbhome_*", "/u0?/app/oracle/product/*/db_*", "/u01/app/oracle/crsdata/*/cvu/cvutrc") or
  process.command_line == "/bin/sh -c /u01/client_1/client/scheduler/execution_agent/bin/jssu" or
  (process.working_directory == "/u01/domains/bi" and process.command_line like "*weblogic.Server*") or
  process.args like ("/tmp/CVU_19_*/exectask.sh*", "java -cp*/u01/MW/bi/modules/oracle.bi.sysman/scripts/../env/stdout_config.properties*") or
  (
    process.parent.executable like "/u01/app/*grid/jdk/bin/java" and
    process.args like ("/bin/rpm*", "/u01/app/grid/bin/*", "/bin/uname -m", "/u01/app/oracle/product/*/bin/*")
  ) or
  (
    process.parent.executable like "/u01/app/oracle/*/jdk/*bin/java" and
    process.args like ("/u01/app/oracle/product/*/bin/*", "/usr/sbin/lpc*", "stty*")
  )
)
'''

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 = "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.technique]]
id = "T1203"
name = "Exploitation for Client Execution"
reference = "https://attack.mitre.org/techniques/T1203/"


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

Stage 1: process

process where event.type == "start" and event.action == "exec" and process.parent.name == "java" and
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and process.args == "-c" and
process.working_directory like~ "/u0?/*" and user.id == 54321 and not (
  process.working_directory like~ ("/u0*/*/sysman/emd", "/u0?/app/oracle/product/*/dbhome_*", "/u0?/app/oracle/product/*/db_*", "/u01/app/oracle/crsdata/*/cvu/cvutrc") or
  process.command_line == "/bin/sh -c /u01/client_1/client/scheduler/execution_agent/bin/jssu" or
  (process.working_directory == "/u01/domains/bi" and process.command_line like "*weblogic.Server*") or
  process.args like ("/tmp/CVU_19_*/exectask.sh*", "java -cp*/u01/MW/bi/modules/oracle.bi.sysman/scripts/../env/stdout_config.properties*") or
  (
    process.parent.executable like "/u01/app/*grid/jdk/bin/java" and
    process.args like ("/bin/rpm*", "/u01/app/grid/bin/*", "/bin/uname -m", "/u01/app/oracle/product/*/bin/*")
  ) or
  (
    process.parent.executable like "/u01/app/oracle/*/jdk/*bin/java" and
    process.args like ("/u01/app/oracle/product/*/bin/*", "/usr/sbin/lpc*", "stty*")
  )
)

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argswildcard/bin/rpm*, /u01/app/grid/bin/*, /bin/uname -m, /u01/app/oracle/product/*/bin/*excludes:process.args
process.parent.executablewildcard/u01/app/*grid/jdk/bin/javaexcludes:process.parent.executable field:"process.parent.executable" value:"/u01/app/*grid/jdk/bin/java"
process.argswildcard/u01/app/oracle/product/*/bin/*, /usr/sbin/lpc*, stty*excludes:process.args field:"process.args" value:"/u01/app/oracle/product/*/bin/*" field:"process.args" value:"/usr/sbin/lpc*" field:"process.args" value:"stty*"
process.parent.executablewildcard/u01/app/oracle/*/jdk/*bin/javaexcludes:process.parent.executable field:"process.parent.executable" value:"/u01/app/oracle/*/jdk/*bin/java"
process.command_linematchweblogic.Serverexcludes:process.command_line field:"process.command_line" value:"weblogic.Server"
process.working_directoryeq/u01/domains/biexcludes:process.working_directory field:"process.working_directory" value:"/u01/domains/bi"
process.argswildcard/tmp/CVU_19_*/exectask.sh*, java -cp*/u01/MW/bi/modules/oracle.bi.sysman/scripts/../env/stdout_config.properties*excludes:process.args field:"process.args" value:"/tmp/CVU_19_*/exectask.sh*" field:"process.args" value:"java -cp*/u01/MW/bi/modules/oracle.bi.sysman/scripts/../env/stdout_config.properties*"
process.command_lineeq/bin/sh -c /u01/client_1/client/scheduler/execution_agent/bin/jssuexcludes:process.command_line field:"process.command_line" value:"/bin/sh -c /u01/client_1/client/scheduler/execution_agent/bin/jssu"
process.working_directorywildcard/u0*/*/sysman/emd, /u0?/app/oracle/product/*/dbhome_*, /u0?/app/oracle/product/*/db_*, /u01/app/oracle/crsdata/*/cvu/cvutrcexcludes:process.working_directory

Suspicious Cmd Execution via WMI

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

Identifies suspicious command execution (cmd) via Windows Management Instrumentation (WMI) on a remote host. This could be indicative of adversary lateral movement.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2020/10/19"
integration = ["endpoint", "windows", "system", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/05/03"

[rule]
author = ["Elastic"]
description = """
Identifies suspicious command execution (cmd) via Windows Management Instrumentation (WMI) on a remote host. This could
be indicative of adversary lateral movement.
"""
from = "now-9m"
index = [
    "endgame-*",
    "logs-crowdstrike.fdr*",
    "logs-endpoint.events.process-*",
    "logs-m365_defender.event-*",
    "logs-sentinel_one_cloud_funnel.*",
    "logs-system.security*",
    "logs-windows.forwarded*",
    "logs-windows.sysmon_operational-*",
    "winlogbeat-*",
]
language = "eql"
license = "Elastic License v2"
name = "Suspicious Cmd Execution via WMI"
references = [
    "https://www.elastic.co/security-labs/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper",
    "https://www.elastic.co/security-labs/operation-bleeding-bear",
]
risk_score = 73
rule_id = "12f07955-1674-44f7-86b5-c35da0a6f41a"
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Execution",
    "Data Source: Elastic Endgame",
    "Data Source: Elastic Defend",
    "Data Source: Windows Security Event Logs",
    "Data Source: Microsoft Defender XDR",
    "Data Source: Sysmon",
    "Data Source: SentinelOne",
    "Data Source: Crowdstrike",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
process where host.os.type == "windows" and event.type == "start" and
 process.parent.name : "WmiPrvSE.exe" and process.name : "cmd.exe" and process.args : "/c" and process.args:"/Q" and 
 process.args : "2>&1" and process.args: "1>"  and 
 process.args : ("C:\\windows\\temp\\*.txt", "\\Windows\\Temp\\*", "-encodehex", "\\\\127.0.0.1\\C$\\Windows\\Temp\\*", "\\\\127.0.0.1\\ADMIN$\\__*.*")
'''

note = """## Triage and analysis

### Investigating Suspicious Cmd Execution via WMI

#### Possible investigation steps

- Does the alert-local command line match the Impacket-style WMI output-capture shape?
  - Focus: `process.command_line` for quiet execution, stdout/stderr redirection, temp or loopback admin-share output paths, `__*` names, and "-encodehex".
  - Implication: escalate when WMI-brokered output capture writes to temp or loopback admin-share paths; lower concern only when the same exact capture shape recurs for one recognized RMM, SCCM, backup, or helpdesk workflow on this `host.id`.

- Are "cmd.exe" and "WmiPrvSE.exe" the expected binaries in the expected launch context?
  - Focus: `process.executable`, `process.code_signature.subject_name`, `process.code_signature.trusted`, `process.parent.executable`, and `process.parent.command_line`.
  - Implication: escalate when either binary is unsigned, renamed, path-abnormal, or WMI broker context does not fit a management service; Microsoft-signed binaries reduce masquerade concern but do not clear output capture.

- What operation does the captured command perform?
  - Focus: `process.command_line` for nested interpreters, discovery commands, copy/archive tools, service or scheduled-task verbs, and defense-evasion tokens.
  - Implication: escalate when the command stages execution, changes services or tasks, performs discovery at scale, invokes secondary interpreters or LOLBins, copies payloads, or hides output; lower concern for one bounded diagnostic or inventory command.

- Does the user, host, and any session metadata fit controlled WMI administration?
  - Focus: `user.id`, `user.domain`, `host.id`, `process.Ext.session_info.logon_type`, and `process.Ext.session_info.authentication_package`.
  - Hint: when `process.Ext.authentication_id` or session details exist, pivot to same-host Windows Security 4624/4648 and match logon/session ID to recover source workstation, source IP, and account context. Missing authentication telemetry is unresolved, not benign.
  - Hint: if session metadata is absent, decide from recurring `user.id`, `host.id`, parent executable, command line, child lineage, and related-alert pattern; missing session metadata is unresolved, not benign.
  - Implication: escalate when a standard user, unusual domain context, network/service session, or unexpected NTLM context drives WMI command execution on this host; lower concern when the same account, host, and parent-command pattern recur as controlled administration.

- Did the WMI-launched command become a launcher for follow-on execution?
  - Focus: child process events from `process.entity_id`, reading child `process.name`, `process.executable`, and `process.command_line`. $investigate_0
  - Hint: if `process.entity_id` is missing, use `host.id` plus alert `process.pid` as child `process.parent.pid` in a tight alert window; treat this as weaker than entity-linked lineage.
  - Implication: escalate when child processes include secondary interpreters, "rundll32.exe", "regsvr32.exe", "schtasks.exe", "sc.exe", copy tools, archivers, or other LOLBins; keep scope narrower when the cmd instance exits after one bounded command and no suspicious child appears.

- If local process evidence stays suspicious or unresolved, do related alerts show the same user or host in lateral-movement activity?
  - Focus: same-`user.id` alerts that reuse WMI output-capture fragments, WMI parentage, SMB, WinRM, service-install, scheduled-task, or matching command-line patterns. $investigate_1
  - Hint: if the user view is quiet or ambiguous, compare same-`host.id` alerts. $investigate_2
  - Implication: broaden scope when the same user, host, or command pattern appears in adjacent remote-execution alerts; keep the case local when related alerts are absent and the local process evidence already explains the activity.

- Escalate when output capture combines with suspicious identity, command intent, session, child, or related-alert evidence; close only when exact command shape, parent, user/host scope, child lineage, and recurrence bind to one recognized workflow on this `host.id`; preserve evidence and escalate when answers conflict or remain incomplete.

### False positive analysis

- Remote-management, software distribution, backup, and helpdesk workflows can run "cmd.exe" through WMI and capture output to temp or loopback admin-share paths. Confirm only when parent executable, command line, `user.id`, `host.id`, process-side session context, and child behavior align with one workflow. Inventories, change records, and owner confirmation can corroborate but not replace telemetry; without them, require recurrence of the same anchors across prior alerts from this rule.
- Bounded diagnostic WMI commands can be legitimate when an admin account runs one inventory or support command and the tree ends there. Do not close on Microsoft-signed "cmd.exe" or "WmiPrvSE.exe" alone; require exact output-capture shape, account, host scope, and no suspicious child processes to match the recognized workflow.
- Build exceptions from the minimum confirmed pattern: stable `process.parent.executable`, specific output-capture command shape, `user.id`, and `host.id`. Avoid exceptions on `process.name`, "cmd.exe", "WmiPrvSE.exe", or temp-path fragments alone.

### Response and remediation

- If confirmed benign, reverse any temporary containment and document the command, WMI broker path, account, host, session context, child-process result, and recurrence evidence that validated the workflow. Create an exception only for that same recurring pattern.
- If suspicious but unconfirmed, export the alert, process tree, command line, parent context, child-process lineage, temp/admin-share output path fragments, and related-alert results before containment. Apply reversible containment first, such as heightened monitoring or temporary WMI restriction for the affected account or host where business impact permits; isolate the host only if child execution, destructive command intent, or related alerts suggest active compromise.
- If confirmed malicious, isolate the host when its role can tolerate isolation, or terminate the alerting "cmd.exe" and malicious child processes only after preserving their command lines and entity IDs. Disable or rotate the affected credentials when user/session evidence or related alerts show account misuse.
- After containment, remove only the temp outputs, staged payloads, services, scheduled tasks, or WMI persistence changes identified during the investigation, then verify no related alerts remain for the same `user.id`, `host.id`, or `process.command_line` pattern.
- Post-incident hardening: restrict remote WMI to recognized admin hosts and accounts, reduce local administrator exposure, and retain process telemetry that distinguishes this output-capture pattern from adjacent WinRM or SMB service-based remote execution.
"""

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)
- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
- [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
- [Windows Process Creation Logs](https://ela.st/audit-process-creation)
"""

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "host.id",
    "user.id",
    "process.entity_id",
    "process.pid",
    "process.executable",
    "process.command_line",
    "process.args",
    "process.code_signature.subject_name",
    "process.code_signature.trusted",
    "process.Ext.session_info.logon_type",
    "process.Ext.session_info.authentication_package",
    "process.parent.executable",
    "process.parent.command_line",
    "process.parent.args",
]

[transform]

[[transform.investigate]]
label = "Child processes from WMI launched via Cmd.exe"
description = ""
providers = [
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
    { 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.parent.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
    { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

[[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 = "T1047"
name = "Windows Management Instrumentation"
reference = "https://attack.mitre.org/techniques/T1047/"

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

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

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

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

[[rule.threat.technique]]
id = "T1021"
name = "Remote Services"
reference = "https://attack.mitre.org/techniques/T1021/"

[[rule.threat.technique.subtechnique]]
id = "T1021.003"
name = "Distributed Component Object Model"
reference = "https://attack.mitre.org/techniques/T1021/003/"

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

Stages and Predicates

Stage 1: process

process where host.os.type == "windows" and event.type == "start" and
 process.parent.name : "WmiPrvSE.exe" and process.name : "cmd.exe" and process.args : "/c" and process.args:"/Q" and 
 process.args : "2>&1" and process.args: "1>"  and 
 process.args : ("C:\\windows\\temp\\*.txt", "\\Windows\\Temp\\*", "-encodehex", "\\\\127.0.0.1\\C$\\Windows\\Temp\\*", "\\\\127.0.0.1\\ADMIN$\\__*.*")

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.argswildcard
  • -encodehex corpus 2 (elastic 2)
  • /Q corpus 7 (elastic 7)
  • /c corpus 7 (elastic 7)
  • 1> corpus 2 (elastic 2)
  • 2>&1 corpus 2 (elastic 2)
  • C:\windows\temp\*.txt corpus 2 (elastic 2)
  • \Windows\Temp\* corpus 2 (elastic 2)
  • \\127.0.0.1\ADMIN$\__*.*
  • \\127.0.0.1\C$\Windows\Temp\* corpus 2 (elastic 2)
field:"process.args" kind:wildcard
process.namewildcard
  • cmd.exe corpus 122 (elastic 93, splunk 29)
field:"process_basename" kind:wildcard value:"cmd.exe"
process.parent.namewildcard
  • WmiPrvSE.exe corpus 24 (elastic 19, splunk 5)
field:"parent_process_basename" kind:wildcard value:"WmiPrvSE.exe"

Suspicious Deobfuscation via Shell Script

#
Time window
10s
Sequence by
process.Ext.effective_parent.entity_id
Source
github.com/elastic/protections-artifacts

Detects when a large shell script is executed followed by the execution of the base64 or xxd binary. Threat actors will often use shell scripts to obfuscate their commands in order to avoid detection. The use of base64 or xxd to decode the shell script is indicative of a threat actor attempting to deobfuscate their commands.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[rule]
description = """
Detects when a large shell script is executed followed by the execution of the base64 or xxd binary. Threat actors will
often use shell scripts to obfuscate their commands in order to avoid detection. The use of base64 or xxd to decode the
shell script is indicative of a threat actor attempting to deobfuscate their commands.
"""
id = "dbc7be20-89c3-4b84-bb0e-b893d06425de"
license = "Elastic License v2"
name = "Suspicious Deobfuscation via Shell Script"
os_list = ["macos"]
reference = ["https://x.com/MsftSecIntel/status/1891410993265123662"]
version = "1.0.4"

query = '''
sequence by process.Ext.effective_parent.entity_id with maxspan=10s
[process where event.type == "start" and event.action == "exec" and (process.name in ("sh", "bash", "zsh", "dash", "csh", "tcsh", "ksh", "tclsh", "fish") or process.name like "tclsh*") and process.args == "-c" and process.command_line == null and process.args_count > 2]
[process where event.type == "start" and event.action == "exec" and process.name in ("base64", "xxd")]
'''

min_endpoint_version = "8.11.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 = "T1027"
name = "Obfuscated Files or Information"
reference = "https://attack.mitre.org/techniques/T1027/"

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


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

[internal]
min_endpoint_version = "8.11.0"

Stages and Predicates

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

Stage 1: process

[process where event.type == "start" and event.action == "exec" and (process.name in ("sh", "bash", "zsh", "dash", "csh", "tcsh", "ksh", "tclsh", "fish") or process.name like "tclsh*") and process.args == "-c" and process.command_line == null and process.args_count > 2]

Stage 2: process

[process where event.type == "start" and event.action == "exec" and process.name in ("base64", "xxd")]

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.argseq
  • -c corpus 91 (elastic 91)
field:"process.args" kind:eq value:"-c"
process.args_countgt
  • 2 transforms: number
field:"process.args_count" kind:gt value:"2"
process.command_lineis_null
  • (no value, null check)
field:"CommandLine" kind:is_null
process.namein
  • base64 corpus 20 (elastic 20)
  • bash corpus 181 (elastic 181)
  • csh corpus 148 (elastic 148)
  • dash corpus 150 (elastic 150)
  • fish corpus 151 (elastic 151)
  • ksh corpus 149 (elastic 149)
  • sh corpus 180 (elastic 180)
  • tclsh corpus 28 (elastic 28)
  • tcsh corpus 145 (elastic 145)
  • xxd corpus 9 (elastic 9)
  • zsh corpus 180 (elastic 180)
field:"process_basename" kind:in
process.namewildcard
  • tclsh* corpus 23 (elastic 23)
field:"process_basename" kind:wildcard value:"tclsh*"

Suspicious Execution as System via Windows Command Shell

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

Identifies the execution of the Windows Command Shell with an integrity level of SYSTEM from a parent process with a Medium integrity level.This behavior is consistent with a successful exploit to escalate privileges and create a process with SYSTEM privileges.

MITRE ATT&CK Coverage

TacticTechniques
Privilege Escalation

Rule Body

[rule]
description = """
Identifies the execution of the Windows Command Shell with an integrity level of SYSTEM from a parent process with a
Medium integrity level.This behavior is consistent with a successful exploit to escalate privileges and create a process
with SYSTEM privileges.
"""
id = "4d1a0064-f5d3-46df-8e23-5a9d78635764"
license = "Elastic License v2"
name = "Suspicious Execution as System via Windows Command Shell"
os_list = ["windows"]
reference = [
    "https://bsodtutorials.wordpress.com/2014/07/31/windows-integrity-levels-process-explorer-and-windbg/",
]
version = "1.0.2"

query = '''
sequence with maxspan=2m
 [process where event.action == "start" and
  process.Ext.token.integrity_level_name == "medium" and
  (process.Ext.relative_file_creation_time <= 500 or process.Ext.relative_file_name_modify_time <= 500)] by process.entity_id
 [process where event.action == "start" and
  process.Ext.token.integrity_level_name == "system" and
  (process.name : "cmd.exe" or process.pe.original_file_name == "Cmd.Exe")] by process.parent.entity_id
'''

min_endpoint_version = "8.4.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 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 = "T1068"
name = "Exploitation for Privilege Escalation"
reference = "https://attack.mitre.org/techniques/T1068/"


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

[internal]
min_endpoint_version = "8.4.0"

Stages and Predicates

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

Stage 1: process

[process where event.action == "start" and
  process.Ext.token.integrity_level_name == "medium" and
  (process.Ext.relative_file_creation_time <= 500 or process.Ext.relative_file_name_modify_time <= 500)] by process.entity_id

Stage 2: process

[process where event.action == "start" and
  process.Ext.token.integrity_level_name == "system" and
  (process.name : "cmd.exe" or process.pe.original_file_name == "Cmd.Exe")] by process.parent.entity_id

Indicators

These rows show field, operator, and value matches.

Suspicious Registry Symbolic Link

#

Suspicious VSCode Extension Child Process

#
Source
github.com/elastic/protections-artifacts

Detects when a vscode extension spawns an abnormal or suspicious child process. This activity can indicate that a malicious extension has been installed and is attempting to perform malicious actions on a user's system for initial access, data stealing, etc.

MITRE ATT&CK Coverage

TacticTechniques
Command & Control

Telemetry Coverage

Rule Body

[rule]
description = """
Detects when a vscode extension spawns an abnormal or suspicious child process. This activity can indicate that a
malicious extension has been installed and is attempting to perform malicious actions on a user's system for initial
access, data stealing, etc.
"""
id = "9718bd56-a611-4c1e-a934-5145d5377656"
license = "Elastic License v2"
name = "Suspicious VSCode Extension Child Process"
os_list = ["macos"]
reference = [
    "https://www.bleepingcomputer.com/news/security/malicious-microsoft-vscode-extensions-steal-passwords-open-remote-shells/",
]
version = "1.0.14"

query = '''
process where event.action == "exec" and 
 (process.parent.executable like~ "/Users/*/.vscode/extensions/*" or process.Ext.effective_parent.executable like~ "/Users/*/.vscode/extensions/*") and
    (
     (process.name in ("sh", "bash", "zsh") and
	     process.args == "-c" and process.args like~ ("*curl*", "*nscurl*", "*osascript*", "*zip*")) or
	  
     (process.name in~ ("tclsh*", "osascript", "curl", "nscurl"))
    ) and not process.parent.code_signature.team_id in ("Q6L2SF6YDW", "2DC432GLL2", "W4NT6CRQ7U")
'''

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1105"
name = "Ingress Tool Transfer"
reference = "https://attack.mitre.org/techniques/T1105/"


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

[internal]
min_endpoint_version = "8.11.0"

Stages and Predicates

Stage 1: process

process where event.action == "exec" and 
 (process.parent.executable like~ "/Users/*/.vscode/extensions/*" or process.Ext.effective_parent.executable like~ "/Users/*/.vscode/extensions/*") and
    (
     (process.name in ("sh", "bash", "zsh") and
	     process.args == "-c" and process.args like~ ("*curl*", "*nscurl*", "*osascript*", "*zip*")) or
	  
     (process.name in~ ("tclsh*", "osascript", "curl", "nscurl"))
    ) and not process.parent.code_signature.team_id in ("Q6L2SF6YDW", "2DC432GLL2", "W4NT6CRQ7U")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • exec corpus 547 (elastic 547)
field:"EventType" kind:eq value:"exec"
process.Ext.effective_parent.executablewildcard
  • /Users/*/.vscode/extensions/*
field:"process.Ext.effective_parent.executable" kind:wildcard value:"/Users/*/.vscode/extensions/*"
process.argseq
  • -c corpus 91 (elastic 91)
field:"process.args" kind:eq value:"-c"
process.argswildcard
  • *curl* corpus 2 (elastic 2)
  • *nscurl* corpus 2 (elastic 2)
  • *osascript*
  • *zip*
field:"process.args" kind:wildcard
process.namein
  • bash corpus 181 (elastic 181)
  • curl corpus 10 (elastic 5, splunk 5)
  • nscurl
  • osascript corpus 2 (elastic 1, splunk 1)
  • sh corpus 180 (elastic 180)
  • tclsh*
  • zsh corpus 180 (elastic 180)
field:"process_basename" kind:in
process.parent.executablewildcard
  • /Users/*/.vscode/extensions/*
field:"ParentImage" kind:wildcard value:"/Users/*/.vscode/extensions/*"

Exclusions

The rule actively suppresses these predicates.

Timestomping Detected via Touch

#
Source
github.com/elastic/protections-artifacts

This rule detects the use of the touch command to modify file timestamps. Attackers may use timestomping to manipulate file timestamps to evade detection and alter the file's appearance. For example, attackers may change the file's creation, modification, and access times to hide malicious activities or make the file appear legitimate.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
This rule detects the use of the `touch` command to modify file timestamps. Attackers may use timestomping to manipulate
file timestamps to evade detection and alter the file's appearance. For example, attackers may change the file's
creation, modification, and access times to hide malicious activities or make the file appear legitimate.
"""
id = "8012a863-8c0c-4461-bb88-b0193dfb9f38"
license = "Elastic License v2"
name = "Timestomping Detected via Touch"
os_list = ["linux"]
version = "1.0.23"

query = '''
process where event.type == "start" and event.action == "exec" and process.name == "touch" and
process.parent.executable != null and process.args like (
  "-t*", "-d*", "-a*", "-m*", "-r*", "--date=*", "--reference=*", "--time=*"
) and process.args like (
  "/etc/*", "/bin/*", "/usr/bin/*", "/sbin/*", "/usr/sbin/*", "/opt/*", "/dev/shm/*",
  "/var/tmp/*", "/boot/*", "/root/*", "/usr/lib*", "/lib*"
) and not (
  process.parent.executable in (
    "/usr/local/bin/manage_omnimesh_logs", "/pro/bin/sys/install/packageUtils.sh", "/bin/dracut",
    "/usr/libexec/postfix/aliasesdb", "pwsh-preview", "/usr/bin/dracut", "/usr/share/initramfs-tools/hooks/amd64_microcode",
    "/usr/local/bin/start-mailserver.sh", "/usr/bin/ssm-agent-worker", "/bin/ssm-agent-worker", "/usr/local/cpanel/scripts/restartsrv_bind",
    "/usr/bin/vmtoolsd", "/usr/local/cpanel/bin/restartsrv_base", "/usr/lib/pcp/bin/pmie_check"
  ) or
  process.parent.executable like (
    "/opt/sw/tomcat/rc_scripts/*", "/tmp/newroot/var/lib/docker/overlay2/*", "/snap/*", "/opt/zeek/*", "/home/*/bin/ndex-rm.sh",
    "/root/.cache/act/*/staging_dir/host/bin/bash"
  ) or
  process.parent.name in (
    "xargs", "find", "sudo", "make", "pmlogger_check", "pmlogger_daily", "pmlogger_janitor", "autoupdate", "pmlogctl",
    "spyglass", "desktop-launch", "pmiectl"
  ) or
  process.parent.args like (
    "/home/*/scripts/auto_download_process.py", "/home/*/scripts/perl_python_eagu1p.py", "/var/lib/dpkg/info/*",
    "bazel-out/k8-dbg/bin/dependencies/thirdparty/libjansson_foreign_cc/build_script.sh", "/usr/lib/portage/python*/ebuild.sh",
    "/var/tmp/rpm-tmp.*", "/usr/lib/pcp/bin/pmlogger_janitor", "/usr/libexec/pcp/bin/pmlogger_janitor",
    "/usr/libexec/pcp/bin/pmlogger_daily", "/usr/lib/pcp/bin/pmlogger_daily", "/opt/oracle.ExaWatcher/GetExaWatcherResults.sh",
    "bazel-out/k8-dbg/bin/external/libzip+/libzip_foreign_cc/build_script.sh", "/builds/*/IP/embedded/platforms/stratawave-yocto/build/*/temp/run.sstate_unpack_package*",
    "/usr/local/bin/manage_omnimesh_logs"
  ) or
  process.args in (
    "/usr/bin/coreutils", "--no-create", "/etc/opt/lumu/lumud.conf", "/opt/vuso*", "/opt/diff", "/etc/aliases.db", "/opt/cursor/cursor"
  ) or
  process.args like (
    "--checkpoint=*", "/root/.config/envman/*", "/var/tmp/dracut*", "/var/tmp/portage*", "/snap/*", "/var/tmp/pmlogger_*/stamp",
    "/opt/ubki/*.jar", "/root/.cache/bazel/_bazel_root/*", "/root/.cache/act/*/hostexecutor/matrix/*/tmp/*.o",
    "/opt/ubki/*/cassandra-repair-dev-test/*"
  ) or
  process.command_line in (
    "/bin/touch -a /tmp/au_status", "touch -d 2 seconds ago /etc/postfix/main.cf", "touch -a /etc/apt/client.key /etc/apt/client.crt",
    "touch -r /etc/aliases.lmdb /var/lib/misc/postfix.aliasesdb-stamp"
  ) or
  process.parent.command_line == "runc init" or
  process.working_directory in ("/opt/libexec", "/opt/local/src/connectxx/build/src/mdp") or
  (process.args like "/var/tmp/pmlogger_check.*/_stamp" and process.parent.args == "/usr/libexec/pcp/bin/pmlogger_check") or
  (process.parent.executable == "/usr/bin/ninja" and process.parent.command_line like "ninja*") or
  (
    process.command_line like "touch -r /etc/horcNEW.conf /etc/horcm*.conf" and
    process.parent.command_line like "bash -c cat - > '/etc/horcm*.conf'; touch -r '/etc/horcNEW.conf' '/etc/horcm*.conf'"
  )
)
'''

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 = "T1070"
name = "Indicator Removal"
reference = "https://attack.mitre.org/techniques/T1070/"
[[threat.technique.subtechnique]]
id = "T1070.006"
name = "Timestomp"
reference = "https://attack.mitre.org/techniques/T1070/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 == "touch" and
process.parent.executable != null and process.args like (
  "-t*", "-d*", "-a*", "-m*", "-r*", "--date=*", "--reference=*", "--time=*"
) and process.args like (
  "/etc/*", "/bin/*", "/usr/bin/*", "/sbin/*", "/usr/sbin/*", "/opt/*", "/dev/shm/*",
  "/var/tmp/*", "/boot/*", "/root/*", "/usr/lib*", "/lib*"
) and not (
  process.parent.executable in (
    "/usr/local/bin/manage_omnimesh_logs", "/pro/bin/sys/install/packageUtils.sh", "/bin/dracut",
    "/usr/libexec/postfix/aliasesdb", "pwsh-preview", "/usr/bin/dracut", "/usr/share/initramfs-tools/hooks/amd64_microcode",
    "/usr/local/bin/start-mailserver.sh", "/usr/bin/ssm-agent-worker", "/bin/ssm-agent-worker", "/usr/local/cpanel/scripts/restartsrv_bind",
    "/usr/bin/vmtoolsd", "/usr/local/cpanel/bin/restartsrv_base", "/usr/lib/pcp/bin/pmie_check"
  ) or
  process.parent.executable like (
    "/opt/sw/tomcat/rc_scripts/*", "/tmp/newroot/var/lib/docker/overlay2/*", "/snap/*", "/opt/zeek/*", "/home/*/bin/ndex-rm.sh",
    "/root/.cache/act/*/staging_dir/host/bin/bash"
  ) or
  process.parent.name in (
    "xargs", "find", "sudo", "make", "pmlogger_check", "pmlogger_daily", "pmlogger_janitor", "autoupdate", "pmlogctl",
    "spyglass", "desktop-launch", "pmiectl"
  ) or
  process.parent.args like (
    "/home/*/scripts/auto_download_process.py", "/home/*/scripts/perl_python_eagu1p.py", "/var/lib/dpkg/info/*",
    "bazel-out/k8-dbg/bin/dependencies/thirdparty/libjansson_foreign_cc/build_script.sh", "/usr/lib/portage/python*/ebuild.sh",
    "/var/tmp/rpm-tmp.*", "/usr/lib/pcp/bin/pmlogger_janitor", "/usr/libexec/pcp/bin/pmlogger_janitor",
    "/usr/libexec/pcp/bin/pmlogger_daily", "/usr/lib/pcp/bin/pmlogger_daily", "/opt/oracle.ExaWatcher/GetExaWatcherResults.sh",
    "bazel-out/k8-dbg/bin/external/libzip+/libzip_foreign_cc/build_script.sh", "/builds/*/IP/embedded/platforms/stratawave-yocto/build/*/temp/run.sstate_unpack_package*",
    "/usr/local/bin/manage_omnimesh_logs"
  ) or
  process.args in (
    "/usr/bin/coreutils", "--no-create", "/etc/opt/lumu/lumud.conf", "/opt/vuso*", "/opt/diff", "/etc/aliases.db", "/opt/cursor/cursor"
  ) or
  process.args like (
    "--checkpoint=*", "/root/.config/envman/*", "/var/tmp/dracut*", "/var/tmp/portage*", "/snap/*", "/var/tmp/pmlogger_*/stamp",
    "/opt/ubki/*.jar", "/root/.cache/bazel/_bazel_root/*", "/root/.cache/act/*/hostexecutor/matrix/*/tmp/*.o",
    "/opt/ubki/*/cassandra-repair-dev-test/*"
  ) or
  process.command_line in (
    "/bin/touch -a /tmp/au_status", "touch -d 2 seconds ago /etc/postfix/main.cf", "touch -a /etc/apt/client.key /etc/apt/client.crt",
    "touch -r /etc/aliases.lmdb /var/lib/misc/postfix.aliasesdb-stamp"
  ) or
  process.parent.command_line == "runc init" or
  process.working_directory in ("/opt/libexec", "/opt/local/src/connectxx/build/src/mdp") or
  (process.args like "/var/tmp/pmlogger_check.*/_stamp" and process.parent.args == "/usr/libexec/pcp/bin/pmlogger_check") or
  (process.parent.executable == "/usr/bin/ninja" and process.parent.command_line like "ninja*") or
  (
    process.command_line like "touch -r /etc/horcNEW.conf /etc/horcm*.conf" and
    process.parent.command_line like "bash -c cat - > '/etc/horcm*.conf'; touch -r '/etc/horcNEW.conf' '/etc/horcm*.conf'"
  )
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • exec
field:"EventType" kind:eq value:"exec"
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
process.argswildcard
  • --date=*
  • --reference=*
  • --time=*
  • -a*
  • -d*
  • -m*
  • -r*
  • -t*
  • /bin/*
  • /boot/*
  • /dev/shm/*
  • /etc/*
  • /lib*
  • /opt/*
  • /root/*
  • /sbin/*
  • /usr/bin/*
  • /usr/lib*
  • /usr/sbin/*
  • /var/tmp/*
field:"process.args" kind:wildcard
process.nameeq
  • touch
field:"process_basename" kind:eq value:"touch"
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.argswildcard/var/tmp/pmlogger_check.*/_stampexcludes:process.args field:"process.args" value:"/var/tmp/pmlogger_check.*/_stamp"
process.parent.argseq/usr/libexec/pcp/bin/pmlogger_checkexcludes:process.parent.args field:"process.parent.args" value:"/usr/libexec/pcp/bin/pmlogger_check"
process.command_linewildcardtouch -r /etc/horcNEW.conf /etc/horcm*.confexcludes:process.command_line field:"process.command_line" value:"touch -r /etc/horcNEW.conf /etc/horcm*.conf"
process.parent.command_linewildcardbash -c cat - > '/etc/horcm*.conf'; touch -r '/etc/horcNEW.conf' '/etc/horcm*.conf'excludes:process.parent.command_line field:"process.parent.command_line" value:"bash -c cat - > '/etc/horcm*.conf'; touch -r '/etc/horcNEW.conf' '/etc/horcm*.conf'"
process.parent.command_linestarts_withninjaexcludes:process.parent.command_line field:"process.parent.command_line" value:"ninja"
process.parent.executableeq/usr/bin/ninjaexcludes:process.parent.executable field:"process.parent.executable" value:"/usr/bin/ninja"
process.argsin--no-create, /etc/aliases.db, /etc/opt/lumu/lumud.conf, /opt/cursor/cursor, /opt/diff, /opt/vuso*, /usr/bin/coreutilsexcludes:process.args
process.argswildcard--checkpoint=*, /root/.config/envman/*, /var/tmp/dracut*, /var/tmp/portage*, /snap/*, /var/tmp/pmlogger_*/stamp, /opt/ubki/*.jar, /root/.cache/bazel/_bazel_root/*, /root/.cache/act/*/hostexecutor/matrix/*/tmp/*.o, /opt/ubki/*/cassandra-repair-dev-test/*excludes:process.args
process.command_linein/bin/touch -a /tmp/au_status, touch -a /etc/apt/client.key /etc/apt/client.crt, touch -d 2 seconds ago /etc/postfix/main.cf, touch -r /etc/aliases.lmdb /var/lib/misc/postfix.aliasesdb-stampexcludes:process.command_line
process.parent.argswildcard/home/*/scripts/auto_download_process.py, /home/*/scripts/perl_python_eagu1p.py, /var/lib/dpkg/info/*, bazel-out/k8-dbg/bin/dependencies/thirdparty/libjansson_foreign_cc/build_script.sh, /usr/lib/portage/python*/ebuild.sh, /var/tmp/rpm-tmp.*, /usr/lib/pcp/bin/pmlogger_janitor, /usr/libexec/pcp/bin/pmlogger_janitor, /usr/libexec/pcp/bin/pmlogger_daily, /usr/lib/pcp/bin/pmlogger_daily, /opt/oracle.ExaWatcher/GetExaWatcherResults.sh, bazel-out/k8-dbg/bin/external/libzip+/libzip_foreign_cc/build_script.sh, /builds/*/IP/embedded/platforms/stratawave-yocto/build/*/temp/run.sstate_unpack_package*, /usr/local/bin/manage_omnimesh_logsexcludes:process.parent.args
process.parent.command_lineeqrunc initexcludes:process.parent.command_line field:"process.parent.command_line" value:"runc init"
process.parent.executablein/bin/dracut, /bin/ssm-agent-worker, /pro/bin/sys/install/packageUtils.sh, /usr/bin/dracut, /usr/bin/ssm-agent-worker, /usr/bin/vmtoolsd, /usr/lib/pcp/bin/pmie_check, /usr/libexec/postfix/aliasesdb, /usr/local/bin/manage_omnimesh_logs, /usr/local/bin/start-mailserver.sh, /usr/local/cpanel/bin/restartsrv_base, /usr/local/cpanel/scripts/restartsrv_bind, /usr/share/initramfs-tools/hooks/amd64_microcode, pwsh-previewexcludes:process.parent.executable
process.parent.executablewildcard/opt/sw/tomcat/rc_scripts/*, /tmp/newroot/var/lib/docker/overlay2/*, /snap/*, /opt/zeek/*, /home/*/bin/ndex-rm.sh, /root/.cache/act/*/staging_dir/host/bin/bashexcludes:process.parent.executable
process.parent.nameinautoupdate, desktop-launch, find, make, pmiectl, pmlogctl, pmlogger_check, pmlogger_daily, pmlogger_janitor, spyglass, sudo, xargsexcludes:process.parent.name
process.working_directoryin/opt/libexec, /opt/local/src/connectxx/build/src/mdpexcludes:process.working_directory field:"process.working_directory" value:"/opt/libexec" field:"process.working_directory" value:"/opt/local/src/connectxx/build/src/mdp"

Unusual Service Host Child Process - Childless Service

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

Identifies unusual child processes of Service Host (svchost.exe) that traditionally do not spawn any child processes. This may indicate a code injection or an equivalent form of exploitation.

Known False Positives

  • Changes to Windows services or a rarely executed child process.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2020/10/13"
integration = ["endpoint", "windows", "m365_defender", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2026/05/04"

[rule]
author = ["Elastic"]
description = """
Identifies unusual child processes of Service Host (svchost.exe) that traditionally do not spawn any child processes.
This may indicate a code injection or an equivalent form of exploitation.
"""
false_positives = ["Changes to Windows services or a rarely executed child process."]
from = "now-9m"
index = [
    "logs-endpoint.events.process-*",
    "winlogbeat-*",
    "logs-windows.sysmon_operational-*",
    "endgame-*",
    "logs-m365_defender.event-*",
    "logs-sentinel_one_cloud_funnel.*",
]
language = "eql"
license = "Elastic License v2"
name = "Unusual Service Host Child Process - Childless 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 Service Host Child Process - Childless Service

Service Host (svchost.exe) is a critical Windows process that hosts multiple services to optimize resource usage. Typically, certain services under svchost.exe do not spawn child processes. Adversaries exploit this by injecting malicious code to execute unauthorized processes, evading detection. The detection rule identifies anomalies by monitoring child processes of traditionally childless services, flagging potential exploitation attempts.

### Possible investigation steps

- Review the process details of the child process, including its name and executable path, to determine if it is a known legitimate process or potentially malicious.
- Examine the parent process arguments to confirm if the svchost.exe instance is associated with a service that traditionally does not spawn child processes, as listed in the query.
- Check the process creation time and correlate it with any other suspicious activities or alerts in the system around the same timeframe.
- Investigate the user account under which the child process was executed to assess if it has the necessary privileges and if the activity aligns with typical user behavior.
- Analyze any network connections or file modifications made by the child process to identify potential malicious actions or data exfiltration attempts.
- Cross-reference the child process with known false positives listed in the query to rule out benign activities.
- Utilize threat intelligence sources to determine if the child process or its executable path is associated with known malware or attack patterns.

### False positive analysis

- Processes like WerFault.exe, WerFaultSecure.exe, and wermgr.exe are known to be legitimate Windows error reporting tools that may occasionally be spawned by svchost.exe. To handle these, add them to the exclusion list in the detection rule to prevent unnecessary alerts.
- RelPost.exe associated with WdiSystemHost can be a legitimate process in certain environments. If this is a common occurrence, consider adding an exception for this executable when it is spawned by WdiSystemHost.
- Rundll32.exe executing winethc.dll with ForceProxyDetectionOnNextRun arguments under WdiServiceHost may be a benign operation in some network configurations. If verified as non-malicious, exclude this specific process and argument combination.
- Processes under the imgsvc service, such as lexexe.exe from Kodak directories, might be legitimate in environments using specific imaging software. Validate these occurrences and exclude them if they are confirmed to be non-threatening.
- Regularly review and update the exclusion list to ensure it reflects the current environment and does not inadvertently allow malicious activity.

### Response and remediation

- Immediately isolate the affected system from the network to prevent further spread or communication with potential command and control servers.
- Terminate any suspicious child processes spawned by svchost.exe that are not typically associated with legitimate operations, as identified in the alert.
- Conduct a thorough scan of the affected system using updated antivirus and anti-malware tools to identify and remove any injected malicious code or associated malware.
- Review and analyze the process tree and parent-child relationships to understand the scope of the compromise and identify any additional affected processes or systems.
- Restore the affected system from a known good backup if malicious activity is confirmed and cannot be fully remediated through cleaning.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if additional systems are compromised.
- Implement enhanced monitoring and logging for svchost.exe and related processes to detect similar anomalies in the future, ensuring that alerts are configured to notify the appropriate personnel promptly."""
risk_score = 47
rule_id = "6a8ab9cc-4023-4d17-b5df-1a3e16882ce7"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Defense Evasion",
    "Tactic: Privilege Escalation",
    "Data Source: Elastic Endgame",
    "Data Source: Elastic Defend",
    "Data Source: Sysmon",
    "Data Source: Microsoft Defender XDR",
    "Data Source: SentinelOne",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
process where host.os.type == "windows" and event.type == "start" and
  process.parent.name : "svchost.exe" and

  /* based on svchost service arguments -s svcname where the service is known to be childless */
  process.parent.args : (
    "WdiSystemHost", "LicenseManager", "StorSvc", "CDPSvc", "cdbhsvc", "BthAvctpSvc", "SstpSvc", "WdiServiceHost",
    "imgsvc", "TrkWks", "WpnService", "IKEEXT", "PolicyAgent", "CryptSvc", "netprofm", "ProfSvc", "StateRepository",
    "camsvc", "LanmanWorkstation", "NlaSvc", "EventLog", "hidserv", "DisplayEnhancementService", "ShellHWDetection",
    "AppHostSvc", "fhsvc", "CscService", "PushToInstall"
  ) and

  /* unknown FPs can be added here */
  not process.name : ("WerFault.exe", "WerFaultSecure.exe", "wermgr.exe") and
  not (process.executable : "?:\\Windows\\System32\\RelPost.exe" and process.parent.args : "WdiSystemHost") and
  not (
    process.name : "rundll32.exe" and
    process.args : "?:\\WINDOWS\\System32\\winethc.dll,ForceProxyDetectionOnNextRun" and
    process.parent.args : "WdiServiceHost"
  ) and
  not (
    process.executable : (
      "?:\\Program Files\\*",
      "?:\\Program Files (x86)\\*",
      "?:\\Windows\\System32\\Kodak\\kds_?????\\lib\\lexexe.exe"
    ) and process.parent.args : "imgsvc"
  )
'''

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:

- [Microsoft Defender XDR](https://ela.st/m365-defender)
- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
- [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
"""


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



[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 = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"
[[rule.threat.technique.subtechnique]]
id = "T1055.012"
name = "Process Hollowing"
reference = "https://attack.mitre.org/techniques/T1055/012/"



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

Stages and Predicates

Stage 1: process

process where host.os.type == "windows" and event.type == "start" and
  process.parent.name : "svchost.exe" and
  process.parent.args : (
    "WdiSystemHost", "LicenseManager", "StorSvc", "CDPSvc", "cdbhsvc", "BthAvctpSvc", "SstpSvc", "WdiServiceHost",
    "imgsvc", "TrkWks", "WpnService", "IKEEXT", "PolicyAgent", "CryptSvc", "netprofm", "ProfSvc", "StateRepository",
    "camsvc", "LanmanWorkstation", "NlaSvc", "EventLog", "hidserv", "DisplayEnhancementService", "ShellHWDetection",
    "AppHostSvc", "fhsvc", "CscService", "PushToInstall"
  ) and
  not process.name : ("WerFault.exe", "WerFaultSecure.exe", "wermgr.exe") and
  not (process.executable : "?:\\Windows\\System32\\RelPost.exe" and process.parent.args : "WdiSystemHost") and
  not (
    process.name : "rundll32.exe" and
    process.args : "?:\\WINDOWS\\System32\\winethc.dll,ForceProxyDetectionOnNextRun" and
    process.parent.args : "WdiServiceHost"
  ) and
  not (
    process.executable : (
      "?:\\Program Files\\*",
      "?:\\Program Files (x86)\\*",
      "?:\\Windows\\System32\\Kodak\\kds_?????\\lib\\lexexe.exe"
    ) and process.parent.args : "imgsvc"
  )

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.parent.argswildcard
  • AppHostSvc
  • BthAvctpSvc
  • CDPSvc
  • CryptSvc
  • CscService
  • DisplayEnhancementService
  • EventLog
  • IKEEXT
  • LanmanWorkstation
  • LicenseManager
  • NlaSvc
  • PolicyAgent
  • ProfSvc
  • PushToInstall
  • ShellHWDetection
  • SstpSvc
  • StateRepository
  • StorSvc
  • TrkWks
  • WdiServiceHost
  • WdiSystemHost
  • WpnService
  • camsvc
  • cdbhsvc
  • fhsvc
  • hidserv
  • imgsvc
  • netprofm
field:"process.parent.args" kind:wildcard
process.parent.namewildcard
  • svchost.exe corpus 15 (elastic 10, splunk 5)
field:"parent_process_basename" kind:wildcard value:"svchost.exe"

Exclusions

The rule actively suppresses these predicates.

Yum/DNF Plugin Status Discovery

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

This rule detects the execution of the grep command with the plugins argument on Linux systems. This command is used to search for YUM/DNF configurations and/or plugins with an enabled state. This behavior may indicate an attacker is attempting to establish persistence in a YUM or DNF plugin.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2024/06/25"
integration = ["endpoint", "crowdstrike", "sentinel_one_cloud_funnel", "auditd_manager"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
This rule detects the execution of the `grep` command with the `plugins` argument on Linux systems. This command is used
to search for YUM/DNF configurations and/or plugins with an enabled state. This behavior may indicate an attacker is
attempting to establish persistence in a YUM or DNF plugin.
"""
from = "now-9m"
index = [
    "auditbeat-*",
    "endgame-*",
    "logs-crowdstrike.fdr*",
    "logs-endpoint.events.process*",
    "logs-sentinel_one_cloud_funnel.*",
    "logs-auditd_manager.auditd-*",
]
language = "eql"
license = "Elastic License v2"
name = "Yum/DNF Plugin Status Discovery"
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 Yum/DNF Plugin Status Discovery

Yum and DNF are package managers for Linux, managing software installations and updates. They support plugins to extend functionality, which can be targeted by attackers to maintain persistence. Adversaries may use commands to identify active plugins, potentially altering them for malicious purposes. The detection rule identifies suspicious use of the `grep` command to search for plugin configurations, signaling possible reconnaissance or tampering attempts.

### Possible investigation steps

- Review the process execution details to confirm the presence of the `grep` command with arguments related to plugin configurations, such as `/etc/yum.conf` or `/etc/dnf/dnf.conf`, to verify the alert's accuracy.
- Examine the user account associated with the process execution to determine if it is a legitimate user or potentially compromised account.
- Check the system's command history for any preceding or subsequent commands executed by the same user to identify potential patterns or further suspicious activity.
- Investigate any recent changes to the plugin configuration files located in directories like `/etc/yum/pluginconf.d/` or `/etc/dnf/plugins/` to detect unauthorized modifications.
- Correlate the alert with other security events or logs from the same host to identify any additional indicators of compromise or related malicious activity.

### False positive analysis

- System administrators or automated scripts may use the grep command to verify plugin configurations during routine maintenance. To handle this, create exceptions for known administrative scripts or user accounts that regularly perform these checks.
- Security audits or compliance checks might involve scanning for plugin configurations to ensure they are correctly set up. Exclude these activities by identifying and whitelisting the specific processes or tools used for such audits.
- Developers or IT staff might search for plugin configurations while troubleshooting or developing new features. Consider excluding processes initiated by trusted development environments or specific user groups involved in these activities.
- Monitoring tools that perform regular checks on system configurations could trigger this rule. Identify these tools and add them to an exclusion list to prevent false alerts.

### Response and remediation

- Immediately isolate the affected system from the network to prevent potential lateral movement by the attacker.
- Terminate any suspicious processes related to the `grep` command that are actively searching for YUM/DNF plugin configurations.
- Conduct a thorough review of the YUM and DNF plugin configuration files and directories for unauthorized changes or additions, specifically in the paths `/etc/yum.conf`, `/usr/lib/yum-plugins/*`, `/etc/yum/pluginconf.d/*`, `/usr/lib/python*/site-packages/dnf-plugins/*`, `/etc/dnf/plugins/*`, and `/etc/dnf/dnf.conf`.
- Restore any altered plugin configurations from a known good backup to ensure system integrity.
- Implement file integrity monitoring on the YUM and DNF configuration directories to detect future unauthorized changes.
- Escalate the incident to the security operations team for further investigation and to determine if additional systems have been compromised.
- Review and update access controls and permissions for users and processes interacting with YUM and DNF configurations to minimize the risk of unauthorized access."""
references = [
    "https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/linux/local/yum_package_manager_persistence.rb",
    "https://pwnshift.github.io/2020/10/01/persistence.html",
    "https://www.elastic.co/security-labs/sequel-on-persistence-mechanisms",
]
risk_score = 21
rule_id = "78390eb5-c838-4c1d-8240-69dd7397cfb7"
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 = "low"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Discovery",
    "Data Source: Auditd Manager",
    "Data Source: Elastic Defend",
    "Data Source: Elastic Endgame",
    "Data Source: Crowdstrike",
    "Data Source: SentinelOne",
    "Resources: Investigation Guide",
]
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 == "grep" and process.args : "plugins*" and process.args like (
  "/etc/yum.conf", "/usr/lib/yum-plugins/*", "/etc/yum/pluginconf.d/*",
  "/usr/lib/python*/site-packages/dnf-plugins/*", "/etc/dnf/plugins/*", "/etc/dnf/dnf.conf"
) and
not ?process.parent.executable == "/usr/lib/venv-salt-minion/bin/python.original"
'''

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

[[rule.threat.technique]]
id = "T1082"
name = "System Information Discovery"
reference = "https://attack.mitre.org/techniques/T1082/"

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

[[rule.threat.technique]]
id = "T1518"
name = "Software Discovery"
reference = "https://attack.mitre.org/techniques/T1518/"

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

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 == "grep" and process.args : "plugins*" and process.args like (
  "/etc/yum.conf", "/usr/lib/yum-plugins/*", "/etc/yum/pluginconf.d/*",
  "/usr/lib/python*/site-packages/dnf-plugins/*", "/etc/dnf/plugins/*", "/etc/dnf/dnf.conf"
) and
not ?process.parent.executable == "/usr/lib/venv-salt-minion/bin/python.original"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actionin
  • ProcessRollup2
  • exec
  • exec_event
  • executed
  • process_started
  • start
field:"EventType" kind:in
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
process.argswildcard
  • /etc/dnf/dnf.conf
  • /etc/dnf/plugins/*
  • /etc/yum.conf
  • /etc/yum/pluginconf.d/*
  • /usr/lib/python*/site-packages/dnf-plugins/*
  • /usr/lib/yum-plugins/*
  • plugins*
field:"process.args" kind:wildcard
process.nameeq
  • grep
field:"process_basename" kind:eq value:"grep"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.parent.executableeq/usr/lib/venv-salt-minion/bin/python.originalexcludes:process.parent.executable field:"process.parent.executable" value:"/usr/lib/venv-salt-minion/bin/python.original"

Back to all Elastic rules