Detection rules › Elastic
Elastic rules: 07
Attempt to Enable the Root Account
#Identifies attempts to enable the root account using the dsenableroot command. This command may be abused by adversaries for persistence, as the root account is disabled by default.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Privilege Escalation |
Rule Body
[metadata]
creation_date = "2020/01/04"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
Identifies attempts to enable the root account using the dsenableroot command. This command may be abused by adversaries
for persistence, as the root account is disabled by default.
"""
from = "now-9m"
index = ["logs-endpoint.events.*"]
language = "eql"
license = "Elastic License v2"
name = "Attempt to Enable the Root Account"
references = ["https://ss64.com/osx/dsenableroot.html"]
risk_score = 47
rule_id = "cc2fd2d0-ba3a-4939-b87f-2901764ed036"
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 macOS 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, for MacOS it is recommended to select "Traditional Endpoints".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/current/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: macOS",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "macos" and event.type in ("start", "process_started") and
process.name == "dsenableroot" and
not process.args == "-d"
'''
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 Attempt to Enable the Root Account
In macOS environments, the root account is typically disabled to enhance security. However, adversaries may attempt to enable it using the `dsenableroot` command to gain persistent, elevated access. The detection rule identifies such attempts by monitoring process events for the execution of `dsenableroot` without the disable flag, indicating potential misuse for persistence.
### Possible investigation steps
- Review the process event logs to confirm the execution of the dsenableroot command without the disable flag, as indicated by the absence of process.args:"-d".
- Identify the user account associated with the process event to determine if the action was initiated by a legitimate user or a potential adversary.
- Check for any recent changes in user account permissions or configurations that might indicate unauthorized access or privilege escalation.
- Investigate any other suspicious activities or process executions around the same time as the dsenableroot command to identify potential lateral movement or further persistence mechanisms.
- Correlate the event with other security alerts or logs from the same host to assess if this is part of a broader attack campaign.
### False positive analysis
- System administrators may legitimately enable the root account for maintenance or troubleshooting. To handle this, create exceptions for known administrator accounts or specific maintenance windows.
- Automated scripts or management tools might use the dsenableroot command as part of their operations. Identify these tools and exclude their process signatures from triggering alerts.
- Educational or testing environments may require enabling the root account for instructional purposes. Implement exclusions for these environments by tagging relevant systems or user accounts.
- Ensure that any exclusion rules are regularly reviewed and updated to reflect changes in administrative practices or tool usage to maintain security integrity.
### Response and remediation
- Immediately isolate the affected macOS system from the network to prevent any potential lateral movement by the adversary.
- Terminate any unauthorized processes associated with the `dsenableroot` command to halt further misuse of elevated privileges.
- Review system logs and user activity to identify any unauthorized changes or access that occurred after the root account was enabled.
- Reset the root account password and disable the root account to prevent further unauthorized access.
- Conduct a thorough scan of the system for any additional signs of compromise or persistence mechanisms that may have been installed.
- Notify the security team and relevant stakeholders about the incident for awareness and further investigation.
- Implement additional monitoring and alerting for any future attempts to enable the root account, ensuring rapid detection and response."""
[[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.003"
name = "Local Accounts"
reference = "https://attack.mitre.org/techniques/T1078/003/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"
[[rule.threat.technique.subtechnique]]
id = "T1078.003"
name = "Local Accounts"
reference = "https://attack.mitre.org/techniques/T1078/003/"
[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
Stages and Predicates
Stage 1: process
process where host.os.type == "macos" and event.type in ("start", "process_started") and
process.name == "dsenableroot" and
not process.args == "-d"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | in |
| field:"event.type" kind:in |
process.name | eq |
| field:"process_basename" kind:eq value:"dsenableroot" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | eq | -d | excludes:process.args field:"process.args" value:"-d" |
AWS Service Quotas Multi-Region GetServiceQuota Requests
#Identifies when a single AWS principal makes GetServiceQuota API calls for the EC2 service quota L-1216C47A, across more than 10 AWS regions within a 30-second window. This quota represents the vCPU limit for on-demand EC2 instances. Adversaries commonly enumerate this quota across regions to assess capacity for large-scale instance deployment, including cryptocurrency mining, malware hosting, or command-and-control infrastructure. This behavior may indicate cloud infrastructure discovery using compromised credentials or a compromised workload.
Known False Positives
- Organizations with mature multi-region operations may legitimately query EC2 service quotas across regions for capacity planning, automation, or compliance validation. Infrastructure-as-code tooling, quota monitoring solutions, or centralized cloud governance platforms may also generate similar activity. Validate the identity, purpose, and historical behavior of the calling principal before treating this activity as malicious.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Discovery |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2024/08/26"
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
Identifies when a single AWS principal makes GetServiceQuota API calls for the EC2 service quota L-1216C47A, across more
than 10 AWS regions within a 30-second window. This quota represents the vCPU limit for on-demand EC2 instances.
Adversaries commonly enumerate this quota across regions to assess capacity for large-scale instance deployment,
including cryptocurrency mining, malware hosting, or command-and-control infrastructure. This behavior may indicate
cloud infrastructure discovery using compromised credentials or a compromised workload.
"""
false_positives = [
"""
Organizations with mature multi-region operations may legitimately query EC2 service quotas across regions for
capacity planning, automation, or compliance validation. Infrastructure-as-code tooling, quota monitoring solutions,
or centralized cloud governance platforms may also generate similar activity. Validate the identity, purpose, and
historical behavior of the calling principal before treating this activity as malicious.
""",
]
from = "now-6m"
language = "esql"
license = "Elastic License v2"
name = "AWS Service Quotas Multi-Region GetServiceQuota Requests"
note = """## Triage and analysis
### Investigating AWS Service Quotas Multi-Region GetServiceQuota Requests
AWS Service Quotas define usage limits for AWS services and are commonly referenced during capacity planning or automation. However, adversaries frequently enumerate EC2 on-demand instance quotas across many regions to identify where they can rapidly deploy compute resources for malicious purposes such as cryptocurrency mining, botnet hosting, or malware staging. This rule detects unusually fast, multi-region enumeration of the EC2 on-demand vCPU quota (`L-1216C47A`), a pattern that is uncommon for normal administrative activity and strongly associated with cloud infrastructure discovery.
### Possible investigation steps
**Identify the actor**
- Review `aws.cloudtrail.user_identity.arn` and `aws.cloudtrail.user_identity.access_key_id` to determine whether the requests originated from an IAM user, role, or assumed role. Validate whether this principal is expected to perform quota discovery or capacity analysis across many regions.
**Evaluate the scope of discovery**
- Review the `cloud.region` values to determine which regions were queried and whether they align with regions normally used by your organization. Rapid enumeration of rarely used or disabled regions increases suspicion.
**Inspect request origin and tooling**
- Review `source.ip`, `source.as.organization.name`, and `user_agent.original` to determine whether the activity originated from a trusted corporate network, known cloud automation environment, or an unexpected hosting provider or VPN.
- Unexpected user agents or hosting providers may indicate compromised credentials or an attacker-controlled instance.
**Correlate with follow-on activity**
- Search for subsequent EC2-related actions such as `RunInstances`, `RequestSpotInstances`, `CreateLaunchTemplate`, or `ModifyInstanceAttribute` following the quota discovery.
- Review recent IAM activity for the same principal, including access key creation, role assumptions, or policy changes.
**Assess intent and risk**
- Determine whether this activity aligns with a known operational task (capacity planning, onboarding, automation testing), or whether it represents unexplained reconnaissance behavior.
- If the principal is newly created, rarely used, or exhibiting other anomalous behavior, treat this as high risk.
### False positive analysis
- Multi-region quota discovery may be legitimate in organizations with global deployments, centralized cloud governance, or automated capacity monitoring.
- Infrastructure-as-code pipelines, quota management tools, or internal cloud platforms may periodically enumerate quotas.
### Response and remediation
- If the activity is unauthorized or suspicious, immediately rotate or disable access keys associated with the principal and revoke active sessions.
- Review CloudTrail activity for evidence of follow-on abuse, particularly EC2 instance launches, network changes, or IAM modifications.
- Apply tighter IAM permissions to restrict access to Service Quotas APIs where not explicitly required.
- Enforce MFA on IAM users and consider conditional access controls (such as source IP or VPC restrictions) for sensitive roles.
- Notify security operations and cloud platform teams to assess potential impact and determine whether containment actions (such as SCP enforcement or account isolation) are required.
- Update detection coverage to monitor for EC2 provisioning attempts following quota discovery to catch resource abuse early.
### Additional information
- **[AWS IR Playbooks](https://github.com/aws-samples/aws-incident-response-playbooks/blob/c151b0dc091755fffd4d662a8f29e2f6794da52c/playbooks/)**
- **[AWS Customer Playbook Framework](https://github.com/aws-samples/aws-customer-playbook-framework/tree/a8c7b313636b406a375952ac00b2d68e89a991f2/docs)**
- **[AWS Knowledge Center – Security Best Practices](https://aws.amazon.com/premiumsupport/knowledge-center/security-best-practices/)**
"""
references = [
"https://www.sentinelone.com/labs/exploring-fbot-python-based-malware-targeting-cloud-and-payment-services/",
"https://docs.aws.amazon.com/servicequotas/2019-06-24/apireference/API_GetServiceQuota.html",
]
risk_score = 21
rule_id = "19be0164-63d2-11ef-8e38-f661ea17fbce"
severity = "low"
tags = [
"Domain: Cloud",
"Data Source: AWS",
"Data Source: Amazon Web Services",
"Data Source: AWS Service Quotas",
"Use Case: Threat Detection",
"Tactic: Discovery",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-aws.cloudtrail-* METADATA _id, _version, _index
// filter for GetServiceQuota API calls
| where
data_stream.dataset == "aws.cloudtrail"
and event.provider == "servicequotas.amazonaws.com"
and event.action == "GetServiceQuota"
// truncate the timestamp to a 30-second window
| eval Esql.time_window_date_trunc = date_trunc(30 seconds, @timestamp)
// dissect request parameters to extract service and quota code
| dissect aws.cloudtrail.request_parameters "{%{?Esql.aws_cloudtrail_request_parameters_service_code_key}=%{Esql.aws_cloudtrail_request_parameters_service_code}, %{?quota_code_key}=%{Esql.aws_cloudtrail_request_parameters_quota_code}}"
// filter for EC2 service quota L-1216C47A (vCPU on-demand instances)
| where Esql.aws_cloudtrail_request_parameters_service_code == "ec2" and Esql.aws_cloudtrail_request_parameters_quota_code == "L-1216C47A"
// keep only the relevant fields
| keep
Esql.time_window_date_trunc,
aws.cloudtrail.user_identity.arn,
cloud.region,
Esql.aws_cloudtrail_request_parameters_service_code,
Esql.aws_cloudtrail_request_parameters_quota_code,
aws.cloudtrail.request_parameters,
@timestamp,
aws.cloudtrail.user_identity.type,
aws.cloudtrail.user_identity.access_key_id,
source.ip,
cloud.account.id,
user_agent.original,
source.as.organization.name,
data_stream.namespace
// count the number of unique regions and total API calls within the time window
| stats
Esql.cloud_region_count_distinct = count_distinct(cloud.region),
Esql.event_count = count(*),
Esql.aws_cloudtrail_request_parameters_values = VALUES(aws.cloudtrail.request_parameters),
Esql.event_timestamp_values = VALUES(@timestamp),
Esql.aws_cloudtrail_user_identity_type_values = VALUES(aws.cloudtrail.user_identity.type),
Esql.aws_cloudtrail_user_identity_access_key_id_values = VALUES(aws.cloudtrail.user_identity.access_key_id),
Esql.source_ip_values = VALUES(source.ip),
Esql.cloud_account_id_values = VALUES(cloud.account.id),
Esql.user_agent_original_values = VALUES(user_agent.original),
Esql.source_as_organization_name_values = VALUES(source.as.organization.name),
Esql.cloud_region_values = VALUES(cloud.region),
Esql.data_stream_namespace_values = VALUES(data_stream.namespace)
by Esql.time_window_date_trunc, aws.cloudtrail.user_identity.arn
// filter for API calls in more than 10 regions within the 30-second window
| where
Esql.cloud_region_count_distinct >= 10
and Esql.event_count >= 10
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1526"
name = "Cloud Service Discovery"
reference = "https://attack.mitre.org/techniques/T1526/"
[[rule.threat.technique]]
id = "T1580"
name = "Cloud Infrastructure Discovery"
reference = "https://attack.mitre.org/techniques/T1580/"
[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
[rule.investigation_fields]
field_names = [
"Esql.cloud_region_count_distinct",
"Esql.event_count",
"Esql.time_window_date_trunc",
"Esql.event_timestamp_values",
"aws.cloudtrail.user_identity.arn",
"Esql.aws_cloudtrail_user_identity_type_values",
"Esql.aws_cloudtrail_user_identity_access_key_id_values",
"Esql.source_ip_values",
"Esql.source_as_organization_name_values",
"Esql.user_agent_original_values",
"Esql.cloud_account_id_values",
"Esql.cloud_region_values",
"Esql.data_stream_namespace_values",
]
Stages and Predicates
Stage 1: from
from logs-aws.cloudtrail-* METADATA _id, _version, _index
Stage 2: where
| where
data_stream.dataset == "aws.cloudtrail"
and event.provider == "servicequotas.amazonaws.com"
and event.action == "GetServiceQuota"
Stage 3: eval
| eval Esql.time_window_date_trunc = date_trunc(30 seconds, @timestamp)
Stage 4: dissect
| dissect aws.cloudtrail.request_parameters "{%{?Esql.aws_cloudtrail_request_parameters_service_code_key}=%{Esql.aws_cloudtrail_request_parameters_service_code}, %{?quota_code_key}=%{Esql.aws_cloudtrail_request_parameters_quota_code}}"
Stage 5: where
| where Esql.aws_cloudtrail_request_parameters_service_code == "ec2" and Esql.aws_cloudtrail_request_parameters_quota_code == "L-1216C47A"
Stage 6: keep
| keep
Esql.time_window_date_trunc,
aws.cloudtrail.user_identity.arn,
cloud.region,
Esql.aws_cloudtrail_request_parameters_service_code,
Esql.aws_cloudtrail_request_parameters_quota_code,
aws.cloudtrail.request_parameters,
@timestamp,
aws.cloudtrail.user_identity.type,
aws.cloudtrail.user_identity.access_key_id,
source.ip,
cloud.account.id,
user_agent.original,
source.as.organization.name,
data_stream.namespace
Stage 7: stats
| stats
Esql.cloud_region_count_distinct = count_distinct(cloud.region),
Esql.event_count = count(*),
Esql.aws_cloudtrail_request_parameters_values = VALUES(aws.cloudtrail.request_parameters),
Esql.event_timestamp_values = VALUES(@timestamp),
Esql.aws_cloudtrail_user_identity_type_values = VALUES(aws.cloudtrail.user_identity.type),
Esql.aws_cloudtrail_user_identity_access_key_id_values = VALUES(aws.cloudtrail.user_identity.access_key_id),
Esql.source_ip_values = VALUES(source.ip),
Esql.cloud_account_id_values = VALUES(cloud.account.id),
Esql.user_agent_original_values = VALUES(user_agent.original),
Esql.source_as_organization_name_values = VALUES(source.as.organization.name),
Esql.cloud_region_values = VALUES(cloud.region),
Esql.data_stream_namespace_values = VALUES(data_stream.namespace)
by Esql.time_window_date_trunc, aws.cloudtrail.user_identity.arn
Stage 8: where
| where
Esql.cloud_region_count_distinct >= 10
and Esql.event_count >= 10
Indicators
These rows show field, operator, and value matches.
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Esql.cloud_region_count_distinct | STATS Esql.cloud_region_count_distinct = count_distinct(cloud.region) |
Esql.event_count | STATS Esql.event_count = count(*) |
Esql.aws_cloudtrail_request_parameters_values | STATS Esql.aws_cloudtrail_request_parameters_values = VALUES(aws.cloudtrail.request_parameters) |
Esql.event_timestamp_values | STATS Esql.event_timestamp_values = VALUES(@timestamp) |
Esql.aws_cloudtrail_user_identity_type_values | STATS Esql.aws_cloudtrail_user_identity_type_values = VALUES(aws.cloudtrail.user_identity.type) |
Esql.aws_cloudtrail_user_identity_access_key_id_values | STATS Esql.aws_cloudtrail_user_identity_access_key_id_values = VALUES(aws.cloudtrail.user_identity.access_key_id) |
Esql.source_ip_values | STATS Esql.source_ip_values = VALUES(source.ip) |
Esql.cloud_account_id_values | STATS Esql.cloud_account_id_values = VALUES(cloud.account.id) |
Esql.user_agent_original_values | STATS Esql.user_agent_original_values = VALUES(user_agent.original) |
Esql.source_as_organization_name_values | STATS Esql.source_as_organization_name_values = VALUES(source.as.organization.name) |
Esql.cloud_region_values | STATS Esql.cloud_region_values = VALUES(cloud.region) |
Esql.data_stream_namespace_values | STATS Esql.data_stream_namespace_values = VALUES(data_stream.namespace) |
Esql.time_window_date_trunc | STATS BY |
aws.cloudtrail.user_identity.arn | STATS BY |
Bun Script Attempted to Access IMDS Metadata
#Identifies Bun scripting interpreter establishing a network connection to the link-local instance metadata service address (169.254.169.254). Adversaries and cloud malware often query the instance metadata API to harvest IAM credentials, tokens, and other secrets from cloud-hosted workloads.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Rule Body
[rule]
description = """
Identifies Bun scripting interpreter establishing a network connection to the link-local instance metadata service
address (169.254.169.254). Adversaries and cloud malware often query the instance metadata API to harvest IAM
credentials, tokens, and other secrets from cloud-hosted workloads.
"""
id = "04a04478-10b8-4b3f-a4e1-fe0c49c0f65b"
license = "Elastic License v2"
name = "Bun Script Attempted to Access IMDS Metadata"
os_list = ["linux", "windows"]
reference = [
"https://attack.mitre.org/techniques/T1552/005/",
"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html",
"https://www.elastic.co/security-labs/shai-hulud-chaindrop-npm-supply-chain",
]
version = "1.0.0"
query = '''
sequence by process.entity_id with maxspan=1m
[process where event.type == "start" and event.action in ("start", "exec") and process.name : ("bun", "bun.exe") and
not process.command_line like ("bun --watch src/app.ts",
"bun test src/integrations/__tests__/*",
"bun run scripts/ingest-resilience-retrospectives.ts --ingest",
"bun packages/product-config/codegen/api-codegen.ts",
"bun run apps/backend/probe-pagination.ts")]
[network where event.action == "connection_attempted" and destination.address == "169.254.169.254" and destination.port == 80]
'''
min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1552"
name = "Unsecured Credentials"
reference = "https://attack.mitre.org/techniques/T1552/"
[[threat.technique.subtechnique]]
id = "T1552.005"
name = "Cloud Instance Metadata API"
reference = "https://attack.mitre.org/techniques/T1552/005/"
[threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 1m, correlated by process.entity_id.
Stage 1: process
[process where event.type == "start" and event.action in ("start", "exec") and process.name : ("bun", "bun.exe") and
not process.command_line like ("bun --watch src/app.ts",
"bun test src/integrations/__tests__/*",
"bun run scripts/ingest-resilience-retrospectives.ts --ingest",
"bun packages/product-config/codegen/api-codegen.ts",
"bun run apps/backend/probe-pagination.ts")]
Stage 2: network
[network where event.action == "connection_attempted" and destination.address == "169.254.169.254" and destination.port == 80]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
destination.address | eq |
| field:"destination.address" kind:eq value:"169.254.169.254" |
destination.port | eq |
| field:"DestinationPort" kind:eq value:"80" |
event.action | eq |
| field:"EventType" kind:eq value:"connection_attempted" |
event.action | in |
| field:"EventType" kind:in |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.command_line | wildcard | bun --watch src/app.ts, bun test src/integrations/__tests__/*, bun run scripts/ingest-resilience-retrospectives.ts --ingest, bun packages/product-config/codegen/api-codegen.ts, bun run apps/backend/probe-pagination.ts | excludes:process.command_line |
First Time Seen RMM Signer Across the Environment
#Identifies a newly observed RMM-related code-signature subject across the Windows Elastic Defend hosts. Attackers often use RMM tools to gain remote access to victim machines and deploy malware.
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 = "2026/07/28"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/07/28"
[rule]
author = ["Elastic"]
description = """
Identifies a newly observed RMM-related code-signature subject across the Windows Elastic Defend hosts. Attackers often
use RMM tools to gain remote access to victim machines and deploy malware.
"""
from = "now-9m"
index = ["logs-endpoint.events.process-*"]
language = "kuery"
license = "Elastic License v2"
name = "First Time Seen RMM Signer Across the Environment"
references = [
"https://thedfirreport.com/2023/04/03/malicious-iso-file-leads-to-domain-wide-ransomware/",
"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 = "bb8dac47-0271-4000-b4e3-1bfc75eec5c4"
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
"""
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Command and Control",
"Resources: Investigation Guide",
"Data Source: Elastic Defend",
]
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"
)
'''
note = """## Triage and analysis
### Investigating First Time Seen RMM Signer Across the Environment
Attackers abuse legitimate RMM and remote-access software to open interactive sessions, persist, and stage follow-on tooling while blending into IT support activity. This rule alerts on a Windows Elastic Defend process start whose `process.code_signature.subject_name` matches a curated vendor list, when that subject is first seen across the visible fleet in the 10-day new_terms history window. Novelty is keyed only on the signer subject, so each certificate string alerts once environment-wide and renamed binaries that still carry a listed signer still match. Signature trust is not a query condition; review `process.code_signature.trusted` as context only.
#### Possible investigation steps
- Is the matched binary a remote-access component, or an unrelated product that shares this signer?
- Focus: `process.executable`, `process.name`, `process.pe.original_file_name`, `process.command_line`.
- Review the other binaries this signer started on the alerted host with $investigate_0
- Implication: Several vendors on this list also ship backup, virtualization, terminal-emulation, and management software under the same certificate, so a signer's first appearance is often not its remote-access product. A path, original file name, and command line matching the vendor's remote-access agent keeps that hypothesis active. An unrelated product from the same vendor makes this a low-value observation that still consumes the signer's novelty term, so confirm the vendor's remote-access footprint now rather than waiting for a later alert this rule will not produce.
- Does the parent and session context explain why this process launched on this host?
- Focus: `process.parent.executable`, `process.parent.command_line`, `process.Ext.session_info.logon_type`, `process.Ext.token.elevation_level`, `user.name`.
- Retrieve the parent process event while the parent entity is still retained with $investigate_1
- Implication: A parent consistent with a software-deployment service or a scheduled management task keeps this inside a rollout hypothesis. A launch from a browser, archive, mail client, script interpreter, or an unexpected interactive session points instead to social engineering or staged access.
- What did the matched process start after launch?
- Focus: child `process.name`, `process.command_line`, `process.parent.entity_id`.
- Review child process starts on the same host with $investigate_2
- Implication: No child process evidence is unresolved, not benign. Children limited to the vendor's own service and updater binaries stay consistent with normal tool operation without proving the deployment was authorized, while child shells, script interpreters, discovery commands, or credential tooling are suspicious.
- Did the same process perform remote-access network activity that changes the host scope?
- Focus: `destination.ip`, `destination.port`, `network.direction`.
- Review endpoint network events for the same process entity with $investigate_3
- Implication: Missing network telemetry is unresolved, not benign. Sessions to the vendor's own service endpoints show the tool operating normally but do not establish who initiated the session, while connections to unrelated external infrastructure keep the case open for escalation and wider scoping.
- If local evidence is suspicious or unresolved, is the same signer or executable hash appearing beyond the alerted host?
- Focus: `process.code_signature.subject_name`, `process.hash.sha256`, `process.executable`, `host.name`, `user.name`.
- Review recent process starts sharing the matched signer or executable hash with $investigate_4; the pivot is bounded to the last 24 hours for performance, so widen the Timeline range when the deployment window or suspected activity is older.
- Implication: Additional hosts or users shift the hypothesis from a single host deployment to an environment-wide remote-access introduction and should expand response scope. This rule reports a signer once for the whole fleet, so it will not alert again for this vendor and will not alert at all on a renamed binary reusing an already-observed signer; a clean 24-hour pivot therefore bounds recent spread only and is not evidence that spread has stopped.
After these checks, escalate when source process, parent, network, or cross-host evidence is suspicious; close only when alert-local and recovered evidence prove the exact expected host/user/signer/hash scope with verified owner confirmation; preserve and escalate mixed or incomplete cases for more context.
### False positive analysis
- This rule can alert on a real but expected first appearance of a listed signer when a software rollout, support session, or vendor agent introduction reaches the Elastic Defend fleet for the first time in the 10-day history window.
- Treat benign disposition as evidence-bounded: the alert's `process.code_signature.subject_name`, `process.executable`, `process.hash.sha256`, `host.id`, `host.name`, `user.id`, and `user.domain` should match a validated change record or verified owner confirmation for the exact system and activity.
- Treat `process.code_signature.trusted` as contextual evidence, not clearance: a trusted signature does not establish authorization or benign intent, and an untrusted, invalid, or missing trust value does not by itself prove malicious use.
- Certificate subjects that differ only in case or punctuation are separate novelty terms, so a single vendor can produce more than one alert as its certificate strings drift across products and releases. Correlate those and treat them as one introduction rather than as repeat findings.
- When justified, scope an exception conjunctively to the exact `process.code_signature.subject_name` plus `process.executable`, further bounded by supported host/user anchors such as `host.id`, `host.name`, `user.id`, or `user.domain`; never exclude on signer alone. `process.hash.sha256` is precise for scoping one investigation but is not a durable exception anchor, because the vendor's next release changes it and the exception silently stops matching.
- Expect an exception to have limited effect here, because the first alert already consumes that signer's novelty term for the history window; an exception only applies if the signer disappears from the visible fleet for more than 10 days and returns. `user.name` appears in the Focus lines for readability during analysis, while exception criteria prefer `user.id` and `user.domain` as stable identifiers rather than display names.
### Response and remediation
- Preserve or export case evidence plus volatile process, memory, executable, and file-system artifacts that could be lost before isolation, process termination, cleanup, or other disruptive action.
- Scope the activity by signer, executable hash, process entity, host, and user before containment; include child processes, same-process network events when available, and any later hosts that show the same signer or hash.
- If malicious use is confirmed, contain affected hosts through the endpoint response integration when available and contain affected accounts using reversible controls first; if direct endpoint response is unavailable, document the collected evidence and artifacts and hand them off to the responsible endpoint or incident-response team able to act. After evidence collection and scoping, terminate malicious processes, remove persistence, and clean up remote-access tooling.
- Review collected evidence for credential exposure, lateral movement, and follow-on tooling before final remediation decisions.
- Document confirmed indicators and any logging or detection gaps for the responsible detection or logging owners after scoping and containment.
"""
[rule.investigation_fields]
field_names = [
"@timestamp",
"host.id",
"host.name",
"user.id",
"user.name",
"user.domain",
"process.entity_id",
"process.parent.entity_id",
"process.code_signature.subject_name",
"process.code_signature.trusted",
"process.name",
"process.executable",
"process.pe.original_file_name",
"process.command_line",
"process.hash.sha256",
"process.Ext.session_info.logon_type",
"process.Ext.token.elevation_level",
]
[[transform.investigate]]
label = "Signer footprint on the alerted host"
description = "Show which binaries sharing the matched code-signature subject started on the alerted host during the investigation window."
providers = [[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.code_signature.subject_name", queryType = "phrase", value = "{{process.code_signature.subject_name}}", valueType = "string" },
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
{ excluded = false, field = "event.type", queryType = "phrase", value = "start", valueType = "string" },
]]
relativeFrom = "now-24h/h"
relativeTo = "now"
[[transform.investigate]]
label = "Parent process context"
description = "Find the parent process event for the matched launch when the parent entity is retained."
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" },
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
]]
relativeFrom = "now-24h/h"
relativeTo = "now"
[[transform.investigate]]
label = "Child process starts"
description = "Find child process starts spawned by the matched process on the same host."
providers = [[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
{ excluded = false, field = "event.type", queryType = "phrase", value = "start", valueType = "string" },
]]
relativeFrom = "now-24h/h"
relativeTo = "now"
[[transform.investigate]]
label = "Same-process network events"
description = "Search for endpoint network events tied to the matched process entity on the same host."
providers = [[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
{ excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" },
]]
relativeFrom = "now-24h/h"
relativeTo = "now"
[[transform.investigate]]
label = "Recent signer and hash spread"
description = "Search the 24-hour investigation window for process starts that share the matched signer or executable hash. Widen the Timeline range to look further back."
providers = [[
{ excluded = false, field = "process.code_signature.subject_name", queryType = "phrase", value = "{{process.code_signature.subject_name}}", valueType = "string" },
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
{ excluded = false, field = "event.type", queryType = "phrase", value = "start", valueType = "string" },
], [
{ excluded = false, field = "process.hash.sha256", queryType = "phrase", value = "{{process.hash.sha256}}", valueType = "string" },
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
{ excluded = false, field = "event.type", queryType = "phrase", value = "start", valueType = "string" },
]]
relativeFrom = "now-24h/h"
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 = ["process.code_signature.subject_name"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-10d"
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"
)
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 |
High Number of Egress Network Connections from Unusual Executable
#This rule detects a high number of egress network connections from an unusual executable on a Linux system. This could indicate a command and control (C2) communication attempt, a brute force attack via a malware infection, or other malicious activity. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth | |
| Command & Control |
Rule Body
[metadata]
creation_date = "2025/02/20"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
This rule detects a high number of egress network connections from an unusual executable on a Linux system. This could
indicate a command and control (C2) communication attempt, a brute force attack via a malware infection, or other
malicious activity. ESQL rules have limited fields available in its alert documents. Make sure to review the original
documents to aid in the investigation of this alert.
"""
from = "now-61m"
interval = "1h"
language = "esql"
license = "Elastic License v2"
name = "High Number of Egress Network Connections from Unusual Executable"
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 High Number of Egress Network Connections from Unusual Executable
In Linux environments, executables can initiate network connections for legitimate purposes. However, adversaries exploit this by deploying malware in temporary directories to establish command and control (C2) channels. The detection rule identifies unusual executables making numerous outbound connections, excluding trusted IP ranges and known benign paths, to flag potential threats.
### Possible investigation steps
- Review the process.executable field to identify the specific executable making the connections and determine if it is known or expected in the environment.
- Examine the destination.ip field to identify the external IP addresses the executable is attempting to connect to and check if they are known malicious or suspicious.
- Check the host.os.type and agent.id fields to identify the specific host and agent involved, and gather additional context about the system's role and recent activity.
- Analyze the @timestamp field to correlate the timing of the connections with other events or activities on the network or host.
- Cross-reference the identified executable and IP addresses with threat intelligence sources to determine if they are associated with known threats or campaigns.
- If the executable is determined to be malicious or suspicious, isolate the affected host and perform a deeper forensic analysis to identify any additional indicators of compromise or lateral movement.
### False positive analysis
- Executables in temporary directories used by legitimate applications or scripts can trigger alerts. Review the process name and executable path to determine if they are associated with known applications or scripts.
- Automated scripts or cron jobs that perform network operations might be flagged. Identify these scripts and consider excluding their paths from the rule if they are verified as non-malicious.
- Development or testing environments often use temporary directories for network operations. If these environments are known and trusted, add their specific paths to the exclusion list.
- Backup or synchronization tools that use temporary directories for data transfer can generate numerous connections. Verify these tools and exclude their paths if they are confirmed to be safe.
- Security tools or monitoring agents that operate in temporary directories might be mistakenly flagged. Confirm their legitimacy and exclude their paths to prevent false positives.
### Response and remediation
- Isolate the affected host immediately from the network to prevent further potential malicious communication and lateral movement.
- Terminate the suspicious process identified by the alert to stop any ongoing malicious activity.
- Conduct a forensic analysis of the affected system to identify any additional indicators of compromise (IOCs) and assess the extent of the infection.
- Remove any malicious executables or files found in temporary directories such as /tmp, /var/tmp, or /dev/shm to eliminate the threat.
- Patch and update the affected system to the latest security standards to close any vulnerabilities that may have been exploited.
- Monitor network traffic for any unusual outbound connections from other systems to detect potential spread or similar threats.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to ensure comprehensive remediation.
"""
risk_score = 47
rule_id = "1fa350e0-0aa2-4055-bf8f-ab8b59233e59"
setup = """## Setup
This rule requires data coming in from Elastic Defend.
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Command and Control",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-endpoint.events.network-* metadata _id, _index, _version
| mv_expand event.action
| where
host.os.type == "linux" and
event.type == "start" and
event.action == "connection_attempted" and
(
process.executable like "/tmp/*" or
process.executable like "/var/tmp/*" or
process.executable like "/dev/shm/*" or
process.executable like "/var/log/*" or
process.executable like "/sys/*" or
process.executable like "/media/*" or
process.executable like "/proc/*" or
process.executable like "/var/backups/*" or
process.executable like "/var/mail/*" or
process.executable like "/var/spool/*" or
process.executable like "./*" or
process.name like ".*"
) and
not (
cidr_match(destination.ip,
"10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12",
"192.0.0.0/24", "192.0.0.29/32", "192.0.0.8/32", "192.0.0.9/32",
"192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24",
"192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24",
"224.0.0.0/4", "100.64.0.0/10", "192.175.48.0/24", "198.18.0.0/15",
"198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1", "FE80::/10", "FF00::/8"
) or
process.executable like "/tmp/newroot/*" or
process.executable like "/tmp/.mount*" or
process.executable like "/tmp/go-build*"
)
| keep
@timestamp,
_id,
_index,
_version,
host.os.type,
event.type,
event.action,
process.name,
process.executable,
destination.ip,
agent.id,
host.name,
data_stream.dataset,
data_stream.namespace
| stats
Esql.event_count = count(),
Esql.agent_id_count_distinct = count_distinct(agent.id),
Esql.host_name_values = values(host.name),
Esql.agent_id_values = values(agent.id),
Esql.data_stream_dataset_values = values(data_stream.dataset),
Esql.data_stream_namespace_values = values(data_stream.namespace)
by process.executable
| where
Esql.agent_id_count_distinct == 1 and
Esql.event_count > 15
// Extract unique values to ECS fields for alerts exclusion
| eval agent.id = mv_min(Esql.agent_id_values),
host.name = mv_min(Esql.host_name_values)
| sort Esql.event_count asc
| keep agent.id, host.name, process.executable, Esql.*
'''
[[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 = "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/"
Stages and Predicates
Stage 1: from
from logs-endpoint.events.network-* metadata _id, _index, _version
Stage 2: mv_expand
| mv_expand event.action
Stage 3: where
| where
host.os.type == "linux" and
event.type == "start" and
event.action == "connection_attempted" and
(
process.executable like "/tmp/*" or
process.executable like "/var/tmp/*" or
process.executable like "/dev/shm/*" or
process.executable like "/var/log/*" or
process.executable like "/sys/*" or
process.executable like "/media/*" or
process.executable like "/proc/*" or
process.executable like "/var/backups/*" or
process.executable like "/var/mail/*" or
process.executable like "/var/spool/*" or
process.executable like "./*" or
process.name like ".*"
) and
not (
cidr_match(destination.ip,
"10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12",
"192.0.0.0/24", "192.0.0.29/32", "192.0.0.8/32", "192.0.0.9/32",
"192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24",
"192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24",
"224.0.0.0/4", "100.64.0.0/10", "192.175.48.0/24", "198.18.0.0/15",
"198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1", "FE80::/10", "FF00::/8"
) or
process.executable like "/tmp/newroot/*" or
process.executable like "/tmp/.mount*" or
process.executable like "/tmp/go-build*"
)
Stage 4: keep
| keep
@timestamp,
_id,
_index,
_version,
host.os.type,
event.type,
event.action,
process.name,
process.executable,
destination.ip,
agent.id,
host.name,
data_stream.dataset,
data_stream.namespace
Stage 5: stats
| stats
Esql.event_count = count(),
Esql.agent_id_count_distinct = count_distinct(agent.id),
Esql.host_name_values = values(host.name),
Esql.agent_id_values = values(agent.id),
Esql.data_stream_dataset_values = values(data_stream.dataset),
Esql.data_stream_namespace_values = values(data_stream.namespace)
by process.executable
Stage 6: where
| where
Esql.agent_id_count_distinct == 1 and
Esql.event_count > 15
Stage 7: eval
| eval agent.id = mv_min(Esql.agent_id_values),
host.name = mv_min(Esql.host_name_values)
Stage 8: sort
| sort Esql.event_count asc
Stage 9: keep
| keep agent.id, host.name, process.executable, Esql.*
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Esql.agent_id_count_distinct | eq |
| field:"Esql.agent_id_count_distinct" kind:eq value:"1" |
Esql.event_count | gt |
| field:"Esql.event_count" kind:gt value:"15" |
event.action | eq |
| field:"EventType" kind:eq value:"connection_attempted" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.executable | wildcard |
| field:"Image" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:".*" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
destination.ip | cidr_match | 10.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.0.0.0/24, 192.0.0.29/32, 192.0.0.8/32, 192.0.0.9/32, 192.0.0.10/32, 192.0.0.170/32, 192.0.0.171/32, 192.0.2.0/24, 192.31.196.0/24, 192.52.193.0/24, 192.168.0.0/16, 192.88.99.0/24, 224.0.0.0/4, 100.64.0.0/10, 192.175.48.0/24, 198.18.0.0/15, 198.51.100.0/24, 203.0.113.0/24, 240.0.0.0/4, ::1, FE80::/10, FF00::/8 | excludes:destination.ip |
process.executable | starts_with | /tmp/.mount | excludes:process.executable field:"process.executable" value:"/tmp/.mount" |
process.executable | starts_with | /tmp/go-build | excludes:process.executable field:"process.executable" value:"/tmp/go-build" |
process.executable | starts_with | /tmp/newroot/ | excludes:process.executable field:"process.executable" value:"/tmp/newroot/" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
agent.id | KEEP agent.id |
host.name | KEEP host.name |
process.executable | KEEP process.executable |
Esql.* | KEEP Esql.* |
Initial Access Staging via Installer Package
#Detects when an installer package creates a new directory structure and immediately moves an executable file into that directory. Threat actors will often include system preparation steps in their initial access installer packages implemented via pre or post install scripts with the purpose of preparing a location to drop and execute their payload from that won't raise suspicion.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence |
Rule Body
[rule]
description = """
Detects when an installer package creates a new directory structure and immediately moves an executable file into that
directory. Threat actors will often include system preparation steps in their initial access installer packages
implemented via pre or post install scripts with the purpose of preparing a location to drop and execute their payload
from that won't raise suspicion.
"""
id = "6e53dbb1-55c6-419c-ab8e-75a5d53aac49"
license = "Elastic License v2"
name = "Initial Access Staging via Installer Package"
os_list = ["macos"]
version = "1.0.12"
query = '''
sequence by process.entity_id with maxspan=15s
[process where event.type == "start" and process.Ext.effective_parent.name == "installer" and
process.parent.name : ("bash", "sh", "zsh", "dash", "csh", "tcsh", "ksh", "tclsh*", "fish") and process.name in ("cp", "mv")]
[file where event.action != "deletion" and file.Ext.header_bytes like~ ("cffaedfe*", "cafebabe*") and
(file.name like~ ".*" or file.path like
("/Users/Shared/*",
"/tmp/*",
"/private/tmp/*",
"/var/tmp/*",
"/Library/WebServer/*",
"/Library/Graphics/*",
"/Library/Fonts/*")) and
not file.path like
("/private/tmp/org.gpgtools/gpgmailloader_install/GPGMailLoader.signed.mailbundle/Contents/MacOS/GPGMailLoader",
"/private/tmp/PKInstallSandbox*")]
'''
min_endpoint_version = "8.8.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 = "T1546"
name = "Event Triggered Execution"
reference = "https://attack.mitre.org/techniques/T1546/"
[[threat.technique.subtechnique]]
id = "T1546.016"
name = "Installer Packages"
reference = "https://attack.mitre.org/techniques/T1546/016/"
[threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[internal]
min_endpoint_version = "8.8.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 15s, correlated by process.entity_id.
Stage 1: process
[process where event.type == "start" and process.Ext.effective_parent.name == "installer" and
process.parent.name : ("bash", "sh", "zsh", "dash", "csh", "tcsh", "ksh", "tclsh*", "fish") and process.name in ("cp", "mv")]
Stage 2: file
[file where event.action != "deletion" and file.Ext.header_bytes like~ ("cffaedfe*", "cafebabe*") and
(file.name like~ ".*" or file.path like
("/Users/Shared/*",
"/tmp/*",
"/private/tmp/*",
"/var/tmp/*",
"/Library/WebServer/*",
"/Library/Graphics/*",
"/Library/Fonts/*")) and
not file.path like
("/private/tmp/org.gpgtools/gpgmailloader_install/GPGMailLoader.signed.mailbundle/Contents/MacOS/GPGMailLoader",
"/private/tmp/PKInstallSandbox*")]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | ne |
| field:"EventType" kind:ne value:"deletion" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
file.Ext.header_bytes | wildcard |
| field:"file.Ext.header_bytes" kind:wildcard |
file.name | wildcard |
| field:"file.name" kind:wildcard value:".*" |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard |
process.Ext.effective_parent.name | eq |
| field:"process.Ext.effective_parent.name" kind:eq value:"installer" |
process.name | in |
| field:"process_basename" kind:in |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
file.path | wildcard | /private/tmp/org.gpgtools/gpgmailloader_install/GPGMailLoader.signed.mailbundle/Contents/MacOS/GPGMailLoader, /private/tmp/PKInstallSandbox* | excludes:file.path field:"file.path" value:"/private/tmp/org.gpgtools/gpgmailloader_install/GPGMailLoader.signed.mailbundle/Contents/MacOS/GPGMailLoader" field:"file.path" value:"/private/tmp/PKInstallSandbox*" |
Microsoft Office File Execution via WMI
#Identifies the execution of a file written or modified by Microsoft Office processes followed by a child process spawned via Windows Management Instrumentation (WMI). This behavior may indicate adversarial activity to avoid spawning a suspicious MS Office child process.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Execution |
Rule Body
[rule]
description = """
Identifies the execution of a file written or modified by Microsoft Office processes followed by a child process spawned
via Windows Management Instrumentation (WMI). This behavior may indicate adversarial activity to avoid spawning a
suspicious MS Office child process.
"""
id = "792411bd-59ef-4ac0-89be-786d52d1a5c8"
license = "Elastic License v2"
name = "Microsoft Office File Execution via WMI"
os_list = ["windows"]
reference = [
"https://medium.com/threatpunter/detecting-adversary-tradecraft-with-image-load-event-logging-and-eql-8de93338c16",
]
version = "1.0.31"
query = '''
sequence with maxspan=1m
[file where event.action != "deletion" and
(file.extension : ("exe", "com") or file.Ext.header_bytes : "4d5a*") and
process.name : ("WINWORD.EXE", "EXCEL.EXE", "POWERPNT.EXE", "MSACCESS.EXE", "MSPUB.EXE", "fltldr.exe")] by file.path
[process where event.action == "start" and process.parent.name : "wmiprvse.exe" and
not process.Ext.token.integrity_level_name == "system"] by process.executable
'''
min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 1
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1566"
name = "Phishing"
reference = "https://attack.mitre.org/techniques/T1566/"
[[threat.technique.subtechnique]]
id = "T1566.001"
name = "Spearphishing Attachment"
reference = "https://attack.mitre.org/techniques/T1566/001/"
[threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1047"
name = "Windows Management Instrumentation"
reference = "https://attack.mitre.org/techniques/T1047/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 1m, correlated by file.path, process.executable.
Stage 1: file
[file where event.action != "deletion" and
(file.extension : ("exe", "com") or file.Ext.header_bytes : "4d5a*") and
process.name : ("WINWORD.EXE", "EXCEL.EXE", "POWERPNT.EXE", "MSACCESS.EXE", "MSPUB.EXE", "fltldr.exe")] by file.path
Stage 2: process
[process where event.action == "start" and process.parent.name : "wmiprvse.exe" and
not process.Ext.token.integrity_level_name == "system"] by process.executable
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
event.action | ne |
| field:"EventType" kind:ne value:"deletion" |
file.Ext.header_bytes | wildcard |
| field:"file.Ext.header_bytes" kind:wildcard value:"4d5a*" |
file.extension | wildcard |
| field:"file.extension" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard value:"wmiprvse.exe" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.Ext.token.integrity_level_name | eq | system | excludes:process.Ext.token.integrity_level_name field:"process.Ext.token.integrity_level_name" value:"system" |
Okta Alerts Following Unusual Proxy Authentication
#Correlates the first occurrence of an Okta user session started via a proxy with subsequent Okta security alerts for the same user. Attackers frequently use proxy infrastructure (VPNs, Tor, residential proxies) to mask their origin when using stolen credentials, and their post-authentication activity often triggers additional detection rules.
Known False Positives
- Legitimate users who routinely use VPN or proxy services for privacy may trigger this if they also trigger unrelated security alerts.
- Security testing or red team exercises using proxy infrastructure.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
Rule Body
[metadata]
creation_date = "2026/02/20"
integration = ["okta"]
maturity = "production"
updated_date = "2026/04/27"
[rule]
author = ["Elastic"]
description = """
Correlates the first occurrence of an Okta user session started via a proxy with subsequent Okta security alerts for the
same user. Attackers frequently use proxy infrastructure (VPNs, Tor, residential proxies) to mask their origin when
using stolen credentials, and their post-authentication activity often triggers additional detection rules.
"""
false_positives = [
"""
Legitimate users who routinely use VPN or proxy services for privacy may trigger this if they also trigger unrelated
security alerts.
""",
"Security testing or red team exercises using proxy infrastructure.",
]
from = "now-60m"
index = [".alerts-security.*"]
interval = "30m"
language = "eql"
license = "Elastic License v2"
name = "Okta Alerts Following Unusual Proxy Authentication"
note = """## Triage and analysis
### Investigating Okta Alerts Following Unusual Proxy Authentication
This rule correlates the first occurrences of authentication behind a proxy followed by an alert with subsequent Okta security alerts for the same user. Attackers frequently use proxy infrastructure (VPNs, Tor, residential proxies) to mask their origin when using stolen credentials, and their post-authentication activity often triggers additional detection rules.
By correlating the proxy alert with other Okta alerts using an EQL sequence, this rule identifies users whose proxy-based authentication was followed by suspicious activity within a 1-hour window.
#### Possible investigation steps
- Identify the affected user and review the correlated security alerts to understand what suspicious activity was detected after the proxy authentication.
- Examine the proxy source IP addresses and cross-reference with threat intelligence feeds for known malicious infrastructure.
- Review the time gap between the proxy authentication and subsequent alert generation.
- Review the user's recent Okta activity for signs of account takeover (MFA changes, new devices, unusual app access).
- Verify with the user whether they intentionally used a proxy or VPN during this session.
### False positive analysis
- Users who legitimately use VPN services for privacy or remote work may trigger this rule if they also trigger unrelated alerts.
- Security testing or red team exercises using proxy infrastructure combined with testing that triggers alerts.
- Corporate VPN egress points that Okta classifies as proxy infrastructure.
### Response and remediation
- If account compromise is suspected, immediately revoke all active sessions for the user.
- Reset the user's password and MFA factors.
- Review and revoke any OAuth tokens or API keys associated with the account.
- Block the source proxy IP at the network perimeter if confirmed malicious.
- Review the user's access to sensitive applications and data during the suspicious session.
"""
references = [
"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",
"https://cloud.google.com/blog/topics/threat-intelligence/expansion-shinyhunters-saas-data-theft",
]
risk_score = 73
rule_id = "af2d8e4c-3b7c-4e91-8f5a-6c9d0e1f2a3b"
severity = "high"
tags = [
"Domain: Identity",
"Domain: Cloud",
"Use Case: Identity and Access Audit",
"Use Case: Threat Detection",
"Data Source: Okta",
"Data Source: Okta System Logs",
"Tactic: Initial Access",
"Rule Type: Higher-Order Rule",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
sequence by user.name with maxspan=30m
[any where event.dataset == "okta.system" and
kibana.alert.rule.rule_id == "6f1bb4b2-7dc8-11ee-92b2-f661ea17fbcd"]
[any where event.dataset == "okta.system" and
kibana.alert.rule.rule_id != null and
kibana.alert.severity != "low" and
kibana.alert.rule.rule_id not in (
"6f1bb4b2-7dc8-11ee-92b2-f661ea17fbcd",
"af2d8e4c-3b7c-4e91-8f5a-6c9d0e1f2a3b"
)
]
'''
[[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
Ordered sequence: each step below must occur in order within 30m, correlated by user.name.
Stage 1: any
[any where event.dataset == "okta.system" and
kibana.alert.rule.rule_id == "6f1bb4b2-7dc8-11ee-92b2-f661ea17fbcd"]
Stage 2: any
[any where event.dataset == "okta.system" and
kibana.alert.rule.rule_id != null and
kibana.alert.severity != "low" and
kibana.alert.rule.rule_id not in (
"6f1bb4b2-7dc8-11ee-92b2-f661ea17fbcd",
"af2d8e4c-3b7c-4e91-8f5a-6c9d0e1f2a3b"
)
]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.dataset | eq |
| field:"event.dataset" kind:eq value:"okta.system" |
kibana.alert.rule.rule_id | eq |
| field:"kibana.alert.rule.rule_id" kind:eq value:"6f1bb4b2-7dc8-11ee-92b2-f661ea17fbcd" |
kibana.alert.rule.rule_id | is_not_null | field:"kibana.alert.rule.rule_id" kind:is_not_null | |
kibana.alert.severity | ne |
| field:"kibana.alert.severity" kind:ne value:"low" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
kibana.alert.rule.rule_id | in | 6f1bb4b2-7dc8-11ee-92b2-f661ea17fbcd, af2d8e4c-3b7c-4e91-8f5a-6c9d0e1f2a3b | excludes:kibana.alert.rule.rule_id field:"kibana.alert.rule.rule_id" value:"6f1bb4b2-7dc8-11ee-92b2-f661ea17fbcd" field:"kibana.alert.rule.rule_id" value:"af2d8e4c-3b7c-4e91-8f5a-6c9d0e1f2a3b" |
Ollama API Accessed from External Network
#Detects when the Ollama LLM server accepts connections from external IP addresses. Ollama lacks built-in authentication, so exposed instances allow unauthenticated model theft, prompt injection, and resource hijacking.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
MITRE ATLAS Coverage
Adversarial-ML threat framework (not MITRE ATT&CK).
| Tactic | Techniques |
|---|---|
| AI Model Access |
Rule Body
[metadata]
creation_date = "2026/01/09"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
Detects when the Ollama LLM server accepts connections from external IP addresses. Ollama lacks built-in authentication,
so exposed instances allow unauthenticated model theft, prompt injection, and resource hijacking.
"""
from = "now-9m"
index = ["logs-endpoint.events.network-*"]
language = "eql"
license = "Elastic License v2"
name = "Ollama API Accessed from External Network"
note = """## Triage and analysis
### Investigating Ollama API Accessed from External Network
This rule detects when Ollama accepts connections from external IP addresses. Ollama binds to localhost:11434 by default but can be exposed via OLLAMA_HOST. Since Ollama lacks authentication, exposed instances allow unauthenticated model theft, prompt injection, and resource hijacking.
### Possible investigation steps
- Check the OLLAMA_HOST environment variable to determine if external exposure was intentional.
- Review the source IP address to identify if it's a known attacker, scanner, or miscategorized internal system.
- Examine Ollama logs for suspicious API calls to /api/pull, /api/push, or /api/generate.
- Check ~/.ollama/models/ for unexpected model downloads that may indicate model poisoning.
- Review network traffic for data exfiltration following the connection.
- Look for child processes spawned by Ollama that may indicate exploitation.
### False positive analysis
- Internal networks not properly classified in CIDR ranges may trigger false positives.
- Load balancers or reverse proxies accessing Ollama from external-facing IPs within trusted infrastructure.
- Legitimate remote access through VPN or authenticated proxy (add proxy IPs to exclusions).
### Response and remediation
- Restrict access immediately by setting OLLAMA_HOST=127.0.0.1:11434 or applying firewall rules.
- If exploitation is suspected, stop Ollama and audit ~/.ollama/models/ for unauthorized models.
- Review Ollama and system logs for signs of compromise.
- Consider running Ollama in a container with network isolation.
"""
references = [
"https://www.greynoise.io/blog/threat-actors-actively-targeting-llms",
"https://atlas.mitre.org/techniques/AML.T0040",
"https://atlas.mitre.org/techniques/AML.T0044",
]
risk_score = 47
rule_id = "d8f2a1b3-c4e5-6789-abcd-ef0123456789"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Linux",
"OS: macOS",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Initial Access",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
"Domain: LLM",
"Mitre Atlas: T0040",
"Mitre Atlas: T0044",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
network where event.action == "connection_accepted" and
process.name in ("ollama", "ollama.exe") and
destination.port == 11434 and
source.ip != null and source.ip != "0.0.0.0" and
not cidrmatch(source.ip,
"10.0.0.0/8",
"127.0.0.0/8",
"169.254.0.0/16",
"172.16.0.0/12",
"192.168.0.0/16",
"100.64.0.0/10",
"::1",
"fe80::/10",
"fc00::/7",
"ff00::/8"
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1133"
name = "External Remote Services"
reference = "https://attack.mitre.org/techniques/T1133/"
[[rule.threat.technique]]
id = "T1190"
name = "Exploit Public-Facing Application"
reference = "https://attack.mitre.org/techniques/T1190/"
[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
Stages and Predicates
Stage 1: network
network where event.action == "connection_accepted" and
process.name in ("ollama", "ollama.exe") and
destination.port == 11434 and
source.ip != null and source.ip != "0.0.0.0" and
not cidrmatch(source.ip,
"10.0.0.0/8",
"127.0.0.0/8",
"169.254.0.0/16",
"172.16.0.0/12",
"192.168.0.0/16",
"100.64.0.0/10",
"::1",
"fe80::/10",
"fc00::/7",
"ff00::/8"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
destination.port | eq |
| field:"DestinationPort" kind:eq value:"11434" |
event.action | eq |
| field:"EventType" kind:eq value:"connection_accepted" |
process.name | in |
| field:"process_basename" kind:in |
source.ip | is_not_null | field:"src_ip" kind:is_not_null | |
source.ip | ne |
| field:"src_ip" kind:ne value:"0.0.0.0" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
source.ip | cidr_match | 10.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.168.0.0/16, 100.64.0.0/10, ::1, fe80::/10, fc00::/7, ff00::/8 | excludes:source.ip |
Potential Fileless Execution via Memory File Descriptor from Interpreter
#Detects when an interpreter process creates a memory file descriptor and executes a command in the proc file system. This activity indicates an active attempt to execute a fileless payload and should be considered highly abnormal or suspicious. This activity can occur when the memfd syscall is utilized to create a memory resident file, like a payload, and then uses it to execute a process via a command and control channel.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Stealth | |
| Command & Control |
Rule Body
[rule]
description = """
Detects when an interpreter process creates a memory file descriptor and executes a command in the proc file system.
This activity indicates an active attempt to execute a fileless payload and should be considered highly abnormal or
suspicious. This activity can occur when the memfd syscall is utilized to create a memory resident file, like a payload,
and then uses it to execute a process via a command and control channel.
"""
id = "87d16b52-e0be-4dd2-b6a8-056f188be018"
license = "Elastic License v2"
name = "Potential Fileless Execution via Memory File Descriptor from Interpreter"
os_list = ["linux"]
version = "1.0.7"
query = '''
process where event.type == "start" and event.action == "memfd_create" and (
(process.name like "python*" and process.args == "-c") or
(process.name like ("perl*", "ruby*", "lua*", "node", "nodejs") and process.args like "-e*") or
(process.name like "php*" and process.args like "-r*") or
process.name like ("*.py", "*.pyc", "*.lua", "*.pl", "*.rb", "*.bin", "*.php", "*.js", "*.mjs") or
(
process.name like ("python*", "perl*", "php*", "ruby*", "lua*", "node", "java", "javaw") and
(
process.args like (
"/tmp/*", "/var/tmp/*", "/dev/shm/*", "/run/user/*", "/var/run/user/*", "/root/*",
"/boot/*", "/sys/*", "/lost+found/*", "/proc/*", "/var/mail/*", "/var/www/*"
) and process.args_count <= 2
)
)
) and not (
process.executable like (
"/usr/lib/libreoffice/program/soffice.bin", "/app/bin/evolution.bin", "/opt/cpanel/ea-php83/root/usr/bin/php-cgi",
"/snap/libreoffice/*/lib/libreoffice/program/soffice.bin", "/usr/NX/bin/nxrunner.bin",
"/usr/lib64/libreoffice/program/soffice.bin", "/opt/libreoffice*/program/soffice.bin", "/opt/hrt/hrtpylon-*/bin/python3*",
"/usr/NX/bin/nxplayer.bin", "/usr/bin/qgis.bin", "/opt/gitlab/embedded/bin/ruby", "/app/libreoffice/program/soffice.bin",
"/ztank/sw/eb/sw/Python/*/bin/python*", "/sw/eb/sw/Python/*/bin/python*", "/home/*/.local/share/uv/python/cpython*/bin/python*",
"/opt/micromamba/bin/python*", "/opt/balenaEtcher/balena-etcher.bin"
) or
process.parent.command_line == "/bin/sh -e /usr/lib/php/sessionclean" or
(
process.name like "php*" and (
process.Ext.memfd.name in (
"memfd:opcache_lock", "anon_hugepage", "opcache_lock", "memfd:anon-handle",
"memfd:anon-shm-handle", "memfd:trampoline_dependencies.so", "memfd:spawn_worker_trampoline"
) or
process.command_line == "php public/index.php"
)
) or
(
process.name like "python*" and
process.Ext.memfd.name like (
"wayland-shm", "memfd:pulseaudio", "memfd:dd_inject_info", "memfd:dd_language_detected", "wayland-cursor",
"memfd:wayland-cursor", "pulseaudio", "datadog-tracer-info*", "memfd:datadog-tracer-info-*", "memfd:libffi",
"libffi", "memfd:xshmfence", "xshmfence", "JITCode*", "unknown-usage*", "JSVMStack*", "JSGCHeap*",
"OTEL_CTX", "memfd:OTEL_CTX"
)
) or
(
process.name like ("ruby*", "node", "nodejs") and
process.Ext.memfd.name like ("OTEL_CTX", "memfd:OTEL_CTX")
) or
(
process.name like "ruby*" and
process.Ext.memfd.name like ("memfd:libffi", "libffi")
) or
(
process.name like ("node", "nodejs") and
process.Ext.memfd.name like ("datadog-tracer-info*", "memfd:datadog-tracer-info-*")
) or
process.parent.executable like (
"/opt/saltstack/salt/bin/python3*", "/usr/lib/systemd/systemd", "/usr/bin/gnome-shell", "/usr/NX/bin/nxexec",
"/usr/bin/sddm", "/usr/bin/bwrap", "/usr/bin/rofi", "/usr/bin/dbus-daemon", "/tmp/.mount_*/lm-studio",
"/usr/libexec/gnome-session-binary", "/usr/local/aegis/AliSecCheckTmp/AliSecCheck", "./runc", "/usr/bin/runc",
"/snap/claude-ai-desktop/*/app/claude-desktop.bin", "/home/*/Programy/WBEST-MNT/WBEST-MNTv1_0_Linux",
"/opt/LM-Studio/lm-studio", "/var/lib/rancher/rke2/data/*/bin/runc", "/var/lib/rancher/rke2/data/*/bin/containerd-shim-runc-v2"
) or
process.parent.command_line in ("/bin/sh /usr/local/bin/docker-php-ext-enable xdebug", "/usr/bin/python3 /usr/bin/nobara-updater --all") or
process.parent.command_line like "*/home/*/.claude/shell-snapshots/snapshot-*" or
(
process.command_line == "buildah-chroot-runtime" and
process.Ext.memfd.name == "memfd:buildah-chroot-runtime"
) or
(
process.name like "ruby*" and
process.args == "-e" and
process.args == "sandbox"
) or
(
process.name like "ruby*" and
process.Ext.memfd.name like "memfd:datadog-tracer-info-*"
) or
(
process.executable == "/usr/bin/perl" and
process.Ext.memfd.name in ("memfd:dd_inject_info", "memfd:dd_language_detected")
) or
(process.name like "python3*" and process.args == "/usr/bin/supervisord") or
(process.name == "node" and process.args == "appCron.js") or
process.parent.executable like "*/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex"
)
'''
min_endpoint_version = "9.1.4"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.006"
name = "Python"
reference = "https://attack.mitre.org/techniques/T1059/006/"
[[threat.technique.subtechnique]]
id = "T1059.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"
[[threat.technique.subtechnique]]
id = "T1059.011"
name = "Lua"
reference = "https://attack.mitre.org/techniques/T1059/011/"
[[threat.technique]]
id = "T1106"
name = "Native API"
reference = "https://attack.mitre.org/techniques/T1106/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"
[[threat.technique.subtechnique]]
id = "T1055.009"
name = "Proc Memory"
reference = "https://attack.mitre.org/techniques/T1055/009/"
[[threat.technique]]
id = "T1620"
name = "Reflective Code Loading"
reference = "https://attack.mitre.org/techniques/T1620/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1105"
name = "Ingress Tool Transfer"
reference = "https://attack.mitre.org/techniques/T1105/"
[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[internal]
min_endpoint_version = "9.1.4"
Stages and Predicates
Stage 1: process
process where event.type == "start" and event.action == "memfd_create" and (
(process.name like "python*" and process.args == "-c") or
(process.name like ("perl*", "ruby*", "lua*", "node", "nodejs") and process.args like "-e*") or
(process.name like "php*" and process.args like "-r*") or
process.name like ("*.py", "*.pyc", "*.lua", "*.pl", "*.rb", "*.bin", "*.php", "*.js", "*.mjs") or
(
process.name like ("python*", "perl*", "php*", "ruby*", "lua*", "node", "java", "javaw") and
(
process.args like (
"/tmp/*", "/var/tmp/*", "/dev/shm/*", "/run/user/*", "/var/run/user/*", "/root/*",
"/boot/*", "/sys/*", "/lost+found/*", "/proc/*", "/var/mail/*", "/var/www/*"
) and process.args_count <= 2
)
)
) and not (
process.executable like (
"/usr/lib/libreoffice/program/soffice.bin", "/app/bin/evolution.bin", "/opt/cpanel/ea-php83/root/usr/bin/php-cgi",
"/snap/libreoffice/*/lib/libreoffice/program/soffice.bin", "/usr/NX/bin/nxrunner.bin",
"/usr/lib64/libreoffice/program/soffice.bin", "/opt/libreoffice*/program/soffice.bin", "/opt/hrt/hrtpylon-*/bin/python3*",
"/usr/NX/bin/nxplayer.bin", "/usr/bin/qgis.bin", "/opt/gitlab/embedded/bin/ruby", "/app/libreoffice/program/soffice.bin",
"/ztank/sw/eb/sw/Python/*/bin/python*", "/sw/eb/sw/Python/*/bin/python*", "/home/*/.local/share/uv/python/cpython*/bin/python*",
"/opt/micromamba/bin/python*", "/opt/balenaEtcher/balena-etcher.bin"
) or
process.parent.command_line == "/bin/sh -e /usr/lib/php/sessionclean" or
(
process.name like "php*" and (
process.Ext.memfd.name in (
"memfd:opcache_lock", "anon_hugepage", "opcache_lock", "memfd:anon-handle",
"memfd:anon-shm-handle", "memfd:trampoline_dependencies.so", "memfd:spawn_worker_trampoline"
) or
process.command_line == "php public/index.php"
)
) or
(
process.name like "python*" and
process.Ext.memfd.name like (
"wayland-shm", "memfd:pulseaudio", "memfd:dd_inject_info", "memfd:dd_language_detected", "wayland-cursor",
"memfd:wayland-cursor", "pulseaudio", "datadog-tracer-info*", "memfd:datadog-tracer-info-*", "memfd:libffi",
"libffi", "memfd:xshmfence", "xshmfence", "JITCode*", "unknown-usage*", "JSVMStack*", "JSGCHeap*",
"OTEL_CTX", "memfd:OTEL_CTX"
)
) or
(
process.name like ("ruby*", "node", "nodejs") and
process.Ext.memfd.name like ("OTEL_CTX", "memfd:OTEL_CTX")
) or
(
process.name like "ruby*" and
process.Ext.memfd.name like ("memfd:libffi", "libffi")
) or
(
process.name like ("node", "nodejs") and
process.Ext.memfd.name like ("datadog-tracer-info*", "memfd:datadog-tracer-info-*")
) or
process.parent.executable like (
"/opt/saltstack/salt/bin/python3*", "/usr/lib/systemd/systemd", "/usr/bin/gnome-shell", "/usr/NX/bin/nxexec",
"/usr/bin/sddm", "/usr/bin/bwrap", "/usr/bin/rofi", "/usr/bin/dbus-daemon", "/tmp/.mount_*/lm-studio",
"/usr/libexec/gnome-session-binary", "/usr/local/aegis/AliSecCheckTmp/AliSecCheck", "./runc", "/usr/bin/runc",
"/snap/claude-ai-desktop/*/app/claude-desktop.bin", "/home/*/Programy/WBEST-MNT/WBEST-MNTv1_0_Linux",
"/opt/LM-Studio/lm-studio", "/var/lib/rancher/rke2/data/*/bin/runc", "/var/lib/rancher/rke2/data/*/bin/containerd-shim-runc-v2"
) or
process.parent.command_line in ("/bin/sh /usr/local/bin/docker-php-ext-enable xdebug", "/usr/bin/python3 /usr/bin/nobara-updater --all") or
process.parent.command_line like "*/home/*/.claude/shell-snapshots/snapshot-*" or
(
process.command_line == "buildah-chroot-runtime" and
process.Ext.memfd.name == "memfd:buildah-chroot-runtime"
) or
(
process.name like "ruby*" and
process.args == "-e" and
process.args == "sandbox"
) or
(
process.name like "ruby*" and
process.Ext.memfd.name like "memfd:datadog-tracer-info-*"
) or
(
process.executable == "/usr/bin/perl" and
process.Ext.memfd.name in ("memfd:dd_inject_info", "memfd:dd_language_detected")
) or
(process.name like "python3*" and process.args == "/usr/bin/supervisord") or
(process.name == "node" and process.args == "appCron.js") or
process.parent.executable like "*/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"memfd_create" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | eq |
| field:"process.args" kind:eq value:"-c" |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.args_count | le |
| field:"process.args_count" kind:le value:"2" |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.Ext.memfd.name | in | anon_hugepage, memfd:anon-handle, memfd:anon-shm-handle, memfd:opcache_lock, memfd:spawn_worker_trampoline, memfd:trampoline_dependencies.so, opcache_lock | excludes:process.Ext.memfd.name |
process.command_line | eq | php public/index.php | excludes:process.command_line field:"process.command_line" value:"php public/index.php" |
process.name | starts_with | php | excludes:process.name field:"process.name" value:"php" |
process.Ext.memfd.name | eq | OTEL_CTX, memfd:OTEL_CTX | excludes:process.Ext.memfd.name field:"process.Ext.memfd.name" value:"OTEL_CTX" field:"process.Ext.memfd.name" value:"memfd:OTEL_CTX" |
process.name | wildcard | ruby*, node, nodejs | excludes:process.name field:"process.name" value:"ruby*" field:"process.name" value:"node" field:"process.name" value:"nodejs" |
process.Ext.memfd.name | eq | memfd:buildah-chroot-runtime | excludes:process.Ext.memfd.name field:"process.Ext.memfd.name" value:"memfd:buildah-chroot-runtime" |
process.command_line | eq | buildah-chroot-runtime | excludes:process.command_line field:"process.command_line" value:"buildah-chroot-runtime" |
process.Ext.memfd.name | eq | memfd:libffi, libffi | excludes:process.Ext.memfd.name field:"process.Ext.memfd.name" value:"memfd:libffi" field:"process.Ext.memfd.name" value:"libffi" |
process.name | starts_with | ruby | excludes:process.name field:"process.name" value:"ruby" |
process.Ext.memfd.name | in | memfd:dd_inject_info, memfd:dd_language_detected | excludes:process.Ext.memfd.name field:"process.Ext.memfd.name" value:"memfd:dd_inject_info" field:"process.Ext.memfd.name" value:"memfd:dd_language_detected" |
process.executable | eq | /usr/bin/perl | excludes:process.executable field:"process.executable" value:"/usr/bin/perl" |
process.Ext.memfd.name | starts_with | datadog-tracer-info, memfd:datadog-tracer-info- | excludes:process.Ext.memfd.name field:"process.Ext.memfd.name" value:"datadog-tracer-info" field:"process.Ext.memfd.name" value:"memfd:datadog-tracer-info-" |
process.name | eq | node, nodejs | excludes:process.name field:"process.name" value:"node" field:"process.name" value:"nodejs" |
process.Ext.memfd.name | starts_with | memfd:datadog-tracer-info- | excludes:process.Ext.memfd.name field:"process.Ext.memfd.name" value:"memfd:datadog-tracer-info-" |
process.Ext.memfd.name | wildcard | wayland-shm, memfd:pulseaudio, memfd:dd_inject_info, memfd:dd_language_detected, wayland-cursor, memfd:wayland-cursor, pulseaudio, datadog-tracer-info*, memfd:datadog-tracer-info-*, memfd:libffi, libffi, memfd:xshmfence, xshmfence, JITCode*, unknown-usage*, JSVMStack*, JSGCHeap*, OTEL_CTX, memfd:OTEL_CTX | excludes:process.Ext.memfd.name |
process.name | starts_with | python | excludes:process.name field:"process.name" value:"python" |
process.args | eq | -e | excludes:process.args field:"process.args" value:"-e" |
process.args | eq | sandbox | excludes:process.args field:"process.args" value:"sandbox" |
process.args | eq | /usr/bin/supervisord | excludes:process.args field:"process.args" value:"/usr/bin/supervisord" |
process.name | starts_with | python3 | excludes:process.name field:"process.name" value:"python3" |
process.args | eq | appCron.js | excludes:process.args field:"process.args" value:"appCron.js" |
process.name | eq | node | excludes:process.name field:"process.name" value:"node" |
process.executable | wildcard | /usr/lib/libreoffice/program/soffice.bin, /app/bin/evolution.bin, /opt/cpanel/ea-php83/root/usr/bin/php-cgi, /snap/libreoffice/*/lib/libreoffice/program/soffice.bin, /usr/NX/bin/nxrunner.bin, /usr/lib64/libreoffice/program/soffice.bin, /opt/libreoffice*/program/soffice.bin, /opt/hrt/hrtpylon-*/bin/python3*, /usr/NX/bin/nxplayer.bin, /usr/bin/qgis.bin, /opt/gitlab/embedded/bin/ruby, /app/libreoffice/program/soffice.bin, /ztank/sw/eb/sw/Python/*/bin/python*, /sw/eb/sw/Python/*/bin/python*, /home/*/.local/share/uv/python/cpython*/bin/python*, /opt/micromamba/bin/python*, /opt/balenaEtcher/balena-etcher.bin | excludes:process.executable |
process.parent.command_line | eq | /bin/sh -e /usr/lib/php/sessionclean | excludes:process.parent.command_line field:"process.parent.command_line" value:"/bin/sh -e /usr/lib/php/sessionclean" |
process.parent.command_line | in | /bin/sh /usr/local/bin/docker-php-ext-enable xdebug, /usr/bin/python3 /usr/bin/nobara-updater --all | excludes:process.parent.command_line field:"process.parent.command_line" value:"/bin/sh /usr/local/bin/docker-php-ext-enable xdebug" field:"process.parent.command_line" value:"/usr/bin/python3 /usr/bin/nobara-updater --all" |
process.parent.command_line | wildcard | */home/*/.claude/shell-snapshots/snapshot-* | excludes:process.parent.command_line field:"process.parent.command_line" value:"*/home/*/.claude/shell-snapshots/snapshot-*" |
process.parent.executable | ends_with | /node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex | excludes:process.parent.executable field:"process.parent.executable" value:"/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex" |
process.parent.executable | wildcard | /opt/saltstack/salt/bin/python3*, /usr/lib/systemd/systemd, /usr/bin/gnome-shell, /usr/NX/bin/nxexec, /usr/bin/sddm, /usr/bin/bwrap, /usr/bin/rofi, /usr/bin/dbus-daemon, /tmp/.mount_*/lm-studio, /usr/libexec/gnome-session-binary, /usr/local/aegis/AliSecCheckTmp/AliSecCheck, ./runc, /usr/bin/runc, /snap/claude-ai-desktop/*/app/claude-desktop.bin, /home/*/Programy/WBEST-MNT/WBEST-MNTv1_0_Linux, /opt/LM-Studio/lm-studio, /var/lib/rancher/rke2/data/*/bin/runc, /var/lib/rancher/rke2/data/*/bin/containerd-shim-runc-v2 | excludes:process.parent.executable |
Process Activity via Compiled HTML File
#Compiled HTML files (.chm) are commonly distributed as part of the Microsoft HTML Help system. Adversaries may conceal malicious code in a CHM file and deliver it to a victim for execution. CHM content is loaded by the HTML Help executable program (hh.exe).
Known False Positives
- The HTML Help executable program (hh.exe) runs whenever a user clicks a compiled help (.chm) file or menu item that opens the help file inside the Help Viewer. This is not always malicious, but adversaries may abuse this technology to conceal malicious code.
MITRE ATT&CK Coverage
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 = "2020/02/18"
integration = ["endpoint", "windows", "system", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/05/04"
[transform]
[[transform.osquery]]
label = "Osquery - Retrieve DNS Cache"
query = "SELECT * FROM dns_cache"
[[transform.osquery]]
label = "Osquery - Retrieve All Services"
query = "SELECT description, display_name, name, path, pid, service_type, start_type, status, user_account FROM services"
[[transform.osquery]]
label = "Osquery - Retrieve Services Running on User Accounts"
query = """
SELECT description, display_name, name, path, pid, service_type, start_type, status, user_account FROM services WHERE
NOT (user_account LIKE '%LocalSystem' OR user_account LIKE '%LocalService' OR user_account LIKE '%NetworkService' OR
user_account == null)
"""
[[transform.osquery]]
label = "Osquery - Retrieve Service Unsigned Executables with Virustotal Link"
query = """
SELECT concat('https://www.virustotal.com/gui/file/', sha1) AS VtLink, name, description, start_type, status, pid,
services.path FROM services JOIN authenticode ON services.path = authenticode.path OR services.module_path =
authenticode.path JOIN hash ON services.path = hash.path WHERE authenticode.result != 'trusted'
"""
[rule]
author = ["Elastic"]
description = """
Compiled HTML files (.chm) are commonly distributed as part of the Microsoft HTML Help system. Adversaries may conceal
malicious code in a CHM file and deliver it to a victim for execution. CHM content is loaded by the HTML Help executable
program (hh.exe).
"""
false_positives = [
"""
The HTML Help executable program (hh.exe) runs whenever a user clicks a compiled help (.chm) file or menu item that
opens the help file inside the Help Viewer. This is not always malicious, but adversaries may abuse this technology
to conceal malicious code.
""",
]
from = "now-9m"
index = [
"endgame-*",
"logs-crowdstrike.fdr*",
"logs-endpoint.events.process-*",
"logs-m365_defender.event-*",
"logs-sentinel_one_cloud_funnel.*",
"logs-system.security*",
"logs-windows.forwarded*",
"logs-windows.sysmon_operational-*",
"winlogbeat-*",
]
language = "eql"
license = "Elastic License v2"
name = "Process Activity via Compiled HTML File"
note = """## Triage and analysis
### Investigating Process Activity via Compiled HTML File
CHM (Compiled HTML) files are a format for delivering online help files on Windows. CHM files are compressed compilations of various content, such as HTML documents, images, and scripting/web-related programming languages such as VBA, JScript, Java, and ActiveX.
When users double-click CHM files, the HTML Help executable program (`hh.exe`) will execute them. `hh.exe` also can be used to execute code embedded in those files, PowerShell scripts, and executables. This makes it useful for attackers not only to proxy the execution of malicious payloads via a signed binary that could bypass security controls, but also to gain initial access to environments via social engineering methods.
> **Note**:
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/current/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.
#### Possible investigation steps
- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Investigate any abnormal behavior by the subject process such as network connections, registry or file modifications, and any spawned child processes.
- Investigate the parent process to gain understanding of what triggered this behavior.
- Retrieve `.chm`, `.ps1`, and other files that were involved to further examination.
- Examine the host for derived artifacts that indicate suspicious activities:
- Analyze the process executables, scripts and help files retrieved from the system using a private sandboxed analysis system.
- Observe and collect information about the following activities in both the sandbox and the alert subject host:
- Attempts to contact external domains and addresses.
- Use the Elastic Defend network events to determine domains and addresses contacted by the subject process by filtering by the process' `process.entity_id`.
- Examine the DNS cache for suspicious or anomalous entries.
- $osquery_0
- Use the Elastic Defend registry events to examine registry keys accessed, modified, or created by the related processes in the process tree.
- Examine the host services for suspicious or anomalous entries.
- $osquery_1
- $osquery_2
- $osquery_3
- Retrieve the files' SHA-256 hash values using the PowerShell `Get-FileHash` cmdlet and search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.
- Investigate potentially compromised accounts. Analysts can do this by searching for login events (for example, 4624) to the target host after the registry modification.
### False positive analysis
- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.
### Response and remediation
- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- If the triage identified malware, search the environment for additional compromised hosts.
- Implement temporary network rules, procedures, and segmentation to contain the malware.
- Stop suspicious processes.
- Immediately block the identified indicators of compromise (IoCs).
- Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that attackers could use to reinfect the system.
- If the malicious file was delivered via phishing:
- Block the email sender from sending future emails.
- Block the malicious web pages.
- Remove emails from the sender from mailboxes.
- Consider improvements to the security awareness program.
- Remove and block malicious artifacts identified during triage.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
setup = """## Setup
This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
Setup instructions: https://ela.st/install-elastic-defend
### Additional data sources
This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
- [CrowdStrike](https://ela.st/crowdstrike-integration)
- [Microsoft Defender XDR](https://ela.st/m365-defender)
- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
- [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
- [Windows Process Creation Logs](https://ela.st/audit-process-creation)
"""
risk_score = 47
rule_id = "e3343ab9-4245-4715-b344-e11c56b0a47f"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Execution",
"Data Source: Elastic Endgame",
"Resources: Investigation Guide",
"Data Source: Elastic Defend",
"Data Source: Windows Security Event Logs",
"Data Source: Microsoft Defender XDR",
"Data Source: Sysmon",
"Data Source: SentinelOne",
"Data Source: Crowdstrike",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "windows" and event.type == "start" and
process.parent.name : "hh.exe" and
process.name : ("mshta.exe", "cmd.exe", "powershell.exe", "pwsh.exe", "powershell_ise.exe", "cscript.exe", "wscript.exe")
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"
[[rule.threat.technique.subtechnique]]
id = "T1059.003"
name = "Windows Command Shell"
reference = "https://attack.mitre.org/techniques/T1059/003/"
[[rule.threat.technique]]
id = "T1204"
name = "User Execution"
reference = "https://attack.mitre.org/techniques/T1204/"
[[rule.threat.technique.subtechnique]]
id = "T1204.002"
name = "Malicious File"
reference = "https://attack.mitre.org/techniques/T1204/002/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"
[[rule.threat.technique.subtechnique]]
id = "T1218.001"
name = "Compiled HTML File"
reference = "https://attack.mitre.org/techniques/T1218/001/"
[[rule.threat.technique.subtechnique]]
id = "T1218.005"
name = "Mshta"
reference = "https://attack.mitre.org/techniques/T1218/005/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Stage 1: process
process where host.os.type == "windows" and event.type == "start" and
process.parent.name : "hh.exe" and
process.name : ("mshta.exe", "cmd.exe", "powershell.exe", "pwsh.exe", "powershell_ise.exe", "cscript.exe", "wscript.exe")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard value:"hh.exe" |
Process Execution Followed by Self-Deletion
#Detects a process execution followed by immediate self-deletion, a common technique used by adversaries to remove traces of their activity on the system. This pattern is often observed in malware and APT campaigns.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule Body
[metadata]
creation_date = "2026/08/19"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/08/31"
[rule]
author = ["Elastic"]
description = """
Detects a process execution followed by immediate self-deletion, a common technique used by adversaries to
remove traces of their activity on the system. This pattern is often observed in malware and APT campaigns.
"""
from = "now-9m"
index = ["logs-endpoint.events.process*", "logs-endpoint.events.file*"]
language = "eql"
license = "Elastic License v2"
name = "Process Execution Followed by Self-Deletion"
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 Process Execution Followed by Self-Deletion
This rule detects a Linux process launched from a temporary, shared-memory, web, or file-descriptor path whose executable is deleted within 30 seconds, a pattern that can erase evidence and hinder analysis. An attacker may drop a payload in `/dev/shm`, execute it to establish access or run malicious commands, and immediately unlink the file while the process continues running.
### Possible investigation steps
- Reconstruct the process tree and review the command line, user, working directory, execution context, and parent legitimacy to determine whether the activity was expected.
- If the process remains active, preserve volatile evidence such as its executable through `/proc/<pid>/exe`, memory, open file descriptors, and cryptographic hashes before containment.
- Correlate nearby child processes, file modifications, persistence changes, DNS requests, and network connections to identify payload behavior and command-and-control activity.
- Trace how the executable reached the host using file-creation events, download records, shell activity, web-server logs, authentication events, and relevant audit telemetry.
- Search the environment for the same hash, command line, user, parent process, destination infrastructure, or deletion pattern, then isolate affected hosts and revoke exposed credentials when malicious activity is confirmed.
### False positive analysis
- Legitimate installation, update, or maintenance scripts may execute a temporary helper from `/tmp`, `/var/tmp`, or `/run` and remove it after completion; verify the parent process, package or change records, signer or hash reputation, and timing against approved activity.
- Administrators or applications may intentionally run short-lived executables from shared memory, web directories, or file descriptors and unlink them immediately; confirm the initiating user, command line, expected application workflow, and absence of suspicious child processes or network activity.
### Response and remediation
- Isolate affected Linux hosts from the network while preserving access for responders, and terminate malicious processes after capturing `/proc/<pid>/exe`, memory, open file descriptors, hashes, and active connections.
- Remove related payloads and persistence from cron jobs, systemd units, shell profiles, SSH `authorized_keys`, startup scripts, web directories, temporary paths, and shared-memory locations.
- Revoke or rotate credentials, API keys, SSH keys, and session tokens used by the malicious process or exposed on the host, and block identified hashes, domains, IP addresses, and download sources.
- Reimage the host or restore it from a verified known-good backup when system integrity cannot be established, then validate packages, configurations, accounts, services, and security tooling before reconnecting it.
- Escalate to incident response immediately if the same payload or infrastructure appears on multiple hosts, privileged accounts were accessed, persistence is present, or command-and-control or data-exfiltration activity is identified.
- Prevent recurrence by restricting execution from `/tmp`, `/var/tmp`, `/dev/shm`, and web-writable directories where operationally feasible, correcting unsafe permissions, patching the initial access vector, and deploying detections for related hashes and behaviors.
"""
risk_score = 47
rule_id = "702a2046-ea74-4bdc-b8ea-b185471f64c8"
setup = """## Setup
This rule requires data coming in from Elastic Defend.
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Defense Evasion",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
type = "eql"
query = '''
sequence by process.entity_id, host.id with maxspan=30s
[process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and
process.executable like (
"/tmp/*", "/var/tmp/*", "/dev/shm/*", "/run/*", "/var/run/*", "/var/www/*",
"/proc/*/fd/*", "?memfd:*", "memfd:*"
)] by process.executable
[file where host.os.type == "linux" and event.action == "deletion"] by file.path
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[rule.threat.tactic]
name = "Defense Evasion"
id = "TA0005"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[rule.threat.technique]]
name = "Indicator Removal"
id = "T1070"
reference = "https://attack.mitre.org/techniques/T1070/"
[[rule.threat.technique.subtechnique]]
name = "File Deletion"
id = "T1070.004"
reference = "https://attack.mitre.org/techniques/T1070/004/"
Stages and Predicates
Ordered sequence: each step below must occur in order within 30s, correlated by file.path, host.id, process.entity_id, process.executable.
Stage 1: process
[process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and
process.executable like (
"/tmp/*", "/var/tmp/*", "/dev/shm/*", "/run/*", "/var/run/*", "/var/www/*",
"/proc/*/fd/*", "?memfd:*", "memfd:*"
)] by process.executable
Stage 2: file
[file where host.os.type == "linux" and event.action == "deletion"] by file.path
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.executable | wildcard |
| field:"Image" kind:wildcard |
Remote Access to Sensitive Registry Keys
#Identifies attempts to query remotely sensitive registry keys containing different credential materials via the remote registry service.
MITRE ATT&CK Coverage
Rule Body
[rule]
description = """
Identifies attempts to query remotely sensitive registry keys containing different credential materials via the remote
registry service.
"""
id = "52741ad7-f7cb-47ae-8ea6-5353e5d0b042"
license = "Elastic License v2"
name = "Remote Access to Sensitive Registry Keys"
os_list = ["windows"]
reference = ["https://www.synacktiv.com/publications/lsa-secrets-revisiting-secretsdump"]
version = "1.0.3"
query = '''
sequence with maxspan=1m
[authentication where event.action == "log_on" and
process.Ext.session_info.logon_type == "Network"] by user.effective.id
[registry where event.action == "query" and
process.executable : "?:\\Windows\\System32\\svchost.exe" and
registry.path :
("HKLM\\SAM\\SAM\\Domains\\Account\\*",
"HKLM\\SECURITY\\Policy\\Secrets\\*",
"HKLM\\SECURITY\\CACHE*") and
not registry.path : ("HKLM\\SAM\\SAM\\Domains\\Account\\Users",
"HKLM\\SAM\\SAM\\Domains\\Account\\Users\\Names",
"HKLM\\SAM\\SAM\\Domains\\Account",
"HKLM\\SAM\\SAM\\Domains\\Account\\Aliases\\*")] by user.id
'''
min_endpoint_version = "8.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1003"
name = "OS Credential Dumping"
reference = "https://attack.mitre.org/techniques/T1003/"
[[threat.technique.subtechnique]]
id = "T1003.002"
name = "Security Account Manager"
reference = "https://attack.mitre.org/techniques/T1003/002/"
[[threat.technique.subtechnique]]
id = "T1003.004"
name = "LSA Secrets"
reference = "https://attack.mitre.org/techniques/T1003/004/"
[[threat.technique.subtechnique]]
id = "T1003.005"
name = "Cached Domain Credentials"
reference = "https://attack.mitre.org/techniques/T1003/005/"
[threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[internal]
min_endpoint_version = "8.15.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 1m, correlated by user.effective.id, user.id.
Stage 1: authentication
[authentication where event.action == "log_on" and
process.Ext.session_info.logon_type == "Network"] by user.effective.id
Stage 2: registry
[registry where event.action == "query" and
process.executable : "?:\\Windows\\System32\\svchost.exe" and
registry.path :
("HKLM\\SAM\\SAM\\Domains\\Account\\*",
"HKLM\\SECURITY\\Policy\\Secrets\\*",
"HKLM\\SECURITY\\CACHE*") and
not registry.path : ("HKLM\\SAM\\SAM\\Domains\\Account\\Users",
"HKLM\\SAM\\SAM\\Domains\\Account\\Users\\Names",
"HKLM\\SAM\\SAM\\Domains\\Account",
"HKLM\\SAM\\SAM\\Domains\\Account\\Aliases\\*")] by user.id
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq |
process.Ext.session_info.logon_type | eq |
| field:"process.Ext.session_info.logon_type" kind:eq value:"Network" |
process.executable | wildcard |
| field:"Image" kind:wildcard value:"?:\Windows\System32\svchost.exe" |
registry.path | wildcard |
| field:"TargetObject" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
registry.path | wildcard | HKLM\SAM\SAM\Domains\Account\Users, HKLM\SAM\SAM\Domains\Account\Users\Names, HKLM\SAM\SAM\Domains\Account, HKLM\SAM\SAM\Domains\Account\Aliases\* | excludes:registry.path |
Sensitive Files Compression
#Identifies the use of a compression utility to collect known files containing sensitive information, such as credentials and system configurations.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access | |
| Collection |
Rule Body
[metadata]
creation_date = "2020/12/22"
integration = ["endpoint", "auditd_manager", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2026/08/25"
[rule]
author = ["Elastic", "Massimo Bertocchi"]
description = """
Identifies the use of a compression utility to collect known files containing sensitive information, such as credentials
and system configurations.
"""
from = "now-9m"
index = [
"auditbeat-*",
"endgame-*",
"logs-auditd_manager.auditd-*",
"logs-endpoint.events.process*",
"logs-sentinel_one_cloud_funnel.*",
]
language = "kuery"
license = "Elastic License v2"
name = "Sensitive Files Compression"
references = [
"https://www.trendmicro.com/en_ca/research/20/l/teamtnt-now-deploying-ddos-capable-irc-bot-tntbotinger.html",
]
risk_score = 47
rule_id = "6b84d470-9036-4cc0-a27c-6d90bbfe81ab"
setup = """## Setup
This rule requires data coming in from one of the following integrations:
- Elastic Defend
- Auditbeat
### 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).
"""
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Collection",
"Tactic: Credential Access",
"Data Source: Elastic Endgame",
"Data Source: Elastic Defend",
"Data Source: SentinelOne",
"Data Source: Auditd Manager",
"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" or "exec_event" or "start" or "executed" or "process_started") and
process.name:(zip or tar or gzip or hdiutil or 7z) and
process.args:
(
/root/.ssh/id_rsa or
/root/.ssh/id_rsa.pub or
/root/.ssh/id_ed25519 or
/root/.ssh/id_ed25519.pub or
/root/.ssh/authorized_keys or
/root/.ssh/authorized_keys2 or
/root/.ssh/known_hosts or
/root/.bash_history or
/etc/hosts or
/home/*/.ssh/id_rsa or
/home/*/.ssh/id_rsa.pub or
/home/*/.ssh/id_ed25519 or
/home/*/.ssh/id_ed25519.pub or
/home/*/.ssh/authorized_keys or
/home/*/.ssh/authorized_keys2 or
/home/*/.ssh/known_hosts or
/home/*/.bash_history or
/root/.aws/credentials or
/root/.aws/config or
/home/*/.aws/credentials or
/home/*/.aws/config or
/home/*/.config/gcloud/credentials.db or
/home/*/.config/gcloud/access_tokens.db or
/home/*/.azure/credentials or
/root/.azure/credentials or
/root/.docker/config.json or
/home/*/.docker/config.json or
/root/.kube/config or
/home/*/.kube/config or
/etc/group or
/etc/passwd or
/etc/shadow or
/etc/gshadow
)
'''
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 Sensitive Files Compression
Compression utilities like zip, tar, and gzip are essential for efficiently managing and transferring files. However, adversaries can exploit these tools to compress and exfiltrate sensitive data, such as SSH keys and configuration files. The detection rule identifies suspicious compression activities by monitoring process executions involving these utilities and targeting known sensitive file paths, thereby flagging potential data collection and credential access attempts.
### Possible investigation steps
- Review the process execution details to identify the user account associated with the compression activity, focusing on the process.name and process.args fields.
- Examine the command line arguments (process.args) to determine which specific sensitive files were targeted for compression.
- Check the event.timestamp to establish a timeline and correlate with other potentially suspicious activities on the host.
- Investigate the host's recent login history and user activity to identify any unauthorized access attempts or anomalies.
- Analyze network logs for any outbound connections from the host around the time of the event to detect potential data exfiltration attempts.
- Assess the integrity and permissions of the sensitive files involved to determine if they have been altered or accessed inappropriately.
### False positive analysis
- Routine system backups or administrative tasks may trigger the rule if they involve compressing sensitive files for legitimate purposes. Users can create exceptions for known backup scripts or administrative processes by excluding specific process names or command-line arguments associated with these tasks.
- Developers or system administrators might compress configuration files during development or deployment processes. To handle this, users can whitelist specific user accounts or directories commonly used for development activities, ensuring these actions are not flagged as suspicious.
- Automated scripts or cron jobs that regularly archive logs or configuration files could be mistakenly identified as threats. Users should review and exclude these scheduled tasks by identifying their unique process identifiers or execution patterns.
- Security tools or monitoring solutions that periodically compress and transfer logs for analysis might be misinterpreted as malicious. Users can exclude these tools by specifying their process names or paths in the detection rule exceptions.
### Response and remediation
- Immediately isolate the affected system from the network to prevent further data exfiltration and unauthorized access.
- Terminate any suspicious processes identified by the detection rule to halt ongoing compression and potential data exfiltration activities.
- Conduct a thorough review of the compressed files and their contents to assess the extent of sensitive data exposure and determine if any data has been exfiltrated.
- Change all credentials associated with the compromised files, such as SSH keys and AWS credentials, to prevent unauthorized access using stolen credentials.
- Restore any altered or deleted configuration files from a known good backup to ensure system integrity and functionality.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if additional systems are affected.
- Implement enhanced monitoring and logging for compression utilities and sensitive file access to detect and respond to similar threats more effectively in the future."""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1552"
name = "Unsecured Credentials"
reference = "https://attack.mitre.org/techniques/T1552/"
[[rule.threat.technique.subtechnique]]
id = "T1552.001"
name = "Credentials In Files"
reference = "https://attack.mitre.org/techniques/T1552/001/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1005"
name = "Data from Local System"
reference = "https://attack.mitre.org/techniques/T1005/"
[[rule.threat.technique]]
id = "T1560"
name = "Archive Collected Data"
reference = "https://attack.mitre.org/techniques/T1560/"
[[rule.threat.technique.subtechnique]]
id = "T1560.001"
name = "Archive via Utility"
reference = "https://attack.mitre.org/techniques/T1560/001/"
[rule.threat.tactic]
id = "TA0009"
name = "Collection"
reference = "https://attack.mitre.org/tactics/TA0009/"
[rule.new_terms]
field = "new_terms_fields"
value = ["host.id", "process.command_line", "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" or "exec_event" or "start" or "executed" or "process_started") and
process.name:(zip or tar or gzip or hdiutil or 7z) and
process.args:
(
/root/.ssh/id_rsa or
/root/.ssh/id_rsa.pub or
/root/.ssh/id_ed25519 or
/root/.ssh/id_ed25519.pub or
/root/.ssh/authorized_keys or
/root/.ssh/authorized_keys2 or
/root/.ssh/known_hosts or
/root/.bash_history or
/etc/hosts or
/home/*/.ssh/id_rsa or
/home/*/.ssh/id_rsa.pub or
/home/*/.ssh/id_ed25519 or
/home/*/.ssh/id_ed25519.pub or
/home/*/.ssh/authorized_keys or
/home/*/.ssh/authorized_keys2 or
/home/*/.ssh/known_hosts or
/home/*/.bash_history or
/root/.aws/credentials or
/root/.aws/config or
/home/*/.aws/credentials or
/home/*/.aws/config or
/home/*/.config/gcloud/credentials.db or
/home/*/.config/gcloud/access_tokens.db or
/home/*/.azure/credentials or
/root/.azure/credentials or
/root/.docker/config.json or
/home/*/.docker/config.json or
/root/.kube/config or
/home/*/.kube/config or
/etc/group or
/etc/passwd or
/etc/shadow or
/etc/gshadow
)
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:"process" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | eq |
| field:"process.args" kind:eq |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.name | in |
| field:"process_basename" kind:in |
Shellcode Behavior from Unusual Memory
#Identifies when a process attempts to allocate shellcode from a memory with unusual properties.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule Body
[rule]
description = "Identifies when a process attempts to allocate shellcode from a memory with unusual properties."
id = "4fd32c09-dcb8-442c-a5ac-b8f3f98ffe6c"
license = "Elastic License v2"
name = "Shellcode Behavior from Unusual Memory"
os_list = ["windows"]
version = "1.0.4"
query = '''
api where process.Ext.api.behaviors in ("allocate_shellcode", "shellcode", "hollow_unbacked", "execute_fluctuation") and
process.thread.Ext.call_stack_final_user_module.protection in ("RW-", "R--", "---") and process.thread.Ext.call_stack_final_user_module.name == "Unbacked" and
process.Ext.api.name in ("VirtualAlloc", "VirtualProtect", "WriteProcessMemory", "VirtualProtectEx", "VirtualAllocEx",
"MapViewOfFile", "MapViewOfFile2", "SetThreadContext", "SuspendThread", "ReadProcessMemory", "connect") and
not _arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature, $entry, $entry.trusted == true and not $entry.subject_name in ("Microsoft Corporation", "Microsoft Windows")) and
not (process.executable : "C:\\Windows\\System32\\WindowsPowerShell\\1.0\\powershell.exe" and process.Ext.api.behaviors == "hollow_unbacked" and
process.thread.Ext.call_stack_final_user_module.protection_provenance_path like "c:\\windows\\assembly\\nativeimages_*.ni.dll") and
not (process.Ext.api.name == "VirtualProtect" and _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info like ("*kernelbase.dll!LoadLibrary*", "*kernel32.dll!ExitProcess*"))) and
process.thread.Ext.call_stack_final_user_module.hash.sha256 != "6a6f026505c3701e03b065ec38e64b105ff6b7129c249a77b45ad4c59d593e26" and
not (process.executable : "C:\\Windows\\System32\\dllhost.exe" and process.parent.executable : "C:\\Windows\\System32\\svchost.exe" and
process.thread.Ext.call_stack_summary == "ntdll.dll|kernelbase.dll|dbgeng.dll|Unbacked|Unknown" and
process.thread.Ext.call_stack_final_user_module.protection_provenance_path == "c:\\windows\\system32\\msmpeg2adec.dll") and
not (process.executable : "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe" and process.thread.Ext.call_stack_final_user_module.protection_provenance_path == "c:\\windows\\syswow64\\d3d9.dll") and
not (process.executable : "C:\\Program Files\\Epic Games\\Fortnite\\FortniteGame\\Binaries\\Win64\\FortniteClient-Win64-Shipping.exe" and
process.code_signature.subject_name == "Epic Games Inc." and process.code_signature.trusted == true)
'''
min_endpoint_version = "8.14.2"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true
[[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.14.2"
Stages and Predicates
Stage 1: api
api where process.Ext.api.behaviors in ("allocate_shellcode", "shellcode", "hollow_unbacked", "execute_fluctuation") and
process.thread.Ext.call_stack_final_user_module.protection in ("RW-", "R--", "---") and process.thread.Ext.call_stack_final_user_module.name == "Unbacked" and
process.Ext.api.name in ("VirtualAlloc", "VirtualProtect", "WriteProcessMemory", "VirtualProtectEx", "VirtualAllocEx",
"MapViewOfFile", "MapViewOfFile2", "SetThreadContext", "SuspendThread", "ReadProcessMemory", "connect") and
not _arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature, $entry, $entry.trusted == true and not $entry.subject_name in ("Microsoft Corporation", "Microsoft Windows")) and
not (process.executable : "C:\\Windows\\System32\\WindowsPowerShell\\1.0\\powershell.exe" and process.Ext.api.behaviors == "hollow_unbacked" and
process.thread.Ext.call_stack_final_user_module.protection_provenance_path like "c:\\windows\\assembly\\nativeimages_*.ni.dll") and
not (process.Ext.api.name == "VirtualProtect" and _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info like ("*kernelbase.dll!LoadLibrary*", "*kernel32.dll!ExitProcess*"))) and
process.thread.Ext.call_stack_final_user_module.hash.sha256 != "6a6f026505c3701e03b065ec38e64b105ff6b7129c249a77b45ad4c59d593e26" and
not (process.executable : "C:\\Windows\\System32\\dllhost.exe" and process.parent.executable : "C:\\Windows\\System32\\svchost.exe" and
process.thread.Ext.call_stack_summary == "ntdll.dll|kernelbase.dll|dbgeng.dll|Unbacked|Unknown" and
process.thread.Ext.call_stack_final_user_module.protection_provenance_path == "c:\\windows\\system32\\msmpeg2adec.dll") and
not (process.executable : "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe" and process.thread.Ext.call_stack_final_user_module.protection_provenance_path == "c:\\windows\\syswow64\\d3d9.dll") and
not (process.executable : "C:\\Program Files\\Epic Games\\Fortnite\\FortniteGame\\Binaries\\Win64\\FortniteClient-Win64-Shipping.exe" and
process.code_signature.subject_name == "Epic Games Inc." and process.code_signature.trusted == true)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
process.Ext.api.behaviors | in |
| field:"process.Ext.api.behaviors" kind:in |
process.Ext.api.name | in |
| field:"process.Ext.api.name" kind:in |
process.thread.Ext.call_stack_final_user_module.hash.sha256 | ne |
| field:"process.thread.Ext.call_stack_final_user_module.hash.sha256" kind:ne value:"6a6f026505c3701e03b065ec38e64b105ff6b7129c249a77b45ad4c59d593e26" |
process.thread.Ext.call_stack_final_user_module.name | eq |
| field:"process.thread.Ext.call_stack_final_user_module.name" kind:eq value:"Unbacked" |
process.thread.Ext.call_stack_final_user_module.protection | in |
| field:"process.thread.Ext.call_stack_final_user_module.protection" kind:in |
Exclusions
The rule actively suppresses these predicates.
Startup Persistence via Unusual Process
#Identifies files written to or modified in the startup folder by an unusual Microsoft process. Adversaries may use this technique to maintain persistence.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence |
Rule Body
[rule]
description = """
Identifies files written to or modified in the startup folder by an unusual Microsoft process. Adversaries may use this
technique to maintain persistence.
"""
id = "95d13ce1-ffb2-4be8-a56e-cc9a891e81e2"
license = "Elastic License v2"
name = "Startup Persistence via Unusual Process"
os_list = ["windows"]
version = "1.0.38"
query = '''
file where event.action != "deletion" and
file.path : ("?:\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\*",
"?:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\StartUp\\*") and
process.executable : "?:\\Windows\\*" and
/* Issue #297 */
not file.name : "desktop.ini" and
not process.executable : "?:\\Windows\\Application Compatibility Scripts\\acregl.exe" and
not process.executable : "?:\\Windows\\Temp\\*.exe" and
not user.id : "S-1-5-18" and
not process.name :
("wscript.exe",
"cscript.exe",
"powershell.exe",
"explorer.exe",
"dllhost.exe",
"notepad.exe",
"cmd.exe",
"Robocopy.exe",
"xcopy.exe",
"wuauclt.exe",
"msiexec.exe",
"CompPkgSrv.exe",
"rundll32.exe",
"svchost.exe",
"sc.exe",
"backgroundTaskHost.exe",
"AppVClient.exe") and
not file.extension : ("TMP", "INF", "INI", "DDF", "CAB", "RPT", "RDP", "ppk")
'''
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 = "T1547"
name = "Boot or Logon Autostart Execution"
reference = "https://attack.mitre.org/techniques/T1547/"
[[threat.technique.subtechnique]]
id = "T1547.001"
name = "Registry Run Keys / Startup Folder"
reference = "https://attack.mitre.org/techniques/T1547/001/"
[threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: file
file where event.action != "deletion" and
file.path : ("?:\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\*",
"?:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\StartUp\\*") and
process.executable : "?:\\Windows\\*" and
not file.name : "desktop.ini" and
not process.executable : "?:\\Windows\\Application Compatibility Scripts\\acregl.exe" and
not process.executable : "?:\\Windows\\Temp\\*.exe" and
not user.id : "S-1-5-18" and
not process.name :
("wscript.exe",
"cscript.exe",
"powershell.exe",
"explorer.exe",
"dllhost.exe",
"notepad.exe",
"cmd.exe",
"Robocopy.exe",
"xcopy.exe",
"wuauclt.exe",
"msiexec.exe",
"CompPkgSrv.exe",
"rundll32.exe",
"svchost.exe",
"sc.exe",
"backgroundTaskHost.exe",
"AppVClient.exe") and
not file.extension : ("TMP", "INF", "INI", "DDF", "CAB", "RPT", "RDP", "ppk")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | ne |
| field:"EventType" kind:ne value:"deletion" |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard |
process.executable | wildcard |
| field:"Image" kind:wildcard value:"?:\Windows\*" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
file.extension | eq | TMP, INF, INI, DDF, CAB, RPT, RDP, ppk | excludes:file.extension |
file.name | eq | desktop.ini | excludes:file.name field:"file.name" value:"desktop.ini" |
process.executable | eq | ?:\Windows\Application Compatibility Scripts\acregl.exe | excludes:process.executable field:"process.executable" value:"?:\Windows\Application Compatibility Scripts\acregl.exe" |
process.executable | wildcard | ?:\Windows\Temp\*.exe | excludes:process.executable field:"process.executable" value:"?:\Windows\Temp\*.exe" |
process.name | eq | wscript.exe, cscript.exe, powershell.exe, explorer.exe, dllhost.exe, notepad.exe, cmd.exe, Robocopy.exe, xcopy.exe, wuauclt.exe, msiexec.exe, CompPkgSrv.exe, rundll32.exe, svchost.exe, sc.exe, backgroundTaskHost.exe, AppVClient.exe | excludes:process.name |
user.id | eq | S-1-5-18 | excludes:user.id field:"user.id" value:"S-1-5-18" |
Suspicious Communication via Mail Protocol
#Identifies DNS queries to Mail domain names by an unusual process. Adversaries may communicate using application layer protocols associated with electronic mail delivery to avoid detection/network filtering by blending in with existing traffic.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Command & Control |
Rule Body
[rule]
description = """
Identifies DNS queries to Mail domain names by an unusual process. Adversaries may communicate using application layer
protocols associated with electronic mail delivery to avoid detection/network filtering by blending in with existing
traffic.
"""
id = "0898f7c9-f667-4db1-a1ce-ddbf61a32361"
license = "Elastic License v2"
name = "Suspicious Communication via Mail Protocol"
os_list = ["windows"]
version = "1.0.18"
query = '''
sequence by process.entity_id with maxspan=3m
[process where event.action == "start" and
(
(process.Ext.device.product_id : ("Virtual DVD-ROM", "Virtual Disk") and not process.executable : "C:\\*") or
(process.Ext.relative_file_creation_time <= 500 and (process.code_signature.trusted == false or process.code_signature.exists == false) and
process.executable : "C:\\*") or
process.name : ("rundll32.exe", "regsvr32.exe", "mshta.exe") or
process.pe.original_file_name : "AutoIt*.exe" or
(process.Ext.relative_file_creation_time <= 500 and
process.executable :
("C:\\Users\\Public\\*",
"C:\\Users\\*\\Downloads\\*",
"C:\\Windows\\Temp\\*",
"C:\\Windows\\Tasks\\*",
"C:\\ProgramData\\*",
"C:\\Windows\\Microsoft.NET\\*")) or
process.executable : ("C:\\Users\\*\\AppData\\Local\\Temp\\7z*\\",
"C:\\Users\\*\\AppData\\Local\\Temp\\Rar$*\\*",
"C:\\Users\\*\\AppData\\Local\\Temp\\Temp?_*\\*",
"C:\\Users\\*\\AppData\\Local\\Temp\\BNZ.*")
) and
not process.parent.executable : "C:\\Program Files\\Microsoft Visual Studio\\*\\Common7\\IDE\\CommonExtensions\\Platform\\Debugger\\VsDebugConsole.exe" and
not process.executable :
("?:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\*\\MsMpEng.exe",
"?:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\*\\NisSrv.exe",
"?:\\ProgramData\\Microsoft\\Windows Defender Advanced Threat Protection\\Platform\\*\\MsSense.exe",
"?:\\Program Files (x86)\\*.exe",
"?:\\Program Files\\*.exe") and
not (process.code_signature.subject_name :
("Google LLC", "Mozilla Corporation", "Wave*", "Brave Software, Inc.", "Opera Norway AS") and
process.code_signature.trusted == true) and
not (process.name : "rundll32.exe" and process.parent.executable : "?:\\Program Files*\\Microsoft Office\\root\\Client\\AppVLP.exe") and
not (process.name : ("rundll32.exe", "regsvr32.exe") and
process.args : ("?:\\PROGRA~?\\MICROS~?\\Office*\\MLCFG32.CPL,@0",
"?:\\Program Files (x86)\\*",
"?:\\Program Files\\*",
"?:\\Windows\\System32\\mshtml.dll,PrintHTML")) and
not process.hash.sha256 :
("e602b527d34ecbb43339f55bf9aa6506886a5cfda239099fbaca3754bcee8618",
"af0652daaa73b748ea967714aaac2d439b562e278d5ad6109416f5fbfee81332",
"b361a064f3e4d953619af3f4646b65b877b1971c716c7b67de3173f50cd9408b",
"8dd74f858de15f072da0fafd3f0a42973ee0c83d8151191fd085c38b15559543",
"8aae9f3c8bddf3b59a16c1e4ba93d4e3b178dc1a9757e9a66a7811ca318f50c4",
"7e400dbd2d895f79d25f42e9738a96d5f0526615fd793e897f2dc90d1c3155f5",
"4a5519a14015a8adfd7d8232bfac648b2bc15f05318be3bf6eb6bcd7191b6818",
"7ad17c0d93925a9b1f172351c397397fcea0f21f881d26412f32e7f7a5c1977f",
"6f44f5a92b3893115e7fdd52735dd639de5d286111841c69aaba53129718eb88",
"9fbf6e5cc6f6f1fcf69c39637fc62ddfe92600364ca6182f748898116f95577c",
"800a013f47846f33f28f28f51a7bc6ad7285466492eb1186511f997438c7d82e",
"3645e1e234ecebe6f138e909203e7d9867cfe3c0880742a280d04673fbf61a46",
"57f0db8244e21dff824d42562fb8a32dc4c65fced809f4b8c319ef9e140ef370",
"b74cfbb7d082e857017b6d593a931ab187cd48535077a74d446974571b25875f")
]
[dns where dns.question.name : ("smtp.*", "mail.*")]
'''
min_endpoint_version = "8.4.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1204"
name = "User Execution"
reference = "https://attack.mitre.org/techniques/T1204/"
[[threat.technique.subtechnique]]
id = "T1204.002"
name = "Malicious File"
reference = "https://attack.mitre.org/techniques/T1204/002/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"
[[threat.technique.subtechnique]]
id = "T1071.003"
name = "Mail Protocols"
reference = "https://attack.mitre.org/techniques/T1071/003/"
[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[internal]
min_endpoint_version = "8.4.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 3m, correlated by process.entity_id.
Stage 1: process
[process where event.action == "start" and
(
(process.Ext.device.product_id : ("Virtual DVD-ROM", "Virtual Disk") and not process.executable : "C:\\*") or
(process.Ext.relative_file_creation_time <= 500 and (process.code_signature.trusted == false or process.code_signature.exists == false) and
process.executable : "C:\\*") or
process.name : ("rundll32.exe", "regsvr32.exe", "mshta.exe") or
process.pe.original_file_name : "AutoIt*.exe" or
(process.Ext.relative_file_creation_time <= 500 and
process.executable :
("C:\\Users\\Public\\*",
"C:\\Users\\*\\Downloads\\*",
"C:\\Windows\\Temp\\*",
"C:\\Windows\\Tasks\\*",
"C:\\ProgramData\\*",
"C:\\Windows\\Microsoft.NET\\*")) or
process.executable : ("C:\\Users\\*\\AppData\\Local\\Temp\\7z*\\",
"C:\\Users\\*\\AppData\\Local\\Temp\\Rar$*\\*",
"C:\\Users\\*\\AppData\\Local\\Temp\\Temp?_*\\*",
"C:\\Users\\*\\AppData\\Local\\Temp\\BNZ.*")
) and
not process.parent.executable : "C:\\Program Files\\Microsoft Visual Studio\\*\\Common7\\IDE\\CommonExtensions\\Platform\\Debugger\\VsDebugConsole.exe" and
not process.executable :
("?:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\*\\MsMpEng.exe",
"?:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\*\\NisSrv.exe",
"?:\\ProgramData\\Microsoft\\Windows Defender Advanced Threat Protection\\Platform\\*\\MsSense.exe",
"?:\\Program Files (x86)\\*.exe",
"?:\\Program Files\\*.exe") and
not (process.code_signature.subject_name :
("Google LLC", "Mozilla Corporation", "Wave*", "Brave Software, Inc.", "Opera Norway AS") and
process.code_signature.trusted == true) and
not (process.name : "rundll32.exe" and process.parent.executable : "?:\\Program Files*\\Microsoft Office\\root\\Client\\AppVLP.exe") and
not (process.name : ("rundll32.exe", "regsvr32.exe") and
process.args : ("?:\\PROGRA~?\\MICROS~?\\Office*\\MLCFG32.CPL,@0",
"?:\\Program Files (x86)\\*",
"?:\\Program Files\\*",
"?:\\Windows\\System32\\mshtml.dll,PrintHTML")) and
not process.hash.sha256 :
("e602b527d34ecbb43339f55bf9aa6506886a5cfda239099fbaca3754bcee8618",
"af0652daaa73b748ea967714aaac2d439b562e278d5ad6109416f5fbfee81332",
"b361a064f3e4d953619af3f4646b65b877b1971c716c7b67de3173f50cd9408b",
"8dd74f858de15f072da0fafd3f0a42973ee0c83d8151191fd085c38b15559543",
"8aae9f3c8bddf3b59a16c1e4ba93d4e3b178dc1a9757e9a66a7811ca318f50c4",
"7e400dbd2d895f79d25f42e9738a96d5f0526615fd793e897f2dc90d1c3155f5",
"4a5519a14015a8adfd7d8232bfac648b2bc15f05318be3bf6eb6bcd7191b6818",
"7ad17c0d93925a9b1f172351c397397fcea0f21f881d26412f32e7f7a5c1977f",
"6f44f5a92b3893115e7fdd52735dd639de5d286111841c69aaba53129718eb88",
"9fbf6e5cc6f6f1fcf69c39637fc62ddfe92600364ca6182f748898116f95577c",
"800a013f47846f33f28f28f51a7bc6ad7285466492eb1186511f997438c7d82e",
"3645e1e234ecebe6f138e909203e7d9867cfe3c0880742a280d04673fbf61a46",
"57f0db8244e21dff824d42562fb8a32dc4c65fced809f4b8c319ef9e140ef370",
"b74cfbb7d082e857017b6d593a931ab187cd48535077a74d446974571b25875f")
]
Stage 2: dns
[dns where dns.question.name : ("smtp.*", "mail.*")]
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | wildcard | ?:\PROGRA~?\MICROS~?\Office*\MLCFG32.CPL,@0, ?:\Program Files (x86)\*, ?:\Program Files\*, ?:\Windows\System32\mshtml.dll,PrintHTML | excludes:process.args |
process.name | eq | rundll32.exe, regsvr32.exe | excludes:process.name field:"process.name" value:"rundll32.exe" field:"process.name" value:"regsvr32.exe" |
process.code_signature.subject_name | wildcard | Google LLC, Mozilla Corporation, Wave*, Brave Software, Inc., Opera Norway AS | excludes:process.code_signature.subject_name |
process.code_signature.trusted | eq | true | excludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true" |
process.name | eq | rundll32.exe | excludes:process.name field:"process.name" value:"rundll32.exe" |
process.parent.executable | wildcard | ?:\Program Files*\Microsoft Office\root\Client\AppVLP.exe | excludes:process.parent.executable field:"process.parent.executable" value:"?:\Program Files*\Microsoft Office\root\Client\AppVLP.exe" |
process.executable | wildcard | ?:\ProgramData\Microsoft\Windows Defender\Platform\*\MsMpEng.exe, ?:\ProgramData\Microsoft\Windows Defender\Platform\*\NisSrv.exe, ?:\ProgramData\Microsoft\Windows Defender Advanced Threat Protection\Platform\*\MsSense.exe, ?:\Program Files (x86)\*.exe, ?:\Program Files\*.exe | excludes:process.executable |
process.hash.sha256 | eq | e602b527d34ecbb43339f55bf9aa6506886a5cfda239099fbaca3754bcee8618, af0652daaa73b748ea967714aaac2d439b562e278d5ad6109416f5fbfee81332, b361a064f3e4d953619af3f4646b65b877b1971c716c7b67de3173f50cd9408b, 8dd74f858de15f072da0fafd3f0a42973ee0c83d8151191fd085c38b15559543, 8aae9f3c8bddf3b59a16c1e4ba93d4e3b178dc1a9757e9a66a7811ca318f50c4, 7e400dbd2d895f79d25f42e9738a96d5f0526615fd793e897f2dc90d1c3155f5, 4a5519a14015a8adfd7d8232bfac648b2bc15f05318be3bf6eb6bcd7191b6818, 7ad17c0d93925a9b1f172351c397397fcea0f21f881d26412f32e7f7a5c1977f, 6f44f5a92b3893115e7fdd52735dd639de5d286111841c69aaba53129718eb88, 9fbf6e5cc6f6f1fcf69c39637fc62ddfe92600364ca6182f748898116f95577c, 800a013f47846f33f28f28f51a7bc6ad7285466492eb1186511f997438c7d82e, 3645e1e234ecebe6f138e909203e7d9867cfe3c0880742a280d04673fbf61a46, 57f0db8244e21dff824d42562fb8a32dc4c65fced809f4b8c319ef9e140ef370, b74cfbb7d082e857017b6d593a931ab187cd48535077a74d446974571b25875f | excludes:process.hash.sha256 |
process.parent.executable | wildcard | C:\Program Files\Microsoft Visual Studio\*\Common7\IDE\CommonExtensions\Platform\Debugger\VsDebugConsole.exe | excludes:process.parent.executable field:"process.parent.executable" value:"C:\Program Files\Microsoft Visual Studio\*\Common7\IDE\CommonExtensions\Platform\Debugger\VsDebugConsole.exe" |
Unusual City For an AWS Command
#A machine learning job detected AWS command activity that, while not inherently suspicious or abnormal, is sourcing from a geolocation (city) that is unusual for the command. This can be the result of compromised credentials or keys being used by a threat actor in a different geography than the authorized user(s).
Known False Positives
- New or unusual command and user geolocation activity can be due to manual troubleshooting or reconfiguration; changes in cloud automation scripts or workflows; adoption of new services; expansion into new regions; increased adoption of work from home policies; or users who travel frequently.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Stealth |
Rule Body
[metadata]
creation_date = "2020/07/13"
integration = ["aws"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
anomaly_threshold = 50
author = ["Elastic"]
description = """
A machine learning job detected AWS command activity that, while not inherently suspicious or abnormal, is sourcing from
a geolocation (city) that is unusual for the command. This can be the result of compromised credentials or keys being
used by a threat actor in a different geography than the authorized user(s).
"""
false_positives = [
"""
New or unusual command and user geolocation activity can be due to manual troubleshooting or reconfiguration;
changes in cloud automation scripts or workflows; adoption of new services; expansion into new regions; increased
adoption of work from home policies; or users who travel frequently.
""",
]
from = "now-2h"
interval = "15m"
license = "Elastic License v2"
machine_learning_job_id = "rare_method_for_a_city"
name = "Unusual City For an AWS Command"
setup = """## Setup
This rule requires the installation of associated Machine Learning jobs, as well as data coming in from AWS.
### Anomaly Detection Setup
Once the rule is enabled, the associated Machine Learning job will start automatically. You can view the Machine Learning job linked under the "Definition" panel of the detection rule. If the job does not start due to an error, the issue must be resolved for the job to commence successfully. For more details on setting up anomaly detection jobs, refer to the [helper guide](https://www.elastic.co/guide/en/kibana/current/xpack-ml-anomalies.html).
### AWS Integration Setup
The AWS integration allows you to collect logs and metrics from Amazon Web Services (AWS) with Elastic Agent.
#### The following steps should be executed in order to add the Elastic Agent System integration "aws" to your system:
- Go to the Kibana home page and click “Add integrations”.
- In the query bar, search for “AWS” and select the integration to see more details about it.
- Click “Add AWS”.
- Configure the integration name and optionally add a description.
- Review optional and advanced settings accordingly.
- Add the newly installed “aws” to an existing or a new agent policy, and deploy the agent on your system from which aws log files are desirable.
- Click “Save and Continue”.
- For more details on the integration refer to the [helper guide](https://www.elastic.co/docs/current/integrations/aws).
"""
note = """## Triage and analysis
### Investigating Unusual City For an AWS Command
CloudTrail logging provides visibility on actions taken within an AWS environment. By monitoring these events and understanding what is considered normal behavior within an organization, you can spot suspicious or malicious activity when deviations occur.
This rule uses a machine learning job to detect an AWS API command that while not inherently suspicious or abnormal, is sourcing from a geolocation (city) that is unusual for the command. This can be the result of compromised credentials or keys used by a threat actor in a different geography than the authorized user(s).
Detection alerts from this rule indicate an AWS API command or method call that is rare and unusual for the geolocation of the source IP address.
#### Possible investigation steps
- Identify the user account involved and the action performed. Verify whether it should perform this kind of action.
- Examine the user identity in the `aws.cloudtrail.user_identity.arn` field and the access key ID in the `aws.cloudtrail.user_identity.access_key_id` field, which can help identify the precise user context.
- The user agent details in the `user_agent.original` field may also indicate what kind of a client made the request.
- Investigate other alerts associated with the user account during the past 48 hours.
- Validate the activity is not related to planned patches, updates, or network administrator activity.
- Examine the request parameters. These might indicate the source of the program or the nature of its tasks.
- Considering the source IP address and geolocation of the user who issued the command:
- Do they look normal for the calling user?
- If the source is an EC2 IP address, is it associated with an EC2 instance in one of your accounts or is the source IP from an EC2 instance that's not under your control?
- If it is an authorized EC2 instance, is the activity associated with normal behavior for the instance role or roles? Are there any other alerts or signs of suspicious activity involving this instance?
- Consider the time of day. If the user is a human (not a program or script), did the activity take place during a normal time of day?
- Contact the account owner and confirm whether they are aware of this activity if suspicious.
- If you suspect the account has been compromised, scope potentially compromised assets by tracking servers, services, and data accessed by the account in the last 24 hours.
### False positive analysis
- False positives can occur if activity is coming from new employees based in a city with no previous history in AWS.
- Examine the history of the command. If the command only manifested recently, it might be part of a new automation module or script. If it has a consistent cadence (for example, it appears in small numbers on a weekly or monthly cadence), it might be part of a housekeeping or maintenance process. You can find the command in the `event.action field` field.
### Related Rules
- Unusual Country For an AWS Command - dca28dee-c999-400f-b640-50a081cc0fd1
- Unusual AWS Command for a User - ac706eae-d5ec-4b14-b4fd-e8ba8086f0e1
- Rare AWS Error Code - 19de8096-e2b0-4bd8-80c9-34a820813fff
- Spike in AWS Error Messages - 78d3d8d9-b476-451d-a9e0-7a5addd70670
### Response and remediation
- Initiate the incident response process based on the outcome of the triage.
- Disable or limit the account during the investigation and response.
- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context:
- Identify the account role in the cloud environment.
- Assess the criticality of affected services and servers.
- Work with your IT team to identify and minimize the impact on users.
- Identify if the attacker is moving laterally and compromising other accounts, servers, or services.
- Identify any regulatory or legal ramifications related to this activity.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords or delete API keys as needed to revoke the attacker's access to the environment. Work with your IT teams to minimize the impact on business operations during these actions.
- Check if unauthorized new users were created, remove unauthorized new accounts, and request password resets for other IAM users.
- Consider enabling multi-factor authentication for users.
- Review the permissions assigned to the implicated user to ensure that the least privilege principle is being followed.
- Implement security best practices [outlined](https://aws.amazon.com/premiumsupport/knowledge-center/security-best-practices/) by AWS.
- Take the actions needed to return affected systems, data, or services to their normal operational levels.
- Identify the initial vector abused by the attacker and take action to prevent reinfection via the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
references = ["https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html"]
risk_score = 21
rule_id = "809b70d3-e2c3-455e-af1b-2626a5a1a276"
severity = "low"
tags = [
"Domain: Cloud",
"Data Source: AWS",
"Data Source: Amazon Web Services",
"Rule Type: ML",
"Rule Type: Machine Learning",
"Resources: Investigation Guide",
]
type = "machine_learning"
[[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/"