Detection rules › Elastic
Elastic rules: 2c
Anomalous Windows Process Creation
#Identifies unusual parent-child process relationships that can indicate malware execution or persistence mechanisms. Malicious scripts often call on other applications and processes as part of their exploit payload. For example, when a malicious Office document runs scripts as part of an exploit payload, Excel or Word may start a script interpreter process, which, in turn, runs a script that downloads and executes malware. Another common scenario is Outlook running an unusual process when malware is downloaded in an email. Monitoring and identifying anomalous process relationships is a method of detecting new and emerging malware that is not yet recognized by anti-virus scanners.
Known False Positives
- Users running scripts in the course of technical support operations of software upgrades could trigger this alert. A newly installed program or one that runs rarely as part of a monthly or quarterly workflow could trigger this alert.
MITRE ATT&CK Coverage
Rule Body
[metadata]
creation_date = "2020/03/25"
integration = ["endpoint", "windows"]
maturity = "production"
min_stack_version = "9.4.0"
min_stack_comments = "Use EA (Entity Analytics) fields"
updated_date = "2026/07/27"
[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 = "Retrieve Service Unisgned 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]
anomaly_threshold = 50
author = ["Elastic"]
description = """
Identifies unusual parent-child process relationships that can indicate malware execution or persistence mechanisms.
Malicious scripts often call on other applications and processes as part of their exploit payload. For example, when a
malicious Office document runs scripts as part of an exploit payload, Excel or Word may start a script interpreter
process, which, in turn, runs a script that downloads and executes malware. Another common scenario is Outlook running
an unusual process when malware is downloaded in an email. Monitoring and identifying anomalous process relationships is
a method of detecting new and emerging malware that is not yet recognized by anti-virus scanners.
"""
false_positives = [
"""
Users running scripts in the course of technical support operations of software upgrades could trigger this alert. A
newly installed program or one that runs rarely as part of a monthly or quarterly workflow could trigger this alert.
""",
]
from = "now-45m"
interval = "15m"
license = "Elastic License v2"
machine_learning_job_id = ["v3_windows_anomalous_process_creation_ea"]
name = "Anomalous Windows Process Creation"
note = """## Triage and analysis
### Investigating Anomalous Windows Process Creation
Searching for abnormal Windows processes is a good methodology to find potentially malicious activity within a network. Understanding what is commonly run within an environment and developing baselines for legitimate activity can help uncover potential malware and suspicious behaviors.
This rule uses a machine learning job to detect an anomalous Windows process with an unusual parent-child relationship, which could indicate malware execution or persistence activities on the host machine.
> **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.
- If the parent process is a legitimate system utility or service, this could be related to software updates or system management. If the parent process is something user-facing like an Office application, this process could be more suspicious.
- Investigate the process metadata — such as the digital signature, directory, etc. — to obtain more context that can indicate whether the executable is associated with an expected software vendor or package.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Consider the user as identified by the `user.name` field. Is this program part of an expected workflow for the user who ran this program on this host?
- Validate the activity is not related to planned patches, updates, network administrator activity, or legitimate software installations.
- Validate if the activity has a consistent cadence (for example, if it runs monthly or quarterly), as it could be part of a monthly or quarterly business process.
- Examine the arguments and working directory of the process. These may provide indications as to the source of the program or the nature of the tasks it is performing.
- Examine the host for derived artifacts that indicate suspicious activities:
- Analyze the process executable using a private sandboxed analysis system.
- Observe and collect information about the following activities in both the sandbox and the alert subject host:
- Attempts to contact external domains and addresses.
- Use the Elastic Defend network events to determine domains and addresses contacted by the subject process by filtering by the process' `process.entity_id`.
- Examine the DNS cache for suspicious or anomalous entries.
- $osquery_0
- Use the Elastic Defend registry events to examine registry keys accessed, modified, or created by the related processes in the process tree.
- Examine the host services for suspicious or anomalous entries.
- $osquery_1
- $osquery_2
- $osquery_3
- Retrieve the files' SHA-256 hash values using the PowerShell `Get-FileHash` cmdlet and search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.
### False Positive Analysis
- If this activity is related to new benign software installation activity, consider adding exceptions — preferably with a combination of user and command line conditions.
- Try to understand the context of the execution by thinking about the user, machine, or business purpose. A small number of endpoints, such as servers with unique software, might appear unusual but satisfy a specific business need.
### Related Rules
- Unusual Process For a Windows Host - 6d448b96-c922-4adb-b51c-b767f1ea5b76
- Unusual Windows Path Activity - 445a342e-03fb-42d0-8656-0367eb2dead5
- Unusual Windows Process Calling the Metadata Service - abae61a8-c560-4dbd-acca-1e1438bff36b
### Response and Remediation
- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved hosts to prevent further post-compromise behavior.
- If the triage identified malware, search the environment for additional compromised hosts.
- Implement temporary network rules, procedures, and segmentation to contain the malware.
- Stop suspicious processes.
- Immediately block the identified indicators of compromise (IoCs).
- Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that attackers could use to reinfect the system.
- Remove and block malicious artifacts identified during triage.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
references = ["https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html"]
risk_score = 21
rule_id = "0b29cab4-dbbd-4a3f-9e8e-1287c7c11ae5"
setup = """## Setup
This rule requires the installation of associated Machine Learning jobs, as well as data coming in from one of the following integrations:
- Elastic Defend
- Windows
### Anomaly Detection Setup
Once the rule is enabled, the associated Machine Learning job will start automatically. You can view the Machine Learning job linked under the "Definition" panel of the detection rule. If the job does not start due to an error, the issue must be resolved for the job to commence successfully. For more details on setting up anomaly detection jobs, refer to the [helper guide](https://www.elastic.co/guide/en/kibana/current/xpack-ml-anomalies.html).
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration to your system:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/current/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
### Windows Integration Setup
The Windows integration allows you to monitor the Windows OS, services, applications, and more.
#### The following steps should be executed in order to add the Elastic Agent System integration "windows" to your system:
- Go to the Kibana home page and click “Add integrations”.
- In the query bar, search for “Windows” and select the integration to see more details about it.
- Click “Add Windows”.
- Configure the integration name and optionally add a description.
- Review optional and advanced settings accordingly.
- Add the newly installed “windows” to an existing or a new agent policy, and deploy the agent on your system from which windows log files are desirable.
- Click “Save and Continue”.
- For more details on the integration refer to the [helper guide](https://docs.elastic.co/integrations/windows).
"""
severity = "low"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Data Source: Elastic Defend",
"Data Source: Windows Security Event Logs",
"Use Case: Threat Detection",
"Rule Type: ML",
"Rule Type: Machine Learning",
"Tactic: Persistence",
"Resources: Investigation Guide",
]
type = "machine_learning"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[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]]
id = "T1203"
name = "Exploitation for Client Execution"
reference = "https://attack.mitre.org/techniques/T1203/"
[[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/"
AWS Bedrock High-Frequency Single-Model Inference API Probing
#Identifies an AWS principal performing a high volume of Amazon Bedrock inference API calls against a single model within a short window. Membership inference attacks require hundreds to thousands of statistically similar queries whose prompts and responses are intentionally content-benign, making guardrail- and content-based rules ineffective. This rule detects the high-frequency single-model probing pattern that precedes membership inference and related exfiltration via the inference API. It is a behavioral / volumetric precursor: it does not observe model confidence scores and a fixed call-count threshold only catches the loud variant, so paced, low-and-slow, or credential-distributed probing will evade it. Definitive membership inference detection requires ML anomaly analysis over per-entity inference-rate and response-distribution baselines.
Known False Positives
- Automated agents, chat applications, retrieval-augmented generation services, evaluation pipelines, and load tests routinely generate high Bedrock inference volume against one model and will exceed any fixed threshold. Validate the principal, user agent, source IP, and application context before treating the activity as malicious, and tune the threshold to the deployment.
MITRE ATLAS Coverage
Adversarial-ML threat framework (not MITRE ATT&CK).
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
Rule Body
[metadata]
creation_date = "2026/06/05"
integration = ["aws"]
maturity = "production"
updated_date = "2026/07/09"
[rule]
author = ["Elastic"]
description = """
Identifies an AWS principal performing a high volume of Amazon Bedrock inference API calls against a single model within
a short window. Membership inference attacks require hundreds to thousands of statistically similar queries whose
prompts and responses are intentionally content-benign, making guardrail- and content-based rules ineffective. This rule
detects the high-frequency single-model probing pattern that precedes membership inference and related exfiltration via
the inference API. It is a behavioral / volumetric precursor: it does not observe model confidence scores and a fixed
call-count threshold only catches the loud variant, so paced, low-and-slow, or credential-distributed probing will evade
it. Definitive membership inference detection requires ML anomaly analysis over per-entity inference-rate and
response-distribution baselines.
"""
false_positives = [
"""
Automated agents, chat applications, retrieval-augmented generation services, evaluation pipelines, and load tests
routinely generate high Bedrock inference volume against one model and will exceed any fixed threshold. Validate the
principal, user agent, source IP, and application context before treating the activity as malicious, and tune the
threshold to the deployment.
""",
]
from = "now-60m"
interval = "10m"
language = "esql"
license = "Elastic License v2"
name = "AWS Bedrock High-Frequency Single-Model Inference API Probing"
note = """## Triage and analysis
### Investigating AWS Bedrock High-Frequency Single-Model Inference API Probing
Membership inference compares many samples against a model to infer whether specific records were present in training data. Because prompts and responses often appear benign, the actionable signal is frequently statistical: unusually high inference rates concentrated on one model from a single principal. AWS CloudTrail records the core Bedrock runtime operations (`InvokeModel`, `InvokeModelWithResponseStream`, `Converse`, `ConverseStream`) as management events, which are logged by default, so this probing phase is observable at the API layer even when Bedrock model invocation logging is disabled. CloudTrail does not capture the prompt body, so this rule is purely volumetric.
This rule is tuned to the loud case. Treat it as corroborating signal alongside other Bedrock alerts, not as conclusive membership inference detection.
#### Possible investigation steps
- Identify the principal in `aws.cloudtrail.user_identity.arn` and the targeted model in the extracted `Esql.model_id`.
- Determine whether the call volume exceeds the principal's historical baseline for the same model.
- Review companion Bedrock invocation logs, if enabled, for short prompts, repeated inputs, or low-variance responses that may indicate membership testing.
- Inspect `Esql.source_ip_values`, `Esql.user_agent_original_values`, and recent IAM activity for signs of compromised credentials or unexpected automation.
- Correlate with bulk output-extraction or guardrail alerts that may indicate a broader inference abuse campaign.
### Response and remediation
- Apply Bedrock service quotas and IAM least privilege for inference APIs while investigating.
- Enable model invocation logging for content-level review if not already configured.
- If abuse is confirmed, rotate access keys or disable the compromised principal.
"""
references = [
"https://atlas.mitre.org/techniques/AML.T0024",
"https://atlas.mitre.org/techniques/AML.T0024.000",
"https://docs.aws.amazon.com/bedrock/latest/userguide/logging-using-cloudtrail.html",
"https://www.elastic.co/security-labs/elastic-advances-llm-security",
]
risk_score = 47
rule_id = "56312ef5-656c-4bf7-ad9a-affed052b102"
setup = """## Setup
This rule requires AWS CloudTrail management events for Amazon Bedrock and ingestion via the AWS
integration (`aws.cloudtrail` data stream). The core Bedrock runtime operations are logged as management
events by default; no Bedrock model invocation logging is required.
"""
severity = "medium"
tags = [
"Domain: Cloud",
"Domain: LLM",
"Data Source: AWS",
"Data Source: Amazon Web Services",
"Data Source: AWS CloudTrail",
"Use Case: Threat Detection",
"Tactic: Exfiltration",
"Mitre Atlas: T0024",
"Mitre Atlas: T0024.000",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
FROM logs-aws.cloudtrail-*
| WHERE event.provider == "bedrock.amazonaws.com"
AND event.action IN (
"InvokeModel",
"Converse",
"ConverseStream",
"InvokeModelWithResponseStream"
)
AND event.outcome == "success"
AND aws.cloudtrail.user_identity.arn IS NOT NULL
AND aws.cloudtrail.request_parameters IS NOT NULL
| GROK aws.cloudtrail.request_parameters """modelId=(?<Esql.model_id>[^,}\]]+)"""
| WHERE Esql.model_id IS NOT NULL
| STATS
Esql.inference_call_count = COUNT(*),
Esql.timestamp_min = MIN(@timestamp),
Esql.timestamp_max = MAX(@timestamp),
Esql.event_ingested_min = MIN(event.ingested),
Esql.event_ingested_max = MAX(event.ingested),
Esql.event_action_values = VALUES(event.action),
Esql.source_ip_values = VALUES(source.ip),
Esql.source_as_organization_name_values =
VALUES(source.as.organization.name),
Esql.source_geo_country_iso_code_values =
VALUES(source.geo.country_iso_code),
Esql.source_geo_city_name_values =
VALUES(source.geo.city_name),
Esql.user_name_values = VALUES(user.name),
Esql.user_agent_original_values = VALUES(user_agent.original),
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.session_issuer_arn_values =
VALUES(aws.cloudtrail.user_identity.session_context.session_issuer.arn),
Esql.cloud_region_values = VALUES(cloud.region),
Esql.data_stream_namespace_values = VALUES(data_stream.namespace)
BY aws.cloudtrail.user_identity.arn,
cloud.account.id,
Esql.model_id
| WHERE Esql.inference_call_count >= 500
| KEEP
aws.cloudtrail.user_identity.arn,
cloud.account.id,
Esql.*
| sort Esql.inference_call_count desc
'''
[rule.alert_suppression]
group_by = ["aws.cloudtrail.user_identity.arn","cloud.account.id"]
missing_fields_strategy = "suppress"
[rule.alert_suppression.duration]
unit = "m"
value = 60
[rule.investigation_fields]
field_names = [
"aws.cloudtrail.user_identity.arn",
"cloud.account.id",
"Esql.model_id",
"Esql.inference_call_count",
"Esql.user_agent_original_values",
"Esql.source_ip_values",
"Esql.user_name_values"
]
Stages and Predicates
Stage 1: from
FROM logs-aws.cloudtrail-*
Stage 2: where
| WHERE event.provider == "bedrock.amazonaws.com"
AND event.action IN (
"InvokeModel",
"Converse",
"ConverseStream",
"InvokeModelWithResponseStream"
)
AND event.outcome == "success"
AND aws.cloudtrail.user_identity.arn IS NOT NULL
AND aws.cloudtrail.request_parameters IS NOT NULL
Stage 3: grok
| GROK aws.cloudtrail.request_parameters """modelId=(?<Esql.model_id>[^,}\]]+)"""
Stage 4: where
| WHERE Esql.model_id IS NOT NULL
Stage 5: stats
| STATS
Esql.inference_call_count = COUNT(*),
Esql.timestamp_min = MIN(@timestamp),
Esql.timestamp_max = MAX(@timestamp),
Esql.event_ingested_min = MIN(event.ingested),
Esql.event_ingested_max = MAX(event.ingested),
Esql.event_action_values = VALUES(event.action),
Esql.source_ip_values = VALUES(source.ip),
Esql.source_as_organization_name_values =
VALUES(source.as.organization.name),
Esql.source_geo_country_iso_code_values =
VALUES(source.geo.country_iso_code),
Esql.source_geo_city_name_values =
VALUES(source.geo.city_name),
Esql.user_name_values = VALUES(user.name),
Esql.user_agent_original_values = VALUES(user_agent.original),
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.session_issuer_arn_values =
VALUES(aws.cloudtrail.user_identity.session_context.session_issuer.arn),
Esql.cloud_region_values = VALUES(cloud.region),
Esql.data_stream_namespace_values = VALUES(data_stream.namespace)
BY aws.cloudtrail.user_identity.arn,
cloud.account.id,
Esql.model_id
Stage 6: where
| WHERE Esql.inference_call_count >= 500
Stage 7: keep
| KEEP
aws.cloudtrail.user_identity.arn,
cloud.account.id,
Esql.*
Stage 8: sort
| sort Esql.inference_call_count desc
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Esql.inference_call_count | ge |
| field:"Esql.inference_call_count" kind:ge value:"500" |
Esql.model_id | is_not_null | field:"Esql.model_id" kind:is_not_null | |
aws.cloudtrail.request_parameters | is_not_null | field:"aws::requestParameters" kind:is_not_null | |
aws.cloudtrail.user_identity.arn | is_not_null | field:"aws::userIdentity.arn" kind:is_not_null | |
event.action | in |
| field:"EventType" kind:in |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"success" |
event.provider | eq |
| field:"Provider_Name" kind:eq value:"bedrock.amazonaws.com" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
aws.cloudtrail.user_identity.arn | KEEP aws.cloudtrail.user_identity.arn |
cloud.account.id | KEEP cloud.account.id |
Esql.* | KEEP Esql.* |
AWS IAM Account Password Policy Deleted
#Identifies deletion of the AWS account password policy via DeleteAccountPasswordPolicy. The account password policy enforces minimum password requirements (length, complexity, rotation, and reuse) for all IAM users in the account. Deleting it removes those requirements account-wide, weakening authentication and easing follow-on credential-based attacks. This is an account-level change that legitimately occurs only during deliberate administration, so its deletion by an unexpected principal warrants review.
Known False Positives
- Identity and platform teams or infrastructure-as-code may delete or replace the account password policy during governance changes. Verify the principal in `aws.cloudtrail.user_identity.arn` against approved change records, and confirm whether a replacement policy was applied shortly after. Known administration roles and automation can be excluded after validation.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Defense Impairment | |
| Credential Access |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2026/06/18"
integration = ["aws"]
maturity = "production"
updated_date = "2026/06/18"
[rule]
author = ["Elastic"]
description = """
Identifies deletion of the AWS account password policy via DeleteAccountPasswordPolicy. The account password policy
enforces minimum password requirements (length, complexity, rotation, and reuse) for all IAM users in the account.
Deleting it removes those requirements account-wide, weakening authentication and easing follow-on credential-based
attacks. This is an account-level change that legitimately occurs only during deliberate administration, so its deletion
by an unexpected principal warrants review.
"""
false_positives = [
"""
Identity and platform teams or infrastructure-as-code may delete or replace the account password policy during
governance changes. Verify the principal in `aws.cloudtrail.user_identity.arn` against approved change records, and
confirm whether a replacement policy was applied shortly after. Known administration roles and automation can be
excluded after validation.
""",
]
from = "now-6m"
index = ["logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS IAM Account Password Policy Deleted"
note = """## Triage and analysis
### Investigating AWS IAM Account Password Policy Deleted
The account password policy is an account-wide control that sets minimum password length, character complexity, maximum age, and reuse-prevention for all IAM users. `DeleteAccountPasswordPolicy` removes it entirely, reverting the account to no enforced password requirements — which weakens authentication and can facilitate credential attacks or mask weak credentials created later. Because this is a single, account-level, high-impact change, it should be deliberate and rare.
### Possible investigation steps
- Identify the actor in `aws.cloudtrail.user_identity.arn`, `aws.cloudtrail.user_identity.type`, and `aws.cloudtrail.user_identity.session_context.session_issuer.arn`, and review `source.ip` / `user_agent.original`.
- Determine whether a replacement policy was set shortly after (`UpdateAccountPasswordPolicy`) or whether the account was left with no policy.
- Confirm whether the change aligns with an approved governance change.
- Correlate with recent activity by the same principal, such as creation of IAM users or login profiles, or other defense-evasion actions (CloudTrail/logging changes) that may indicate a broader effort to weaken controls.
### False positive analysis
- Approved governance or infrastructure-as-code may delete/replace the policy. Confirm the change is expected and exclude known administration roles or automation on `aws.cloudtrail.user_identity.arn` after validation.
- Note: AWS GuardDuty also surfaces account password policy changes via `Stealth:IAMUser/PasswordPolicyChange`; correlate if GuardDuty is enabled.
### Response and remediation
- If the deletion is unauthorized, restore an appropriate account password policy (`UpdateAccountPasswordPolicy`) that meets your organization's standards, and review any IAM users or login profiles created while no policy was enforced.
- Rotate or restrict credentials for the principal if compromise is suspected, and constrain `iam:DeleteAccountPasswordPolicy` and `iam:UpdateAccountPasswordPolicy` to a small set of trusted administrators.
"""
references = [
"https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_account-policy.html",
"https://docs.aws.amazon.com/IAM/latest/APIReference/API_DeleteAccountPasswordPolicy.html",
]
risk_score = 47
rule_id = "283f6c2a-9811-4239-9a40-52b066c67f99"
severity = "medium"
tags = [
"Domain: Cloud",
"Domain: Identity",
"Data Source: AWS",
"Data Source: Amazon Web Services",
"Data Source: AWS IAM",
"Use Case: Threat Detection",
"Tactic: Defense Evasion",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset: "aws.cloudtrail"
and event.provider: "iam.amazonaws.com"
and event.action: "DeleteAccountPasswordPolicy"
and event.outcome: "success"
and not aws.cloudtrail.user_identity.type: "AWSService"
and not user_agent.original: (*terraform* or *pulumi* or *ansible*)
and not aws.cloudtrail.user_identity.arn: (*terraform* or *pulumi* or *ansible*)
and not source.address: ("cloudformation.amazonaws.com" or "servicecatalog.amazonaws.com")
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1556"
name = "Modify Authentication Process"
reference = "https://attack.mitre.org/techniques/T1556/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[rule.investigation_fields]
field_names = [
"@timestamp",
"user.name",
"user_agent.original",
"source.ip",
"aws.cloudtrail.user_identity.arn",
"aws.cloudtrail.user_identity.type",
"aws.cloudtrail.user_identity.access_key_id",
"aws.cloudtrail.user_identity.session_context.session_issuer.arn",
"aws.cloudtrail.request_parameters",
"event.action",
"event.outcome",
"cloud.account.id",
"cloud.region",
]
Stages and Predicates
Stage 1: query
data_stream.dataset: "aws.cloudtrail"
and event.provider: "iam.amazonaws.com"
and event.action: "DeleteAccountPasswordPolicy"
and event.outcome: "success"
and not aws.cloudtrail.user_identity.type: "AWSService"
and not user_agent.original: (*terraform* or *pulumi* or *ansible*)
and not aws.cloudtrail.user_identity.arn: (*terraform* or *pulumi* or *ansible*)
and not source.address: ("cloudformation.amazonaws.com" or "servicecatalog.amazonaws.com")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"aws.cloudtrail" |
event.action | eq |
| field:"EventType" kind:eq value:"DeleteAccountPasswordPolicy" |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"success" |
event.provider | eq |
| field:"Provider_Name" kind:eq value:"iam.amazonaws.com" |
Exclusions
The rule actively suppresses these predicates.
AWS SSM `SendCommand` Execution by Rare User
#Detects the execution of commands or scripts on EC2 instances using AWS Systems Manager (SSM), such as RunShellScript, RunPowerShellScript or custom documents. While legitimate users may employ these commands for management tasks, they can also be exploited by attackers with credentials to establish persistence, install malware, or execute reverse shells for further access to compromised instances. This is a New Terms rule that looks for the first instance of this behavior by a user or role.
Known False Positives
- Verify whether the user identity, user agent, and/or hostname should be making changes in your environment. Suspicious commands from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution |
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
Rule Body
[metadata]
creation_date = "2020/07/06"
integration = ["aws"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
Detects the execution of commands or scripts on EC2 instances using AWS Systems Manager (SSM), such as RunShellScript, RunPowerShellScript or custom documents. While legitimate users may employ these commands for management tasks, they can also be exploited by attackers with credentials to establish persistence, install malware, or execute reverse shells for further access to compromised instances. This is a New Terms rule that looks for the first instance of this behavior by a user or role.
"""
false_positives = [
"""
Verify whether the user identity, user agent, and/or hostname should be making changes in your environment. Suspicious commands from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule.
""",
]
from = "now-6m"
interval = "5m"
index = ["filebeat-*", "logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS SSM `SendCommand` Execution by Rare User"
note = """## Triage and analysis
### Investigating AWS SSM `SendCommand` Execution by Rare User
This rule detects the execution of commands or scripts on EC2 instances using AWS Systems Manager (SSM) by an unexpected or new user. The SSM `SendCommand` action can enable remote command execution, which adversaries may exploit to install backdoors, deploy malware, or interact with compromised instances through reverse shells.
#### Possible Investigation Steps
- **Identify the Target Instance**:
- **Instance ID**: Review the `aws.cloudtrail.request_parameters` field to identify which EC2 instances were targeted by this command. Confirm if these instances are expected to be managed through SSM.
- **Document Used**: Check the `aws.cloudtrail.request_parameters` field, which specifies the name of the document or script being executed. Commands such as `RunShellScript` or `RunPowerShellScript` can indicate interactive sessions or script-based interactions.
- **Review User Context**:
- **User Identity**: Inspect the `aws.cloudtrail.user_identity.arn` field to determine the user or role executing the `SendCommand`. If this user is not typically involved in EC2 or SSM interactions, this could indicate unauthorized access.
- **Access Patterns**: Validate whether the user typically has permissions to perform `SendCommand` operations on instances and whether the frequency of this action matches expected behavior.
- **Analyze Command Parameters**:
- **Document Contents**: While the exact command may not be visible in CloudTrail, use logs to determine the purpose of the script, especially if the document name suggests encryption, data transfer, or reverse shell capabilities.
- **Timing and Context**: Compare this command execution with other recent SSM actions in your environment. A single `SendCommand` event by an unusual user can indicate an early stage of a larger attack.
- **Check User Agent and Source IP**:
- **User Agent Analysis**: Review the `user_agent.original` field to verify the tool or client used (e.g., `aws-cli`). This can provide insight into whether this action was automated, scripted, or executed manually.
- **Source IP and Geolocation**: Use `source.ip` and `source.geo` fields to check if the IP address and geolocation align with expected regions for your organization. Unusual IP addresses or locations can indicate external adversaries.
- **Evaluate for Persistence Indicators**:
- **Command Consistency**: Investigate if this action is part of a recurring pattern, such as repeated command executions across instances, which may suggest an attempt to maintain access.
- **Permissions**: Ensure that the IAM policies associated with the user limit `SendCommand` actions to necessary use cases. Consider adding alerts for commands executed by users with minimal roles or permissions.
- **Correlate with Other CloudTrail Events**:
- **Cross-Reference SSM Actions**: Look for other recent SSM actions like `CreateDocument`, `UpdateDocument`, or additional `SendCommand` events that could indicate preparation for further exploitation.
- **Monitor Data Access or Modification**: Correlate with S3 access patterns, IAM changes, or EC2 modifications in recent events to detect broader malicious activities.
### False Positive Analysis
- **Routine Automation**: SSM `SendCommand` may be used by automation scripts or management tools. Verify if this event aligns with known, routine automated workflows.
- **Maintenance Activity**: Confirm if legitimate administrative activities, such as patching or updates, are expected at this time, which may involve similar commands executed on multiple instances.
### Response and Remediation
- **Limit SSM Permissions**: If unauthorized, immediately revoke `SendCommand` permissions from the user or role to prevent further access.
- **Quarantine Target Instance**: If malicious behavior is confirmed, isolate the affected EC2 instance(s) to limit lateral movement or data exfiltration.
- **Investigate and Contain User Account**: If the action was performed by a compromised account, review recent activity and reset access credentials as necessary.
- **Audit SSM and IAM Configurations**: Periodically review permissions associated with SSM usage and ensure least privilege access principles are in place.
### Additional Information
For further details on managing AWS SSM and security best practices for EC2 instances, refer to the [AWS Systems Manager Documentation](https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-plugins.html) and AWS best practices.
"""
references = ["https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-plugins.html"]
risk_score = 21
rule_id = "37b211e8-4e2f-440f-86d8-06cc8f158cfa"
severity = "low"
tags = [
"Domain: Cloud",
"Data Source: AWS",
"Data Source: Amazon Web Services",
"Data Source: AWS SSM",
"Data Source: AWS Systems Manager",
"Use Case: Log Auditing",
"Use Case: Threat Detection",
"Tactic: Execution",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
data_stream.dataset: "aws.cloudtrail"
and event.provider: "ssm.amazonaws.com"
and event.action: "SendCommand"
and event.outcome: "success"
and not source.address: (
"ssm-guiconnect.amazonaws.com" or
"ssm.amazonaws.com" or
"inspector2.amazonaws.com"
)
'''
[rule.investigation_fields]
field_names = [
"@timestamp",
"user.name",
"user_agent.original",
"source.ip",
"aws.cloudtrail.user_identity.arn",
"aws.cloudtrail.user_identity.type",
"aws.cloudtrail.user_identity.access_key_id",
"event.action",
"event.outcome",
"cloud.account.id",
"cloud.region",
"aws.cloudtrail.request_parameters",
"aws.cloudtrail.response_elements"
]
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1651"
name = "Cloud Administration Command"
reference = "https://attack.mitre.org/techniques/T1651/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[rule.new_terms]
field = "new_terms_fields"
value = ["cloud.account.id", "user.name"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-7d"
Stages and Predicates
Stage 1: new_terms
data_stream.dataset: "aws.cloudtrail"
and event.provider: "ssm.amazonaws.com"
and event.action: "SendCommand"
and event.outcome: "success"
and not source.address: (
"ssm-guiconnect.amazonaws.com" or
"ssm.amazonaws.com" or
"inspector2.amazonaws.com"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"aws.cloudtrail" |
event.action | eq |
| field:"EventType" kind:eq value:"SendCommand" |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"success" |
event.provider | eq |
| field:"Provider_Name" kind:eq value:"ssm.amazonaws.com" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
source.address | in | inspector2.amazonaws.com, ssm-guiconnect.amazonaws.com, ssm.amazonaws.com | excludes:source.address field:"source.address" value:"inspector2.amazonaws.com" field:"source.address" value:"ssm-guiconnect.amazonaws.com" field:"source.address" value:"ssm.amazonaws.com" |
Azure VNet Full Network Packet Capture Enabled
#Identifies potential full network packet capture in Azure. Packet Capture is an Azure Network Watcher feature that can be used to inspect network traffic. This feature can potentially be abused to read sensitive data from unencrypted internal traffic.
Known False Positives
- Full Network Packet Capture may be done by a system or network administrator. Verify whether the user identity, user agent, and/or hostname should be making changes in your environment. Full Network Packet Capture from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access | |
| Discovery |
Rule Body
[metadata]
creation_date = "2021/08/12"
integration = ["azure"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Austin Songer"]
description = """
Identifies potential full network packet capture in Azure. Packet Capture is an Azure Network Watcher feature that can
be used to inspect network traffic. This feature can potentially be abused to read sensitive data from unencrypted
internal traffic.
"""
false_positives = [
"""
Full Network Packet Capture may be done by a system or network administrator. Verify whether the user identity, user
agent, and/or hostname should be making changes in your environment. Full Network Packet Capture from unfamiliar
users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the
rule.
""",
]
from = "now-9m"
index = ["logs-azure.activitylogs-*", "filebeat-*"]
language = "kuery"
license = "Elastic License v2"
name = "Azure VNet Full Network Packet Capture Enabled"
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 Azure VNet Full Network Packet Capture Enabled
Azure's Packet Capture is a feature of Network Watcher that allows for the inspection of network traffic, useful for diagnosing network issues. However, if misused, it can capture sensitive data from unencrypted traffic, posing a security risk. Adversaries might exploit this to access credentials or other sensitive information. The detection rule identifies suspicious packet capture activities by monitoring specific Azure activity logs for successful operations, helping to flag potential misuse.
### Possible investigation steps
- Review the Azure activity logs to identify the specific user or service principal associated with the packet capture operation by examining the `azure.activitylogs.operation_name` and `event.dataset` fields.
- Check the timestamp of the detected packet capture activity to determine the exact time frame of the event and correlate it with any other suspicious activities or changes in the environment.
- Investigate the source and destination IP addresses involved in the packet capture to understand the scope and potential impact, focusing on any unencrypted traffic that might have been captured.
- Verify the legitimacy of the packet capture request by contacting the user or team responsible for the operation to confirm if it was authorized and necessary for troubleshooting or other legitimate purposes.
- Assess the risk of exposed sensitive data by identifying any critical systems or services that were part of the captured network traffic, especially those handling credentials or personal information.
### False positive analysis
- Routine network diagnostics by authorized personnel can trigger the rule. To manage this, create exceptions for specific user accounts or IP addresses known to perform regular diagnostics.
- Automated network monitoring tools might initiate packet captures as part of their normal operations. Identify these tools and exclude their activities from triggering alerts.
- Scheduled maintenance activities often involve packet captures for performance analysis. Document these schedules and configure the rule to ignore captures during these periods.
- Development and testing environments may frequently use packet capture for debugging purposes. Exclude these environments by filtering based on resource tags or environment identifiers.
- Legitimate security audits may involve packet capture to assess network security. Coordinate with the audit team to whitelist their activities during the audit period.
### Response and remediation
- Immediately isolate the affected network segment to prevent further unauthorized packet capture and potential data exfiltration.
- Revoke any suspicious or unauthorized access to Azure Network Watcher and related resources to prevent further misuse.
- Conduct a thorough review of the captured network traffic logs to identify any sensitive data exposure and assess the potential impact.
- Reset credentials and access tokens for any accounts or services that may have been compromised due to exposed unencrypted traffic.
- Implement network encryption protocols to protect sensitive data in transit and reduce the risk of future packet capture exploitation.
- Escalate the incident to the security operations team for further investigation and to determine if additional security measures are necessary.
- Enhance monitoring and alerting for Azure Network Watcher activities to detect and respond to similar threats more effectively in the future.
## Setup
The Azure Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
references = ["https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations"]
risk_score = 47
rule_id = "3ad77ed4-4dcf-4c51-8bfc-e3f7ce316b2f"
severity = "medium"
tags = ["Domain: Cloud", "Data Source: Azure", "Tactic: Credential Access", "Resources: Investigation Guide"]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:azure.activitylogs and azure.activitylogs.operation_name:
(
MICROSOFT.NETWORK/*/STARTPACKETCAPTURE/ACTION or
MICROSOFT.NETWORK/*/VPNCONNECTIONS/STARTPACKETCAPTURE/ACTION or
MICROSOFT.NETWORK/*/PACKETCAPTURES/WRITE
) and
event.outcome:(Success or success)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1040"
name = "Network Sniffing"
reference = "https://attack.mitre.org/techniques/T1040/"
[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 = "T1040"
name = "Network Sniffing"
reference = "https://attack.mitre.org/techniques/T1040/"
[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
Stages and Predicates
Stage 1: query
data_stream.dataset:azure.activitylogs and azure.activitylogs.operation_name:
(
MICROSOFT.NETWORK/*/STARTPACKETCAPTURE/ACTION or
MICROSOFT.NETWORK/*/VPNCONNECTIONS/STARTPACKETCAPTURE/ACTION or
MICROSOFT.NETWORK/*/PACKETCAPTURES/WRITE
) and
event.outcome:(Success or success)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
azure.activitylogs.operation_name | wildcard |
| field:"azure.activitylogs.operation_name" kind:wildcard |
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"azure.activitylogs" |
event.outcome | in |
| field:"event.outcome" kind:in |
Dynamic Linker Creation
#Detects the creation of files related to the configuration of the dynamic linker on Linux systems. The dynamic linker is a shared library that is used by the Linux kernel to load and execute programs. Attackers may attempt to hijack the execution flow of a program by modifying the dynamic linker configuration files. This technique is often observed by userland rootkits that leverage shared objects to maintain persistence on a compromised host.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule Body
[metadata]
creation_date = "2024/08/08"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
Detects the creation of files related to the configuration of the dynamic linker on Linux systems. The dynamic linker
is a shared library that is used by the Linux kernel to load and execute programs. Attackers may attempt to hijack
the execution flow of a program by modifying the dynamic linker configuration files. This technique is often observed
by userland rootkits that leverage shared objects to maintain persistence on a compromised host.
"""
from = "now-9m"
index = ["logs-endpoint.events.file*"]
language = "eql"
license = "Elastic License v2"
name = "Dynamic Linker Creation"
risk_score = 47
rule_id = "640f79d1-571d-4f96-a9af-1194fc8cf763"
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",
"Tactic: Persistence",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
file where host.os.type == "linux" and event.action == "creation" and
file.path like ("/etc/ld.so.preload", "/etc/ld.so.conf.d/*", "/etc/ld.so.conf") and
not (
process.executable in (
"/bin/dpkg", "/usr/bin/dpkg", "/bin/dockerd", "/usr/bin/dockerd", "/usr/sbin/dockerd", "/bin/microdnf",
"/usr/bin/microdnf", "/bin/rpm", "/usr/bin/rpm", "/bin/snapd", "/usr/bin/snapd", "/bin/yum", "/usr/bin/yum",
"/bin/dnf", "/usr/bin/dnf", "/bin/podman", "/usr/bin/podman", "/bin/dnf-automatic", "/usr/bin/dnf-automatic",
"/bin/pacman", "/usr/bin/pacman", "/usr/bin/dpkg-divert", "/bin/dpkg-divert", "/sbin/apk", "/usr/sbin/apk",
"/usr/local/sbin/apk", "/usr/bin/apt", "/usr/sbin/pacman", "/bin/podman", "/usr/bin/podman", "/usr/bin/puppet",
"/bin/puppet", "/opt/puppetlabs/puppet/bin/puppet", "/usr/bin/chef-client", "/bin/chef-client",
"/bin/autossl_check", "/usr/bin/autossl_check", "/proc/self/exe", "/usr/bin/pamac-daemon",
"/bin/pamac-daemon", "/usr/lib/snapd/snapd", "/usr/local/bin/dockerd", "/usr/libexec/platform-python",
"/usr/lib/snapd/snap-update-ns", "/usr/bin/vmware-config-tools.pl", "./usr/bin/podman", "/bin/nvidia-cdi-hook",
"/usr/lib/dracut/dracut-install", "./usr/bin/nvidia-cdi-hook", "/.envbuilder/bin/envbuilder", "/usr/bin/buildah",
"/usr/sbin/dnf", "/usr/bin/pamac", "/sbin/pacman", "/usr/bin/crio", "/usr/sbin/yum-cron"
) or
file.extension in ("swp", "swpx", "swx", "dpkg-remove") or
file.Ext.original.extension == "dpkg-new" or
process.executable : (
"/nix/store/*", "/var/lib/dpkg/*", "/snap/*", "/dev/fd/*", "/usr/lib/virtualbox/*", "/opt/dynatrace/oneagent/*",
"/usr/libexec/platform-python*"
) or
process.executable == null or
process.name in (
"java", "executor", "ssm-agent-worker", "packagekitd", "crio", "dockerd-entrypoint.sh",
"docker-init", "BootTimeChecker", "dockerd (deleted)", "dockerd"
) or
(process.name == "sed" and file.name : "sed*") or
(process.name == "perl" and file.name : "e2scrub_all.tmp*") or
(process.name == "init" and file.name == "ld.wsl.conf") or
(process.name == "sshd" and file.extension == "dpkg-new")
)
'''
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 Dynamic Linker Creation or Modification
The dynamic linker in Linux systems is crucial for loading shared libraries needed by programs at runtime. Adversaries may exploit this by altering linker configuration files to hijack program execution, enabling persistence or evasion. The detection rule identifies suspicious creation or renaming of these files, excluding benign processes and extensions, to flag potential threats.
### Possible investigation steps
- Review the file path involved in the alert to determine if it matches any of the critical dynamic linker configuration files such as /etc/ld.so.preload, /etc/ld.so.conf.d/*, or /etc/ld.so.conf.
- Identify the process that triggered the alert by examining the process.executable field and verify if it is listed as a benign process in the exclusion list. If not, investigate the legitimacy of the process.
- Check the file extension and file.Ext.original.extension fields to ensure the file is not a temporary or expected system file, such as those with extensions like swp, swpx, swx, or dpkg-new.
- Investigate the process.name field to determine if the process is a known system utility like java, sed, or perl, and assess if its usage in this context is typical or suspicious.
- Gather additional context by reviewing recent system logs and other security alerts to identify any related or preceding suspicious activities that might indicate a broader attack or compromise.
### False positive analysis
- Package management operations can trigger false positives when legitimate package managers like dpkg, rpm, or yum modify linker configuration files. To handle this, ensure these processes are included in the exclusion list to prevent unnecessary alerts.
- System updates or software installations often involve temporary file modifications with extensions like swp or dpkg-new. Exclude these extensions to reduce false positives.
- Automated system management tools such as Puppet or Chef may modify linker files as part of their configuration management tasks. Add these tools to the exclusion list to avoid false alerts.
- Virtualization and containerization platforms like Docker or VMware may alter linker configurations during normal operations. Verify these processes and exclude them if they are part of routine system behavior.
- Custom scripts or applications that use common names like sed or perl might be flagged if they interact with linker files. Review these scripts and consider excluding them if they are verified as safe.
### Response and remediation
- Immediately isolate the affected system from the network to prevent further unauthorized access or lateral movement by the adversary.
- Review and restore the original dynamic linker configuration files from a known good backup to ensure the integrity of the system's execution flow.
- Conduct a thorough scan of the affected system using updated antivirus and anti-malware tools to identify and remove any additional malicious software or scripts.
- Analyze system logs and the process execution history to identify the source of the unauthorized changes and determine if any other systems may be compromised.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to assess the potential impact on the organization.
- Implement additional monitoring on the affected system and similar systems to detect any future attempts to modify dynamic linker configuration files.
- Review and update access controls and permissions to ensure that only authorized personnel have the ability to modify critical system files, reducing the risk of similar incidents in the future."""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"
[[rule.threat.technique.subtechnique]]
id = "T1574.006"
name = "Dynamic Linker Hijacking"
reference = "https://attack.mitre.org/techniques/T1574/006/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"
[[rule.threat.technique.subtechnique]]
id = "T1574.006"
name = "Dynamic Linker Hijacking"
reference = "https://attack.mitre.org/techniques/T1574/006/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"
[[rule.threat.technique.subtechnique]]
id = "T1574.006"
name = "Dynamic Linker Hijacking"
reference = "https://attack.mitre.org/techniques/T1574/006/"
[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
Stages and Predicates
Stage 1: file
file where host.os.type == "linux" and event.action == "creation" and
file.path like ("/etc/ld.so.preload", "/etc/ld.so.conf.d/*", "/etc/ld.so.conf") and
not (
process.executable in (
"/bin/dpkg", "/usr/bin/dpkg", "/bin/dockerd", "/usr/bin/dockerd", "/usr/sbin/dockerd", "/bin/microdnf",
"/usr/bin/microdnf", "/bin/rpm", "/usr/bin/rpm", "/bin/snapd", "/usr/bin/snapd", "/bin/yum", "/usr/bin/yum",
"/bin/dnf", "/usr/bin/dnf", "/bin/podman", "/usr/bin/podman", "/bin/dnf-automatic", "/usr/bin/dnf-automatic",
"/bin/pacman", "/usr/bin/pacman", "/usr/bin/dpkg-divert", "/bin/dpkg-divert", "/sbin/apk", "/usr/sbin/apk",
"/usr/local/sbin/apk", "/usr/bin/apt", "/usr/sbin/pacman", "/bin/podman", "/usr/bin/podman", "/usr/bin/puppet",
"/bin/puppet", "/opt/puppetlabs/puppet/bin/puppet", "/usr/bin/chef-client", "/bin/chef-client",
"/bin/autossl_check", "/usr/bin/autossl_check", "/proc/self/exe", "/usr/bin/pamac-daemon",
"/bin/pamac-daemon", "/usr/lib/snapd/snapd", "/usr/local/bin/dockerd", "/usr/libexec/platform-python",
"/usr/lib/snapd/snap-update-ns", "/usr/bin/vmware-config-tools.pl", "./usr/bin/podman", "/bin/nvidia-cdi-hook",
"/usr/lib/dracut/dracut-install", "./usr/bin/nvidia-cdi-hook", "/.envbuilder/bin/envbuilder", "/usr/bin/buildah",
"/usr/sbin/dnf", "/usr/bin/pamac", "/sbin/pacman", "/usr/bin/crio", "/usr/sbin/yum-cron"
) or
file.extension in ("swp", "swpx", "swx", "dpkg-remove") or
file.Ext.original.extension == "dpkg-new" or
process.executable : (
"/nix/store/*", "/var/lib/dpkg/*", "/snap/*", "/dev/fd/*", "/usr/lib/virtualbox/*", "/opt/dynatrace/oneagent/*",
"/usr/libexec/platform-python*"
) or
process.executable == null or
process.name in (
"java", "executor", "ssm-agent-worker", "packagekitd", "crio", "dockerd-entrypoint.sh",
"docker-init", "BootTimeChecker", "dockerd (deleted)", "dockerd"
) or
(process.name == "sed" and file.name : "sed*") or
(process.name == "perl" and file.name : "e2scrub_all.tmp*") or
(process.name == "init" and file.name == "ld.wsl.conf") or
(process.name == "sshd" and file.extension == "dpkg-new")
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"creation" |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
file.extension | eq | dpkg-new | excludes:file.extension field:"file.extension" value:"dpkg-new" |
process.name | eq | sshd | excludes:process.name field:"process.name" value:"sshd" |
file.name | eq | ld.wsl.conf | excludes:file.name field:"file.name" value:"ld.wsl.conf" |
process.name | eq | init | excludes:process.name field:"process.name" value:"init" |
file.name | starts_with | e2scrub_all.tmp | excludes:file.name field:"file.name" value:"e2scrub_all.tmp" |
process.name | eq | perl | excludes:process.name field:"process.name" value:"perl" |
file.name | starts_with | sed | excludes:file.name field:"file.name" value:"sed" |
process.name | eq | sed | excludes:process.name field:"process.name" value:"sed" |
file.Ext.original.extension | eq | dpkg-new | excludes:file.Ext.original.extension field:"file.Ext.original.extension" value:"dpkg-new" |
file.extension | in | dpkg-remove, swp, swpx, swx | excludes:file.extension |
process.executable | in | ./usr/bin/nvidia-cdi-hook, ./usr/bin/podman, /.envbuilder/bin/envbuilder, /bin/autossl_check, /bin/chef-client, /bin/dnf, /bin/dnf-automatic, /bin/dockerd, /bin/dpkg, /bin/dpkg-divert, /bin/microdnf, /bin/nvidia-cdi-hook, /bin/pacman, /bin/pamac-daemon, /bin/podman, /bin/puppet, /bin/rpm, /bin/snapd, /bin/yum, /opt/puppetlabs/puppet/bin/puppet, /proc/self/exe, /sbin/apk, /sbin/pacman, /usr/bin/apt, /usr/bin/autossl_check, /usr/bin/buildah, /usr/bin/chef-client, /usr/bin/crio, /usr/bin/dnf, /usr/bin/dnf-automatic, /usr/bin/dockerd, /usr/bin/dpkg, /usr/bin/dpkg-divert, /usr/bin/microdnf, /usr/bin/pacman, /usr/bin/pamac, /usr/bin/pamac-daemon, /usr/bin/podman, /usr/bin/puppet, /usr/bin/rpm, /usr/bin/snapd, /usr/bin/vmware-config-tools.pl, /usr/bin/yum, /usr/lib/dracut/dracut-install, /usr/lib/snapd/snap-update-ns, /usr/lib/snapd/snapd, /usr/libexec/platform-python, /usr/local/bin/dockerd, /usr/local/sbin/apk, /usr/sbin/apk, /usr/sbin/dnf, /usr/sbin/dockerd, /usr/sbin/pacman, /usr/sbin/yum-cron | excludes:process.executable |
process.executable | is_null | excludes:process.executable | |
process.executable | starts_with | /nix/store/, /var/lib/dpkg/, /snap/, /dev/fd/, /usr/lib/virtualbox/, /opt/dynatrace/oneagent/, /usr/libexec/platform-python | excludes:process.executable |
process.name | in | BootTimeChecker, crio, docker-init, dockerd, dockerd (deleted), dockerd-entrypoint.sh, executor, java, packagekitd, ssm-agent-worker | excludes:process.name |
Entra ID Potential AiTM Sign-In via OfficeHome (Tycoon2FA)
#Detects Microsoft Entra ID sign-ins consistent with Tycoon2FA phishing-as-a-service (PhaaS) adversary-in-the-middle (AiTM) activity: the Microsoft Authentication Broker requesting tokens for Microsoft Graph or Exchange Online, or the Office web client application authenticating to itself, combined with Node.js-style user agents (node, axios, undici). Tycoon 2FA bypasses MFA by relaying authentication and capturing session material, often targeting Microsoft 365 and Gmail. Baseline legitimate automation and developer tooling before tuning.
Known False Positives
- Legitimate Node.js or undici-based automation, health checks, or internal services that use the Microsoft Authentication Broker or the same first-party application IDs against Graph or Exchange may match. Developers using axios or undici with delegated flows can also resemble this pattern.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Credential Access |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2026/05/14"
integration = ["azure"]
maturity = "production"
updated_date = "2026/05/14"
[rule]
author = ["Elastic"]
description = """
Detects Microsoft Entra ID sign-ins consistent with Tycoon2FA phishing-as-a-service (PhaaS) adversary-in-the-middle
(AiTM) activity: the Microsoft Authentication Broker requesting tokens for Microsoft Graph or Exchange Online, or the
Office web client application authenticating to itself, combined with Node.js-style user agents (node, axios, undici).
Tycoon 2FA bypasses MFA by relaying authentication and capturing session material, often targeting Microsoft 365 and
Gmail. Baseline legitimate automation and developer tooling before tuning.
"""
false_positives = [
"""
Legitimate Node.js or undici-based automation, health checks, or internal services that use the Microsoft
Authentication Broker or the same first-party application IDs against Graph or Exchange may match. Developers using
axios or undici with delegated flows can also resemble this pattern.
""",
]
from = "now-9m"
index = ["logs-azure.signinlogs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Entra ID Potential AiTM Sign-In via OfficeHome (Tycoon2FA)"
note = """## Triage and analysis
### Investigating Entra ID Potential AiTM Sign-In via OfficeHome (Tycoon2FA)
Review user.name, azure.signinlogs.properties.user_principal_name, azure.signinlogs.properties.app_id,
azure.signinlogs.properties.resource_id, user_agent.original, source.ip, source.geo fields, and
azure.signinlogs.properties.session_id.
Confirm whether the user intentionally signed in and whether Node.js-style user agents (node, axios, undici) are
expected for Microsoft Authentication Broker or Office web client flows in your environment.
### Possible investigation steps
- Correlate the session with Microsoft Graph activity logs and mailbox audit for follow-on data access.
- Review conditional access outcomes and MFA detail for the same session.
- Hunt for other sign-ins from the same source IP with unusual user agents or rapid OAuth patterns.
### Response and remediation
- If malicious, revoke refresh tokens for the user, reset credentials per policy, and review application consent.
- Block or monitor the source IP and escalate per incident procedures.
"""
references = ["https://any.run/malware-trends/tycoon/"]
risk_score = 73
rule_id = "6e6376c1-a71e-4789-a795-198b05664064"
severity = "high"
tags = [
"Domain: Cloud",
"Domain: Identity",
"Data Source: Azure",
"Data Source: Microsoft Entra ID",
"Data Source: Microsoft Entra ID Sign-in Logs",
"Use Case: Threat Detection",
"Threat: Tycoon2FA",
"Tactic: Initial Access",
"Tactic: Credential Access",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:"azure.signinlogs" and event.category:"authentication" and
event.action:"Sign-in activity" and
(
(
azure.signinlogs.properties.app_id:"29d9ed98-a469-4536-ade2-f981bc1d605e" and
azure.signinlogs.properties.resource_id:(
"00000002-0000-0ff1-ce00-000000000000" or "00000003-0000-0000-c000-000000000000"
)
) or
(
azure.signinlogs.properties.app_id:"4765445b-32c6-49b0-83e6-1d93765276ca" and
azure.signinlogs.properties.resource_id:"4765445b-32c6-49b0-83e6-1d93765276ca"
)
) and user_agent.original:(node or axios* or undici)
'''
[rule.investigation_fields]
field_names = [
"@timestamp",
"user.name",
"user_agent.original",
"source.ip",
"source.geo.country_name",
"event.outcome",
"azure.signinlogs.properties.user_principal_name",
"azure.signinlogs.properties.session_id",
"azure.signinlogs.properties.app_display_name",
"azure.signinlogs.properties.app_id",
"azure.signinlogs.properties.resource_display_name",
"azure.signinlogs.properties.resource_id",
"azure.signinlogs.properties.authentication_protocol",
"azure.tenant_id",
]
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1566"
name = "Phishing"
reference = "https://attack.mitre.org/techniques/T1566/"
[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 = "T1539"
name = "Steal Web Session Cookie"
reference = "https://attack.mitre.org/techniques/T1539/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
Stages and Predicates
Stage 1: query
data_stream.dataset:"azure.signinlogs" and event.category:"authentication" and
event.action:"Sign-in activity" and
(
(
azure.signinlogs.properties.app_id:"29d9ed98-a469-4536-ade2-f981bc1d605e" and
azure.signinlogs.properties.resource_id:(
"00000002-0000-0ff1-ce00-000000000000" or "00000003-0000-0000-c000-000000000000"
)
) or
(
azure.signinlogs.properties.app_id:"4765445b-32c6-49b0-83e6-1d93765276ca" and
azure.signinlogs.properties.resource_id:"4765445b-32c6-49b0-83e6-1d93765276ca"
)
) and user_agent.original:(node or axios* or undici)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
azure.signinlogs.properties.app_id | eq |
| field:"azure_ad::app_id" kind:eq |
azure.signinlogs.properties.resource_id | eq |
| field:"azure_ad::resource_id" kind:eq value:"4765445b-32c6-49b0-83e6-1d93765276ca" |
azure.signinlogs.properties.resource_id | in |
| field:"azure_ad::resource_id" kind:in |
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"azure.signinlogs" |
event.action | eq |
| field:"EventType" kind:eq value:"Sign-in activity" |
event.category | eq |
| field:"event.category" kind:eq value:"authentication" |
user_agent.original | eq |
| field:"aws::userAgent" kind:eq |
user_agent.original | wildcard |
| field:"aws::userAgent" kind:wildcard value:"axios*" |
Entra ID Sign-in TeamFiltration User-Agent Detected
#Identifies potential enumeration or password spraying activity using TeamFiltration tool. TeamFiltration is an open-source enumeration, password spraying and exfiltration tool designed for Entra ID and Microsoft 365. Adversaries are known to use TeamFiltration in-the-wild to enumerate users, groups, and roles, as well as to perform password spraying attacks against Microsoft Entra ID and Microsoft 365 accounts. This rule detects the use of TeamFiltration by monitoring for specific user-agent strings associated with the tool in Azure and Microsoft 365 logs.
Known False Positives
- Legitimate administrative or security assessment activities may use these user-agents, especially in environments where TeamFiltration is employed for authorized audits. If this is expected behavior, consider adjusting the rule or adding exceptions for specific user-agents or IP addresses.
- Expected red team assessments or penetration tests may utilize TeamFiltration to evaluate the security posture of Azure or Microsoft 365 environments. If this is expected behavior, consider adjusting the rule or adding exceptions for specific IP addresses, registered applications, JWT tokens, PRTs or user
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access | |
| Discovery |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2025/07/02"
integration = ["azure", "o365"]
maturity = "production"
updated_date = "2026/07/08"
[rule]
author = ["Elastic"]
description = """
Identifies potential enumeration or password spraying activity using TeamFiltration tool. TeamFiltration is an
open-source enumeration, password spraying and exfiltration tool designed for Entra ID and Microsoft 365. Adversaries
are known to use TeamFiltration in-the-wild to enumerate users, groups, and roles, as well as to perform password
spraying attacks against Microsoft Entra ID and Microsoft 365 accounts. This rule detects the use of TeamFiltration by
monitoring for specific user-agent strings associated with the tool in Azure and Microsoft 365 logs.
"""
false_positives = [
"""
Legitimate administrative or security assessment activities may use these user-agents, especially in environments
where TeamFiltration is employed for authorized audits. If this is expected behavior, consider adjusting the rule or
adding exceptions for specific user-agents or IP addresses.
""",
"""
Expected red team assessments or penetration tests may utilize TeamFiltration to evaluate the security posture of
Azure or Microsoft 365 environments. If this is expected behavior, consider adjusting the rule or adding exceptions
for specific IP addresses, registered applications, JWT tokens, PRTs or user
""",
]
from = "now-9m"
index = ["filebeat-*", "logs-azure.signinlogs-*", "logs-o365.audit-*"]
language = "kuery"
license = "Elastic License v2"
name = "Entra ID Sign-in TeamFiltration User-Agent Detected"
note = """## Triage and analysis
Identifies potential enumeration or password spraying activity using TeamFiltration tool. TeamFiltration is an open-source enumeration, password spraying and exfiltration tool designed for Entra ID and Microsoft 365. Adversaries are known to use TeamFiltration in-the-wild to enumerate users, groups, and roles, as well as to perform password spraying attacks against Microsoft Entra ID and Microsoft 365 accounts. This rule detects the use of TeamFiltration by monitoring for specific user-agent strings associated with the tool in Azure and Microsoft 365 logs.
The detection is based on TeamFiltration's hardcoded user agent string and/or the use of `Electron` by monitoring multiple log sources, including:
- Azure Graph API Activity Logs
- Microsoft 365 Audit Logs
- Entra ID Sign-in Logs
- Entra ID Audit Logs
- Azure Activity Logs
### Possible investigation steps
- Confirm the tool used via `user_agent.original`.
- Identify the `user.id`, `user.name`, or `azure.signinlogs.properties.user_principal_name` fields to determine which identity executed the API requests or sign-in attempts.
- Review `app_id`, `app_display_name`, or `client_id` to identify the application context (e.g., Azure CLI, Graph Explorer, unauthorized app). TeamFiltration uses a list of FOCI compliant applications to perform enumeration and password spraying. TeamFiltration uses Microsoft Teams client ID `1fec8e78-bce4-4aaf-ab1b-5451cc387264` for enumeration.
- Check `http.request.method`, `http.response.status_code`, and `event.action` for enumeration patterns (many successful GETs in a short period) if Graph API activity logs.
- Investigate correlated sign-ins (`azure.signinlogs`) by the same user, IP, or app immediately preceding the API calls. Was MFA used? Is the location suspicious?
- Review `source.ip` or `client.geo.*` fields to determine the origin of the requests. Flag unexpected IPs or ISPs. Check the for the use of several source addresses originating from Amazon ASNs (e.g., `AS16509`, `AS14618`, `AS14618`) which are commonly used by TeamFiltration as it proxies requests through FireProx and Amazon API Gateway.
- If the event originates in M365 Audit Logs, investigate cross-service activity: Exchange Online, Teams, SharePoint, or role escalations via Unified Audit.
### False positive analysis
- This activity may be benign if performed by red teams, internal security auditors, or known security tools under authorization.
### Response and remediation
- If confirmed malicious:
- Identify successful sign-in attempts or API calls made by the user or app.
- Revoke active sessions or tokens associated with the identified user/app.
- Disable the account or rotate credentials immediately.
- Review the role assignments (`Directory.Read.All`, `AuditLog.Read.All`, `Directory.AccessAsUser.All`) and remove excessive privileges.
- Conduct historical analysis to determine how long enumeration has been occurring and what objects were queried.
- Enable Conditional Access policies to require MFA for API and CLI-based access.
- Validate audit logging and alerting is enabled across Microsoft Graph, Azure Activity Logs, and M365 workloads.
- If legitimate:
- Document the source or user (e.g., red team operation, security tool).
- Add appropriate allowlist conditions for service principal, user, source address or device if policy allows.
"""
references = [
"https://www.proofpoint.com/us/blog/threat-insight/attackers-unleash-teamfiltration-account-takeover-campaign",
"https://github.com/Flangvik/TeamFiltration",
]
risk_score = 73
rule_id = "f541ca3a-5752-11f0-b44b-f661ea17fbcd"
severity = "high"
tags = [
"Domain: Cloud",
"Data Source: Azure",
"Data Source: Microsoft 365",
"Data Source: Microsoft 365 Audit Logs",
"Data Source: Microsoft Entra ID",
"Data Source: Microsoft Entra ID Sign-in Logs",
"Use Case: Identity and Access Audit",
"Use Case: Threat Detection",
"Tactic: Discovery",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:("azure.signinlogs" or "o365.audit")
and ((user_agent.name:"Electron" and user_agent.os.name:"Windows" and user_agent.version:"8.5.1") or
user_agent.original:"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Teams/1.3.00.30866 Chrome/80.0.3987.165 Electron/8.5.1 Safari/537.36")
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1069"
name = "Permission Groups Discovery"
reference = "https://attack.mitre.org/techniques/T1069/"
[[rule.threat.technique.subtechnique]]
id = "T1069.003"
name = "Cloud Groups"
reference = "https://attack.mitre.org/techniques/T1069/003/"
[[rule.threat.technique]]
id = "T1082"
name = "System Information Discovery"
reference = "https://attack.mitre.org/techniques/T1082/"
[[rule.threat.technique]]
id = "T1087"
name = "Account Discovery"
reference = "https://attack.mitre.org/techniques/T1087/"
[[rule.threat.technique.subtechnique]]
id = "T1087.004"
name = "Cloud Account"
reference = "https://attack.mitre.org/techniques/T1087/004/"
[[rule.threat.technique]]
id = "T1201"
name = "Password Policy Discovery"
reference = "https://attack.mitre.org/techniques/T1201/"
[[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.technique]]
id = "T1673"
name = "Virtual Machine Discovery"
reference = "https://attack.mitre.org/techniques/T1673/"
[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1110"
name = "Brute Force"
reference = "https://attack.mitre.org/techniques/T1110/"
[[rule.threat.technique.subtechnique]]
id = "T1110.003"
name = "Password Spraying"
reference = "https://attack.mitre.org/techniques/T1110/003/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
Stages and Predicates
Stage 1: query
data_stream.dataset:("azure.signinlogs" or "o365.audit")
and ((user_agent.name:"Electron" and user_agent.os.name:"Windows" and user_agent.version:"8.5.1") or
user_agent.original:"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Teams/1.3.00.30866 Chrome/80.0.3987.165 Electron/8.5.1 Safari/537.36")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | in |
| field:"data_stream.dataset" kind:in |
user_agent.name | eq |
| field:"user_agent.name" kind:eq value:"Electron" |
user_agent.original | eq |
| field:"aws::userAgent" kind:eq value:"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Teams/1.3.00.30866 Chrome/80.0.3987.165 Electron/8.5.1 Safari/537.36" |
user_agent.os.name | eq |
| field:"user_agent.os.name" kind:eq value:"Windows" |
user_agent.version | eq |
| field:"user_agent.version" kind:eq value:"8.5.1" |
Execution of a Downloaded Windows Script
#Identifies the creation of a Windows script downloaded from the internet followed by the execution of a scripting utility. Adversaries may use Windows script files for initial access and execution.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Stealth |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2025/01/31"
integration = ["endpoint"]
maturity = "production"
min_stack_comments = "Changing min stack to 9.3.0, the latest minimum supported version for 9.X releases."
min_stack_version = "9.3.0"
updated_date = "2026/07/20"
[rule]
author = ["Elastic"]
description = """
Identifies the creation of a Windows script downloaded from the internet followed by the execution of a scripting utility.
Adversaries may use Windows script files for initial access and execution.
"""
from = "now-9m"
index = ["logs-endpoint.events.file-*", "logs-endpoint.events.process-*"]
language = "eql"
license = "Elastic License v2"
name = "Execution of a Downloaded Windows Script"
risk_score = 47
rule_id = "79543b00-28a5-4461-81ac-644c4dc4012f"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Execution",
"Data Source: Elastic Defend",
"Resources: Investigation Guide"
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
sequence by host.id, user.id with maxspan=3m
[file where host.os.type == "windows" and event.action == "creation" and user.id != "S-1-5-18" and
process.name : ("chrome.exe", "msedge.exe", "brave.exe", "browser.exe", "dragon.exe", "vivaldi.exe", "explorer.exe", "winrar.exe", "7zFM.exe", "7zG.exe", "Bandizip.exe") and
file.extension in~ ("js", "jse", "vbs", "vbe", "wsh", "wsf", "sct", "hta", "cmd", "bat", "ps1", "msi") and
(file.origin_url != null or file.origin_referrer_url != null)]
[process where host.os.type == "windows" and event.type == "start" and
process.parent.name : ("chrome.exe", "msedge.exe", "brave.exe", "firefox.exe", "browser.exe", "dragon.exe", "vivaldi.exe", "explorer.exe", "winrar.exe", "7zFM.exe", "7zG.exe", "Bandizip.exe") and
process.args_count >= 2 and
(
process.name in~ ("wscript.exe", "cscript.exe", "mshta.exe") or
(process.name : "cmd.exe" and process.command_line : ("*.cmd*", "*.bat*", "*.wsf*")) or
(process.name in~ ("powershell.exe", "pwsh.exe") and process.command_line : "*.ps1*") or
(process.name : "msiexec.exe" and process.command_line : "*.msi" and process.args : ("/i*", "-i*"))
)]
'''
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
"""
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 Execution of a downloaded windows script
Windows scripts, often used for legitimate automation tasks, can be exploited by adversaries to execute malicious code. Attackers may download scripts via browsers or file utilities, then execute them using scripting tools like wscript or mshta. The detection rule identifies such threats by monitoring script creation from internet sources and subsequent execution, focusing on unusual parent-child process relationships and script attributes.
### Possible investigation steps
- Review the file creation event to identify the specific script file that was downloaded, noting its name, path, and extension to understand the potential threat.
- Examine the origin URL or referrer URL of the downloaded script to determine the source and assess its legitimacy or potential malicious intent.
- Investigate the parent process, such as chrome.exe or explorer.exe, to understand how the script was downloaded and whether it aligns with typical user behavior.
- Analyze the execution event of the scripting utility (wscript.exe or mshta.exe) to identify the command-line arguments used, which may provide insight into the script's intended actions.
- Check the user account associated with the script execution to determine if the activity is expected for that user or if it indicates a compromised account.
- Correlate the timing of the script creation and execution events to see if they fall within a suspicious timeframe, such as outside of normal working hours.
- Look for any additional related alerts or logs on the host that might indicate further malicious activity or lateral movement following the script execution.
### False positive analysis
- Legitimate script automation tools may trigger this rule if they download and execute scripts from the internet. Users can create exceptions for known safe tools by excluding specific file paths or process names.
- Software updates or installations that download scripts as part of their process might be flagged. To handle this, users can whitelist specific origin URLs or referrer URLs associated with trusted software vendors.
- Internal scripts distributed via corporate intranet sites could be misidentified as threats. Users should consider excluding scripts with known internal origin URLs or specific user IDs associated with IT operations.
- Browser extensions or plugins that automate tasks using scripts may cause false positives. Users can exclude these by identifying and excluding the specific browser process names or file extensions involved.
- Frequent use of file utilities like winrar or 7zFM for legitimate script handling can be excluded by specifying trusted file paths or user IDs that regularly perform these actions.
### Response and remediation
- Isolate the affected system from the network to prevent further execution of potentially malicious scripts and lateral movement.
- Terminate any suspicious processes identified in the alert, such as wscript.exe or mshta.exe, to stop the execution of the downloaded script.
- Quarantine the downloaded script file and any associated files to prevent further execution and facilitate forensic analysis.
- Conduct a thorough scan of the affected system using updated antivirus or endpoint detection and response (EDR) tools to identify and remove any additional malicious files or remnants.
- Review and analyze the origin URL and referrer URL of the downloaded script to identify potential malicious websites or compromised sources, and block these URLs at the network level.
- 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 application whitelisting to restrict the execution of unauthorized scripts and scripting utilities, reducing the risk of similar threats in the future."""
[[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.subtechnique]]
id = "T1059.005"
name = "Visual Basic"
reference = "https://attack.mitre.org/techniques/T1059/005/"
[[rule.threat.technique.subtechnique]]
id = "T1059.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"
[[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.005"
name = "Mshta"
reference = "https://attack.mitre.org/techniques/T1218/005/"
[[rule.threat.technique.subtechnique]]
id = "T1218.007"
name = "Msiexec"
reference = "https://attack.mitre.org/techniques/T1218/007/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Ordered sequence: each step below must occur in order within 3m, correlated by host.id, user.id.
Stage 1: file
[file where host.os.type == "windows" and event.action == "creation" and user.id != "S-1-5-18" and
process.name : ("chrome.exe", "msedge.exe", "brave.exe", "browser.exe", "dragon.exe", "vivaldi.exe", "explorer.exe", "winrar.exe", "7zFM.exe", "7zG.exe", "Bandizip.exe") and
file.extension in~ ("js", "jse", "vbs", "vbe", "wsh", "wsf", "sct", "hta", "cmd", "bat", "ps1", "msi") and
(file.origin_url != null or file.origin_referrer_url != null)]
Stage 2: process
[process where host.os.type == "windows" and event.type == "start" and
process.parent.name : ("chrome.exe", "msedge.exe", "brave.exe", "firefox.exe", "browser.exe", "dragon.exe", "vivaldi.exe", "explorer.exe", "winrar.exe", "7zFM.exe", "7zG.exe", "Bandizip.exe") and
process.args_count >= 2 and
(
process.name in~ ("wscript.exe", "cscript.exe", "mshta.exe") or
(process.name : "cmd.exe" and process.command_line : ("*.cmd*", "*.bat*", "*.wsf*")) or
(process.name in~ ("powershell.exe", "pwsh.exe") and process.command_line : "*.ps1*") or
(process.name : "msiexec.exe" and process.command_line : "*.msi" and process.args : ("/i*", "-i*"))
)]
Indicators
These rows show field, operator, and value matches.
File Download from or Upload to Hosting Service
#This rule detects the execution of curl or wget commands that download files from hosting services. Attackers may use these services to temporary host malicious files or payloads for later execution.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution |
Rule Body
[rule]
description = """
This rule detects the execution of curl or wget commands that download files from hosting services. Attackers may use
these services to temporary host malicious files or payloads for later execution.
"""
id = "5c18132a-e279-404e-a8d8-922546d469a7"
license = "Elastic License v2"
name = "File Download from or Upload to Hosting Service"
os_list = ["linux"]
version = "1.0.10"
query = '''
process where event.type == "start" and event.action == "exec" and process.name in ("curl", "wget") and
process.command_line like~ (
"*pastebin.*", "*ghostbin.*", "*hastebin.*", "*termbin.*", "*dpaste.*", "*controlc.*", "*0bin.net*", "*p.ip.fi*", "*sprunge.us*", "*paste.ee*",
"*paste.ofcode.org*", "*textbin.net*", "*transfer.sh*", "*anonfiles.*", "*easyupload.io*", "*gofile.io*", "*send.cm*", "*ufile.io*",
"*pixeldrain.com*", "*bayfiles.*", "*megaupload.*", "*mediafire.*", "*zippyshare.com*", "*dropapk.to*", "*shorturl.at*", "*tinyurl.com*",
"*bit.ly/*", "*cutt.ly/*", "*is.gd/*", "*rebrand.ly/*", "*adf.ly/*", "*rb.gy/*", "*bashupload.com/*", "*bujang.online/*", "*paste.wakas.org*",
"*paste.c-net.org*", "*paste.hexaspaces.com*"
) and not (
process.parent.executable in ("/opt/aws/awsagent/bin/update", "/batch/pac.liste.categorie.sh") or
process.parent.args == "/usr/local/gg/crowdsec-extract.sh" or
process.parent.command_line like "*/.claude/shell-snapshots/snapshot-*"
)
'''
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
tree = true
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: process
process where event.type == "start" and event.action == "exec" and process.name in ("curl", "wget") and
process.command_line like~ (
"*pastebin.*", "*ghostbin.*", "*hastebin.*", "*termbin.*", "*dpaste.*", "*controlc.*", "*0bin.net*", "*p.ip.fi*", "*sprunge.us*", "*paste.ee*",
"*paste.ofcode.org*", "*textbin.net*", "*transfer.sh*", "*anonfiles.*", "*easyupload.io*", "*gofile.io*", "*send.cm*", "*ufile.io*",
"*pixeldrain.com*", "*bayfiles.*", "*megaupload.*", "*mediafire.*", "*zippyshare.com*", "*dropapk.to*", "*shorturl.at*", "*tinyurl.com*",
"*bit.ly/*", "*cutt.ly/*", "*is.gd/*", "*rebrand.ly/*", "*adf.ly/*", "*rb.gy/*", "*bashupload.com/*", "*bujang.online/*", "*paste.wakas.org*",
"*paste.c-net.org*", "*paste.hexaspaces.com*"
) and not (
process.parent.executable in ("/opt/aws/awsagent/bin/update", "/batch/pac.liste.categorie.sh") or
process.parent.args == "/usr/local/gg/crowdsec-extract.sh" or
process.parent.command_line like "*/.claude/shell-snapshots/snapshot-*"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard |
process.name | in |
| field:"process_basename" kind:in |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.parent.args | eq | /usr/local/gg/crowdsec-extract.sh | excludes:process.parent.args field:"process.parent.args" value:"/usr/local/gg/crowdsec-extract.sh" |
process.parent.command_line | match | /.claude/shell-snapshots/snapshot- | excludes:process.parent.command_line field:"process.parent.command_line" value:"/.claude/shell-snapshots/snapshot-" |
process.parent.executable | in | /batch/pac.liste.categorie.sh, /opt/aws/awsagent/bin/update | excludes:process.parent.executable field:"process.parent.executable" value:"/batch/pac.liste.categorie.sh" field:"process.parent.executable" value:"/opt/aws/awsagent/bin/update" |
Javascript Reverse Shell via Nodejs
#Detects Node.js spawning child processes to execute JavaScript files, followed by network connections to raw IP addresses within one minute. This indicates malicious NPM packages establishing reverse shells in supply chain attacks.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Execution |
Telemetry Coverage
Rule Body
[rule]
description = """
Detects Node.js spawning child processes to execute JavaScript files, followed by network connections to raw IP
addresses within one minute. This indicates malicious NPM packages establishing reverse shells in supply chain attacks.
"""
id = "753afa27-34c9-41d9-b61e-373c0182bd4e"
license = "Elastic License v2"
name = "Javascript Reverse Shell via Nodejs"
os_list = ["macos"]
reference = ["https://www.reversinglabs.com/blog/malicious-npm-patch-delivers-reverse-shell"]
version = "1.0.6"
query = '''
sequence by process.entity_id with maxspan=1m
[process where event.type == "start" and event.action == "exec" and process.name == "node" and
process.args == "node" and process.args : "*.js" and process.args_count == 2 and
process.parent.name == "node"]
[network where event.type == "start" and destination.domain == null and
not destination.port == 53 and
not cidrmatch(destination.ip,
"240.0.0.0/4", "233.252.0.0/24", "224.0.0.0/4", "198.19.0.0/16", "192.18.0.0/15",
"192.0.0.0/24", "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12",
"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",
"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",
"::1", "FE80::/10", "FF00::/8", "0.0.0.0/32")]
'''
min_endpoint_version = "8.16.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1195"
name = "Supply Chain Compromise"
reference = "https://attack.mitre.org/techniques/T1195/"
[[threat.technique.subtechnique]]
id = "T1195.001"
name = "Compromise Software Dependencies and Development Tools"
reference = "https://attack.mitre.org/techniques/T1195/001/"
[threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[internal]
min_endpoint_version = "8.16.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 == "exec" and process.name == "node" and
process.args == "node" and process.args : "*.js" and process.args_count == 2 and
process.parent.name == "node"]
Stage 2: network
[network where event.type == "start" and destination.domain == null and
not destination.port == 53 and
not cidrmatch(destination.ip,
"240.0.0.0/4", "233.252.0.0/24", "224.0.0.0/4", "198.19.0.0/16", "192.18.0.0/15",
"192.0.0.0/24", "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12",
"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",
"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",
"::1", "FE80::/10", "FF00::/8", "0.0.0.0/32")]
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
destination.ip | cidr_match | 240.0.0.0/4, 233.252.0.0/24, 224.0.0.0/4, 198.19.0.0/16, 192.18.0.0/15, 192.0.0.0/24, 10.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 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, 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, ::1, FE80::/10, FF00::/8, 0.0.0.0/32 | excludes:destination.ip |
destination.port | eq | 53 | excludes:destination.port field:"destination.port" value:"53" |
Kerberos Pre-authentication Disabled for User
#Identifies the modification of an account's Kerberos pre-authentication options. An adversary with GenericWrite/GenericAll rights over the account can maliciously modify these settings to perform offline password cracking attacks such as AS-REP roasting.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Privilege Escalation | |
| Stealth | |
| Defense Impairment | |
| Credential Access |
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Security-Auditing | Event ID 4738: A user account was changed. |
Rule Body
[metadata]
creation_date = "2022/01/24"
integration = ["system", "windows"]
maturity = "production"
updated_date = "2026/05/04"
[rule]
author = ["Elastic"]
description = """
Identifies the modification of an account's Kerberos pre-authentication options. An adversary with
GenericWrite/GenericAll rights over the account can maliciously modify these settings to perform offline password
cracking attacks such as AS-REP roasting.
"""
from = "now-9m"
index = ["logs-system.security*", "logs-windows.forwarded*", "winlogbeat-*"]
language = "eql"
license = "Elastic License v2"
name = "Kerberos Pre-authentication Disabled for User"
note = """## Triage and analysis
### Investigating Kerberos Pre-authentication Disabled for User
Kerberos pre-authentication is an account protection against offline password cracking. When enabled, a user requesting access to a resource initiates communication with the Domain Controller (DC) by sending an Authentication Server Request (AS-REQ) message with a timestamp that is encrypted with the hash of their password. If and only if the DC is able to successfully decrypt the timestamp with the hash of the user’s password, it will then send an Authentication Server Response (AS-REP) message that contains the Ticket Granting Ticket (TGT) to the user. Part of the AS-REP message is signed with the user’s password. Microsoft's security monitoring [recommendations](https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4738) state that `'Don't Require Preauth' – Enabled` should not be enabled for user accounts because it weakens security for the account’s Kerberos authentication.
AS-REP roasting is an attack against Kerberos for user accounts that do not require pre-authentication, which means that if the target user has pre-authentication disabled, an attacker can request authentication data for it and get a TGT that can be brute-forced offline, similarly to Kerberoasting.
#### Possible investigation steps
- Identify the user account that performed the action and whether it should perform this kind of action.
- Contact the account owner and confirm whether they are aware of this activity.
- Determine if the target account is sensitive or privileged.
- Inspect the account activities for suspicious or abnormal behaviors in the alert timeframe.
### False positive analysis
- Disabling pre-authentication is a bad security practice and should not be allowed in the domain. The security team should map and monitor any potential benign true positives (B-TPs), especially if the target account is privileged.
### Response and remediation
- Initiate the incident response process based on the outcome of the triage.
- Reset the target account's password if there is any risk of TGTs having been retrieved.
- Re-enable the preauthentication option or disable the target account.
- Review the privileges assigned to the involved users to ensure that the least privilege principle is being followed.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- 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://harmj0y.medium.com/roasting-as-reps-e6179a65216b",
"https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4738",
"https://github.com/atc-project/atomic-threat-coverage/blob/master/Atomic_Threat_Coverage/Logging_Policies/LP_0026_windows_audit_user_account_management.md",
]
risk_score = 47
rule_id = "e514d8cd-ed15-4011-84e2-d15147e059f1"
setup = """## Setup
Audit User Account Management must be enabled to generate the events used by this rule.
Setup instructions: https://ela.st/audit-user-account-management
"""
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Credential Access",
"Tactic: Defense Evasion",
"Tactic: Privilege Escalation",
"Resources: Investigation Guide",
"Use Case: Active Directory Monitoring",
"Data Source: Active Directory",
"Data Source: Windows Security Event Logs",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
any where host.os.type == "windows" and event.code == "4738" and
winlog.event_data.NewUACList == "USER_DONT_REQUIRE_PREAUTH"
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1558"
name = "Steal or Forge Kerberos Tickets"
reference = "https://attack.mitre.org/techniques/T1558/"
[[rule.threat.technique.subtechnique]]
id = "T1558.004"
name = "AS-REP Roasting"
reference = "https://attack.mitre.org/techniques/T1558/004/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"
[[rule.threat.technique.subtechnique]]
id = "T1078.002"
name = "Domain Accounts"
reference = "https://attack.mitre.org/techniques/T1078/002/"
[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
Stages and Predicates
Stage 1: any
any where host.os.type == "windows" and event.code == "4738" and
winlog.event_data.NewUACList == "USER_DONT_REQUIRE_PREAUTH"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.code | eq |
| field:"EventID" kind:eq value:"4738" |
winlog.event_data.NewUACList | eq |
| field:"NewUACList" kind:eq value:"USER_DONT_REQUIRE_PREAUTH" |
Kubernetes Rapid Secret GET Activity Against Multiple Objects
#This rule detects an unusual volume of Kubernetes API get requests against multiple distinct Secret objects from the same client fingerprint (user, source IP, and user agent) within a defined lookback window. This can indicate credential access or in-cluster reconnaissance, where a user or token is used to enumerate and retrieve sensitive data such as service account tokens, registry credentials, TLS material, or application configuration. Failed get requests are also included, as they may reveal RBAC boundaries, confirm the existence of targeted secrets, or reflect automated probing activity.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Kubernetes | any-secrets: any verb on secrets (synthetic aggregation) |
Rules Detecting the Same Action
These rules filter on the same operation.
Rule Body
[metadata]
creation_date = "2026/04/22"
integration = ["kubernetes"]
maturity = "production"
updated_date = "2026/05/15"
[rule]
author = ["Elastic"]
description = """
This rule detects an unusual volume of Kubernetes API get requests against multiple distinct Secret objects from the same client
fingerprint (user, source IP, and user agent) within a defined lookback window. This can indicate credential access or in-cluster
reconnaissance, where a user or token is used to enumerate and retrieve sensitive data such as service account tokens, registry
credentials, TLS material, or application configuration. Failed get requests are also included, as they may reveal RBAC boundaries,
confirm the existence of targeted secrets, or reflect automated probing activity.
"""
from = "now-6m"
language = "esql"
license = "Elastic License v2"
name = "Kubernetes Rapid Secret GET Activity Against Multiple Objects"
note = """## Triage and analysis
### Investigating Kubernetes Rapid Secret GET Activity Against Multiple Objects
This rule surfaces clusters of `get` operations on the `secrets` API where the same identity and client path
(`user.name`, `source.ip`, `user_agent.original`) touch several different secret names within the rule lookback window.
**Allowed and denied** outcomes are included: successful reads may indicate harvesting; repeated **forbidden** or
**unauthorized** responses can still signal reconnaissance, RBAC probing, or scripted spray against secret names that
exist in the cluster.
### Investigation steps
- Inspect `Esql.outcome` for a mix of allow vs deny and whether failures cluster on sensitive namespaces.
- Map the identity to RBAC and namespace scope; review `Esql.secrets_names` and `Esql.namespaces` for high-value
targets (tokens, registry credentials, TLS bundles, application secrets).
- Pivot on the same `source.ip` and user for follow-on API activity (exec, pod create, role changes, broad `list` on secrets).
- Validate against expected automation (CI, GitOps, backup, in-cluster controllers) before treating as malicious.
### False positives
- Startup, Helm, or controllers may legitimately touch many secrets in one window; tune by user, namespace, or IP
allowlists when baselined.
"""
references = [
"https://attack.mitre.org/techniques/T1552/007/",
]
risk_score = 73
rule_id = "b4c8e2a1-9f3d-4e7c-a2b1-0d5e6f7a8b9c"
severity = "high"
tags = [
"Data Source: Kubernetes",
"Domain: Kubernetes",
"Use Case: Threat Detection",
"Tactic: Credential Access",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-kubernetes.audit_logs-* metadata _id, _index, _version
| where event.dataset == "kubernetes.audit_logs"
and event.action == "get"
and kubernetes.audit.objectRef.resource == "secrets"
and source.ip is not null and user.name is not null
and not to_string(source.ip) in ("127.0.0.1", "::1") and
not user.name in ("system:kube-controller-manager", "system:kube-scheduler") and
not kubernetes.audit.objectRef.name like "sh.helm.release.*" and
not kubernetes.audit.user.username in ("system:serviceaccount:flux-system:kustomize-controller", "system:serviceaccount:flux-system:helm-controller", "system:serviceaccount:flux-system:source-controller", "system:serviceaccount:security:trivy-operator")
| stats
Esql.unique_credentials = count_distinct(kubernetes.audit.objectRef.name),
Esql.secrets_names = values(kubernetes.audit.objectRef.name),
Esql.namespaces = values(kubernetes.audit.objectRef.namespace),
Esql.outcome = values(`kubernetes.audit.annotations.authorization_k8s_io/decision`)
by user.name, kubernetes.audit.user.username, source.ip, user_agent.original
| where Esql.unique_credentials >= 3
| KEEP user.name, kubernetes.audit.user.username, source.ip, user_agent.original, Esql.*
'''
[[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.007"
name = "Container API"
reference = "https://attack.mitre.org/techniques/T1552/007/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
Stages and Predicates
Stage 1: from
from logs-kubernetes.audit_logs-* metadata _id, _index, _version
Stage 2: where
| where event.dataset == "kubernetes.audit_logs"
and event.action == "get"
and kubernetes.audit.objectRef.resource == "secrets"
and source.ip is not null and user.name is not null
and not to_string(source.ip) in ("127.0.0.1", "::1") and
not user.name in ("system:kube-controller-manager", "system:kube-scheduler") and
not kubernetes.audit.objectRef.name like "sh.helm.release.*" and
not kubernetes.audit.user.username in ("system:serviceaccount:flux-system:kustomize-controller", "system:serviceaccount:flux-system:helm-controller", "system:serviceaccount:flux-system:source-controller", "system:serviceaccount:security:trivy-operator")
Stage 3: stats
| stats
Esql.unique_credentials = count_distinct(kubernetes.audit.objectRef.name),
Esql.secrets_names = values(kubernetes.audit.objectRef.name),
Esql.namespaces = values(kubernetes.audit.objectRef.namespace),
Esql.outcome = values(`kubernetes.audit.annotations.authorization_k8s_io/decision`)
by user.name, kubernetes.audit.user.username, source.ip, user_agent.original
Stage 4: where
| where Esql.unique_credentials >= 3
Stage 5: keep
| KEEP user.name, kubernetes.audit.user.username, source.ip, user_agent.original, Esql.*
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
kubernetes.audit.objectRef.name | starts_with | sh.helm.release. | excludes:kubernetes.audit.objectRef.name field:"kubernetes.audit.objectRef.name" value:"sh.helm.release." |
kubernetes.audit.user.username | in | system:serviceaccount:flux-system:helm-controller, system:serviceaccount:flux-system:kustomize-controller, system:serviceaccount:flux-system:source-controller, system:serviceaccount:security:trivy-operator | excludes:kubernetes.audit.user.username |
user.name | in | system:kube-controller-manager, system:kube-scheduler | excludes:user.name field:"user.name" value:"system:kube-controller-manager" field:"user.name" value:"system:kube-scheduler" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
user.name | KEEP user.name |
kubernetes.audit.user.username | KEEP kubernetes.audit.user.username |
source.ip | KEEP source.ip |
user_agent.original | KEEP user_agent.original |
Esql.* | KEEP Esql.* |
Kubernetes Suspicious Self-Subject Review via Unusual User Agent
#This rule detects when a service account or node attempts to enumerate their own permissions via the selfsubjectaccessreview or selfsubjectrulesreview APIs via an unusual user agent. This is highly unusual behavior for non-human identities like service accounts and nodes. An adversary may have gained access to credentials/tokens and this could be an attempt to determine what privileges they have to facilitate further movement or execution within the cluster.
Known False Positives
- An administrator may submit this request as an "impersonatedUser" to determine what privileges a particular service account has been granted. However, an adversary may utilize the same technique as a means to determine the privileges of another token other than that of the compromised account.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Discovery |
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
Rule Body
[metadata]
creation_date = "2022/06/30"
integration = ["kubernetes"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
This rule detects when a service account or node attempts to enumerate their own permissions via the selfsubjectaccessreview
or selfsubjectrulesreview APIs via an unusual user agent. This is highly unusual behavior for non-human identities like
service accounts and nodes. An adversary may have gained access to credentials/tokens and this could be an attempt to
determine what privileges they have to facilitate further movement or execution within the cluster.
"""
false_positives = [
"""
An administrator may submit this request as an "impersonatedUser" to determine what privileges a particular service
account has been granted. However, an adversary may utilize the same technique as a means to determine the
privileges of another token other than that of the compromised account.
""",
]
index = ["logs-kubernetes.audit_logs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Kubernetes Suspicious Self-Subject Review via Unusual User Agent"
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 Kubernetes Suspicious Self-Subject Review via Unusual User Agent
Kubernetes uses APIs like selfsubjectaccessreview and selfsubjectrulesreview to allow entities to check their own permissions. While useful for debugging, adversaries can exploit these APIs to assess their access level after compromising service accounts or nodes. The detection rule identifies unusual API calls by non-human identities, flagging potential unauthorized privilege enumeration attempts.
### Possible investigation steps
- Review the Kubernetes audit logs to identify the specific service account or node that triggered the alert by examining the kubernetes.audit.user.username or kubernetes.audit.impersonatedUser.username fields.
- Check the context of the API call by analyzing the kubernetes.audit.objectRef.resource field to confirm whether it involved selfsubjectaccessreviews or selfsubjectrulesreviews.
- Investigate the source of the API request by looking at the IP address and user agent in the audit logs to determine if the request originated from a known or expected source.
- Assess the recent activity of the implicated service account or node to identify any unusual patterns or deviations from normal behavior.
- Verify if there have been any recent changes to the permissions or roles associated with the service account or node to understand if the access level has been altered.
- Cross-reference the alert with any other security events or alerts in the environment to determine if this is part of a broader attack or compromise.
### False positive analysis
- Service accounts used for automated tasks may trigger this rule if they are programmed to check permissions as part of their routine operations. To handle this, identify these accounts and create exceptions for their specific API calls.
- Nodes performing legitimate self-assessment for compliance or security checks might be flagged. Review the node's purpose and, if necessary, whitelist these actions in the detection rule.
- Development or testing environments where permissions are frequently checked by service accounts can generate false positives. Consider excluding these environments from the rule or adjusting the rule's sensitivity for these specific contexts.
- Regularly scheduled jobs or scripts that include permission checks as part of their execution may cause alerts. Document these jobs and adjust the rule to ignore these specific, non-threatening behaviors.
### Response and remediation
- Immediately isolate the compromised service account or node by revoking its access tokens and credentials to prevent further unauthorized actions within the cluster.
- Conduct a thorough review of the audit logs to identify any other suspicious activities or access patterns associated with the compromised identity, focusing on any lateral movement or privilege escalation attempts.
- Rotate credentials and tokens for all service accounts and nodes that may have been exposed or compromised, ensuring that new credentials are distributed securely.
- Implement network segmentation and access controls to limit the ability of compromised identities to interact with sensitive resources or other parts of the cluster.
- Escalate the incident to the security operations team for further investigation and to determine if additional systems or data have been affected.
- Enhance monitoring and alerting for similar suspicious activities by tuning detection systems to recognize patterns of unauthorized privilege enumeration attempts.
- Review and update Kubernetes role-based access control (RBAC) policies to ensure that service accounts and nodes have the minimum necessary permissions, reducing the risk of privilege abuse.
## Setup
The Kubernetes Fleet integration with Audit Logs enabled or similarly structured data is required to be compatible with this rule."""
references = [
"https://www.paloaltonetworks.com/apps/pan/public/downloadResource?pagePath=/content/pan/en_US/resources/whitepapers/kubernetes-privilege-escalation-excessive-permissions-in-popular-platforms",
"https://kubernetes.io/docs/reference/access-authn-authz/authorization/#checking-api-access",
"https://techcommunity.microsoft.com/t5/microsoft-defender-for-cloud/detecting-identity-attacks-in-kubernetes/ba-p/3232340",
]
risk_score = 21
rule_id = "12a2f15d-597e-4334-88ff-38a02cb1330b"
severity = "low"
tags = [
"Data Source: Kubernetes",
"Domain: Kubernetes",
"Use Case: Threat Detection",
"Tactic: Discovery",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
data_stream.dataset : "kubernetes.audit_logs" and
kubernetes.audit.annotations.authorization_k8s_io/decision:"allow" and
kubernetes.audit.verb:"create" and
kubernetes.audit.objectRef.resource:("selfsubjectaccessreviews" or "selfsubjectrulesreviews") and (
kubernetes.audit.user.username:(system\:serviceaccount\:* or system\:node\:*) or
kubernetes.audit.impersonatedUser.username:(system\:serviceaccount\:* or system\:node\:*)
) and user_agent.original:(* and not (*kubernetes/$Format))
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1069"
name = "Permission Groups Discovery"
reference = "https://attack.mitre.org/techniques/T1069/"
[[rule.threat.technique.subtechnique]]
id = "T1069.003"
name = "Cloud Groups"
reference = "https://attack.mitre.org/techniques/T1069/003/"
[[rule.threat.technique]]
id = "T1613"
name = "Container and Resource Discovery"
reference = "https://attack.mitre.org/techniques/T1613/"
[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
[rule.new_terms]
field = "new_terms_fields"
value = ["user_agent.original"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-7d"
Stages and Predicates
Stage 1: new_terms
data_stream.dataset : "kubernetes.audit_logs" and
kubernetes.audit.annotations.authorization_k8s_io/decision:"allow" and
kubernetes.audit.verb:"create" and
kubernetes.audit.objectRef.resource:("selfsubjectaccessreviews" or "selfsubjectrulesreviews") and (
kubernetes.audit.user.username:(system\:serviceaccount\:* or system\:node\:*) or
kubernetes.audit.impersonatedUser.username:(system\:serviceaccount\:* or system\:node\:*)
) and user_agent.original:(* and not (*kubernetes/$Format))
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"kubernetes.audit_logs" |
kubernetes.audit.annotations.authorization_k8s_io/decision | eq |
| field:"kubernetes.audit.annotations.authorization_k8s_io/decision" kind:eq value:"allow" |
kubernetes.audit.impersonatedUser.username | wildcard |
| field:"kubernetes.audit.impersonatedUser.username" kind:wildcard |
kubernetes.audit.objectRef.resource | in |
| field:"kubernetes.audit.objectRef.resource" kind:in |
kubernetes.audit.user.username | wildcard |
| field:"kubernetes.audit.user.username" kind:wildcard |
kubernetes.audit.verb | eq |
| field:"kubernetes.audit.verb" kind:eq value:"create" |
user_agent.original | is_not_null | field:"aws::userAgent" kind:is_not_null |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
user_agent.original | ends_with | kubernetes/$Format | excludes:user_agent.original field:"user_agent.original" value:"kubernetes/$Format" |
Lateral Movement Alerts from a Newly Observed User
#This rule detects multiple lateral movement alerts from a user that was observed for the first time in the previous 5 days of alerts history. Analysts can use this high-order detection to prioritize triage and response.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Lateral Movement | No specific technique |
Rule Body
[metadata]
creation_date = "2026/01/14"
maturity = "production"
updated_date = "2026/02/16"
[rule]
author = ["Elastic"]
description = """
This rule detects multiple lateral movement alerts from a user that was observed for the first time in the previous 5 days
of alerts history. Analysts can use this high-order detection to prioritize triage and response.
"""
from = "now-7200m"
interval = "9m"
language = "esql"
license = "Elastic License v2"
name = "Lateral Movement Alerts from a Newly Observed User"
risk_score = 73
rule_id = "e819b7eb-c2d4-4adc-b0c9-658aeb140450"
severity = "high"
tags = ["OS: Windows", "Use Case: Threat Detection", "Rule Type: Higher-Order Rule", "Tactic: Lateral Movement", "Resources: Investigation Guide"]
timestamp_override = "event.ingested"
type = "esql"
query = '''
FROM .alerts-security.* METADATA _index
// Lateral Movement related rules
| where kibana.alert.rule.threat.tactic.name is not null and user.id is not null and
(to_string(user.id) like "S-1-5-21*" or to_string(user.id) like "S-1-12-*") and
host.id is not null and KQL("""kibana.alert.rule.threat.tactic.name : "Lateral Movement" """) and
not KQL("""kibana.alert.rule.tags : "Rule Type: Higher-Order Rule" """)
// aggregate stats by user.id
| stats Esql.first_time_seen = MIN(@timestamp),
Esql.alerts_count = count(*),
Esql.unique_rules_count = COUNT_DISTINCT(kibana.alert.rule.name),
Esql.unique_count_host_id = COUNT_DISTINCT(host.id),
Esql.rule_name_values = VALUES(kibana.alert.rule.name),
Esql.host_id_values = VALUES(host.id),
Esql.host_ip_values = VALUES(host.ip),
Esql.source_ip_values = VALUES(source.ip),
Esql.process_cmd_line = VALUES(process.command_line),
Esql.tactic_name_values = VALUES(kibana.alert.rule.threat.tactic.name) by user.id, user.name
// at least 2 unique lateral movement detection rules from same user.id and that was first seen in last 5 days
| eval Esql.date_diff = DATE_DIFF("minute", Esql.first_time_seen, now())
| where Esql.unique_rules_count >= 2 and
// matches are within 10m of the rule execution time to avoid alert duplicates
Esql.date_diff <= 10
| eval source.ip = MV_FIRST(Esql.source_ip_values), host.id = MV_FIRST(Esql.host_id_values)
| KEEP Esql.*, user.id, user.name, host.id, source.ip
'''
note = """## Triage and analysis
### Investigating Lateral Movement Alerts from a Newly Observed User
This rule surfaces newly observed, low-frequency source user triggering multiple lateral movement alerts.
Because the alert has not been seen previously for this rule and host, it should be prioritized for validation to determine
whether it represents a true compromise or rare benign activity.
### Investigation Steps
- Identify the source user, affected hosts and review the associated rule name to understand the behavior that triggered the alert.
- Validate the source address and user context under which the activity occurred and assess whether it aligns with normal behavior for that address.
- Refer to the specific rule investigation guide for further actions.
### False Positive Considerations
- Administrative scripts or automation tools can trigger behavior-based detections when first introduced.
- Security tooling, IT management agents, or EDR integrations may generate new behavior alerts during updates or configuration changes.
- Development or testing environments may produce one-off behaviors that resemble malicious techniques.
### Response and Remediation
- If the activity is confirmed malicious, isolate the affected host to prevent further execution or lateral movement.
- Terminate malicious processes and remove any dropped files or persistence mechanisms.
- Collect forensic artifacts to understand initial access and execution flow.
- Patch or remediate any vulnerabilities or misconfigurations that enabled the behavior.
- If benign, document the finding and consider tuning or exception handling to reduce future noise.
- Continue monitoring the host and environment for recurrence of the behavior or related alerts."""
references = ["https://www.elastic.co/docs/solutions/security/detect-and-alert/about-detection-rules"]
[[rule.threat]]
framework = "MITRE ATT&CK"
[rule.threat.tactic]
id = "TA0008"
name = "Lateral Movement"
reference = "https://attack.mitre.org/tactics/TA0008/"
Stages and Predicates
Stage 1: from
FROM .alerts-security.* METADATA _index
Stage 2: where
| where kibana.alert.rule.threat.tactic.name is not null and user.id is not null and
(to_string(user.id) like "S-1-5-21*" or to_string(user.id) like "S-1-12-*") and
host.id is not null and KQL("""kibana.alert.rule.threat.tactic.name : "Lateral Movement" """) and
not KQL("""kibana.alert.rule.tags : "Rule Type: Higher-Order Rule" """)
Stage 3: stats
| stats Esql.first_time_seen = MIN(@timestamp),
Esql.alerts_count = count(*),
Esql.unique_rules_count = COUNT_DISTINCT(kibana.alert.rule.name),
Esql.unique_count_host_id = COUNT_DISTINCT(host.id),
Esql.rule_name_values = VALUES(kibana.alert.rule.name),
Esql.host_id_values = VALUES(host.id),
Esql.host_ip_values = VALUES(host.ip),
Esql.source_ip_values = VALUES(source.ip),
Esql.process_cmd_line = VALUES(process.command_line),
Esql.tactic_name_values = VALUES(kibana.alert.rule.threat.tactic.name) by user.id, user.name
Stage 4: eval
| eval Esql.date_diff = DATE_DIFF("minute", Esql.first_time_seen, now())
Stage 5: where
| where Esql.unique_rules_count >= 2 and
Esql.date_diff <= 10
Stage 6: eval
| eval source.ip = MV_FIRST(Esql.source_ip_values), host.id = MV_FIRST(Esql.host_id_values)
Stage 7: keep
| KEEP Esql.*, user.id, user.name, host.id, source.ip
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
kibana.alert.rule.tags | eq | Rule Type: Higher-Order Rule | excludes:kibana.alert.rule.tags field:"kibana.alert.rule.tags" value:"Rule Type: Higher-Order Rule" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Esql.* | KEEP Esql.* |
user.id | KEEP user.id |
user.name | KEEP user.name |
host.id | KEEP host.id |
source.ip | KEEP source.ip |
Malware - Prevented - Elastic Endgame
#Elastic Endgame prevented Malware. Click the Elastic Endgame icon in the event.module column or the link in the rule.reference column for additional information.
Rule Body
[metadata]
creation_date = "2020/02/18"
maturity = "production"
promotion = true
updated_date = "2025/03/21"
[rule]
author = ["Elastic"]
description = """
Elastic Endgame prevented Malware. Click the Elastic Endgame icon in the event.module column or the link in the
rule.reference column for additional information.
"""
from = "now-2m"
index = ["endgame-*"]
interval = "1m"
language = "kuery"
license = "Elastic License v2"
max_signals = 1000
name = "Malware - Prevented - Elastic Endgame"
risk_score = 73
rule_id = "3b382770-efbb-44f4-beed-f5e0a051b895"
setup = """## Setup
### Additional notes
For information on troubleshooting the maximum alerts warning please refer to this [guide](https://www.elastic.co/guide/en/security/current/alerts-ui-monitor.html#troubleshoot-max-alerts).
"""
severity = "high"
tags = ["Data Source: Elastic Endgame", "Resources: Investigation Guide"]
timestamp_override = "event.ingested"
type = "query"
query = '''
event.kind:alert and event.module:endgame and endgame.metadata.type:prevention and (event.action:file_classification_event or endgame.event_subtype_full:file_classification_event)
'''
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 Malware - Prevented - Elastic Endgame
Elastic Endgame is a security solution designed to prevent malware by analyzing and classifying files in real-time. Adversaries may attempt to bypass such defenses by disguising malicious files to evade detection. The detection rule identifies prevention events where Elastic Endgame has successfully blocked a file classified as malware, focusing on alerts generated by file classification activities. This helps security analysts quickly respond to and investigate potential threats.
### Possible investigation steps
- Review the alert details to confirm the event.kind is 'alert' and event.module is 'endgame', ensuring the alert is relevant to the Elastic Endgame prevention mechanism.
- Examine the endgame.metadata.type field to verify it is 'prevention', indicating that the alert pertains to a successfully blocked malware attempt.
- Investigate the event.action or endgame.event_subtype_full fields to understand the specific file classification event that triggered the alert.
- Gather additional context by checking the file path, hash, and any associated metadata to identify the potentially malicious file and its origin.
- Cross-reference the alert with other security logs and alerts to determine if there are related events or patterns that could indicate a broader attack campaign.
- Assess the risk score and severity to prioritize the investigation and response efforts, considering the high severity and risk score of 73.
- Utilize the Elastic Endgame interface or provided links for further information and context about the specific prevention event and any recommended remediation actions.
### False positive analysis
- Legitimate software updates or installations may trigger the rule if they involve file classification activities. To manage this, create exceptions for known and trusted software update processes.
- Security tools or system processes that perform file scanning or classification might be flagged. Identify these processes and add them to an exception list to prevent unnecessary alerts.
- Custom scripts or applications developed in-house that perform file operations similar to malware can be mistaken for threats. Review these scripts and whitelist them if they are verified as safe.
- Frequent alerts from specific directories known to contain non-malicious files, such as temporary or backup folders, can be excluded by specifying these paths in the rule exceptions.
- If certain file types are consistently misclassified as threats, consider adjusting the rule to exclude these file types after confirming they are not harmful.
### Response and remediation
- Isolate the affected system immediately to prevent the spread of malware to other parts of the network. Disconnect the system from the network and any shared drives.
- Verify the alert by cross-referencing the blocked file details with known malware signatures or threat intelligence sources to confirm the threat.
- Remove the malicious file from the system using a trusted antivirus or endpoint protection tool. Ensure that the file is quarantined or deleted to prevent re-execution.
- Conduct a thorough scan of the affected system and any connected devices to identify and remove any additional malicious files or remnants.
- Restore any affected files or systems from a clean backup, ensuring that the backup is free from malware before restoration.
- Escalate the incident to the security operations center (SOC) or incident response team for further analysis and to determine if additional systems may be compromised.
- Review and update security policies and endpoint protection configurations to enhance detection and prevention capabilities against similar threats in the future."""
Stages and Predicates
Stage 1: query
event.kind:alert and event.module:endgame and endgame.metadata.type:prevention and (event.action:file_classification_event or endgame.event_subtype_full:file_classification_event)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
endgame.event_subtype_full | eq |
| field:"endgame.event_subtype_full" kind:eq value:"file_classification_event" |
endgame.metadata.type | eq |
| field:"endgame.metadata.type" kind:eq value:"prevention" |
event.action | eq |
| field:"EventType" kind:eq value:"file_classification_event" |
event.kind | eq |
| field:"event.kind" kind:eq value:"alert" |
event.module | eq |
| field:"event.module" kind:eq value:"endgame" |
Memory Swap Modification
#This rule detects memory swap modification events on Linux systems. Memory swap modification can be used to manipulate the system's memory and potentially impact the system's performance. This behavior is commonly observed in malware that deploys miner software such as XMRig.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Impact |
Rule Body
[metadata]
creation_date = "2024/11/04"
integration = ["endpoint", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
This rule detects memory swap modification events on Linux systems. Memory swap modification can be used to manipulate
the system's memory and potentially impact the system's performance. This behavior is commonly observed in malware that
deploys miner software such as XMRig.
"""
from = "now-9m"
index = ["endgame-*", "logs-endpoint.events.process*", "logs-sentinel_one_cloud_funnel.*", "logs-crowdstrike.fdr*"]
language = "eql"
license = "Elastic License v2"
name = "Memory Swap Modification"
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 Memory Swap Modification
Memory swap in Linux systems manages RAM by moving inactive pages to disk, freeing up memory for active processes. Adversaries exploit this by altering swap settings to degrade performance or deploy resource-intensive malware like cryptominers. The detection rule identifies suspicious activities by monitoring processes that modify swap settings or execute related commands, flagging potential misuse for further investigation.
### Possible investigation steps
- Review the process details to identify the parent process using the field process.parent.executable. This can help determine if the swap modification was initiated by a legitimate or suspicious parent process.
- Examine the command line arguments captured in process.command_line to understand the specific changes made to swap settings, such as modifications to vm.swappiness.
- Check the user account associated with the process to determine if the action was performed by a privileged or unauthorized user.
- Investigate any recent system performance issues or anomalies that could be linked to swap modifications, such as increased CPU or memory usage.
- Correlate the event with other security alerts or logs to identify if this activity is part of a larger pattern of suspicious behavior, such as the presence of cryptomining software like XMRig.
- Assess the system for any unauthorized software installations or configurations that could indicate a compromise, focusing on resource-intensive applications.
### False positive analysis
- System administrators may frequently modify swap settings during routine maintenance or performance tuning. To handle this, create exceptions for known administrator accounts or specific maintenance scripts.
- Automated configuration management tools like Ansible or Puppet might execute commands that alter swap settings. Identify these tools and exclude their processes from triggering alerts.
- Some legitimate applications may adjust swap settings to optimize their performance. Monitor and whitelist these applications to prevent unnecessary alerts.
- Development environments often experiment with system settings, including swap configurations. Consider excluding processes from known development environments or specific user accounts associated with development activities.
- Scheduled tasks or cron jobs might include swap modification commands for system optimization. Review and whitelist these tasks if they are verified as non-threatening.
### Response and remediation
- Immediately isolate the affected system from the network to prevent further spread or impact of the potential malware.
- Terminate any suspicious processes identified by the detection rule, such as those involving "swapon", "swapoff", or unauthorized modifications to "vm.swappiness".
- Conduct a thorough scan of the isolated system using updated antivirus or anti-malware tools to identify and remove any malicious software, particularly cryptominers like XMRig.
- Review and restore swap settings to their default or secure configurations to ensure system stability and performance.
- Implement monitoring for any further unauthorized changes to swap settings or related processes to detect and respond to similar threats promptly.
- Escalate the incident to the security operations team for a detailed forensic analysis to understand the scope and origin of the attack.
- Update system and security patches to close any vulnerabilities that may have been exploited by the adversary."""
risk_score = 47
rule_id = "5e4023e7-6357-4061-ae1c-9df33e78c674"
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: Impact",
"Tactic: Execution",
"Data Source: Elastic Defend",
"Data Source: SentinelOne",
"Data Source: Elastic Endgame",
"Resources: Investigation Guide",
"Data Source: Crowdstrike",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "exec_event", "start", "ProcessRollup2") and
?process.parent.executable != null and
process.name in ("swapon", "swapoff") or (
process.command_line like ("*vm.swappiness*", "*/proc/sys/vm/swappiness*") and (
(process.name == "sysctl" and process.args like ("*-w*", "*--write*", "*=*")) or
(
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and process.args == "-c" and
process.command_line like "*echo *"
)
)
) and
not (
process.parent.name in ("lynis", "systemd", "end-zram-swapping", "SyxsenseResponder", "tuned", "platform-python", "timeout") or
?process.parent.executable in ("/opt/puppetlabs/puppet/bin/ruby", "/u01/app/grid/perl/bin/perl")
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1496"
name = "Resource Hijacking"
reference = "https://attack.mitre.org/techniques/T1496/"
[[rule.threat.technique.subtechnique]]
id = "T1496.001"
name = "Compute Hijacking"
reference = "https://attack.mitre.org/techniques/T1496/001/"
[rule.threat.tactic]
id = "TA0040"
name = "Impact"
reference = "https://attack.mitre.org/tactics/TA0040/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
Stages and Predicates
Stage 1: process
process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "exec_event", "start", "ProcessRollup2") and
?process.parent.executable != null and
process.name in ("swapon", "swapoff") or (
process.command_line like ("*vm.swappiness*", "*/proc/sys/vm/swappiness*") and (
(process.name == "sysctl" and process.args like ("*-w*", "*--write*", "*=*")) or
(
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and process.args == "-c" and
process.command_line like "*echo *"
)
)
) and
not (
process.parent.name in ("lynis", "systemd", "end-zram-swapping", "SyxsenseResponder", "tuned", "platform-python", "timeout") or
?process.parent.executable in ("/opt/puppetlabs/puppet/bin/ruby", "/u01/app/grid/perl/bin/perl")
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | in |
| field:"EventType" kind:in |
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.command_line | wildcard |
| field:"CommandLine" kind:wildcard |
process.name | eq |
| field:"process_basename" kind:eq value:"sysctl" |
process.name | in |
| field:"process_basename" kind:in |
process.parent.executable | is_not_null | field:"ParentImage" kind:is_not_null |
PHP File Creation in WordPress Plugin Directory
#Detects the creation of a PHP file in the WordPress plugin directory, which is a common technique used by attackers to establish persistence on a compromised web server. Attackers may upload a malicious PHP file and call it from a web browser to gain remote access to the server.
Known False Positives
- Web servers or administrators may create PHP files in the WordPress plugin directory during maintenance.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Execution | |
| Persistence |
Rule Body
[metadata]
creation_date = "2026/07/20"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/08/03"
[rule]
author = ["Elastic"]
description = """
Detects the creation of a PHP file in the WordPress plugin directory, which is a common technique used
by attackers to establish persistence on a compromised web server. Attackers may upload a malicious PHP
file and call it from a web browser to gain remote access to the server.
"""
false_positives = [
"""
Web servers or administrators may create PHP files in the WordPress plugin directory during maintenance.
""",
]
from = "now-9m"
index = ["logs-endpoint.events.file*"]
language = "eql"
license = "Elastic License v2"
name = "PHP File Creation in WordPress Plugin Directory"
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 PHP File Creation in WordPress Plugin Directory
This alert flags a new or modified PHP file under a WordPress plugin folder when it was written by a web server, PHP handler, shell, or download utility. That matters because attackers often hide webshells or rogue plugin code there to survive on a compromised site and run commands remotely. A common pattern is exploiting a vulnerable plugin to upload a backdoor into wp-content/plugins and then calling it from a browser.
### Possible investigation steps
- Determine whether the new PHP file is part of a legitimate plugin installation or update by comparing its path, filename, hash, and timestamp against the official plugin package and your deployment records.
- Review the file contents for common webshell indicators such as obfuscation, eval or base64_decode chains, command execution functions, upload handlers, or hardcoded external URLs, and extract any indicators for broader searching.
- Correlate the write time with web access logs and WordPress or PHP logs to identify the originating HTTP request, source IP, authenticated user, target endpoint, and any upload or admin action that preceded the file creation.
- Trace the creating activity through parent and child processes, execution user, working directory, and any concurrent shell or download activity to separate expected maintenance from exploitation or post-compromise staging.
- Inspect the rest of the WordPress environment for related signs of compromise, including other newly modified plugin or theme files, unexpected administrator accounts, suspicious scheduled tasks, dropped archives, or unusual outbound connections.
### False positive analysis
- A legitimate WordPress plugin installation or update can create or modify PHP files under `wp-content/plugins` through the normal web application update flow; verify the file path, name, hash, and timestamp match an approved plugin package and any recent administrator update activity.
- Authorized maintenance such as restoring a plugin from backup or deploying plugin code with `bash`, `sh`, `curl`, or `wget` can also trigger this alert; verify the process lineage and maintenance records show an expected bulk file change rather than an isolated unfamiliar PHP file.
### Response and remediation
- Isolate the affected web server or container from the network and disable external access to the compromised WordPress site while preserving the malicious PHP file, related plugin directories, and relevant logs for evidence.
- Remove attacker persistence by deleting the malicious PHP file and any companion backdoors, rogue plugins, modified `.htaccess` entries, cron jobs, systemd timers, SSH keys, or unauthorized WordPress administrator accounts created during the intrusion.
- Reset exposed secrets by rotating WordPress admin passwords, hosting control panel credentials, SSH keys, database passwords, API tokens, and session cookies that may have been accessed from the compromised host.
- Restore the site from a known-good backup or redeploy the affected plugin and WordPress core from trusted packages, then verify hashes and review `wp-content/plugins`, `wp-content/themes`, and `uploads` for any remaining unauthorized PHP files or recent modifications.
- Escalate to incident response immediately if the webshell executed commands, multiple hosts show similar plugin-directory writes, sensitive data may have been accessed, or the attacker obtained root privileges, and expand scoping across reverse proxy, WAF, database, and authentication logs.
- Harden the environment by patching the exploited plugin or WordPress version, removing unused plugins, enforcing least-privilege write access so the web server cannot write to plugin directories, enabling MFA for administrators, and adding monitoring for new executable files under web content.
"""
references = [
"https://github.com/Icex0/wp2shell-poc",
]
risk_score = 21
rule_id = "fb76c80b-3eb2-4c56-9ed1-e4c529425d0f"
setup = """## Setup
This rule requires data coming in from Elastic Defend.
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "low"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Tactic: Initial Access",
"Use Case: Vulnerability",
"Data Source: Elastic Defend",
"Resources: Investigation Guide"
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
file where host.os.type == "linux" and event.type in ("creation", "change") and (
process.name in (
"nginx", "apache2", "httpd", "php-cgi", "php-fcgi", "php-cgi.cagefs", "sw-engine-fpm",
"wget", "curl", "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "mksh", "busybox"
) or
process.name like ("php-fpm*", "lsphp*", "*.cgi", "*.fcgi")
) and
file.path like~ "*/wp-content/plugins/*"
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1505"
name = "Server Software Component"
reference = "https://attack.mitre.org/techniques/T1505/"
[[rule.threat.technique.subtechnique]]
id = "T1505.003"
name = "Web Shell"
reference = "https://attack.mitre.org/techniques/T1505/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 = "T1190"
name = "Exploit Public-Facing Application"
reference = "https://attack.mitre.org/techniques/T1190/"
[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
Stages and Predicates
Stage 1: file
file where host.os.type == "linux" and event.type in ("creation", "change") and (
process.name in (
"nginx", "apache2", "httpd", "php-cgi", "php-fcgi", "php-cgi.cagefs", "sw-engine-fpm",
"wget", "curl", "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "mksh", "busybox"
) or
process.name like ("php-fpm*", "lsphp*", "*.cgi", "*.fcgi")
) and
file.path like~ "*/wp-content/plugins/*"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | in |
| field:"event.type" kind:in |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard value:"*/wp-content/plugins/*" |
process.name | in |
| field:"process_basename" kind:in |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
Potential PowerShell Empire Execution
#Identifies the execution of PowerShell with suspicious argument values. This behavior is often observed during malware installation leveraging PowerShell.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution |
Rule Body
[rule]
description = """
Identifies the execution of PowerShell with suspicious argument values. This behavior is often observed during malware
installation leveraging PowerShell.
"""
id = "97c40962-ab00-4741-b8f9-8c03b5f0eaa7"
license = "Elastic License v2"
name = "Potential PowerShell Empire Execution"
os_list = ["windows"]
version = "1.0.2"
query = '''
process where event.action == "start" and process.name : "powershell.exe" and
process.command_line : ("* -noP -sta -w 1 -enc SQBmACgAJABQAFMAV*",
"* hidden -e SQBmACgAJABQAFMAV*",
"* -noP -sta -w 1 -enc IAAgA*",
"*LwBkAG8AdwBuAGwAbwBhAGQALwBwAG8AdwBlAHIAcwBoAGUAbABsAC8AJw*",
"*AvAGQAbwB3AG4AbABvAGEAZAAvAGMAcwBoAGEAcgBwAC8AIgApADsA*",
"*AAKAAkAEkAVgArACQASwApACkAfABJAEUAWAA=*",
"*IAAgACYAKAAiAHsAMgB9AHsAMAB9AHsAMQB9ACIA*")
'''
min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: process
process where event.action == "start" and process.name : "powershell.exe" and
process.command_line : ("* -noP -sta -w 1 -enc SQBmACgAJABQAFMAV*",
"* hidden -e SQBmACgAJABQAFMAV*",
"* -noP -sta -w 1 -enc IAAgA*",
"*LwBkAG8AdwBuAGwAbwBhAGQALwBwAG8AdwBlAHIAcwBoAGUAbABsAC8AJw*",
"*AvAGQAbwB3AG4AbABvAGEAZAAvAGMAcwBoAGEAcgBwAC8AIgApADsA*",
"*AAKAAkAEkAVgArACQASwApACkAfABJAEUAWAA=*",
"*IAAgACYAKAAiAHsAMgB9AHsAMAB9AHsAMQB9ACIA*")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:"powershell.exe" |
Potential Protocol Tunneling via Chisel Client
#This rule monitors for common command line flags leveraged by the Chisel client utility followed by a connection attempt. Chisel is a command-line utility used for creating and managing TCP and UDP tunnels, enabling port forwarding and secure communication between machines. Attackers can abuse the Chisel utility to establish covert communication channels, bypass network restrictions, and carry out malicious activities by creating tunnels that allow unauthorized access to internal systems.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Command & Control |
Rule Body
[metadata]
creation_date = "2023/08/23"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"
[transform]
[[transform.osquery]]
label = "Osquery - Retrieve Listening Ports"
query = "SELECT pid, address, port, socket, protocol, path FROM listening_ports"
[[transform.osquery]]
label = "Osquery - Retrieve Open Sockets"
query = "SELECT pid, family, remote_address, remote_port, socket, state FROM process_open_sockets"
[[transform.osquery]]
label = "Osquery - Retrieve Information for a Specific User"
query = "SELECT * FROM users WHERE username = {{user.name}}"
[[transform.osquery]]
label = "Osquery - Investigate the Account Authentication Status"
query = "SELECT * FROM logged_in_users WHERE user = {{user.name}}"
[[transform.osquery]]
label = "Osquery - Retrieve Running Processes by User"
query = "SELECT pid, username, name FROM processes p JOIN users u ON u.uid = p.uid ORDER BY username"
[[transform.osquery]]
label = "Osquery - Retrieve Process Info"
query = "SELECT name, cmdline, parent, path, uid FROM processes"
[rule]
author = ["Elastic"]
description = """
This rule monitors for common command line flags leveraged by the Chisel client utility followed by a connection
attempt. Chisel is a command-line utility used for creating and managing TCP and UDP tunnels, enabling port forwarding
and secure communication between machines. Attackers can abuse the Chisel utility to establish covert communication
channels, bypass network restrictions, and carry out malicious activities by creating tunnels that allow unauthorized
access to internal systems.
"""
from = "now-9m"
index = ["logs-endpoint.events.network*", "logs-endpoint.events.process*"]
language = "eql"
license = "Elastic License v2"
name = "Potential Protocol Tunneling via Chisel Client"
note = """## Triage and analysis
### Investigating Potential Protocol Tunneling via Chisel Client
Attackers can leverage `chisel` to clandestinely tunnel network communications and evade security measures, potentially gaining unauthorized access to sensitive systems.
This rule looks for a sequence of command line arguments that are consistent with `chisel` client tunneling behavior, followed by a network event by an uncommon process.
> **Note**:
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/current/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.
> This investigation guide uses [placeholder fields](https://www.elastic.co/guide/en/security/current/osquery-placeholder-fields.html) to dynamically pass alert data into Osquery queries. Placeholder fields were introduced in Elastic Stack version 8.7.0. If you're using Elastic Stack version 8.6.0 or earlier, you'll need to manually adjust this investigation guide's queries to ensure they properly run.
#### Possible investigation steps
- Identify any signs of suspicious network activity or anomalies that may indicate protocol tunneling. This could include unexpected traffic patterns or unusual network behavior.
- Investigate listening ports and open sockets to look for potential protocol tunneling, reverse shells, or data exfiltration.
- $osquery_0
- $osquery_1
- Identify the user account that performed the action, analyze it, and check whether it should perform this kind of action.
- $osquery_2
- Investigate whether the user is currently logged in and active.
- $osquery_3
- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence and whether they are located in expected locations.
- $osquery_4
- $osquery_5
- Investigate other alerts associated with the user/host during the past 48 hours.
- If scripts or executables were dropped, retrieve the files and determine if they are malicious:
- Use a private sandboxed malware analysis system to perform analysis.
- Observe and collect information about the following activities:
- Attempts to contact external domains and addresses.
- Check if the domain is newly registered or unexpected.
- Check the reputation of the domain or IP address.
- File access, modification, and creation activities.
### Related rules
- Potential Protocol Tunneling via Chisel Server - ac8805f6-1e08-406c-962e-3937057fa86f
- Potential Linux Tunneling and/or Port Forwarding - 6ee947e9-de7e-4281-a55d-09289bdf947e
- Potential Protocol Tunneling via EarthWorm - 9f1c4ca3-44b5-481d-ba42-32dc215a2769
### False positive analysis
- If this activity is related to new benign software installation activity, consider adding exceptions — preferably with a combination of user and command line conditions.
- If this activity is related to a system administrator or developer who uses port tunneling for benign purposes, consider adding exceptions for specific user accounts or hosts.
- Try to understand the context of the execution by thinking about the user, machine, or business purpose. A small number of endpoints, such as servers with unique software, might appear unusual but satisfy a specific business need.
### Response and remediation
- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- If the triage identified malware, search the environment for additional compromised hosts.
- Implement temporary network rules, procedures, and segmentation to contain the malware.
- Stop suspicious processes.
- Immediately block the identified indicators of compromise (IoCs).
- Inspect the affected systems for additional malware backdoors, such as reverse shells, reverse proxies, or droppers, that attackers could use to reinfect the system.
- Remove and block malicious artifacts identified during triage.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Leverage the incident response data and logging to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
references = [
"https://blog.bitsadmin.com/living-off-the-foreign-land-windows-as-offensive-platform",
"https://book.hacktricks.xyz/generic-methodologies-and-resources/tunneling-and-port-forwarding",
]
risk_score = 47
rule_id = "3f12325a-4cc6-410b-8d4c-9fbbeb744cfd"
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",
]
type = "eql"
query = '''
sequence by host.id, process.entity_id with maxspan=3s
[process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and
process.args == "client" and process.args : ("R*", "*:*", "*socks*") and process.args_count >= 4 and
process.parent.name in ("bash", "dash", "ash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and
not process.name in ("velociraptor", "nbemmcmd", "redis-cli", "ipa")]
[network where host.os.type == "linux" and event.action == "connection_attempted" and event.type == "start" and
destination.ip != null and destination.ip != "127.0.0.1" and destination.ip != "::1" and
not process.name : (
"python*", "php*", "perl", "ruby", "lua*", "openssl", "nc", "netcat", "ncat", "telnet", "awk", "java", "telnet",
"ftp", "socat", "curl", "wget", "dpkg", "docker", "dockerd", "yum", "apt", "rpm", "dnf", "ssh", "sshd", "kubectl*",
"clickhouse"
)]
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1090"
name = "Proxy"
reference = "https://attack.mitre.org/techniques/T1090/"
[[rule.threat.technique]]
id = "T1572"
name = "Protocol Tunneling"
reference = "https://attack.mitre.org/techniques/T1572/"
[rule.threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
Stages and Predicates
Ordered sequence: each step below must occur in order within 3s, correlated by host.id, process.entity_id.
Stage 1: process
[process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and
process.args == "client" and process.args : ("R*", "*:*", "*socks*") and process.args_count >= 4 and
process.parent.name in ("bash", "dash", "ash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and
not process.name in ("velociraptor", "nbemmcmd", "redis-cli", "ipa")]
Stage 2: network
[network where host.os.type == "linux" and event.action == "connection_attempted" and event.type == "start" and
destination.ip != null and destination.ip != "127.0.0.1" and destination.ip != "::1" and
not process.name : (
"python*", "php*", "perl", "ruby", "lua*", "openssl", "nc", "netcat", "ncat", "telnet", "awk", "java", "telnet",
"ftp", "socat", "curl", "wget", "dpkg", "docker", "dockerd", "yum", "apt", "rpm", "dnf", "ssh", "sshd", "kubectl*",
"clickhouse"
)]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
destination.ip | is_not_null | field:"dest_ip" kind:is_not_null | |
destination.ip | ne |
| field:"dest_ip" kind:ne |
event.action | eq |
| field:"EventType" kind:eq |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | eq |
| field:"process.args" kind:eq value:"client" |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.args_count | ge |
| field:"process.args_count" kind:ge value:"4" |
process.parent.name | in |
| field:"parent_process_basename" kind:in |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.name | in | ipa, nbemmcmd, redis-cli, velociraptor | excludes:process.name |
process.name | wildcard | python*, php*, perl, ruby, lua*, openssl, nc, netcat, ncat, telnet, awk, java, telnet, ftp, socat, curl, wget, dpkg, docker, dockerd, yum, apt, rpm, dnf, ssh, sshd, kubectl*, clickhouse | excludes:process.name |
Potential Reverse Shell via Suspicious Child Process
#This detection rule detects the creation of a shell through a suspicious process chain. Any reverse shells spawned by the specified utilities that are initialized from a single process followed by a network connection attempt will be captured through this rule. Attackers may spawn reverse shells to establish persistence onto a target system.
MITRE ATT&CK Coverage
Rule Body
[metadata]
creation_date = "2023/07/04"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
This detection rule detects the creation of a shell through a suspicious process chain. Any reverse shells spawned by
the specified utilities that are initialized from a single process followed by a network connection attempt will be
captured through this rule. Attackers may spawn reverse shells to establish persistence onto a target system.
"""
from = "now-9m"
index = ["logs-endpoint.events.network*", "logs-endpoint.events.process*"]
language = "eql"
license = "Elastic License v2"
name = "Potential Reverse Shell via Suspicious Child Process"
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Potential Reverse Shell via Suspicious Child Process
Reverse shells are a common technique used by attackers to gain remote access to a compromised system. They exploit scripting languages and utilities like Python, Perl, and Netcat to execute commands remotely. The detection rule identifies suspicious process chains and network activities, such as unexpected shell spawns and outbound connections, to flag potential reverse shell attempts, leveraging process and network event analysis to detect anomalies.
### Possible investigation steps
- Review the process chain to identify the parent process and determine if it is expected behavior for the system. Check the process.parent.name field for any unusual or unauthorized parent processes.
- Analyze the process arguments captured in the alert, such as process.args, to understand the command being executed and assess if it aligns with known reverse shell patterns.
- Investigate the network connection details, focusing on the destination.ip field, to determine if the connection is to a known malicious IP or an unexpected external address.
- Check the process.name field to identify the specific utility used (e.g., python, perl, nc) and verify if its usage is legitimate or if it indicates a potential compromise.
- Correlate the alert with other security events or logs from the same host.id to identify any additional suspicious activities or patterns that may indicate a broader attack.
- Consult threat intelligence sources to gather information on any identified IP addresses or domains involved in the network connection to assess their reputation and potential threat level.
### False positive analysis
- Development and testing environments may frequently execute scripts using languages like Python, Perl, or Ruby, which can trigger the rule. To manage this, consider excluding specific host IDs or process names associated with known development activities.
- Automated scripts or cron jobs that utilize network connections for legitimate purposes, such as data backups or updates, might be flagged. Identify these processes and add them to an exception list based on their parent process names or specific arguments.
- System administrators might use tools like Netcat or OpenSSL for troubleshooting or monitoring network connections. If these activities are routine and verified, exclude them by specifying the administrator's user ID or the specific command patterns used.
- Security tools or monitoring solutions that simulate attack scenarios for testing purposes can also trigger this rule. Ensure these tools are recognized and excluded by their process names or associated network activities.
- Custom scripts that use shell commands to interact with remote systems for maintenance tasks may appear suspicious. Review these scripts and exclude them by their unique process arguments or parent process names.
### Response and remediation
- Immediately isolate the affected host from the network to prevent further unauthorized access or data exfiltration.
- Terminate any suspicious processes identified by the detection rule, particularly those involving scripting languages or utilities like Python, Perl, or Netcat.
- Conduct a forensic analysis of the affected system to identify any additional indicators of compromise, such as unauthorized user accounts or modified system files.
- Review and reset credentials for any accounts that may have been accessed or compromised during the incident.
- Apply security patches and updates to the affected system to address any vulnerabilities that may have been exploited.
- Monitor network traffic for any signs of further suspicious activity, focusing on outbound connections from the affected host.
- Escalate the incident to the security operations center (SOC) or relevant security team for further investigation and to ensure comprehensive remediation efforts."""
references = [
"https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md",
]
risk_score = 73
rule_id = "76e4d92b-61c1-4a95-ab61-5fd94179a1ee"
setup = """## Setup
This rule requires data coming in from Elastic Defend.
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "high"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Execution",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
type = "eql"
query = '''
sequence by host.id, process.entity_id with maxspan=1s
[process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "fork") and (
(process.name : "python*" and process.args : "-c" and process.args : (
"*import*pty*spawn*", "*import*subprocess*call*"
)) or
(process.name : "perl*" and process.args : "-e" and process.args : "*socket*" and process.args : (
"*exec*", "*system*"
)) or
(process.name : "ruby*" and process.args : ("-e", "-rsocket") and process.args : (
"*TCPSocket.new*", "*TCPSocket.open*"
)) or
(process.name : "lua*" and process.args : "-e" and process.args : "*socket.tcp*" and process.args : (
"*io.popen*", "*os.execute*"
)) or
(process.name : "php*" and process.args : "-r" and process.args : "*fsockopen*" and process.args : "*/bin/*sh*") or
(process.name : ("awk", "gawk", "mawk", "nawk") and process.args : "*/inet/tcp/*") or
(process.name : ("nc", "ncat", "netcat") and process.args == "-e" and process.args_count >= 3 and
not process.args == "-z")
) and process.parent.name : (
"bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "python*", "php*", "perl", "ruby", "lua*",
"nc", "netcat", "ncat", "awk", "gawk", "mawk", "nawk")]
[network where host.os.type == "linux" and event.type == "start" and event.action in ("connection_attempted", "connection_accepted") and
process.name : ("python*", "php*", "perl", "ruby", "lua*", "nc", "netcat", "ncat", "awk", "gawk", "mawk", "nawk") and
destination.ip != null and not cidrmatch(destination.ip, "127.0.0.0/8", "169.254.0.0/16", "224.0.0.0/4", "::1")]
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"
[[rule.threat.technique.subtechnique]]
id = "T1059.006"
name = "Python"
reference = "https://attack.mitre.org/techniques/T1059/006/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"
[[rule.threat.technique]]
id = "T1095"
name = "Non-Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1095/"
[rule.threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
Stages and Predicates
Ordered sequence: each step below must occur in order within 1s, correlated by host.id, process.entity_id.
Stage 1: process
[process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "fork") and (
(process.name : "python*" and process.args : "-c" and process.args : (
"*import*pty*spawn*", "*import*subprocess*call*"
)) or
(process.name : "perl*" and process.args : "-e" and process.args : "*socket*" and process.args : (
"*exec*", "*system*"
)) or
(process.name : "ruby*" and process.args : ("-e", "-rsocket") and process.args : (
"*TCPSocket.new*", "*TCPSocket.open*"
)) or
(process.name : "lua*" and process.args : "-e" and process.args : "*socket.tcp*" and process.args : (
"*io.popen*", "*os.execute*"
)) or
(process.name : "php*" and process.args : "-r" and process.args : "*fsockopen*" and process.args : "*/bin/*sh*") or
(process.name : ("awk", "gawk", "mawk", "nawk") and process.args : "*/inet/tcp/*") or
(process.name : ("nc", "ncat", "netcat") and process.args == "-e" and process.args_count >= 3 and
not process.args == "-z")
) and process.parent.name : (
"bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "python*", "php*", "perl", "ruby", "lua*",
"nc", "netcat", "ncat", "awk", "gawk", "mawk", "nawk")]
Stage 2: network
[network where host.os.type == "linux" and event.type == "start" and event.action in ("connection_attempted", "connection_accepted") and
process.name : ("python*", "php*", "perl", "ruby", "lua*", "nc", "netcat", "ncat", "awk", "gawk", "mawk", "nawk") and
destination.ip != null and not cidrmatch(destination.ip, "127.0.0.0/8", "169.254.0.0/16", "224.0.0.0/4", "::1")]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
destination.ip | is_not_null | field:"dest_ip" kind:is_not_null | |
event.action | in |
| field:"EventType" kind:in |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | eq |
| field:"process.args" kind:eq value:"-e" |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.args_count | ge |
| field:"process.args_count" kind:ge value:"3" |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
destination.ip | cidr_match | 127.0.0.0/8, 169.254.0.0/16, 224.0.0.0/4, ::1 | excludes:destination.ip |
Potential SIP REGISTER Brute Force
#Identifies repeated SIP REGISTER authentication rejection responses for one or more extensions from a client to a VoIP server within five minutes. The rule distinguishes repeated failures from the single 401 or 407 challenge expected in a normal digest-authentication flow. Attackers brute-force extension credentials to register rogue endpoints for toll fraud, call interception, or registration hijacking.
Known False Positives
- Misconfigured phones, expired credentials, or provisioning errors can generate repeated REGISTER failures from a single device. Validate the client, affected extensions, and registration state before escalating.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Rule Body
[metadata]
creation_date = "2026/07/31"
integration = ["network_traffic"]
maturity = "production"
min_stack_comments = "Requires ES|QL JSON_EXTRACT on _source to read SIP fields across current and legacy schemas."
min_stack_version = "9.4.0"
updated_date = "2026/07/31"
[rule]
author = ["Elastic"]
description = """
Identifies repeated SIP REGISTER authentication rejection responses for one or more extensions from a client to a VoIP
server within five minutes. The rule distinguishes repeated failures from the single 401 or 407 challenge expected in a
normal digest-authentication flow. Attackers brute-force extension credentials to register rogue endpoints for toll
fraud, call interception, or registration hijacking.
"""
false_positives = [
"""
Misconfigured phones, expired credentials, or provisioning errors can generate repeated REGISTER failures from a
single device. Validate the client, affected extensions, and registration state before escalating.
""",
]
from = "now-9m"
language = "esql"
license = "Elastic License v2"
max_signals = 5
name = "Potential SIP REGISTER Brute Force"
note = """## Triage and analysis
### Investigating Potential SIP REGISTER Brute Force
SIP REGISTER authenticates endpoints to a PBX or SBC. Attackers iterate extensions and passwords, producing many 401 Unauthorized, 403 Forbidden, or 407 Proxy Authentication Required responses from one external or internal client. A single 401 or 407 challenge is expected during normal digest authentication, so this rule requires either ten failures for one extension or a broader spray affecting at least five repeatedly challenged extensions.
### Possible investigation steps
- Determine whether `Esql.client_ip` is an expected phone, gateway, proxy, or external attacker address and confirm that `Esql.server_ip` is the intended PBX or SBC.
- Review `Esql.sample_extensions`, `Esql.total_failures`, and `Esql.max_failures_per_extension` to distinguish a targeted password attack from a broader extension spray.
- Review REGISTER requests corresponding to the rejection responses and confirm whether credentials were supplied after the initial digest challenge.
- Check for a successful REGISTER (2xx response) from the same client and extension shortly after the burst. Multiple failures followed by success should be escalated as possible credential compromise.
- Inspect CDR/billing records for anomalous outbound calls if a registration succeeded.
### False positive analysis
- A single misconfigured phone repeatedly attempting REGISTER with a stale password can trigger the targeted-failure branch. Lower severity when only one extension is affected and the client maps to a known device.
- NAT gateways and SIP proxies can represent many legitimate phones behind one address. The rule requires repeated challenges per extension to reduce alerts caused by one normal digest challenge from each phone.
### Response and remediation
- Block or rate-limit the offending `Esql.client_ip` at the SBC and enforce strong SIP credentials.
- Rotate compromised extension passwords and audit active registrations for rogue contact bindings.
- Enable geo-blocking or IP allowlists for REGISTER if the PBX is internal-only.
"""
references = ["https://attack.mitre.org/techniques/T1110/"]
risk_score = 47
rule_id = "1ca59146-7386-4033-a010-1c32717e9321"
setup = """## Setup
This rule requires the Elastic **network_traffic** integration with the **SIP** protocol module enabled on a sensor that
observes VoIP REGISTER signaling to or from the PBX/SBC.
The rule requires decoded SIP headers and responses. SIP over TLS (commonly TCP 5061) is not visible unless the sensor
receives decrypted traffic or observes plaintext SIP after TLS termination. SRTP encryption does not affect this rule
when SIP signaling remains visible.
"""
severity = "medium"
tags = [
"Domain: Network",
"Use Case: Threat Detection",
"Use Case: Network Security Monitoring",
"Tactic: Credential Access",
"Data Source: Network Packet Capture",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-network_traffic.sip-*, packetbeat-* metadata _source
| eval
Esql.method = TO_UPPER(COALESCE(
JSON_EXTRACT(_source, "network_traffic.sip.cseq.method"),
JSON_EXTRACT(_source, "sip.cseq.method"),
JSON_EXTRACT(_source, "network_traffic.sip.method"),
JSON_EXTRACT(_source, "sip.method")
)),
Esql.sip_type = TO_LOWER(COALESCE(
JSON_EXTRACT(_source, "network_traffic.sip.type"),
JSON_EXTRACT(_source, "sip.type")
)),
Esql.code = COALESCE(
JSON_EXTRACT(_source, "network_traffic.sip.code"),
JSON_EXTRACT(_source, "sip.code")
),
Esql.client_ip = COALESCE(client.ip, destination.ip),
Esql.server_ip = COALESCE(server.ip, source.ip),
Esql.extension = COALESCE(
JSON_EXTRACT(_source, "network_traffic.sip.to.uri.username"),
JSON_EXTRACT(_source, "sip.to.uri.username")
)
| where
Esql.method == "REGISTER" and
Esql.sip_type == "response" and
Esql.code in ("401", "403", "407") and
Esql.client_ip is not null and
Esql.server_ip is not null and
Esql.extension is not null
| eval Esql.time_window = DATE_TRUNC(5 minutes, @timestamp)
| stats
Esql.failures_per_extension = COUNT(*)
by Esql.time_window, Esql.client_ip, Esql.server_ip, Esql.extension
| eval Esql.repeated_extension = CASE(Esql.failures_per_extension >= 2, 1, 0)
| stats
Esql.total_failures = SUM(Esql.failures_per_extension),
Esql.max_failures_per_extension = MAX(Esql.failures_per_extension),
Esql.distinct_extensions = COUNT_DISTINCT(Esql.extension),
Esql.repeated_extensions = SUM(Esql.repeated_extension),
Esql.sample_extensions = MV_SLICE(VALUES(Esql.extension), 0, 20)
by Esql.time_window, Esql.client_ip, Esql.server_ip
| where
Esql.max_failures_per_extension >= 10 or
(
Esql.total_failures >= 25 and
Esql.distinct_extensions >= 5 and
Esql.repeated_extensions >= 5
)
| keep Esql.*
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1110"
name = "Brute Force"
reference = "https://attack.mitre.org/techniques/T1110/"
[[rule.threat.technique.subtechnique]]
id = "T1110.001"
name = "Password Guessing"
reference = "https://attack.mitre.org/techniques/T1110/001/"
[[rule.threat.technique.subtechnique]]
id = "T1110.003"
name = "Password Spraying"
reference = "https://attack.mitre.org/techniques/T1110/003/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[rule.alert_suppression]
group_by = ["Esql.client_ip", "Esql.server_ip"]
missing_fields_strategy = "suppress"
[rule.alert_suppression.duration]
unit = "h"
value = 1
Stages and Predicates
Stage 1: from
from logs-network_traffic.sip-*, packetbeat-* metadata _source
Stage 2: eval
| eval
Esql.method = TO_UPPER(COALESCE(
JSON_EXTRACT(_source, "network_traffic.sip.cseq.method"),
JSON_EXTRACT(_source, "sip.cseq.method"),
JSON_EXTRACT(_source, "network_traffic.sip.method"),
JSON_EXTRACT(_source, "sip.method")
)),
Esql.sip_type = TO_LOWER(COALESCE(
JSON_EXTRACT(_source, "network_traffic.sip.type"),
JSON_EXTRACT(_source, "sip.type")
)),
Esql.code = COALESCE(
JSON_EXTRACT(_source, "network_traffic.sip.code"),
JSON_EXTRACT(_source, "sip.code")
),
Esql.client_ip = COALESCE(client.ip, destination.ip),
Esql.server_ip = COALESCE(server.ip, source.ip),
Esql.extension = COALESCE(
JSON_EXTRACT(_source, "network_traffic.sip.to.uri.username"),
JSON_EXTRACT(_source, "sip.to.uri.username")
)
Stage 3: where
| where
Esql.method == "REGISTER" and
Esql.sip_type == "response" and
Esql.code in ("401", "403", "407") and
Esql.client_ip is not null and
Esql.server_ip is not null and
Esql.extension is not null
Stage 4: eval
| eval Esql.time_window = DATE_TRUNC(5 minutes, @timestamp)
Stage 5: stats
| stats
Esql.failures_per_extension = COUNT(*)
by Esql.time_window, Esql.client_ip, Esql.server_ip, Esql.extension
Stage 6: eval
| eval Esql.repeated_extension = CASE(Esql.failures_per_extension >= 2, 1, 0)
Esql.repeated_extension =Esql.failures_per_extension >= 210Stage 7: stats
| stats
Esql.total_failures = SUM(Esql.failures_per_extension),
Esql.max_failures_per_extension = MAX(Esql.failures_per_extension),
Esql.distinct_extensions = COUNT_DISTINCT(Esql.extension),
Esql.repeated_extensions = SUM(Esql.repeated_extension),
Esql.sample_extensions = MV_SLICE(VALUES(Esql.extension), 0, 20)
by Esql.time_window, Esql.client_ip, Esql.server_ip
Stage 8: where
| where
Esql.max_failures_per_extension >= 10 or
(
Esql.total_failures >= 25 and
Esql.distinct_extensions >= 5 and
Esql.repeated_extensions >= 5
)
Stage 9: keep
| keep Esql.*
Indicators
These rows show field, operator, and value matches.
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Esql.* | KEEP Esql.* |
PowerShell Obfuscation Spawned via Microsoft Office
#Identifies a Microsoft Office application (Word, PowerPoint, Excel) starting Windows PowerShell with a suspicious command line.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Execution |
Rule Body
[rule]
description = """
Identifies a Microsoft Office application (Word, PowerPoint, Excel) starting Windows PowerShell with a suspicious
command line.
"""
id = "93ef8a09-0f8d-4aa1-b0fb-47d5d5b40cf2"
license = "Elastic License v2"
name = "PowerShell Obfuscation Spawned via Microsoft Office"
os_list = ["windows"]
reference = [
"https://github.com/danielbohannon/Invoke-Obfuscation",
"https://www.elastic.co/security-labs/effective-parenting-detecting-lrpc-based-parent-pid-spoofing",
]
version = "1.0.41"
query = '''
process where event.action == "start" and
(process.pe.original_file_name == "PowerShell.EXE" or process.name : ("powershell.exe", "pwsh.exe")) and
(
process.parent.name : ("excel.exe", "powerpnt.exe", "winword.exe") or
(descendant of [process where event.action == "start" and process.name : ("excel.exe", "powerpnt.exe", "winword.exe")] and
/* Issue #263 */
not process.parent.executable : ("?:\\Program Files\\*.exe", "?:\\Program Files (x86)\\*.exe"))
) and
not process.Ext.token.integrity_level_name == "system" and process.parent.executable != null and
process.command_line :
("*^*^*^*^*^*^*^*^*^*",
"*''*''*''*",
"*`*`*`*`*",
"*{*{*{*{*{*{*{*{*{*{*{*{*{*{*{*{*{*{*{*",
"*+*+*+*+*+*",
"*$*$*$*$*",
"*[char[]](*)*-join",
"*Base64String*",
"*[*Convert]*",
"*.Text.Encoding*",
"*.Compression.*",
"*.replace(*",
"*MemoryStream*",
"*WriteAllBytes*",
"* -en* *",
"* -ec *",
"* -e *",
"* -ex* *",
"* -ep *",
"* /e *",
"* /en* *",
"* /ec *",
"* /ex* *",
"* /ep *",
"*WebClient*",
"*DownloadFile*",
"*DownloadString*",
"*BitsTransfer*",
"*Invoke-Exp*",
"*invoke-web*",
"*iex*",
"*iwr*",
"*Reflection.Assembly*",
"*Assembly.GetType*",
"*.Sockets.*",
"*PromptForCredential*",
"*nslookup*-q=txt*",
"*wget*http*") and
/* Issue #263 */
not process.parent.executable :
("?:\\ProgramData\\CentraStage\\AEMAgent\\AEMAgent.exe",
"?:\\Windows\\System32\\svchost.exe",
"?:\\Windows\\System32\\CompatTelRunner.exe",
"?:\\Windows\\System32\\taskeng.exe") and
not process.args : ("Get-AuthenticodeSignature*", "Write-Host") and not process.command_line : "*Get-AppxPackage*Microsoft.Office*" and
not (process.name : "powershell.exe" and process.command_line : "*Get-CIMInstance -Class Win32_Service*" and
process.parent.executable : "C:\\WINDOWS\\System32\\cmd.exe" and process.parent.args : "C:\\WINDOWS\\TEMP\\nessus_*.TMP") and
not process.command_line : "powershell.exe -NoProfile -NoLogo -InputFormat Text -NoExit -ExecutionPolicy Unrestricted -Command -" and
not (process.name : "powershell.exe" and process.args : "$ErrorActionPreference='silentlycontinue'; $tmp = (Get-Item -Path $env:PROGRAMFILES\\Google\\Chrome\\Application\\chrome.exe).VersionInfo.FileVersion; if ($tmp) {echo $tmp; Exit;}; $tmp = (Get-Item -Path $env:PROGRAMFILES") and
not (process.parent.name : "cmd.exe" and process.parent.args : "chcp 65001 & powershell -NonInteractive -WindowStyle Hidden -command &") and
not (process.args : "-NoLogo" and process.args : "\\\\*.ps1") and
not process.args : "$bytes=[System.Text.Encoding]::UTF8.GetBytes('*');$hash=[System.Security.Cryptography.SHA256]::Create().ComputeHash($bytes);[BitConverter]::ToString($hash).Replace('-','').ToLower()"
'''
min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
[[optional_actions]]
action = "rollback"
field = "process.parent.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1566"
name = "Phishing"
reference = "https://attack.mitre.org/techniques/T1566/"
[[threat.technique.subtechnique]]
id = "T1566.001"
name = "Spearphishing Attachment"
reference = "https://attack.mitre.org/techniques/T1566/001/"
[threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: process
process where event.action == "start" and
(process.pe.original_file_name == "PowerShell.EXE" or process.name : ("powershell.exe", "pwsh.exe")) and
(
process.parent.name : ("excel.exe", "powerpnt.exe", "winword.exe") or
(descendant of [process where event.action == "start" and process.name : ("excel.exe", "powerpnt.exe", "winword.exe")] and
not process.parent.executable : ("?:\\Program Files\\*.exe", "?:\\Program Files (x86)\\*.exe"))
) and
not process.Ext.token.integrity_level_name == "system" and process.parent.executable != null and
process.command_line :
("*^*^*^*^*^*^*^*^*^*",
"*''*''*''*",
"*`*`*`*`*",
"*{*{*{*{*{*{*{*{*{*{*{*{*{*{*{*{*{*{*{*",
"*+*+*+*+*+*",
"*$*$*$*$*",
"*[char[]](*)*-join",
"*Base64String*",
"*[*Convert]*",
"*.Text.Encoding*",
"*.Compression.*",
"*.replace(*",
"*MemoryStream*",
"*WriteAllBytes*",
"* -en* *",
"* -ec *",
"* -e *",
"* -ex* *",
"* -ep *",
"* /e *",
"* /en* *",
"* /ec *",
"* /ex* *",
"* /ep *",
"*WebClient*",
"*DownloadFile*",
"*DownloadString*",
"*BitsTransfer*",
"*Invoke-Exp*",
"*invoke-web*",
"*iex*",
"*iwr*",
"*Reflection.Assembly*",
"*Assembly.GetType*",
"*.Sockets.*",
"*PromptForCredential*",
"*nslookup*-q=txt*",
"*wget*http*") and
not process.parent.executable :
("?:\\ProgramData\\CentraStage\\AEMAgent\\AEMAgent.exe",
"?:\\Windows\\System32\\svchost.exe",
"?:\\Windows\\System32\\CompatTelRunner.exe",
"?:\\Windows\\System32\\taskeng.exe") and
not process.args : ("Get-AuthenticodeSignature*", "Write-Host") and not process.command_line : "*Get-AppxPackage*Microsoft.Office*" and
not (process.name : "powershell.exe" and process.command_line : "*Get-CIMInstance -Class Win32_Service*" and
process.parent.executable : "C:\\WINDOWS\\System32\\cmd.exe" and process.parent.args : "C:\\WINDOWS\\TEMP\\nessus_*.TMP") and
not process.command_line : "powershell.exe -NoProfile -NoLogo -InputFormat Text -NoExit -ExecutionPolicy Unrestricted -Command -" and
not (process.name : "powershell.exe" and process.args : "$ErrorActionPreference='silentlycontinue'; $tmp = (Get-Item -Path $env:PROGRAMFILES\\Google\\Chrome\\Application\\chrome.exe).VersionInfo.FileVersion; if ($tmp) {echo $tmp; Exit;}; $tmp = (Get-Item -Path $env:PROGRAMFILES") and
not (process.parent.name : "cmd.exe" and process.parent.args : "chcp 65001 & powershell -NonInteractive -WindowStyle Hidden -command &") and
not (process.args : "-NoLogo" and process.args : "\\\\*.ps1") and
not process.args : "$bytes=[System.Text.Encoding]::UTF8.GetBytes('*');$hash=[System.Security.Cryptography.SHA256]::Create().ComputeHash($bytes);[BitConverter]::ToString($hash).Replace('-','').ToLower()"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
process.parent.executable | is_not_null | field:"ParentImage" kind:is_not_null | |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard |
process.pe.original_file_name | eq |
| field:"OriginalFileName" kind:eq value:"PowerShell.EXE" |
Exclusions
The rule actively suppresses these predicates.
Process Execution Following Ptrace Manipulation
#This rule detects a process executing shortly after its memory or register state was modified by another process through ptrace. The rule correlates memory writes and register modifications with the traced process identifier and may indicate successful process injection.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule Body
[rule]
description = """
This rule detects a process executing shortly after its memory or register state was modified by another process through
ptrace. The rule correlates memory writes and register modifications with the traced process identifier and may indicate
successful process injection.
"""
id = "2771aca4-31d7-41ae-8cd7-2fbae9b89a47"
license = "Elastic License v2"
name = "Process Execution Following Ptrace Manipulation"
os_list = ["linux"]
reference = [
"https://man7.org/linux/man-pages/man2/ptrace.2.html",
"https://www.akamai.com/blog/security-research/the-definitive-guide-to-linux-process-injection",
]
version = "1.0.3"
query = '''
sequence with maxspan=3s
[process where event.type == "start" and event.action == "ptrace" and (
process.Ext.ptrace.request in (4, 5, 13, 16901) or
(process.Ext.ptrace.request == 6 and process.Ext.ptrace.addr in (48, 60, 128, 152))
) and process.executable != null and
not process.executable like (
"/opt/dynatrace/oneagent/agent/lib64/oneagenthelper", "/opt/scorec/toolworks/totalview.*/bin/tvdengine"
)] by process.Ext.ptrace.child_pid
[process where event.type == "start" and event.action == "exec"] by process.pid
'''
min_endpoint_version = "9.1.4"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 1
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"
[[threat.technique.subtechnique]]
id = "T1055.008"
name = "Ptrace System Calls"
reference = "https://attack.mitre.org/techniques/T1055/008/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "9.1.4"
Stages and Predicates
Ordered sequence: each step below must occur in order within 3s, correlated by process.Ext.ptrace.child_pid, process.pid.
Stage 1: process
[process where event.type == "start" and event.action == "ptrace" and (
process.Ext.ptrace.request in (4, 5, 13, 16901) or
(process.Ext.ptrace.request == 6 and process.Ext.ptrace.addr in (48, 60, 128, 152))
) and process.executable != null and
not process.executable like (
"/opt/dynatrace/oneagent/agent/lib64/oneagenthelper", "/opt/scorec/toolworks/totalview.*/bin/tvdengine"
)] by process.Ext.ptrace.child_pid
Stage 2: process
[process where event.type == "start" and event.action == "exec"] by process.pid
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.Ext.ptrace.addr | in |
| field:"process.Ext.ptrace.addr" kind:in |
process.Ext.ptrace.request | eq |
| field:"process.Ext.ptrace.request" kind:eq value:"6" |
process.Ext.ptrace.request | in |
| field:"process.Ext.ptrace.request" kind:in |
process.executable | is_not_null | field:"Image" kind:is_not_null |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.executable | wildcard | /opt/dynatrace/oneagent/agent/lib64/oneagenthelper, /opt/scorec/toolworks/totalview.*/bin/tvdengine | excludes:process.executable field:"process.executable" value:"/opt/dynatrace/oneagent/agent/lib64/oneagenthelper" field:"process.executable" value:"/opt/scorec/toolworks/totalview.*/bin/tvdengine" |
Rare Powershell Script
#A machine learning job detected a rare PowerShell script, identified by its script block hash, that may indicate execution of malware, or persistence mechanisms. Unlike anomaly detection based on content entropy, this rule identifies scripts that have rarely or never been seen in the environment.
Known False Positives
- A newly installed program or one that runs rarely as part of a monthly or quarterly workflow could trigger this alert. PowerShell scripts that are new to the environment or run infrequently may trigger this alert.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution |
Rule Body
[metadata]
creation_date = "2026/03/27"
integration = ["windows"]
maturity = "production"
updated_date = "2026/07/27"
min_stack_version = "9.4.0"
min_stack_comments = "Use EA (Entity Analytics) fields"
[rule]
anomaly_threshold = 50
author = ["Elastic"]
description = """
A machine learning job detected a rare PowerShell script, identified by its script block hash, that may indicate
execution of malware, or persistence mechanisms. Unlike anomaly detection based on content entropy, this rule
identifies scripts that have rarely or never been seen in the environment.
"""
false_positives = [
"""
A newly installed program or one that runs rarely as part of a monthly or quarterly workflow could trigger this
alert. PowerShell scripts that are new to the environment or run infrequently may trigger this alert.
""",
]
from = "now-45m"
interval = "15m"
license = "Elastic License v2"
machine_learning_job_id = ["v3_windows_rare_script_ea"]
name = "Rare Powershell Script"
note = """## Triage and analysis
### Investigating Rare Powershell Script
Searching for abnormal PowerShell scripts is a good methodology to find potentially malicious activity within a network. Understanding what is commonly run within an environment and developing baselines for legitimate activity can help uncover potential malware and suspicious behaviors.
This rule uses a machine learning job to detect a PowerShell script that is rare and unusual for an individual Windows host in your environment, based on the script block hash.
#### Possible investigation steps
- Investigate the PowerShell script block that triggered the detection. Retrieve the full script content associated with the hash and examine it for malicious indicators such as encoded commands, suspicious URLs, or unusual system calls.
- Investigate the process execution chain (parent process tree) for the PowerShell process. Examine the parent process for prevalence, whether it is located in an expected location, and if it is signed with a valid digital signature.
- If the parent process is a legitimate system utility or service, this could be related to software updates or system management. If the parent process is something user-facing like an Office application, this process could be more suspicious.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Consider the user as identified by the `user.name` field. Is this script part of an expected workflow for the user who ran it on this host?
- Validate the activity is not related to planned patches, updates, network administrator activity, or legitimate software installations.
- Validate if the activity has a consistent cadence (for example, if it runs monthly or quarterly), as it could be part of a monthly or quarterly business process.
- Retrieve the script block hash value and search for its existence and reputation in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.
### False Positive Analysis
- If this activity is related to new benign software installation activity, consider adding exceptions — preferably with a combination of user and command line conditions.
- Try to understand the context of the execution by thinking about the user, machine, or business purpose. A small number of endpoints, such as servers with unique software, might appear unusual but satisfy a specific business need.
### Related Rules
- Suspicious Powershell Script - 1781d055-5c66-4adf-9d60-fc0fa58337b6
### Response and Remediation
- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved hosts to prevent further post-compromise behavior.
- If the triage identified malware, search the environment for additional compromised hosts.
- Implement temporary network rules, procedures, and segmentation to contain the malware.
- Stop suspicious processes.
- Immediately block the identified indicators of compromise (IoCs).
- Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that attackers could use to reinfect the system.
- Remove and block malicious artifacts identified during triage.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
references = [
"https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html",
"https://www.elastic.co/security-labs/detecting-living-off-the-land-attacks-with-new-elastic-integration",
]
risk_score = 21
rule_id = "4577d441-0c05-4bfb-9068-39a0cb855269"
setup = """## Setup
This rule requires the installation of associated Machine Learning jobs, as well as data coming in from one of the following integrations:
- Windows
### Anomaly Detection Setup
Once the rule is enabled, the associated Machine Learning job will start automatically. You can view the Machine Learning job linked under the "Definition" panel of the detection rule. If the job does not start due to an error, the issue must be resolved for the job to commence successfully. For more details on setting up anomaly detection jobs, refer to the [helper guide](https://www.elastic.co/guide/en/kibana/current/xpack-ml-anomalies.html).
### Windows Integration Setup
The Windows integration allows you to monitor the Windows OS, services, applications, and more.
#### The following steps should be executed in order to add the Elastic Agent System integration "windows" to your system:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Windows" and select the integration to see more details about it.
- Click "Add Windows".
- Configure the integration name and optionally add a description.
- Review optional and advanced settings accordingly.
- Add the newly installed "windows" to an existing or a new agent policy, and deploy the agent on your system from which windows log files are desirable.
- Click "Save and Continue".
- For more details on the integration refer to the [helper guide](https://docs.elastic.co/integrations/windows).
"""
severity = "low"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Data Source: PowerShell Logs",
"Use Case: Threat Detection",
"Rule Type: ML",
"Rule Type: Machine Learning",
"Tactic: Execution",
"Resources: Investigation Guide",
]
type = "machine_learning"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
rc.local/rc.common File Creation
#This rule monitors the creation of the rc.local/rc.common files. The "/etc/rc.local" file is used to start custom applications, services, scripts or commands during start-up. The rc.local file has mostly been replaced by Systemd. However, through the "systemd-rc-local-generator", rc.local files can be converted to services that run at boot. Adversaries may alter rc.local/rc.common to execute malicious code at start-up, and gain persistence onto the system.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Privilege Escalation |
Rule Body
[metadata]
creation_date = "2023/02/28"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"
[transform]
[[transform.osquery]]
label = "Osquery - Retrieve File Information"
query = "SELECT * FROM file WHERE path = {{file.path}}"
[[transform.osquery]]
label = "Osquery - Retrieve Running Processes by User"
query = "SELECT pid, username, name FROM processes p JOIN users u ON u.uid = p.uid ORDER BY username"
[[transform.osquery]]
label = "Osquery - Retrieve rc-local.service File Information"
query = """
SELECT * FROM file WHERE (path = '/run/systemd/generator/multi-user.target.wants/rc-local.service' OR path =
'/run/systemd/generator/multi-user.target.wants/rc-local.service')
"""
[[transform.osquery]]
label = "Osquery - Retrieve Crontab Information"
query = "SELECT * FROM crontab"
[rule]
author = ["Elastic"]
description = """
This rule monitors the creation of the rc.local/rc.common files. The "/etc/rc.local" file is used to start
custom applications, services, scripts or commands during start-up. The rc.local file has mostly been replaced by
Systemd. However, through the "systemd-rc-local-generator", rc.local files can be converted to services that run at
boot. Adversaries may alter rc.local/rc.common to execute malicious code at start-up, and gain persistence onto the
system.
"""
from = "now-9m"
index = ["logs-endpoint.events.file*"]
language = "eql"
license = "Elastic License v2"
name = "rc.local/rc.common File Creation"
note = """## Triage and analysis
### Investigating rc.local/rc.common File Creation
The `rc.local` file executes custom commands or scripts during system startup on Linux systems. `rc.local` has been deprecated in favor of the use of `systemd services`, and more recent Unix distributions no longer leverage this method of on-boot script execution.
There might still be users that use `rc.local` in a benign matter, so investigation to see whether the file is malicious is vital.
Detection alerts from this rule indicate the creation of a new `/etc/rc.local` file.
> **Note**:
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/current/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.
> This investigation guide uses [placeholder fields](https://www.elastic.co/guide/en/security/current/osquery-placeholder-fields.html) to dynamically pass alert data into Osquery queries. Placeholder fields were introduced in Elastic Stack version 8.7.0. If you're using Elastic Stack version 8.6.0 or earlier, you'll need to manually adjust this investigation guide's queries to ensure they properly run.
#### Possible Investigation Steps
- Identify the user account that performed the action and whether it should perform this kind of action.
- Investigate the file that was created or modified.
- $osquery_0
- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence and whether they are located in expected locations.
- $osquery_1
- Investigate whether the `/lib/systemd/system/rc-local.service` and `/run/systemd/generator/multi-user.target.wants/rc-local.service` files were created through the `systemd-rc-local-generator` located at `/usr/lib/systemd/system-generators/systemd-rc-local-generator`.
- $osquery_2
- In case the file is not present here, `sudo systemctl status rc-local` can be executed to find the location of the rc-local unit file.
- If `rc-local.service` is found, manual investigation is required to check for the rc script execution. Systemd will generate syslogs in case of the execution of the rc-local service. `sudo cat /var/log/syslog | grep "rc-local.service|/etc/rc.local Compatibility"` can be executed to check for the execution of the service.
- If logs are found, it's likely that the contents of the `rc.local` file have been executed. Analyze the logs. In case several syslog log files are available, use a wildcard to search through all of the available logs.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Validate whether this activity is related to planned patches, updates, network administrator activity, or legitimate software installations.
- Investigate whether the altered scripts call other malicious scripts elsewhere on the file system.
- If scripts or executables were dropped, retrieve the files and determine if they are malicious:
- Use a private sandboxed malware analysis system to perform analysis.
- Observe and collect information about the following activities:
- Attempts to contact external domains and addresses.
- Check if the domain is newly registered or unexpected.
- Check the reputation of the domain or IP address.
- File access, modification, and creation activities.
- Cron jobs, services and other persistence mechanisms.
- $osquery_3
### False Positive Analysis
- If this activity is related to new benign software installation activity, consider adding exceptions — preferably with a combination of user and command line conditions.
- If this activity is related to a system administrator who uses `rc.local` for administrative purposes, consider adding exceptions for this specific administrator user account.
- Try to understand the context of the execution by thinking about the user, machine, or business purpose. A small number of endpoints, such as servers with unique software, might appear unusual but satisfy a specific business need.
### Response and remediation
- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- If the triage identified malware, search the environment for additional compromised hosts.
- Implement temporary network rules, procedures, and segmentation to contain the malware.
- Stop suspicious processes.
- Immediately block the identified indicators of compromise (IoCs).
- Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that attackers could use to reinfect the system.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Delete the `service/rc.local` files or restore their original configuration.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Leverage the incident response data and logging to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
references = [
"https://www.intezer.com/blog/malware-analysis/hiddenwasp-malware-targeting-linux-systems/",
"https://pberba.github.io/security/2022/02/06/linux-threat-hunting-for-persistence-initialization-scripts-and-shell-configuration/#8-boot-or-logon-initialization-scripts-rc-scripts",
"https://www.cyberciti.biz/faq/how-to-enable-rc-local-shell-script-on-systemd-while-booting-linux-system/",
"https://www.elastic.co/security-labs/sequel-on-persistence-mechanisms",
]
risk_score = 73
rule_id = "0f4d35e4-925e-4959-ab24-911be207ee6f"
setup = """## Setup
This rule requires data coming in from Elastic Defend.
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "high"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Resources: Investigation Guide",
"Data Source: Elastic Defend",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
file where host.os.type == "linux" and event.action == "creation" and
file.path in ("/etc/rc.local", "/etc/rc.common") and not (
process.executable in (
"/bin/dpkg", "/usr/bin/dpkg", "/bin/dockerd", "/usr/bin/dockerd", "/usr/sbin/dockerd", "/bin/microdnf",
"/usr/bin/microdnf", "/bin/rpm", "/usr/bin/rpm", "/bin/snapd", "/usr/bin/snapd", "/bin/yum", "/usr/bin/yum",
"/bin/dnf", "/usr/bin/dnf", "/bin/podman", "/usr/bin/podman", "/bin/dnf-automatic", "/usr/bin/dnf-automatic",
"/bin/pacman", "/usr/bin/pacman", "/usr/bin/dpkg-divert", "/bin/dpkg-divert", "/sbin/apk", "/usr/sbin/apk",
"/usr/local/sbin/apk", "/usr/bin/apt", "/usr/sbin/pacman", "/bin/podman", "/usr/bin/podman", "/usr/bin/puppet",
"/bin/puppet", "/opt/puppetlabs/puppet/bin/puppet", "/usr/bin/chef-client", "/bin/chef-client",
"/bin/autossl_check", "/usr/bin/autossl_check", "/proc/self/exe", "/dev/fd/*", "/usr/bin/pamac-daemon",
"/bin/pamac-daemon", "/usr/lib/snapd/snapd", "/usr/local/bin/dockerd", "/usr/libexec/platform-python"
) or
file.extension in ("swp", "swpx", "swx", "dpkg-remove") or
file.Ext.original.extension == "dpkg-new" or
process.executable : (
"/nix/store/*", "/var/lib/dpkg/*", "/snap/*", "/dev/fd/*", "/usr/lib/virtualbox/*"
) or
process.executable == null or
process.name in ("ssm-agent-worker", "convert2rhel", "platform-python*") or
(process.name == "sed" and file.name : "sed*") or
(process.name == "perl" and file.name : "e2scrub_all.tmp*")
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1037"
name = "Boot or Logon Initialization Scripts"
reference = "https://attack.mitre.org/techniques/T1037/"
[[rule.threat.technique.subtechnique]]
id = "T1037.004"
name = "RC Scripts"
reference = "https://attack.mitre.org/techniques/T1037/004/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1037"
name = "Boot or Logon Initialization Scripts"
reference = "https://attack.mitre.org/techniques/T1037/"
[[rule.threat.technique.subtechnique]]
id = "T1037.004"
name = "RC Scripts"
reference = "https://attack.mitre.org/techniques/T1037/004/"
[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
Stages and Predicates
Stage 1: file
file where host.os.type == "linux" and event.action == "creation" and
file.path in ("/etc/rc.local", "/etc/rc.common") and not (
process.executable in (
"/bin/dpkg", "/usr/bin/dpkg", "/bin/dockerd", "/usr/bin/dockerd", "/usr/sbin/dockerd", "/bin/microdnf",
"/usr/bin/microdnf", "/bin/rpm", "/usr/bin/rpm", "/bin/snapd", "/usr/bin/snapd", "/bin/yum", "/usr/bin/yum",
"/bin/dnf", "/usr/bin/dnf", "/bin/podman", "/usr/bin/podman", "/bin/dnf-automatic", "/usr/bin/dnf-automatic",
"/bin/pacman", "/usr/bin/pacman", "/usr/bin/dpkg-divert", "/bin/dpkg-divert", "/sbin/apk", "/usr/sbin/apk",
"/usr/local/sbin/apk", "/usr/bin/apt", "/usr/sbin/pacman", "/bin/podman", "/usr/bin/podman", "/usr/bin/puppet",
"/bin/puppet", "/opt/puppetlabs/puppet/bin/puppet", "/usr/bin/chef-client", "/bin/chef-client",
"/bin/autossl_check", "/usr/bin/autossl_check", "/proc/self/exe", "/dev/fd/*", "/usr/bin/pamac-daemon",
"/bin/pamac-daemon", "/usr/lib/snapd/snapd", "/usr/local/bin/dockerd", "/usr/libexec/platform-python"
) or
file.extension in ("swp", "swpx", "swx", "dpkg-remove") or
file.Ext.original.extension == "dpkg-new" or
process.executable : (
"/nix/store/*", "/var/lib/dpkg/*", "/snap/*", "/dev/fd/*", "/usr/lib/virtualbox/*"
) or
process.executable == null or
process.name in ("ssm-agent-worker", "convert2rhel", "platform-python*") or
(process.name == "sed" and file.name : "sed*") or
(process.name == "perl" and file.name : "e2scrub_all.tmp*")
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"creation" |
file.path | in |
| field:"TargetFilename" kind:in |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
file.name | starts_with | e2scrub_all.tmp | excludes:file.name field:"file.name" value:"e2scrub_all.tmp" |
process.name | eq | perl | excludes:process.name field:"process.name" value:"perl" |
file.name | starts_with | sed | excludes:file.name field:"file.name" value:"sed" |
process.name | eq | sed | excludes:process.name field:"process.name" value:"sed" |
file.Ext.original.extension | eq | dpkg-new | excludes:file.Ext.original.extension field:"file.Ext.original.extension" value:"dpkg-new" |
file.extension | in | dpkg-remove, swp, swpx, swx | excludes:file.extension |
process.executable | in | /bin/autossl_check, /bin/chef-client, /bin/dnf, /bin/dnf-automatic, /bin/dockerd, /bin/dpkg, /bin/dpkg-divert, /bin/microdnf, /bin/pacman, /bin/pamac-daemon, /bin/podman, /bin/puppet, /bin/rpm, /bin/snapd, /bin/yum, /dev/fd/*, /opt/puppetlabs/puppet/bin/puppet, /proc/self/exe, /sbin/apk, /usr/bin/apt, /usr/bin/autossl_check, /usr/bin/chef-client, /usr/bin/dnf, /usr/bin/dnf-automatic, /usr/bin/dockerd, /usr/bin/dpkg, /usr/bin/dpkg-divert, /usr/bin/microdnf, /usr/bin/pacman, /usr/bin/pamac-daemon, /usr/bin/podman, /usr/bin/puppet, /usr/bin/rpm, /usr/bin/snapd, /usr/bin/yum, /usr/lib/snapd/snapd, /usr/libexec/platform-python, /usr/local/bin/dockerd, /usr/local/sbin/apk, /usr/sbin/apk, /usr/sbin/dockerd, /usr/sbin/pacman | excludes:process.executable |
process.executable | is_null | excludes:process.executable | |
process.executable | starts_with | /nix/store/, /var/lib/dpkg/, /snap/, /dev/fd/, /usr/lib/virtualbox/ | excludes:process.executable |
process.name | in | convert2rhel, platform-python*, ssm-agent-worker | excludes:process.name field:"process.name" value:"convert2rhel" field:"process.name" value:"platform-python*" field:"process.name" value:"ssm-agent-worker" |
Scheduled Task Creation via Unsigned Parent
#Identifies the creation of a scheduled task using schtasks.exe utility and from a recently dropped unsigned parent process. This behavior is consistent with an adversary attempting to establish persistence.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence |
Rule Body
[rule]
description = """
Identifies the creation of a scheduled task using schtasks.exe utility and from a recently dropped unsigned parent
process. This behavior is consistent with an adversary attempting to establish persistence.
"""
id = "bcafc042-2aaa-4011-8650-1621e3bd6807"
license = "Elastic License v2"
name = "Scheduled Task Creation via Unsigned Parent"
os_list = ["windows"]
reference = ["https://docs.microsoft.com/en-us/windows/win32/taskschd"]
version = "1.0.16"
query = '''
sequence by user.id with maxspan=3m
[process where event.action == "start" and
(process.Ext.relative_file_creation_time <= 500 or process.Ext.relative_file_name_modify_time <= 500) and
not process.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*") and
not process.hash.sha256 : ("d0766b7caa8a7ee828f776116e564e5f231307cb748eb4b9164fa679a88185ca",
"6b509b774512fcd3581c321040119bf412a308c20d681575170a3a21078225b7",
"84efcc024b5f6de6554c40033462b21ca550a240c84e46b36ebb972799aa8a8b",
"5781e4524a79859f2f5097829d5a848a47529181a0cc34342f298d77ab31209f",
"7e2afab5c7bda9ed6b308807757dbd5aecd572a02edb540b7cb8c98865d21278",
"d678d9b1ecb942d88c39c23cd93884b28f6fe0792e2a122e8f1b00c2e34dde27",
"830b7954516ca041fe9aba5e472023002236773aa9f2482a2025706b4536b8d0")
] by process.entity_id
[process where event.action == "start" and
(process.pe.original_file_name : ("schtasks.exe", "sctasks.exe", "cmd.exe", "powershell.exe") or
process.name : ("schtasks.exe", "cmd.exe", "powershell.exe")) and
not process.Ext.token.integrity_level_name == "system" and
process.args : ("/create", "-create") and process.args : "/tr"] by process.parent.entity_id
'''
min_endpoint_version = "8.4.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 = "T1053"
name = "Scheduled Task/Job"
reference = "https://attack.mitre.org/techniques/T1053/"
[[threat.technique.subtechnique]]
id = "T1053.005"
name = "Scheduled Task"
reference = "https://attack.mitre.org/techniques/T1053/005/"
[threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[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, process.parent.entity_id, user.id.
Stage 1: process
[process where event.action == "start" and
(process.Ext.relative_file_creation_time <= 500 or process.Ext.relative_file_name_modify_time <= 500) and
not process.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*") and
not process.hash.sha256 : ("d0766b7caa8a7ee828f776116e564e5f231307cb748eb4b9164fa679a88185ca",
"6b509b774512fcd3581c321040119bf412a308c20d681575170a3a21078225b7",
"84efcc024b5f6de6554c40033462b21ca550a240c84e46b36ebb972799aa8a8b",
"5781e4524a79859f2f5097829d5a848a47529181a0cc34342f298d77ab31209f",
"7e2afab5c7bda9ed6b308807757dbd5aecd572a02edb540b7cb8c98865d21278",
"d678d9b1ecb942d88c39c23cd93884b28f6fe0792e2a122e8f1b00c2e34dde27",
"830b7954516ca041fe9aba5e472023002236773aa9f2482a2025706b4536b8d0")
] by process.entity_id
Stage 2: process
[process where event.action == "start" and
(process.pe.original_file_name : ("schtasks.exe", "sctasks.exe", "cmd.exe", "powershell.exe") or
process.name : ("schtasks.exe", "cmd.exe", "powershell.exe")) and
not process.Ext.token.integrity_level_name == "system" and
process.args : ("/create", "-create") and process.args : "/tr"] by process.parent.entity_id
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.Ext.relative_file_creation_time | le |
| field:"process.Ext.relative_file_creation_time" kind:le value:"500" |
process.Ext.relative_file_name_modify_time | le |
| field:"process.Ext.relative_file_name_modify_time" kind:le value:"500" |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
process.pe.original_file_name | wildcard |
| field:"OriginalFileName" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.code_signature.status | wildcard | trusted, errorExpired, errorCode_endpoint* | excludes:process.code_signature.status field:"process.code_signature.status" value:"trusted" field:"process.code_signature.status" value:"errorExpired" field:"process.code_signature.status" value:"errorCode_endpoint*" |
process.hash.sha256 | eq | d0766b7caa8a7ee828f776116e564e5f231307cb748eb4b9164fa679a88185ca, 6b509b774512fcd3581c321040119bf412a308c20d681575170a3a21078225b7, 84efcc024b5f6de6554c40033462b21ca550a240c84e46b36ebb972799aa8a8b, 5781e4524a79859f2f5097829d5a848a47529181a0cc34342f298d77ab31209f, 7e2afab5c7bda9ed6b308807757dbd5aecd572a02edb540b7cb8c98865d21278, d678d9b1ecb942d88c39c23cd93884b28f6fe0792e2a122e8f1b00c2e34dde27, 830b7954516ca041fe9aba5e472023002236773aa9f2482a2025706b4536b8d0 | excludes:process.hash.sha256 |
process.Ext.token.integrity_level_name | eq | system | excludes:process.Ext.token.integrity_level_name field:"process.Ext.token.integrity_level_name" value:"system" |
Sensitive Attributes Discovery via LDAP
#Attackers often query LDAP for sensitive attributes that may contain credentials, password-like values, or LAPS-managed local admin passwords.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Discovery |
Rule Body
[rule]
description = """
Attackers often query LDAP for sensitive attributes that may contain credentials, password-like values, or LAPS-managed
local admin passwords.
"""
id = "b64874f2-a50c-4fb0-837e-cc1925067587"
license = "Elastic License v2"
name = "Sensitive Attributes Discovery via LDAP"
os_list = ["windows"]
reference = [
"https://bloodhound.specterops.io/resources/edges/read-laps-password",
"https://github.com/netwrix/LAPS-Permissions-Collection/blob/master/LAPS_Permissions_Collection.ps1",
]
version = "1.0.3"
query = '''
api where process.Ext.api.name == "ldap_search" and user.id != "S-1-5-18" and
not process.executable :
("?:\\Program Files\\Azure Advanced Threat Protection Sensor\\*\\Microsoft.Tri.Sensor.exe",
"?:\\Windows\\ADFS\\Microsoft.IdentityServer.ServiceHost.exe") and
process.Ext.api.parameters.search_filter : (
// LAPS attributes
"*(name=ms-Mcs-AdmPwd)*",
"(&(objectCategory=Computer)(ms-MCS-AdmPwd=?))",
"*(name=ms-Mcs-AdmPwdExpirationTime)*",
"*(name=msLAPS-Password)*",
// Password related attributes
"*(name=dBCSPwd)",
"*(name=lmPwdHistory)*",
"*(name=ntPwdHistory)*",
"*(name=supplementalCredentials)*",
// Defender token and secret attributes
"*defender-tokenData=*",
"(name=*secret*)",
"(name=*trust*)",
// passwords in description or comments
"(&(&(objectCategory=person)(objectClass=user))(|(description=?pass?)(comment=?pass?)))"
)
'''
min_endpoint_version = "9.1.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1087"
name = "Account Discovery"
reference = "https://attack.mitre.org/techniques/T1087/"
[[threat.technique.subtechnique]]
id = "T1087.002"
name = "Domain Account"
reference = "https://attack.mitre.org/techniques/T1087/002/"
[[threat.technique]]
id = "T1482"
name = "Domain Trust Discovery"
reference = "https://attack.mitre.org/techniques/T1482/"
[threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
[internal]
min_endpoint_version = "9.1.0"
Stages and Predicates
Stage 1: api
api where process.Ext.api.name == "ldap_search" and user.id != "S-1-5-18" and
not process.executable :
("?:\\Program Files\\Azure Advanced Threat Protection Sensor\\*\\Microsoft.Tri.Sensor.exe",
"?:\\Windows\\ADFS\\Microsoft.IdentityServer.ServiceHost.exe") and
process.Ext.api.parameters.search_filter : (
"*(name=ms-Mcs-AdmPwd)*",
"(&(objectCategory=Computer)(ms-MCS-AdmPwd=?))",
"*(name=ms-Mcs-AdmPwdExpirationTime)*",
"*(name=msLAPS-Password)*",
"*(name=dBCSPwd)",
"*(name=lmPwdHistory)*",
"*(name=ntPwdHistory)*",
"*(name=supplementalCredentials)*",
"*defender-tokenData=*",
"(name=*secret*)",
"(name=*trust*)",
"(&(&(objectCategory=person)(objectClass=user))(|(description=?pass?)(comment=?pass?)))"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
process.Ext.api.name | eq |
| field:"process.Ext.api.name" kind:eq value:"ldap_search" |
process.Ext.api.parameters.search_filter | wildcard |
| field:"process.Ext.api.parameters.search_filter" kind:wildcard |
user.id | ne |
| field:"user.id" kind:ne value:"S-1-5-18" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.executable | wildcard | ?:\Program Files\Azure Advanced Threat Protection Sensor\*\Microsoft.Tri.Sensor.exe, ?:\Windows\ADFS\Microsoft.IdentityServer.ServiceHost.exe | excludes:process.executable field:"process.executable" value:"?:\Program Files\Azure Advanced Threat Protection Sensor\*\Microsoft.Tri.Sensor.exe" field:"process.executable" value:"?:\Windows\ADFS\Microsoft.IdentityServer.ServiceHost.exe" |
Suspicious Call Stack Trailing Bytes
#Identifies API or library events with suspicious call stack trailing bytes often related to shellcode execution.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule Body
[rule]
description = "Identifies API or library events with suspicious call stack trailing bytes often related to shellcode execution."
id = "0c5fe593-39c8-436a-a5ec-7003267f9e0e"
license = "Elastic License v2"
name = "Suspicious Call Stack Trailing Bytes"
os_list = ["windows"]
reference = ["https://www.elastic.co/security-labs/doubling-down-etw-callstacks"]
version = "1.0.11"
query = '''
any where process.executable != null and
/* add esp, 0xab; ret; nop; nop; nop; */
_arraysearch(process.thread.Ext.call_stack, $entry, $entry.callsite_trailing_bytes : ("4883????c3909090909090*", "4883C4485B415CC390909090*")) and
(
(event.category == "api" and process.Ext.api.name like ("VirtualProtect*", "WriteProcessMemory")) or
(event.category == "library" and dll.name in~ ("ws2_32.dll", "wininet.dll", "winhttp.dll"))
) and
not _arraysearch(process.thread.Ext.call_stack, $entry,
$entry.callsite_trailing_bytes :
("4883c428c390909090909090904c8bdc574883ec6049c743b8feffffff49895b1849897320488b05c9a024004833c44889442450488bfa488bd9488b521849c7",
"4883c4205bc3488b8180000000c390909090909090904883ec2833c08b123b15261b3601751d83797c007417488b05f3d43101488b008b517c4889c1e8c5a406",
"4883c428c3909090909090909090909044894c242044894424188954241048894c24084883ec28*")) and
not _arraysearch(process.thread.Ext.call_stack, $entry,
$entry.callsite_leading_bytes :"3b4208750b498908488b01ff5008eb05bb024000808bc34883c4205bc34883ec3848c7442420feffffff488bc1488b094885c9740b48832000488b01ff501090")
'''
min_endpoint_version = "8.8.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "8.8.0"
Stages and Predicates
Stage 1: any
any where process.executable != null and
_arraysearch(process.thread.Ext.call_stack, $entry, $entry.callsite_trailing_bytes : ("4883????c3909090909090*", "4883C4485B415CC390909090*")) and
(
(event.category == "api" and process.Ext.api.name like ("VirtualProtect*", "WriteProcessMemory")) or
(event.category == "library" and dll.name in~ ("ws2_32.dll", "wininet.dll", "winhttp.dll"))
) and
not _arraysearch(process.thread.Ext.call_stack, $entry,
$entry.callsite_trailing_bytes :
("4883c428c390909090909090904c8bdc574883ec6049c743b8feffffff49895b1849897320488b05c9a024004833c44889442450488bfa488bd9488b521849c7",
"4883c4205bc3488b8180000000c390909090909090904883ec2833c08b123b15261b3601751d83797c007417488b05f3d43101488b008b517c4889c1e8c5a406",
"4883c428c3909090909090909090909044894c242044894424188954241048894c24084883ec28*")) and
not _arraysearch(process.thread.Ext.call_stack, $entry,
$entry.callsite_leading_bytes :"3b4208750b498908488b01ff5008eb05bb024000808bc34883c4205bc34883ec3848c7442420feffffff488bc1488b094885c9740b48832000488b01ff501090")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
dll.name | in |
| field:"dll.name" kind:in |
event.category | eq |
| field:"event.category" kind:eq |
process.Ext.api.name | wildcard |
| field:"process.Ext.api.name" kind:wildcard |
process.executable | is_not_null | field:"Image" kind:is_not_null |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.thread.Ext.call_stack | array_any | excludes:process.thread.Ext.call_stack |
Suspicious Critical System Files Modification
#Identifies attempts to delete or modify critical files used during the boot process to prevent the system from booting. This may indicate a destructive attack behavior.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Impact |
Rule Body
[rule]
description = """
Identifies attempts to delete or modify critical files used during the boot process to prevent the system from booting.
This may indicate a destructive attack behavior.
"""
id = "e2c925f7-fccb-4199-a345-cab12acedab0"
license = "Elastic License v2"
name = "Suspicious Critical System Files Modification"
os_list = ["windows"]
version = "1.0.4"
query = '''
file where process.pid != 4 and process.executable != null and
(
(event.action in ("deletion", "overwrite") and
file.path : ("C:\\Windows\\System32\\winload.exe",
"C:\\Windows\\System32\\winload.efi",
"C:\\Windows\\System32\\ntoskrnl.exe",
"C:\\Windows\\Boot\\PCAT\\bootmgr",
"C:\\Windows\\System32\\Boot\\winload.efi",
"C:\\Windows\\System32\\Boot\\winload.exe",
"C:\\Windows\\WinSxS\\amd64_microsoft-windows-os-kernel_*\\ntoskrnl.exe")) or
(event.action == "rename" and
file.Ext.original.path :
("C:\\Windows\\System32\\winload.exe",
"C:\\Windows\\System32\\winload.efi",
"C:\\Windows\\System32\\ntoskrnl.exe",
"C:\\Windows\\Boot\\PCAT\\bootmgr",
"C:\\Windows\\System32\\Boot\\winload.efi",
"C:\\Windows\\System32\\Boot\\winload.exe",
"C:\\Windows\\WinSxS\\amd64_microsoft-windows-os-kernel_*\\ntoskrnl.exe"))
) and not process.executable :
("C:\\Windows\\System32\\poqexec.exe",
"C:\\Windows\\System32\\wbengine.exe",
"C:\\Windows\\WinSxS\\*\\TiWorker.exe")
'''
min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1485"
name = "Data Destruction"
reference = "https://attack.mitre.org/techniques/T1485/"
[[threat.technique]]
id = "T1490"
name = "Inhibit System Recovery"
reference = "https://attack.mitre.org/techniques/T1490/"
[threat.tactic]
id = "TA0040"
name = "Impact"
reference = "https://attack.mitre.org/tactics/TA0040/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: file
file where process.pid != 4 and process.executable != null and
(
(event.action in ("deletion", "overwrite") and
file.path : ("C:\\Windows\\System32\\winload.exe",
"C:\\Windows\\System32\\winload.efi",
"C:\\Windows\\System32\\ntoskrnl.exe",
"C:\\Windows\\Boot\\PCAT\\bootmgr",
"C:\\Windows\\System32\\Boot\\winload.efi",
"C:\\Windows\\System32\\Boot\\winload.exe",
"C:\\Windows\\WinSxS\\amd64_microsoft-windows-os-kernel_*\\ntoskrnl.exe")) or
(event.action == "rename" and
file.Ext.original.path :
("C:\\Windows\\System32\\winload.exe",
"C:\\Windows\\System32\\winload.efi",
"C:\\Windows\\System32\\ntoskrnl.exe",
"C:\\Windows\\Boot\\PCAT\\bootmgr",
"C:\\Windows\\System32\\Boot\\winload.efi",
"C:\\Windows\\System32\\Boot\\winload.exe",
"C:\\Windows\\WinSxS\\amd64_microsoft-windows-os-kernel_*\\ntoskrnl.exe"))
) and not process.executable :
("C:\\Windows\\System32\\poqexec.exe",
"C:\\Windows\\System32\\wbengine.exe",
"C:\\Windows\\WinSxS\\*\\TiWorker.exe")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"rename" |
event.action | in |
| field:"EventType" kind:in |
file.Ext.original.path | wildcard |
| field:"file.Ext.original.path" kind:wildcard |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard |
process.executable | is_not_null | field:"Image" kind:is_not_null | |
process.pid | ne |
| field:"process_id" kind:ne value:"4" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.executable | wildcard | C:\Windows\System32\poqexec.exe, C:\Windows\System32\wbengine.exe, C:\Windows\WinSxS\*\TiWorker.exe | excludes:process.executable field:"process.executable" value:"C:\Windows\System32\poqexec.exe" field:"process.executable" value:"C:\Windows\System32\wbengine.exe" field:"process.executable" value:"C:\Windows\WinSxS\*\TiWorker.exe" |
Suspicious ImageLoad from an ISO Mounted Device
#Identifies instances of RunDLL32, Regsvr32 or Odbcconf loading a DLL from a mounted ISO device. Adversaries may deliver a malicious payload via an ISO file and execute it via rundll32.exe, regsvr32 or Odbcconf.
MITRE ATT&CK Coverage
Rule Body
[rule]
description = """
Identifies instances of RunDLL32, Regsvr32 or Odbcconf loading a DLL from a mounted ISO device. Adversaries may deliver
a malicious payload via an ISO file and execute it via rundll32.exe, regsvr32 or Odbcconf.
"""
id = "779b9502-7912-4773-95a1-51cd702a71c8"
license = "Elastic License v2"
name = "Suspicious ImageLoad from an ISO Mounted Device"
os_list = ["windows"]
reference = [
"https://www.elastic.co/security-labs/Hunting-for-Suspicious-Windows-Libraries-for-Execution-and-Evasion",
]
version = "1.0.29"
query = '''
sequence by process.entity_id with maxspan=1m
[process where event.action == "start" and
process.name : ("rundll32.exe", "regsvr32.exe", "odbcconf.exe", "certoc.exe") and
process.parent.name : ("cmd.exe", "explorer.exe", "powershell.exe", "winrar.exe", "7zFM.exe")]
[library where process.name : ("rundll32.exe", "regsvr32.exe", "odbcconf.exe", "certoc.exe") and
not dll.code_signature.trusted == true and not user.id : ("S-1-5-18", "S-1-5-19", "S-1-5-20") and
/* loading dll from a mounted device */
(dll.path : "\\Device\\CdRom*" or dll.path regex """[d-zD-Z]:\\[0-9a-zA-Z\.]+""")]
'''
min_endpoint_version = "7.16.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"
[[threat.technique.subtechnique]]
id = "T1218.010"
name = "Regsvr32"
reference = "https://attack.mitre.org/techniques/T1218/010/"
[[threat.technique.subtechnique]]
id = "T1218.011"
name = "Rundll32"
reference = "https://attack.mitre.org/techniques/T1218/011/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "7.16.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 1m, correlated by process.entity_id.
Stage 1: process
[process where event.action == "start" and
process.name : ("rundll32.exe", "regsvr32.exe", "odbcconf.exe", "certoc.exe") and
process.parent.name : ("cmd.exe", "explorer.exe", "powershell.exe", "winrar.exe", "7zFM.exe")]
Stage 2: library
[library where process.name : ("rundll32.exe", "regsvr32.exe", "odbcconf.exe", "certoc.exe") and
not dll.code_signature.trusted == true and not user.id : ("S-1-5-18", "S-1-5-19", "S-1-5-20") and
(dll.path : "\\Device\\CdRom*" or dll.path regex """[d-zD-Z]:\\[0-9a-zA-Z\.]+""")]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
dll.path | regex_match |
| field:"ImageLoaded" kind:regex_match value:"[d-zD-Z]:\[0-9a-zA-Z.]+" |
dll.path | wildcard |
| field:"ImageLoaded" kind:wildcard value:"\Device\CdRom*" |
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
dll.code_signature.trusted | eq | true | excludes:dll.code_signature.trusted field:"dll.code_signature.trusted" value:"true" |
user.id | eq | S-1-5-18, S-1-5-19, S-1-5-20 | excludes:user.id field:"user.id" value:"S-1-5-18" field:"user.id" value:"S-1-5-19" field:"user.id" value:"S-1-5-20" |
Windows Trojan Zloader
#Identifies the load of the winsock library or spawn a child process with a call stack containing byte patterns specific to the new Zloader trojan.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule Body
[rule]
description = """
Identifies the load of the winsock library or spawn a child process with a call stack containing byte patterns specific
to the new Zloader trojan.
"""
id = "1ff592a3-8f38-40b7-813d-65e5d65d2380"
license = "Elastic License v2"
name = "Windows Trojan Zloader"
os_list = ["windows"]
reference = ["https://www.zscaler.com/blogs/security-research/zloader-no-longer-silent-night"]
version = "1.0.4"
query = '''
any where event.category in ("library", "process") and
(
(event.category == "library" and dll.name == "ws2_32.dll" and
process.thread.Ext.call_stack_summary == "ntdll.dll|kernelbase.dll|Unbacked" and
_arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info: "Unbacked*" and
$entry.callsite_trailing_bytes : ("48894*00751031c9ba*31c9ffd0eb00488b5*",
"488944243048837c243000751031c9*",
"*31c9ffd0eb00488b44243048634c2428*"))) or
(event.category == "process" and event.action == "start" and process.parent.thread.Ext.call_stack_summary == "Unbacked" and
_arraysearch(process.thread.Ext.call_stack, $entry,
$entry.callsite_trailing_bytes: "c3cd2ec30f1f8400000000004c8bd1b8*75030f05c3cd2*"))
)
'''
min_endpoint_version = "8.8.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "8.8.0"
Stages and Predicates
Stage 1: any
any where event.category in ("library", "process") and
(
(event.category == "library" and dll.name == "ws2_32.dll" and
process.thread.Ext.call_stack_summary == "ntdll.dll|kernelbase.dll|Unbacked" and
_arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info: "Unbacked*" and
$entry.callsite_trailing_bytes : ("48894*00751031c9ba*31c9ffd0eb00488b5*",
"488944243048837c243000751031c9*",
"*31c9ffd0eb00488b44243048634c2428*"))) or
(event.category == "process" and event.action == "start" and process.parent.thread.Ext.call_stack_summary == "Unbacked" and
_arraysearch(process.thread.Ext.call_stack, $entry,
$entry.callsite_trailing_bytes: "c3cd2ec30f1f8400000000004c8bd1b8*75030f05c3cd2*"))
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
dll.name | eq |
| field:"dll.name" kind:eq value:"ws2_32.dll" |
event.action | eq |
| field:"EventType" kind:eq value:"start" |
event.category | eq |
| field:"event.category" kind:eq |
event.category | in |
| field:"event.category" kind:in |
process.parent.thread.Ext.call_stack_summary | eq |
| field:"process.parent.thread.Ext.call_stack_summary" kind:eq value:"Unbacked" |
process.thread.Ext.call_stack_summary | eq |
| field:"process.thread.Ext.call_stack_summary" kind:eq value:"ntdll.dll|kernelbase.dll|Unbacked" |