Detection rules › Elastic
Elastic rules: 0i
AWS Access Token Used from Multiple Addresses
#This rule identifies potentially suspicious activity by detecting instances where a single IAM user's temporary session token is accessed from multiple IP addresses within a short time frame. Such behavior may suggest that an adversary has compromised temporary credentials and is utilizing them from various locations. To enhance detection accuracy and minimize false positives, the rule incorporates criteria that evaluate unique IP addresses, user agents, cities, and networks. These additional checks help distinguish between legitimate distributed access patterns and potential credential misuse. Detected activities are classified into different types based on the combination of unique indicators, with each classification assigned a fidelity score reflecting the likelihood of malicious behavior. High fidelity scores are given to patterns most indicative of threats, such as multiple unique IPs, networks, cities, and user agents. Medium and low fidelity scores correspond to less severe patterns, enabling security teams to effectively prioritize alerts.
Known False Positives
- Highly distributed environments (e.g., globally deployed automation or edge nodes) may cause a single IAM user to appear from multiple IPs. Review the geolocation, network context, and user agent patterns to rule out benign use. This rule automatically excludes console login sessions, reducing false positives from legitimate console-based access across VPN or network changes.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Stealth |
Rule Body
[metadata]
creation_date = "2025/04/11"
integration = ["aws"]
maturity = "production"
min_stack_version = "9.3.0"
min_stack_comments = "Changing min stack to 9.3.0, the latest minimum supported version for 9.X releases."
updated_date = "2026/07/20"
[rule]
author = ["Elastic"]
description = """
This rule identifies potentially suspicious activity by detecting instances where a single IAM user's temporary session
token is accessed from multiple IP addresses within a short time frame. Such behavior may suggest that an adversary has
compromised temporary credentials and is utilizing them from various locations. To enhance detection accuracy and
minimize false positives, the rule incorporates criteria that evaluate unique IP addresses, user agents, cities, and
networks. These additional checks help distinguish between legitimate distributed access patterns and potential
credential misuse. Detected activities are classified into different types based on the combination of unique
indicators, with each classification assigned a fidelity score reflecting the likelihood of malicious behavior. High
fidelity scores are given to patterns most indicative of threats, such as multiple unique IPs, networks, cities, and
user agents. Medium and low fidelity scores correspond to less severe patterns, enabling security teams to effectively
prioritize alerts.
"""
false_positives = [
"""
Highly distributed environments (e.g., globally deployed automation or edge nodes) may cause a single IAM user to
appear from multiple IPs. Review the geolocation, network context, and user agent patterns to rule out benign use.
This rule automatically excludes console login sessions, reducing false positives from legitimate console-based access across VPN or network changes.
""",
]
from = "now-32m"
interval = "15m"
language = "esql"
license = "Elastic License v2"
name = "AWS Access Token Used from Multiple Addresses"
note = """## Triage and analysis
### Investigating AWS Access Token Used from Multiple Addresses
Access tokens are bound to a single user. Usage from multiple IP addresses may indicate the token was stolen and used elsewhere. By correlating this with additional detection criteria like multiple user agents, different cities, and different networks, we can improve the fidelity of the rule and help to eliminate false positives associated with expected behavior, like dual-stack IPV4/IPV6 usage.
### Possible investigation steps
- **Identify the IAM User**: Examine the `aws.cloudtrail.user_identity.arn` stored in `user_id` and correlate with the `source.ips` stored in `ip_list` and `unique_ips` count to determine how widely the token was used.
- **Correlate Additional Detection Context**: Examine `activity_type` and `fidelity_score` to determine additional cities, networks or user agents associated with the token usage.
- **Determine Access Key Type**: Examine the `access_key_id` to determine whether the token is short-term (beginning with ASIA) or long-term (beginning with AKIA).
- **Check Recent MFA Events**: Determine whether the user recently enabled MFA, registered devices, or assumed a role using this token.
- **Review Workload Context**: Confirm whether the user was expected to be active across multiple cities, networks or user agent environments.
- **Trace Adversary Movement**: Pivot to related actions (e.g., `s3:ListBuckets`, `iam:ListUsers`, `sts:GetCallerIdentity`) to track further enumeration.
### False positive analysis
- Automation frameworks that rotate through multiple IPs or cloud functions with dynamic egress IPs may cause this alert to fire.
- Confirm geolocation and workload context before escalating.
### Response and remediation
- **Revoke the Token**: Disable or rotate the IAM credentials and invalidate the temporary session token.
- **Audit the Environment**: Look for signs of lateral movement or data access during the token's validity.
- **Strengthen Controls**: Require MFA for high-privilege actions, restrict access via policy conditions (e.g., IP range or device).
### Additional information
- [IAM Long-Term Credentials](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html)
- [STS Temporary Credentials](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html)
- [Using MFA with Temporary Credentials](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
- [AWS Threat Detection Use Cases](https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-standards-fsbp-controls.html)
"""
references = ["https://www.sygnia.co/blog/sygnia-investigation-bybit-hack/"]
risk_score = 47
rule_id = "0d92d30a-5f3e-4b71-bc3d-4a0c4914b7e0"
severity = "medium"
tags = [
"Domain: Cloud",
"Data Source: AWS",
"Data Source: Amazon Web Services",
"Data Source: AWS IAM",
"Data Source: AWS CloudTrail",
"Tactic: Initial Access",
"Use Case: Identity and Access Audit",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-aws.cloudtrail* metadata _id, _version, _index
| where data_stream.dataset == "aws.cloudtrail"
and aws.cloudtrail.user_identity.arn is not null
and aws.cloudtrail.user_identity.type == "IAMUser"
and source.ip is not null
and aws.cloudtrail.user_identity.access_key_id is not null
and not aws.cloudtrail.session_credential_from_console == "true"
and not (
user_agent.original like "*Terraform*" or
user_agent.original like "*Ansible*" or
user_agent.original like "*Pulumi*"
)
and `source.as.organization.name` != "AMAZON-AES"
and not ((
`source.as.organization.name` == "AMAZON-02" and aws.cloudtrail.event_category == "Data"))
and event.provider not in (
"health.amazonaws.com", "monitoring.amazonaws.com", "notifications.amazonaws.com",
"ce.amazonaws.com", "cost-optimization-hub.amazonaws.com",
"servicecatalog-appregistry.amazonaws.com", "securityhub.amazonaws.com",
"account.amazonaws.com", "budgets.amazonaws.com", "freetier.amazonaws.com", "support.amazonaws.com",
"support-console.amazonaws.com"
)
| eval
Esql.time_window_date_trunc = date_trunc(30 minutes, @timestamp),
Esql.aws_cloudtrail_user_identity_arn = aws.cloudtrail.user_identity.arn,
Esql.aws_cloudtrail_user_identity_access_key_id = aws.cloudtrail.user_identity.access_key_id,
Esql.source_ip = source.ip,
Esql.user_agent_original = user_agent.original,
Esql.source_ip_string = to_string(source.ip),
Esql.source_ip_user_agent_pair = concat(Esql.source_ip_string, " - ", user_agent.original),
Esql.source_ip_city_pair = concat(Esql.source_ip_string, " - ", source.geo.city_name),
Esql.source_geo_city_name = source.geo.city_name,
Esql.source_network_org_name = `source.as.organization.name`,
Esql.source_ip_network_pair = concat(Esql.source_ip_string, "-", `source.as.organization.name`),
Esql.event_timestamp = @timestamp,
Esql.data_stream_namespace = data_stream.namespace
| stats
Esql.event_action_values = values(event.action),
Esql.event_provider_count_distinct = count_distinct(event.provider),
Esql.event_provider_values = values(event.provider),
Esql.aws_cloudtrail_user_identity_access_key_id_values = values(Esql.aws_cloudtrail_user_identity_access_key_id),
Esql.aws_cloudtrail_user_identity_arn_values = values(Esql.aws_cloudtrail_user_identity_arn),
Esql.source_ip_values = values(Esql.source_ip),
Esql.user_agent_original_values = values(Esql.user_agent_original),
Esql.source_ip_user_agent_pair_values = values(Esql.source_ip_user_agent_pair),
Esql.source_geo_city_name_values = values(Esql.source_geo_city_name),
Esql.source_ip_city_pair_values = values(Esql.source_ip_city_pair),
Esql.source_network_org_name_values = values(Esql.source_network_org_name),
Esql.source_ip_network_pair_values = values(Esql.source_ip_network_pair),
Esql.source_ip_count_distinct = count_distinct(Esql.source_ip),
Esql.user_agent_original_count_distinct = count_distinct(Esql.user_agent_original),
Esql.source_geo_city_name_count_distinct = count_distinct(Esql.source_geo_city_name),
Esql.source_network_org_name_count_distinct = count_distinct(Esql.source_network_org_name),
Esql.data_stream_namespace_values = values(Esql.data_stream_namespace),
Esql.timestamp_first_seen = min(Esql.event_timestamp),
Esql.timestamp_last_seen = max(Esql.event_timestamp),
Esql.event_count = count()
by Esql.time_window_date_trunc, Esql.aws_cloudtrail_user_identity_access_key_id
| eval
Esql.activity_type = case(
Esql.source_ip_count_distinct >= 2 and Esql.source_network_org_name_count_distinct >= 2 and Esql.source_geo_city_name_count_distinct >= 2 and Esql.user_agent_original_count_distinct >= 2, "multiple_ip_network_city_user_agent",
Esql.source_ip_count_distinct >= 2 and Esql.source_network_org_name_count_distinct >= 2 and Esql.source_geo_city_name_count_distinct >= 2, "multiple_ip_network_city",
Esql.source_ip_count_distinct >= 2 and Esql.source_geo_city_name_count_distinct >= 2, "multiple_ip_and_city",
Esql.source_ip_count_distinct >= 2 and Esql.source_network_org_name_count_distinct >= 2, "multiple_ip_and_network",
Esql.source_ip_count_distinct >= 2 and Esql.user_agent_original_count_distinct >= 2, "multiple_ip_and_user_agent",
"normal_activity"
),
Esql.activity_fidelity_score = case(
Esql.activity_type == "multiple_ip_network_city_user_agent", "high",
Esql.activity_type == "multiple_ip_network_city", "high",
Esql.activity_type == "multiple_ip_and_city", "medium",
Esql.activity_type == "multiple_ip_and_network", "medium",
Esql.activity_type == "multiple_ip_and_user_agent", "low"
)
| keep
Esql.time_window_date_trunc,
Esql.activity_type,
Esql.activity_fidelity_score,
Esql.event_count,
Esql.timestamp_first_seen,
Esql.timestamp_last_seen,
Esql.aws_cloudtrail_user_identity_arn_values,
Esql.aws_cloudtrail_user_identity_access_key_id_values,
Esql.event_provider_count_distinct,
Esql.event_action_values,
Esql.event_provider_values,
Esql.source_ip_values,
Esql.user_agent_original_values,
Esql.source_ip_user_agent_pair_values,
Esql.source_geo_city_name_values,
Esql.source_ip_city_pair_values,
Esql.source_network_org_name_values,
Esql.source_ip_network_pair_values,
Esql.source_ip_count_distinct,
Esql.user_agent_original_count_distinct,
Esql.source_geo_city_name_count_distinct,
Esql.source_network_org_name_count_distinct,
Esql.data_stream_namespace_values
| where Esql.activity_fidelity_score == "high" and Esql.event_provider_count_distinct > 1
// this rule only alerts for "high" fidelity cases, to broaden the rule scope to include all activity
// change the final condition to
// | where Esql.activity_type != "normal_activity" and Esql.event_provider_count_distinct > 1
'''
[rule.investigation_fields]
field_names = [
"Esql.timestamp_first_seen",
"Esql.timestamp_last_seen",
"Esql.activity_type",
"Esql.activity_fidelity_score",
"Esql.event_count",
"Esql.aws_cloudtrail_user_identity_arn_values",
"Esql.aws_cloudtrail_user_identity_access_key_id_values",
"Esql.event_action_values",
"Esql.event_provider_values",
"Esql.source_ip_values",
"Esql.user_agent_original_values",
"Esql.source_ip_user_agent_pair_values",
"Esql.source_geo_city_name_values",
"Esql.source_ip_city_pair_values",
"Esql.source_network_org_name_values",
"Esql.source_ip_network_pair_values",
"Esql.source_ip_count_distinct",
"Esql.user_agent_original_count_distinct",
"Esql.source_geo_city_name_count_distinct",
"Esql.source_network_org_name_count_distinct",
"Esql.data_stream_namespace_values"
]
[[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 = "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 = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Stage 1: from
from logs-aws.cloudtrail* metadata _id, _version, _index
Stage 2: where
| where data_stream.dataset == "aws.cloudtrail"
and aws.cloudtrail.user_identity.arn is not null
and aws.cloudtrail.user_identity.type == "IAMUser"
and source.ip is not null
and aws.cloudtrail.user_identity.access_key_id is not null
and not aws.cloudtrail.session_credential_from_console == "true"
and not (
user_agent.original like "*Terraform*" or
user_agent.original like "*Ansible*" or
user_agent.original like "*Pulumi*"
)
and `source.as.organization.name` != "AMAZON-AES"
and not ((
`source.as.organization.name` == "AMAZON-02" and aws.cloudtrail.event_category == "Data"))
and event.provider not in (
"health.amazonaws.com", "monitoring.amazonaws.com", "notifications.amazonaws.com",
"ce.amazonaws.com", "cost-optimization-hub.amazonaws.com",
"servicecatalog-appregistry.amazonaws.com", "securityhub.amazonaws.com",
"account.amazonaws.com", "budgets.amazonaws.com", "freetier.amazonaws.com", "support.amazonaws.com",
"support-console.amazonaws.com"
)
Stage 3: eval
| eval
Esql.time_window_date_trunc = date_trunc(30 minutes, @timestamp),
Esql.aws_cloudtrail_user_identity_arn = aws.cloudtrail.user_identity.arn,
Esql.aws_cloudtrail_user_identity_access_key_id = aws.cloudtrail.user_identity.access_key_id,
Esql.source_ip = source.ip,
Esql.user_agent_original = user_agent.original,
Esql.source_ip_string = to_string(source.ip),
Esql.source_ip_user_agent_pair = concat(Esql.source_ip_string, " - ", user_agent.original),
Esql.source_ip_city_pair = concat(Esql.source_ip_string, " - ", source.geo.city_name),
Esql.source_geo_city_name = source.geo.city_name,
Esql.source_network_org_name = `source.as.organization.name`,
Esql.source_ip_network_pair = concat(Esql.source_ip_string, "-", `source.as.organization.name`),
Esql.event_timestamp = @timestamp,
Esql.data_stream_namespace = data_stream.namespace
Stage 4: stats
| stats
Esql.event_action_values = values(event.action),
Esql.event_provider_count_distinct = count_distinct(event.provider),
Esql.event_provider_values = values(event.provider),
Esql.aws_cloudtrail_user_identity_access_key_id_values = values(Esql.aws_cloudtrail_user_identity_access_key_id),
Esql.aws_cloudtrail_user_identity_arn_values = values(Esql.aws_cloudtrail_user_identity_arn),
Esql.source_ip_values = values(Esql.source_ip),
Esql.user_agent_original_values = values(Esql.user_agent_original),
Esql.source_ip_user_agent_pair_values = values(Esql.source_ip_user_agent_pair),
Esql.source_geo_city_name_values = values(Esql.source_geo_city_name),
Esql.source_ip_city_pair_values = values(Esql.source_ip_city_pair),
Esql.source_network_org_name_values = values(Esql.source_network_org_name),
Esql.source_ip_network_pair_values = values(Esql.source_ip_network_pair),
Esql.source_ip_count_distinct = count_distinct(Esql.source_ip),
Esql.user_agent_original_count_distinct = count_distinct(Esql.user_agent_original),
Esql.source_geo_city_name_count_distinct = count_distinct(Esql.source_geo_city_name),
Esql.source_network_org_name_count_distinct = count_distinct(Esql.source_network_org_name),
Esql.data_stream_namespace_values = values(Esql.data_stream_namespace),
Esql.timestamp_first_seen = min(Esql.event_timestamp),
Esql.timestamp_last_seen = max(Esql.event_timestamp),
Esql.event_count = count()
by Esql.time_window_date_trunc, Esql.aws_cloudtrail_user_identity_access_key_id
Stage 5: eval
| eval
Esql.activity_type = case(
Esql.source_ip_count_distinct >= 2 and Esql.source_network_org_name_count_distinct >= 2 and Esql.source_geo_city_name_count_distinct >= 2 and Esql.user_agent_original_count_distinct >= 2, "multiple_ip_network_city_user_agent",
Esql.source_ip_count_distinct >= 2 and Esql.source_network_org_name_count_distinct >= 2 and Esql.source_geo_city_name_count_distinct >= 2, "multiple_ip_network_city",
Esql.source_ip_count_distinct >= 2 and Esql.source_geo_city_name_count_distinct >= 2, "multiple_ip_and_city",
Esql.source_ip_count_distinct >= 2 and Esql.source_network_org_name_count_distinct >= 2, "multiple_ip_and_network",
Esql.source_ip_count_distinct >= 2 and Esql.user_agent_original_count_distinct >= 2, "multiple_ip_and_user_agent",
"normal_activity"
),
Esql.activity_fidelity_score = case(
Esql.activity_type == "multiple_ip_network_city_user_agent", "high",
Esql.activity_type == "multiple_ip_network_city", "high",
Esql.activity_type == "multiple_ip_and_city", "medium",
Esql.activity_type == "multiple_ip_and_network", "medium",
Esql.activity_type == "multiple_ip_and_user_agent", "low"
)
Esql.activity_fidelity_score =Esql.activity_type == "multiple_ip_network_city_user_agent""high"Esql.activity_type == "multiple_ip_network_city""high"Esql.activity_type == "multiple_ip_and_city""medium"Esql.activity_type == "multiple_ip_and_network""medium""low"Esql.activity_type =Esql.source_ip_count_distinct >= 2 and Esql.source_network_org_name_count_distinct >= 2 and Esql.source_geo_city_name_count_distinct >= 2 and Esql.user_agent_original_count_distinct >= 2"multiple_ip_network_city_user_agent"Esql.source_ip_count_distinct >= 2 and Esql.source_network_org_name_count_distinct >= 2 and Esql.source_geo_city_name_count_distinct >= 2"multiple_ip_network_city"Esql.source_ip_count_distinct >= 2 and Esql.source_geo_city_name_count_distinct >= 2"multiple_ip_and_city"Esql.source_ip_count_distinct >= 2 and Esql.source_network_org_name_count_distinct >= 2"multiple_ip_and_network"Esql.source_ip_count_distinct >= 2 and Esql.user_agent_original_count_distinct >= 2"multiple_ip_and_user_agent""normal_activity"Stage 6: keep
| keep
Esql.time_window_date_trunc,
Esql.activity_type,
Esql.activity_fidelity_score,
Esql.event_count,
Esql.timestamp_first_seen,
Esql.timestamp_last_seen,
Esql.aws_cloudtrail_user_identity_arn_values,
Esql.aws_cloudtrail_user_identity_access_key_id_values,
Esql.event_provider_count_distinct,
Esql.event_action_values,
Esql.event_provider_values,
Esql.source_ip_values,
Esql.user_agent_original_values,
Esql.source_ip_user_agent_pair_values,
Esql.source_geo_city_name_values,
Esql.source_ip_city_pair_values,
Esql.source_network_org_name_values,
Esql.source_ip_network_pair_values,
Esql.source_ip_count_distinct,
Esql.user_agent_original_count_distinct,
Esql.source_geo_city_name_count_distinct,
Esql.source_network_org_name_count_distinct,
Esql.data_stream_namespace_values
Stage 7: where
| where Esql.activity_fidelity_score == "high" and Esql.event_provider_count_distinct > 1
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
aws.cloudtrail.event_category | eq | Data | excludes:aws.cloudtrail.event_category field:"aws.cloudtrail.event_category" value:"Data" |
source.as.organization.name | eq | AMAZON-02 | excludes:source.as.organization.name field:"source.as.organization.name" value:"AMAZON-02" |
user_agent.original | match | Ansible | excludes:user_agent.original field:"user_agent.original" value:"Ansible" |
user_agent.original | match | Pulumi | excludes:user_agent.original field:"user_agent.original" value:"Pulumi" |
user_agent.original | match | Terraform | excludes:user_agent.original field:"user_agent.original" value:"Terraform" |
aws.cloudtrail.session_credential_from_console | eq | true | excludes:aws.cloudtrail.session_credential_from_console field:"aws.cloudtrail.session_credential_from_console" value:"true" |
event.provider | in | account.amazonaws.com, budgets.amazonaws.com, ce.amazonaws.com, cost-optimization-hub.amazonaws.com, freetier.amazonaws.com, health.amazonaws.com, monitoring.amazonaws.com, notifications.amazonaws.com, securityhub.amazonaws.com, servicecatalog-appregistry.amazonaws.com, support-console.amazonaws.com, support.amazonaws.com | excludes:event.provider |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Esql.time_window_date_trunc | KEEP Esql.time_window_date_trunc |
Esql.activity_type | KEEP Esql.activity_type |
Esql.activity_fidelity_score | KEEP Esql.activity_fidelity_score |
Esql.event_count | KEEP Esql.event_count |
Esql.timestamp_first_seen | KEEP Esql.timestamp_first_seen |
Esql.timestamp_last_seen | KEEP Esql.timestamp_last_seen |
Esql.aws_cloudtrail_user_identity_arn_values | KEEP Esql.aws_cloudtrail_user_identity_arn_values |
Esql.aws_cloudtrail_user_identity_access_key_id_values | KEEP Esql.aws_cloudtrail_user_identity_access_key_id_values |
Esql.event_provider_count_distinct | KEEP Esql.event_provider_count_distinct |
Esql.event_action_values | KEEP Esql.event_action_values |
Esql.event_provider_values | KEEP Esql.event_provider_values |
Esql.source_ip_values | KEEP Esql.source_ip_values |
Esql.user_agent_original_values | KEEP Esql.user_agent_original_values |
Esql.source_ip_user_agent_pair_values | KEEP Esql.source_ip_user_agent_pair_values |
Esql.source_geo_city_name_values | KEEP Esql.source_geo_city_name_values |
Esql.source_ip_city_pair_values | KEEP Esql.source_ip_city_pair_values |
Esql.source_network_org_name_values | KEEP Esql.source_network_org_name_values |
Esql.source_ip_network_pair_values | KEEP Esql.source_ip_network_pair_values |
Esql.source_ip_count_distinct | KEEP Esql.source_ip_count_distinct |
Esql.user_agent_original_count_distinct | KEEP Esql.user_agent_original_count_distinct |
Esql.source_geo_city_name_count_distinct | KEEP Esql.source_geo_city_name_count_distinct |
Esql.source_network_org_name_count_distinct | KEEP Esql.source_network_org_name_count_distinct |
Esql.data_stream_namespace_values | KEEP Esql.data_stream_namespace_values |
Entra ID Register Device with Unusual User Agent (Azure AD Join)
#Detects successful Microsoft Entra ID audit events for Register device where additional details indicate an Azure AD join and the recorded user agent is not one of the common native registration clients (Dsreg, DeviceRegistrationClient, or Dalvik-based Android enrollment). Legitimate Windows and standard mobile enrollment flows often present predictable user-agent strings; unexpected clients may reflect scripted registration, third-party tooling, or adversary-driven device registration used for persistence or token abuse. Baseline approved provisioning tools and MDM integrations before tuning.
Known False Positives
- Custom device management agents, OEM enrollment clients, or updated Microsoft clients that use new user-agent strings may match. Add exclusions for known `azure.auditlogs.properties.userAgent` values or enrollment programs after review.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Azure | Register device |
Rules Detecting the Same Action
These rules filter on the same operation.
- Azure Device No Longer Managed or Compliant (Sigma)
- Azure Device or Configuration Modified or Deleted (Sigma)
- Entra ID AiTM Phishing-Kit Chain Detected (Elastic)
- Entra ID Device Registration with Phishing Kit Default OS Build (Elastic)
- Entra ID Device Registration with ROADtools Default OS Build (Elastic)
- Entra ID Deviceless Windows Hello Sign-in Followed by Device Registration (Elastic)
- Entra ID Multiple Device Registrations by a Single User (Elastic)
- Entra ID Protection User Alert and Device Registration (Elastic)
Rule Body
[metadata]
creation_date = "2026/05/15"
integration = ["azure"]
maturity = "production"
updated_date = "2026/05/15"
[rule]
author = ["Elastic"]
description = """
Detects successful Microsoft Entra ID audit events for Register device where additional details indicate an Azure AD join
and the recorded user agent is not one of the common native registration clients (Dsreg, DeviceRegistrationClient, or
Dalvik-based Android enrollment). Legitimate Windows and standard mobile enrollment flows often present predictable
user-agent strings; unexpected clients may reflect scripted registration, third-party tooling, or adversary-driven device
registration used for persistence or token abuse. Baseline approved provisioning tools and MDM integrations before tuning.
"""
false_positives = [
"""
Custom device management agents, OEM enrollment clients, or updated Microsoft clients that use new user-agent strings
may match. Add exclusions for known `azure.auditlogs.properties.userAgent` values or enrollment programs after review.
""",
]
from = "now-9m"
index = ["logs-azure.auditlogs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Entra ID Register Device with Unusual User Agent (Azure AD Join)"
note = """## Triage and analysis
### Investigating Entra ID Register Device with Unusual User Agent (Azure AD Join)
Review `azure.auditlogs.properties.initiated_by.user.userPrincipalName`, source IP fields on the audit event,
`azure.auditlogs.properties.target_resources.0.display_name` for the device name, and
`azure.correlation_id` for related audit entries.
Compare `azure.auditlogs.properties.userAgent` to your organization's standard Autopilot, Intune, and Windows enrollment
clients.
### Possible investigation steps
- Confirm whether the user intentionally joined a device and whether the user agent matches a known provisioning package.
- Pivot to `azure.signinlogs` for the same principal and timeframe for risky sign-ins or token broker activity.
- Search for other `Register device` events from the same IP or user agent across the tenant.
### Response and remediation
- If malicious, remove the device in Entra ID, revoke refresh and primary refresh tokens for the user, and reset credentials per policy.
- Tighten device registration and join controls via Conditional Access and device compliance policies.
"""
references = [
"https://learn.microsoft.com/en-us/entra/identity/devices/concept-directory-join",
"https://github.com/dirkjanm/ROADtools",
]
risk_score = 47
rule_id = "d4695889-0410-4e7b-a4aa-59be525a11a6"
severity = "medium"
tags = [
"Domain: Cloud",
"Domain: Identity",
"Data Source: Azure",
"Data Source: Microsoft Entra ID",
"Data Source: Microsoft Entra ID Audit Logs",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:"azure.auditlogs" and event.action:"Register device" and
event.outcome:(success or Success) and
azure.auditlogs.properties.userAgent:(* and not (Dsreg* or DeviceRegistrationClient or Dalvik*)) and
azure.auditlogs.properties.additional_details.value:"Azure AD join"
'''
[rule.investigation_fields]
field_names = [
"@timestamp",
"event.action",
"event.outcome",
"azure.auditlogs.properties.userAgent",
"azure.auditlogs.properties.additional_details.value",
"azure.auditlogs.properties.initiated_by.user.userPrincipalName",
"azure.auditlogs.properties.initiated_by.user.ipAddress",
"azure.auditlogs.properties.target_resources.0.display_name",
"azure.auditlogs.properties.target_resources.0.id",
"azure.correlation_id",
]
[[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.005"
name = "Device Registration"
reference = "https://attack.mitre.org/techniques/T1098/005/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
Stages and Predicates
Stage 1: query
data_stream.dataset:"azure.auditlogs" and event.action:"Register device" and
event.outcome:(success or Success) and
azure.auditlogs.properties.userAgent:(* and not (Dsreg* or DeviceRegistrationClient or Dalvik*)) and
azure.auditlogs.properties.additional_details.value:"Azure AD join"
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
azure.auditlogs.properties.userAgent | eq | DeviceRegistrationClient | excludes:azure.auditlogs.properties.userAgent field:"azure.auditlogs.properties.userAgent" value:"DeviceRegistrationClient" |
azure.auditlogs.properties.userAgent | starts_with | Dalvik | excludes:azure.auditlogs.properties.userAgent field:"azure.auditlogs.properties.userAgent" value:"Dalvik" |
azure.auditlogs.properties.userAgent | starts_with | Dsreg | excludes:azure.auditlogs.properties.userAgent field:"azure.auditlogs.properties.userAgent" value:"Dsreg" |
Execution of a Windows Script with Unusual File Extension
#Identifies the execution of a script with an unusual file extension by Windows Script Host processes (cscript or wscript).
MITRE ATT&CK Coverage
Rule Body
[rule]
description = """
Identifies the execution of a script with an unusual file extension by Windows Script Host processes (cscript or
wscript).
"""
id = "b76c0a04-b504-4a2f-a0cf-b4175a2f3eea"
license = "Elastic License v2"
name = "Execution of a Windows Script with Unusual File Extension"
os_list = ["windows"]
version = "1.0.36"
query = '''
process where event.action == "start" and
(process.pe.original_file_name :"wscript.exe" or process.name : "wscript.exe") and process.parent.name != null and
process.args : ("-e:*", "/e:*", "//e:*") and
not process.command_line : ("*.js*", "*.vb*", "*.wsf*", "*.wsh*", "*.wsc*", "*.tmp*") and
/* Issue #286 */
not process.parent.executable : ("?:\\Program Files\\*.exe", "?:\\Program Files (x86)\\*.exe") and
not process.command_line : ("*:\\Program Files\\*", "*:\\Program Files (x86)\\*", "*\\Windows\\system32\\spool\\DRIVERS\\*") and
not (process.name : "cscript.exe" and process.args : "C:\\PGM_TC~1\\DHL_FR~1\\xls2csv.bat") and
not (process.args : "\\\\*" and process.args_count >= 3) and
not (process.args : "/mts/wav/adf" and process.args : "/emf") and
not (process.parent.args : "D:\\*.cmd" and process.args : "https://app.*:444/api/Banner") and
not (process.parent.name : "cmd.exe" and process.parent.command_line : ("\"C:\\windows\\system32\\cmd.exe\" ", "cmd ")) and
not (process.parent.name : "cmd.exe" and
process.parent.args :
("C:\\ProgramData\\NinjaRMMAgent\\scripting\\customscript_gen_?.bat-ninjascript.bat",
"C:\\Storage\\VisualStudioProjects\\connect_wise_script\\install_speerity.bat",
"C:\\PGM_TC~1\\DHL_FR~1\\xls2csv.bat",
"C:\\MBS\\UTIL\\repl.bat",
"C:\\MBS\\UTIL\\PBSCOVER.BAT",
"M:\\sendkeys.bat Mayer",
"F:\\wamp64\\www\\centralstores\\cronjobs\\*.bat"))
'''
min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.005"
name = "Visual Basic"
reference = "https://attack.mitre.org/techniques/T1059/005/"
[[threat.technique.subtechnique]]
id = "T1059.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: process
process where event.action == "start" and
(process.pe.original_file_name :"wscript.exe" or process.name : "wscript.exe") and process.parent.name != null and
process.args : ("-e:*", "/e:*", "//e:*") and
not process.command_line : ("*.js*", "*.vb*", "*.wsf*", "*.wsh*", "*.wsc*", "*.tmp*") and
not process.parent.executable : ("?:\\Program Files\\*.exe", "?:\\Program Files (x86)\\*.exe") and
not process.command_line : ("*:\\Program Files\\*", "*:\\Program Files (x86)\\*", "*\\Windows\\system32\\spool\\DRIVERS\\*") and
not (process.name : "cscript.exe" and process.args : "C:\\PGM_TC~1\\DHL_FR~1\\xls2csv.bat") and
not (process.args : "\\\\*" and process.args_count >= 3) and
not (process.args : "/mts/wav/adf" and process.args : "/emf") and
not (process.parent.args : "D:\\*.cmd" and process.args : "https://app.*:444/api/Banner") and
not (process.parent.name : "cmd.exe" and process.parent.command_line : ("\"C:\\windows\\system32\\cmd.exe\" ", "cmd ")) and
not (process.parent.name : "cmd.exe" and
process.parent.args :
("C:\\ProgramData\\NinjaRMMAgent\\scripting\\customscript_gen_?.bat-ninjascript.bat",
"C:\\Storage\\VisualStudioProjects\\connect_wise_script\\install_speerity.bat",
"C:\\PGM_TC~1\\DHL_FR~1\\xls2csv.bat",
"C:\\MBS\\UTIL\\repl.bat",
"C:\\MBS\\UTIL\\PBSCOVER.BAT",
"M:\\sendkeys.bat Mayer",
"F:\\wamp64\\www\\centralstores\\cronjobs\\*.bat"))
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:"wscript.exe" |
process.parent.name | is_not_null | field:"parent_process_basename" kind:is_not_null | |
process.pe.original_file_name | wildcard |
| field:"OriginalFileName" kind:wildcard value:"wscript.exe" |
Exclusions
The rule actively suppresses these predicates.
First Time Seen Remote Monitoring and Management Tool
#Adversaries may install legitimate remote monitoring and management (RMM) tools or remote access software on compromised endpoints for command-and-control (C2), persistence, and execution of native commands. This rule detects when a process is started whose name or code signature matches commonly abused RMM or remote access tools. New Terms type: the host.id and process.name pair has not been seen before within the configured 7-day history window.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Command & Control |
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 1: Process creation |
| Security-Auditing | Event ID 4688: A new process has been created. |
Rule Body
[metadata]
creation_date = "2023/04/03"
integration = ["endpoint", "windows", "system"]
maturity = "production"
updated_date = "2026/06/23"
[rule]
author = ["Elastic"]
description = """
Adversaries may install legitimate remote monitoring and management (RMM) tools or remote access software on compromised endpoints for command-and-control (C2), persistence, and execution of native commands. This rule detects when a process is started whose name or code signature matches commonly abused RMM or remote access tools. New Terms type: the host.id and process.name pair has not been seen before within the configured 7-day history window.
"""
from = "now-9m"
index = [
"logs-endpoint.events.process-*",
"endgame-*",
"winlogbeat-*",
"logs-windows.forwarded*",
"logs-windows.sysmon_operational-*",
"logs-system.security*",
]
language = "kuery"
license = "Elastic License v2"
name = "First Time Seen Remote Monitoring and Management Tool"
references = [
"https://thedfirreport.com/2023/04/03/malicious-iso-file-leads-to-domain-wide-ransomware/",
"https://github.com/redcanaryco/surveyor/blob/master/definitions/remote-admin.json",
"https://www.cisa.gov/news-events/cybersecurity-advisories/aa23-025a",
"https://www.cisa.gov/sites/default/files/2025-06/aa25-163a-ransomware-simplehelp-rmm-compromise.pdf",
"https://lolrmm.io/",
]
risk_score = 47
rule_id = "6e1a2cc4-d260-11ed-8829-f661ea17fbcc"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Command and Control",
"Resources: Investigation Guide",
"Data Source: Elastic Defend",
"Data Source: Elastic Endgame",
"Data Source: Windows Security Event Logs",
"Data Source: Sysmon",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
host.os.type: "windows" and
event.category: "process" and event.type: "start" and
(
process.code_signature.subject_name : (
"Action1 Corporation" or
"Aeroadmin LLC" or
"AeroAdmin LLC" or
"AmidaWare LLC" or
"Ammyy LLC" or
"AnyDesk Software GmbH" or
"AOMEI International Network Limited" or
"Atera Networks Ltd" or
"AWERAY PTE. LTD." or
"BeamYourScreen GmbH" or
"Bomgar Corporation" or
"BreakingSecurity.net" or
"ConnectWise, Inc." or
"ConnectWise, LLC" or
"Connectwise, LLC" or
"Devolutions Inc" or
"Devolutions inc." or
"DOMOTZ INC." or
"DUC FABULOUS CO.,LTD" or
"DWSNET OÜ" or
"DWSNET srl" or
"Electronic Team, Inc." or
"Famatech Corp." or
"FleetDeck Inc" or
"GlavSoft LLC" or
"GlavSoft LLC." or
"GoTo Technologies USA, LLC" or
"Hefei Pingbo Network Technology Co. Ltd" or
"IDrive, Inc." or
"Impero Solutions Limited" or
"IMPERO SOLUTIONS LIMITED" or
"Instant Housecall" or
"ISL Online Ltd." or
"JumpCloud Inc" or
"Level Software, Inc." or
"LogMeIn, Inc." or
"LUNIXAR SAS DE CV" or
"MMSOFT Design Ltd." or
"Monitoring Client" or
"MSPBytes Corp" or
"MSPBytes, Corp." or
"N-ABLE TECHNOLOGIES LTD" or
"Nanosystems S.r.l." or
"NetSupport Ltd" or
"NetSupport Ltd." or
"NETSUPPORT LTD." or
"NinjaOne LLC" or
"NinjaRMM, LLC" or
"Open Source Developer, Huabing Zhou" or
"Parallels International GmbH" or
"philandro Software GmbH" or
"Pro Softnet Corporation" or
"PURSLANE" or
"RealVNC" or
"RealVNC Limited" or
"REMOTE UTILITIES PTE. LTD." or
"Remote Utilities LLC" or
"Rocket Software, Inc." or
"Rsupport Co., Ltd." or
"SAFIB" or
"ScreenConnect Client" or
"Servably, Inc." or
"Servably Inc." or
"ShowMyPC INC" or
"SimpleHelp Ltd" or
"Splashtop Inc." or
"Superops Inc." or
"Tailscale Inc." or
"TeamViewer" or
"TeamViewer GmbH" or
"TeamViewer Germany GmbH" or
"Techinline Limited" or
"uvnc bvba" or
"Yakhnovets Denis Aleksandrovich IP" or
"Zhou Huabing" or
"ZOHO Corporation Private Limited"
) or
process.name.caseless : (
AA_v*.exe or
"AcronisCyberProtectConnectAgent.exe" or
"AeroAdmin.exe" or
"AgentMon.exe" or
"AnyDesk.exe" or
"apc_Admin.exe" or
"apc_host.exe" or
"AteraAgent.exe" or
aweray_remote*.exe or
"AweSun.exe" or
"B4-Service.exe" or
"BASupSrvc.exe" or
"bomgar-scc.exe" or
"CagService.exe" or
"CloudRaCmd.exe" or
"CloudRaSd.exe" or
"CloudRaService.exe" or
ConnectWiseControl*.exe or
"connectwisecontrol.client.exe" or
"domotzagent.exe" or
"domotz-windows-x64-10.exe" or
"dwagsvc.exe" or
"DWRCC.exe" or
"dwrcs.exe" or
"dwrcst.exe" or
fleetdeck_commander*.exe or
"g2aservice.exe" or
"getscreen.exe" or
"GoToAssistService.exe" or
"GoToResolveProcessChecker.exe" or
"GoToResolveRemoteControl.exe" or
"GoToResolveService.exe" or
"GoToResolveTerminal.exe" or
"GoToResolveUnattended.exe" or
"gotohttp.exe" or
"helpwire.exe" or
"ImmyAgent.exe" or
"ImmyBot.Agent.Ephemeral.exe" or
"ImmyUpdater.exe" or
"ImperoClientSVC.exe" or
"ImperoServerSVC.exe" or
"ISLLight.exe" or
"ISLLightClient.exe" or
"jumpcloud-agent.exe" or
"komari.exe" or
"komari-agent.exe" or
"level.exe" or
"lmi_rescue.exe" or
"lmi_rescue_srv.exe" or
"LMIIgnition.exe" or
"LogMeIn.exe" or
"ltsvc.exe" or
"ltsvcmon.exe" or
"lttray.exe" or
"Lunixar.exe" or
"LunixarRemote.exe" or
"LunixarUpdater.exe" or
"LvAgent.exe" or
"ManageEngine_Remote_Access_Plus.exe" or
"MeshAgent.exe" or
"Mikogo-Service.exe" or
"nezha-agent.exe" or
"NinjaRMMAgent.exe" or
"NinjaRMMAgentPatcher.exe" or
"ninjarmm-cli.exe" or
"parsec.exe" or
"PService.exe" or
"quickassist.exe" or
"r_server.exe" or
"radmin.exe" or
"radmin3.exe" or
"rcengmgru.exe" or
"RCClient.exe" or
"rcmgrsvc.exe" or
"RCService.exe" or
"Remote Support.exe" or
"RemoteDesktopManager.exe" or
"Remotely_Agent.exe" or
"Remotely_Desktop.exe" or
"RemotePC.exe" or
"RemotePCDesktop.exe" or
"RemotePCService.exe" or
"remoteview.exe" or
"rfusclient.exe" or
"RMM.Agent.exe" or
"ROMServer.exe" or
"ROMViewer.exe" or
"RPCSuite.exe" or
"rserver3.exe" or
"rustdesk.exe" or
"rutserv.exe" or
"rutview.exe" or
"rvagent.exe" or
"rvagtray.exe" or
"saazapsc.exe" or
ScreenConnect*.exe or
"ScreenConnect.ClientService.exe" or
"session_win.exe" or
"simplegatewayservice.exe" or
"simplehelpcustomer.exe" or
"smpcview.exe" or
"spclink.exe" or
"Splashtop-streamer.exe" or
"SplashtopSOS.exe" or
"spsrv.exe" or
"sragent.exe" or
"SRService.exe" or
"srmanager.exe" or
"srserver.exe" or
"strwinclt.exe" or
"Supremo.exe" or
"SupremoService.exe" or
"Syncro.App.Runner.exe" or
"Syncro.Installer.exe" or
"Syncro.Overmind.Service.exe" or
"Syncro.Service.exe" or
"SyncroLive.Agent.exe" or
"SyncroLive.Agent.Runner.exe" or
"SyncroLive.Service.exe" or
"tacticalrmm.exe" or
"tailscale.exe" or
"tailscaled.exe" or
"teamviewer.exe" or
"teamviewer_desktop.exe" or
"teamviewer_service.exe" or
"TiAgent.exe" or
"TiClientCore.exe" or
"ToDesk_Service.exe" or
"ToolsIQ.exe" or
"TSClient.exe" or
"tvn.exe" or
"tvnserver.exe" or
"tvnviewer.exe" or
"twingate.exe" or
UltraVNC*.exe or
UltraViewer*.exe or
"Velociraptor.exe" or
"vncserver.exe" or
"vncviewer.exe" or
"winvnc.exe" or
"winwvc.exe" or
"ZA_Access.exe" or
"za_connect.exe" or
"Zaservice.exe" or
"ZMAgent.exe" or
"ZohoMeeting.exe" or
"zohotray.exe" or
"ZohoURS.exe" or
"ZohoURSService.exe"
)
) and
not (process.pe.original_file_name : ("G2M.exe" or "Updater.exe" or "powershell.exe") and process.code_signature.subject_name : "LogMeIn, Inc.")
'''
note = """## Triage and analysis
### Investigating First Time Seen Remote Monitoring and Management Tool
#### Possible investigation steps
- Validate the alert-local process event and identify the matched RMM artifact.
- Focus: `host.name`, `host.id`, `process.name`, `process.executable`, `process.code_signature.subject_name`.
- Review the exact process entity on the alerted host with $investigate_0
- Implication: The alert proves one Windows process start from the supported process data sources where the `host.id` and `process.name` pair is first seen within the 7-day new terms window; it does not prove the remote session or legitimacy. Close only if the exact host, account, process name, executable, signer, and support or deployment window match a validated change record or verified owner confirmation; otherwise continue.
- Determine why this RMM process is new for the host.
- Focus: `host.id`, `process.name`, `process.executable`, `process.command_line`, `process.hash.sha256`.
- Review same-host executions across the rule history window with $investigate_1
- Implication: Repeated executions clustered around the same deployment or support window can support a bounded benign explanation only when the exact executable, command line, hash, host, and account match the recovered business context. A new hash, renamed executable, unexpected arguments, or executions outside that window keep the case suspicious.
- Reconstruct the parent process and logon context that launched the tool.
- Focus: `process.parent.name`, `process.parent.executable`, `process.parent.command_line`, `process.Ext.session_info.logon_type`, `user.name`.
- Review the parent process entity on the same host with $investigate_2
- Implication: A parent and session that match the same validated change record and account owner confirmation can bound the activity to one workflow. A launch from user-download, browser, archive, script, or unrelated service context is suspicious for social engineering or staged access.
- Inspect endpoint artifacts and child behavior before broader scoping.
- Focus: `process.entity_id`, `process.Ext.ancestry`, `process.args`, `process.working_directory`, `process.Ext.token.elevation_level`.
- Implication: Recover child process, service, file, registry, and persistence evidence from endpoint timeline or live host data before interpretation because those artifact fields are not guaranteed on the alert. Child execution, persistence, unusual working directories, or elevated token use by the matched RMM process supports escalation; absence of recoverable artifacts does not prove benign.
- If local process, parent, and endpoint-artifact evidence is suspicious or incomplete, broaden scope for the RMM hypothesis.
- Focus: `host.id`, `user.name`, `process.name`, `process.hash.sha256`, `process.code_signature.subject_name`.
- Review same host and account activity with $investigate_3
- Review the same executable hash across available process events with $investigate_4
- Implication: The hypothesis is RMM staging or reuse across hosts or accounts; matching hash activity, related alerts, or repeated account use should drive host and account scoping plus evidence preservation. No related alerts or hash matches only limits currently observed spread and does not prove benign; exact matches limited to the validated host, account, and time window may support closure after the earlier evidence aligns.
Disposition: Escalate suspicious RMM artifacts, launch chains, or expanded scope; close only when alert-local evidence and recovered context prove one expected support or deployment workflow on the exact host and account; preserve and escalate mixed or incomplete cases for more context before final disposition.
### False positive analysis
- Potential benign cases include first deployment of a remote support tool, first use after host rebuild, a product update that changes `process.name`, or a one-time support session only when alert-local and recovered process evidence match `host.id`, `user.name`, `process.name`, `process.executable`, `process.code_signature.subject_name`, `process.code_signature.trusted`, `process.pe.original_file_name`, and `process.hash.sha256` when available, and that evidence aligns with a verified owner confirmation or validated change record for the observed support or deployment window.
- Do not close on the tool name, signer, executable path, or lack of related alerts alone. Escalate when artifacts indicate social engineering, an unexpected parent or session, a renamed executable, hash mismatch, or unbounded account or host spread.
- Scope exceptions only to durable future-alert fields that match the validated benign workflow, using `host.id`, `user.name`, `process.name`, `process.executable`, `process.code_signature.subject_name`, `process.code_signature.trusted`, `process.pe.original_file_name`, and `process.hash.sha256` when available. Do not scope exceptions by prose-only groups such as support teams or known RMM activity; preserve and escalate mixed or incomplete cases instead of creating broad exclusions.
### Response and remediation
- Preserve or export case evidence plus volatile process, memory, executable, or file-system artifacts that could be lost before isolation, process termination, cleanup, or other disruptive action.
- For confirmed malicious activity, scope first by reviewing the matched process, parent and child processes, persistence artifacts, same-hash executions, related alerts, and account activity across affected hosts.
- After evidence capture and initial scoping, isolate affected hosts or disable active remote access paths when containment is required to prevent continued access.
- After containment decisions and evidence review, terminate malicious RMM processes, remove persistence, clean up dropped files or services, revoke active sessions, and reset credentials exposed through the RMM session or related activity.
- If social engineering led to the remote access, validate the user interaction, collect relevant communications or download sources when available, and include affected accounts in credential review.
- Document confirmed indicators and logging or detection gaps for the responsible detection or logging owners after scoping and containment.
"""
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:
- [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 = [
"host.id",
"host.name",
"user.name",
"process.entity_id",
"process.name",
"process.executable",
"process.command_line",
"process.hash.sha256",
"process.code_signature.subject_name",
"process.code_signature.trusted",
"process.pe.original_file_name",
"process.parent.entity_id",
"process.parent.name",
"process.parent.executable",
"process.parent.command_line",
]
[[transform.investigate]]
label = "Matched process context"
description = "Find the exact alerted process entity on the same host around the alert window."
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" },
],
]
relativeFrom = "now-1h"
relativeTo = "now"
[[transform.investigate]]
label = "Same host process name history"
description = "Find same-host executions of the matched process name across the rule history window."
providers = [
[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.name", queryType = "phrase", value = "{{process.name}}", valueType = "string" },
],
]
relativeFrom = "now-7d/d"
relativeTo = "now"
[[transform.investigate]]
label = "Parent process activity"
description = "Recover events for the parent process entity that launched the matched RMM process."
providers = [
[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.parent.entity_id}}", valueType = "string" },
],
]
relativeFrom = "now-24h"
relativeTo = "now"
[[transform.investigate]]
label = "Host account activity"
description = "Review activity by the same account on the same host before broader scoping."
providers = [
[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "user.name", queryType = "phrase", value = "{{user.name}}", valueType = "string" },
],
]
relativeFrom = "now-48h/h"
relativeTo = "now"
[[transform.investigate]]
label = "Executable hash scope"
description = "Find other executions of the same executable hash when local evidence is suspicious or unresolved."
providers = [
[
{ excluded = false, field = "process.hash.sha256", queryType = "phrase", value = "{{process.hash.sha256}}", valueType = "string" },
],
]
relativeFrom = "now-7d/d"
relativeTo = "now"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1219"
name = "Remote Access Tools"
reference = "https://attack.mitre.org/techniques/T1219/"
[[rule.threat.technique.subtechnique]]
id = "T1219.002"
name = "Remote Desktop Software"
reference = "https://attack.mitre.org/techniques/T1219/002/"
[rule.threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[rule.new_terms]
field = "new_terms_fields"
value = ["host.id", "process.name"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-7d"
Stages and Predicates
Stage 1: new_terms
host.os.type: "windows" and
event.category: "process" and event.type: "start" and
(
process.code_signature.subject_name : (
"Action1 Corporation" or
"Aeroadmin LLC" or
"AeroAdmin LLC" or
"AmidaWare LLC" or
"Ammyy LLC" or
"AnyDesk Software GmbH" or
"AOMEI International Network Limited" or
"Atera Networks Ltd" or
"AWERAY PTE. LTD." or
"BeamYourScreen GmbH" or
"Bomgar Corporation" or
"BreakingSecurity.net" or
"ConnectWise, Inc." or
"ConnectWise, LLC" or
"Connectwise, LLC" or
"Devolutions Inc" or
"Devolutions inc." or
"DOMOTZ INC." or
"DUC FABULOUS CO.,LTD" or
"DWSNET OÜ" or
"DWSNET srl" or
"Electronic Team, Inc." or
"Famatech Corp." or
"FleetDeck Inc" or
"GlavSoft LLC" or
"GlavSoft LLC." or
"GoTo Technologies USA, LLC" or
"Hefei Pingbo Network Technology Co. Ltd" or
"IDrive, Inc." or
"Impero Solutions Limited" or
"IMPERO SOLUTIONS LIMITED" or
"Instant Housecall" or
"ISL Online Ltd." or
"JumpCloud Inc" or
"Level Software, Inc." or
"LogMeIn, Inc." or
"LUNIXAR SAS DE CV" or
"MMSOFT Design Ltd." or
"Monitoring Client" or
"MSPBytes Corp" or
"MSPBytes, Corp." or
"N-ABLE TECHNOLOGIES LTD" or
"Nanosystems S.r.l." or
"NetSupport Ltd" or
"NetSupport Ltd." or
"NETSUPPORT LTD." or
"NinjaOne LLC" or
"NinjaRMM, LLC" or
"Open Source Developer, Huabing Zhou" or
"Parallels International GmbH" or
"philandro Software GmbH" or
"Pro Softnet Corporation" or
"PURSLANE" or
"RealVNC" or
"RealVNC Limited" or
"REMOTE UTILITIES PTE. LTD." or
"Remote Utilities LLC" or
"Rocket Software, Inc." or
"Rsupport Co., Ltd." or
"SAFIB" or
"ScreenConnect Client" or
"Servably, Inc." or
"Servably Inc." or
"ShowMyPC INC" or
"SimpleHelp Ltd" or
"Splashtop Inc." or
"Superops Inc." or
"Tailscale Inc." or
"TeamViewer" or
"TeamViewer GmbH" or
"TeamViewer Germany GmbH" or
"Techinline Limited" or
"uvnc bvba" or
"Yakhnovets Denis Aleksandrovich IP" or
"Zhou Huabing" or
"ZOHO Corporation Private Limited"
) or
process.name.caseless : (
AA_v*.exe or
"AcronisCyberProtectConnectAgent.exe" or
"AeroAdmin.exe" or
"AgentMon.exe" or
"AnyDesk.exe" or
"apc_Admin.exe" or
"apc_host.exe" or
"AteraAgent.exe" or
aweray_remote*.exe or
"AweSun.exe" or
"B4-Service.exe" or
"BASupSrvc.exe" or
"bomgar-scc.exe" or
"CagService.exe" or
"CloudRaCmd.exe" or
"CloudRaSd.exe" or
"CloudRaService.exe" or
ConnectWiseControl*.exe or
"connectwisecontrol.client.exe" or
"domotzagent.exe" or
"domotz-windows-x64-10.exe" or
"dwagsvc.exe" or
"DWRCC.exe" or
"dwrcs.exe" or
"dwrcst.exe" or
fleetdeck_commander*.exe or
"g2aservice.exe" or
"getscreen.exe" or
"GoToAssistService.exe" or
"GoToResolveProcessChecker.exe" or
"GoToResolveRemoteControl.exe" or
"GoToResolveService.exe" or
"GoToResolveTerminal.exe" or
"GoToResolveUnattended.exe" or
"gotohttp.exe" or
"helpwire.exe" or
"ImmyAgent.exe" or
"ImmyBot.Agent.Ephemeral.exe" or
"ImmyUpdater.exe" or
"ImperoClientSVC.exe" or
"ImperoServerSVC.exe" or
"ISLLight.exe" or
"ISLLightClient.exe" or
"jumpcloud-agent.exe" or
"komari.exe" or
"komari-agent.exe" or
"level.exe" or
"lmi_rescue.exe" or
"lmi_rescue_srv.exe" or
"LMIIgnition.exe" or
"LogMeIn.exe" or
"ltsvc.exe" or
"ltsvcmon.exe" or
"lttray.exe" or
"Lunixar.exe" or
"LunixarRemote.exe" or
"LunixarUpdater.exe" or
"LvAgent.exe" or
"ManageEngine_Remote_Access_Plus.exe" or
"MeshAgent.exe" or
"Mikogo-Service.exe" or
"nezha-agent.exe" or
"NinjaRMMAgent.exe" or
"NinjaRMMAgentPatcher.exe" or
"ninjarmm-cli.exe" or
"parsec.exe" or
"PService.exe" or
"quickassist.exe" or
"r_server.exe" or
"radmin.exe" or
"radmin3.exe" or
"rcengmgru.exe" or
"RCClient.exe" or
"rcmgrsvc.exe" or
"RCService.exe" or
"Remote Support.exe" or
"RemoteDesktopManager.exe" or
"Remotely_Agent.exe" or
"Remotely_Desktop.exe" or
"RemotePC.exe" or
"RemotePCDesktop.exe" or
"RemotePCService.exe" or
"remoteview.exe" or
"rfusclient.exe" or
"RMM.Agent.exe" or
"ROMServer.exe" or
"ROMViewer.exe" or
"RPCSuite.exe" or
"rserver3.exe" or
"rustdesk.exe" or
"rutserv.exe" or
"rutview.exe" or
"rvagent.exe" or
"rvagtray.exe" or
"saazapsc.exe" or
ScreenConnect*.exe or
"ScreenConnect.ClientService.exe" or
"session_win.exe" or
"simplegatewayservice.exe" or
"simplehelpcustomer.exe" or
"smpcview.exe" or
"spclink.exe" or
"Splashtop-streamer.exe" or
"SplashtopSOS.exe" or
"spsrv.exe" or
"sragent.exe" or
"SRService.exe" or
"srmanager.exe" or
"srserver.exe" or
"strwinclt.exe" or
"Supremo.exe" or
"SupremoService.exe" or
"Syncro.App.Runner.exe" or
"Syncro.Installer.exe" or
"Syncro.Overmind.Service.exe" or
"Syncro.Service.exe" or
"SyncroLive.Agent.exe" or
"SyncroLive.Agent.Runner.exe" or
"SyncroLive.Service.exe" or
"tacticalrmm.exe" or
"tailscale.exe" or
"tailscaled.exe" or
"teamviewer.exe" or
"teamviewer_desktop.exe" or
"teamviewer_service.exe" or
"TiAgent.exe" or
"TiClientCore.exe" or
"ToDesk_Service.exe" or
"ToolsIQ.exe" or
"TSClient.exe" or
"tvn.exe" or
"tvnserver.exe" or
"tvnviewer.exe" or
"twingate.exe" or
UltraVNC*.exe or
UltraViewer*.exe or
"Velociraptor.exe" or
"vncserver.exe" or
"vncviewer.exe" or
"winvnc.exe" or
"winwvc.exe" or
"ZA_Access.exe" or
"za_connect.exe" or
"Zaservice.exe" or
"ZMAgent.exe" or
"ZohoMeeting.exe" or
"zohotray.exe" or
"ZohoURS.exe" or
"ZohoURSService.exe"
)
) and
not (process.pe.original_file_name : ("G2M.exe" or "Updater.exe" or "powershell.exe") and process.code_signature.subject_name : "LogMeIn, Inc.")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.category | eq |
| field:"event.category" kind:eq value:"process" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.code_signature.subject_name | in |
| field:"Signature" kind:in |
process.name.caseless | eq |
| field:"process.name.caseless" kind:eq |
process.name.caseless | wildcard |
| field:"process.name.caseless" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.code_signature.subject_name | eq | LogMeIn, Inc. | excludes:process.code_signature.subject_name field:"process.code_signature.subject_name" value:"LogMeIn, Inc." |
process.pe.original_file_name | in | G2M.exe, Updater.exe, powershell.exe | excludes:process.pe.original_file_name field:"process.pe.original_file_name" value:"G2M.exe" field:"process.pe.original_file_name" value:"Updater.exe" field:"process.pe.original_file_name" value:"powershell.exe" |
GKE Ephemeral Container Added to Pod
#Detects allowed updates or patches to the pods/ephemeralcontainers subresource on GKE by a non-system identity. Ephemeral containers are commonly used for debugging (kubectl debug) but can also be abused to inject tooling into a running pod, access mounted secrets, and execute commands in the target pod context. Attackers with sufficient RBAC may use ephemeral containers to escalate privileges, move laterally, or establish persistence without deploying a new workload.
Known False Positives
- Cluster operators or SREs may legitimately use ephemeral containers for debugging production workloads. Baseline approved admin identities and tune exclusions for known automation.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Privilege Escalation |
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
- Azure AKS Ephemeral Container Added to Pod (Elastic)
- Direct Interactive Kubernetes API Request by Unusual Utilities (Elastic)
- GCP K8s Pod Attached To Node Host Network (Panther)
- GCP K8S Pod Create Or Modify Host Path Volume Mount (Panther)
- GCP K8s Pod Using Host PID Namespace (Panther)
- GKE Anonymous Pod Create/Update/Patch (Elastic)
- GKE Pod Created with a Sensitive hostPath Volume (Elastic)
- GKE Pod Created With HostIPC (Elastic)
Rule Body
[metadata]
creation_date = "2026/07/13"
integration = ["gcp"]
maturity = "production"
updated_date = "2026/07/13"
[rule]
author = ["Elastic"]
description = """
Detects allowed updates or patches to the pods/ephemeralcontainers subresource on GKE by a non-system identity.
Ephemeral containers are commonly used for debugging (kubectl debug) but can also be abused to inject tooling into a
running pod, access mounted secrets, and execute commands in the target pod context. Attackers with sufficient RBAC may
use ephemeral containers to escalate privileges, move laterally, or establish persistence without deploying a new
workload.
"""
false_positives = [
"""
Cluster operators or SREs may legitimately use ephemeral containers for debugging production workloads. Baseline
approved admin identities and tune exclusions for known automation.
""",
]
from = "now-6m"
index = ["logs-gcp.audit-*"]
language = "kuery"
license = "Elastic License v2"
name = "GKE Ephemeral Container Added to Pod"
note = """## Triage and analysis
### Investigating GKE Ephemeral Container Added to Pod
Ephemeral containers allow adding a container to an existing pod for troubleshooting. When abused, they can gain
interactive access to a workload, read sensitive files, and run tools that were not present in the original image.
### Possible investigation steps
- Review `client.user.email`, `source.ip`, and `user_agent.original` and confirm the identity is authorized to use
ephemeral containers.
- Inspect `gcp.audit.resource_name` to identify the targeted pod and owning workload.
- If request bodies are captured, review the ephemeral container image, command, and securityContext for privilege
indicators.
- Correlate with follow-on audit activity such as pod exec, secret reads, TokenRequest, or RBAC modifications.
### False positive analysis
- Approved on-call debugging with `kubectl debug` may match. Allowlist known admin identities after review.
### Response and remediation
- If unauthorized, remove excessive RBAC that grants update or patch on pods/ephemeralcontainers and rotate exposed
credentials.
- Quarantine or redeploy impacted workloads and hunt for additional compromised pods or identities.
"""
setup = """
The GCP Fleet integration with GKE audit logs enabled is required to be compatible with this rule.
"""
references = [
"https://kubernetes.io/docs/concepts/workloads/pods/ephemeral-containers/",
]
risk_score = 47
rule_id = "d52e2418-978c-4184-9eab-e084af1f76b7"
severity = "medium"
tags = [
"Domain: Cloud",
"Domain: Kubernetes",
"Data Source: GCP",
"Data Source: Google Cloud Platform",
"Use Case: Threat Detection",
"Tactic: Privilege Escalation",
"Tactic: Execution",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:gcp.audit and service.name:"k8s.io" and event.outcome:success and
event.action:(
"io.k8s.core.v1.pods.ephemeralcontainers.update" or
"io.k8s.core.v1.pods.ephemeralcontainers.patch"
) and not client.user.email:(
system\:node\:* or
system\:serviceaccount\:kube-system\:*
)
'''
[[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 = "T1609"
name = "Container Administration Command"
reference = "https://attack.mitre.org/techniques/T1609/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[rule.investigation_fields]
field_names = [
"@timestamp",
"client.user.email",
"source.ip",
"user_agent.original",
"event.action",
"event.outcome",
"gcp.audit.resource_name",
"gcp.audit.request",
"data_stream.namespace",
]
Stages and Predicates
Stage 1: query
data_stream.dataset:gcp.audit and service.name:"k8s.io" and event.outcome:success and
event.action:(
"io.k8s.core.v1.pods.ephemeralcontainers.update" or
"io.k8s.core.v1.pods.ephemeralcontainers.patch"
) and not client.user.email:(
system\:node\:* or
system\:serviceaccount\:kube-system\:*
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"gcp.audit" |
event.action | in |
| field:"EventType" kind:in |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"success" |
service.name | eq |
| field:"ServiceName" kind:eq value:"k8s.io" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
client.user.email | starts_with | system:node: | excludes:client.user.email field:"client.user.email" value:"system:node:" |
client.user.email | starts_with | system:serviceaccount:kube-system: | excludes:client.user.email field:"client.user.email" value:"system:serviceaccount:kube-system:" |
Google Workspace User Login with Unusual ASN
#Detects the first time a Google Workspace user successfully signs in from a given source ASN within a 14-day historical window. Most users have a stable set of egress ASNs (home ISP, corporate VPN, mobile carrier). A new ASN for a user is a meaningful anomaly as it surfaces ISP changes and travel, but also catches AiTM phishing-kit relays whose egress ASN was never previously associated with the user.
Known False Positives
- Legitimate first-time use of a new network: ISP change, new VPN provider, travel to a region using a different mobile carrier, new home office.
- Carrier-grade NAT or load-balanced corporate egress that occasionally routes through alternate ASNs.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Credential Access |
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
- First Time Seen Google Workspace OAuth Login from Third-Party Application (Elastic)
- GCP Successful Single-Factor Authentication (Splunk)
- Google Workspace Device Registration After OAuth from Suspicious ASN (Elastic)
- Google Workspace OAuth Token Requests from New IP (Panther)
- Google Workspace OAuth Token Requests from New IPs (Panther)
- Google Workspace Object Copied from External Drive with App Consent (Elastic)
- Google Workspace Rapid Multi-IP Authentication (Panther)
- Google Workspace Rapid Multi-IP Authentication (Panther)
Rule Body
[metadata]
creation_date = "2026/05/14"
integration = ["google_workspace"]
maturity = "production"
updated_date = "2026/05/14"
[rule]
author = ["Elastic"]
description = """
Detects the first time a Google Workspace user successfully signs in from a given source ASN within a 14-day historical
window. Most users have a stable set of egress ASNs (home ISP, corporate VPN, mobile carrier). A new ASN for a user is a
meaningful anomaly as it surfaces ISP changes and travel, but also catches AiTM phishing-kit relays whose egress ASN was
never previously associated with the user.
"""
false_positives = [
"""
Legitimate first-time use of a new network: ISP change, new VPN provider, travel to a region using a different
mobile carrier, new home office.
""",
"""
Carrier-grade NAT or load-balanced corporate egress that occasionally routes through alternate ASNs.
"""
]
from = "now-130m"
index = ["logs-google_workspace.login*", "logs-google_workspace.token*"]
interval = "10m"
language = "kuery"
license = "Elastic License v2"
name = "Google Workspace User Login with Unusual ASN"
note = """## Triage and analysis
### Investigating Google Workspace User Login with Unusual ASN
This rule emits when a user signs in successfully from an ASN that has not been observed for that user in the prior 14 days. Most legitimate users cluster around a small number of egress ASNs (corporate VPN, home ISP, primary mobile carrier). New ASNs are not all malicious, but new ASNs that match hosting providers, anonymization networks, or geographies inconsistent with the user's profile are high-fidelity suspicious.
### Possible investigation steps
- Inspect `source.as.organization.name` and `source.as.number`. Categorize: residential ISP (low concern absent other indicators), corporate VPN (validate against tenant baseline), mobile carrier (validate by region), hosting provider / VPS (Clouvider, Host Telecom, Alibaba, OVH, M247, DigitalOcean, Vultr) - high concern for interactive sign-ins.
- Inspect `source.geo.country_name` and `source.geo.region_name`. New geo + known travel is fine. New geo + unexpected travel needs user confirmation.
- Pull the user's full `google_workspace.login` history across the lookback. Is this a one-off sign-in or sustained activity from the new ASN?
- Cross-reference `logs-google_workspace.token` for any `event.action: "authorize"` events from the same `user.email` immediately following the sign-in. An OAuth grant minted from the new ASN within seconds of sign-in is the AiTM kit signature.
- Cross-reference `logs-google_workspace.device` for any `DEVICE_REGISTER_UNREGISTER_EVENT` with `account_state: "REGISTERED"` from the same user near the same time. New device + new ASN is a stronger compromise signal than either alone.
- Confirm with the user whether they signed in from a new network intentionally.
### False positive analysis
- Users on rotating VPN exits, hotspot sharing, or coffee-shop Wi-Fi will produce new ASNs legitimately.
- Mobile users in unfamiliar regions (travel, conference attendance) will geo-resolve to new ASNs.
- Engineering teams using cloud workstations (Cloud Workstations, Codespaces, etc.) will egress through hosting ASNs even for legitimate sign-ins. Tune by allowlisting your tenant's known cloud-workstation egress.
- For high-noise tenants, expand `history_window_start` to 14 days to reduce false-positive rate at the cost of slower-to-fire detection for genuinely new ASNs.
### Response and remediation
- If the new ASN is a hosting provider and the user has not knowingly used such a network: treat as likely AiTM. Suspend user, revoke OAuth tokens, reset password, clear recovery info, sign out all sessions.
- If the new ASN is benign (verified ISP change, travel, new VPN): add to the user's baseline. Consider broader hardening (require MFA re-verification on new-network sign-in via Workspace Context-Aware Access).
"""
references = [
"https://any.run/malware-trends/tycoon/",
"https://www.elastic.co/security-labs/google-workspace-attack-surface-part-one",
]
risk_score = 21
rule_id = "1f489c86-d9c4-40de-9316-931721ca9b45"
setup = """## Setup
### Important Information Regarding Google Workspace Event Lag Times
- Google Workspace Reports API ingestion lag commonly runs in the 30-minute to 3-hour range. This rule's 130-minute lookback gives partial coverage but will miss events delayed beyond that envelope.
- See https://support.google.com/a/answer/7061566 for Google's published guidance on event availability.
- Check your integration's Login lag time to ensure it is configured to meet the needs of this rule.
"""
severity = "low"
tags = [
"Domain: Cloud",
"Domain: Identity",
"Data Source: Google Workspace",
"Data Source: Google Workspace Audit Logs",
"Data Source: Google Workspace User Log Events",
"Use Case: Threat Detection",
"Use Case: Identity and Access Audit",
"Tactic: Initial Access",
"Tactic: Credential Access",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
data_stream.dataset: ("google_workspace.login" or "google_workspace.token") and
event.action: ("login_success" or "authorize") and
source.as.number: * and
user.email: *
'''
[[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 = "T1528"
name = "Steal Application Access Token"
reference = "https://attack.mitre.org/techniques/T1528/"
[[rule.threat.technique]]
id = "T1557"
name = "Adversary-in-the-Middle"
reference = "https://attack.mitre.org/techniques/T1557/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[rule.investigation_fields]
field_names = [
"@timestamp",
"user.email",
"user.name",
"source.ip",
"source.as.number",
"source.as.organization.name",
"source.geo.country_name",
"source.geo.region_name",
"google_workspace.login.type",
"google_workspace.login.challenge_method",
]
[rule.new_terms]
field = "new_terms_fields"
value = ["user.email", "source.as.number"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-7d"
Stages and Predicates
Stage 1: new_terms
data_stream.dataset: ("google_workspace.login" or "google_workspace.token") and
event.action: ("login_success" or "authorize") and
source.as.number: * and
user.email: *
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | in |
| field:"data_stream.dataset" kind:in |
event.action | in |
| field:"EventType" kind:in |
source.as.number | is_not_null | field:"source.as.number" kind:is_not_null | |
user.email | is_not_null | field:"user.email" kind:is_not_null |
Keystrokes Input Capture from a Suspicious Module
#Identifies attempts to enumerate the state of keyboard keys and the call is coming from Python, AutoIt, NodeJs or LUA libraries. Adversaries may log user keystrokes to intercept credentials or other information from the user as the user types them.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Collection |
Rule Body
[rule]
description = """
Identifies attempts to enumerate the state of keyboard keys and the call is coming from Python, AutoIt, NodeJs or LUA
libraries. Adversaries may log user keystrokes to intercept credentials or other information from the user as the user
types them.
"""
id = "ca00acf2-6e1b-4823-8fdd-7339ffa7079f"
license = "Elastic License v2"
name = "Keystrokes Input Capture from a Suspicious Module"
os_list = ["windows"]
reference = [
"https://attack.mitre.org/techniques/T1056/001/",
"https://www.elastic.co/security-labs/protecting-your-devices-from-information-theft-keylogger-protection",
]
version = "1.0.9"
query = '''
api where process.executable != null and
(
(process.Ext.api.name == "GetAsyncKeyState" and process.Ext.api.metadata.background_callcount >= 400 and
process.Ext.api.metadata.ms_since_last_keyevent >= 100) or
(process.Ext.api.name == "SetWindowsHookEx" and process.Ext.api.parameters.hook_type == "WH_KEYBOARD_LL")
) and
(
process.thread.Ext.call_stack_final_user_module.name : ("libffi*.dll", "python*.dll", "luacom.dll", "lua?.?.dll", "lua??.dll") or
process.code_signature.subject_name in ("AutoIt Consulting Ltd", "OpenJS Foundation")
) and
not (process.code_signature.subject_name == "NV Access Limited" and process.code_signature.trusted == true) and
not process.executable : ("C:\\Program Files\\Python39\\pythonw.exe", "C:\\Program Files\\WSL\\msrdc.exe") and
not process.thread.Ext.call_stack_final_user_module.hash.sha256 in ("eff52743773eb550fcc6ce3efc37c85724502233b6b002a35496d828bd7b280a", "0817a2a657a24c0d5fbb60df56960f42fc66b3039d522ec952dab83e2d869364", "f60dd9f2fcbd495674dfc1555effb710eb081fc7d4cae5fa58c438ab50405081")
'''
min_endpoint_version = "8.12.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 = "T1056"
name = "Input Capture"
reference = "https://attack.mitre.org/techniques/T1056/"
[[threat.technique.subtechnique]]
id = "T1056.001"
name = "Keylogging"
reference = "https://attack.mitre.org/techniques/T1056/001/"
[threat.tactic]
id = "TA0009"
name = "Collection"
reference = "https://attack.mitre.org/tactics/TA0009/"
[internal]
min_endpoint_version = "8.12.0"
Stages and Predicates
Stage 1: api
api where process.executable != null and
(
(process.Ext.api.name == "GetAsyncKeyState" and process.Ext.api.metadata.background_callcount >= 400 and
process.Ext.api.metadata.ms_since_last_keyevent >= 100) or
(process.Ext.api.name == "SetWindowsHookEx" and process.Ext.api.parameters.hook_type == "WH_KEYBOARD_LL")
) and
(
process.thread.Ext.call_stack_final_user_module.name : ("libffi*.dll", "python*.dll", "luacom.dll", "lua?.?.dll", "lua??.dll") or
process.code_signature.subject_name in ("AutoIt Consulting Ltd", "OpenJS Foundation")
) and
not (process.code_signature.subject_name == "NV Access Limited" and process.code_signature.trusted == true) and
not process.executable : ("C:\\Program Files\\Python39\\pythonw.exe", "C:\\Program Files\\WSL\\msrdc.exe") and
not process.thread.Ext.call_stack_final_user_module.hash.sha256 in ("eff52743773eb550fcc6ce3efc37c85724502233b6b002a35496d828bd7b280a", "0817a2a657a24c0d5fbb60df56960f42fc66b3039d522ec952dab83e2d869364", "f60dd9f2fcbd495674dfc1555effb710eb081fc7d4cae5fa58c438ab50405081")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
process.Ext.api.metadata.background_callcount | ge |
| field:"process.Ext.api.metadata.background_callcount" kind:ge value:"400" |
process.Ext.api.metadata.ms_since_last_keyevent | ge |
| field:"process.Ext.api.metadata.ms_since_last_keyevent" kind:ge value:"100" |
process.Ext.api.name | eq |
| field:"process.Ext.api.name" kind:eq |
process.Ext.api.parameters.hook_type | eq |
| field:"process.Ext.api.parameters.hook_type" kind:eq value:"WH_KEYBOARD_LL" |
process.code_signature.subject_name | in |
| field:"Signature" kind:in |
process.executable | is_not_null | field:"Image" kind:is_not_null | |
process.thread.Ext.call_stack_final_user_module.name | wildcard |
| field:"process.thread.Ext.call_stack_final_user_module.name" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
Kill Command Execution
#This rule detects the execution of kill, pkill, and killall commands on Linux systems. These commands are used to terminate processes on a system. Attackers may use these commands to kill security tools or other processes to evade detection or disrupt system operations.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Stealth | |
| Defense Impairment | |
| Impact |
Rule Body
[metadata]
creation_date = "2025/02/21"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
This rule detects the execution of kill, pkill, and killall commands on Linux systems. These commands are used to terminate
processes on a system. Attackers may use these commands to kill security tools or other processes to evade detection or
disrupt system operations.
"""
from = "now-9m"
index = ["logs-endpoint.events.process*"]
language = "kuery"
license = "Elastic License v2"
name = "Kill Command Execution"
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 Kill Command Execution
In Linux environments, commands like kill, pkill, and killall are essential for managing processes, allowing users to terminate them as needed. However, adversaries can exploit these commands to disable security tools or disrupt operations, aiding in evasion tactics. The detection rule identifies such misuse by monitoring process execution events, specifically targeting these commands to flag potential threats.
### Possible investigation steps
- Review the process execution event details to identify the user account associated with the kill, pkill, or killall command execution. This can help determine if the action was performed by a legitimate user or a potential adversary.
- Examine the parent process of the command execution to understand the context in which the kill command was initiated. This can provide insights into whether the command was part of a script or an interactive session.
- Check the target process IDs (PIDs) that were terminated by the kill command to assess if critical or security-related processes were affected, which might indicate malicious intent.
- Investigate the timing and frequency of the command execution to identify patterns or anomalies, such as repeated or scheduled executions, which could suggest automated or scripted activity.
- Correlate the event with other security alerts or logs from the same host around the same timeframe to identify any related suspicious activities or indicators of compromise.
### False positive analysis
- Routine system maintenance tasks may trigger the rule when administrators use kill commands to manage processes. To handle this, create exceptions for known maintenance scripts or processes by identifying their unique attributes, such as user or command line arguments.
- Automated scripts or monitoring tools that use kill commands for legitimate purposes, like restarting services, can cause false positives. Exclude these by specifying the script names or paths in the detection rule.
- Development environments where developers frequently use kill commands during testing can lead to alerts. Consider excluding processes executed by specific user accounts associated with development activities.
- System updates or package management tools might use kill commands as part of their operation. Identify these processes and exclude them based on their parent process or command line patterns.
- Backup or recovery operations that involve stopping services may trigger the rule. Exclude these by recognizing the specific backup software or service names involved.
### Response and remediation
- Immediately isolate the affected Linux system from the network to prevent further malicious activity or lateral movement by the attacker.
- Identify and terminate any unauthorized or suspicious processes that were started around the time of the alert, focusing on those that may have been targeted by the kill, pkill, or killall commands.
- Review system logs and process execution history to determine the origin of the kill command execution and assess whether it was initiated by a legitimate user or a compromised account.
- Restore any terminated security tools or critical processes to ensure the system's defenses are fully operational.
- Conduct a thorough scan of the affected system using updated antivirus or endpoint detection tools to identify and remove any additional malware or persistence mechanisms.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if other systems may be affected.
- Implement additional monitoring and alerting for similar command executions across the network to enhance detection and response capabilities for future incidents.
"""
risk_score = 21
rule_id = "f391d3fd-219b-42a3-9ba9-2f66eb0155aa"
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: Defense Evasion",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
event.category:process and host.os.type:linux and event.type:start and event.action:exec and
process.name:(kill or pkill or killall) and not (
process.args:("-HUP" or "-SIGUSR1" or "-USR2" or "-WINCH" or "-USR1") or
process.parent.command_line:"runc init" or
process.parent.executable:(
"/usr/lib/systemd/systemd" or "/usr/local/qualys/cloud-agent/bin/qualys-cloud-agent" or "/bin/xargs" or
"/usr/bin/xargs" or "/usr/bin/sudo" or "/usr/sbin/safe_asterisk" or "/usr/local/manageengine/uems_agent/bin/dcservice" or
"/lib/systemd/systemd" or "/opt/nessus_agent/sbin/nessuscli" or "/etc/rubrik/start_stop_bootstrap.sh" or
"/usr/local/manageengine/uems_agent/bin/dcpatchscan")
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[[rule.threat.technique.subtechnique]]
id = "T1562.001"
name = "Disable or Modify Tools"
reference = "https://attack.mitre.org/techniques/T1562/001/"
[[rule.threat.technique.subtechnique]]
id = "T1562.006"
name = "Indicator Blocking"
reference = "https://attack.mitre.org/techniques/T1562/006/"
[[rule.threat.technique]]
id = "T1564"
name = "Hide Artifacts"
reference = "https://attack.mitre.org/techniques/T1564/"
[[rule.threat.technique.subtechnique]]
id = "T1564.001"
name = "Hidden Files and Directories"
reference = "https://attack.mitre.org/techniques/T1564/001/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.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 = "T1489"
name = "Service Stop"
reference = "https://attack.mitre.org/techniques/T1489/"
[rule.threat.tactic]
id = "TA0040"
name = "Impact"
reference = "https://attack.mitre.org/tactics/TA0040/"
[rule.new_terms]
field = "new_terms_fields"
value = ["host.id", "process.parent.executable"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-5d"
Stages and Predicates
Stage 1: new_terms
event.category:process and host.os.type:linux and event.type:start and event.action:exec and
process.name:(kill or pkill or killall) and not (
process.args:("-HUP" or "-SIGUSR1" or "-USR2" or "-WINCH" or "-USR1") or
process.parent.command_line:"runc init" or
process.parent.executable:(
"/usr/lib/systemd/systemd" or "/usr/local/qualys/cloud-agent/bin/qualys-cloud-agent" or "/bin/xargs" or
"/usr/bin/xargs" or "/usr/bin/sudo" or "/usr/sbin/safe_asterisk" or "/usr/local/manageengine/uems_agent/bin/dcservice" or
"/lib/systemd/systemd" or "/opt/nessus_agent/sbin/nessuscli" or "/etc/rubrik/start_stop_bootstrap.sh" or
"/usr/local/manageengine/uems_agent/bin/dcpatchscan")
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.category | eq |
| field:"event.category" kind:eq value:"process" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.name | in |
| field:"process_basename" kind:in |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | in | -HUP, -SIGUSR1, -USR1, -USR2, -WINCH | excludes:process.args |
process.parent.command_line | eq | runc init | excludes:process.parent.command_line field:"process.parent.command_line" value:"runc init" |
process.parent.executable | in | /bin/xargs, /etc/rubrik/start_stop_bootstrap.sh, /lib/systemd/systemd, /opt/nessus_agent/sbin/nessuscli, /usr/bin/sudo, /usr/bin/xargs, /usr/lib/systemd/systemd, /usr/local/manageengine/uems_agent/bin/dcpatchscan, /usr/local/manageengine/uems_agent/bin/dcservice, /usr/local/qualys/cloud-agent/bin/qualys-cloud-agent, /usr/sbin/safe_asterisk | excludes:process.parent.executable |
M365 Defender Alerts Signal (UAL)
#Identifies alerts generated by Microsoft Defender products including Windows Defender for Endpoint (WDATP), Microsoft Cloud App Security (MCAS), Microsoft Defender for Identity, Microsoft 365 Defender custom detections, and Defender Experts for XDR via M365 Unified Audit Logs (UAL). These cross-platform alerts indicate detected threats across endpoints, cloud applications, and identity systems. This building block rule generates security events for correlation, threat hunting, and telemetry collection to support comprehensive threat detection.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | No specific technique |
| Execution | No specific technique |
| Stealth | No specific technique |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Microsoft 365 | any: Microsoft Defender for Cloud Apps alert events (catch-all) |
Rule Body
[metadata]
bypass_bbr_timing = true
creation_date = "2026/02/20"
integration = ["o365"]
maturity = "production"
updated_date = "2026/06/30"
[rule]
author = ["Elastic"]
building_block_type = "default"
description = """
Identifies alerts generated by Microsoft Defender products including Windows Defender for Endpoint (WDATP), Microsoft
Cloud App Security (MCAS), Microsoft Defender for Identity, Microsoft 365 Defender custom detections, and Defender
Experts for XDR via M365 Unified Audit Logs (UAL). These cross-platform alerts indicate detected threats across
endpoints, cloud applications, and identity systems. This building block rule generates security events for correlation,
threat hunting, and telemetry collection to support comprehensive threat detection.
"""
from = "now-9m"
index = ["logs-o365.audit-*"]
language = "kuery"
license = "Elastic License v2"
name = "M365 Defender Alerts Signal (UAL)"
note = """## Triage and analysis
This rule identifies Microsoft Defender alerts forwarded through the Microsoft 365 Unified Audit Log (`logs-o365.audit-*`). For alerts and incidents ingested directly from the Microsoft Defender XDR integration data streams (`logs-m365_defender.alert-*` and `logs-m365_defender.incident-*`), enable the corresponding promotion rules instead:
- Microsoft Defender XDR Alert External Alerts (rule_id: c2a0e42b-ac3d-468f-82a5-0082066e1b59)
- Microsoft Defender XDR Incident External Alerts (rule_id: 3c99579e-6491-4562-87f4-4d10f0a822b4)
"""
references = [
"https://learn.microsoft.com/en-us/defender-endpoint/",
"https://learn.microsoft.com/en-us/defender-cloud-apps/",
"https://learn.microsoft.com/en-us/defender-for-identity/",
"https://learn.microsoft.com/en-us/office/office-365-management-api/office-365-management-activity-api-schema#enum-auditlogrecordtype---type-edmint32",
]
risk_score = 47
rule_id = "054853f3-2ce0-41f3-a6eb-4a4867f39cdc"
setup = """### 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 = [
"Domain: Cloud",
"Domain: SaaS",
"Domain: Endpoint",
"Data Source: Microsoft 365",
"Data Source: Microsoft 365 Audit Logs",
"Data Source: Microsoft Defender XDR",
"Data Source: Microsoft Defender for Cloud Apps",
"Data Source: Microsoft Defender for Identity",
"Use Case: Threat Detection",
"Tactic: Initial Access",
"Tactic: Execution",
"Tactic: Defense Evasion",
"Rule Type: BBR",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
event.dataset:o365.audit and
event.code:(WDATPAlerts or MCASAlerts or MicrosoftDefenderForIdentityAudit or MS365DCustomDetection or DefenderExpertsforXDRAdmin)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Stage 1: query
event.dataset:o365.audit and
event.code:(WDATPAlerts or MCASAlerts or MicrosoftDefenderForIdentityAudit or MS365DCustomDetection or DefenderExpertsforXDRAdmin)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.code | in |
| field:"EventID" kind:in |
event.dataset | eq |
| field:"event.dataset" kind:eq value:"o365.audit" |
Okta Sign-In Events via Third-Party IdP
#Detects sign-in events where authentication is carried out via a third-party Identity Provider (IdP) that has not been seen before. Adversaries may add an unauthorized IdP to an Okta tenant to gain persistent access. This rule uses New Terms detection to only alert when a previously unseen IdP is used for authentication, reducing noise from legitimate federated identity providers while highlighting potentially rogue IdP additions.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Persistence |
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
- Okta Identity Provider Sign-in (Panther)
Rule Body
[metadata]
creation_date = "2023/11/06"
integration = ["okta"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
Detects sign-in events where authentication is carried out via a third-party Identity Provider (IdP) that has not been
seen before. Adversaries may add an unauthorized IdP to an Okta tenant to gain persistent access. This rule uses New
Terms detection to only alert when a previously unseen IdP is used for authentication, reducing noise from legitimate
federated identity providers while highlighting potentially rogue IdP additions.
"""
from = "now-9m"
index = ["logs-okta.system-*"]
language = "kuery"
license = "Elastic License v2"
name = "Okta Sign-In Events via Third-Party IdP"
note = """## Triage and analysis
### Investigating Okta Sign-In Events via Third-Party IdP
This rule detects sign-in events where authentication is carried out via a third-party Identity Provider (IdP).
Adversaries may attempt to add an unauthorized IdP to an Okta tenant to gain access to the tenant. Following this action, adversaries may attempt to sign in to the tenant using the unauthorized IdP. This rule detects both the addition of an unauthorized IdP and the subsequent sign-in attempt.
#### Possible investigation steps:
- Identify the third-party IdP by examining the `okta.authentication_context.issuer.id` field.
- Once the third-party IdP is identified, determine if this IdP is authorized to be used by the tenant.
- If the IdP is unauthorized, deactivate it immediately via the Okta console.
- Identify the actor associated with the IdP creation by examining the `okta.actor.id`, `okta.actor.type`, `okta.actor.alternate_id`, and `okta.actor.display_name` fields in historical data.
- The `New Okta Identity Provider (IdP) Added by Admin` rule may be helpful in identifying the actor and the IdP creation event.
- Determine the client used by the actor. Review the `okta.client.ip`, `okta.client.user_agent.raw_user_agent`, `okta.client.zone`, `okta.client.device`, and `okta.client.id` fields.
- If the client is a device, check the `okta.device.id`, `okta.device.name`, `okta.device.os_platform`, `okta.device.os_version`, and `okta.device.managed` fields.
- Review the past activities of the actor involved in this action by checking their previous actions logged in the `okta.target` field.
- Examine the `okta.request.ip_chain` field to potentially determine if the actor used a proxy or VPN to perform this action.
- Evaluate the actions that happened just before and after this event in the `okta.event_type` field to help understand the full context of the activity.
### False positive analysis:
- It might be a false positive if this IdP is authorized to be used by the tenant.
- This may be a false positive if an authorized third-party IdP is used to sign in to the tenant but failures occurred due to an incorrect configuration.
### Response and remediation:
- If the IdP is unauthorized, deactivate it immediately via the Okta console.
- Reset the effected user's password and enforce MFA re-enrollment, if applicable.
- Mobile device forensics may be required to determine if the user's device is compromised.
- If the IdP is authorized, ensure that the actor who created it is authorized to do so.
- If the actor is unauthorized, deactivate their account via the Okta console.
- If the actor is authorized, ensure that the actor's account is not compromised.
- Block the IP address or device used in the attempts if they appear suspicious, using the data from the `okta.client.ip` and `okta.device.id` fields.
- Conduct a review of Okta policies and ensure they are in accordance with security best practices.
- If the deactivated IdP was crucial to the organization, consider adding a new IdP and removing the unauthorized IdP.
## Setup
The Okta Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.
"""
references = [
"https://blog.cloudflare.com/cloudflare-investigation-of-the-january-2022-okta-compromise/",
"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://unit42.paloaltonetworks.com/muddled-libra/",
"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 = 47
rule_id = "1ceb05c4-7d25-11ee-9562-f661ea17fbcd"
severity = "medium"
tags = [
"Domain: Identity",
"Use Case: Identity and Access Audit",
"Tactic: Initial Access",
"Data Source: Okta",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
data_stream.dataset: "okta.system"
and okta.authentication_context.issuer.id: (* and not "Okta")
and (
event.action: (
"user.authentication.auth_via_IDP"
or "user.authentication.auth_via_inbound_SAML"
or "user.authentication.auth_via_social"
)
or (
event.action: "user.authentication.auth_via_IDP"
and okta.outcome.result: "FAILURE"
and okta.outcome.reason: (
"A SAML assert with the same ID has already been processed by Okta for a previous request"
or "Unable to match transformed username"
or "Unable to resolve IdP endpoint"
or "Unable to validate SAML Response"
or "Unable to validate incoming SAML Assertion"
)
)
)
'''
[rule.new_terms]
field = "new_terms_fields"
value = ["okta.authentication_context.issuer.id"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-5d"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1199"
name = "Trusted Relationship"
reference = "https://attack.mitre.org/techniques/T1199/"
[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.subtechnique]]
id = "T1078.004"
name = "Cloud Accounts"
reference = "https://attack.mitre.org/techniques/T1078/004/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
Stages and Predicates
Stage 1: new_terms
data_stream.dataset: "okta.system"
and okta.authentication_context.issuer.id: (* and not "Okta")
and (
event.action: (
"user.authentication.auth_via_IDP"
or "user.authentication.auth_via_inbound_SAML"
or "user.authentication.auth_via_social"
)
or (
event.action: "user.authentication.auth_via_IDP"
and okta.outcome.result: "FAILURE"
and okta.outcome.reason: (
"A SAML assert with the same ID has already been processed by Okta for a previous request"
or "Unable to match transformed username"
or "Unable to resolve IdP endpoint"
or "Unable to validate SAML Response"
or "Unable to validate incoming SAML Assertion"
)
)
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"okta.system" |
event.action | eq |
| field:"EventType" kind:eq value:"user.authentication.auth_via_IDP" |
event.action | in |
| field:"EventType" kind:in |
okta.authentication_context.issuer.id | is_not_null | field:"okta.authentication_context.issuer.id" kind:is_not_null | |
okta.outcome.reason | in |
| field:"okta::outcome.reason" kind:in |
okta.outcome.result | eq |
| field:"okta::outcome.result" kind:eq value:"FAILURE" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
okta.authentication_context.issuer.id | eq | Okta | excludes:okta.authentication_context.issuer.id field:"okta.authentication_context.issuer.id" value:"Okta" |
Okta Successful Login After Credential Attack
#Correlates Okta credential attack alerts with subsequent successful authentication for the same user account, identifying potential compromise following brute force, password spray, or credential stuffing attempts.
Known False Positives
- A user experiencing legitimate login issues (forgotten password, typos) may trigger credential attack alerts before successfully authenticating.
- Automated password reset flows where a user fails multiple times then succeeds after resetting their password.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Credential Access |
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
- Failed Logins from Unknown or Invalid User (Kusto)
- First Occurrence of Okta User Session Started via Proxy (Elastic)
- High-Risk Admin Activity (Kusto)
- Multiple Okta Sessions Detected for a Single User (Elastic)
- Multiple Okta User Authentication Events with Same Device Token Hash (Elastic)
- New Device/Location sign-in along with critical operation (Kusto)
- Okta AiTM Session Cookie Replay (Elastic)
- Okta Login From CrowdStrike Unmanaged Device (Panther)
Rule Body
[metadata]
creation_date = "2026/02/12"
integration = ["okta"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
Correlates Okta credential attack alerts with subsequent successful authentication for the same user account,
identifying potential compromise following brute force, password spray, or credential stuffing attempts.
"""
false_positives = [
"A user experiencing legitimate login issues (forgotten password, typos) may trigger credential attack alerts before successfully authenticating.",
"Automated password reset flows where a user fails multiple times then succeeds after resetting their password.",
]
from = "now-6h"
interval = "30m"
language = "esql"
license = "Elastic License v2"
name = "Okta Successful Login After Credential Attack"
note = """## Triage and analysis
### Investigating Okta Successful Login After Credential Attack
This rule correlates credential attack alerts with subsequent successful authentication for the same user account. The correlation is user-centric, capturing IP rotation scenarios where attackers may login from a different IP after obtaining credentials.
#### Possible investigation steps
- Identify the user account and review the timeline between the attack and successful login.
- Compare the attack source IPs versus the login source IP to identify potential IP rotation.
- Review the original credential attack alert to understand the scope and nature of the attack.
- Check the authentication method used and whether MFA was required and satisfied.
- Review the session activity following the successful login for signs of account takeover.
- Verify with the user if the login was legitimate.
### False positive analysis
- Users experiencing legitimate login issues may trigger attack alerts before successfully authenticating.
- Automated password reset flows where a user fails multiple times then succeeds after resetting may trigger this rule.
- The rule correlates on user identity only, so it fires when a user is targeted and later logs in, even if from different IPs.
### Response and remediation
- If compromise is suspected, reset the user's password and revoke all active sessions.
- Reset MFA if the attacker may have enrolled their own device.
- Block the source IP at the network perimeter.
- Review the user's recent activity for signs of lateral movement or data access.
- Check for persistence mechanisms such as new OAuth apps, API tokens, or enrolled devices.
"""
references = [
"https://support.okta.com/help/s/article/Troubleshooting-Distributed-Brute-Force-andor-Password-Spray-attacks-in-Okta",
"https://www.okta.com/identity-101/brute-force/",
"https://developer.okta.com/docs/reference/api/system-log/",
"https://developer.okta.com/docs/reference/api/event-types/",
"https://www.elastic.co/security-labs/testing-okta-visibility-and-detection-dorothy",
"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 = "50742e15-c5ef-49c8-9a2d-31221d45af58"
setup = """## Setup
This rule requires the following:
1. The Okta Fleet integration, Filebeat module, or similarly structured data for Okta System Logs.
2. The correlated credential attack detection rules must be enabled (at least one):
- Potential Okta Credential Stuffing (Single Source) (94e734c0-2cda-11ef-84e1-f661ea17fbce)
- Potential Okta Password Spray (Single Source) (42bf698b-4738-445b-8231-c834ddefd8a0)
- Potential Okta Brute Force (Device Token Rotation) (23f18264-2d6d-11ef-9413-f661ea17fbce)
- Potential Okta Brute Force (Multi-Source) (5889760c-9858-4b4b-879c-e299df493295)
- Potential Okta Password Spray (Multi-Source) (2d3c27d5-d133-4152-8102-8d051619ec4a)
3. Alerts from these rules must be written to the `.alerts-security.*` indices.
The rule queries both alert indices and Okta log indices to correlate attack alerts with successful logins."""
severity = "high"
tags = [
"Domain: Identity",
"Use Case: Identity and Access Audit",
"Use Case: Threat Detection",
"Data Source: Okta",
"Data Source: Okta System Logs",
"Tactic: Credential Access",
"Tactic: Initial Access",
"Resources: Investigation Guide",
"Rule Type: Higher-Order Rule",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
FROM .alerts-security.*, logs-okta.system-* METADATA _id, _version, _index
// Filter for credential attack alerts OR successful Okta authentications
| WHERE
(
// Credential attack alerts from the five correlated rules
kibana.alert.rule.rule_id IN (
"94e734c0-2cda-11ef-84e1-f661ea17fbce", // Credential Stuffing
"42bf698b-4738-445b-8231-c834ddefd8a0", // Password Spraying
"23f18264-2d6d-11ef-9413-f661ea17fbce", // DT Brute Force
"5889760c-9858-4b4b-879c-e299df493295", // Distributed Brute Force
"2d3c27d5-d133-4152-8102-8d051619ec4a" // Distributed Spray
)
)
OR (
// Successful Okta authentication events
data_stream.dataset == "okta.system"
AND (event.action LIKE "user.authentication.*" OR event.action == "user.session.start")
AND okta.outcome.result == "SUCCESS"
AND okta.actor.alternate_id IS NOT NULL
)
// correlation - alerts may store user/IP in different fields than raw logs
| EVAL
Esql.user = COALESCE(okta.actor.alternate_id, user.name, user.email),
Esql.source_ip = COALESCE(okta.client.ip, client.ip, source.ip)
// Must have user identity to correlate
| WHERE Esql.user IS NOT NULL
// Classify events and capture timestamps/IPs by event type
| EVAL
Esql.is_attack_alert = CASE(
kibana.alert.rule.rule_id IN (
"94e734c0-2cda-11ef-84e1-f661ea17fbce",
"42bf698b-4738-445b-8231-c834ddefd8a0",
"23f18264-2d6d-11ef-9413-f661ea17fbce",
"5889760c-9858-4b4b-879c-e299df493295",
"2d3c27d5-d133-4152-8102-8d051619ec4a"
), 1, 0
),
Esql.is_success_login = CASE(
data_stream.dataset == "okta.system"
AND okta.outcome.result == "SUCCESS", 1, 0
),
Esql.attack_ip = CASE(
kibana.alert.rule.rule_id IN (
"94e734c0-2cda-11ef-84e1-f661ea17fbce",
"42bf698b-4738-445b-8231-c834ddefd8a0",
"23f18264-2d6d-11ef-9413-f661ea17fbce",
"5889760c-9858-4b4b-879c-e299df493295",
"2d3c27d5-d133-4152-8102-8d051619ec4a"
), Esql.source_ip, null
),
Esql.login_ip = CASE(
data_stream.dataset == "okta.system"
AND okta.outcome.result == "SUCCESS", Esql.source_ip, null
),
Esql.attack_ts = CASE(
kibana.alert.rule.rule_id IN (
"94e734c0-2cda-11ef-84e1-f661ea17fbce",
"42bf698b-4738-445b-8231-c834ddefd8a0",
"23f18264-2d6d-11ef-9413-f661ea17fbce",
"5889760c-9858-4b4b-879c-e299df493295",
"2d3c27d5-d133-4152-8102-8d051619ec4a"
), @timestamp, null
),
Esql.login_ts = CASE(
data_stream.dataset == "okta.system"
AND okta.outcome.result == "SUCCESS", @timestamp, null
)
// Aggregate by user (catches IP rotation: spray from IP A, login from IP B)
| STATS
Esql.attack_count = SUM(Esql.is_attack_alert),
Esql.login_count = SUM(Esql.is_success_login),
Esql.earliest_attack = MIN(Esql.attack_ts),
Esql.latest_attack = MAX(Esql.attack_ts),
Esql.earliest_login = MIN(Esql.login_ts),
Esql.latest_login = MAX(Esql.login_ts),
Esql.attack_source_ips = VALUES(Esql.attack_ip),
Esql.login_source_ips = VALUES(Esql.login_ip),
Esql.all_source_ips = VALUES(Esql.source_ip),
Esql.alert_rule_ids = VALUES(kibana.alert.rule.rule_id),
Esql.alert_rule_names = VALUES(kibana.alert.rule.name),
Esql.event_action_values = VALUES(event.action),
Esql.geo_country_values = VALUES(client.geo.country_name),
Esql.geo_city_values = VALUES(client.geo.city_name),
Esql.source_asn_values = VALUES(source.as.number),
Esql.source_asn_org_values = VALUES(source.as.organization.name),
Esql.user_agent_values = VALUES(okta.client.user_agent.raw_user_agent),
Esql.device_values = VALUES(okta.client.device),
Esql.is_proxy_values = VALUES(okta.security_context.is_proxy)
BY Esql.user
// Calculate time gap between latest attack and earliest subsequent login
| EVAL Esql.attack_to_login_minutes = DATE_DIFF("minute", Esql.latest_attack, Esql.earliest_login)
// Correlation: attack BEFORE login + success within reasonable window (3 hours)
| WHERE
Esql.attack_count > 0
AND Esql.login_count > 0
AND Esql.latest_attack < Esql.earliest_login
AND Esql.attack_to_login_minutes <= 180
| SORT Esql.login_count DESC
| KEEP Esql.*
'''
[[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.technique.subtechnique]]
id = "T1110.003"
name = "Password Spraying"
reference = "https://attack.mitre.org/techniques/T1110/003/"
[[rule.threat.technique.subtechnique]]
id = "T1110.004"
name = "Credential Stuffing"
reference = "https://attack.mitre.org/techniques/T1110/004/"
[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: from
FROM .alerts-security.*, logs-okta.system-* METADATA _id, _version, _index
Stage 2: where
| WHERE
(
kibana.alert.rule.rule_id IN (
"94e734c0-2cda-11ef-84e1-f661ea17fbce",
"42bf698b-4738-445b-8231-c834ddefd8a0",
"23f18264-2d6d-11ef-9413-f661ea17fbce",
"5889760c-9858-4b4b-879c-e299df493295",
"2d3c27d5-d133-4152-8102-8d051619ec4a"
)
)
OR (
data_stream.dataset == "okta.system"
AND (event.action LIKE "user.authentication.*" OR event.action == "user.session.start")
AND okta.outcome.result == "SUCCESS"
AND okta.actor.alternate_id IS NOT NULL
)
Stage 3: eval
| EVAL
Esql.user = COALESCE(okta.actor.alternate_id, user.name, user.email),
Esql.source_ip = COALESCE(okta.client.ip, client.ip, source.ip)
Stage 4: where
| WHERE Esql.user IS NOT NULL
Stage 5: eval
| EVAL
Esql.is_attack_alert = CASE(
kibana.alert.rule.rule_id IN (
"94e734c0-2cda-11ef-84e1-f661ea17fbce",
"42bf698b-4738-445b-8231-c834ddefd8a0",
"23f18264-2d6d-11ef-9413-f661ea17fbce",
"5889760c-9858-4b4b-879c-e299df493295",
"2d3c27d5-d133-4152-8102-8d051619ec4a"
), 1, 0
),
Esql.is_success_login = CASE(
data_stream.dataset == "okta.system"
AND okta.outcome.result == "SUCCESS", 1, 0
),
Esql.attack_ip = CASE(
kibana.alert.rule.rule_id IN (
"94e734c0-2cda-11ef-84e1-f661ea17fbce",
"42bf698b-4738-445b-8231-c834ddefd8a0",
"23f18264-2d6d-11ef-9413-f661ea17fbce",
"5889760c-9858-4b4b-879c-e299df493295",
"2d3c27d5-d133-4152-8102-8d051619ec4a"
), Esql.source_ip, null
),
Esql.login_ip = CASE(
data_stream.dataset == "okta.system"
AND okta.outcome.result == "SUCCESS", Esql.source_ip, null
),
Esql.attack_ts = CASE(
kibana.alert.rule.rule_id IN (
"94e734c0-2cda-11ef-84e1-f661ea17fbce",
"42bf698b-4738-445b-8231-c834ddefd8a0",
"23f18264-2d6d-11ef-9413-f661ea17fbce",
"5889760c-9858-4b4b-879c-e299df493295",
"2d3c27d5-d133-4152-8102-8d051619ec4a"
), @timestamp, null
),
Esql.login_ts = CASE(
data_stream.dataset == "okta.system"
AND okta.outcome.result == "SUCCESS", @timestamp, null
)
Esql.attack_ip =kibana.alert.rule.rule_id IN (
"94e734c0-2cda-11ef-84e1-f661ea17fbce",
"42bf698b-4738-445b-8231-c834ddefd8a0",
"23f18264-2d6d-11ef-9413-f661ea17fbce",
"5889760c-9858-4b4b-879c-e299df493295",
"2d3c27d5-d133-4152-8102-8d051619ec4a"
)Esql.source_ipnullEsql.attack_ts =kibana.alert.rule.rule_id IN (
"94e734c0-2cda-11ef-84e1-f661ea17fbce",
"42bf698b-4738-445b-8231-c834ddefd8a0",
"23f18264-2d6d-11ef-9413-f661ea17fbce",
"5889760c-9858-4b4b-879c-e299df493295",
"2d3c27d5-d133-4152-8102-8d051619ec4a"
)@timestampnullEsql.is_attack_alert =kibana.alert.rule.rule_id IN (
"94e734c0-2cda-11ef-84e1-f661ea17fbce",
"42bf698b-4738-445b-8231-c834ddefd8a0",
"23f18264-2d6d-11ef-9413-f661ea17fbce",
"5889760c-9858-4b4b-879c-e299df493295",
"2d3c27d5-d133-4152-8102-8d051619ec4a"
)10Esql.is_success_login =data_stream.dataset == "okta.system"
AND okta.outcome.result == "SUCCESS"10Esql.login_ip =data_stream.dataset == "okta.system"
AND okta.outcome.result == "SUCCESS"Esql.source_ipnullEsql.login_ts =data_stream.dataset == "okta.system"
AND okta.outcome.result == "SUCCESS"@timestampnullStage 6: stats
| STATS
Esql.attack_count = SUM(Esql.is_attack_alert),
Esql.login_count = SUM(Esql.is_success_login),
Esql.earliest_attack = MIN(Esql.attack_ts),
Esql.latest_attack = MAX(Esql.attack_ts),
Esql.earliest_login = MIN(Esql.login_ts),
Esql.latest_login = MAX(Esql.login_ts),
Esql.attack_source_ips = VALUES(Esql.attack_ip),
Esql.login_source_ips = VALUES(Esql.login_ip),
Esql.all_source_ips = VALUES(Esql.source_ip),
Esql.alert_rule_ids = VALUES(kibana.alert.rule.rule_id),
Esql.alert_rule_names = VALUES(kibana.alert.rule.name),
Esql.event_action_values = VALUES(event.action),
Esql.geo_country_values = VALUES(client.geo.country_name),
Esql.geo_city_values = VALUES(client.geo.city_name),
Esql.source_asn_values = VALUES(source.as.number),
Esql.source_asn_org_values = VALUES(source.as.organization.name),
Esql.user_agent_values = VALUES(okta.client.user_agent.raw_user_agent),
Esql.device_values = VALUES(okta.client.device),
Esql.is_proxy_values = VALUES(okta.security_context.is_proxy)
BY Esql.user
Stage 7: eval
| EVAL Esql.attack_to_login_minutes = DATE_DIFF("minute", Esql.latest_attack, Esql.earliest_login)
Stage 8: where
| WHERE
Esql.attack_count > 0
AND Esql.login_count > 0
AND Esql.latest_attack < Esql.earliest_login
AND Esql.attack_to_login_minutes <= 180
Stage 9: sort
| SORT Esql.login_count DESC
Stage 10: keep
| KEEP Esql.*
Indicators
These rows show field, operator, and value matches.
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Esql.* | KEEP Esql.* |
OpenSSL Reverse Shell Activity via Named Pipe
#This rule detects the execution of a named pipe, followed by a network connection initiated by the openssl process. Attackers may use openssl to establish a reverse connection.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Command & Control |
Rule Body
[rule]
description = """
This rule detects the execution of a named pipe, followed by a network connection initiated by the openssl process.
Attackers may use openssl to establish a reverse connection.
"""
id = "a62907d2-673a-4d64-99c0-34b6ed0c8b32"
license = "Elastic License v2"
name = "OpenSSL Reverse Shell Activity via Named Pipe"
os_list = ["linux"]
version = "1.0.4"
query = '''
sequence by process.parent.entity_id with maxspan=10s
[process where event.type == "start" and event.action == "exec" and process.name in ("mkfifo", "mknod")]
[network where event.type == "start" and event.action == "connection_attempted" and process.name == "openssl"]
'''
min_endpoint_version = "8.6.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1
tree = true
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
tree = true
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 1
tree = true
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "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 = "8.6.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 10s, correlated by process.parent.entity_id.
Stage 1: process
[process where event.type == "start" and event.action == "exec" and process.name in ("mkfifo", "mknod")]
Stage 2: network
[network where event.type == "start" and event.action == "connection_attempted" and process.name == "openssl"]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.name | eq |
| field:"process_basename" kind:eq value:"openssl" |
process.name | in |
| field:"process_basename" kind:in |
Potential LSASS Clone Creation via PssCaptureSnapShot
#Identifies the creation of an LSASS process clone via PssCaptureSnapShot where the parent process is the initial LSASS process instance. This may indicate an attempt to evade detection and dump LSASS memory for credential access.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Security-Auditing | Event ID 4688: A new process has been created. |
Rule Body
[metadata]
creation_date = "2021/11/27"
integration = ["windows", "system"]
maturity = "production"
updated_date = "2026/04/27"
[rule]
author = ["Elastic"]
description = """
Identifies the creation of an LSASS process clone via PssCaptureSnapShot where the parent process is the initial LSASS
process instance. This may indicate an attempt to evade detection and dump LSASS memory for credential access.
"""
from = "now-9m"
index = ["logs-system.security*", "logs-windows.forwarded*", "winlogbeat-*"]
language = "eql"
license = "Elastic License v2"
name = "Potential LSASS Clone Creation via PssCaptureSnapShot"
references = [
"https://www.matteomalvica.com/blog/2019/12/02/win-defender-atp-cred-bypass/",
"https://medium.com/@Achilles8284/the-birth-of-a-process-part-2-97c6fb9c42a2",
]
risk_score = 73
rule_id = "a16612dd-b30e-4d41-86a0-ebe70974ec00"
severity = "high"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Credential Access",
"Data Source: Windows Security Event Logs",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "windows" and event.code:"4688" and
process.executable : "?:\\Windows\\System32\\lsass.exe" and
process.parent.executable : "?:\\Windows\\System32\\lsass.exe"
'''
note = """## Triage and analysis
### Investigating Potential LSASS Clone Creation via PssCaptureSnapShot
#### Possible investigation steps
- Does the alert-local 4688 event show the LSASS-clone pattern?
- Focus: `event.code`, `process.executable`, `process.parent.executable`, `host.id`, `@timestamp`.
- Implication: treat the alert as clone creation when both paths resolve to lsass.exe on one host; lower suspicion only when the tuple maps to stable EDR, forensic, or debugging workflow.
- Hint: pivot with `host.id` plus `process.entity_id`; if absent, use `host.id`, `process.pid`, and a tight alert-time window.
- Do surrounding 4688 events reveal the setup or dump-conversion chain?
- Focus: same-host 4688 around `@timestamp`, especially `process.executable`, `process.command_line`, `process.parent.executable`, `user.id`, and terms such as "PssCaptureSnapshot", "MiniDumpWriteDump", "comsvcs", "rundll32", "WerFault", "procdump", "createdump", archive utilities, or cleanup commands. $investigate_0
- Implication: escalate when shells, PowerShell, dump helpers, archive tools, cleanup, or remote-admin launchers appear without the same recognized collection workflow; absence of helpers leaves the clone unresolved, not benign.
- If file telemetry exists, did the clone create dumps, archives, or renamed outputs?
- Focus: same-host file or child-process telemetry for `file.path`, `file.Ext.original.path` matching ".dmp", ".zip", ".7z", or renamed outputs. $investigate_1. If unavailable, use surrounding 4688 commands with output files or archive utilities.
- Implication: escalate when dump paths, archive names, or cleanup commands appear around clone creation. Missing file telemetry is unresolved, not benign.
- Do authentication events show follow-on remote use, explicit credentials, or unusual logons?
- Why: clone creation often precedes credential use; later auth can show post-dump pivoting.
- Focus: same-host 4624, 4648, and 4625 around `@timestamp`, using `winlog.event_data.TargetUserName`, `winlog.logon.type`, and `source.ip`. $investigate_2
- Implication: escalate when the host or user quickly shows new remote-interactive, service, or explicit-credential logons from unusual sources. If auth telemetry is missing, record the gap and keep the finding unresolved.
- Does same-user or same-host activity repeat the evidence pattern?
- Focus: same-user 48h alerts for helper commands, dump/archive names, or post-clone authentication. $investigate_3
- Hint: if user scope is sparse or the host is shared, review same-host alerts for process, output, and authentication evidence. $investigate_4
- Implication: broaden scope when helper-command, output, or authentication patterns repeat around clone windows; no repeat keeps response local but does not clear the clone.
- Escalate for unauthorized LSASS clone creation, dump preparation, post-clone credential use, or clone creation on domain controllers, jump hosts, or privileged admin systems; close only when the alert tuple and recovery evidence bind to one recognized EDR, forensic, or debugging workflow with no conflicting dump-conversion, output, or authentication evidence; preserve artifacts and escalate when answers are mixed or visibility is incomplete.
### False positive analysis
- Recognized EDR/forensic collection or bounded lab validation can create snapshot-based clones. Require the alert tuple, helper command line, `user.id`, `host.id`, dump-output pattern, and no unexpected 4624 or 4648 activity inside that workflow; use records only to corroborate unresolved telemetry.
- Before creating an exception, validate that the same `host.id` and `user.id` cohort repeats the same process identity, helper-command, output-path, and authentication pattern across prior alerts from this rule. Avoid exceptions on "lsass.exe", `event.code`, or `host.id` alone.
### Response and remediation
- If confirmed benign, reverse temporary containment and document the collection workflow identity, launcher path, actor, host scope, dump-output pattern, and follow-on authentication pattern. Create an exception only if that pattern recurs across prior alerts.
- If suspicious but unconfirmed, preserve the alert 4688 event, surrounding helper-process events, command lines, dump/archive paths, rename evidence, affected identities, and post-clone authentication records before containment. Apply reversible containment first, such as heightened monitoring or temporary restrictions on remote admin access; escalate to host isolation only when dump artifacts or post-clone authentication confirm likely credential exposure and the host role can tolerate interruption.
- If confirmed malicious, preserve the alert event, helper-process chain, dump/archive paths, rename evidence, and affected identities before containment. Then isolate the host through endpoint response; if unavailable, escalate with preserved evidence. Block confirmed remote-auth or transfer sources before cleanup.
- On domain controllers, jump hosts, or privileged admin systems, scope which local, cached, service, or domain credentials may have been exposed, then reset or rotate affected credentials before removing collected artifacts.
- Before eradication, review related hosts and users for the same helper-process pattern, dump path, `winlog.logon.type`, or `source.ip` indicators. Then remove dump files, archives, helper tools, and persistence, and remediate the access or privilege path that enabled clone creation.
- Post-incident hardening: restrict memory-acquisition and dump tooling to recognized admin cohorts, retain supplemental file telemetry where its absence limited the case, and document the confirmed workflow or malicious pattern for future triage.
"""
setup = """## Setup
Audit Process Creation and Command Line must be enabled to generate the events used by this rule.
Setup instructions: https://ela.st/audit-process-creation
"""
[rule.investigation_fields]
field_names = [
"@timestamp",
"host.name",
"host.id",
"user.name",
"user.id",
"user.domain",
"process.entity_id",
"process.pid",
"process.executable",
"process.command_line",
"process.parent.entity_id",
"process.parent.pid",
"process.parent.name",
"process.parent.executable",
"process.parent.command_line",
]
[transform]
[[transform.investigate]]
label = "Same-host 4688 process creation events"
description = ""
providers = [
[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "event.code", queryType = "phrase", value = "4688", valueType = "string" }
]
]
relativeFrom = "now-1h"
relativeTo = "now"
[[transform.investigate]]
label = "File activity on the affected host"
description = ""
providers = [
[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" }
]
]
relativeFrom = "now-1h"
relativeTo = "now"
[[transform.investigate]]
label = "Authentication events on the affected host"
description = ""
providers = [
[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.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 = "event.code", queryType = "phrase", value = "4648", valueType = "string" }
],
[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "event.code", queryType = "phrase", value = "4625", 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 = "T1003"
name = "OS Credential Dumping"
reference = "https://attack.mitre.org/techniques/T1003/"
[[rule.threat.technique.subtechnique]]
id = "T1003.001"
name = "LSASS Memory"
reference = "https://attack.mitre.org/techniques/T1003/001/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
Stages and Predicates
Stage 1: process
process where host.os.type == "windows" and event.code:"4688" and
process.executable : "?:\\Windows\\System32\\lsass.exe" and
process.parent.executable : "?:\\Windows\\System32\\lsass.exe"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.code | wildcard |
| field:"EventID" kind:wildcard value:"4688" |
process.executable | wildcard |
| field:"Image" kind:wildcard value:"?:\Windows\System32\lsass.exe" |
process.parent.executable | wildcard |
| field:"ParentImage" kind:wildcard value:"?:\Windows\System32\lsass.exe" |
Ransomware - Detected - Elastic Defend
#Generates a detection alert each time an Elastic Defend alert for ransomware are received. Enabling this rule allows you to immediately begin investigating your Endpoint ransomware alerts. This rule identifies Elastic Defend ransomware detections only, and does not include prevention alerts.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Impact |
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 ransomware are received. Enabling this rule allows you
to immediately begin investigating your Endpoint ransomware alerts. This rule identifies Elastic Defend ransomware
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 = "Ransomware - Detected - Elastic Defend"
note = """## Triage and analysis
### Investigating Ransomware - Detected - Elastic Defend
Ransomware protection adds a dedicated layer of detection and prevention against ransomware attacks. Our Ransomware protection consists of 3 subtypes: `behavioral`, `canary files`, and `MBR`. Our behavioral ransomware protection monitors the low level file system activity of all processes on the system to identify generic file encryption techniques. We include signals such as file header information, entropy calculations, known and suspicious extensions, and more to make verdicts. Canary files serve as a high confidence short-cut to other behavior techniques. Our endpoint places hidden files in select directories on the system and will trigger on any process attempting to tamper with the files. Finally, we protect the Master Boot Record (MBR) with our kernel minifilter driver to prevent this type of ransomware attack.
Generally, our ransomware protection is tuned to have extremely low false positives rates. We understand how alarming and disruptive ransomware false positives can be which has factored into its design goals. More likely than not, if this protection fires, it is a true positive. However, certain categories of software do behave similarly to ransomware from the perspective of this protection. That includes installers and backup software, which can make a large number of modifications to documents (especially during a restore operation). Further, encryption or system utilities which modify the system’s MBR may also trigger our MBR protection.
### Possible investigation steps
- The `Ransomware.files` field provides details about files modifications (paths, entropy, extension and file headers).
- Investigate the metadata and the activity of the process or processes that triggered the alert.
- Assess whether this activity prevalent in the environment by looking for similar occurrences across hosts.
- Some Ransomware attacks tend to execute the operation on multiple hosts at the same time for maximum impact.
- Verify the activity of the `user.name` associated with the alert (local or remote actity, privileged or standard user).
- Quickly identifying the compromised credentials is critical to remediate Ransomware attacks.
- 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
- Installers and backup software, which can make a large number of modifications to documents (especially during a restore operation).
- Encryption or system utilities which modify the system’s MBR may also trigger our MBR protection.
### Response and Remediation
- Immediate Isolation and Containment: Quickly disconnect affected systems from the network, including both wired and wireless connections, to prevent the ransomware from spreading. This includes disabling network cards and removing network cables if necessary, while keeping the systems powered on for forensic purposes.
- Activate Incident Response Team and Plan: Assemble your incident response team and implement your incident response plan. Contact necessary stakeholders including IT security, legal counsel, and executive management. Document all actions taken from the moment of detection.
Initial Assessment and Evidence Preservation: Identify the scope of the infection and the type of ransomware.
- Take screenshots of ransom messages and create disk images of affected systems. Record all observable indicators of compromise (IOCs) before any remediation begins.
- Business Impact Analysis: Evaluate which critical business operations are affected and establish priority systems for recovery. Determine regulatory reporting requirements based on the type of data potentially compromised.
- Secure Backup Verification: Identify and verify the integrity of your latest clean backups. Check backup systems for potential compromise and ensure they were disconnected during the attack to prevent encryption of backup data.
- System Recovery Preparation: Build a clean environment for recovery operations, including secured networks and validated clean systems. Prepare tools and resources needed for system restoration.
- Malware Eradication: Remove the ransomware from infected systems using appropriate security tools. This may involve complete system rebuilds from known clean sources rather than attempting to clean infected systems.
- Data Restoration: Begin restoring systems from verified clean backups, starting with the most critical business operations. Implement additional security controls and monitoring during the restoration process.
- Security Posture Strengthening: Update all security systems including firewalls, antivirus, and endpoint protection. Reset all credentials across the organization and implement additional access controls like multi-factor authentication where needed.
- Post-Incident Activities: Conduct a detailed post-incident analysis to identify how the ransomware entered the environment. Update security policies and incident response plans based on lessons learned, and provide additional security awareness training to staff.
"""
references = [
"https://github.com/elastic/protections-artifacts/tree/main/ransomware",
"https://docs.elastic.co/en/integrations/endpoint",
]
risk_score = 73
rule_id = "0c74cd7e-ea35-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 = "high"
tags = ["Data Source: Elastic Defend", "Tactic: Impact", "Resources: Investigation Guide"]
timestamp_override = "event.ingested"
type = "query"
query = '''
event.kind : alert and event.code : ransomware 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 = "T1486"
name = "Data Encrypted for Impact"
reference = "https://attack.mitre.org/techniques/T1486/"
[rule.threat.tactic]
id = "TA0040"
name = "Impact"
reference = "https://attack.mitre.org/tactics/TA0040/"
Stages and Predicates
Stage 1: query
event.kind : alert and event.code : ransomware and (event.type : allowed or (event.type: denied and event.outcome: failure))
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.code | eq |
| field:"EventID" kind:eq value:"ransomware" |
event.kind | eq |
| field:"event.kind" kind:eq value:"alert" |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"failure" |
event.type | eq |
| field:"event.type" kind:eq |
Shell Command Execution via Kworker
#This rule monitors for the execution of shell commands via a kworker parent process. kworker, or kernel worker, processes are part of the kernel's workqueue mechanism. They are responsible for executing work that has been scheduled to be done in kernel space, which might include tasks like handling interrupts, background activities, and other kernel-related tasks. Attackers may attempt to evade detection by masquerading as a kernel worker process.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Stealth |
Rule Body
[rule]
description = """
This rule monitors for the execution of shell commands via a kworker parent process. kworker, or kernel worker,
processes are part of the kernel's workqueue mechanism. They are responsible for executing work that has been scheduled
to be done in kernel space, which might include tasks like handling interrupts, background activities, and other
kernel-related tasks. Attackers may attempt to evade detection by masquerading as a kernel worker process.
"""
id = "94943f02-5580-4d1d-a763-09e958bd0f57"
license = "Elastic License v2"
name = "Shell Command Execution via Kworker"
os_list = ["linux"]
version = "1.0.11"
query = '''
process where event.type == "start" and event.action == "exec" and process.parent.name like "kworker*" and
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and process.args == "-c" and
process.args in (
"bash", "/bin/bash", "/usr/bin/bash", "/usr/local/bin/bash",
"sh", "/bin/sh", "/usr/bin/sh", "/usr/local/bin/sh",
"dash", "/bin/dash", "/usr/bin/dash", "/usr/local/bin/dash",
"tcsh", "/bin/tcsh", "/usr/bin/tcsh", "/usr/local/bin/tcsh",
"csh", "/bin/csh", "/usr/bin/csh", "/usr/local/bin/csh",
"zsh", "/bin/zsh", "/usr/bin/zsh", "/usr/local/bin/zsh",
"ksh", "/bin/ksh", "/usr/bin/ksh", "/usr/local/bin/ksh",
"fish", "/bin/fish", "/usr/bin/fish", "/usr/local/bin/fish"
) and
process.args_count >= 3 and process.command_line like (
"*ip*", "*whoami*", "*id*", "*hostname*", "*touch*", "*curl*", "*wget*", "*chmod*", "*busybox*", "*chattr*", "*echo*",
"*python*", "*php*", "*perl*", "*ruby*", "*lua*", "*openssl*", "*nc*", "*netcat*", "*ncat*"
) and not (
process.command_line == "sh -c /bin/true" or
process.args like ("/sbin/modprobe *", "/usr/sbin/modprobe *")
)
'''
min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "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.type == "start" and event.action == "exec" and process.parent.name like "kworker*" and
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and process.args == "-c" and
process.args in (
"bash", "/bin/bash", "/usr/bin/bash", "/usr/local/bin/bash",
"sh", "/bin/sh", "/usr/bin/sh", "/usr/local/bin/sh",
"dash", "/bin/dash", "/usr/bin/dash", "/usr/local/bin/dash",
"tcsh", "/bin/tcsh", "/usr/bin/tcsh", "/usr/local/bin/tcsh",
"csh", "/bin/csh", "/usr/bin/csh", "/usr/local/bin/csh",
"zsh", "/bin/zsh", "/usr/bin/zsh", "/usr/local/bin/zsh",
"ksh", "/bin/ksh", "/usr/bin/ksh", "/usr/local/bin/ksh",
"fish", "/bin/fish", "/usr/bin/fish", "/usr/local/bin/fish"
) and
process.args_count >= 3 and process.command_line like (
"*ip*", "*whoami*", "*id*", "*hostname*", "*touch*", "*curl*", "*wget*", "*chmod*", "*busybox*", "*chattr*", "*echo*",
"*python*", "*php*", "*perl*", "*ruby*", "*lua*", "*openssl*", "*nc*", "*netcat*", "*ncat*"
) and not (
process.command_line == "sh -c /bin/true" or
process.args like ("/sbin/modprobe *", "/usr/sbin/modprobe *")
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | eq |
| field:"process.args" kind:eq value:"-c" |
process.args | in |
| field:"process.args" kind:in |
process.args_count | ge |
| field:"process.args_count" kind:ge value:"3" |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard |
process.name | in |
| field:"process_basename" kind:in |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard value:"kworker*" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | starts_with | /sbin/modprobe , /usr/sbin/modprobe | excludes:process.args field:"process.args" value:"/sbin/modprobe " field:"process.args" value:"/usr/sbin/modprobe " |
process.command_line | eq | sh -c /bin/true | excludes:process.command_line field:"process.command_line" value:"sh -c /bin/true" |
Suricata and Elastic Defend Network Correlation
#This detection correlates Suricata alerts with Elastic Defend network events to identify the source process performing the network activity.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Discovery | |
| Command & Control |
Rule Body
[metadata]
creation_date = "2025/12/10"
integration = ["endpoint", "suricata"]
maturity = "production"
updated_date = "2026/09/10"
[rule]
author = ["Elastic"]
description = """
This detection correlates Suricata alerts with Elastic Defend network events to identify the source process performing
the network activity.
"""
from = "now-9m"
index = ["logs-endpoint.events.network-*", "filebeat-*", "logs-suricata.*"]
language = "eql"
license = "Elastic License v2"
name = "Suricata and Elastic Defend Network Correlation"
references = [
"https://attack.mitre.org/tactics/TA0011/",
"https://www.elastic.co/docs/reference/integrations/suricata",
"https://www.elastic.co/docs/reference/integrations/endpoint"
]
risk_score = 47
rule_id = "9edd000e-cbd1-4d6a-be72-2197b5625a05"
severity = "medium"
tags = [
"Domain: Endpoint",
"Domain: Network",
"OS: Linux",
"OS: Windows",
"OS: macOS",
"Use Case: Threat Detection",
"Tactic: Command and Control",
"Data Source: Elastic Defend",
"Data Source: Suricata",
"Resources: Investigation Guide",
]
type = "eql"
query = '''
sequence by source.port, source.ip, destination.ip with maxspan=5s
[network where data_stream.dataset == "suricata.eve" and event.kind == "alert" and
event.severity != 3 and source.ip != null and destination.ip != null and
not rule.name in ("ET INFO SMB2 NT Create AndX Request For a Powershell .ps1 File", "ET SCAN MS Terminal Server Traffic on Non-standard Port")]
[network where event.module == "endpoint" and event.action in ("disconnect_received", "connection_attempted") and
not process.executable in ("System", "C:\\Program Files (x86)\\Admin Arsenal\\PDQ Inventory\\PDQInventoryService.exe") and
not process.executable : "C:\\Windows\\AdminArsenal\\PDQInventory-Scanner\\service-*\\exec\\PDQInventoryScanner.exe"]
'''
note = """## Triage and analysis
### Investigating Suricata and Elastic Defend Network Correlation
### Possible investigation steps
- Investigate in the Timeline feature the two events matching this correlation (Suricata and Elastic Defend).
- Review the process details like command_line, privileges, global relevance and reputation.
- Assess the destination.ip reputation and global relevance.
- Review the parent process execution details like command_line, global relevance and reputation.
- Examine all network connection details performed by the process during last 48h.
- Correlate the alert with other security events or logs to identify any patterns or additional indicators of compromise related to the same process or network activity.
### False positive analysis
- Trusted system or third party processes performing network activity that looks like beaconing.
### Response and remediation
- Immediately isolate the affected system from the network to prevent further unauthorized access or data exfiltration.
- Terminate the suspicious processes and all associated children and parents.
- Implement network-level controls to block traffic to the destination.ip.
- Conduct a thorough review of the system's configuration files to identify unauthorized changes.
- Reset credentials for any accounts associated with the source machine.
- 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 = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"
[[rule.threat.technique]]
id = "T1571"
name = "Non-Standard Port"
reference = "https://attack.mitre.org/techniques/T1571/"
[rule.threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1046"
name = "Network Service Discovery"
reference = "https://attack.mitre.org/techniques/T1046/"
[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
Stages and Predicates
Ordered sequence: each step below must occur in order within 5s, correlated by destination.ip, source.ip, source.port.
Stage 1: network
[network where data_stream.dataset == "suricata.eve" and event.kind == "alert" and
event.severity != 3 and source.ip != null and destination.ip != null and
not rule.name in ("ET INFO SMB2 NT Create AndX Request For a Powershell .ps1 File", "ET SCAN MS Terminal Server Traffic on Non-standard Port")]
Stage 2: network
[network where event.module == "endpoint" and event.action in ("disconnect_received", "connection_attempted") and
not process.executable in ("System", "C:\\Program Files (x86)\\Admin Arsenal\\PDQ Inventory\\PDQInventoryService.exe") and
not process.executable : "C:\\Windows\\AdminArsenal\\PDQInventory-Scanner\\service-*\\exec\\PDQInventoryScanner.exe"]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"suricata.eve" |
destination.ip | is_not_null | field:"dest_ip" kind:is_not_null | |
event.action | in |
| field:"EventType" kind:in |
event.kind | eq |
| field:"event.kind" kind:eq value:"alert" |
event.module | eq |
| field:"event.module" kind:eq value:"endpoint" |
event.severity | ne |
| field:"event.severity" kind:ne value:"3" |
source.ip | is_not_null | field:"src_ip" kind:is_not_null |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
rule.name | in | ET INFO SMB2 NT Create AndX Request For a Powershell .ps1 File, ET SCAN MS Terminal Server Traffic on Non-standard Port | excludes:rule.name field:"rule.name" value:"ET INFO SMB2 NT Create AndX Request For a Powershell .ps1 File" field:"rule.name" value:"ET SCAN MS Terminal Server Traffic on Non-standard Port" |
process.executable | in | C:\Program Files (x86)\Admin Arsenal\PDQ Inventory\PDQInventoryService.exe, System | excludes:process.executable field:"process.executable" value:"C:\Program Files (x86)\Admin Arsenal\PDQ Inventory\PDQInventoryService.exe" field:"process.executable" value:"System" |
process.executable | wildcard | C:\Windows\AdminArsenal\PDQInventory-Scanner\service-*\exec\PDQInventoryScanner.exe | excludes:process.executable field:"process.executable" value:"C:\Windows\AdminArsenal\PDQInventory-Scanner\service-*\exec\PDQInventoryScanner.exe" |
Suspicious Execution via Microsoft Common Console
#Identifies the execution of a child process from a Microsoft Common Console file. Adversaries may embed malicious commands in an MSC file in order to trick them into executing malicious commands.
MITRE ATT&CK Coverage
Rule Body
[rule]
description = """
Identifies the execution of a child process from a Microsoft Common Console file. Adversaries may embed malicious
commands in an MSC file in order to trick them into executing malicious commands.
"""
id = "6e5cb5a0-1439-481d-bcba-0c5307b4746b"
license = "Elastic License v2"
name = "Suspicious Execution via Microsoft Common Console"
os_list = ["windows"]
reference = [
"https://www.genians.co.kr/blog/threat_intelligence/facebook",
"https://www.elastic.co/security-labs/grimresource",
]
version = "1.0.6"
query = '''
process where event.action == "start" and
process.parent.executable : "?:\\Windows\\System32\\mmc.exe" and process.parent.args : "*.msc" and
not process.parent.args : ("?:\\Windows\\System32\\*.msc", "?:\\Windows\\SysWOW64\\*.msc", "?:\\Program files\\*.msc", "?:\\Program Files (x86)\\*.msc") and
not process.executable :
("?:\\Windows\\System32\\mmc.exe",
"?:\\Windows\\System32\\wermgr.exe",
"?:\\Windows\\System32\\WerFault.exe",
"?:\\Windows\\System32\\DWWIN.EXE",
"?:\\Windows\\SysWOW64\\mmc.exe",
"?:\\Program Files\\*.exe",
"?:\\Program Files (x86)\\*.exe",
"?:\\Windows\\System32\\shrpubw.exe",
"?:\\Windows\\System32\\certreq.exe",
"?:\\Windows\\System32\\spool\\drivers\\x64\\3\\*.EXE",
"?:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe",
"?:\\Program Files\\internet explorer\\iexplore.exe",
"?:\\Windows\\Microsoft.NET\\Framework64\\*\\vbc.exe",
"?:\\windows\\system32\\VmConnect.exe",
"?:\\Windows\\System32\\Dism\\dismhost.exe",
"?:\\Windows\\System32\\DeviceProperties.exe") and
not (process.executable : "?:\\Windows\\explorer.exe" and process.args : "ms-settings:windowsupdate") and
not (process.pe.original_file_name == "DismHost.exe" and process.args : "{*}" and
process.code_signature.subject_name == "Microsoft Windows" and process.code_signature.trusted == true) and
process.hash.sha256 != "7208b36f57e9af293043adcaf2180db10fff9e0bfffdbac81ad2ac5dbead6a30"
'''
min_endpoint_version = "7.16.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.technique.subtechnique]]
id = "T1566.002"
name = "Spearphishing Link"
reference = "https://attack.mitre.org/techniques/T1566/002/"
[threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1204"
name = "User Execution"
reference = "https://attack.mitre.org/techniques/T1204/"
[[threat.technique.subtechnique]]
id = "T1204.001"
name = "Malicious Link"
reference = "https://attack.mitre.org/techniques/T1204/001/"
[[threat.technique.subtechnique]]
id = "T1204.002"
name = "Malicious File"
reference = "https://attack.mitre.org/techniques/T1204/002/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"
[[threat.technique.subtechnique]]
id = "T1218.014"
name = "MMC"
reference = "https://attack.mitre.org/techniques/T1218/014/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "7.16.0"
Stages and Predicates
Stage 1: process
process where event.action == "start" and
process.parent.executable : "?:\\Windows\\System32\\mmc.exe" and process.parent.args : "*.msc" and
not process.parent.args : ("?:\\Windows\\System32\\*.msc", "?:\\Windows\\SysWOW64\\*.msc", "?:\\Program files\\*.msc", "?:\\Program Files (x86)\\*.msc") and
not process.executable :
("?:\\Windows\\System32\\mmc.exe",
"?:\\Windows\\System32\\wermgr.exe",
"?:\\Windows\\System32\\WerFault.exe",
"?:\\Windows\\System32\\DWWIN.EXE",
"?:\\Windows\\SysWOW64\\mmc.exe",
"?:\\Program Files\\*.exe",
"?:\\Program Files (x86)\\*.exe",
"?:\\Windows\\System32\\shrpubw.exe",
"?:\\Windows\\System32\\certreq.exe",
"?:\\Windows\\System32\\spool\\drivers\\x64\\3\\*.EXE",
"?:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe",
"?:\\Program Files\\internet explorer\\iexplore.exe",
"?:\\Windows\\Microsoft.NET\\Framework64\\*\\vbc.exe",
"?:\\windows\\system32\\VmConnect.exe",
"?:\\Windows\\System32\\Dism\\dismhost.exe",
"?:\\Windows\\System32\\DeviceProperties.exe") and
not (process.executable : "?:\\Windows\\explorer.exe" and process.args : "ms-settings:windowsupdate") and
not (process.pe.original_file_name == "DismHost.exe" and process.args : "{*}" and
process.code_signature.subject_name == "Microsoft Windows" and process.code_signature.trusted == true) and
process.hash.sha256 != "7208b36f57e9af293043adcaf2180db10fff9e0bfffdbac81ad2ac5dbead6a30"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.hash.sha256 | ne |
| field:"Hashes" kind:ne value:"7208b36f57e9af293043adcaf2180db10fff9e0bfffdbac81ad2ac5dbead6a30" |
process.parent.args | wildcard |
| field:"process.parent.args" kind:wildcard value:"*.msc" |
process.parent.executable | wildcard |
| field:"ParentImage" kind:wildcard value:"?:\Windows\System32\mmc.exe" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | eq | ms-settings:windowsupdate | excludes:process.args field:"process.args" value:"ms-settings:windowsupdate" |
process.executable | eq | ?:\Windows\explorer.exe | excludes:process.executable field:"process.executable" value:"?:\Windows\explorer.exe" |
process.args | wildcard | {*} | excludes:process.args field:"process.args" value:"{*}" |
process.code_signature.subject_name | eq | Microsoft Windows | excludes:process.code_signature.subject_name field:"process.code_signature.subject_name" value:"Microsoft Windows" |
process.code_signature.trusted | eq | true | excludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true" |
process.pe.original_file_name | eq | DismHost.exe | excludes:process.pe.original_file_name field:"process.pe.original_file_name" value:"DismHost.exe" |
process.executable | wildcard | ?:\Windows\System32\mmc.exe, ?:\Windows\System32\wermgr.exe, ?:\Windows\System32\WerFault.exe, ?:\Windows\System32\DWWIN.EXE, ?:\Windows\SysWOW64\mmc.exe, ?:\Program Files\*.exe, ?:\Program Files (x86)\*.exe, ?:\Windows\System32\shrpubw.exe, ?:\Windows\System32\certreq.exe, ?:\Windows\System32\spool\drivers\x64\3\*.EXE, ?:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe, ?:\Program Files\internet explorer\iexplore.exe, ?:\Windows\Microsoft.NET\Framework64\*\vbc.exe, ?:\windows\system32\VmConnect.exe, ?:\Windows\System32\Dism\dismhost.exe, ?:\Windows\System32\DeviceProperties.exe | excludes:process.executable |
process.parent.args | wildcard | ?:\Windows\System32\*.msc, ?:\Windows\SysWOW64\*.msc, ?:\Program files\*.msc, ?:\Program Files (x86)\*.msc | excludes:process.parent.args |
Suspicious Network Activity to the Internet by Previously Unknown Executable
#This rule monitors for network connectivity to the internet from a previously unknown executable located in a suspicious directory. An alert from this rule can indicate the presence of potentially malicious activity, such as the execution of unauthorized or suspicious processes attempting to establish connections to unknown or suspicious destinations such as a command and control server. Detecting and investigating such behavior can help identify and mitigate potential security threats, protecting the system and its data from potential compromise.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Command & Control |
Rule Body
[metadata]
creation_date = "2023/06/14"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"
[transform]
[[transform.osquery]]
label = "Osquery - Retrieve Listening Ports"
query = "SELECT pid, address, port, socket, protocol, path FROM listening_ports"
[[transform.osquery]]
label = "Osquery - Retrieve Open Sockets"
query = "SELECT pid, family, remote_address, remote_port, socket, state FROM process_open_sockets"
[[transform.osquery]]
label = "Osquery - Retrieve Information for a Specific User"
query = "SELECT * FROM users WHERE username = {{user.name}}"
[[transform.osquery]]
label = "Osquery - Investigate the Account Authentication Status"
query = "SELECT * FROM logged_in_users WHERE user = {{user.name}}"
[[transform.osquery]]
label = "Osquery - Retrieve Running Processes by User"
query = "SELECT pid, username, name FROM processes p JOIN users u ON u.uid = p.uid ORDER BY username"
[[transform.osquery]]
label = "Osquery - Retrieve Process Info"
query = "SELECT name, cmdline, parent, path, uid FROM processes"
[rule]
author = ["Elastic"]
description = """
This rule monitors for network connectivity to the internet from a previously unknown executable located in a suspicious
directory. An alert from this rule can indicate the presence of potentially malicious activity, such as the execution of
unauthorized or suspicious processes attempting to establish connections to unknown or suspicious destinations such as a
command and control server. Detecting and investigating such behavior can help identify and mitigate potential security
threats, protecting the system and its data from potential compromise.
"""
from = "now-59m"
index = ["auditbeat-*", "filebeat-*", "packetbeat-*", "logs-endpoint.events.*", "endgame-*"]
language = "kuery"
license = "Elastic License v2"
name = "Suspicious Network Activity to the Internet by Previously Unknown Executable"
note = """## Triage and analysis
### Investigating Suspicious Network Activity to the Internet by Previously Unknown Executable
After being installed, malware will often call out to its command and control server to receive further instructions by its operators.
This rule leverages the new terms rule type to detect previously unknown processes, initiating network connections to external IP-addresses.
> **Note**:
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/current/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.
> This investigation guide uses [placeholder fields](https://www.elastic.co/guide/en/security/current/osquery-placeholder-fields.html) to dynamically pass alert data into Osquery queries. Placeholder fields were introduced in Elastic Stack version 8.7.0. If you're using Elastic Stack version 8.6.0 or earlier, you'll need to manually adjust this investigation guide's queries to ensure they properly run.
#### Possible investigation steps
- Identify any signs of suspicious network activity or anomalies that may indicate malicious behavior. This could include unexpected traffic patterns or unusual network behavior.
- Investigate listening ports and open sockets to look for potential malicious processes, reverse shells or data exfiltration.
- $osquery_0
- $osquery_1
- Identify the user account that performed the action, analyze it, and check whether it should perform this kind of action.
- $osquery_2
- Investigate whether the user is currently logged in and active.
- $osquery_3
- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence and whether they are located in expected locations.
- $osquery_4
- $osquery_5
- Investigate other alerts associated with the user/host during the past 48 hours.
- If scripts or executables were dropped, retrieve the files and determine if they are malicious:
- Use a private sandboxed malware analysis system to perform analysis.
- Observe and collect information about the following activities:
- Attempts to contact external domains and addresses.
- Check if the domain is newly registered or unexpected.
- Check the reputation of the domain or IP address.
- File access, modification, and creation activities.
### Related rules
- Network Activity Detected via cat - afd04601-12fc-4149-9b78-9c3f8fe45d39
### False positive analysis
- If this activity is related to new benign software installation activity, consider adding exceptions — preferably with a combination of user and command line conditions.
- Try to understand the context of the execution by thinking about the user, machine, or business purpose. A small number of endpoints, such as servers with unique software, might appear unusual but satisfy a specific business need.
### Response and remediation
- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- If the triage identified malware, search the environment for additional compromised hosts.
- Implement temporary network rules, procedures, and segmentation to contain the malware.
- Stop suspicious processes.
- Immediately block the identified indicators of compromise (IoCs).
- Inspect the affected systems for additional malware backdoors, such as reverse shells, reverse proxies, or droppers, that attackers could use to reinfect the system.
- Remove and block malicious artifacts identified during triage.
- 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.
- Leverage the incident response data and logging to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
risk_score = 21
rule_id = "53617418-17b4-4e9c-8a2c-8deb8086ca4b"
setup = """## Setup
This rule requires data coming in from one of the following integrations:
- Elastic Defend
- Auditbeat
- Filebeat
- Packetbeat
### 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 to select "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).
### Auditbeat Setup
Auditbeat is a lightweight shipper that you can install on your servers to audit the activities of users and processes on your systems. For example, you can use Auditbeat to collect and centralize audit events from the Linux Audit Framework. You can also use Auditbeat to detect changes to critical files, like binaries and configuration files, and identify potential security policy violations.
#### The following steps should be executed in order to add the Auditbeat on a Linux System:
- Elastic provides repositories available for APT and YUM-based distributions. Note that we provide binary packages, but no source packages.
- To install the APT and YUM repositories follow the setup instructions in this [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/setup-repositories.html).
- To run Auditbeat on Docker follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/running-on-docker.html).
- To run Auditbeat on Kubernetes follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/running-on-kubernetes.html).
- For complete “Setup and Run Auditbeat” information refer to the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/setting-up-and-running.html).
### Filebeat Setup
Filebeat is a lightweight shipper for forwarding and centralizing log data. Installed as an agent on your servers, Filebeat monitors the log files or locations that you specify, collects log events, and forwards them either to Elasticsearch or Logstash for indexing.
#### The following steps should be executed in order to add the Filebeat on a Linux System:
- Elastic provides repositories available for APT and YUM-based distributions. Note that we provide binary packages, but no source packages.
- To install the APT and YUM repositories follow the setup instructions in this [helper guide](https://www.elastic.co/guide/en/beats/filebeat/current/setup-repositories.html).
- To run Filebeat on Docker follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/filebeat/current/running-on-docker.html).
- To run Filebeat on Kubernetes follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/filebeat/current/running-on-kubernetes.html).
- For quick start information for Filebeat refer to the [helper guide](https://www.elastic.co/guide/en/beats/filebeat/8.11/filebeat-installation-configuration.html).
- For complete “Setup and Run Filebeat” information refer to the [helper guide](https://www.elastic.co/guide/en/beats/filebeat/current/setting-up-and-running.html).
### Packetbeat Setup
Packetbeat is a real-time network packet analyzer that you can use for application monitoring, performance analytics, and threat detection. Packetbeat works by capturing the network traffic between your application servers, decoding the application layer protocols (HTTP, MySQL, Redis, and so on), correlating the requests with the responses, and recording the interesting fields for each transaction.
#### The following steps should be executed in order to add the Packetbeat on a Linux System:
- Elastic provides repositories available for APT and YUM-based distributions. Note that we provide binary packages, but no source packages.
- To install the APT and YUM repositories follow the setup instructions in this [helper guide](https://www.elastic.co/guide/en/beats/packetbeat/current/setup-repositories.html).
- To run Packetbeat on Docker follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/packetbeat/current/running-on-docker.html).
- For quick start information for Packetbeat refer to the [helper guide](https://www.elastic.co/guide/en/beats/packetbeat/current/packetbeat-installation-configuration.html).
- For complete “Setup and Run Packetbeat” information refer to the [helper guide](https://www.elastic.co/guide/en/beats/packetbeat/current/setting-up-and-running.html).
"""
severity = "low"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Command and Control",
"Data Source: Elastic Endgame",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
host.os.type:linux and event.category:network and event.action:(connection_attempted or ipv4_connection_attempt_event) and
process.executable : (
/etc/crontab or /etc/rc.local or ./* or /boot/* or /dev/shm/* or /etc/cron.*/* or /etc/init.d/* or /etc/rc*.d/* or
/etc/update-motd.d/* or /home/*/.* or /tmp/* or /usr/lib/update-notifier/* or /var/log/* or /var/tmp/*
) and process.name : * and
not (
process.executable : (
/tmp/newroot/* or /tmp/snap.rootfs* or /etc/cron.hourly/BitdefenderRedline or /tmp/go-build* or /srv/snp/docker/* or
/run/containerd/* or /tmp/.mount* or /run/k3s/containerd/* or /tmp/selenium* or /tmp/tmp.*/juliainstaller or
/tmp/.criu.mntns* or /home/*/.local/share/containers/* or /etc/update-motd.d/*
) or
source.ip:(10.0.0.0/8 or 127.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) or
process.name : (
apt or chrome or curl or dnf or dockerd or dpkg or firefox-bin or git-remote-https or java or kite-update or
kited or node or rpm or saml2aws or selenium-manager or solana-validator or wget or yum or ansible* or aws* or
php* or pip* or python* or steam* or terraform* or filebeat or apk or cursor or http
) or
destination.ip:(
0.0.0.0 or 10.0.0.0/8 or 100.64.0.0/10 or 127.0.0.0/8 or 169.254.0.0/16 or 172.16.0.0/12 or 192.0.0.0/24 or
192.0.0.0/29 or 192.0.0.10/32 or 192.0.0.170/32 or 192.0.0.171/32 or 192.0.0.8/32 or 192.0.0.9/32 or 192.0.2.0/24 or
192.168.0.0/16 or 192.175.48.0/24 or 192.31.196.0/24 or 192.52.193.0/24 or 192.88.99.0/24 or 198.18.0.0/15 or
198.51.100.0/24 or 203.0.113.0/24 or 224.0.0.0/4 or 240.0.0.0/4 or "::1" or "FE80::/10" or "FF00::/8"
)
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"
[rule.threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1037"
name = "Boot or Logon Initialization Scripts"
reference = "https://attack.mitre.org/techniques/T1037/"
[[rule.threat.technique.subtechnique]]
id = "T1037.004"
name = "RC Scripts"
reference = "https://attack.mitre.org/techniques/T1037/004/"
[[rule.threat.technique]]
id = "T1053"
name = "Scheduled Task/Job"
reference = "https://attack.mitre.org/techniques/T1053/"
[[rule.threat.technique.subtechnique]]
id = "T1053.003"
name = "Cron"
reference = "https://attack.mitre.org/techniques/T1053/003/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[rule.new_terms]
field = "new_terms_fields"
value = ["process.executable"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-20d"
Stages and Predicates
Stage 1: new_terms
host.os.type:linux and event.category:network and event.action:(connection_attempted or ipv4_connection_attempt_event) and
process.executable : (
/etc/crontab or /etc/rc.local or .* or /etc/init.d/* or /etc/rc*.d/* or
/etc/update-motd.d.* or /tmp/* or /usr/lib/update-notifier/* or /var/log/* or /var/tmp/*
) and process.name : * and
not (
process.executable : (
/tmp/newroot/* or /tmp/snap.rootfs* or /etc/cron.hourly/BitdefenderRedline or /tmp/go-build* or /srv/snp/docker/* or
/run/containerdjuliainstaller or
/tmp/.criu.mntns* or /home/*/.local/share/containers/* or /etc/update-motd.d/*
) or
source.ip:(10.0.0.0/8 or 127.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16) or
process.name : (
apt or chrome or curl or dnf or dockerd or dpkg or firefox-bin or git-remote-https or java or kite-update or
kited or node or rpm or saml2aws or selenium-manager or solana-validator or wget or yum or ansible* or aws* or
php* or pip* or python* or steam* or terraform* or filebeat or apk or cursor or http
) or
destination.ip:(
0.0.0.0 or 10.0.0.0/8 or 100.64.0.0/10 or 127.0.0.0/8 or 169.254.0.0/16 or 172.16.0.0/12 or 192.0.0.0/24 or
192.0.0.0/29 or 192.0.0.10/32 or 192.0.0.170/32 or 192.0.0.171/32 or 192.0.0.8/32 or 192.0.0.9/32 or 192.0.2.0/24 or
192.168.0.0/16 or 192.175.48.0/24 or 192.31.196.0/24 or 192.52.193.0/24 or 192.88.99.0/24 or 198.18.0.0/15 or
198.51.100.0/24 or 203.0.113.0/24 or 224.0.0.0/4 or 240.0.0.0/4 or "::1" or "FE80::/10" or "FF00::/8"
)
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | in |
| field:"EventType" kind:in |
event.category | eq |
| field:"event.category" kind:eq value:"network" |
process.executable | eq |
| field:"Image" kind:eq |
process.executable | wildcard |
| field:"Image" kind:wildcard |
process.name | is_not_null | field:"process_basename" kind:is_not_null |
Exclusions
The rule actively suppresses these predicates.
Suspicious Task for Pid System Call
#Identifies when a process invoke the task_for_pid system service which gives a process the capability to control another process. A process needs root privileges to call task_for_pid or possesses the com.apple.security.get-task-allow entitlement. This type of behavior may indicate inter-process code injection or legit debugging activity. Adversaries may inject code into processes in order to evade process-based defenses as well as possibly elevate privileges.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule Body
[rule]
description = """
Identifies when a process invoke the task_for_pid system service which gives a process the capability to control another
process. A process needs root privileges to call task_for_pid or possesses the com.apple.security.get-task-allow
entitlement. This type of behavior may indicate inter-process code injection or legit debugging activity. Adversaries
may inject code into processes in order to evade process-based defenses as well as possibly elevate privileges.
"""
id = "572ec53e-fc79-43ad-8bdd-573999ff70d7"
license = "Elastic License v2"
name = "Suspicious Task for Pid System Call"
os_list = ["macos"]
reference = [
"http://os-tres.net/blog/2010/02/17/mac-os-x-and-task-for-pid-mach-call/",
"https://knight.sc/malware/2019/03/15/code-injection-on-macos.html",
"https://blog.xpnsec.com/macos-injection-via-third-party-frameworks/",
"https://wojciechregula.blog/post/learn-xpc-exploitation-part-3-code-injections/",
]
version = "1.0.38"
query = '''
process where event.action == "process_open" and
(process.code_signature.trusted == false or process.code_signature.exists == false) and
not process.executable like~ ("/private/var/folders/*",
"/Users/*/.pyenv/*",
"/opt/homebrew/*",
"/nix/store/*",
"/Users/*/.homebrew/*",
"/Users/*/miniconda3/envs/*",
"/usr/local/Cellar/*",
"/usr/local/Caskroom/*",
"/System/*") and
not process.name == "htop" and
not Target.process.executable like "/Users/*/anaconda3/envs/python*" and
not (startswith~(process.parent.executable, Target.process.executable) or
startswith~(process.executable, Target.process.executable)) and
not process.hash.sha256 : ("d41e02b5366b186a237f33150baa7c5ef4747ba06646a193ab9ba5125fc6ef7a",
"bee1a00ffb1c4b7c2c4784a1fdcb849dc7853b9deb5173ff4c5a08209c84bc26",
"6ac6f81d80afff9b6ee9d3608d9964566a39188d0166ae867df97c624e632b98",
"8698f4e54c64667c4a4c7ccde3fbcd7babc6478a5e8e22732732f633cc2fc499") and
not (process.executable like "/Users/*/micromamba/envs/grid/bin/python*" and Target.process.executable in ("/bin/bash", "/usr/bin/which", "/usr/bin/uname")) and
not (process.executable like "/Users/*/.local/share/uv/python/cpython-*-macos-aarch64-none/bin/python*" and Target.process.executable like "/Users/*/Code/eis-ray/.venv/lib/python*/site-packages/ray/core/src/ray/gcs/gcs_server") and
not (process.executable like "/Users/*/anaconda?/bin/python*" and Target.process.executable like "/Users/*/anaconda?/envs/python*/bin/python*")
'''
min_endpoint_version = "8.4.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 = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "8.4.0"
Stages and Predicates
Stage 1: process
process where event.action == "process_open" and
(process.code_signature.trusted == false or process.code_signature.exists == false) and
not process.executable like~ ("/private/var/folders/*",
"/Users/*/.pyenv/*",
"/opt/homebrew/*",
"/nix/store/*",
"/Users/*/.homebrew/*",
"/Users/*/miniconda3/envs/*",
"/usr/local/Cellar/*",
"/usr/local/Caskroom/*",
"/System/*") and
not process.name == "htop" and
not Target.process.executable like "/Users/*/anaconda3/envs/python*" and
not (startswith~(process.parent.executable, Target.process.executable) or
startswith~(process.executable, Target.process.executable)) and
not process.hash.sha256 : ("d41e02b5366b186a237f33150baa7c5ef4747ba06646a193ab9ba5125fc6ef7a",
"bee1a00ffb1c4b7c2c4784a1fdcb849dc7853b9deb5173ff4c5a08209c84bc26",
"6ac6f81d80afff9b6ee9d3608d9964566a39188d0166ae867df97c624e632b98",
"8698f4e54c64667c4a4c7ccde3fbcd7babc6478a5e8e22732732f633cc2fc499") and
not (process.executable like "/Users/*/micromamba/envs/grid/bin/python*" and Target.process.executable in ("/bin/bash", "/usr/bin/which", "/usr/bin/uname")) and
not (process.executable like "/Users/*/.local/share/uv/python/cpython-*-macos-aarch64-none/bin/python*" and Target.process.executable like "/Users/*/Code/eis-ray/.venv/lib/python*/site-packages/ray/core/src/ray/gcs/gcs_server") and
not (process.executable like "/Users/*/anaconda?/bin/python*" and Target.process.executable like "/Users/*/anaconda?/envs/python*/bin/python*")
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
URL as argument to Python Script and Immediate Network Connection
#Detects when a URL is supplied as an argument to a python script via the commandline. Threat actors have been seen utilizing this technique in order to download additional payloads stages or tools.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Command & Control |
Telemetry Coverage
Rule Body
[rule]
description = """
Detects when a URL is supplied as an argument to a python script via the commandline. Threat actors have been seen
utilizing this technique in order to download additional payloads stages or tools.
"""
id = "d230b7d8-b5cf-4d94-ba4c-4635f8c0497c"
license = "Elastic License v2"
name = "URL as argument to Python Script and Immediate Network Connection"
os_list = ["macos"]
version = "1.0.7"
query = '''
sequence by process.entity_id with maxspan=30s
[process where event.type == "start" and event.action == "exec" and
process.args like~ "python*" and process.args like ("/Users/*", "/tmp/*", "/private/tmp/*", "/var/tmp/*") and
process.args like~ "http*" and
process.args_count <= 3 and
not process.name in ("curl", "nscurl", "wget", "git", "git-remote-http", "http", "hg")]
[network where event.type == "start"]
'''
min_endpoint_version = "8.16.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 = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"
[[threat.technique.subtechnique]]
id = "T1071.001"
name = "Web Protocols"
reference = "https://attack.mitre.org/techniques/T1071/001/"
[[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.16.0"
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.action == "exec" and
process.args like~ "python*" and process.args like ("/Users/*", "/tmp/*", "/private/tmp/*", "/var/tmp/*") and
process.args like~ "http*" and
process.args_count <= 3 and
not process.name in ("curl", "nscurl", "wget", "git", "git-remote-http", "http", "hg")]
Stage 2: network
[network where event.type == "start"]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.args_count | le |
| field:"process.args_count" kind:le value:"3" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.name | in | curl, git, git-remote-http, hg, http, nscurl, wget | excludes:process.name |
User Keychain copied via Shell interpreter
#Detects when the copy command is used to copy the user keychain database via a shell interpreter. Some recent malware stealer samples have been seen using this technique to retrieve sensitive files prior to exfiltration. The copying of the user keychain database is not normal activity under almost any circumstance and should be considered highly suspicious if not malicious.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Telemetry Coverage
Rule Body
[rule]
description = """
Detects when the copy command is used to copy the user keychain database via a shell interpreter. Some recent malware
stealer samples have been seen using this technique to retrieve sensitive files prior to exfiltration. The copying of
the user keychain database is not normal activity under almost any circumstance and should be considered highly
suspicious if not malicious.
"""
id = "8b0e22e0-dfee-46fa-8695-be94334d34f1"
license = "Elastic License v2"
name = "User Keychain copied via Shell interpreter"
os_list = ["macos"]
reference = ["https://hunt.io/blog/macos-malware-impersonates-the-unarchiver-app-to-steal-user-data"]
version = "1.0.3"
query = '''
process where event.type == "start" and event.action == "exec" and process.name == "cp" and
process.command_line like~ "*/Users/*/Library/Keychains/login.keychain-db*" and
process.parent.name in~ ("bash", "zsh", "sh", "Terminal")
'''
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 = "T1555"
name = "Credentials from Password Stores"
reference = "https://attack.mitre.org/techniques/T1555/"
[[threat.technique.subtechnique]]
id = "T1555.001"
name = "Keychain"
reference = "https://attack.mitre.org/techniques/T1555/001/"
[threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[internal]
min_endpoint_version = "8.11.0"
Stages and Predicates
Stage 1: process
process where event.type == "start" and event.action == "exec" and process.name == "cp" and
process.command_line like~ "*/Users/*/Library/Keychains/login.keychain-db*" and
process.parent.name in~ ("bash", "zsh", "sh", "Terminal")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard value:"*/Users/*/Library/Keychains/login.keychain-db*" |
process.name | eq |
| field:"process_basename" kind:eq value:"cp" |
process.parent.name | in |
| field:"parent_process_basename" kind:in |