Detection rules › Elastic

Elastic rules: 3i

Adversary Behavior - Detected - Elastic Endgame

#

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

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

Elastic Endgame detected an Adversary Behavior. 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 detected an Adversary Behavior. 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 = "Adversary Behavior - Detected - Elastic Endgame"
risk_score = 47
rule_id = "77a3c3df-8ec4-4da4-b758-878f551dee69"
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 = "medium"
tags = ["Data Source: Elastic Endgame", "Resources: Investigation Guide"]
timestamp_override = "event.ingested"
type = "query"

query = '''
event.kind:alert and event.module:endgame and (event.action:behavior_protection_event or endgame.event_subtype_full:behavior_protection_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 Adversary Behavior - Detected - Elastic Endgame

Elastic Endgame is a security solution designed to detect and prevent adversarial actions by monitoring system behaviors. Adversaries may exploit system vulnerabilities or execute unauthorized actions to compromise environments. This detection rule identifies suspicious behavior by analyzing alerts and specific event actions, flagging potential threats for further investigation. The rule's medium severity and risk score highlight its importance in maintaining security posture.

### Possible investigation steps

- Review the alert details in the Elastic Endgame console by clicking the Elastic Endgame icon in the event.module column or the link in the rule.reference column to gather more context about the detected behavior.
- Analyze the event.action and endgame.event_subtype_full fields to understand the specific behavior protection event that triggered the alert.
- Correlate the alert with other recent alerts or logs from the same host or user to identify any patterns or additional suspicious activities.
- Investigate the affected system for any signs of compromise or unauthorized changes, focusing on the timeframe around the alert.
- Check for any known vulnerabilities or misconfigurations in the affected system that could have been exploited by the adversary.
- Consult with the IT or security team to determine if any recent changes or updates could have triggered the alert as a false positive.

### False positive analysis

- Routine software updates or installations may trigger alerts due to behavior resembling adversarial actions. Users can create exceptions for known update processes to reduce false positives.
- Legitimate administrative tasks, such as system configuration changes, might be flagged. Identifying and excluding these tasks from monitoring can help minimize unnecessary alerts.
- Security tools or scripts that perform regular scans or maintenance can mimic adversary behavior. Whitelisting these tools in the detection rule settings can prevent them from being flagged.
- Automated backup processes that access multiple files or systems simultaneously may be misinterpreted as suspicious. Users should ensure these processes are recognized and excluded from triggering alerts.
- Custom applications with unique behaviors might be incorrectly identified as threats. Users should document and exclude these behaviors if they are verified as non-threatening.

### Response and remediation

- Isolate the affected system immediately to prevent further unauthorized actions or potential lateral movement by the adversary.
- Review the specific event.action and endgame.event_subtype_full fields to understand the nature of the detected behavior and identify any compromised accounts or processes.
- Terminate any unauthorized processes or sessions identified during the investigation to halt adversary activities.
- Apply security patches or updates to address any exploited vulnerabilities that may have been used by the adversary.
- Conduct a thorough scan of the affected system and network to identify and remove any malicious artifacts or backdoors left by the adversary.
- Restore affected systems from a known good backup if necessary, ensuring that the backup is free from compromise.
- Escalate the incident to the security operations center (SOC) or incident response team for further analysis and to determine if additional systems are affected."""

Stages and Predicates

Stage 1: query

event.kind:alert and event.module:endgame and (event.action:behavior_protection_event or endgame.event_subtype_full:behavior_protection_event)

Indicators

These rows show field, operator, and value matches.

Attempt to Delete an Okta Application

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

Detects attempts to delete an Okta application. An adversary may attempt to modify, deactivate, or delete an Okta application in order to weaken an organization's security controls or disrupt their business operations.

Known False Positives

  • Consider adding exceptions to this rule to filter false positives if your organization's Okta applications are regularly deleted and the behavior is expected.

MITRE ATT&CK Coverage

TacticTechniques
Impact

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

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

[rule]
author = ["Elastic"]
description = """
Detects attempts to delete an Okta application. An adversary may attempt to modify, deactivate, or delete an Okta
application in order to weaken an organization's security controls or disrupt their business operations.
"""
false_positives = [
    """
    Consider adding exceptions to this rule to filter false positives if your organization's Okta applications are
    regularly deleted and the behavior is expected.
    """,
]
index = ["filebeat-*", "logs-okta*"]
language = "kuery"
license = "Elastic License v2"
name = "Attempt to Delete an Okta Application"
note = """## Triage and analysis

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

### Investigating Attempt to Delete an Okta Application

Okta is a widely used identity management service that helps organizations manage user access to applications securely. Adversaries may target Okta applications to disrupt operations or weaken security by attempting deletions. The detection rule monitors system events for deletion actions, flagging potential threats with a low-risk score, aiding analysts in identifying and mitigating unauthorized attempts.

### Possible investigation steps

- Review the event logs for entries with event.dataset:okta.system and event.action:application.lifecycle.delete to confirm the attempted deletion action.
- Identify the user account associated with the deletion attempt and verify their role and permissions within the organization to assess if the action was authorized.
- Check the timestamp of the event to determine if the deletion attempt coincides with any known maintenance windows or authorized changes.
- Investigate the specific Okta application targeted for deletion to understand its importance and potential impact on business operations if it were successfully deleted.
- Examine any recent changes or unusual activities associated with the user account or the targeted application to identify potential indicators of compromise.
- Correlate this event with other security alerts or logs to determine if it is part of a broader attack or isolated incident.

### False positive analysis

- Routine maintenance activities by IT staff may trigger the rule when they legitimately delete or modify applications. To manage this, create exceptions for known maintenance periods or specific user accounts responsible for these tasks.
- Automated scripts or tools used for application lifecycle management might generate false positives. Identify these scripts and exclude their actions from triggering alerts by whitelisting their associated user accounts or service accounts.
- Testing environments where applications are frequently created and deleted for development purposes can lead to false positives. Exclude these environments from monitoring or adjust the rule to ignore actions within specific test domains.
- Changes in application configurations by authorized personnel for legitimate business needs may be flagged. Implement a process to log and approve such changes, allowing for easy identification and exclusion from alerts.

### Response and remediation

- Immediately isolate the affected Okta application to prevent further unauthorized actions. This can be done by temporarily disabling the application or restricting access to it.
- Review the audit logs and event details associated with the deletion attempt to identify the source of the action, including user accounts and IP addresses involved.
- Revoke access for any compromised or suspicious user accounts identified in the investigation to prevent further unauthorized actions.
- Restore the deleted application from backup if applicable, ensuring that all configurations and settings are intact.
- Notify the security team and relevant stakeholders about the incident, providing details of the attempted deletion and actions taken.
- Conduct a root cause analysis to determine how the unauthorized attempt was made and implement additional security controls to prevent similar incidents in the future.
- Enhance monitoring and alerting for Okta application lifecycle events to ensure rapid detection and response to any future unauthorized modification or deletion attempts.

## Setup

The Okta Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
references = [
    "https://developer.okta.com/docs/reference/api/system-log/",
    "https://developer.okta.com/docs/reference/api/event-types/",
    "https://www.elastic.co/security-labs/testing-okta-visibility-and-detection-dorothy",
    "https://www.elastic.co/security-labs/monitoring-okta-threats-with-elastic-security",
    "https://www.elastic.co/security-labs/starter-guide-to-understanding-okta",
]
risk_score = 21
rule_id = "d48e1c13-4aca-4d1f-a7b1-a9161c0ad86f"
severity = "low"
tags = [
    "Use Case: Identity and Access Audit",
    "Data Source: Okta",
    "Tactic: Impact",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset:okta.system and event.action:application.lifecycle.delete
'''


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

[[rule.threat.technique]]
id = "T1489"
name = "Service Stop"
reference = "https://attack.mitre.org/techniques/T1489/"

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

Stages and Predicates

Stage 1: query

data_stream.dataset:okta.system and event.action:application.lifecycle.delete

Indicators

These rows show field, operator, and value matches.

AWS Organizations Delegated Administrator Registered

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

Detects when an AWS member account is registered as a delegated administrator for an AWS service via the RegisterDelegatedAdministrator API. Delegated administrators receive service-level administrative access across the entire organization without being the management account. An attacker who compromises a principal with organizations permissions can abuse overly permissive managed policies to register a member account they control as a delegated administrator, then use that privileged access to escalate privileges organization-wide and compromise all member accounts.

Known False Positives

  • Legitimate cloud platform operations — enabling Security Hub, GuardDuty, or other AWS services at the organization level — require registering a delegated administrator. Validate the called service and target account against your organization's approved delegated admin configuration and a corresponding change management record.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

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

[rule]
author = ["Elastic"]
description = """
Detects when an AWS member account is registered as a delegated administrator for an AWS
service via the RegisterDelegatedAdministrator API. Delegated administrators receive
service-level administrative access across the entire organization without being the
management account. An attacker who compromises a principal with organizations permissions
can abuse overly permissive managed policies to register a member account they control as
a delegated administrator, then use that privileged access to escalate privileges
organization-wide and compromise all member accounts.
"""
false_positives = [
    """
    Legitimate cloud platform operations — enabling Security Hub, GuardDuty, or other
    AWS services at the organization level — require registering a delegated administrator.
    Validate the called service and target account against your organization's approved
    delegated admin configuration and a corresponding change management record.
    """,
]
from = "now-6m"
index = ["logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS Organizations Delegated Administrator Registered"
note = """## Triage and analysis

### Investigating AWS Organizations Delegated Administrator Registered

AWS allows organizations to delegate service-level administrative access to a member account via RegisterDelegatedAdministrator. The delegated account gains organization-wide administrative privileges for the specified service without being the management account. Adversaries who compromise a principal in the management account with overly permissive Organizations policies can register an attacker-controlled member account as a delegated administrator, then use that foothold to escalate privileges across all accounts in the organization.

This technique was documented by Cymulate, who found that AmazonGuardDutyFullAccess v1 (before AWS corrected it) granted organizations:RegisterDelegatedAdministrator without resource restrictions, allowing any principal with that policy to elevate a member account to organization-wide admin for sensitive services such as Identity Center or CloudFormation StackSets.

### Possible investigation steps

- Identify the caller in aws.cloudtrail.user_identity.arn and user.name. Verify they are an authorized cloud platform administrator.
- Review aws.cloudtrail.request_parameters for the servicePrincipal (which AWS service was delegated) and accountId (which member account was elevated). Confirm the member account belongs to your organization's account inventory.
- Determine whether this delegation was planned. Compare against your organization's current delegated administrator configuration via organizations:ListDelegatedAdministrators.
- Check whether the newly elevated member account subsequently made cross-account API calls or modified permission sets, IAM roles, or CloudFormation stacks.
- Review which managed policies are attached to the calling principal. Policies with broad organizations:* grants without resource restrictions may be exploited for this technique.

### Response and remediation

- If unauthorized, deregister the delegated administrator with organizations:DeregisterDelegatedAdministrator.
- Revoke active sessions for the calling identity and audit all management account activity.
- Review and tighten IAM policies attached to principals in the management account — ensure organizations:RegisterDelegatedAdministrator is restricted to a dedicated, MFA-required role.
- Enumerate all delegated administrators in the organization to identify any additional unauthorized delegations.
"""
references = [
    "https://docs.aws.amazon.com/organizations/latest/APIReference/API_RegisterDelegatedAdministrator.html",
    "https://cymulate.com/blog/aws-delegated-admin-org-takeover/",
]
risk_score = 47
rule_id = "ad8ca41c-8e3d-49cd-b130-42af09d1eb42"
setup = "The AWS integration must be ingesting management events into `logs-aws.cloudtrail-*`. Organizations management events are logged in the organization management account by default."
severity = "medium"
tags = [
    "Domain: Cloud",
    "Platform: AWS",
    "Data Source: AWS CloudTrail",
    "Service: AWS Organizations",
    "Rule Type: Custom Query (KQL)",
    "Tactic: Persistence",
    "Tactic: Privilege Escalation",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset: "aws.cloudtrail"
    and event.provider: "organizations.amazonaws.com"
    and event.action: "RegisterDelegatedAdministrator"
    and event.outcome: "success"
'''


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


[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1484"
name = "Domain or Tenant Policy Modification"
reference = "https://attack.mitre.org/techniques/T1484/"


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

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

Stages and Predicates

Stage 1: query

data_stream.dataset: "aws.cloudtrail"
    and event.provider: "organizations.amazonaws.com"
    and event.action: "RegisterDelegatedAdministrator"
    and event.outcome: "success"

Indicators

These rows show field, operator, and value matches.

Azure VM Extension CRUD Operation with Unusual Source ASN

#
Status
production
Severity
medium
Time window
9m
Group by
azure.resource.name, source.as.number
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies create, read, update, or delete (CRUD) operations against Azure VM or VM scale set extensions ("MICROSOFT.COMPUTE/VIRTUALMACHINES/EXTENSIONS/*" or the scale set equivalent) where the combination of the targeted extension resource name and the source autonomous system (AS) number has not been observed recently. VM extensions such as CustomScript and DSC run with high privilege on the guest (SYSTEM on Windows, root on Linux), so writing, modifying, or removing them is a common code-execution and persistence primitive. By keying a new terms approach on the extension resource name and the source AS number, this rule surfaces extension operations originating from networks that have not historically managed that extension, while routine first-party Microsoft automation (which originates from well-known Microsoft AS numbers) is excluded.

Known False Positives

  • Infrastructure-as-code, configuration management, and patching automation routinely create, update, and delete VM extensions. The first time a given extension resource name is operated on from a new source AS number will alert. Baseline expected management networks (corporate egress, CI/CD runners, third-party automation SaaS) and exclude their AS numbers if the activity is verified as authorized. Read operations are typically not emitted to the Azure activity log; the rule predominantly fires on WRITE and DELETE.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2026/06/15"
integration = ["azure"]
maturity = "production"
updated_date = "2026/06/15"

[rule]
author = ["Elastic"]
description = """
Identifies create, read, update, or delete (CRUD) operations against Azure VM or VM scale set extensions
("MICROSOFT.COMPUTE/VIRTUALMACHINES/EXTENSIONS/*" or the scale set equivalent) where the combination of the targeted
extension resource name and the source autonomous system (AS) number has not been observed recently. VM extensions such
as CustomScript and DSC run with high privilege on the guest (SYSTEM on Windows, root on Linux), so writing, modifying,
or removing them is a common code-execution and persistence primitive. By keying a new terms approach on the extension
resource name and the source AS number, this rule surfaces extension operations originating from networks that have not
historically managed that extension, while routine first-party Microsoft automation (which originates from well-known
Microsoft AS numbers) is excluded.
"""
false_positives = [
    """
    Infrastructure-as-code, configuration management, and patching automation routinely create, update, and delete VM
    extensions. The first time a given extension resource name is operated on from a new source AS number will alert.
    Baseline expected management networks (corporate egress, CI/CD runners, third-party automation SaaS) and exclude
    their AS numbers if the activity is verified as authorized. Read operations are typically not emitted to the Azure
    activity log; the rule predominantly fires on WRITE and DELETE.
    """,
]
from = "now-9m"
index = ["logs-azure.activitylogs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Azure VM Extension CRUD Operation with Unusual Source ASN"
note = """## Triage and analysis

### Investigating Azure VM Extension CRUD Operation with Unusual Source ASN

Azure VM and VM scale set extensions (for example CustomScript, DSC, and AADSSHLoginForLinux) execute on the guest with
high privilege. Creating or updating an extension (`EXTENSIONS/WRITE`) can run attacker-supplied code as SYSTEM or root,
while deleting one (`EXTENSIONS/DELETE`) can remove security tooling or clean up after execution. This rule uses a new
terms approach keyed on the pair (`azure.resource.name`, `source.as.number`), so it fires when a given extension resource
is operated on from a source network that has not been seen managing it within the history window. Well-known Microsoft
AS numbers used by first-party automation are excluded in the query.

### Triage checklist

- Identify the source via `source.ip`, `source.as.number`, and `source.as.organization.name`. Operations from cloud
  hosting, VPS, or anonymizing networks are more suspicious than known corporate egress.
- Identify the acting principal via `azure.activitylogs.identity.authorization.evidence.principal_id` and
  `...principal_type` (User vs ServicePrincipal) and `azure.activitylogs.identity.claims.appid`.
- Inspect `azure.resource.id` for the target VM/VMSS and `azure.resource.name` for the extension. CustomScript/DSC
  extensions and randomly named extensions warrant closer review.
- Determine the operation: WRITE (create/update — code execution) vs DELETE (removal — possible defense evasion or
  cleanup).
- Correlate with endpoint telemetry on the target host: process activity parented by the Azure guest agent
  (`WaAppAgent.exe` / `walinuxagent`) within ~120 seconds of the operation timestamp.

### Possible investigation steps

- Review the principal's Entra ID sign-in logs and RBAC role assignments on the subscription, resource group, and VM.
- Retrieve the extension settings/protected settings from the VM (the activity log does not contain the script body) to
  assess intent.
- Pivot on the VM for credential access, new local accounts, or outbound C2 connections following the operation.

### Response and remediation

- If unauthorized, remove the malicious extension, isolate the VM, rotate credentials reachable from it, and review RBAC
  on the affected scope.
- Block or investigate the source AS/network if it is not an expected management path.
- Collect endpoint and activity log artifacts per incident procedures.
"""
references = [
    "https://www.netspi.com/blog/technical-blog/adversary-simulation/7-ways-to-execute-command-on-azure-virtual-machine-virtual-machine-scale-sets/",
    "https://learn.microsoft.com/en-us/azure/virtual-machines/extensions/custom-script-windows",
    "https://hackingthe.cloud/azure/run-command-abuse/",
    "https://blog.pwnedlabs.io/diving-deep-into-azure-vm-attack-vectors",
    "https://www.sysdig.com/blog/the-expendable-extension-name-azure-vmaccess-naming-chaos-password-resets-and-a-detection-gap",
]
risk_score = 47
rule_id = "d69d05f8-d48a-4dcb-b226-fb2efbedd6ba"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Domain: Endpoint",
    "Data Source: Azure",
    "Data Source: Azure Activity Logs",
    "Use Case: Threat Detection",
    "Tactic: Execution",
    "Tactic: Persistence",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"

query = '''
data_stream.dataset:azure.activitylogs and
    event.action:(
        "MICROSOFT.COMPUTE/VIRTUALMACHINES/EXTENSIONS/DELETE" or
        "MICROSOFT.COMPUTE/VIRTUALMACHINES/EXTENSIONS/READ" or
        "MICROSOFT.COMPUTE/VIRTUALMACHINES/EXTENSIONS/WRITE" or
        "MICROSOFT.COMPUTE/VIRTUALMACHINESCALESETS/EXTENSIONS/DELETE" or
        "MICROSOFT.COMPUTE/VIRTUALMACHINESCALESETS/EXTENSIONS/READ" or
        "MICROSOFT.COMPUTE/VIRTUALMACHINESCALESETS/EXTENSIONS/WRITE"
    ) and event.outcome:(Success or success) and
    azure.resource.name:* and
    source.as.number:(* and not (3598 or 8068 or 8069 or 8070 or 8071 or 8072 or 8073 or 8074 or 8075 or 12076))
'''


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


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

[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1037"
name = "Boot or Logon Initialization Scripts"
reference = "https://attack.mitre.org/techniques/T1037/"

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

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

[rule.new_terms]
field = "new_terms_fields"
value = ["azure.resource.name", "source.as.number"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-7d"


Stages and Predicates

Stage 1: new_terms

data_stream.dataset:azure.activitylogs and
    event.action:(
        "MICROSOFT.COMPUTE/VIRTUALMACHINES/EXTENSIONS/DELETE" or
        "MICROSOFT.COMPUTE/VIRTUALMACHINES/EXTENSIONS/READ" or
        "MICROSOFT.COMPUTE/VIRTUALMACHINES/EXTENSIONS/WRITE" or
        "MICROSOFT.COMPUTE/VIRTUALMACHINESCALESETS/EXTENSIONS/DELETE" or
        "MICROSOFT.COMPUTE/VIRTUALMACHINESCALESETS/EXTENSIONS/READ" or
        "MICROSOFT.COMPUTE/VIRTUALMACHINESCALESETS/EXTENSIONS/WRITE"
    ) and event.outcome:(Success or success) and
    azure.resource.name:* and
    source.as.number:(* and not (3598 or 8068 or 8069 or 8070 or 8071 or 8072 or 8073 or 8074 or 8075 or 12076))

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
azure.resource.nameis_not_null
  • (no value, null check)
field:"azure.resource.name" kind:is_not_null
data_stream.dataseteq
  • azure.activitylogs corpus 38 (elastic 38)
field:"data_stream.dataset" kind:eq value:"azure.activitylogs"
event.actionin
  • MICROSOFT.COMPUTE/VIRTUALMACHINES/EXTENSIONS/DELETE
  • MICROSOFT.COMPUTE/VIRTUALMACHINES/EXTENSIONS/READ
  • MICROSOFT.COMPUTE/VIRTUALMACHINES/EXTENSIONS/WRITE
  • MICROSOFT.COMPUTE/VIRTUALMACHINESCALESETS/EXTENSIONS/DELETE
  • MICROSOFT.COMPUTE/VIRTUALMACHINESCALESETS/EXTENSIONS/READ
  • MICROSOFT.COMPUTE/VIRTUALMACHINESCALESETS/EXTENSIONS/WRITE
field:"EventType" kind:in
event.outcomein
  • Success corpus 306 (elastic 306)
  • success corpus 306 (elastic 306)
field:"event.outcome" kind:in
source.as.numberis_not_null
  • (no value, null check)
field:"source.as.number" kind:is_not_null

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
source.as.numberin12076, 3598, 8068, 8069, 8070, 8071, 8072, 8073, 8074, 8075excludes:source.as.number

Decoded or Decrypted Payload Written to Suspicious Directory

#
Source
github.com/elastic/protections-artifacts

Identifies when the openssl utility is used to decode and/or decrypt a payload and write it to an abnormal or suspicious directory. Malware authors may attempt to evade detection by encoding and/or encrypting their payload. This behavior is consistent with the Bundlore malware family.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[rule]
description = """
Identifies when the openssl utility is used to decode and/or decrypt a payload and write it to an abnormal or suspicious
directory. Malware authors may attempt to evade detection by encoding and/or encrypting their payload. This behavior is
consistent with the Bundlore malware family.
"""
id = "4dd92062-2871-43bc-adda-82f15cf6e189"
license = "Elastic License v2"
name = "Decoded or Decrypted Payload Written to Suspicious Directory"
os_list = ["macos"]
reference = ["https://attack.mitre.org/software/S0482/"]
version = "1.0.30"

query = '''
process where event.action == "exec" and
  ((process.name == "openssl" and process.args like~ "-out" and process.args like~ "enc" and process.args in ("-d", "-base64") and
    process.args like~ ("/tmp/*", 
                        "/Users/*/.*",
                        "/Applications/*/.*",
                        "/private/tmp/*", 
                        "/var/tmp/*", 
                        "/var/folders/*", 
                        "/Users/Shared/*",
                        "/Library/Graphics/*",
                        "/Users/*/Library/Preferences/*",
                        "/Users/*/Library/Services/*", 
                        "/Library/Containers/*", 
                        "/var/root/*", 
                        "/var/lib/*",
                        "/Library/WebServer/*",
                        "/Library/Fonts/*")) or 
   (process.name == "base64" and process.args == "-d" and 
    process.args like~ ("/tmp/*", 
                        "*/.*",
                        "/private/tmp/*", 
                        "/var/tmp/*", 
                        "/var/folders/*", 
                        "/Users/Shared/*", 
                        "/Library/Graphics/*",
                        "/Users/*/Library/Preferences/*",
                        "/Users/*/Library/Services/*", 
                        "/Library/Containers/*", 
                        "/var/root/*", 
                        "/var/lib/*",
                        "/Library/WebServer/*",
                        "/Library/Fonts/*")))
'''

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

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

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


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



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

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


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

[internal]
min_endpoint_version = "8.10.2"

Stages and Predicates

Stage 1: process

process where event.action == "exec" and
  ((process.name == "openssl" and process.args like~ "-out" and process.args like~ "enc" and process.args in ("-d", "-base64") and
    process.args like~ ("/tmp/*", 
                        "/Users/*/.*",
                        "/Applications/*/.*",
                        "/private/tmp/*", 
                        "/var/tmp/*", 
                        "/var/folders/*", 
                        "/Users/Shared/*",
                        "/Library/Graphics/*",
                        "/Users/*/Library/Preferences/*",
                        "/Users/*/Library/Services/*", 
                        "/Library/Containers/*", 
                        "/var/root/*", 
                        "/var/lib/*",
                        "/Library/WebServer/*",
                        "/Library/Fonts/*")) or 
   (process.name == "base64" and process.args == "-d" and 
    process.args like~ ("/tmp/*", 
                        "*/.*",
                        "/private/tmp/*", 
                        "/var/tmp/*", 
                        "/var/folders/*", 
                        "/Users/Shared/*", 
                        "/Library/Graphics/*",
                        "/Users/*/Library/Preferences/*",
                        "/Users/*/Library/Services/*", 
                        "/Library/Containers/*", 
                        "/var/root/*", 
                        "/var/lib/*",
                        "/Library/WebServer/*",
                        "/Library/Fonts/*")))

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • exec corpus 547 (elastic 547)
field:"EventType" kind:eq value:"exec"
process.argseq
  • -d corpus 8 (elastic 8)
field:"process.args" kind:eq value:"-d"
process.argsin
  • -base64 corpus 11 (elastic 11)
  • -d corpus 14 (elastic 14)
field:"process.args" kind:in
process.argswildcard
  • */.*
  • -out corpus 2 (elastic 2)
  • /Applications/*/.*
  • /Library/Containers/* corpus 3 (elastic 3)
  • /Library/Fonts/* corpus 3 (elastic 3)
  • /Library/Graphics/* corpus 2 (elastic 2)
  • /Library/WebServer/* corpus 3 (elastic 3)
  • /Users/*/.*
  • /Users/*/Library/Preferences/*
  • /Users/*/Library/Services/*
  • /Users/Shared/* corpus 3 (elastic 3)
  • /private/tmp/* corpus 3 (elastic 3)
  • /tmp/* corpus 7 (elastic 7)
  • /var/folders/* corpus 3 (elastic 3)
  • /var/lib/* corpus 2 (elastic 2)
  • /var/root/* corpus 3 (elastic 3)
  • /var/tmp/* corpus 7 (elastic 7)
  • enc corpus 5 (elastic 5)
field:"process.args" kind:wildcard
process.nameeq
  • base64 corpus 6 (elastic 6)
  • openssl corpus 24 (elastic 24)
field:"process_basename" kind:eq

Dynamic IEX Reconstruction via Method String Access

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

Detects PowerShell scripts that rebuilds IEX by converting method references to strings (for example, ''.IndexOf.ToString()) and extracting multiple indexed characters (for example, [n,n,n]). Attackers use method-string reconstruction to conceal dynamic execution and bypass static detections and AMSI.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2025/04/16"
integration = ["windows"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
Detects PowerShell scripts that rebuilds IEX by converting method references to strings (for example,
''.IndexOf.ToString()) and extracting multiple indexed characters (for example, [n,n,n]). Attackers use method-string
reconstruction to conceal dynamic execution and bypass static detections and AMSI.
"""
from = "now-9m"
language = "esql"
license = "Elastic License v2"
name = "Dynamic IEX Reconstruction via Method String Access"
note = """## Triage and analysis

> **Disclaimer**:
> This guide was created by humans with the assistance of generative AI. While its contents have been manually curated to include the most valuable information, always validate assumptions and adjust procedures to match your internal runbooks and incident triage and response policies.

### Investigating Dynamic IEX Reconstruction via Method String Access

This alert indicates PowerShell script block content that uses method-to-string conversion and indexed character extraction to assemble an execution primitive at runtime, commonly "IEX" (Invoke-Expression). This obfuscation technique can conceal dynamic execution intent and is often used to reduce obvious keywords in the script body.

#### Key alert fields to review

- `user.name`, `user.domain`, `user.id`: Account execution context for correlation, prioritization, and scoping.
- `host.name`, `host.id`: Host execution context for correlation, prioritization, and scoping.
- `file.path`, `file.directory`, `file.name`: File-origin context when the script block is sourced from an on-disk file.
- `powershell.file.script_block_text`: Script block content that matched the detection logic.
- `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`: Script block metadata to pivot to other fragments or reconstruct full script content when split across multiple events.
- `Esql.script_block_tmp`: Transformed script block where detection patterns replace original content with a marker to support scoring/counting and quickly spot match locations.
- `Esql.script_block_pattern_count`: Count of matches for the detection pattern(s) observed in the script block content.
- `powershell.file.script_block_entropy_bits`: Shannon entropy of the script block. Higher values may indicate obfuscation.
- `powershell.file.script_block_surprisal_stdev`: Standard deviation of surprisal across the script block. Low values indicate uniform randomness. High values indicate mixed patterns and variability.
- `powershell.file.script_block_unique_symbols`: Count of distinct characters present in the script block.
- `powershell.file.script_block_length`: Script block length (size) context.

#### Possible investigation steps

- Establish execution context and scope:
  - Review `host.name` and `host.id` to identify the affected endpoint and its role/criticality.
  - Review `user.name`, `user.domain`, and `user.id` to determine whether the activity aligns with expected administrative or automation usage.
  - Review `file.path`, `file.directory`, and `file.name` (when present) to understand whether the script originated from an on-disk file.
  - Review `agent.id` to pivot to other telemetry from the same endpoint and timeframe.

- Validate what matched and how extensively it appears:
  - Review `Esql.script_block_pattern_count` to gauge how often the technique appears within the script block (higher counts can indicate heavier obfuscation).
  - Use `Esql.script_block_tmp` to quickly locate the matched regions, then review the corresponding locations in `powershell.file.script_block_text` for the exact construct and nearby context.
  - Review `powershell.file.script_block_length` alongside `powershell.file.script_block_entropy_bits`, `powershell.file.script_block_surprisal_stdev`, and `powershell.file.script_block_unique_symbols` to help distinguish isolated string tricks from broader obfuscation.

- Reconstruct the full script block when content is split:
  - Pivot on `powershell.file.script_block_id` and order results by `powershell.sequence`.
  - Use `powershell.total` to confirm you have all fragments before making a final assessment.
  - Preserve the reassembled content from `powershell.file.script_block_text` for follow-on analysis and scoping.

- Determine the reconstructed token and follow-on behavior:
  - In `powershell.file.script_block_text`, identify the method string being indexed and the associated index list (for example, [n,n,n]) to determine what characters are being assembled.
  - Identify how the reconstructed string is used (for example, invoked directly, assigned to a variable, or passed as an argument) and what content it ultimately executes.
  - Capture any secondary artifacts referenced in the script content (for example, embedded payload strings, additional script blocks, or external resource locations) and use them to drive further correlation.

- Validate likely origin and initiating source:
  - If `file.path` is present, validate whether the script location is expected for the user and host, and whether it appears in a user-writable location or a standard administrative tooling path.
  - If file origin fields are not present, the script may have been executed interactively or generated at runtime; rely on surrounding endpoint telemetry to identify the initiating process and any related activity.

- Correlate with adjacent activity to understand impact:
  - Review other PowerShell script blocks on the same `host.id` and `user.id` around the alert time to identify staging steps and any follow-on execution.
  - If process telemetry is available, identify the PowerShell process and its parent process that initiated execution, and check for suspicious child processes near the alert time.
  - If network or file telemetry is available, look for downloads, outbound connections, and file writes temporally aligned with the script block execution and the content referenced within `powershell.file.script_block_text`.

- Assess prevalence across the environment:
  - Search for similar patterns (including stable substrings from `powershell.file.script_block_text`) across other hosts and users.
  - Prioritize results with higher `Esql.script_block_pattern_count` and higher obfuscation metrics to identify likely common tooling or shared payloads.

### False positive analysis

- PowerShell developers or automation teams may experiment with unconventional string manipulation, but method-string indexing to assemble execution primitives is uncommon in routine administration.
- Authorized security testing, malware analysis, or threat emulation activities can intentionally use this technique; validate against approved testing windows and operator accounts.
- Some script packaging or code protection approaches can introduce non-standard string operations; treat as benign only when the script origin (`file.path` / `file.name`), execution context (`user.id`), and surrounding host activity support a known, approved workflow.

### Response and remediation

- If malicious or suspicious activity is confirmed:
  - Contain the affected host identified by `host.id` to prevent additional execution and lateral movement.
  - Preserve evidence from the alert, including `powershell.file.script_block_text`, `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`, `file.path`, and `Esql.script_block_pattern_count`.
  - Scope for related activity by searching for similar content patterns across the environment and identifying additional impacted hosts and accounts.
  - If an on-disk script is involved (`file.path` present), collect the file for analysis and remove or quarantine it according to your incident handling process.
  - Review the associated account (`user.id`) for additional suspicious activity and remediate credential exposure as appropriate (for example, reset credentials and review recent authentication activity).

- If the activity is determined to be benign:
  - Document the legitimate script source, expected hosts, and operator accounts for future triage.
  - Reduce noise with narrowly scoped suppression using stable characteristics available in the alert (for example, consistent `file.path` and repeatable non-sensitive substrings in `powershell.file.script_block_text`), while continuing to monitor for deviations.
"""
risk_score = 21
rule_id = "9f432a8b-9588-4550-838e-1f77285580d3"
setup = """## Setup

PowerShell Script Block Logging must be enabled to generate the events used by this rule (e.g., 4104).
Setup instructions: https://ela.st/powershell-logging-setup
"""
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Defense Evasion",
    "Data Source: PowerShell Logs",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"

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

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

// replace the patterns we are looking for with the 🔥 emoji to enable counting them
// The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1
| eval Esql.script_block_tmp = replace(
    powershell.file.script_block_text,
    """(?i)['"]['"].(Insert|Normalize|Chars|substring|Remove|LastIndexOfAny|LastIndexOf|IsNormalized|IndexOfAny|IndexOf)[^\[]+\[\d+,\d+,\d+\]""",
    "🔥"
)

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

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

// Filter for scripts that match the pattern at least once
| where Esql.script_block_pattern_count >= 1

| where not (
    file.directory like "C:\\\\Program Files\\\\WindowsPowerShell\\\\Modules\\\\Maester\\\\1.1.0*" or
    file.directory like "C:\\\\Users\\\\*\\\\Documents\\\\WindowsPowerShell\\\\Modules\\\\Maester\\\\1.1.0*"
  )
  // ESQL requires this condition, otherwise it only returns matches where file.directory exists.
  or file.directory is null
'''


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

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

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

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

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

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

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

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

[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[rule.investigation_fields]
field_names = [
    "@timestamp",
    "user.name",
    "user.id",
    "user.domain",
    "powershell.file.script_block_text",
    "powershell.file.script_block_id",
    "powershell.sequence",
    "powershell.total",
    "file.path",
    "file.directory",
    "file.name",
    "process.pid",
    "host.name",
    "host.id",
    "powershell.file.script_block_length"
]

Stages and Predicates

Stage 1: from

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

Stage 2: where

| where event.code == "4104"

Stage 3: eval

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

Stage 4: where

| where Esql.script_block_length > 500

Stage 5: eval

| eval Esql.script_block_tmp = replace(
    powershell.file.script_block_text,
    """(?i)['"]['"].(Insert|Normalize|Chars|substring|Remove|LastIndexOfAny|LastIndexOf|IsNormalized|IndexOfAny|IndexOf)[^\[]+\[\d+,\d+,\d+\]""",
    "🔥"
)

Stage 6: eval

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

Stage 7: keep

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

Stage 8: where

| where Esql.script_block_pattern_count >= 1

Stage 9: where

| where not (
    file.directory like "C:\\\\Program Files\\\\WindowsPowerShell\\\\Modules\\\\Maester\\\\1.1.0*" or
    file.directory like "C:\\\\Users\\\\*\\\\Documents\\\\WindowsPowerShell\\\\Modules\\\\Maester\\\\1.1.0*"
  )
  or file.directory is null

Indicators

These rows show field, operator, and value matches.

Output Fields

These fields are emitted when the rule matches.

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

Egress Network Connection Followed by Command Execution

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

Detects network connections originating from a binary located in a potentially suspicious location, followed by command execution. This behavior is consistent with C2 agents such as Poseidon and Athena, connecting to a C2 framework such as Mythic. The agent polls the C2 for commands through a web request, after which the command gets executed.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Detects network connections originating from a binary located in a potentially suspicious location, followed by command
execution. This behavior is consistent with C2 agents such as Poseidon and Athena, connecting to a C2 framework such as
Mythic. The agent polls the C2 for commands through a web request, after which the command gets executed.
"""
id = "8c2977dd-07ce-4a8e-8ccd-5e4183138675"
license = "Elastic License v2"
name = "Egress Network Connection Followed by Command Execution"
os_list = ["linux"]
version = "1.0.15"

query = '''
sequence with maxspan=5s
  [network where event.type == "start" and event.action == "connection_attempted" and
   process.executable like ("./*", "/boot/*", "/dev/shm/*", "/run/*", "/var/run/*", "/tmp/*", "/var/tmp/*") and
   not (
      process.executable like "/tmp/*/*" or
      destination.ip == null or
      destination.ip == "0.0.0.0" or 
      cidrmatch(
        destination.ip, "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12",
        "192.0.0.0/24", "192.0.0.0/29","192.0.0.8/32", "192.0.0.9/32", "192.0.0.10/32",
        "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24", "192.31.196.0/24", "192.52.193.0/24",
        "192.168.0.0/16", "192.88.99.0/24", "224.0.0.0/4", "100.64.0.0/10", "192.175.48.0/24",
        "198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1", "FE80::/10",
        "FF00::/8"
      )
    )
  ] by process.entity_id
  [process where event.type == "start" and event.action == "exec" and
   process.parent.executable like ("./*", "/boot/*", "/dev/shm/*", "/run/*", "/var/run/*", "/tmp/*", "/var/tmp/*") and
   process.args like (
     "ip*", "whoami*", "id*", "hostname*", "touch*", "curl*", "wget*", "chmod*", "busybox*", "chattr*", "echo*",
     "php*", "perl*", "ruby*", "lua*", "openssl*", "nc*", "netcat*", "ncat*"
   ) and
   not (
     process.parent.executable in (
       "/srv/nessus_agent/sbin/nessus-agent-module", "/var/log/amazon/ssm/patch-baseline-operations", "./app",
       "./config.json/usr/local/bin/py.test", "./runc"
     ) or
     process.parent.name in ("nseserv", "nexserv", "pycharm") or
     process.parent.command_line == "/usr/bin/php ./boot-watcher.php" or
     process.working_directory == "/usr/lib/adlumin" or
     process.parent.executable like ("/run/k3s/containerd/*", "/run/user/*/.bubblewrap/opt/chef/bin/chef-client", "/run/containerd/*") or
     (
       process.command_line == "sh -c -- hostname -I 2>/dev/null | awk '{print $1}'" and
       process.parent.command_line like "/usr/sbin/php-fpm* --nodaemonize --fpm-config /etc/php/*/fpm/php-fpm.conf"
     )
   )
  ] by process.parent.entity_id
'''

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

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



[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"
[[threat.technique.subtechnique]]
id = "T1071.001"
name = "Web Protocols"
reference = "https://attack.mitre.org/techniques/T1071/001/"



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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

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

Stage 1: network

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

Stage 2: process

[process where event.type == "start" and event.action == "exec" and
   process.parent.executable like ("./*", "/boot/*", "/dev/shm/*", "/run/*", "/var/run/*", "/tmp/*", "/var/tmp/*") and
   process.args like (
     "ip*", "whoami*", "id*", "hostname*", "touch*", "curl*", "wget*", "chmod*", "busybox*", "chattr*", "echo*",
     "php*", "perl*", "ruby*", "lua*", "openssl*", "nc*", "netcat*", "ncat*"
   ) and
   not (
     process.parent.executable in (
       "/srv/nessus_agent/sbin/nessus-agent-module", "/var/log/amazon/ssm/patch-baseline-operations", "./app",
       "./config.json/usr/local/bin/py.test", "./runc"
     ) or
     process.parent.name in ("nseserv", "nexserv", "pycharm") or
     process.parent.command_line == "/usr/bin/php ./boot-watcher.php" or
     process.working_directory == "/usr/lib/adlumin" or
     process.parent.executable like ("/run/k3s/containerd/*", "/run/user/*/.bubblewrap/opt/chef/bin/chef-client", "/run/containerd/*") or
     (
       process.command_line == "sh -c -- hostname -I 2>/dev/null | awk '{print $1}'" and
       process.parent.command_line like "/usr/sbin/php-fpm* --nodaemonize --fpm-config /etc/php/*/fpm/php-fpm.conf"
     )
   )
  ] by process.parent.entity_id

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • connection_attempted
  • exec
field:"EventType" kind:eq
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
process.argswildcard
  • busybox*
  • chattr*
  • chmod*
  • curl*
  • echo*
  • hostname*
  • id*
  • ip*
  • lua*
  • nc*
  • ncat*
  • netcat*
  • openssl*
  • perl*
  • php*
  • ruby*
  • touch*
  • wget*
  • whoami*
field:"process.args" kind:wildcard
process.executablewildcard
  • ./*
  • /boot/*
  • /dev/shm/*
  • /run/*
  • /tmp/*
  • /var/run/*
  • /var/tmp/*
field:"Image" kind:wildcard
process.parent.executablewildcard
  • ./*
  • /boot/*
  • /dev/shm/*
  • /run/*
  • /tmp/*
  • /var/run/*
  • /var/tmp/*
field:"ParentImage" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
destination.ipcidr_match10.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.0.0.0/24, 192.0.0.0/29, 192.0.0.8/32, 192.0.0.9/32, 192.0.0.10/32, 192.0.0.170/32, 192.0.0.171/32, 192.0.2.0/24, 192.31.196.0/24, 192.52.193.0/24, 192.168.0.0/16, 192.88.99.0/24, 224.0.0.0/4, 100.64.0.0/10, 192.175.48.0/24, 198.18.0.0/15, 198.51.100.0/24, 203.0.113.0/24, 240.0.0.0/4, ::1, FE80::/10, FF00::/8excludes:destination.ip
destination.ipeq0.0.0.0excludes:destination.ip field:"destination.ip" value:"0.0.0.0"
destination.ipis_null(no value, null check)excludes:destination.ip
process.executablewildcard/tmp/*/*excludes:process.executable field:"process.executable" value:"/tmp/*/*"
process.command_lineeqsh -c -- hostname -I 2>/dev/null | awk '{print $1}'excludes:process.command_line field:"process.command_line" value:"sh -c -- hostname -I 2>/dev/null | awk '{print $1}'"
process.parent.command_linewildcard/usr/sbin/php-fpm* --nodaemonize --fpm-config /etc/php/*/fpm/php-fpm.confexcludes:process.parent.command_line field:"process.parent.command_line" value:"/usr/sbin/php-fpm* --nodaemonize --fpm-config /etc/php/*/fpm/php-fpm.conf"
process.parent.command_lineeq/usr/bin/php ./boot-watcher.phpexcludes:process.parent.command_line field:"process.parent.command_line" value:"/usr/bin/php ./boot-watcher.php"
process.parent.executablein./app, ./config.json/usr/local/bin/py.test, ./runc, /srv/nessus_agent/sbin/nessus-agent-module, /var/log/amazon/ssm/patch-baseline-operationsexcludes:process.parent.executable
process.parent.executablewildcard/run/k3s/containerd/*, /run/user/*/.bubblewrap/opt/chef/bin/chef-client, /run/containerd/*excludes:process.parent.executable field:"process.parent.executable" value:"/run/k3s/containerd/*" field:"process.parent.executable" value:"/run/user/*/.bubblewrap/opt/chef/bin/chef-client" field:"process.parent.executable" value:"/run/containerd/*"
process.parent.nameinnexserv, nseserv, pycharmexcludes:process.parent.name field:"process.parent.name" value:"nexserv" field:"process.parent.name" value:"nseserv" field:"process.parent.name" value:"pycharm"
process.working_directoryeq/usr/lib/adluminexcludes:process.working_directory field:"process.working_directory" value:"/usr/lib/adlumin"

Embedded Executable via Windows Shortcut File

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

Identifies the execution of a an executable extracted from within a Windows shortcut (lnk) file. Adversaries may embed malicious files in a shortcut file before delivering it to their target in order to trick them into executing the payload.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the execution of a an executable extracted from within a Windows shortcut (lnk) file. Adversaries may embed
malicious files in a shortcut file before delivering it to their target in order to trick them into executing the
payload.
"""
id = "9fdd772b-b483-404f-bc02-7ec87e332bec"
license = "Elastic License v2"
name = "Embedded Executable via Windows Shortcut File"
os_list = ["windows"]
reference = ["https://www.x86matthew.com/view_post?id=embed_exe_lnk"]
version = "1.0.28"

query = '''
sequence with maxspan=1m
 [ file where event.action != "deletion" and
   (file.Ext.header_bytes : "4d5a*" or file.extension : ("exe", "scr", "pif", "com")) and
   process.name : ("cmd.exe", "powershell.exe") ] by process.entity_id
 [ process where event.action == "start" and
   process.parent.name : ("cmd.exe", "powershell.exe") and process.parent.command_line : "*.lnk*"] by process.parent.entity_id
'''

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

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1566"
name = "Phishing"
reference = "https://attack.mitre.org/techniques/T1566/"
[[threat.technique.subtechnique]]
id = "T1566.001"
name = "Spearphishing Attachment"
reference = "https://attack.mitre.org/techniques/T1566/001/"

[[threat.technique.subtechnique]]
id = "T1566.002"
name = "Spearphishing Link"
reference = "https://attack.mitre.org/techniques/T1566/002/"



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

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


[[threat.technique]]
id = "T1204"
name = "User Execution"
reference = "https://attack.mitre.org/techniques/T1204/"
[[threat.technique.subtechnique]]
id = "T1204.001"
name = "Malicious Link"
reference = "https://attack.mitre.org/techniques/T1204/001/"

[[threat.technique.subtechnique]]
id = "T1204.002"
name = "Malicious File"
reference = "https://attack.mitre.org/techniques/T1204/002/"



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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

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

Stage 1: file

[ file where event.action != "deletion" and
   (file.Ext.header_bytes : "4d5a*" or file.extension : ("exe", "scr", "pif", "com")) and
   process.name : ("cmd.exe", "powershell.exe") ] by process.entity_id

Stage 2: process

[ process where event.action == "start" and
   process.parent.name : ("cmd.exe", "powershell.exe") and process.parent.command_line : "*.lnk*"] by process.parent.entity_id

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq value:"start"
event.actionne
  • deletion corpus 90 (elastic 90)
field:"EventType" kind:ne value:"deletion"
file.Ext.header_byteswildcard
  • 4d5a* corpus 45 (elastic 45)
field:"file.Ext.header_bytes" kind:wildcard value:"4d5a*"
file.extensionwildcard
  • com corpus 16 (elastic 16)
  • exe corpus 32 (elastic 32)
  • pif corpus 18 (elastic 18)
  • scr corpus 17 (elastic 17)
field:"file.extension" kind:wildcard
process.namewildcard
  • cmd.exe corpus 122 (elastic 93, splunk 29)
  • powershell.exe corpus 187 (elastic 140, splunk 44, kusto 3)
field:"process_basename" kind:wildcard
process.parent.command_linewildcard
  • *.lnk* corpus 3 (sigma 2, elastic 1)
field:"ParentCommandLine" kind:wildcard value:"*.lnk*"
process.parent.namewildcard
  • cmd.exe corpus 37 (elastic 32, splunk 4, kusto 1)
  • powershell.exe corpus 37 (elastic 35, splunk 1, kusto 1)
field:"parent_process_basename" kind:wildcard

Ingress Tool Transfer via PowerShell

#
Source
github.com/elastic/protections-artifacts

Identifies the execution of files downloaded using Windows PowerShell. This tactic may be indicative of malicious activity where malware is downloading second stage payloads using built-in Windows programs.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the execution of files downloaded using Windows PowerShell. This tactic may be indicative of malicious
activity where malware is downloading second stage payloads using built-in Windows programs.
"""
id = "5abd98fb-ffbe-4cd6-9592-3cda7b155ff5"
license = "Elastic License v2"
name = "Ingress Tool Transfer via PowerShell"
os_list = ["windows"]
version = "1.0.26"

query = '''
process where event.action == "start" and not user.id : "S-1-5-18" and

 (process.Ext.relative_file_creation_time <= 500 or process.Ext.relative_file_name_modify_time <= 500) and

 (process.code_signature.trusted == false or 
  process.code_signature.exists == false or
  process.executable : ("?:\\Users\\Public\\*", "?:\\Windows\\Tasks\\*", "?:\\ProgramData\\*")) and

  (
    (process.parent.name : "powershell.exe" and process.parent.command_line : "*http*" and 
     not process.command_line : ("*bmx-panels-check.s3.us-east-1.amazonaws.com*", "*https://aka.ms/vscode-powershell*")) or

    descendant of [process where event.action == "start" and
                   process.name : "powershell.exe" and process.command_line : "*http*" and 
                   not process.command_line : ("*bmx-panels-check.s3.us-east-1.amazonaws.com*", "*https://aka.ms/vscode-powershell*")]
  )  and

  not process.executable : ("?:\\Program Files\\*", "?:\\Program Files (x86)\\*") and
  not (process.code_signature.subject_name : ("Chocolatey Software, Inc.", "Chocolatey Software, Inc", "Illumio, Inc.") and process.code_signature.trusted == true) and
  not process.executable : ("?:\\ProgramData\\Microsoft\\VisualStudio\\Packages\\*", 
                            "?:\\ProgramData\\chocolatey\\lib\\*", 
                            "?:\\Users\\*\\AppData\\Local\\Temp\\ns*.tmp\\*.exe",
                            "C:\\ProgramData\\chocolatey\\bin\\wacs.exe") and
  not process.parent.executable : "C:\\Program Files\\dotnet\\dotnet.exe" and
  not process.hash.sha256 : 
                 ("1aac95f980af717c580b1b32885f51e67f0c3631ca0e7cfb2908b75df9a3501c", 
                  "c73c4ac2a7cdc48829fe0f9d7ec91ca41c8b434490d4eb3205aad69c7aa3b921", 
                  "3655b300361f205778b3d998a158b7ffb962ede315d92c25c0735b7925b26d8e", 
                  "2aac5c0da14cce02f809e0619c17dcc42ed995898dfb43f8312a924dd6b62a8a",
                  "8426d62aebc7819badc0260eb7a9c83efb65d8c0534d83be691e215db53bf244",
                  "f9fabf2f1c975ae974ac88245b804b526f0e79a97ee7ccc814432784cffb02d4",
                  "d7c9b99aa403c0e629086e8e4acf6438a5489fe9070dc22d6b033d759414fb76",
                  "f689ee9af94b00e9e3f0bb072b34caaf207f32dcb4f5782fc9ca351df9a06c97",
                  "d7c9b99aa403c0e629086e8e4acf6438a5489fe9070dc22d6b033d759414fb76",
                  "e815c36f5f62f2b5de4f2d273553424fc1bce6e735803633a5ca266b62c4efc5",
                  "8ed42db29649e7f20b2821ceef050ba6fa2260aca318b55ba56c3d2fdc292a89",
                  "95604b7ee58263efb39e260f6f94369d349b31c2bfc1fbf1a6598df126bd04d6",
                  "271dc2d7dd9fe171618cb4d1f8bd02a7b7cebb75288277f859e6b247b2d01e2d")
'''

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 = "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/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1105"
name = "Ingress Tool Transfer"
reference = "https://attack.mitre.org/techniques/T1105/"


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

[internal]
min_endpoint_version = "8.4.0"

Stages and Predicates

Stage 1: process

process where event.action == "start" and not user.id : "S-1-5-18" and

 (process.Ext.relative_file_creation_time <= 500 or process.Ext.relative_file_name_modify_time <= 500) and

 (process.code_signature.trusted == false or 
  process.code_signature.exists == false or
  process.executable : ("?:\\Users\\Public\\*", "?:\\Windows\\Tasks\\*", "?:\\ProgramData\\*")) and

  (
    (process.parent.name : "powershell.exe" and process.parent.command_line : "*http*" and 
     not process.command_line : ("*bmx-panels-check.s3.us-east-1.amazonaws.com*", "*https://aka.ms/vscode-powershell*")) or

    descendant of [process where event.action == "start" and
                   process.name : "powershell.exe" and process.command_line : "*http*" and 
                   not process.command_line : ("*bmx-panels-check.s3.us-east-1.amazonaws.com*", "*https://aka.ms/vscode-powershell*")]
  )  and

  not process.executable : ("?:\\Program Files\\*", "?:\\Program Files (x86)\\*") and
  not (process.code_signature.subject_name : ("Chocolatey Software, Inc.", "Chocolatey Software, Inc", "Illumio, Inc.") and process.code_signature.trusted == true) and
  not process.executable : ("?:\\ProgramData\\Microsoft\\VisualStudio\\Packages\\*", 
                            "?:\\ProgramData\\chocolatey\\lib\\*", 
                            "?:\\Users\\*\\AppData\\Local\\Temp\\ns*.tmp\\*.exe",
                            "C:\\ProgramData\\chocolatey\\bin\\wacs.exe") and
  not process.parent.executable : "C:\\Program Files\\dotnet\\dotnet.exe" and
  not process.hash.sha256 : 
                 ("1aac95f980af717c580b1b32885f51e67f0c3631ca0e7cfb2908b75df9a3501c", 
                  "c73c4ac2a7cdc48829fe0f9d7ec91ca41c8b434490d4eb3205aad69c7aa3b921", 
                  "3655b300361f205778b3d998a158b7ffb962ede315d92c25c0735b7925b26d8e", 
                  "2aac5c0da14cce02f809e0619c17dcc42ed995898dfb43f8312a924dd6b62a8a",
                  "8426d62aebc7819badc0260eb7a9c83efb65d8c0534d83be691e215db53bf244",
                  "f9fabf2f1c975ae974ac88245b804b526f0e79a97ee7ccc814432784cffb02d4",
                  "d7c9b99aa403c0e629086e8e4acf6438a5489fe9070dc22d6b033d759414fb76",
                  "f689ee9af94b00e9e3f0bb072b34caaf207f32dcb4f5782fc9ca351df9a06c97",
                  "d7c9b99aa403c0e629086e8e4acf6438a5489fe9070dc22d6b033d759414fb76",
                  "e815c36f5f62f2b5de4f2d273553424fc1bce6e735803633a5ca266b62c4efc5",
                  "8ed42db29649e7f20b2821ceef050ba6fa2260aca318b55ba56c3d2fdc292a89",
                  "95604b7ee58263efb39e260f6f94369d349b31c2bfc1fbf1a6598df126bd04d6",
                  "271dc2d7dd9fe171618cb4d1f8bd02a7b7cebb75288277f859e6b247b2d01e2d")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq value:"start"
process.Ext.relative_file_creation_timele
  • 500 transforms: number corpus 28 (elastic 28)
field:"process.Ext.relative_file_creation_time" kind:le value:"500"
process.Ext.relative_file_name_modify_timele
  • 500 transforms: number corpus 21 (elastic 21)
field:"process.Ext.relative_file_name_modify_time" kind:le value:"500"
process.code_signature.existseq
  • false transforms: boolean corpus 118 (elastic 118)
field:"process.code_signature.exists" kind:eq value:"false"
process.code_signature.trustedeq
  • false transforms: boolean corpus 114 (elastic 114)
field:"process.code_signature.trusted" kind:eq value:"false"
process.executablewildcard
  • ?:\ProgramData\* corpus 17 (elastic 17)
  • ?:\Users\Public\* corpus 4 (elastic 4)
  • ?:\Windows\Tasks\* corpus 7 (elastic 7)
field:"Image" kind:wildcard
process.parent.command_linewildcard
  • *http* corpus 2 (elastic 2)
field:"ParentCommandLine" kind:wildcard value:"*http*"
process.parent.namewildcard
  • powershell.exe corpus 37 (elastic 35, splunk 1, kusto 1)
field:"parent_process_basename" kind:wildcard value:"powershell.exe"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.code_signature.subject_nameeqChocolatey Software, Inc., Chocolatey Software, Inc, Illumio, Inc.excludes:process.code_signature.subject_name field:"process.code_signature.subject_name" value:"Chocolatey Software, Inc." field:"process.code_signature.subject_name" value:"Chocolatey Software, Inc" field:"process.code_signature.subject_name" value:"Illumio, Inc."
process.code_signature.trustedeqtrueexcludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true"
process.executablestarts_with?:\Program Files\, ?:\Program Files (x86)\excludes:process.executable field:"process.executable" value:"?:\Program Files\" field:"process.executable" value:"?:\Program Files (x86)\"
process.executablewildcard?:\ProgramData\Microsoft\VisualStudio\Packages\*, ?:\ProgramData\chocolatey\lib\*, ?:\Users\*\AppData\Local\Temp\ns*.tmp\*.exe, C:\ProgramData\chocolatey\bin\wacs.exeexcludes:process.executable
process.hash.sha256eq1aac95f980af717c580b1b32885f51e67f0c3631ca0e7cfb2908b75df9a3501c, c73c4ac2a7cdc48829fe0f9d7ec91ca41c8b434490d4eb3205aad69c7aa3b921, 3655b300361f205778b3d998a158b7ffb962ede315d92c25c0735b7925b26d8e, 2aac5c0da14cce02f809e0619c17dcc42ed995898dfb43f8312a924dd6b62a8a, 8426d62aebc7819badc0260eb7a9c83efb65d8c0534d83be691e215db53bf244, f9fabf2f1c975ae974ac88245b804b526f0e79a97ee7ccc814432784cffb02d4, d7c9b99aa403c0e629086e8e4acf6438a5489fe9070dc22d6b033d759414fb76, f689ee9af94b00e9e3f0bb072b34caaf207f32dcb4f5782fc9ca351df9a06c97, d7c9b99aa403c0e629086e8e4acf6438a5489fe9070dc22d6b033d759414fb76, e815c36f5f62f2b5de4f2d273553424fc1bce6e735803633a5ca266b62c4efc5, 8ed42db29649e7f20b2821ceef050ba6fa2260aca318b55ba56c3d2fdc292a89, 95604b7ee58263efb39e260f6f94369d349b31c2bfc1fbf1a6598df126bd04d6, 271dc2d7dd9fe171618cb4d1f8bd02a7b7cebb75288277f859e6b247b2d01e2dexcludes:process.hash.sha256
process.parent.executableeqC:\Program Files\dotnet\dotnet.exeexcludes:process.parent.executable field:"process.parent.executable" value:"C:\Program Files\dotnet\dotnet.exe"
user.ideqS-1-5-18excludes:user.id field:"user.id" value:"S-1-5-18"

M365 Exchange Malware Filter Policy Deleted

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

Identifies when a malware filter policy has been deleted in Microsoft 365. A malware filter policy is used to alert administrators that an internal user sent a message that contained malware. This may indicate an account or machine compromise that would need to be investigated. Deletion of a malware filter policy may be done to evade detection.

Known False Positives

  • A malware filter policy may be deleted by a system or network administrator. Verify that the configuration change was expected. Exceptions can be added to this rule to filter expected behavior.

MITRE ATT&CK Coverage

TacticTechniques
Defense Impairment

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2020/11/19"
integration = ["o365"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Identifies when a malware filter policy has been deleted in Microsoft 365. A malware filter policy is used to alert
administrators that an internal user sent a message that contained malware. This may indicate an account or machine
compromise that would need to be investigated. Deletion of a malware filter policy may be done to evade detection.
"""
false_positives = [
    """
    A malware filter policy may be deleted by a system or network administrator. Verify that the configuration change
    was expected. Exceptions can be added to this rule to filter expected behavior.
    """,
]
from = "now-9m"
index = ["logs-o365.audit-*", "filebeat-*"]
language = "kuery"
license = "Elastic License v2"
name = "M365 Exchange Malware Filter Policy Deleted"
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 M365 Exchange Malware Filter Policy Deleted

Microsoft 365 Exchange uses malware filter policies to detect and alert administrators about malware in emails, crucial for maintaining security. Adversaries may delete these policies to bypass detection, facilitating undetected malware distribution. The detection rule monitors audit logs for successful deletions of these policies, signaling potential defense evasion attempts.

### Possible investigation steps

- Review the audit logs for the specific event.action "Remove-MalwareFilterPolicy" to identify the user account responsible for the deletion.
- Investigate the event.outcome to confirm the success of the policy deletion and gather additional context from related logs.
- Check the event.provider "Exchange" and event.category "web" to ensure the activity is consistent with expected administrative actions.
- Assess the recent activity of the identified user account for any unusual behavior or signs of compromise, such as unexpected login locations or times.
- Examine other security alerts or incidents involving the same user account or related systems to identify potential patterns or coordinated attacks.
- Verify if there are any recent changes in permissions or roles for the user account that could explain the ability to delete the malware filter policy.
- Coordinate with IT and security teams to determine if the deletion was authorized or if immediate remediation actions are necessary to restore security controls.

### False positive analysis

- Administrative maintenance activities may trigger the rule if administrators are legitimately updating or removing outdated malware filter policies. To manage this, maintain a log of scheduled maintenance activities and cross-reference with alerts to verify legitimacy.
- Automated scripts or third-party tools used for policy management might inadvertently delete policies, leading to false positives. Ensure these tools are configured correctly and consider excluding their actions from the rule if they are verified as non-threatening.
- Changes in organizational policy or security strategy might necessitate the removal of certain malware filter policies. Document these changes and create exceptions in the detection rule for these specific actions to prevent unnecessary alerts.
- User error during policy management could result in accidental deletions. Implement additional verification steps or approval processes for policy deletions to reduce the likelihood of such errors triggering false positives.

### Response and remediation

- Immediately isolate the affected account or system to prevent further unauthorized actions or malware distribution.
- Recreate the deleted malware filter policy to restore the email security posture and prevent further evasion attempts.
- Conduct a thorough review of recent audit logs to identify any other suspicious activities or policy changes that may indicate a broader compromise.
- Reset passwords and enforce multi-factor authentication for the affected account to secure access and prevent further unauthorized actions.
- Notify the security team and relevant stakeholders about the incident for awareness and potential escalation if further investigation reveals a larger threat.
- Implement additional monitoring on the affected account and related systems to detect any further suspicious activities or attempts to bypass security measures.
- Review and update security policies and configurations to ensure they are robust against similar evasion tactics in the future.

## Setup

The Office 365 Logs Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
references = [
    "https://docs.microsoft.com/en-us/powershell/module/exchange/remove-malwarefilterpolicy?view=exchange-ps",
]
risk_score = 47
rule_id = "d743ff2a-203e-4a46-a3e3-40512cfe8fbb"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Data Source: Microsoft 365",
    "Use Case: Configuration Audit",
    "Tactic: Defense Evasion",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset:o365.audit and event.provider:Exchange and event.category:web and event.action:"Remove-MalwareFilterPolicy" and event.outcome:success
'''


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

[[rule.threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"

[[rule.threat.technique.subtechnique]]
id = "T1562.001"
name = "Disable or Modify Tools"
reference = "https://attack.mitre.org/techniques/T1562/001/"

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

Stages and Predicates

Stage 1: query

data_stream.dataset:o365.audit and event.provider:Exchange and event.category:web and event.action:"Remove-MalwareFilterPolicy" and event.outcome:success

Indicators

These rows show field, operator, and value matches.

Microsoft Build Engine Using an Alternate Name

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

An instance of MSBuild, the Microsoft Build Engine, was started after being renamed. This is uncommon behavior and may indicate an attempt to run unnoticed or undetected.

Known False Positives

  • The Build Engine is commonly used by Windows developers but use by non-engineers is unusual.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2020/03/25"
integration = ["endpoint", "windows", "m365_defender", "crowdstrike"]
maturity = "production"
updated_date = "2026/05/04"

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

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

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

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


[rule]
author = ["Elastic"]
description = """
An instance of MSBuild, the Microsoft Build Engine, was started after being renamed. This is uncommon behavior and may
indicate an attempt to run unnoticed or undetected.
"""
false_positives = ["The Build Engine is commonly used by Windows developers but use by non-engineers is unusual."]
from = "now-9m"
index = [
    "winlogbeat-*",
    "logs-endpoint.events.process-*",
    "logs-windows.sysmon_operational-*",
    "endgame-*",
    "logs-m365_defender.event-*",
    "logs-crowdstrike.fdr*",
]
language = "eql"
license = "Elastic License v2"
name = "Microsoft Build Engine Using an Alternate Name"
note = """## Triage and analysis

### Investigating Microsoft Build Engine Using an Alternate Name

The OriginalFileName attribute of a PE (Portable Executable) file is a metadata field that contains the original name of the executable file when compiled or linked. By using this attribute, analysts can identify renamed instances that attackers can use with the intent of evading detections, application allowlists, and other security protections.

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

This rule checks for renamed instances of MSBuild, which can indicate an attempt of evading detections, application allowlists, and other security protections.

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

#### Possible investigation steps

- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Investigate any abnormal behavior by the subject process such as network connections, registry or file modifications, and any spawned child processes.
- 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

- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.

### Response and remediation

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

setup = """## Setup

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

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

### Additional data sources

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

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

risk_score = 21
rule_id = "9d110cb3-5f4b-4c9a-b9f5-53f0a1707ae4"
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Defense Evasion",
    "Tactic: Execution",
    "Data Source: Elastic Endgame",
    "Resources: Investigation Guide",
    "Data Source: Elastic Defend",
    "Data Source: Sysmon",
    "Data Source: Microsoft Defender XDR",
    "Data Source: Crowdstrike",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
process where host.os.type == "windows" and event.type == "start" and
  process.pe.original_file_name == "MSBuild.exe" and
  not process.name : "MSBuild.exe"
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1036"
name = "Masquerading"
reference = "https://attack.mitre.org/techniques/T1036/"
[[rule.threat.technique.subtechnique]]
id = "T1036.003"
name = "Rename Legitimate Utilities"
reference = "https://attack.mitre.org/techniques/T1036/003/"


[[rule.threat.technique]]
id = "T1127"
name = "Trusted Developer Utilities Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1127/"
[[rule.threat.technique.subtechnique]]
id = "T1127.001"
name = "MSBuild"
reference = "https://attack.mitre.org/techniques/T1127/001/"



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

Stages and Predicates

Stage 1: process

process where host.os.type == "windows" and event.type == "start" and
  process.pe.original_file_name == "MSBuild.exe" and
  not process.name : "MSBuild.exe"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.pe.original_file_nameeq
  • MSBuild.exe corpus 4 (elastic 4)
field:"OriginalFileName" kind:eq value:"MSBuild.exe"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.nameeqMSBuild.exeexcludes:process.name field:"process.name" value:"MSBuild.exe"

Multiple Alerts Involving a User

#
Status
production
Severity
high
Time window
4h
Group by
user.id, user.name
Author
Elastic
Source
github.com/elastic/detection-rules

This rule uses alert data to determine when multiple different alerts involving the same user are triggered. Analysts can use this to prioritize triage and response, as these users are more likely to be compromised.

Rule Body

[metadata]
creation_date = "2022/11/16"
maturity = "production"
updated_date = "2026/09/04"

[rule]
author = ["Elastic"]
description = """
This rule uses alert data to determine when multiple different alerts involving the same user are triggered. Analysts
can use this to prioritize triage and response, as these users are more likely to be compromised.
"""
from = "now-4h"
interval = "1h"
language = "esql"
license = "Elastic License v2"
name = "Multiple Alerts Involving a User"
risk_score = 73
rule_id = "0d160033-fab7-4e72-85a3-3a9d80c8bff7"
severity = "high"
tags = ["Use Case: Threat Detection", "Rule Type: Higher-Order Rule", "Resources: Investigation Guide"]
timestamp_override = "event.ingested"
type = "esql"

query = '''
from .alerts-security.*
| where kibana.alert.rule.name is not null and user.id is not null and
  // Exclude low severity alerts
  kibana.alert.risk_score > 21 and
  not KQL("""kibana.alert.rule.tags : "Rule Type: Higher-Order Rule" """)
| stats
    Esql.kibana_alert_rule_name_distinct_count = COUNT_DISTINCT(kibana.alert.rule.name), 
    Esql.kibana_alert_rule_rule_id_distinct_count = COUNT_DISTINCT(kibana.alert.rule.rule_id),
    Esql.host_id_distinct_count = COUNT_DISTINCT(host.id),
    Esql.kibana_alert_risk_score_distinct_count = COUNT_DISTINCT(kibana.alert.risk_score),
    Esql.event_dataset_distinct_count = COUNT_DISTINCT(event.dataset),
    Esql.kibana_alert_rule_name_values = VALUES(kibana.alert.rule.name), 
    Esql.kibana_alert_risk_score_values = VALUES(kibana.alert.risk_score), 
    Esql.event_dataset_values = VALUES(event.dataset),
    Esql.event_module_values = VALUES(event.module), 
    Esql.process_command_line_values = VALUES(process.command_line), 
    Esql.host_id_values = VALUES(host.id), 
    Esql.source_ip_values = VALUES(source.ip), 
    Esql.destination_ip_values = VALUES(destination.ip) by user.id, user.name

| where Esql.kibana_alert_rule_name_distinct_count >= 4 AND Esql.kibana_alert_rule_rule_id_distinct_count >= 2 and
 // Exclude known system accounts with matches in more than one host
 not (
   (length(TO_STRING(user.id)) <= 4 or user.id IN ("S-1-5-18", "S-1-5-19", "S-1-5-20", "0")) and
   (Esql.host_id_distinct_count >= 2 or Esql.host_id_distinct_count == 0)
 )

| keep user.id, user.name, Esql.*
'''
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 Multiple Alerts Involving a User

In security environments, monitoring user activity is crucial as adversaries often exploit user accounts to gain unauthorized access. Attackers may trigger multiple alerts by performing suspicious actions under a compromised user account. The detection rule identifies such patterns by correlating diverse alerts linked to the same user, excluding known system accounts, thus prioritizing potential threats for analysts.

### Possible investigation steps

- Review the alert details to identify the specific user account involved, focusing on the user.name field to gather initial context about the user.
- Examine the timeline and sequence of the triggered alerts to understand the pattern of activity associated with the user, noting any unusual or unexpected actions.
- Cross-reference the user activity with known legitimate activities or scheduled tasks to rule out false positives, ensuring that the actions are not part of normal operations.
- Investigate the source and destination IP addresses associated with the alerts to identify any suspicious or unauthorized access points.
- Check for any recent changes in user permissions or group memberships that could indicate privilege escalation attempts.
- Look into any recent login attempts or authentication failures for the user account to detect potential brute force or credential stuffing attacks.
- Collaborate with the user or their manager to verify if the activities were authorized or if the account might be compromised.

### False positive analysis

- Alerts triggered by automated system processes or scripts that mimic user behavior can be false positives. To manage these, identify and exclude known benign scripts or processes from the rule.
- Frequent alerts from users in roles that inherently require access to multiple systems or sensitive data, such as IT administrators, may not indicate compromise. Implement role-based exceptions to reduce noise.
- Alerts generated by legitimate software updates or maintenance activities can be mistaken for suspicious behavior. Schedule these activities during known maintenance windows and exclude them from the rule during these times.
- Users involved in testing or development environments may trigger multiple alerts due to their work nature. Create exceptions for these environments to prevent unnecessary alerts.
- High-volume users, such as those in customer support or sales, may naturally generate more alerts. Monitor these users separately and adjust the rule to focus on unusual patterns rather than volume alone.

### Response and remediation

- Isolate the affected user account immediately to prevent further unauthorized access. Disable the account or change the password to stop any ongoing malicious activity.
- Conduct a thorough review of the affected user's recent activities and access logs to identify any unauthorized actions or data access. This will help in understanding the scope of the compromise.
- Remove any malicious software or unauthorized tools that may have been installed on the user's system. Use endpoint detection and response (EDR) tools to scan and clean the system.
- Restore any altered or deleted data from backups, ensuring that the restored data is free from any malicious modifications.
- Notify relevant stakeholders, including IT security teams and management, about the incident and the steps being taken to address it. This ensures that everyone is aware and can provide support if needed.
- Implement additional monitoring on the affected user account and related systems to detect any further suspicious activities. This includes setting up alerts for unusual login attempts or data access patterns.
- Review and update access controls and permissions for the affected user and similar accounts to prevent future incidents. Ensure that least privilege principles are applied."""

Stages and Predicates

Stage 1: from

from .alerts-security.*

Stage 2: where

| where kibana.alert.rule.name is not null and user.id is not null and
  kibana.alert.risk_score > 21 and
  not KQL("""kibana.alert.rule.tags : "Rule Type: Higher-Order Rule" """)

Stage 3: stats

| stats
    Esql.kibana_alert_rule_name_distinct_count = COUNT_DISTINCT(kibana.alert.rule.name), 
    Esql.kibana_alert_rule_rule_id_distinct_count = COUNT_DISTINCT(kibana.alert.rule.rule_id),
    Esql.host_id_distinct_count = COUNT_DISTINCT(host.id),
    Esql.kibana_alert_risk_score_distinct_count = COUNT_DISTINCT(kibana.alert.risk_score),
    Esql.event_dataset_distinct_count = COUNT_DISTINCT(event.dataset),
    Esql.kibana_alert_rule_name_values = VALUES(kibana.alert.rule.name), 
    Esql.kibana_alert_risk_score_values = VALUES(kibana.alert.risk_score), 
    Esql.event_dataset_values = VALUES(event.dataset),
    Esql.event_module_values = VALUES(event.module), 
    Esql.process_command_line_values = VALUES(process.command_line), 
    Esql.host_id_values = VALUES(host.id), 
    Esql.source_ip_values = VALUES(source.ip), 
    Esql.destination_ip_values = VALUES(destination.ip) by user.id, user.name

Stage 4: where

| where Esql.kibana_alert_rule_name_distinct_count >= 4 AND Esql.kibana_alert_rule_rule_id_distinct_count >= 2 and
 not (
   (length(TO_STRING(user.id)) <= 4 or user.id IN ("S-1-5-18", "S-1-5-19", "S-1-5-20", "0")) and
   (Esql.host_id_distinct_count >= 2 or Esql.host_id_distinct_count == 0)
 )

Stage 5: keep

| keep user.id, user.name, Esql.*

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
kibana.alert.rule.tagseqRule Type: Higher-Order Ruleexcludes:kibana.alert.rule.tags field:"kibana.alert.rule.tags" value:"Rule Type: Higher-Order Rule"
Esql.host_id_distinct_counteq0excludes:Esql.host_id_distinct_count field:"Esql.host_id_distinct_count" value:"0"
Esql.host_id_distinct_countge2excludes:Esql.host_id_distinct_count field:"Esql.host_id_distinct_count" value:"2"
user.idin0, S-1-5-18, S-1-5-19, S-1-5-20excludes:user.id

Output Fields

These fields are emitted when the rule matches.

FieldSource
user.idKEEP user.id
user.nameKEEP user.name
Esql.*KEEP Esql.*

Netcat File Transfer or Listener Detected via Defend for Containers

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

This rule detects an established netcat file transfer or listener running inside a container. Netcat is a utility used for reading and writing data across network connections, and it can be used for malicious purposes such as establishing a backdoor for persistence, exfiltrating data or file transfer.

Known False Positives

  • There is a potential for false positives if the container is used for legitimate tasks that require the use of netcat, such as network troubleshooting, testing or system monitoring. It is important to investigate any alerts generated by this rule to determine if they are indicative of malicious activity or part of legitimate container activity.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2023/04/26"
integration = ["cloud_defend"]
maturity = "production"
min_stack_comments = "Defend for Containers integration was re-introduced in 9.3.0"
min_stack_version = "9.3.0"
updated_date = "2026/07/29"

[rule]
author = ["Elastic"]
description = """
This rule detects an established netcat file transfer or listener running inside a container. Netcat is a utility
used for reading and writing data across network connections, and it can be used for malicious purposes such as
establishing a backdoor for persistence, exfiltrating data or file transfer.
"""
false_positives = [
    """
    There is a potential for false positives if the container is used for legitimate tasks that require the use of
    netcat, such as network troubleshooting, testing or system monitoring. It is important to investigate any alerts
    generated by this rule to determine if they are indicative of malicious activity or part of legitimate container
    activity.
    """,
]
from = "now-6m"
index = ["logs-cloud_defend.process*"]
interval = "5m"
language = "eql"
license = "Elastic License v2"
name = "Netcat File Transfer or Listener Detected via Defend for Containers"
note = """## Setup

## 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 Netcat File Transfer or Listener Detected via Defend for Containers

Netcat is a versatile networking tool used for reading and writing data across network connections, often employed for legitimate purposes like debugging and network diagnostics. However, adversaries can exploit Netcat to establish unauthorized backdoors or exfiltrate data from containers. The detection rule identifies suspicious Netcat activity by monitoring process events within containers, focusing on specific arguments that indicate a listening state, which is a common trait of malicious use. This proactive detection helps mitigate potential threats by flagging unusual network behavior indicative of compromise.

### Possible investigation steps

- Review the container ID associated with the alert to identify the specific container where the Netcat listener was established. This can help in understanding the context and potential impact.
- Examine the process name and arguments to confirm the presence of Netcat and its listening state. Look for arguments like "-l", "--listen", "-p", or "--source-port" to verify the listener setup.
- Check the parent process of the Netcat instance to determine how it was initiated. This can provide insights into whether it was started by a legitimate application or a potentially malicious script.
- Investigate the network connections associated with the container to identify any unusual or unauthorized connections that may indicate data exfiltration or communication with a command and control server.
- Analyze the container's recent activity and logs to identify any other suspicious behavior or anomalies that could be related to the Netcat listener, such as unexpected file modifications or other process executions.
- Assess the container's security posture and configuration to determine if there are any vulnerabilities or misconfigurations that could have been exploited to establish the Netcat listener.

### False positive analysis

- Development and testing activities within containers may trigger the rule if Netcat is used for legitimate debugging or network diagnostics. Users can create exceptions for specific container IDs or process names associated with known development environments.
- Automated scripts or tools that utilize Netcat for routine network checks or health monitoring might be flagged. To mitigate this, users can whitelist these scripts by identifying their unique process arguments or execution patterns.
- Containers running network services that rely on Netcat for legitimate communication purposes could be mistakenly identified. Users should document and exclude these services by specifying their container IDs and associated process arguments.
- Security tools or monitoring solutions that incorporate Netcat for legitimate scanning or testing purposes may cause false positives. Users can manage this by excluding these tools based on their known process names and arguments.

### Response and remediation

- Immediately isolate the affected container to prevent further unauthorized access or data exfiltration. This can be done by stopping the container or disconnecting it from the network.
- Conduct a thorough review of the container's logs and process history to identify any unauthorized access or data transfers that may have occurred.
- Remove any unauthorized Netcat binaries or scripts found within the container to eliminate the backdoor.
- Rebuild the container from a known good image to ensure no residual malicious artifacts remain.
- Update container images and underlying host systems with the latest security patches to mitigate vulnerabilities that could be exploited by similar threats.
- Implement network segmentation and firewall rules to restrict unauthorized outbound connections from containers, reducing the risk of data exfiltration.
- Escalate the incident to the security operations team for further investigation and to assess the potential impact on other containers or systems within the environment."""
risk_score = 47
rule_id = "a52a9439-d52c-401c-be37-2785235c6547"
severity = "medium"
tags = [
    "Data Source: Elastic Defend for Containers",
    "Domain: Container",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Execution",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and (
  process.name in ("nc","ncat","netcat","netcat.openbsd","netcat.traditional") or
  (
    /* account for tools that execute utilities as a subprocess, in this case the target utility name will appear as a process arg */
    process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox") and
    process.args in (
      "nc", "/bin/nc", "/usr/bin/nc", "/usr/local/bin/nc",
      "ncat", "/bin/ncat", "/usr/bin/ncat", "/usr/local/bin/ncat",
      "netcat", "/bin/netcat", "/usr/bin/netcat", "/usr/local/bin/netcat",
      "netcat.openbsd", "/bin/netcat.openbsd", "/usr/bin/netcat.openbsd", "/usr/local/bin/netcat.openbsd",
      "netcat.traditional", "/bin/netcat.traditional", "/usr/bin/netcat.traditional", "/usr/local/bin/netcat.traditional"
    ) and 
    /* default exclusion list to not FP on default multi-process commands */
    not process.args in (
      "which", "/bin/which", "/usr/bin/which", "/usr/local/bin/which",
      "man", "/bin/man", "/usr/bin/man", "/usr/local/bin/man",
      "chmod", "/bin/chmod", "/usr/bin/chmod", "/usr/local/bin/chmod",
      "chown", "/bin/chown", "/usr/bin/chown", "/usr/local/bin/chown"
    )
  )
) and
process.args like~ (
  /* bind shell to specific port or listener */
  "-*l*","-*p*",
  /* reverse shell to command-line interpreter used for command execution */
  "-*e*",
  /* file transfer via stdout/pipe */
  ">","<", "|"
) and container.id like "*"
'''

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

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

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

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

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

[[rule.threat.technique]]
id = "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/"

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

[[rule.threat.technique]]
id = "T1048"
name = "Exfiltration Over Alternative Protocol"
reference = "https://attack.mitre.org/techniques/T1048/"

[[rule.threat.technique.subtechnique]]
id = "T1048.003"
name = "Exfiltration Over Unencrypted Non-C2 Protocol"
reference = "https://attack.mitre.org/techniques/T1048/003/"

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

Stages and Predicates

Stage 1: process

process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and (
  process.name in ("nc","ncat","netcat","netcat.openbsd","netcat.traditional") or
  (
    process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox") and
    process.args in (
      "nc", "/bin/nc", "/usr/bin/nc", "/usr/local/bin/nc",
      "ncat", "/bin/ncat", "/usr/bin/ncat", "/usr/local/bin/ncat",
      "netcat", "/bin/netcat", "/usr/bin/netcat", "/usr/local/bin/netcat",
      "netcat.openbsd", "/bin/netcat.openbsd", "/usr/bin/netcat.openbsd", "/usr/local/bin/netcat.openbsd",
      "netcat.traditional", "/bin/netcat.traditional", "/usr/bin/netcat.traditional", "/usr/local/bin/netcat.traditional"
    ) and
    not process.args in (
      "which", "/bin/which", "/usr/bin/which", "/usr/local/bin/which",
      "man", "/bin/man", "/usr/bin/man", "/usr/local/bin/man",
      "chmod", "/bin/chmod", "/usr/bin/chmod", "/usr/local/bin/chmod",
      "chown", "/bin/chown", "/usr/bin/chown", "/usr/local/bin/chown"
    )
  )
) and
process.args like~ (
  "-*l*","-*p*",
  "-*e*",
  ">","<", "|"
) and container.id like "*"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
container.idwildcard
  • *
field:"container.id" kind:wildcard value:"*"
event.actioneq
  • exec
field:"EventType" kind:eq value:"exec"
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
process.argsin
  • /bin/nc
  • /bin/ncat
  • /bin/netcat
  • /bin/netcat.openbsd
  • /bin/netcat.traditional
  • /usr/bin/nc
  • /usr/bin/ncat
  • /usr/bin/netcat
  • /usr/bin/netcat.openbsd
  • /usr/bin/netcat.traditional
  • /usr/local/bin/nc
  • /usr/local/bin/ncat
  • /usr/local/bin/netcat
  • /usr/local/bin/netcat.openbsd
  • /usr/local/bin/netcat.traditional
  • nc
  • ncat
  • netcat
  • netcat.openbsd
  • netcat.traditional
field:"process.args" kind:in
process.argswildcard
  • -*e*
  • -*l*
  • -*p*
  • <
  • >
  • |
field:"process.args" kind:wildcard
process.namein
  • bash
  • busybox
  • csh
  • dash
  • fish
  • ksh
  • nc
  • ncat
  • netcat
  • netcat.openbsd
  • netcat.traditional
  • sh
  • tcsh
  • zsh
field:"process_basename" kind:in

Network Connection via Compiled HTML File

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

Compiled HTML files (.chm) are commonly distributed as part of the Microsoft HTML Help system. Adversaries may conceal malicious code in a CHM file and deliver it to a victim for execution. CHM content is loaded by the HTML Help executable program (hh.exe).

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

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

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

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

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

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


[rule]
author = ["Elastic"]
description = """
Compiled HTML files (.chm) are commonly distributed as part of the Microsoft HTML Help system. Adversaries may conceal
malicious code in a CHM file and deliver it to a victim for execution. CHM content is loaded by the HTML Help executable
program (hh.exe).
"""
from = "now-9m"
index = [
    "winlogbeat-*",
    "logs-endpoint.events.process-*",
    "logs-endpoint.events.network-*",
    "logs-windows.sysmon_operational-*",
    "logs-sentinel_one_cloud_funnel.*",
]
language = "eql"
license = "Elastic License v2"
name = "Network Connection via Compiled HTML File"
note = """## Triage and analysis

### Investigating Network Connection via Compiled HTML File

CHM (Compiled HTML) files are a format for delivering online help files on Windows. CHM files are compressed compilations of various content, such as HTML documents, images, and scripting/web-related programming languages such as VBA, JScript, Java, and ActiveX.

When users double-click CHM files, the HTML Help executable program (`hh.exe`) will execute them. `hh.exe` also can be used to execute code embedded in those files, PowerShell scripts, and executables. This makes it useful for attackers not only to proxy the execution of malicious payloads via a signed binary that could bypass security controls, but also to gain initial access to environments via social engineering methods.

This rule identifies network connections done by `hh.exe`, which can potentially indicate abuse to download malicious files or tooling, or masquerading.

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

#### Possible investigation steps

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

### False positive analysis

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

### Response and remediation

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

setup = """## Setup

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

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

### Additional data sources

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

- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
- [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
- [Sysmon Event ID 3 - Network Connection](https://ela.st/sysmon-event-3-setup)
- [Sysmon Event ID 22 - DNS Query](https://ela.st/sysmon-event-22-setup)
"""

references = ["https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml"]
risk_score = 21
rule_id = "b29ee2be-bf99-446c-ab1a-2dc0183394b8"
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Execution",
    "Resources: Investigation Guide",
    "Data Source: Elastic Defend",
    "Data Source: Sysmon",
    "Data Source: SentinelOne",
]
type = "eql"

query = '''
sequence by process.entity_id
  [process where host.os.type == "windows" and process.name : "hh.exe" and event.type == "start"]
  [network where host.os.type == "windows" and process.name : "hh.exe" and
     not cidrmatch(destination.ip, "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24",
       "192.0.0.0/29", "192.0.0.8/32", "192.0.0.9/32", "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32",
       "192.0.2.0/24", "192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", "224.0.0.0/4",
       "100.64.0.0/10", "192.175.48.0/24","198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1",
       "FE80::/10", "FF00::/8") and
     not dns.question.name : "localhost"]
'''


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

[[rule.threat.technique]]
id = "T1204"
name = "User Execution"
reference = "https://attack.mitre.org/techniques/T1204/"

[[rule.threat.technique.subtechnique]]
id = "T1204.002"
name = "Malicious File"
reference = "https://attack.mitre.org/techniques/T1204/002/"

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

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

[[rule.threat.technique]]
id = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"

[[rule.threat.technique.subtechnique]]
id = "T1218.001"
name = "Compiled HTML File"
reference = "https://attack.mitre.org/techniques/T1218/001/"

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

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

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

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

Stages and Predicates

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

Stage 1: process

[process where host.os.type == "windows" and process.name : "hh.exe" and event.type == "start"]

Stage 2: network

[network where host.os.type == "windows" and process.name : "hh.exe" and
     not cidrmatch(destination.ip, "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24",
       "192.0.0.0/29", "192.0.0.8/32", "192.0.0.9/32", "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32",
       "192.0.2.0/24", "192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", "224.0.0.0/4",
       "100.64.0.0/10", "192.175.48.0/24","198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1",
       "FE80::/10", "FF00::/8") and
     not dns.question.name : "localhost"]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.namewildcard
  • hh.exe corpus 8 (elastic 5, splunk 3)
field:"process_basename" kind:wildcard value:"hh.exe"

Exclusions

The rule actively suppresses these predicates.

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

Possible FIN7 DGA Command and Control Behavior

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

This rule detects a known command and control pattern in network events. The FIN7 threat group is known to use this command and control technique, while maintaining persistence in their target's network.

Known False Positives

  • This rule could identify benign domains that are formatted similarly to FIN7's command and control algorithm. Alerts should be investigated by an analyst to assess the validity of the individual observations.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2020/07/06"
integration = ["network_traffic", "panw"]
maturity = "production"
updated_date = "2026/08/26"

[rule]
author = ["Elastic"]
description = """
This rule detects a known command and control pattern in network events. The FIN7 threat group is known to use this
command and control technique, while maintaining persistence in their target's network.
"""
false_positives = [
    """
    This rule could identify benign domains that are formatted similarly to FIN7's command and control algorithm. Alerts
    should be investigated by an analyst to assess the validity of the individual observations.
    """,
]
from = "now-9m"
language = "esql"
license = "Elastic License v2"
name = "Possible FIN7 DGA Command and Control Behavior"
note = """## Triage and analysis

In the event this rule identifies benign domains in your environment, the `destination.domain` exclusion in the rule can be modified to include those domains. Example: `... | where destination.domain not in ("zoom.us", "benign.domain1", "benign.domain2")`."""
references = [
    "https://www.fireeye.com/blog/threat-research/2018/08/fin7-pursuing-an-enigmatic-and-evasive-global-criminal-operation.html",
]
risk_score = 73
rule_id = "4a4e23cf-78a2-449c-bac3-701924c269d3"
severity = "high"
tags = [
    "Use Case: Threat Detection",
    "Tactic: Command and Control",
    "Domain: Endpoint",
    "Rule Type: ESQL",
    "Data Source: PAN-OS",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"

query = '''
from packetbeat-*, filebeat-*, logs-network_traffic.*, logs-panw.panos* metadata _id, _version, _index
| where (
    data_stream.dataset in ("network_traffic.tls", "network_traffic.http") or
    (
      data_stream.dataset == "panw.panos" and
      network.application in ("ssl", "web-browsing") and network.transport == "tcp"
    ) or
    (event.category in ("network", "network_traffic") and network.protocol in ("tls", "http") and network.transport == "tcp")
  )
| where destination.domain RLIKE "[a-zA-Z]{4,5}\\.(pw|us|club|info|site|top)"
| where destination.domain != "zoom.us"
| keep @timestamp, destination.domain, source.ip, destination.ip, network.protocol, network.transport, data_stream.dataset, _id, _version, _index
'''


[[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.subtechnique]]
id = "T1071.001"
name = "Web Protocols"
reference = "https://attack.mitre.org/techniques/T1071/001/"


[[rule.threat.technique]]
id = "T1568"
name = "Dynamic Resolution"
reference = "https://attack.mitre.org/techniques/T1568/"
[[rule.threat.technique.subtechnique]]
id = "T1568.002"
name = "Domain Generation Algorithms"
reference = "https://attack.mitre.org/techniques/T1568/002/"



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

Stages and Predicates

Stage 1: from

from packetbeat-*, filebeat-*, logs-network_traffic.*, logs-panw.panos* metadata _id, _version, _index

Stage 2: where

| where (
    data_stream.dataset in ("network_traffic.tls", "network_traffic.http") or
    (
      data_stream.dataset == "panw.panos" and
      network.application in ("ssl", "web-browsing") and network.transport == "tcp"
    ) or
    (event.category in ("network", "network_traffic") and network.protocol in ("tls", "http") and network.transport == "tcp")
  )

Stage 3: where

| where destination.domain RLIKE "[a-zA-Z]{4,5}\\.(pw|us|club|info|site|top)"

Stage 4: where

| where destination.domain != "zoom.us"

Stage 5: keep

| keep @timestamp, destination.domain, source.ip, destination.ip, network.protocol, network.transport, data_stream.dataset, _id, _version, _index

Indicators

These rows show field, operator, and value matches.

Output Fields

These fields are emitted when the rule matches.

FieldSource
@timestampKEEP @timestamp
destination.domainKEEP destination.domain
source.ipKEEP source.ip
destination.ipKEEP destination.ip
network.protocolKEEP network.protocol
network.transportKEEP network.transport
data_stream.datasetKEEP data_stream.dataset
_idKEEP _id
_versionKEEP _version
_indexKEEP _index

Potential Evasion via Boot Time Removal Tool

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

Identifies creation of a ":changelist" NTFS alternate data stream or a Windows service Args registry value pointing to a ":changelist" path. Microsoft Defender's Boot-Time Removal (BTR.sys) driver reads an RC4-encrypted transaction blob from a driver ADS named ":changelist", referenced by HKLM\SYSTEM*ControlSet*\Services*\Args. Adversaries can reproduce this staging outside Defender to abuse BTR.sys as a signed kernel primitive for arbitrary file and registry operations. This rule focuses on non-System writers and excludes Microsoft-signed MRT.exe running as SYSTEM, which may perform related remediation staging.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2026/08/21"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/08/21"

[rule]
author = ["Elastic"]
description = """
Identifies creation of a ":changelist" NTFS alternate data stream or a Windows service Args registry value pointing to
a ":changelist" path. Microsoft Defender's Boot-Time Removal (BTR.sys) driver reads an RC4-encrypted transaction blob
from a driver ADS named ":changelist", referenced by HKLM\\SYSTEM\\*ControlSet*\\Services\\*\\Args. Adversaries can
reproduce this staging outside Defender to abuse BTR.sys as a signed kernel primitive for arbitrary file and registry
operations. This rule focuses on non-System writers and excludes Microsoft-signed MRT.exe running as SYSTEM, which may
perform related remediation staging.
"""
from = "now-9m"
language = "esql"
license = "Elastic License v2"
name = "Potential Evasion via Boot Time Removal Tool"
note = """## Triage and analysis

### Investigating Potential Evasion via Boot Time Removal Tool

Windows Defender's Boot-Time Removal driver (`BTR.sys`) is instructed via an encrypted configuration stored in an
Alternate Data Stream named `:changelist` on a `.sys` image. The service `Args` value under
`HKLM\\SYSTEM\\*ControlSet*\\Services\\<name>\\Args` points at that ADS path. Check Point Research (BTR Reforged)
showed that the same staging can be performed by non-Defender tooling (for example BTR_CLI) to drive Ring-0 file and
registry actions, including neutralization of security products during early boot.

#### Possible investigation steps

- Identify whether the alert is a file ADS creation or a service `Args` registry write using `event.category`,
  `file.name` / `file.path`, and `registry.path` / `registry.data.strings`.
- Review `process.executable`, `process.name`, `process.pid`, `process.parent.executable`, and `user.id` to determine
  whether a Defender component, MRT, or an unexpected user-mode binary staged the `:changelist` artifact.
- For file events, inspect the base `.sys` path (strip `:changelist`), size, hash, and code signature. Confirm whether
  the driver was recently dropped under a user-writable path (Downloads, Temp, Desktop) versus a Defender-managed path.
- For registry events, note the service key name under `Services\\*` and check sibling values (`ImagePath`, `Type`,
  `Group`). Abuse tooling often sets `Group` to `Boot Bus Extender` and may create the service via direct registry
  writes / `NtLoadDriver` without a corresponding SCM service-install event (7045).
- Hunt on the same `host.id` for related activity: creation of `*.sys:*.dat` feedback ADS, load of a Microsoft-signed
  driver matching BTR, creation/deletion of `\\\\SystemRoot\\\\Temp\\\\BootClean.log` by PID 4, and deletions of security
  binaries attributed to System.
- Correlate with other alerts for the same `user.id` and `host.id` in the prior 48 hours for privilege escalation,
  driver load, or Defender tampering.

### False positive analysis

- Legitimate Defender or MRT reboot remediation may create `:changelist` ADS and related service Args values. This rule
  excludes PID 4 and Microsoft-signed `MRT.exe` as SYSTEM; unsigned or differently signed `MRT.exe` still alerts. Rare
  Defender paths (for example `MsMpEng.exe`) may still match and should be validated before exceptioning.
- Security research labs intentionally exercising BTR_CLI or similar PoCs will generate true-positive-looking events;
  confirm host cohort and change windows.

### Response and remediation

- If activity is unexplained: isolate the host, preserve the `.sys` file and `:changelist` stream, export the service
  registry key, and capture the staging process tree before cleanup.
- Search the estate for the same `file.name` / ADS pattern, service `Args` values containing `:changelist`, and related
  driver hashes.
- Remove unauthorized service keys and staged drivers, restore any deleted security components from known-good media,
  and rotate credentials for accounts that held `SeLoadDriverPrivilege` on the host.
- Restrict and monitor assignment/use of `SeLoadDriverPrivilege`; treat signed remediation drivers as LOLDrivers that
  require lineage and ADS context monitoring, not signature blocking alone.
"""

setup = """## Setup

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

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

references = [
    "https://research.checkpoint.com/2026/btr-reforged-weaponizing-defenders-remediation-driver-as-a-kernel-operation-primitive/",
    "https://github.com/Dump-GUY/BTR_CLI",
]
risk_score = 73
rule_id = "942c8f59-f01c-4dc0-a05f-2f5bba836ad8"
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Defense Evasion",
    "Tactic: Persistence",
    "Resources: Investigation Guide",
    "Data Source: Elastic Defend",
]
timestamp_override = "event.ingested"
type = "esql"

query = '''
from logs-endpoint.events.file-*, logs-endpoint.events.registry-* metadata _id, _version, _index
| where host.os.type == "windows"
  and process.pid != 4
  and not (
    user.id == "S-1-5-18"
    and to_lower(process.executable) like """?:\\windows\\system32\\mrt.exe"""
    and process.code_signature.subject_name in ("Microsoft Windows", "Microsoft Corporation") 
    and process.code_signature.trusted == true
  )
  and (
    (
      event.category == "file"
      and event.type == "creation"
      and ends_with(to_lower(file.name), ":changelist")
    )
    or (
      event.category == "registry"
      and event.type == "change"
      and to_lower(registry.path) like """*\\system\\*controlset*\\services\\*\\args"""
      and to_lower(registry.data.strings) like "*:changelist"
    )
  )
| keep
    @timestamp,
    host.id,
    host.name,
    user.id,
    user.name,
    process.pid,
    process.name,
    process.executable,
    process.code_signature.subject_name,
    event.category,
    event.type,
    file.path,
    file.name,
    file.size,
    registry.path,
    registry.value,
    registry.data.strings,
    data_stream.namespace,
    _id,
    _version,
    _index
| limit 100
'''

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "host.id",
    "host.name",
    "user.id",
    "user.name",
    "process.pid",
    "process.name",
    "process.executable",
    "process.code_signature.subject_name",
    "event.category",
    "file.path",
    "file.name",
    "file.size",
    "registry.path",
    "registry.value",
    "registry.data.strings",
]

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

[[rule.threat.technique]]
id = "T1564"
name = "Hide Artifacts"
reference = "https://attack.mitre.org/techniques/T1564/"

[[rule.threat.technique.subtechnique]]
id = "T1564.004"
name = "NTFS File Attributes"
reference = "https://attack.mitre.org/techniques/T1564/004/"

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

[[rule.threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"

[[rule.threat.technique.subtechnique]]
id = "T1562.001"
name = "Disable or Modify Tools"
reference = "https://attack.mitre.org/techniques/T1562/001/"

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

[[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.technique.subtechnique]]
id = "T1543.003"
name = "Windows Service"
reference = "https://attack.mitre.org/techniques/T1543/003/"

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

Stages and Predicates

Stage 1: from

from logs-endpoint.events.file-*, logs-endpoint.events.registry-* metadata _id, _version, _index

Stage 2: where

| where host.os.type == "windows"
  and process.pid != 4
  and not (
    user.id == "S-1-5-18"
    and to_lower(process.executable) like """?:\\windows\\system32\\mrt.exe"""
    and process.code_signature.subject_name in ("Microsoft Windows", "Microsoft Corporation") 
    and process.code_signature.trusted == true
  )
  and (
    (
      event.category == "file"
      and event.type == "creation"
      and ends_with(to_lower(file.name), ":changelist")
    )
    or (
      event.category == "registry"
      and event.type == "change"
      and to_lower(registry.path) like """*\\system\\*controlset*\\services\\*\\args"""
      and to_lower(registry.data.strings) like "*:changelist"
    )
  )

Stage 3: keep

| keep
    @timestamp,
    host.id,
    host.name,
    user.id,
    user.name,
    process.pid,
    process.name,
    process.executable,
    process.code_signature.subject_name,
    event.category,
    event.type,
    file.path,
    file.name,
    file.size,
    registry.path,
    registry.value,
    registry.data.strings,
    data_stream.namespace,
    _id,
    _version,
    _index

Stage 4: limit

| limit 100

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.categoryeq
  • file corpus 14 (elastic 14)
  • registry corpus 7 (elastic 7)
field:"event.category" kind:eq
event.typeeq
  • change corpus 89 (elastic 89)
  • creation corpus 48 (elastic 48)
field:"event.type" kind:eq
process.pidne
  • 4
field:"process_id" kind:ne value:"4"
to_lower(file.name)ends_with
  • :changelist
field:"to_lower(file.name)" kind:ends_with value:":changelist"

Exclusions

The rule actively suppresses these predicates.

Output Fields

These fields are emitted when the rule matches.

FieldSource
@timestampKEEP @timestamp
host.idKEEP host.id
host.nameKEEP host.name
user.idKEEP user.id
user.nameKEEP user.name
process.pidKEEP process.pid
process.nameKEEP process.name
process.executableKEEP process.executable
process.code_signature.subject_nameKEEP process.code_signature.subject_name
event.categoryKEEP event.category
event.typeKEEP event.type
file.pathKEEP file.path
file.nameKEEP file.name
file.sizeKEEP file.size
registry.pathKEEP registry.path
registry.valueKEEP registry.value
registry.data.stringsKEEP registry.data.strings
data_stream.namespaceKEEP data_stream.namespace
_idKEEP _id
_versionKEEP _version
_indexKEEP _index

Potential SYN-Based Port Scan Detected

#
Status
production
Severity
low
Time window
9m
Group by
destination.ip, source.ip
Author
Elastic
Source
github.com/elastic/detection-rules

This rule identifies a potential SYN-Based port scan. A SYN port scan is a technique employed by attackers to scan a target network for open ports by sending SYN packets to multiple ports and observing the response. Attackers use this method to identify potential entry points or services that may be vulnerable to exploitation, allowing them to launch targeted attacks or gain unauthorized access to the system or network, compromising its security and potentially leading to data breaches or further malicious activities. This rule defines a threshold-based approach to detect connection attempts from a single source to a large number of unique destination ports, while limiting the number of packets per port.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2023/05/17"
integration = ["network_traffic", "panw"]
maturity = "production"
updated_date = "2026/09/03"

[rule]
author = ["Elastic"]
description = """
This rule identifies a potential SYN-Based port scan. A SYN port scan is a technique employed by attackers to scan a
target network for open ports by sending SYN packets to multiple ports and observing the response. Attackers use this
method to identify potential entry points or services that may be vulnerable to exploitation, allowing them to launch
targeted attacks or gain unauthorized access to the system or network, compromising its security and potentially leading
to data breaches or further malicious activities. This rule defines a threshold-based approach to detect connection
attempts from a single source to a large number of unique destination ports, while limiting the number of packets per port.
"""
from = "now-9m"
index = ["logs-network_traffic.*", "packetbeat-*", "filebeat-*", "logs-panw.panos*"]
language = "kuery"
license = "Elastic License v2"
max_signals = 5
name = "Potential SYN-Based Port Scan Detected"
risk_score = 21
rule_id = "bbaa96b9-f36c-4898-ace2-581acb00a409"
severity = "low"
tags = [
    "Domain: Network",
    "Tactic: Discovery",
    "Tactic: Reconnaissance",
    "Use Case: Network Security Monitoring",
    "Data Source: PAN-OS",
    "Resources: Investigation Guide"
]
timestamp_override = "event.ingested"
type = "threshold"
query = '''
event.action:(network_flow or flow_started) and destination.port:* and network.packets <= 2 and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)
'''
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 SYN-Based Port Scan Detected

SYN-based port scanning is a reconnaissance technique where attackers send SYN packets to multiple ports to identify open services. This method helps adversaries map network vulnerabilities for potential exploitation. The detection rule identifies such scans by flagging connection attempts from internal IPs to multiple ports with minimal packet exchange, indicating a low-risk reconnaissance activity.

### Possible investigation steps

- Review the source IP address involved in the alert to determine if it belongs to a known or authorized device within the network. Check for any recent changes or unusual activity associated with this IP.
- Analyze the destination ports targeted by the scan to identify any patterns or specific services that may be of interest to the attacker. Determine if these ports are associated with critical or vulnerable services.
- Examine historical logs to identify any previous scanning activity from the same source IP or similar patterns of behavior. This can help establish whether the activity is part of a larger reconnaissance effort.
- Correlate the alert with other security events or alerts to assess if there is a broader attack campaign underway. Look for related alerts that might indicate subsequent exploitation attempts.
- Investigate the timing and frequency of the scan attempts to understand if they coincide with other suspicious activities or known attack windows. This can provide context on the attacker's intent and urgency.
- Assess the network's current security posture and ensure that appropriate defenses, such as firewalls and intrusion detection systems, are configured to mitigate potential exploitation of identified open ports.

### False positive analysis

- Internal network scanning tools or scripts used by IT teams for legitimate network mapping can trigger this rule. To manage this, create exceptions for known internal IP addresses or subnets used by IT for network discovery.
- Automated monitoring systems or security appliances that perform regular port checks might be flagged. Identify these systems and exclude their IP addresses from the rule to prevent false positives.
- Software updates or patch management systems that check multiple ports for service availability can be mistaken for a SYN-based port scan. Whitelist these systems to avoid unnecessary alerts.
- Load balancers or network devices that perform health checks across multiple ports may trigger the rule. Exclude these devices from the rule to ensure accurate detection.
- Development or testing environments where multiple port scans are part of routine operations can cause false positives. Implement exceptions for these environments to maintain focus on genuine threats.

### Response and remediation

- Isolate the affected internal IP address to prevent further reconnaissance or potential exploitation of identified open ports.
- Conduct a thorough review of firewall and network access control lists to ensure that only necessary ports are open and accessible from internal networks.
- Implement rate limiting on SYN packets to reduce the risk of successful port scanning and reconnaissance activities.
- Monitor the network for any unusual outbound traffic from the affected IP address, which may indicate further malicious activity or data exfiltration attempts.
- Escalate the incident to the security operations team for further analysis and to determine if additional network segments or systems are affected.
- Update intrusion detection and prevention systems to enhance detection capabilities for similar SYN-based port scanning activities.
- Review and update network segmentation policies to limit the exposure of critical services and systems to internal reconnaissance activities."""

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

[[rule.threat.technique]]
id = "T1046"
name = "Network Service Discovery"
reference = "https://attack.mitre.org/techniques/T1046/"

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

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

[[rule.threat.technique]]
id = "T1595"
name = "Active Scanning"
reference = "https://attack.mitre.org/techniques/T1595/"

[[rule.threat.technique.subtechnique]]
id = "T1595.001"
name = "Scanning IP Blocks"
reference = "https://attack.mitre.org/techniques/T1595/001/"

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

[rule.threshold]
field = ["destination.ip", "source.ip"]
value = 1

[[rule.threshold.cardinality]]
field = "destination.port"
value = 250

[rule.alert_suppression.duration]
unit = "h"
value = 1

Stages and Predicates

Stage 1: query

event.action:(network_flow or flow_started) and destination.port:* and network.packets <= 2 and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)
Threshold
gte 1
Cardinality
destination.port ≥ 250

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
destination.portis_not_null
  • (no value, null check)
field:"DestinationPort" kind:is_not_null
event.actionin
  • flow_started
  • network_flow
field:"EventType" kind:in
network.packetsle
  • 2
field:"network.packets" kind:le value:"2"
source.ipin
  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.168.0.0/16
field:"src_ip" kind:in

Rare AWS Error Code

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

A machine learning job detected an unusual error in a CloudTrail message. These can be byproducts of attempted or successful persistence, privilege escalation, defense evasion, discovery, lateral movement, or collection.

Known False Positives

  • Rare and unusual errors may indicate an impending service failure state. Rare and unusual user error activity can also be due to manual troubleshooting or reconfiguration attempts by insufficiently privileged users, bugs in cloud automation scripts or workflows, or changes to IAM privileges.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2020/07/13"
integration = ["aws"]
maturity = "production"
updated_date = "2025/11/18"

[rule]
anomaly_threshold = 50
author = ["Elastic"]
description = """
A machine learning job detected an unusual error in a CloudTrail message. These can be byproducts of attempted or
successful persistence, privilege escalation, defense evasion, discovery, lateral movement, or collection.
"""
false_positives = [
    """
    Rare and unusual errors may indicate an impending service failure state. Rare and unusual user error activity can
    also be due to manual troubleshooting or reconfiguration attempts by insufficiently privileged users, bugs in cloud
    automation scripts or workflows, or changes to IAM privileges.
    """,
]
from = "now-2h"
interval = "15m"
license = "Elastic License v2"
machine_learning_job_id = "rare_error_code"
name = "Rare AWS Error Code"
setup = """## Setup

This rule requires the installation of associated Machine Learning jobs, as well as data coming in from AWS.

### Anomaly Detection Setup

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

### AWS Integration Setup
The AWS integration allows you to collect logs and metrics from Amazon Web Services (AWS) with Elastic Agent.

#### The following steps should be executed in order to add the Elastic Agent System integration "aws" to your system:
- Go to the Kibana home page and click “Add integrations”.
- In the query bar, search for “AWS” and select the integration to see more details about it.
- Click “Add AWS”.
- Configure the integration name and optionally add a description.
- Review optional and advanced settings accordingly.
- Add the newly installed “aws” to an existing or a new agent policy, and deploy the agent on your system from which aws log files are desirable.
- Click “Save and Continue”.
- For more details on the integration refer to the [helper guide](https://www.elastic.co/docs/current/integrations/aws).
"""
note = """## Triage and analysis

### Investigating Rare AWS Error Code

CloudTrail logging provides visibility on actions taken within an AWS environment. By monitoring these events and understanding what is considered normal behavior within an organization, you can spot suspicious or malicious activity when deviations occur.

This rule uses a machine learning job to detect an unusual error in a CloudTrail message. This can be byproducts of attempted or successful persistence, privilege escalation, defense evasion, discovery, lateral movement, or collection.

Detection alerts from this rule indicate a rare and unusual error code that was associated with the response to an AWS API command or method call.

#### Possible investigation steps

- Examine the history of the error. If the error only manifested recently, it might be related to recent changes in an automation module or script. You can find the error in the `aws.cloudtrail.error_code field` field.
- Investigate other alerts associated with the user account during the past 48 hours.
- Validate the activity is not related to planned patches, updates, or network administrator activity.
- Examine the request parameters. These may indicate the source of the program or the nature of the task being performed when the error occurred.
    - Check whether the error is related to unsuccessful attempts to enumerate or access objects, data, or secrets.
- Considering the source IP address and geolocation of the user who issued the command:
    - Do they look normal for the calling user?
    - If the source is an EC2 IP address, is it associated with an EC2 instance in one of your accounts or is the source IP from an EC2 instance that's not under your control?
    - If it is an authorized EC2 instance, is the activity associated with normal behavior for the instance role or roles? Are there any other alerts or signs of suspicious activity involving this instance?
- Consider the time of day. If the user is a human (not a program or script), did the activity take place during a normal time of day?
- Contact the account owner and confirm whether they are aware of this activity if suspicious.
- If you suspect the account has been compromised, scope potentially compromised assets by tracking servers, services, and data accessed by the account in the last 24 hours.

### False positive analysis

- Examine the history of the command. If the command only manifested recently, it might be part of a new automation module or script. If it has a consistent cadence (for example, it appears in small numbers on a weekly or monthly cadence), it might be part of a housekeeping or maintenance process. You can find the command in the `event.action field` field.
- The adoption of new services or the addition of new functionality to scripts may generate false positives.

### Related Rules

- Unusual City For an AWS Command - 809b70d3-e2c3-455e-af1b-2626a5a1a276
- Unusual Country For an AWS Command - dca28dee-c999-400f-b640-50a081cc0fd1
- Unusual AWS Command for a User - ac706eae-d5ec-4b14-b4fd-e8ba8086f0e1
- Spike in AWS Error Messages - 78d3d8d9-b476-451d-a9e0-7a5addd70670

### Response and remediation

- Initiate the incident response process based on the outcome of the triage.
- Disable or limit the account during the investigation and response.
- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context:
    - Identify the account role in the cloud environment.
    - Assess the criticality of affected services and servers.
    - Work with your IT team to identify and minimize the impact on users.
    - Identify if the attacker is moving laterally and compromising other accounts, servers, or services.
    - Identify any regulatory or legal ramifications related to this activity.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords or delete API keys as needed to revoke the attacker's access to the environment. Work with your IT teams to minimize the impact on business operations during these actions.
- Check if unauthorized new users were created, remove unauthorized new accounts, and request password resets for other IAM users.
- Consider enabling multi-factor authentication for users.
- Review the permissions assigned to the implicated user to ensure that the least privilege principle is being followed.
- Implement security best practices [outlined](https://aws.amazon.com/premiumsupport/knowledge-center/security-best-practices/) by AWS.
- Take the actions needed to return affected systems, data, or services to their normal operational levels.
- Identify the initial vector abused by the attacker and take action to prevent reinfection via the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
references = ["https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html"]
risk_score = 21
rule_id = "19de8096-e2b0-4bd8-80c9-34a820813fff"
severity = "low"
tags = [
    "Domain: Cloud",
    "Data Source: AWS",
    "Data Source: Amazon Web Services",
    "Rule Type: ML",
    "Rule Type: Machine Learning",
    "Resources: Investigation Guide",
]
type = "machine_learning"

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

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

[[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]]
framework = "MITRE ATT&CK"

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

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

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

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

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

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

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

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

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

Suspicious Execution from MSSQL Service

#
Source
github.com/elastic/protections-artifacts

Identifies the execution of suspicious processes from the Windows MSSQL service, this may indicate the use of MSSQL stored procedures such as xp_cmdshell or the exploitation of SQL injection vulnerabilities to execute malicious commands on the host Operating System.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the execution of suspicious processes from the Windows MSSQL service, this may indicate the use of MSSQL
stored procedures such as xp_cmdshell or the exploitation of SQL injection vulnerabilities to execute malicious commands
on the host Operating System.
"""
id = "547636af-cad2-4be0-a74e-613c7bb86664"
license = "Elastic License v2"
name = "Suspicious Execution from MSSQL Service"
os_list = ["windows"]
version = "1.0.29"

query = '''
process where event.action == "start" and
(
  /* registry or xp_cmdshell stored procedures */
 (process.parent.name : "sqlservr.exe" and
  process.pe.original_file_name in ("cmd.exe", "PowerShell.EXE", "reg.exe")) or

  /* descendant of cmd or powershell */
  (descendant of [process where event.action == "start" and process.pe.original_file_name in ("cmd.exe", "PowerShell.EXE") and
   process.parent.name : "sqlservr.exe"] and not process.executable : "?:\\Windows\\System32\\conhost.exe") or

   /* unsigned child of sqlserv */
  (process.parent.name : "sqlservr.exe" and process.code_signature.trusted != true and
   not process.executable : ("?:\\Program Files\\*.exe", "?:\\Program Files (x86)\\*.exe") and
   process.code_signature.status != "errorChaining" and
   not process.hash.sha256 : "1a9adfd83a88d80377d9060c7e2857964bf24974eae13447678cedca7da3dba8") or

   (process.parent.name : "sqlservr.exe" and (process.name : "vpnbridge.exe" or process.pe.original_file_name : "vpnbridge.exe")) or

   (process.parent.name : "sqlservr.exe" and
    (process.name : "certutil.exe" or process.pe.original_file_name == "CertUtil.exe") and process.args : "-urlcache") or

   (process.parent.name : "sqlservr.exe" and
    (process.name : "bitsadmin.exe" or process.pe.original_file_name : "bitsadmin.exe") and
    process.command_line : ("*download*", "*transfer*", "*create*", "*addfile*", "*SetNotifyCmdLine*"))
) and
not process.executable :
              ("\\Device\\HarddiskVolume?\\MSSQL12.ITSM\\MSSQL\\Binn\\DatabaseMail.exe",
               "\\Device\\HarddiskVolume?\\MSSQL13.GP\\MSSQL\\Binn\\DatabaseMail.exe",
               "\\Device\\HarddiskVolume?\\MSSQL13.MSSQLSERVER\\MSSQL\\Binn\\DatabaseMail.exe",
               "S:\\MSSQL\\MSSQL13.MSSQLSERVER\\MSSQL\\Binn\\slssqlmaint.exe")
'''

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

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

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



[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.parent.name : "sqlservr.exe" and
  process.pe.original_file_name in ("cmd.exe", "PowerShell.EXE", "reg.exe")) or
  (descendant of [process where event.action == "start" and process.pe.original_file_name in ("cmd.exe", "PowerShell.EXE") and
   process.parent.name : "sqlservr.exe"] and not process.executable : "?:\\Windows\\System32\\conhost.exe") or
  (process.parent.name : "sqlservr.exe" and process.code_signature.trusted != true and
   not process.executable : ("?:\\Program Files\\*.exe", "?:\\Program Files (x86)\\*.exe") and
   process.code_signature.status != "errorChaining" and
   not process.hash.sha256 : "1a9adfd83a88d80377d9060c7e2857964bf24974eae13447678cedca7da3dba8") or
   (process.parent.name : "sqlservr.exe" and (process.name : "vpnbridge.exe" or process.pe.original_file_name : "vpnbridge.exe")) or
   (process.parent.name : "sqlservr.exe" and
    (process.name : "certutil.exe" or process.pe.original_file_name == "CertUtil.exe") and process.args : "-urlcache") or
   (process.parent.name : "sqlservr.exe" and
    (process.name : "bitsadmin.exe" or process.pe.original_file_name : "bitsadmin.exe") and
    process.command_line : ("*download*", "*transfer*", "*create*", "*addfile*", "*SetNotifyCmdLine*"))
) and
not process.executable :
              ("\\Device\\HarddiskVolume?\\MSSQL12.ITSM\\MSSQL\\Binn\\DatabaseMail.exe",
               "\\Device\\HarddiskVolume?\\MSSQL13.GP\\MSSQL\\Binn\\DatabaseMail.exe",
               "\\Device\\HarddiskVolume?\\MSSQL13.MSSQLSERVER\\MSSQL\\Binn\\DatabaseMail.exe",
               "S:\\MSSQL\\MSSQL13.MSSQLSERVER\\MSSQL\\Binn\\slssqlmaint.exe")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq value:"start"
process.argswildcard
  • -urlcache corpus 3 (elastic 3)
field:"process.args" kind:wildcard value:"-urlcache"
process.code_signature.statusne
  • errorChaining
field:"SignatureStatus" kind:ne value:"errorChaining"
process.code_signature.trustedne
  • true transforms: boolean corpus 8 (elastic 8)
field:"process.code_signature.trusted" kind:ne value:"true"
process.command_linewildcard
  • *SetNotifyCmdLine* corpus 2 (elastic 2)
  • *addfile* corpus 2 (elastic 2)
  • *create* corpus 29 (sigma 17, splunk 7, elastic 5)
  • *download* corpus 4 (elastic 3, sigma 1)
  • *transfer* corpus 3 (elastic 3)
field:"CommandLine" kind:wildcard
process.namewildcard
  • bitsadmin.exe corpus 25 (elastic 22, splunk 2, kusto 1)
  • certutil.exe corpus 45 (elastic 39, splunk 6)
  • vpnbridge.exe
field:"process_basename" kind:wildcard
process.parent.namewildcard
  • sqlservr.exe corpus 3 (elastic 2, splunk 1)
field:"parent_process_basename" kind:wildcard value:"sqlservr.exe"
process.pe.original_file_nameeq
  • CertUtil.exe corpus 5 (elastic 5)
field:"OriginalFileName" kind:eq value:"CertUtil.exe"
process.pe.original_file_namein
  • PowerShell.EXE corpus 19 (elastic 19)
  • cmd.exe
  • reg.exe corpus 3 (elastic 3)
field:"OriginalFileName" kind:in
process.pe.original_file_namewildcard
  • bitsadmin.exe corpus 19 (sigma 9, elastic 8, splunk 2)
  • vpnbridge.exe
field:"OriginalFileName" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.executableeq\Device\HarddiskVolume?\MSSQL12.ITSM\MSSQL\Binn\DatabaseMail.exe, \Device\HarddiskVolume?\MSSQL13.GP\MSSQL\Binn\DatabaseMail.exe, \Device\HarddiskVolume?\MSSQL13.MSSQLSERVER\MSSQL\Binn\DatabaseMail.exe, S:\MSSQL\MSSQL13.MSSQLSERVER\MSSQL\Binn\slssqlmaint.exeexcludes:process.executable

Suspicious Network Connection to Gmail via Nodejs

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

Detects when the Node binary makes an outbound network connection to Gmails SMTP servers. Malicious NPM packages have been seen using Gmail SMTP servers to exfiltrate sensitive data.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[rule]
description = """
Detects when the Node binary makes an outbound network connection to Gmails SMTP servers. Malicious NPM packages have
been seen using Gmail SMTP servers to exfiltrate sensitive data.
"""
id = "d8135e78-d8fa-4ce0-93fe-73c2af058dbd"
license = "Elastic License v2"
name = "Suspicious Network Connection to Gmail via Nodejs"
os_list = ["macos"]
reference = [
    "https://socket.dev/blog/gmail-for-exfiltration-malicious-npm-packages-target-solana-private-keys-and-drain-victim-s",
]
version = "1.0.3"

query = '''
sequence by process.entity_id with maxspan=1m
[process where event.type == "start" and event.action == "exec" and process.name == "node"]
[network where event.type == "start" and destination.domain in ("smtp.gmail.com", "smtp.gmail.com.")]
'''

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 = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"



[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"
[[threat.technique.subtechnique]]
id = "T1071.003"
name = "Mail Protocols"
reference = "https://attack.mitre.org/techniques/T1071/003/"



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

[internal]
min_endpoint_version = "8.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"]

Stage 2: network

[network where event.type == "start" and destination.domain in ("smtp.gmail.com", "smtp.gmail.com.")]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
destination.domainin
  • smtp.gmail.com
  • smtp.gmail.com.
field:"DestinationHostname" kind:in
event.actioneq
  • exec corpus 547 (elastic 547)
field:"EventType" kind:eq value:"exec"
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.nameeq
  • node corpus 17 (elastic 17)
field:"process_basename" kind:eq value:"node"

Suspicious TruffleHog Execution via NodeJS

#
Source
github.com/elastic/protections-artifacts

This rule detects the execution of TruffleHog from a JavaScript interpreter, TruffleHog is a tool used to search for high-entropy strings and secrets in code repositories, which may indicate an attempt to access credentials. This tool was abused by the Shai-Hulud worm to search for credentials in code repositories.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[rule]
description = """
This rule detects the execution of TruffleHog from a JavaScript interpreter, TruffleHog is a tool used to search for
high-entropy strings and secrets in code repositories, which may indicate an attempt to access credentials. This tool
was abused by the Shai-Hulud worm to search for credentials in code repositories.
"""
id = "0f46cf1b-2c9f-4d56-8073-08b41bac72b4"
license = "Elastic License v2"
name = "Suspicious TruffleHog Execution via NodeJS"
os_list = ["macos"]
reference = [
    "https://www.elastic.co/blog/shai-hulud-worm-npm-supply-chain-compromise",
    "https://socket.dev/blog/shai-hulud-strikes-again-v2",
]
version = "1.0.1"

query = '''
process where event.action in ("start", "exec") and
 (
  (process.name in ("trufflehog", "trufflehog.exe") and process.args == "filesystem") or
  (process.args == "--json" and process.args == "filesystem")
  ) and
 (
  process.parent.name in ("node.exe", "node", "bun", "bun.exe") or
  process.working_directory like "*node_modules*"
 )
'''

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "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/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1555"
name = "Credentials from Password Stores"
reference = "https://attack.mitre.org/techniques/T1555/"


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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Stage 1: process

process where event.action in ("start", "exec") and
 (
  (process.name in ("trufflehog", "trufflehog.exe") and process.args == "filesystem") or
  (process.args == "--json" and process.args == "filesystem")
  ) and
 (
  process.parent.name in ("node.exe", "node", "bun", "bun.exe") or
  process.working_directory like "*node_modules*"
 )

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actionin
  • exec corpus 180 (elastic 180)
  • start corpus 157 (elastic 157)
field:"EventType" kind:in
process.argseq
  • --json corpus 3 (elastic 3)
  • filesystem corpus 3 (elastic 3)
field:"process.args" kind:eq
process.namein
  • trufflehog corpus 2 (elastic 2)
  • trufflehog.exe corpus 2 (elastic 2)
field:"process_basename" kind:in
process.parent.namein
  • bun corpus 7 (elastic 7)
  • bun.exe corpus 6 (elastic 6)
  • node corpus 14 (elastic 14)
  • node.exe corpus 8 (elastic 8)
field:"parent_process_basename" kind:in
process.working_directorywildcard
  • *node_modules* corpus 2 (elastic 2)
field:"CurrentDirectory" kind:wildcard value:"*node_modules*"

User Account Creation

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

Identifies attempts to create new users. This is sometimes done by attackers to increase access or establish persistence on a system or domain.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2020/02/18"
integration = ["endpoint", "windows", "system", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/05/04"

[rule]
author = ["Elastic"]
description = """
Identifies attempts to create new users. This is sometimes done by attackers to increase access or establish persistence
on a system or domain.
"""
from = "now-9m"
index = [
    "endgame-*",
    "logs-crowdstrike.fdr*",
    "logs-endpoint.events.process-*",
    "logs-m365_defender.event-*",
    "logs-sentinel_one_cloud_funnel.*",
    "logs-system.security*",
    "logs-windows.forwarded*",
    "logs-windows.sysmon_operational-*",
    "winlogbeat-*",
]
language = "eql"
license = "Elastic License v2"
name = "User Account Creation"
note = """## Triage and analysis

### Investigating User Account Creation

Attackers may create new accounts (both local and domain) to maintain access to victim systems.

This rule identifies the usage of `net.exe` to create new accounts.

#### 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.
- Identify the user account that performed the action and whether it should perform this kind of action.
- Identify if the account was added to privileged groups or assigned special privileges after creation.
- Investigate other alerts associated with the user/host during the past 48 hours.

### False positive analysis

- Account creation is a common administrative task, so there is a high chance of the activity being legitimate. Before investigating further, verify that this activity is not benign.

### Related rules

- Creation of a Hidden Local User Account - 2edc8076-291e-41e9-81e4-e3fcbc97ae5e
- Windows User Account Creation - 38e17753-f581-4644-84da-0d60a8318694

### 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.
- Delete the created account.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""

setup = """## Setup

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

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

### Additional data sources

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

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

risk_score = 21
rule_id = "1aa9181a-492b-4c01-8b16-fa0735786b2b"
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Persistence",
    "Resources: Investigation Guide",
    "Data Source: Elastic Endgame",
    "Data Source: Elastic Defend",
    "Data Source: Windows Security Event Logs",
    "Data Source: Microsoft Defender XDR",
    "Data Source: Sysmon",
    "Data Source: SentinelOne",
    "Data Source: Crowdstrike",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
process where host.os.type == "windows" and event.type == "start" and
  (process.name : ("net.exe", "net1.exe") and not process.parent.name : "net.exe") and
  (process.args : "user" and process.args : ("/ad", "/add"))
'''


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

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

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

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

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

Stages and Predicates

Stage 1: process

process where host.os.type == "windows" and event.type == "start" and
  (process.name : ("net.exe", "net1.exe") and not process.parent.name : "net.exe") and
  (process.args : "user" and process.args : ("/ad", "/add"))

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.argswildcard
  • /ad
  • /add corpus 2 (elastic 2)
  • user corpus 4 (elastic 4)
field:"process.args" kind:wildcard
process.namewildcard
  • net.exe corpus 30 (elastic 27, splunk 2, kusto 1)
  • net1.exe corpus 40 (elastic 21, splunk 19)
field:"process_basename" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.parent.nameeqnet.exeexcludes:process.parent.name field:"process.parent.name" value:"net.exe"

Windows API via a CallBack Function

#
Source
github.com/elastic/protections-artifacts

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

MITRE ATT&CK Coverage

TacticTechniques
Stealth

Rule Body

[rule]
description = """
Identifies the call of Memory Windows APIs indirectly via a callback function. This may be the result of an evasion
attempt to hide the origin of the API call from the call stack such as unbacked memory region.
"""
id = "8a8daa15-eed0-4bf0-85b5-ada73b55ab05"
license = "Elastic License v2"
name = "Windows API via a CallBack Function"
os_list = ["windows"]
reference = ["https://www.elastic.co/security-labs/doubling-down-etw-callstacks"]
version = "1.0.24"

query = '''
api where process.executable != null and
 (
  (process.Ext.api.behaviors == "proxy_call" and
   process.Ext.api.name in ("VirtualAlloc", "VirtualProtect", "WriteProcessMemory", "VirtualProtectEx", "VirtualAllocEx",
                            "MapViewOfFile", "MapViewOfFile2", "SuspendThread", "ReadProcessMemory") and
   process.thread.Ext.call_stack_summary in ("ntdll.dll|kernelbase.dll|ntdll.dll|kernel32.dll|ntdll.dll", "ntdll.dll|kernel32.dll|ntdll.dll") and
   process.thread.Ext.call_stack_final_user_module.name in ("ntdll.dll", "Undetermined") and
   _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info : ("*TpReleaseCleanupGroupMembers*", "*ntdll.dll!RtlDeregisterWaitEx*"))) or

  (process.Ext.api.name == "SetThreadContext" and process.thread.Ext.call_stack_summary in ("ntdll.dll|kernelbase.dll|ntdll.dll|kernel32.dll|ntdll.dll", "ntdll.dll|kernel32.dll|ntdll.dll") and
   process.thread.Ext.call_stack_final_user_module.name in ("ntdll.dll", "Undetermined")) or

  (process.Ext.api.behaviors == "proxy_call" and
   process.Ext.api.name in ("VirtualProtect", "VirtualAlloc", "WriteProcessMemory", "VirtualProtectEx", "VirtualAllocEx", "SuspendThread") and
   process.thread.Ext.call_stack_summary == "ntdll.dll|kernelbase.dll|ntdll.dll|kernel32.dll|ntdll.dll" and
   process.thread.Ext.call_stack_final_user_module.name == "Undetermined") and
   not _arraysearch(process.thread.Ext.call_stack, $entry,
                    $entry.symbol_info : ("c:\\windows\\system32\\ntdll.dll!KiUserApcDispatcher*",
                                          "c:\\windows\\system32\\ntdll.dll!LdrShutdownThread*",
                                          "c:\\windows\\system32\\kernelbase.dll!GetFinalPathNameByHandleW*",
                                          "c:\\windows\\system32\\kernelbase.dll!LoadLibrary*"))
 ) and
 not _arraysearch(process.thread.Ext.call_stack, $entry,
                  $entry.symbol_info : ("*\\jhooksatellite.dll!*",
                                        "*ntdll.dll!qsort*",
                                        "*kernelbase.dll!AppXLookupMoniker*",
                                        "*ntdll.dll!RtlCaptureStackContext*",
                                        "*ntdll.dll!LdrSystemDllInitBlock*",
                                        "*kernelbase.dll!CheckIsMSIXPackage*",
                                        "*rpcrt4.dll!NdrSendReceive*",
                                        "*ntdll.dll!RtlSetThreadWorkOnBehalfTicket*",
                                        "*ntdll.dll!RtlPcToFileHeader*",
                                        "?:\\program files*\\remote desktop\\rdclientax.dll!DllDeleteSavedCreds*",
                                        "c:\\windows\\system32\\ntdll.dll!NtUpdateWnfStateData+*",
                                        "*ntdll.dll!*RtlUnlockHeap*", "*ntdll.dll+0x*", "*kernelbase.dll!AppXUpdatePackageCapabilities*"))
'''

min_endpoint_version = "8.10.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.10.0"

Stages and Predicates

Stage 1: api

api where process.executable != null and
 (
  (process.Ext.api.behaviors == "proxy_call" and
   process.Ext.api.name in ("VirtualAlloc", "VirtualProtect", "WriteProcessMemory", "VirtualProtectEx", "VirtualAllocEx",
                            "MapViewOfFile", "MapViewOfFile2", "SuspendThread", "ReadProcessMemory") and
   process.thread.Ext.call_stack_summary in ("ntdll.dll|kernelbase.dll|ntdll.dll|kernel32.dll|ntdll.dll", "ntdll.dll|kernel32.dll|ntdll.dll") and
   process.thread.Ext.call_stack_final_user_module.name in ("ntdll.dll", "Undetermined") and
   _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info : ("*TpReleaseCleanupGroupMembers*", "*ntdll.dll!RtlDeregisterWaitEx*"))) or

  (process.Ext.api.name == "SetThreadContext" and process.thread.Ext.call_stack_summary in ("ntdll.dll|kernelbase.dll|ntdll.dll|kernel32.dll|ntdll.dll", "ntdll.dll|kernel32.dll|ntdll.dll") and
   process.thread.Ext.call_stack_final_user_module.name in ("ntdll.dll", "Undetermined")) or

  (process.Ext.api.behaviors == "proxy_call" and
   process.Ext.api.name in ("VirtualProtect", "VirtualAlloc", "WriteProcessMemory", "VirtualProtectEx", "VirtualAllocEx", "SuspendThread") and
   process.thread.Ext.call_stack_summary == "ntdll.dll|kernelbase.dll|ntdll.dll|kernel32.dll|ntdll.dll" and
   process.thread.Ext.call_stack_final_user_module.name == "Undetermined") and
   not _arraysearch(process.thread.Ext.call_stack, $entry,
                    $entry.symbol_info : ("c:\\windows\\system32\\ntdll.dll!KiUserApcDispatcher*",
                                          "c:\\windows\\system32\\ntdll.dll!LdrShutdownThread*",
                                          "c:\\windows\\system32\\kernelbase.dll!GetFinalPathNameByHandleW*",
                                          "c:\\windows\\system32\\kernelbase.dll!LoadLibrary*"))
 ) and
 not _arraysearch(process.thread.Ext.call_stack, $entry,
                  $entry.symbol_info : ("*\\jhooksatellite.dll!*",
                                        "*ntdll.dll!qsort*",
                                        "*kernelbase.dll!AppXLookupMoniker*",
                                        "*ntdll.dll!RtlCaptureStackContext*",
                                        "*ntdll.dll!LdrSystemDllInitBlock*",
                                        "*kernelbase.dll!CheckIsMSIXPackage*",
                                        "*rpcrt4.dll!NdrSendReceive*",
                                        "*ntdll.dll!RtlSetThreadWorkOnBehalfTicket*",
                                        "*ntdll.dll!RtlPcToFileHeader*",
                                        "?:\\program files*\\remote desktop\\rdclientax.dll!DllDeleteSavedCreds*",
                                        "c:\\windows\\system32\\ntdll.dll!NtUpdateWnfStateData+*",
                                        "*ntdll.dll!*RtlUnlockHeap*", "*ntdll.dll+0x*", "*kernelbase.dll!AppXUpdatePackageCapabilities*"))

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
process.Ext.api.behaviorseq
  • proxy_call corpus 4 (elastic 4)
field:"process.Ext.api.behaviors" kind:eq value:"proxy_call"
process.Ext.api.nameeq
  • SetThreadContext corpus 4 (elastic 4)
field:"process.Ext.api.name" kind:eq value:"SetThreadContext"
process.Ext.api.namein
  • MapViewOfFile corpus 24 (elastic 24)
  • MapViewOfFile2 corpus 24 (elastic 24)
  • ReadProcessMemory corpus 9 (elastic 9)
  • SuspendThread corpus 12 (elastic 12)
  • VirtualAlloc corpus 27 (elastic 27)
  • VirtualAllocEx corpus 22 (elastic 22)
  • VirtualProtect corpus 35 (elastic 35)
  • VirtualProtectEx corpus 29 (elastic 29)
  • WriteProcessMemory corpus 23 (elastic 23)
field:"process.Ext.api.name" kind:in
process.executableis_not_null
  • (no value, null check)
field:"Image" kind:is_not_null
process.thread.Ext.call_stack_final_user_module.nameeq
  • Undetermined corpus 4 (elastic 4)
field:"process.thread.Ext.call_stack_final_user_module.name" kind:eq value:"Undetermined"
process.thread.Ext.call_stack_final_user_module.namein
  • Undetermined corpus 2 (elastic 2)
  • ntdll.dll
field:"process.thread.Ext.call_stack_final_user_module.name" kind:in
process.thread.Ext.call_stack_summaryeq
  • ntdll.dll|kernelbase.dll|ntdll.dll|kernel32.dll|ntdll.dll
field:"process.thread.Ext.call_stack_summary" kind:eq value:"ntdll.dll|kernelbase.dll|ntdll.dll|kernel32.dll|ntdll.dll"
process.thread.Ext.call_stack_summaryin
  • ntdll.dll|kernel32.dll|ntdll.dll
  • ntdll.dll|kernelbase.dll|ntdll.dll|kernel32.dll|ntdll.dll corpus 4 (elastic 4)
field:"process.thread.Ext.call_stack_summary" kind:in

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.thread.Ext.call_stackarray_any(no value, null check)excludes:process.thread.Ext.call_stack

WMI Image Load via Microsoft Office

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

Identifies a suspicious image load (wmiutils.dll) from Microsoft Office processes followed by a child process spawned via Windows Management Instrumentation (WMI). This behavior may indicate adversarial activity to avoid spawning a suspicious MS Office child process.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies a suspicious image load (wmiutils.dll) from Microsoft Office processes followed by a child process spawned
via Windows Management Instrumentation (WMI). This behavior may indicate adversarial activity to avoid spawning a
suspicious MS Office child process.
"""
id = "46952f58-6741-4280-8e74-fa43f63c9604"
license = "Elastic License v2"
name = "WMI Image Load via Microsoft Office"
os_list = ["windows"]
reference = [
    "https://medium.com/threatpunter/detecting-adversary-tradecraft-with-image-load-event-logging-and-eql-8de93338c16",
]
version = "1.0.31"

query = '''
sequence by user.id with maxspan=30s
    [library where dll.name : ("wmiutils.dll", "fastprox.dll", "wbemprox.dll") and 
     process.name : ("excel.exe", "powerpnt.exe", "winword.exe")]
    [process where event.action == "start" and
     process.parent.name : "wmiprvse.exe" and
     not process.Ext.token.integrity_level_name == "system" and
     (process.pe.original_file_name :
        (
          "cscript.exe",
          "wscript.exe",
          "PowerShell.EXE",
          "Cmd.Exe",
          "pwsh.exe",
          "bitsadmin.exe",
          "certutil.exe",
          "hh.exe",
          "MSHTA.EXE",
          "RUNDLL32.EXE",
          "REGSVR32.EXE",
          "MSBuild.exe",
          "InstallUtil.exe",
          "RegAsm.exe",
          "RegSvcs.exe",
          "msxsl.exe",
          "CONTROL.EXE",
          "EXPLORER.EXE",
          "Microsoft.Workflow.Compiler.exe",
          "msiexec.exe",
          "sc.exe",
          "schtasks.exe",
          "WMIC.exe",
          "curl.exe"
        ) or
      process.executable : ("?:\\Users\\*.exe", "?:\\ProgramData\\*.exe")
     ) and
     not (process.name : "powershell.exe" and process.command_line : "*\\windows\\CCM\\*")

    ]
'''

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1566"
name = "Phishing"
reference = "https://attack.mitre.org/techniques/T1566/"
[[threat.technique.subtechnique]]
id = "T1566.001"
name = "Spearphishing Attachment"
reference = "https://attack.mitre.org/techniques/T1566/001/"



[threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1047"
name = "Windows Management Instrumentation"
reference = "https://attack.mitre.org/techniques/T1047/"


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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

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

Stage 1: library

[library where dll.name : ("wmiutils.dll", "fastprox.dll", "wbemprox.dll") and 
     process.name : ("excel.exe", "powerpnt.exe", "winword.exe")]

Stage 2: process

[process where event.action == "start" and
     process.parent.name : "wmiprvse.exe" and
     not process.Ext.token.integrity_level_name == "system" and
     (process.pe.original_file_name :
        (
          "cscript.exe",
          "wscript.exe",
          "PowerShell.EXE",
          "Cmd.Exe",
          "pwsh.exe",
          "bitsadmin.exe",
          "certutil.exe",
          "hh.exe",
          "MSHTA.EXE",
          "RUNDLL32.EXE",
          "REGSVR32.EXE",
          "MSBuild.exe",
          "InstallUtil.exe",
          "RegAsm.exe",
          "RegSvcs.exe",
          "msxsl.exe",
          "CONTROL.EXE",
          "EXPLORER.EXE",
          "Microsoft.Workflow.Compiler.exe",
          "msiexec.exe",
          "sc.exe",
          "schtasks.exe",
          "WMIC.exe",
          "curl.exe"
        ) or
      process.executable : ("?:\\Users\\*.exe", "?:\\ProgramData\\*.exe")
     ) and
     not (process.name : "powershell.exe" and process.command_line : "*\\windows\\CCM\\*")

    ]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
dll.namewildcard
  • fastprox.dll
  • wbemprox.dll corpus 2 (elastic 2)
  • wmiutils.dll corpus 6 (elastic 6)
field:"dll.name" kind:wildcard
event.actioneq
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq value:"start"
process.executablewildcard
  • ?:\ProgramData\*.exe corpus 9 (elastic 9)
  • ?:\Users\*.exe corpus 6 (elastic 6)
field:"Image" kind:wildcard
process.namewildcard
  • excel.exe corpus 34 (elastic 34)
  • powerpnt.exe corpus 31 (elastic 31)
  • winword.exe corpus 35 (elastic 35)
field:"process_basename" kind:wildcard
process.parent.namewildcard
  • wmiprvse.exe corpus 24 (elastic 19, splunk 5)
field:"parent_process_basename" kind:wildcard value:"wmiprvse.exe"
process.pe.original_file_namewildcard
  • CONTROL.EXE corpus 3 (elastic 2, splunk 1)
  • Cmd.Exe corpus 75 (sigma 43, splunk 17, elastic 15)
  • EXPLORER.EXE corpus 4 (elastic 3, splunk 1)
  • InstallUtil.exe corpus 19 (elastic 9, sigma 6, splunk 4)
  • MSBuild.exe corpus 16 (elastic 11, splunk 4, sigma 1)
  • MSHTA.EXE corpus 40 (elastic 21, sigma 13, splunk 6)
  • Microsoft.Workflow.Compiler.exe corpus 11 (elastic 6, sigma 3, splunk 2)
  • PowerShell.EXE corpus 134 (sigma 86, splunk 30, elastic 18)
  • REGSVR32.EXE corpus 37 (sigma 17, elastic 15, splunk 5)
  • RUNDLL32.EXE corpus 72 (sigma 35, splunk 21, elastic 16)
  • RegAsm.exe corpus 13 (sigma 6, elastic 6, splunk 1)
  • RegSvcs.exe corpus 12 (elastic 6, sigma 5, splunk 1)
  • WMIC.exe corpus 74 (sigma 38, elastic 18, splunk 18)
  • bitsadmin.exe corpus 19 (sigma 9, elastic 8, splunk 2)
  • certutil.exe corpus 26 (sigma 14, elastic 6, splunk 6)
  • cscript.exe corpus 32 (sigma 17, elastic 15)
  • curl.exe corpus 22 (sigma 13, elastic 6, splunk 3)
  • hh.exe corpus 11 (sigma 5, splunk 4, elastic 2)
  • msiexec.exe corpus 18 (elastic 9, sigma 5, splunk 4)
  • msxsl.exe corpus 9 (elastic 6, sigma 3)
  • pwsh.exe corpus 7 (elastic 7)
  • sc.exe corpus 28 (sigma 12, splunk 10, elastic 6)
  • schtasks.exe corpus 29 (sigma 18, elastic 7, splunk 4)
  • wscript.exe corpus 37 (elastic 20, sigma 17)
field:"OriginalFileName" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

Back to all Elastic rules