Detection rules › Elastic

Elastic rules: 3j

RuleSeverity
AWS IAM API Calls via Temporary Session Tokenshigh
AWS KMS Key Policy Updated via PutKeyPolicymedium
AWS STS Role Assumption by Userlow
Azure AKS Certificate Signing Request Created or Approvedmedium
Azure Recovery Services Resource Deletedmedium
Azure VM Boot Diagnostics Retrievedmedium
Container Management Utility Run Inside A Containerlow
DLL Side Loading of a file dropped by Microsoft Office
DNS Over HTTPS by an Unusual Process
File Download from Suspicious Top Level Domain
First Occurrence of User-Agent For a GitHub Userlow
Google Workspace Login Flagged Suspiciouslow
Kerberos Cached Credentials Dumpinghigh
Keystroke Messages Hooking via SetWindowsHookEx
Microsoft Entra ID Impossible Travel Sign-inhigh
NotificationCenter Silenced via Killall Binary
Potential Browser Credentials Stealer
Potential Chroot Container Escape via Mounthigh
Potential DLL Hollowing from a Writable Image
Potential Injection via Asynchronous Procedure Call
Potential Linux Tunneling and/or Port Forwarding via Command Linemedium
Potential PowerShell Obfuscation via High Special Character Proportionlow
Potential PowerShell Obfuscation via Reverse Keywordslow
Potential WinRAR CVE-2023-38831 Exploitation
Successful SSH Authentication from Unusual Userlow
Suspicious Execution via Microsoft OfficeCmd URL Handler
Suspicious Execution via Windows Services
Suspicious JavaScript Execution via Denohigh
Suspicious Microsoft Antimalware Service Executionhigh
Suspicious Python Shell Command Executionmedium
Svchost spawning Cmdlow
Unusual Web Requestlow
World Writeable Directory File Creation and Outbound Connection

AWS IAM API Calls via Temporary Session Tokens

#
Status
production
Severity
high
Time window
6m
Group by
aws.cloudtrail.user_identity.arn
Author
Elastic
Source
github.com/elastic/detection-rules

Detects sensitive AWS IAM API operations executed using temporary session credentials (access key IDs beginning with "ASIA"). Temporary credentials are commonly issued through sts:GetSessionToken, sts:AssumeRole, or AWS SSO logins and are meant for short-term use. It is unusual for legitimate users or automated processes to perform privileged IAM actions (e.g., creating users, updating policies, or enabling/disabling MFA) with session tokens. This behavior may indicate credential theft, session hijacking, or the abuse of a privileged role’s temporary credentials.

Known False Positives

  • Some CI/CD pipelines or administrative users may use session tokens. Review user context, IP, and timing to validate. This rule automatically excludes console login sessions using the aws.cloudtrail.session_credential_from_console field, which significantly reduces false positives from legitimate console-based IAM operations.

MITRE ATT&CK Coverage

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2025/04/16"
integration = ["aws"]
maturity = "production"
min_stack_version = "9.3.0"
min_stack_comments = "Changing min stack to 9.3.0, the latest minimum supported version for 9.X releases."
updated_date = "2026/07/20"

[rule]
author = ["Elastic"]
description = """
Detects sensitive AWS IAM API operations executed using temporary session credentials (access key IDs beginning with
"ASIA"). Temporary credentials are commonly issued through sts:GetSessionToken, sts:AssumeRole, or AWS SSO logins and
are meant for short-term use. It is unusual for legitimate users or automated processes to perform privileged IAM
actions (e.g., creating users, updating policies, or enabling/disabling MFA) with session tokens. This behavior may
indicate credential theft, session hijacking, or the abuse of a privileged role’s temporary credentials.
"""
false_positives = [
    """
    Some CI/CD pipelines or administrative users may use session tokens. Review user context, IP, and timing to
    validate. This rule automatically excludes console login sessions using the aws.cloudtrail.session_credential_from_console
    field, which significantly reduces false positives from legitimate console-based IAM operations.
    """,
]
from = "now-6m"
index = ["logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS IAM API Calls via Temporary Session Tokens"
note = """## Triage and analysis

### Investigating AWS IAM API Calls via Temporary Session Tokens

Temporary session credentials in AWS (identified by access keys beginning with "ASIA") are typically short-lived tokens 
issued by the AWS Security Token Service (STS). While they are legitimate and often used by developers or automation pipelines, 
their use in direct IAM management or privilege modification is highly unusual and may indicate credential misuse.

Attackers who compromise IAM users, roles, or federated identities can obtain session tokens to blend in with normal operations. 
They may then execute sensitive IAM API actions such as `CreateAccessKey`, `PutUserPolicy`, or `UpdateAssumeRolePolicy` to 
establish persistence, escalate privileges, or disable protections.

### Possible investigation steps

- **Identify the actor**
  - Review `aws.cloudtrail.user_identity.arn` and `aws.cloudtrail.user_identity.type` to determine the originating user or role.
  - This rule automatically filters out console login sessions using `aws.cloudtrail.session_credential_from_console`, so alerts indicate non-console temporary credential usage.
  - Examine `aws.cloudtrail.user_identity.session_context.mfa_authenticated` — absence of MFA may indicate token misuse.

- **Analyze the API context**
  - Review `event.action` and `aws.cloudtrail.request_parameters` for the exact IAM operation performed.
  - Identify whether the action modifies roles, user policies, trust relationships, or credentials.
  - Determine if this session token was associated with prior `sts:GetSessionToken`, `sts:AssumeRole`, or `AWS SSO` events.

- **Evaluate source and behavior**
  - Inspect `source.ip` and `user_agent.original` for unexpected origins or tools.
  - Check if the request came from known infrastructure (e.g., CI/CD nodes, bastion hosts) or an anomalous network.
  - Compare `@timestamp` against normal operating hours or deployment schedules.

- **Correlate related activity**
  - Look for subsequent or preceding activity using the same access key:
    - IAM changes (`CreateUser`, `AttachUserPolicy`, `EnableMFADevice`)
    - STS operations (`AssumeRole`, `GetCallerIdentity`)
    - CloudTrail or GuardDuty configuration changes (possible defense evasion)
  - If applicable, search for multiple users exhibiting similar patterns, a sign of large-scale token misuse.

### False positive analysis

- **Expected automation**
  - Some CI/CD pipelines, monitoring tools, or AWS SDK-based automation may perform IAM operations using temporary credentials.
  - Validate whether the IAM user or assumed role performing these actions belongs to an authorized automation workflow.
- **Administrative operations**
  - Security or DevOps engineers may temporarily use session credentials for maintenance or testing.
  - Cross-reference with recent change tickets or known operations schedules.
- **Federated identity scenarios**
  - Federated logins (via AWS SSO or external IdPs) can also generate temporary "ASIA" credentials. Verify if the source identity 
    aligns with expected roles or groups.
- **Console Login Session**
  - Console login sessions are automatically filtered out by this rule using the `aws.cloudtrail.session_credential_from_console` field.

### Response and remediation

- **Containment**
  - If activity is unauthorized, immediately revoke the temporary session by invalidating the associated IAM credentials.
  - Rotate long-term credentials (access keys, passwords) for the parent IAM user or role.

- **Investigation**
  - Search for all actions linked to the same `access_key_id` to assess potential persistence or lateral movement.
  - Examine the creation of new users, keys, or policies during or shortly after the detected session.

- **Recovery and hardening**
  - Require MFA for all privileged actions using `aws:MultiFactorAuthPresent` conditions.
  - Implement detection coverage for follow-on persistence actions such as:
    - `iam:CreateAccessKey`
    - `iam:PutUserPolicy`
    - `iam:UpdateAssumeRolePolicy`
  - Educate administrative users and developers on secure token handling and the risks of shared credential reuse.

### Additional information

For more information on detecting and mitigating session token abuse:
- **[AWS Security Token Service (STS) Documentation](https://docs.aws.amazon.com/STS/latest/APIReference/Welcome.html)**
- **[AWS IR Playbooks](https://github.com/aws-samples/aws-incident-response-playbooks/blob/c151b0dc091755fffd4d662a8f29e2f6794da52c/playbooks/)** 
- **[AWS Customer Playbook Framework](https://github.com/aws-samples/aws-customer-playbook-framework/tree/a8c7b313636b406a375952ac00b2d68e89a991f2/docs)** 
- **Security Best Practices:** [AWS Knowledge Center – Security Best Practices](https://aws.amazon.com/premiumsupport/knowledge-center/security-best-practices/).
"""
references = ["https://www.sygnia.co/blog/sygnia-investigation-bybit-hack/"]
risk_score = 73
rule_id = "c70d9f0d-8cb6-4cfc-85df-a95c1ccf4eab"
severity = "high"
tags = [
    "Domain: Cloud",
    "Data Source: AWS",
    "Data Source: Amazon Web Services",
    "Data Source: AWS CloudTrail",
    "Data Source: AWS IAM",
    "Data Source: AWS STS",
    "Tactic: Persistence",
    "Tactic: Privilege Escalation",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"

query = '''
data_stream.dataset: aws.cloudtrail
    and event.provider: ("iam.amazonaws.com")
    and event.outcome: "success"
    and aws.cloudtrail.user_identity.type: "IAMUser"
    and aws.cloudtrail.user_identity.access_key_id: ASIA*
    and source.ip: *
    and not user_agent.original : "AWS Internal"
    and not aws.cloudtrail.session_credential_from_console: true
'''


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

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

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

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

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

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

[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[rule.investigation_fields]
field_names = [
    "@timestamp",
    "user.name",
    "user_agent.original",
    "source.ip",
    "aws.cloudtrail.user_identity.arn",
    "aws.cloudtrail.user_identity.type",
    "aws.cloudtrail.user_identity.access_key_id",
    "event.action",
    "event.outcome",
    "cloud.account.id",
    "cloud.region",
    "aws.cloudtrail.request_parameters",
]

[rule.new_terms]
field = "new_terms_fields"
value = ["aws.cloudtrail.user_identity.arn"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-7d"


Stages and Predicates

Stage 1: new_terms

data_stream.dataset: aws.cloudtrail
    and event.provider: ("iam.amazonaws.com")
    and event.outcome: "success"
    and aws.cloudtrail.user_identity.type: "IAMUser"
    and aws.cloudtrail.user_identity.access_key_id: ASIA*
    and source.ip: *
    and not user_agent.original : "AWS Internal"
    and not aws.cloudtrail.session_credential_from_console: true

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

AWS KMS Key Policy Updated via PutKeyPolicy

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

Identifies successful PutKeyPolicy calls on AWS KMS keys. The key policy is a resource-based policy that controls which principals can use the key for cryptographic operations and administration. Adversaries with "kms:PutKeyPolicy" may add or broaden principals (including external accounts) to decrypt or exfiltrate data protected by the key, or to preserve access after other credentials are rotated. This is distinct from disabling or scheduling deletion of the key.

Known False Positives

  • Security, platform, and encryption teams legitimately update KMS key policies during onboarding, key rotation, or cross-account access design. Review the policy document diff, ticketing, and whether new principals are in-org.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

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

[rule]
author = ["Elastic"]
description = """
Identifies successful PutKeyPolicy calls on AWS KMS keys. The key policy is a resource-based policy that controls which
principals can use the key for cryptographic operations and administration. Adversaries with "kms:PutKeyPolicy" may add
or broaden principals (including external accounts) to decrypt or exfiltrate data protected by the key, or to preserve
access after other credentials are rotated. This is distinct from disabling or scheduling deletion of the key.
"""
false_positives = [
    """
    Security, platform, and encryption teams legitimately update KMS key policies during onboarding, key rotation, or
    cross-account access design. Review the policy document diff, ticketing, and whether new principals are in-org.
    """,
]
from = "now-6m"
index = ["filebeat-*", "logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS KMS Key Policy Updated via PutKeyPolicy"
note = """## Triage and analysis

### Investigating AWS KMS Key Policy Updated via PutKeyPolicy

`PutKeyPolicy` replaces the entire key policy for a customer managed KMS key (and is used in limited scenarios for AWS
managed keys). Unexpected changes can grant `kms:Decrypt`, `kms:GenerateDataKey`, or administrative actions to new
identities.

#### Possible investigation steps

- Identify the key from `aws.cloudtrail.resources.arn` or `aws.cloudtrail.request_parameters.keyId`.
- Inspect `policy` in `aws.cloudtrail.request_parameters` (or related fields) for new `Principal`, `AWS`, or
  `kms:CallerAccount` entries and cross-account ARNs.
- Determine which data stores use the key (S3, EBS, RDS, Secrets Manager, etc.) via CMK aliases or CMDB.
- Correlate with `iam:AttachRolePolicy`, `sts:AssumeRole`, or data-plane access from newly added principals.

### False positive analysis

- Planned multi-account encryption patterns; confirm recipient accounts are approved.

### Response and remediation

- If unauthorized: restore a known-good policy from backup or IAM/KMS change history, remove rogue principals, and
  restrict `kms:PutKeyPolicy` to break-glass roles.

### Additional information

- [PutKeyPolicy](https://docs.aws.amazon.com/kms/latest/APIReference/API_PutKeyPolicy.html)
- [KMS key policies](https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html)
"""
references = [
    "https://docs.aws.amazon.com/kms/latest/APIReference/API_PutKeyPolicy.html",
    "https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html",
]
risk_score = 47
rule_id = "f6a0b2c3-4d5e-4f7a-8b9c-0d1e2f3a4b5c"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Platform: AWS",
    "Data Source: AWS CloudTrail",
    "Service: AWS KMS",
    "Tactic: Defense Evasion",
    "Tactic: Privilege Escalation",
    "Rule Type: Custom Query (KQL)",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
event.dataset: "aws.cloudtrail"
    and event.provider: "kms.amazonaws.com"
    and event.action: "PutKeyPolicy"
    and event.outcome: "success"
    and not aws.cloudtrail.user_identity.type: "AWSService"
    and not user_agent.original: (*Terraform* or *Pulumi*)
'''

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


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

[[rule.threat.technique]]
id = "T1548"
name = "Abuse Elevation Control Mechanism"
reference = "https://attack.mitre.org/techniques/T1548/"

[[rule.threat.technique.subtechnique]]
id = "T1548.005"
name = "Temporary Elevated Cloud Access"
reference = "https://attack.mitre.org/techniques/T1548/005/"

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

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

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

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

Stages and Predicates

Stage 1: query

event.dataset: "aws.cloudtrail"
    and event.provider: "kms.amazonaws.com"
    and event.action: "PutKeyPolicy"
    and event.outcome: "success"
    and not aws.cloudtrail.user_identity.type: "AWSService"
    and not user_agent.original: (*Terraform* or *Pulumi*)

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

AWS STS Role Assumption by User

#
Status
production
Severity
low
Time window
6m
Group by
aws.cloudtrail.resources.arn, aws.cloudtrail.user_identity.arn
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies when a user or role has assumed a role in AWS Security Token Service (STS). Users can assume a role to obtain temporary credentials and access AWS resources. Adversaries can use this technique for credential access and privilege escalation. This is a New Terms rule that identifies when a user assumes a role in AWS Security Token Service (STS) to obtain temporary credentials and access AWS resources. While often legitimate, adversaries may use this technique for unauthorized access, privilege escalation, or lateral movement within an AWS environment.

Known False Positives

  • AWS administrators or automated processes might regularly assume roles for legitimate administrative purposes. Applications integrated with AWS might assume roles to access AWS resources. Automated workflows might assume roles to perform periodic tasks such as data backups, updates, or deployments.

MITRE ATT&CK Coverage

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

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

[rule]
author = ["Elastic"]
description = """
Identifies when a user or role has assumed a role in AWS Security Token Service (STS). Users can assume a role to obtain
temporary credentials and access AWS resources. Adversaries can use this technique for credential access and privilege
escalation. This is a New Terms rule that identifies when a user assumes a role in AWS Security Token Service (STS)
to obtain temporary credentials and access AWS resources. While often legitimate, adversaries may use this technique for
unauthorized access, privilege escalation, or lateral movement within an AWS environment.
"""
false_positives = [
    """
    AWS administrators or automated processes might regularly assume roles for legitimate administrative purposes.
    Applications integrated with AWS might assume roles to access AWS resources. Automated workflows might assume roles
    to perform periodic tasks such as data backups, updates, or deployments.
    """,
]
from = "now-6m"
index = ["filebeat-*", "logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS STS Role Assumption by User"
note = """## Triage and analysis

### Investigating AWS STS Role Assumption by User

This rule detects when a user assumes a role in AWS Security Token Service (STS), receiving temporary credentials to access AWS resources. While often used for legitimate purposes, this action can be leveraged by adversaries to obtain unauthorized access, escalate privileges, or move laterally within an AWS environment.

### Possible investigation steps

- **Identify the User and Assumed Role**:
  - **User Identity**: Check `aws.cloudtrail.user_identity.arn` for details about the initiator of the `AssumeRole` action.
  - **Role Assumed**: Review `aws.cloudtrail.resources.arn` to confirm the role assumed and ensure it aligns with the user’s standard permissions.
  - **Session Name**: Note `aws.cloudtrail.flattened.request_parameters.roleSessionName` for context on the purpose of the session.
  - **Expiration Time**: Use `aws.cloudtrail.flattened.response_elements.credentials.expiration` to confirm the credential expiration.

- **Inspect User Agent and Source Information**:
  - **User Agent**: Analyze the `user_agent.original` field to identify if specific tooling or SDKs like AWS CLI, Boto3, or custom agents were used.
  - **Source IP and Geolocation**: Examine `source.ip` and `source.geo` fields to determine the origin of the request, confirming if it aligns with expected locations.

- **Correlate with Related Events**:
  - **Identify Patterns**: Review related CloudTrail events for unusual access patterns, such as resource access or sensitive actions following this `AssumeRole` action.
  - **Filter High-Volume Roles**: If this role or user has a high volume of access, evaluate `roleArn` or `user_agent` values for common patterns and add trusted entities as exceptions.

- **Review the Privileges of the Assumed Role**:
  - **Permissions**: Examine permissions associated with the `roleArn` to assess its access scope.
  - **Authorized Usage**: Confirm if the role is used frequently for administrative purposes and if this aligns with the user’s regular responsibilities.

### False positive analysis

- **Automated Processes and Applications**: Applications or scheduled tasks may assume roles regularly for operational purposes. Validate the consistency of the `user_agent` or `roleArn` with known automated workflows.
- **Standard IAM Policy Usage**: Confirm if the user or application routinely assumes new roles for normal operations by reviewing historical activity.

### Response and remediation

- **Terminate Unauthorized Sessions**: If the role assumption is deemed unauthorized, revoke the session by modifying IAM policies or the permissions associated with the assumed role.
- **Strengthen Monitoring and Alerts**: Implement additional monitoring for specific high-risk roles, especially those with elevated permissions.
- **Regularly Manage Exceptions**: Regularly review high-volume roles and user agent patterns to refine alerts, minimizing noise by adding trusted patterns as exceptions.
- **Incident Response**: If confirmed as malicious, follow incident response protocols for containment, investigation, and remediation.

### Additional information

For more details on managing and securing AWS STS in your environment, refer to the [AWS STS documentation](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html).
"""
references = ["https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html"]
risk_score = 21
rule_id = "288a198e-9b9b-11ef-a0a8-f661ea17fbcd"
severity = "low"
tags = [
    "Domain: Cloud",
    "Data Source: AWS",
    "Data Source: Amazon Web Services",
    "Data Source: AWS STS",
    "Resources: Investigation Guide",
    "Use Case: Identity and Access Audit",
    "Tactic: Privilege Escalation",
    "Tactic: Lateral Movement",
]
timestamp_override = "event.ingested"
type = "new_terms"

query = '''
data_stream.dataset: "aws.cloudtrail"
    and event.provider: "sts.amazonaws.com"
    and event.action: "AssumeRole"
    and event.outcome: "success"
    and aws.cloudtrail.user_identity.type: "IAMUser"
'''


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

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

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

[[rule.threat.technique]]
id = "T1548"
name = "Abuse Elevation Control Mechanism"
reference = "https://attack.mitre.org/techniques/T1548/"

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

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

[[rule.threat.technique]]
id = "T1550"
name = "Use Alternate Authentication Material"
reference = "https://attack.mitre.org/techniques/T1550/"

[[rule.threat.technique.subtechnique]]
id = "T1550.001"
name = "Application Access Token"
reference = "https://attack.mitre.org/techniques/T1550/001/"

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

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

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

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

[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[rule.investigation_fields]
field_names = [
    "@timestamp",
    "user.name",
    "user_agent.original",
    "source.ip",
    "aws.cloudtrail.user_identity.arn",
    "aws.cloudtrail.user_identity.type",
    "aws.cloudtrail.user_identity.access_key_id",
    "event.action",
    "event.outcome",
    "aws.cloudtrail.resources.arn",
    "aws.cloudtrail.resources.type",
    "aws.cloudtrail.flattened.request_parameters.roleSessionName",
    "aws.cloudtrail.flattened.response_elements.credentials.accessKeyId",
    "cloud.region",
    "cloud.account.id",
    "aws.cloudtrail.request_parameters",
    "aws.cloudtrail.response_elements",
]

[rule.new_terms]
field = "new_terms_fields"
value = ["aws.cloudtrail.user_identity.arn", "aws.cloudtrail.resources.arn"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-5d"


Stages and Predicates

Stage 1: new_terms

data_stream.dataset: "aws.cloudtrail"
    and event.provider: "sts.amazonaws.com"
    and event.action: "AssumeRole"
    and event.outcome: "success"
    and aws.cloudtrail.user_identity.type: "IAMUser"

Indicators

These rows show field, operator, and value matches.

Azure AKS Certificate Signing Request Created or Approved

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

Detects an identity creating a client-authentication CertificateSigningRequest (signer kubernetes.io/kube-apiserver-client) or approving a CSR on AKS (Azure Kubernetes Service), excluding node bootstrap and platform controllers. Adversaries submit and self-approve a CSR against the kube-apiserver-client signer to mint a long-lived client certificate for an arbitrary subject (for example a Common Name in system:masters), giving durable authenticated access that survives token revocation. Coverage includes workload service accounts (system:serviceaccount:*), so a compromised in-cluster token forging a certificate is not excluded.

Known False Positives

  • Node bootstrap, cert-manager, and platform controllers legitimately create and approve CSRs. Validate the requesting identity and the certificate subject, and add exclusions for verified automation.

MITRE ATT&CK Coverage

TacticTechniques
Credential Access

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2026/07/09"
integration = ["azure"]
maturity = "production"
updated_date = "2026/07/09"

[rule]
author = ["Elastic"]
description = """
Detects an identity creating a client-authentication CertificateSigningRequest (signer
kubernetes.io/kube-apiserver-client) or approving a CSR on AKS (Azure Kubernetes Service), excluding node bootstrap and
platform controllers. Adversaries submit and self-approve a CSR against the kube-apiserver-client signer to mint a
long-lived client certificate for an arbitrary subject (for example a Common Name in system:masters), giving durable
authenticated access that survives token revocation. Coverage includes workload service accounts
(system:serviceaccount:*), so a compromised in-cluster token forging a certificate is not excluded.
"""
false_positives = [
    """
    Node bootstrap, cert-manager, and platform controllers legitimately create and approve CSRs. Validate the requesting
    identity and the certificate subject, and add exclusions for verified automation.
    """,
]
from = "now-9m"
index = ["logs-azure.platformlogs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Azure AKS Certificate Signing Request Created or Approved"
note = """## Triage and analysis

### Investigating Azure AKS Certificate Signing Request Created or Approved

AKS kube-audit events are carried under the flattened `azure.platformlogs.properties.log.*` subtree and share the ARM
operation `event.action: Microsoft.ContainerService/managedClusters/diagnosticLogs/Read`. A CSR created against the
`kubernetes.io/kube-apiserver-client` signer lets the requester choose the certificate's subject (Common Name and
organization/groups); once approved it mints a client certificate for an arbitrary identity that yields access not tied
to a token. The default `CertificateSubjectRestriction` admission controller blocks requests for the `system:masters`
group, so attackers commonly request a Common Name matching an existing privileged user (or another privileged group)
instead, making the requested subject the key thing to decode. Node and kubelet certificates use the
`kube-apiserver-client-kubelet` and `kubelet-serving` signers (whose subject is constrained to the node) and are out of
scope; cert-manager and application CSRs use their own signers.

### Possible investigation steps

- Identify the requesting identity in `azure.platformlogs.properties.log.user.username` (and its groups in
  `azure.platformlogs.properties.log.user.groups`) and whether it should submit or approve CSRs. A workload service
  account (`system:serviceaccount:<ns>:<sa>`) or `masterclient` (the local cluster-admin cert) is the higher-concern
  case.
- Confirm the signer in `azure.platformlogs.properties.log.requestObject.spec.signerName` and decode the base64 CSR in
  `azure.platformlogs.properties.log.requestObject.spec.request` to read the requested Common Name and organization
  (groups); a subject in `system:masters` or another privileged group is the escalation.
- Determine whether the same or a related identity approved the CSR (`verb:update`/`patch` on the `approval`
  subresource), which indicates self-approval, and inspect `azure.platformlogs.properties.log.userAgent`.
- Evaluate the source in `azure.platformlogs.properties.log.sourceIPs` and pivot on it for follow-on privileged API
  activity using the newly issued certificate.

### False positive analysis

- Node bootstrap (`kube-apiserver-client-kubelet` signer), kubelet-serving CSRs, and cert-manager/application CSRs
  (custom signers) are out of scope by design; the kube-controller-manager `certificate-controller` and the AKS
  `aksService` approver are excluded by identity.
- Manual CSR approval by an administrator, or an operator that legitimately mints client certificates, may surface;
  baseline those identities and exclude the specific validated account rather than re-broadening to all `system:*`,
  which would blind the rule to compromised workload service accounts.

### Response and remediation

- If unauthorized, deny or delete the CSR, revoke the issued certificate, and rotate the cluster CA if a privileged
  certificate was minted.
- Review the RBAC that allowed CSR creation and approval, and audit actions taken with the certificate.
- Collect kube-audit and identity artifacts per incident response procedures.
"""
references = [
    "https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/",
    "https://microsoft.github.io/Threat-Matrix-for-Kubernetes/",
    "https://github.com/inguardians/peirates",
    "https://raesene.github.io/blog/2022/12/21/Kubernetes-persistence-with-Tocan-and-Teisteanas/",
    "https://cloud.google.com/blog/topics/threat-intelligence/escalating-privileges-azure-kubernetes-services",
    "https://www.aquasec.com/blog/kubernetes-rbac-privilige-escalation/",
]
risk_score = 47
rule_id = "3f6c636a-1ca5-410c-bdad-f8b59a1f2b49"
setup = """The Azure Fleet integration collecting AKS diagnostic logs forwarded through Event Hub into the `azure.platformlogs`
data stream is required for this rule. Enable either the `kube-audit` or the `kube-audit-admin` log category (Microsoft
recommends `kube-audit-admin` alone to reduce volume, as it only drops read-only get/list events). CSR create and
approval are mutating operations recorded in both categories with the same `auditID`, so clusters that enable both
categories may generate two alerts per event.
"""
severity = "medium"
tags = [
    "Domain: Cloud",
    "Domain: Kubernetes",
    "Data Source: Azure",
    "Data Source: Azure Platform Logs",
    "Data Source: Kubernetes",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset:azure.platformlogs and
  event.action:"Microsoft.ContainerService/managedClusters/diagnosticLogs/Read" and
  azure.platformlogs.category:("kube-audit" or "kube-audit-admin") and
  azure.platformlogs.properties.log.stage:"ResponseComplete" and
  azure.platformlogs.properties.log.objectRef.resource:"certificatesigningrequests" and
  azure.platformlogs.properties.log.responseStatus.code: "200" and
  azure.platformlogs.properties.log.requestObject.status.conditions.type: "Approved" and
  (
    (
      azure.platformlogs.properties.log.verb:"create" and
      azure.platformlogs.properties.log.requestObject.spec.signerName:"kubernetes.io/kube-apiserver-client"
    ) or (
      azure.platformlogs.properties.log.verb:("update" or "patch") and
      azure.platformlogs.properties.log.objectRef.subresource:"approval"
    )
  ) and
  not azure.platformlogs.properties.log.user.username:(
    system\:node\:* or system\:bootstrap\:* or "aksService" or "hcpService" or
    "readinessChecker" or system\:serviceaccount\:kube-system\:*
  )
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1649"
name = "Steal or Forge Authentication Certificates"
reference = "https://attack.mitre.org/techniques/T1649/"


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

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "event.action",
    "azure.platformlogs.category",
    "azure.platformlogs.properties.log.verb",
    "azure.platformlogs.properties.log.user.username",
    "azure.platformlogs.properties.log.user.groups",
    "azure.platformlogs.properties.log.userAgent",
    "azure.platformlogs.properties.log.sourceIPs",
    "azure.platformlogs.properties.log.objectRef.resource",
    "azure.platformlogs.properties.log.objectRef.name",
    "azure.platformlogs.properties.log.objectRef.subresource",
    "azure.platformlogs.properties.log.requestObject.spec.signerName",
    "azure.platformlogs.properties.log.requestObject.spec.request",
    "azure.platformlogs.properties.log.responseStatus.code",
]

Stages and Predicates

Stage 1: query

data_stream.dataset:azure.platformlogs and
  event.action:"Microsoft.ContainerService/managedClusters/diagnosticLogs/Read" and
  azure.platformlogs.category:("kube-audit" or "kube-audit-admin") and
  azure.platformlogs.properties.log.stage:"ResponseComplete" and
  azure.platformlogs.properties.log.objectRef.resource:"certificatesigningrequests" and
  azure.platformlogs.properties.log.responseStatus.code: "200" and
  azure.platformlogs.properties.log.requestObject.status.conditions.type: "Approved" and
  (
    (
      azure.platformlogs.properties.log.verb:"create" and
      azure.platformlogs.properties.log.requestObject.spec.signerName:"kubernetes.io/kube-apiserver-client"
    ) or (
      azure.platformlogs.properties.log.verb:("update" or "patch") and
      azure.platformlogs.properties.log.objectRef.subresource:"approval"
    )
  ) and
  not azure.platformlogs.properties.log.user.username:(
    system\:node\:* or system\:bootstrap\:* or "aksService" or "hcpService" or
    "readinessChecker" or system\:serviceaccount\:kube-system\:*
  )

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
azure.platformlogs.categoryin
  • kube-audit corpus 6 (elastic 6)
  • kube-audit-admin corpus 6 (elastic 6)
field:"azure.platformlogs.category" kind:in
azure.platformlogs.properties.log.objectRef.resourceeq
  • certificatesigningrequests
field:"azure.platformlogs.properties.log.objectRef.resource" kind:eq value:"certificatesigningrequests"
azure.platformlogs.properties.log.objectRef.subresourceeq
  • approval
field:"azure.platformlogs.properties.log.objectRef.subresource" kind:eq value:"approval"
azure.platformlogs.properties.log.requestObject.spec.signerNameeq
  • kubernetes.io/kube-apiserver-client
field:"azure.platformlogs.properties.log.requestObject.spec.signerName" kind:eq value:"kubernetes.io/kube-apiserver-client"
azure.platformlogs.properties.log.requestObject.status.conditions.typeeq
  • Approved
field:"azure.platformlogs.properties.log.requestObject.status.conditions.type" kind:eq value:"Approved"
azure.platformlogs.properties.log.responseStatus.codeeq
  • 200
field:"azure.platformlogs.properties.log.responseStatus.code" kind:eq value:"200"
azure.platformlogs.properties.log.stageeq
  • ResponseComplete corpus 7 (elastic 7)
field:"azure.platformlogs.properties.log.stage" kind:eq value:"ResponseComplete"
azure.platformlogs.properties.log.verbeq
  • create corpus 3 (elastic 3)
field:"azure.platformlogs.properties.log.verb" kind:eq value:"create"
azure.platformlogs.properties.log.verbin
  • patch corpus 3 (elastic 3)
  • update corpus 3 (elastic 3)
field:"azure.platformlogs.properties.log.verb" kind:in
data_stream.dataseteq
  • azure.platformlogs corpus 14 (elastic 14)
field:"data_stream.dataset" kind:eq value:"azure.platformlogs"
event.actioneq
  • Microsoft.ContainerService/managedClusters/diagnosticLogs/Read corpus 11 (elastic 11)
field:"EventType" kind:eq value:"Microsoft.ContainerService/managedClusters/diagnosticLogs/Read"

Exclusions

The rule actively suppresses these predicates.

Azure Recovery Services Resource Deleted

#
Status
production
Kind
building block (feeds higher-level correlation rules; not a standalone alert)
Severity
medium
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies the deletion of Azure Recovery Services resources. Azure Recovery Services vaults contain data for copies of VMs, workloads, servers, and other resources regarding Infrastructure as a Service (IaaS). Adversaries may delete these recovery services to impact backup capabilities during stable operations or to inhibit disaster recovery services during ransom-based attacks or operational disruptions.

MITRE ATT&CK Coverage

TacticTechniques
Impact

Rule Body

[metadata]
bypass_bbr_timing = true
creation_date = "2025/10/13"
integration = ["azure"]
maturity = "production"
updated_date = "2025/10/13"

[rule]
author = ["Elastic"]
building_block_type = "default"
description = """
Identifies the deletion of Azure Recovery Services resources. Azure Recovery Services vaults contain data for copies of
VMs, workloads, servers, and other resources regarding Infrastructure as a Service (IaaS). Adversaries may delete these
recovery services to impact backup capabilities during stable operations or to inhibit disaster recovery services during
ransom-based attacks or operational disruptions.
"""
from = "now-9m"
index = ["logs-azure.activitylogs-*", "filebeat-*"]
language = "kuery"
license = "Elastic License v2"
name = "Azure Recovery Services Resource Deleted"
references = [
    "https://www.microsoft.com/en-us/security/blog/2023/07/25/storm-0501-ransomware-attacks-expanding-to-hybrid-cloud-environments/",
]
risk_score = 47
rule_id = "b8c3e5d0-8a1a-11ef-9b4a-f661ea17fbce"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Domain: Storage",
    "Data Source: Azure",
    "Data Source: Azure Activity Logs",
    "Use Case: Threat Detection",
    "Tactic: Impact",
    "Resources: Investigation Guide",
    "Rule Type: BBR",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
event.dataset:azure.activitylogs and
    azure.activitylogs.operation_name:MICROSOFT.RECOVERYSERVICES/*/DELETE and
    event.outcome:(Success or success)
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1490"
name = "Inhibit System Recovery"
reference = "https://attack.mitre.org/techniques/T1490/"


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

Stages and Predicates

Stage 1: query

event.dataset:azure.activitylogs and
    azure.activitylogs.operation_name:MICROSOFT.RECOVERYSERVICES/*/DELETE and
    event.outcome:(Success or success)

Indicators

These rows show field, operator, and value matches.

Azure VM Boot Diagnostics Retrieved

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

Identifies retrieval of Azure VM boot diagnostics data ("MICROSOFT.COMPUTE/VIRTUALMACHINES/RETRIEVEBOOTDIAGNOSTICSDATA/ACTION") by an identity that has not performed this operation recently. Boot diagnostics expose the VM serial console log and a console screenshot, which frequently contain plaintext boot-time output such as credentials, tokens, cloud-init/agent secrets, and command history. An adversary with VM read/contributor rights can retrieve this data over the control plane, without logging into the guest or touching the network, to harvest credentials.

Known False Positives

  • Support engineers, infrastructure-as-code, and VM health automation may legitimately retrieve boot diagnostics during troubleshooting. The first occurrence per principal will alert; baseline expected support users, service principals, and managed identities and exclude them if the activity is verified as authorized.

MITRE ATT&CK Coverage

TacticTechniques
Credential Access

Telemetry Coverage

Rule Body

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

[rule]
author = ["Elastic"]
description = """
Identifies retrieval of Azure VM boot diagnostics data
("MICROSOFT.COMPUTE/VIRTUALMACHINES/RETRIEVEBOOTDIAGNOSTICSDATA/ACTION") by an identity that has not performed this
operation recently. Boot diagnostics expose the VM serial console log and a console screenshot, which frequently contain
plaintext boot-time output such as credentials, tokens, cloud-init/agent secrets, and command history. An adversary with
VM read/contributor rights can retrieve this data over the control plane, without logging into the guest or touching the
network, to harvest credentials.
"""
false_positives = [
    """
    Support engineers, infrastructure-as-code, and VM health automation may legitimately retrieve boot diagnostics
    during troubleshooting. The first occurrence per principal will alert; baseline expected support users, service
    principals, and managed identities and exclude them if the activity is verified as authorized.
    """,
]
from = "now-9m"
index = ["logs-azure.activitylogs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Azure VM Boot Diagnostics Retrieved"
note = """## Triage and analysis

### Investigating Azure VM Boot Diagnostics Retrieved

Retrieving boot diagnostics (`retrieveBootDiagnosticsData/action`) returns SAS URIs to the VM serial console log and a
console screenshot. The serial log often contains plaintext boot output: cloud-init/agent activity, command history, and
sometimes credentials or tokens. The action is a control-plane read requiring only VM read/contributor rights, leaves no
guest footprint, and bypasses NSG/JIT.

### Triage checklist

- Identify the acting principal via `azure.activitylogs.identity.authorization.evidence.principal_id` and
  `...principal_type` (User vs ServicePrincipal) and `azure.activitylogs.identity.claims.appid`. Service principal or
  managed identity retrieval is more suspicious than a known support user.
- Review the source: `source.ip`, `source.as.number`, `source.as.organization.name`, `source.geo.country_name`.
  Retrieval from cloud hosting, VPS, or anonymizing networks is more suspicious than known corporate egress.
- Inspect `azure.resource.id` / `azure.resource.name` to identify the target VM. Was the same principal recently granted
  access to it, or is this their first interaction?
- Did the same principal recently perform reconnaissance, role assignments, Run Command, or extension operations on the
  VM or subscription?

### 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 boot diagnostics serial log and screenshot from the VM and assess whether they exposed credentials or
  other secrets that now require rotation.
- Pivot on the VM and any credentials observed in the serial log for follow-on access, lateral movement, or persistence.

### Response and remediation

- If unauthorized, rotate any credentials/tokens exposed in the serial log, review RBAC on the affected scope, and revoke
  the principal's access if compromised.
- Collect activity log artifacts per incident procedures.
"""
references = [
    "https://blog.pwnedlabs.io/diving-deep-into-azure-vm-attack-vectors",
    "https://www.microsoft.com/en-us/msrc/blog/2023/08/azure-serial-console-attack-and-defense-part-1",
    "https://learn.microsoft.com/en-us/azure/virtual-machines/boot-diagnostics",
    "https://www.netspi.com/blog/technical-blog/adversary-simulation/7-ways-to-execute-command-on-azure-virtual-machine-virtual-machine-scale-sets/",
]
risk_score = 47
rule_id = "e7509f8f-e70b-4b67-b864-aaa4254b4484"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Domain: Endpoint",
    "Data Source: Azure",
    "Data Source: Azure Activity Logs",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset:azure.activitylogs and
    event.action:"MICROSOFT.COMPUTE/VIRTUALMACHINES/RETRIEVEBOOTDIAGNOSTICSDATA/ACTION" and
    event.outcome:(success or Success)
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1552"
name = "Unsecured Credentials"
reference = "https://attack.mitre.org/techniques/T1552/"


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

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

Stages and Predicates

Stage 1: query

data_stream.dataset:azure.activitylogs and
    event.action:"MICROSOFT.COMPUTE/VIRTUALMACHINES/RETRIEVEBOOTDIAGNOSTICSDATA/ACTION" and
    event.outcome:(success or Success)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
data_stream.dataseteq
  • azure.activitylogs corpus 38 (elastic 38)
field:"data_stream.dataset" kind:eq value:"azure.activitylogs"
event.actioneq
  • MICROSOFT.COMPUTE/VIRTUALMACHINES/RETRIEVEBOOTDIAGNOSTICSDATA/ACTION
field:"EventType" kind:eq value:"MICROSOFT.COMPUTE/VIRTUALMACHINES/RETRIEVEBOOTDIAGNOSTICSDATA/ACTION"
event.outcomein
  • Success corpus 306 (elastic 306)
  • success corpus 306 (elastic 306)
field:"event.outcome" kind:in

Container Management Utility Run Inside A Container

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

This rule detects when a container management binary is run from inside a container. These binaries are critical components of many containerized environments, and their presence and execution in unauthorized containers could indicate compromise or a misconfiguration.

Known False Positives

  • There is a potential for false positives if the container is used for legitimate administrative tasks that require the use of container management utilities, such as deploying, scaling, or updating containerized applications. 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 = "2025/03/12"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
This rule detects when a container management binary is run from inside a container. These binaries are critical
components of many containerized environments, and their presence and execution in unauthorized containers could
indicate compromise or a misconfiguration.
"""
false_positives = [
    """
    There is a potential for false positives if the container is used for legitimate administrative tasks that require
    the use of container management utilities, such as deploying, scaling, or updating containerized applications. 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-9m"
index = ["logs-endpoint.events.process*"]
language = "eql"
license = "Elastic License v2"
name = "Container Management Utility Run Inside A Container"
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 Container Management Utility Run Inside A Container

Container management utilities like Docker and Kubectl are essential for orchestrating and managing containerized applications. They facilitate tasks such as deployment, scaling, and networking. However, adversaries can exploit these tools to execute unauthorized commands within containers, potentially leading to system compromise. The detection rule identifies suspicious execution of these utilities within containers, signaling possible misuse or misconfiguration, by monitoring specific process activities and event types.

### Possible investigation steps

- Examine the process name and command line arguments to understand the context of the execution and identify any anomalies or unauthorized commands.
- Check the user and permissions associated with the process to assess if it aligns with expected roles and access levels for container management tasks.
- Investigate the container's creation and deployment history to identify any recent changes or deployments that could explain the presence of the management utility.
- Analyze network activity associated with the container to detect any unusual connections or data transfers that might indicate malicious activity.
- Correlate the event with other security alerts or logs to identify patterns or related incidents that could provide additional context or evidence of compromise.

### False positive analysis

- Routine maintenance tasks within containers can trigger the rule. Exclude known maintenance scripts or processes by adding them to an allowlist if they frequently execute container management utilities.
- Development and testing environments often run container management commands for legitimate purposes. Consider excluding these environments from monitoring or adjust the rule to focus on production environments only.
- Automated deployment tools may execute container management commands as part of their workflow. Identify these tools and create exceptions for their activities to prevent false positives.
- System updates or patches might involve running container management utilities. Monitor update schedules and temporarily adjust the rule to avoid unnecessary alerts during these periods.
- Legitimate administrative actions by authorized personnel can trigger the rule. Implement user-based exceptions for known administrators to reduce false positives while maintaining security oversight.

### Response and remediation

- Immediately isolate the affected container to prevent further unauthorized access or execution of commands. This can be done by stopping the container or disconnecting it from the network.
- Review the container's configuration and access controls to identify any misconfigurations or unauthorized access permissions that may have allowed the execution of container management utilities.
- Conduct a thorough analysis of the container's logs and process activities to determine the extent of the compromise and identify any additional malicious activities or lateral movement attempts.
- Remove any unauthorized or suspicious binaries and scripts from the container to prevent further exploitation.
- Patch and update the container image and underlying host system to address any known vulnerabilities that may have been exploited.
- Implement stricter access controls and monitoring on container management utilities to ensure they are only accessible by authorized users and processes.
- Escalate the incident to the security operations team for further investigation and to assess the need for broader security measures across the container environment."""

risk_score = 21
rule_id = "4b74d3b0-416e-4099-b432-677e1cd098cc"
setup = """## Setup

This rule requires data coming in from Elastic Defend.

### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.

#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).

#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.

For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "low"
tags = [
    "Domain: Container",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Execution",
    "Data Source: Elastic Defend",
    "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.entry_leader.entry_meta.type == "container" and process.interactive == true and
process.name in ("dockerd", "kubelet", "kube-proxy", "kubectl", "containerd", "systemd", "crictl") and
not (
  process.parent.executable in ("/sbin/init", "/usr/bin/dockerd", "/usr/bin/runc", "/usr/bin/containerd-shim-runc-v2") or
  process.working_directory == "/aws" or
  process.parent.command_line == "runc init" or
  (process.parent.name == "busybox" and process.name == "kubectl")
)
'''

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

[[rule.threat.technique]]
id = "T1609"
name = "Container Administration Command"
reference = "https://attack.mitre.org/techniques/T1609/"

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

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

[[rule.threat.technique]]
id = "T1613"
name = "Container and Resource Discovery"
reference = "https://attack.mitre.org/techniques/T1613/"

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

Stages and Predicates

Stage 1: process

process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and
process.entry_leader.entry_meta.type == "container" and process.interactive == true and
process.name in ("dockerd", "kubelet", "kube-proxy", "kubectl", "containerd", "systemd", "crictl") and
not (
  process.parent.executable in ("/sbin/init", "/usr/bin/dockerd", "/usr/bin/runc", "/usr/bin/containerd-shim-runc-v2") or
  process.working_directory == "/aws" or
  process.parent.command_line == "runc init" or
  (process.parent.name == "busybox" and process.name == "kubectl")
)

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.nameeqkubectlexcludes:process.name field:"process.name" value:"kubectl"
process.parent.nameeqbusyboxexcludes:process.parent.name field:"process.parent.name" value:"busybox"
process.parent.command_lineeqrunc initexcludes:process.parent.command_line field:"process.parent.command_line" value:"runc init"
process.parent.executablein/sbin/init, /usr/bin/containerd-shim-runc-v2, /usr/bin/dockerd, /usr/bin/runcexcludes:process.parent.executable
process.working_directoryeq/awsexcludes:process.working_directory field:"process.working_directory" value:"/aws"

DLL Side Loading of a file dropped by Microsoft Office

#
Time window
5m
Sequence by
dll.path, file.path
Source
github.com/elastic/protections-artifacts

Identifies when a Microsoft Office process creates an executable file (DLL) and the file is subsequently loaded by a trusted binary. An adversary may deliver a weaponized Office document to their target that writes and loads malicious modules.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies when a Microsoft Office process creates an executable file (DLL) and the file is subsequently loaded by a
trusted binary. An adversary may deliver a weaponized Office document to their target that writes and loads malicious
modules.
"""
id = "68218637-3940-42cb-b2b7-0610fc1dde56"
license = "Elastic License v2"
name = "DLL Side Loading of a file dropped by Microsoft Office"
os_list = ["windows"]
version = "1.0.21"

query = '''
sequence with maxspan=5m
  [ file where event.action != "deletion" and
      process.name :
          ("WINWORD.EXE",
           "EXCEL.EXE",
           "POWERPNT.EXE",
           "MSACCESS.EXE",
           "MSPUB.EXE") and
      (
        file.extension : ("dll", "cpl", "ocx") or
        // Match Windows PE files by header data (MZ)
        file.Ext.header_bytes : "4d5a*"
      ) ] by file.path
  [ library where
   (dll.code_signature.exists == false or
   (dll.code_signature.trusted == false and not dll.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*"))) and
    process.code_signature.trusted == true and
    not process.name : ("WINWORD.EXE", "EXCEL.EXE", "POWERPNT.EXE", "MSACCESS.EXE", "ONENOTE.EXE") and
    not startswith~(dll.name, process.name) and
    not dll.hash.sha256 in ("ac0b2e4ea19c34536a58e6818fe0d37599495a6b3da7e8d3a3444ea0eff9d6e6", "d85639d208dc27961832b15eb42f9861faffca18e0ded8d5697c9bf13b7b598c") and
    not dll.path : "?:\\Windows\\assembly\\NativeImages_*" and
    not (process.executable : "?:\\Windows\\System32\\spoolsv.exe" and user.id : "S-1-5-18") and
    not process.executable : ("?:\\Windows\\SysWOW64\\msiexec.exe", "?:\\Windows\\system32\\msiexec.exe")
    ] by dll.path
'''

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

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

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 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 = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"
[[threat.technique.subtechnique]]
id = "T1574.001"
name = "DLL"
reference = "https://attack.mitre.org/techniques/T1574/001/"



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

[internal]
min_endpoint_version = "8.4.0"

Stages and Predicates

Ordered sequence: each step below must occur in order within 5m, correlated by dll.path, file.path.

Stage 1: file

[ file where event.action != "deletion" and
      process.name :
          ("WINWORD.EXE",
           "EXCEL.EXE",
           "POWERPNT.EXE",
           "MSACCESS.EXE",
           "MSPUB.EXE") and
      (
        file.extension : ("dll", "cpl", "ocx") or
        file.Ext.header_bytes : "4d5a*"
      ) ] by file.path

Stage 2: library

[ library where
   (dll.code_signature.exists == false or
   (dll.code_signature.trusted == false and not dll.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*"))) and
    process.code_signature.trusted == true and
    not process.name : ("WINWORD.EXE", "EXCEL.EXE", "POWERPNT.EXE", "MSACCESS.EXE", "ONENOTE.EXE") and
    not startswith~(dll.name, process.name) and
    not dll.hash.sha256 in ("ac0b2e4ea19c34536a58e6818fe0d37599495a6b3da7e8d3a3444ea0eff9d6e6", "d85639d208dc27961832b15eb42f9861faffca18e0ded8d5697c9bf13b7b598c") and
    not dll.path : "?:\\Windows\\assembly\\NativeImages_*" and
    not (process.executable : "?:\\Windows\\System32\\spoolsv.exe" and user.id : "S-1-5-18") and
    not process.executable : ("?:\\Windows\\SysWOW64\\msiexec.exe", "?:\\Windows\\system32\\msiexec.exe")
    ] by dll.path

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
dll.code_signature.existseq
  • false transforms: boolean corpus 22 (elastic 22)
field:"dll.code_signature.exists" kind:eq value:"false"
dll.code_signature.trustedeq
  • false transforms: boolean corpus 21 (elastic 21)
field:"dll.code_signature.trusted" kind:eq value:"false"
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
  • cpl corpus 19 (elastic 19)
  • dll corpus 32 (elastic 32)
  • ocx corpus 6 (elastic 6)
field:"file.extension" kind:wildcard
process.code_signature.trustedeq
  • true transforms: boolean corpus 14 (elastic 14)
field:"process.code_signature.trusted" kind:eq value:"true"
process.namewildcard
  • EXCEL.EXE corpus 34 (elastic 34)
  • MSACCESS.EXE corpus 19 (elastic 19)
  • MSPUB.EXE corpus 15 (elastic 15)
  • POWERPNT.EXE corpus 31 (elastic 31)
  • WINWORD.EXE corpus 35 (elastic 35)
field:"process_basename" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.executableeq?:\Windows\System32\spoolsv.exeexcludes:process.executable field:"process.executable" value:"?:\Windows\System32\spoolsv.exe"
user.ideqS-1-5-18excludes:user.id field:"user.id" value:"S-1-5-18"
dll.hash.sha256inac0b2e4ea19c34536a58e6818fe0d37599495a6b3da7e8d3a3444ea0eff9d6e6, d85639d208dc27961832b15eb42f9861faffca18e0ded8d5697c9bf13b7b598cexcludes:dll.hash.sha256 field:"dll.hash.sha256" value:"ac0b2e4ea19c34536a58e6818fe0d37599495a6b3da7e8d3a3444ea0eff9d6e6" field:"dll.hash.sha256" value:"d85639d208dc27961832b15eb42f9861faffca18e0ded8d5697c9bf13b7b598c"
dll.namestarts_withprocess.nameexcludes:dll.name field:"dll.name" value:"process.name"
dll.pathstarts_with?:\Windows\assembly\NativeImages_excludes:dll.path field:"dll.path" value:"?:\Windows\assembly\NativeImages_"
process.executableeq?:\Windows\SysWOW64\msiexec.exe, ?:\Windows\system32\msiexec.exeexcludes:process.executable field:"process.executable" value:"?:\Windows\SysWOW64\msiexec.exe" field:"process.executable" value:"?:\Windows\system32\msiexec.exe"
process.nameeqWINWORD.EXE, EXCEL.EXE, POWERPNT.EXE, MSACCESS.EXE, ONENOTE.EXEexcludes:process.name

DNS Over HTTPS by an Unusual Process

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

Identifies DNS queries to known DNS over HTTPS (DoH) Providers by an unusual Microsoft signed binary or files from suspicious paths. This may indicate abuse of DoH for Command and Control communications.

MITRE ATT&CK Coverage

TacticTechniques
Command & Control

Rule Body

[rule]
description = """
Identifies DNS queries to known DNS over HTTPS (DoH) Providers by an unusual Microsoft signed binary or files from
suspicious paths. This may indicate abuse of DoH for Command and Control communications.
"""
id = "9371a660-2ee8-4840-820d-8a9754308d53"
license = "Elastic License v2"
name = "DNS Over HTTPS by an Unusual Process"
os_list = ["windows"]
reference = ["https://www.blackhillsinfosec.com/dns-over-https-for-cobalt-strike/"]
version = "1.0.4"

query = '''
sequence by process.entity_id with maxspan=1m
  [process where event.action == "start" and user.id like ("S-1-5-21*", "S-1-12-*") and
   (
    (process.executable : "C:\\Windows\\*.exe" and
     process.code_signature.subject_name in ("Microsoft Windows Publisher", "Microsoft Corporation", "Microsoft Windows") and
     not process.executable : ("C:\\Windows\\Sys?????\\ipconfig.exe",
                               "C:\\Windows\\Sys?????\\nslookup.exe",
                               "C:\\Windows\\Sys?????\\TRACERT.EXE",
                               "C:\\Windows\\Sys?????\\PING.EXE",
                               "C:\\Windows\\System32\\Microsoft-Edge-WebView\\msedgewebview2.exe")) or

     (process.Ext.relative_file_creation_time <= 900 and process.code_signature.status in ("errorBadDigest", "errorUntrustedRoot")) or

     (process.Ext.relative_file_creation_time <= 900 and process.executable : ("C:\\ProgramData\\*", "C:\\Users\\Public\\*", "C:\\Users\\*\\Downloads\\*"))
   )
   ]
  [dns where dns.question.name : ("cloudflare-dns.com", "mozilla.cloudflare-dns.com", "dns.google", "dns.quad9.net", "doh.opendns.com", "ordns.he.net") and
   not (dns.question.name : "dns.google" and
        process.executable : ("C:\\Program Files\\WindowsApps\\Enflick.TextNow-UnlimitedTextCalls_*\\app\\TextNow.exe",
                              "C:\\Program Files (x86)\\Steam\\steamapps\\common\\assettocorsa\\cache\\cef\\Assetto Corsa CEF.exe"))]
'''

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"
[[threat.technique.subtechnique]]
id = "T1071.004"
name = "DNS"
reference = "https://attack.mitre.org/techniques/T1071/004/"



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

[internal]
min_endpoint_version = "8.4.0"

Stages and Predicates

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

Stage 1: process

[process where event.action == "start" and user.id like ("S-1-5-21*", "S-1-12-*") and
   (
    (process.executable : "C:\\Windows\\*.exe" and
     process.code_signature.subject_name in ("Microsoft Windows Publisher", "Microsoft Corporation", "Microsoft Windows") and
     not process.executable : ("C:\\Windows\\Sys?????\\ipconfig.exe",
                               "C:\\Windows\\Sys?????\\nslookup.exe",
                               "C:\\Windows\\Sys?????\\TRACERT.EXE",
                               "C:\\Windows\\Sys?????\\PING.EXE",
                               "C:\\Windows\\System32\\Microsoft-Edge-WebView\\msedgewebview2.exe")) or

     (process.Ext.relative_file_creation_time <= 900 and process.code_signature.status in ("errorBadDigest", "errorUntrustedRoot")) or

     (process.Ext.relative_file_creation_time <= 900 and process.executable : ("C:\\ProgramData\\*", "C:\\Users\\Public\\*", "C:\\Users\\*\\Downloads\\*"))
   )
   ]

Stage 2: dns

[dns where dns.question.name : ("cloudflare-dns.com", "mozilla.cloudflare-dns.com", "dns.google", "dns.quad9.net", "doh.opendns.com", "ordns.he.net") and
   not (dns.question.name : "dns.google" and
        process.executable : ("C:\\Program Files\\WindowsApps\\Enflick.TextNow-UnlimitedTextCalls_*\\app\\TextNow.exe",
                              "C:\\Program Files (x86)\\Steam\\steamapps\\common\\assettocorsa\\cache\\cef\\Assetto Corsa CEF.exe"))]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
dns.question.namewildcard
  • cloudflare-dns.com
  • dns.google
  • dns.quad9.net
  • doh.opendns.com
  • mozilla.cloudflare-dns.com
  • ordns.he.net
field:"QueryName" kind:wildcard
event.actioneq
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq value:"start"
process.Ext.relative_file_creation_timele
  • 900 transforms: number corpus 7 (elastic 7)
field:"process.Ext.relative_file_creation_time" kind:le value:"900"
process.code_signature.statusin
  • errorBadDigest
  • errorUntrustedRoot
field:"SignatureStatus" kind:in
process.code_signature.subject_namein
  • Microsoft Corporation corpus 5 (elastic 5)
  • Microsoft Windows corpus 5 (elastic 5)
  • Microsoft Windows Publisher corpus 2 (elastic 2)
field:"Signature" kind:in
process.executablewildcard
  • C:\ProgramData\* corpus 2 (elastic 2)
  • C:\Users\*\Downloads\* corpus 2 (elastic 2)
  • C:\Users\Public\* corpus 2 (elastic 2)
  • C:\Windows\*.exe corpus 2 (elastic 2)
field:"Image" kind:wildcard
user.idwildcard
  • S-1-12-* corpus 21 (elastic 21)
  • S-1-5-21* corpus 21 (elastic 21)
field:"user.id" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
dns.question.nameeqdns.googleexcludes:dns.question.name field:"dns.question.name" value:"dns.google"
process.executablewildcardC:\Program Files\WindowsApps\Enflick.TextNow-UnlimitedTextCalls_*\app\TextNow.exe, C:\Program Files (x86)\Steam\steamapps\common\assettocorsa\cache\cef\Assetto Corsa CEF.exeexcludes:process.executable field:"process.executable" value:"C:\Program Files\WindowsApps\Enflick.TextNow-UnlimitedTextCalls_*\app\TextNow.exe" field:"process.executable" value:"C:\Program Files (x86)\Steam\steamapps\common\assettocorsa\cache\cef\Assetto Corsa CEF.exe"

File Download from Suspicious Top Level Domain

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

Identifies network connections to commonly abused Top Level Domains followed by the immdiate creation of a Python, Shell Script, Applescript, or Binary. This may indicate an attempt to establish initial access or command and control by a malicious payload.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[rule]
description = """
Identifies network connections to commonly abused Top Level Domains followed by the immdiate creation of a Python, Shell
Script, Applescript, or Binary. This may indicate an attempt to establish initial access or command and control by a
malicious payload.
"""
id = "9a3acafe-2ecd-487f-8c1f-1697fe9d33c7"
license = "Elastic License v2"
name = "File Download from Suspicious Top Level Domain"
os_list = ["macos"]
version = "1.0.12"

query = '''
sequence by process.entity_id with maxspan=30s
[network where event.type == "start" and
  destination.domain like~ ("*.team", "*.team.", "*.lol", "*.lol.", "*.app", "*.app.", "*.kr", "*.kr.", "*.ke", "*.ke.", "*.nu", "*.nu.", "*.space", "*.space.", "*.capital", "*.capital.", "*.in", "*.in.", "*.cfd", "*.cfd.", "*.online", "*.online.", 
                            "*.info", "*.info.", "*.top", "*.top.", "*.buzz", "*.buzz.", "*.xyz", "*.xyz.", "*.rest", "*.rest.", "*.ml", "*.ml.", "*.cf", "*.cf.", "*.gq", "*.gq.", "*.ga", "*.ga.", "*.onion", "*.onion.",
                            "*.network", "*.network.", "*.monster", "*.monster.", "*.marketing", "*.marketing.", "*.cyou", "*.cyou.", "*.quest", "*.quest.", "*.cc", "*.cc.", "*.bar", "*.bar.", "*.click", "*.click.", "*.cam", "*.cam.",
                            "*.surf", "*.surf.", "*.tk", "*.tk.", "*.shop", "*.shop.", "*.club", "*.club.", "*.icu", "*.icu.", "*.pw", "*.pw.", "*.ws", "*.ws.", "*.rest", "*.rest.", "*.hair", "*.hair.",
                            "*.mom", "*.mom.", "*.beauty", "*.beauty.", "*.boats", "*.boats.", "*.online", "*.online.", "*.fun", "*.fun.", "*.life", "*.life.", "*.store", "*.store.")]
[file where event.action == "modification" and file.extension in ("py", "sh", "scpt", "pyc") and file.path like ("/Users/Shared/*", "/tmp/*", "/private/tmp/*", "/private/var/tmp/*", "/var/tmp/*", "/private/var/root/*", "/var/root/*") and
  not file.path like~ "/private/var/folders/*" and
  not file.extension in ("so", "dylib")]
'''

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

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

[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 = "8.16.0"

Stages and Predicates

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

Stage 1: network

[network where event.type == "start" and
  destination.domain like~ ("*.team", "*.team.", "*.lol", "*.lol.", "*.app", "*.app.", "*.kr", "*.kr.", "*.ke", "*.ke.", "*.nu", "*.nu.", "*.space", "*.space.", "*.capital", "*.capital.", "*.in", "*.in.", "*.cfd", "*.cfd.", "*.online", "*.online.", 
                            "*.info", "*.info.", "*.top", "*.top.", "*.buzz", "*.buzz.", "*.xyz", "*.xyz.", "*.rest", "*.rest.", "*.ml", "*.ml.", "*.cf", "*.cf.", "*.gq", "*.gq.", "*.ga", "*.ga.", "*.onion", "*.onion.",
                            "*.network", "*.network.", "*.monster", "*.monster.", "*.marketing", "*.marketing.", "*.cyou", "*.cyou.", "*.quest", "*.quest.", "*.cc", "*.cc.", "*.bar", "*.bar.", "*.click", "*.click.", "*.cam", "*.cam.",
                            "*.surf", "*.surf.", "*.tk", "*.tk.", "*.shop", "*.shop.", "*.club", "*.club.", "*.icu", "*.icu.", "*.pw", "*.pw.", "*.ws", "*.ws.", "*.rest", "*.rest.", "*.hair", "*.hair.",
                            "*.mom", "*.mom.", "*.beauty", "*.beauty.", "*.boats", "*.boats.", "*.online", "*.online.", "*.fun", "*.fun.", "*.life", "*.life.", "*.store", "*.store.")]

Stage 2: file

[file where event.action == "modification" and file.extension in ("py", "sh", "scpt", "pyc") and file.path like ("/Users/Shared/*", "/tmp/*", "/private/tmp/*", "/private/var/tmp/*", "/var/tmp/*", "/private/var/root/*", "/var/root/*") and
  not file.path like~ "/private/var/folders/*" and
  not file.extension in ("so", "dylib")]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
destination.domainwildcard
  • *.app
  • *.app.
  • *.bar corpus 2 (elastic 2)
  • *.bar.
  • *.beauty corpus 2 (elastic 2)
  • *.beauty.
  • *.boats corpus 2 (elastic 2)
  • *.boats.
  • *.buzz corpus 2 (elastic 2)
  • *.buzz.
  • *.cam corpus 2 (elastic 2)
  • *.cam.
  • *.capital corpus 2 (elastic 2)
  • *.capital.
  • *.cc corpus 2 (elastic 2)
  • *.cc.
  • *.cf corpus 2 (elastic 2)
  • *.cf.
  • *.cfd corpus 2 (elastic 2)
  • *.cfd.
  • *.click corpus 2 (elastic 2)
  • *.click.
  • *.club corpus 2 (elastic 2)
  • *.club.
  • *.cyou corpus 2 (elastic 2)
  • *.cyou.
  • *.fun corpus 2 (elastic 2)
  • *.fun.
  • *.ga corpus 2 (elastic 2)
  • *.ga.
  • *.gq corpus 2 (elastic 2)
  • *.gq.
  • *.hair corpus 2 (elastic 2)
  • *.hair.
  • *.icu corpus 2 (elastic 2)
  • *.icu.
  • *.in corpus 2 (elastic 2)
  • *.in.
  • *.info corpus 2 (elastic 2)
  • *.info.
  • +48 more values (see full rule source)
field:"DestinationHostname" kind:wildcard
event.actioneq
  • modification corpus 72 (elastic 72)
field:"EventType" kind:eq value:"modification"
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
file.extensionin
  • py corpus 10 (elastic 10)
  • pyc corpus 4 (elastic 4)
  • scpt corpus 7 (elastic 7)
  • sh corpus 13 (elastic 13)
field:"file.extension" kind:in
file.pathwildcard
  • /Users/Shared/* corpus 8 (elastic 8)
  • /private/tmp/* corpus 11 (elastic 11)
  • /private/var/root/*
  • /private/var/tmp/* corpus 6 (elastic 6)
  • /tmp/* corpus 15 (elastic 15)
  • /var/root/*
  • /var/tmp/* corpus 11 (elastic 11)
field:"TargetFilename" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

First Occurrence of User-Agent For a GitHub User

#
Status
production
Kind
building block (feeds higher-level correlation rules; not a standalone alert)
Severity
low
Time window
9m
Group by
github.user_agent, user.name
Author
Elastic
Source
github.com/elastic/detection-rules

Detects a new user agent used for a GitHub user not previously seen in the last 14 days.

MITRE ATT&CK Coverage

TacticTechniques
Initial Access

Rule Body

[metadata]
bypass_bbr_timing = true
creation_date = "2023/10/11"
integration = ["github"]
maturity = "production"
updated_date = "2025/12/24"

[rule]
author = ["Elastic"]
building_block_type = "default"
description = "Detects a new user agent used for a GitHub user not previously seen in the last 14 days.\n"
from = "now-9m"
index = ["logs-github.audit-*"]
language = "kuery"
license = "Elastic License v2"
name = "First Occurrence of User-Agent For a GitHub User"
risk_score = 21
rule_id = "41761cd3-380f-4d4d-89f3-46d6853ee35d"
severity = "low"
tags = [
    "Domain: Cloud",
    "Use Case: Threat Detection",
    "Use Case: UEBA",
    "Tactic: Initial Access",
    "Rule Type: BBR",
    "Data Source: Github",
]
timestamp_override = "event.ingested"
type = "new_terms"

query = '''
event.dataset:"github.audit" and event.category:"configuration" and
github.user_agent:* and user.name:*
'''


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



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

[rule.new_terms]
field = "new_terms_fields"
value = ["user.name", "github.user_agent"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-5d"


Stages and Predicates

Stage 1: new_terms

event.dataset:"github.audit" and event.category:"configuration" and
github.user_agent:* and user.name:*

Indicators

These rows show field, operator, and value matches.

Google Workspace Login Flagged Suspicious

#
Status
production
Kind
building block (feeds higher-level correlation rules; not a standalone alert)
Severity
low
Time window
3h
Author
Elastic
Source
github.com/elastic/detection-rules

Surfaces Google Workspace sign-in events that Google's identity risk engine has flagged as suspicious via the is_suspicious field on the login activity record. This is Google's own ML-driven sign-in risk signal. The field is set by Google server-side based on signals like sign-ins from anonymizer infrastructure, known-malicious IP ranges, atypical user characteristics, or anomalous device fingerprints. Use this signal as enrichment alongside the other Workspace sign-in rules rather than as a standalone alert. This rule is a building block. It does not generate user-facing alerts by default but populates signal.rule.building_block_type for correlation rules or analyst pivots.

Known False Positives

  • Google's risk engine occasionally flags legitimate sign-ins as suspicious when the user is on a new device, on a VPN egress that geo-resolves to a different region, or after extended time away. Validate by checking the user's recent sign-in history and confirming with the user.

MITRE ATT&CK Coverage

Telemetry Coverage

PlatformRecord / event type
Google Workspaceany: Login (any event)

Rule Body

[metadata]
creation_date = "2026/05/14"
integration = ["google_workspace"]
maturity = "production"
updated_date = "2026/05/14"

[rule]
author = ["Elastic"]
building_block_type = "default"
description = """
Surfaces Google Workspace sign-in events that Google's identity risk engine has flagged as suspicious via the
`is_suspicious` field on the `login` activity record. This is Google's own ML-driven sign-in risk signal. The field is
set by Google server-side based on signals like sign-ins from anonymizer infrastructure, known-malicious IP ranges,
atypical user characteristics, or anomalous device fingerprints. Use this signal as enrichment alongside the other
Workspace sign-in rules rather than as a standalone alert. This rule is a building block. It does not generate
user-facing alerts by default but populates `signal.rule.building_block_type` for correlation rules or analyst pivots.
"""
false_positives = [
    """
    Google's risk engine occasionally flags legitimate sign-ins as suspicious when the user is on a new device, on a VPN
    egress that geo-resolves to a different region, or after extended time away. Validate by checking the user's recent
    sign-in history and confirming with the user.
    """,
]
from = "now-180m"
index = ["filebeat-*", "logs-google_workspace.login*"]
interval = "60m"
language = "kuery"
license = "Elastic License v2"
name = "Google Workspace Login Flagged Suspicious"
note = """## Triage and analysis

### Investigating Google Workspace Login Flagged Suspicious

Google sets `google_workspace.login.is_suspicious: true` when its server-side risk engine identifies a sign-in event as anomalous for the user. Triggers commonly include:

- Sign-in from an anonymizer (Tor exit, public VPN, etc.)
- Sign-in from a known-malicious IP range
- Atypical device fingerprint for the user
- Sign-in from a geography or ASN inconsistent with the user's history

As a building block, this signal is intended for use alongside other detection rules. On its own it is medium-confidence.

### Possible investigation steps

- Inspect `source.ip`, `source.as.organization.name`, `source.geo.country_name`. Classify the network: residential ISP, corporate VPN, hosting provider (high concern), anonymizer (high concern).
- Inspect `google_workspace.login.type`. `google_password` is an interactive sign-in (highest concern). `reauth` is a silent token refresh (lower concern unless paired with other signals).
- Inspect `google_workspace.login.challenge_method`. Whether 2FA was relayed or skipped factors into the kit-vs-traveler determination.
- Pull the user's recent sign-in history. Is this a one-off flag or a sustained pattern from a new network?
- Cross-reference `logs-google_workspace.token` for `event.action: "authorize"` events from the same `user.email` immediately following the suspicious sign-in. An OAuth grant minted seconds after a Google-flagged sign-in is the AiTM kit signature.
- Cross-reference `logs-google_workspace.device` for `DEVICE_REGISTER_UNREGISTER_EVENT` with `account_state: "REGISTERED"` near the same time. New device registration paired with `is_suspicious` is high-fidelity compromise.
- Confirm with the user whether the sign-in was theirs.

### False positive analysis

- Travelers, VPN users, new-device sign-ins, and users returning from leave will all trip Google's risk engine occasionally.
- Building-block signals are not tuned for false-positive minimization at the source; they trade noise for coverage. Combine with other signals before treating as actionable.

### Response and remediation

- This rule does not generate user-facing alerts by default. Use it as enrichment for higher-level correlation rules.
- If a correlation surfaces this signal alongside other indicators (atypical ASN, atypical country, OAuth grant, device registration), follow the response steps in those rules.
"""
references = [
    "https://knowledge.workspace.google.com/admin/security/user-login-attempts-report",
    "https://www.elastic.co/security-labs/google-workspace-attack-surface-part-one",
]
risk_score = 21
rule_id = "93d2c5bf-dac1-4e0f-ab52-16f440782bb8"
setup = """## Setup

### Important Information Regarding Google Workspace Event Lag Times
- Google Workspace Reports API ingestion lag commonly runs in the 30-minute to 3-hour range. This rule's 130-minute lookback gives partial coverage but will miss events delayed beyond that envelope.
- See https://support.google.com/a/answer/7061566 for Google's published guidance on event availability.
- Check your integration's Login lag time to ensure it is configured to meet the needs of this rule.
"""
severity = "low"
tags = [
    "Domain: Cloud",
    "Domain: Identity",
    "Data Source: Google Workspace",
    "Data Source: Google Workspace Audit Logs",
    "Data Source: Google Workspace User Log Events",
    "Use Case: Threat Detection",
    "Use Case: Identity and Access Audit",
    "Tactic: Initial Access",
    "Tactic: Credential Access",
    "Rule Type: BBR",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset: "google_workspace.login" and
    event.provider: "login" and
    google_workspace.login.is_suspicious: true
'''


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



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

[[rule.threat.technique]]
id = "T1557"
name = "Adversary-in-the-Middle"
reference = "https://attack.mitre.org/techniques/T1557/"


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

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "user.email",
    "user.name",
    "source.ip",
    "source.as.number",
    "source.as.organization.name",
    "source.geo.country_name",
    "google_workspace.login.type",
    "google_workspace.login.challenge_method",
    "google_workspace.login.is_suspicious",
]

Stages and Predicates

Stage 1: query

data_stream.dataset: "google_workspace.login" and
    event.provider: "login" and
    google_workspace.login.is_suspicious: true

Indicators

These rows show field, operator, and value matches.

Kerberos Cached Credentials Dumping

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

Identifies the use of the Kerberos credential cache (kcc) utility to dump locally cached Kerberos tickets. Adversaries may attempt to dump credential material in the form of tickets that can be leveraged for lateral movement.

MITRE ATT&CK Coverage

Rule Body

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

[rule]
author = ["Elastic"]
description = """
Identifies the use of the Kerberos credential cache (kcc) utility to dump locally cached Kerberos tickets. Adversaries
may attempt to dump credential material in the form of tickets that can be leveraged for lateral movement.
"""
from = "now-9m"
index = ["logs-endpoint.events.*"]
language = "eql"
license = "Elastic License v2"
name = "Kerberos Cached Credentials Dumping"
references = [
    "https://github.com/EmpireProject/EmPyre/blob/master/lib/modules/collection/osx/kerberosdump.py",
    "https://opensource.apple.com/source/Heimdal/Heimdal-323.12/kuser/kcc-commands.in.auto.html",
]
risk_score = 73
rule_id = "ad88231f-e2ab-491c-8fc6-64746da26cfe"
setup = """## Setup

This rule requires data coming in from Elastic Defend.

### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.

#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).

#### The following steps should be executed in order to add the Elastic Defend integration on a macOS System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, for MacOS it is recommended to select "Traditional Endpoints".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/current/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: macOS",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Data Source: Elastic Defend",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
process where host.os.type == "macos" and event.type in ("start", "process_started") and
  process.name == "kcc" and
  process.args like~ "copy_cred_cache"
'''
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 Kerberos Cached Credentials Dumping

Kerberos is a network authentication protocol designed to provide secure identity verification for users and services. It uses tickets to allow nodes to prove their identity in a secure manner. Adversaries may exploit tools like the Kerberos credential cache utility to extract these tickets, enabling unauthorized access and lateral movement within a network. The detection rule identifies suspicious activity by monitoring for specific processes and arguments on macOS systems, flagging potential credential dumping attempts.

### Possible investigation steps

- Review the alert details to confirm the presence of the process name 'kcc' and the argument 'copy_cred_cache' in the process execution logs on macOS systems.
- Identify the user account associated with the process execution to determine if the activity aligns with expected behavior or if it indicates potential unauthorized access.
- Examine the timeline of the process execution to identify any preceding or subsequent suspicious activities, such as unusual login attempts or lateral movement within the network.
- Check for any other alerts or logs related to the same host or user account to assess if this is part of a broader attack pattern.
- Investigate the source and destination of any network connections made by the process to identify potential data exfiltration or communication with known malicious IP addresses.
- Consult with the user or system owner to verify if the use of the 'kcc' utility was legitimate or if it requires further investigation.

### False positive analysis

- Routine administrative tasks using the kcc utility may trigger the rule. Identify and document these tasks to create exceptions for known benign activities.
- Automated scripts or maintenance processes that involve copying Kerberos credential caches can be mistaken for malicious activity. Review and whitelist these scripts if they are verified as safe.
- Developers or IT personnel testing Kerberos configurations might use the kcc utility in a non-malicious context. Establish a process to log and approve such activities to prevent false alarms.
- Security tools or monitoring solutions that interact with Kerberos tickets for legitimate purposes may inadvertently trigger the rule. Coordinate with security teams to ensure these tools are recognized and excluded from detection.

### Response and remediation

- Immediately isolate the affected macOS system from the network to prevent further unauthorized access or lateral movement.
- Terminate the suspicious process identified as 'kcc' with the argument 'copy_cred_cache' to stop any ongoing credential dumping activity.
- Conduct a thorough review of the system's Kerberos ticket cache to identify any unauthorized access or anomalies, and invalidate any compromised tickets.
- Reset passwords and regenerate Kerberos tickets for any accounts that may have been affected to prevent further unauthorized access.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine the scope of the breach.
- Implement additional monitoring on the affected system and similar endpoints to detect any recurrence of the credential dumping activity.
- Review and update access controls and Kerberos configurations to enhance security and reduce the risk of similar attacks in the future."""


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

[[rule.threat.technique]]
id = "T1003"
name = "OS Credential Dumping"
reference = "https://attack.mitre.org/techniques/T1003/"

[[rule.threat.technique]]
id = "T1558"
name = "Steal or Forge Kerberos Tickets"
reference = "https://attack.mitre.org/techniques/T1558/"

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

[[rule.threat.technique.subtechnique]]
id = "T1558.005"
name = "Ccache Files"
reference = "https://attack.mitre.org/techniques/T1558/005/"

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

Stages and Predicates

Stage 1: process

process where host.os.type == "macos" and event.type in ("start", "process_started") and
  process.name == "kcc" and
  process.args like~ "copy_cred_cache"

Indicators

These rows show field, operator, and value matches.

Keystroke Messages Hooking via SetWindowsHookEx

#
Source
github.com/elastic/protections-artifacts

Identifies attempts to install an application-defined hook procedure to monitor keystroke messages. Adversaries may log user keystrokes to intercept credentials or other information from the user as the user types them.

MITRE ATT&CK Coverage

TacticTechniques
Collection

Rule Body

[rule]
description = """
Identifies attempts to install an application-defined hook procedure to monitor keystroke messages. Adversaries may log
user keystrokes to intercept credentials or other information from the user as the user types them.
"""
id = "7ae180e1-e08f-40c2-82db-f274f688eea2"
license = "Elastic License v2"
name = "Keystroke Messages Hooking via SetWindowsHookEx"
os_list = ["windows"]
reference = [
    "https://attack.mitre.org/techniques/T1056/001/",
    "https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexa",
    "https://www.elastic.co/security-labs/protecting-your-devices-from-information-theft-keylogger-protection",
]
version = "1.0.19"

query = '''
api where process.Ext.api.name == "SetWindowsHookEx" and process.Ext.api.parameters.hook_type == "WH_KEYBOARD_LL" and
 process.Ext.api.parameters.hook_module == "null" and
 process.thread.Ext.call_stack_final_user_module.hash.sha256 != null and not process.code_signature.status : "trusted" and
 process.thread.Ext.call_stack_summary : "?*" and process.executable != null and
 not process.thread.Ext.call_stack_summary :
                               ("*user32.dll|explorer.exe|user32.dll*",
                                "*user32.dll|tabskb.dll|kernel32.dll*",
                                "*user32.dll|taskbar.dll*",
                                "win32u.dll|user32.dll|pilotshubapp.dll",
                                "*win32u.dll|user32.dll|mtb.exe|mfc90u.dll|mtb.exe*",
                                "win32u.dll|user32.dll|powertoy*",
                                "win32u.dll|user32.dll|rdclientax.dl*",
                                "*qt6gui.dll|qt6core.dll*",
                                "win32u.dll|user32.dll|rwsfoundation_x64.dll|ucrtbase.dll|kernel32.dll|ntdll.dll",
                                "win32u.dll|user32.dll|autohotkey*.exe|kernel32.dll|ntdll.dll") and
 not process.thread.Ext.call_stack_final_user_module.hash.sha256 in
                        ("1683394a15b58815a01bbe030dfc1e441a9b0f7f38d18bd5c13d41d573d58f53",
                         "bec3b34c8e9c04a1da28c623fb06cee45739113a38a1eae52d2a3b208c4baa6f",
                         "0d083e72eb0e8cbcec2c347840bff815513eecf29648065163b08c600f6c95ff",
                         "38011e713b4be8577576062754cad03e9899859488932ae4c9c83e5fbb5cb7d2",
                         "b67e006287fba2278f897d242ff58548b7d6b15ac490a91c26318c6f396da195",
                         "feaf9479260db6f41d1e6443d0d80826eeee4905ef97a1cab78c16bc304248a5",
                         "465d3985e1dd8bc69137e2a8c5a4a6ba16b0ff99c647245ca66942750ccc75ef",
                         "549888a9e268dd5ca6544cabc8266148ff0d8728c3aa0f1c68f9f8bcb116e53d") and
 not process.thread.Ext.call_stack_final_user_module.path :
                        ("?:\\Program Files\\*",
                         "?:\\Program Files (x86)\\*",
                         "?:\\windows\\system32\\*",
                         "?:\\windows\\syswow64\\*",
                         "\\Program Files\\*",
                         "\\Program Files (x86)\\*",
                         "\\windows\\system32\\*",
                         "\\windows\\syswow64\\*",
                         "?:\\windows\\explorer.exe",
                         "\\windows\\explorer.exe",
                         "*\\windows\\systemapps\\*",
                         "c:\\windows\\microsoft.net\\framework*\\clr.dll",
                         "*\\windows\\assembly\\*",
                         "?:\\windows\\systemapps\\*.dll",
                         "?:\\Windows\\WinSxS\\*.dll",
                         "?:\\windows\\assembly\\*.dll",
                         "\\windows\\systemapps\\*.dll",
                         "\\Windows\\WinSxS\\*.dll",
                         "\\windows\\assembly\\*.dll",
                         "\\windows\\shellexperiences\\*.dll",
                         "?:\\progra~?\\citrix\\icacli~?\\vdkbhook.dll",
                         "?:\\windows\\shellexperiences\\*.dll",
                         "\\windows\\shellexperiences\\*.dll",
                         "?:\\windows\\jmesoft\\keyhook.dll",
                         "?:\\users\\*\\appdata\\local\\microsoft\\teams\\current\\d3dcompiler_??.dll",
                         "\\device\\mup\\*",
                         "?:\\windows\\immersivecontrolpanel\\systemsettings.dll") and
    not process.thread.Ext.call_stack_final_user_module.name : ("Unknown", "Undetermined") and
    not process.thread.Ext.call_stack_final_user_module.protection_provenance : ("hmpalert.dll", "kernel") and
    not process.executable :
                ("?:\\Program Files\\workspacer\\workspacer.exe",
                 "?:\\Program Files (x86)\\Do It Again\\DoItAgain.exe",
                 "?:\\Program Files (x86)\\HP\\HP LaserJet Pro MFP *\\bin\\HPScan.exe",
                 "?:\\Program Files (x86)\\Avaya\\Avaya IX Workplace\\fTarget\\Avaya.BrowserExtension.exe") and
    not _arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature, $entry, $entry.status : "trusted")
'''

min_endpoint_version = "8.12.0"
reputation = true
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1056"
name = "Input Capture"
reference = "https://attack.mitre.org/techniques/T1056/"
[[threat.technique.subtechnique]]
id = "T1056.001"
name = "Keylogging"
reference = "https://attack.mitre.org/techniques/T1056/001/"



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

[internal]
min_endpoint_version = "8.12.0"

Stages and Predicates

Stage 1: api

api where process.Ext.api.name == "SetWindowsHookEx" and process.Ext.api.parameters.hook_type == "WH_KEYBOARD_LL" and
 process.Ext.api.parameters.hook_module == "null" and
 process.thread.Ext.call_stack_final_user_module.hash.sha256 != null and not process.code_signature.status : "trusted" and
 process.thread.Ext.call_stack_summary : "?*" and process.executable != null and
 not process.thread.Ext.call_stack_summary :
                               ("*user32.dll|explorer.exe|user32.dll*",
                                "*user32.dll|tabskb.dll|kernel32.dll*",
                                "*user32.dll|taskbar.dll*",
                                "win32u.dll|user32.dll|pilotshubapp.dll",
                                "*win32u.dll|user32.dll|mtb.exe|mfc90u.dll|mtb.exe*",
                                "win32u.dll|user32.dll|powertoy*",
                                "win32u.dll|user32.dll|rdclientax.dl*",
                                "*qt6gui.dll|qt6core.dll*",
                                "win32u.dll|user32.dll|rwsfoundation_x64.dll|ucrtbase.dll|kernel32.dll|ntdll.dll",
                                "win32u.dll|user32.dll|autohotkey*.exe|kernel32.dll|ntdll.dll") and
 not process.thread.Ext.call_stack_final_user_module.hash.sha256 in
                        ("1683394a15b58815a01bbe030dfc1e441a9b0f7f38d18bd5c13d41d573d58f53",
                         "bec3b34c8e9c04a1da28c623fb06cee45739113a38a1eae52d2a3b208c4baa6f",
                         "0d083e72eb0e8cbcec2c347840bff815513eecf29648065163b08c600f6c95ff",
                         "38011e713b4be8577576062754cad03e9899859488932ae4c9c83e5fbb5cb7d2",
                         "b67e006287fba2278f897d242ff58548b7d6b15ac490a91c26318c6f396da195",
                         "feaf9479260db6f41d1e6443d0d80826eeee4905ef97a1cab78c16bc304248a5",
                         "465d3985e1dd8bc69137e2a8c5a4a6ba16b0ff99c647245ca66942750ccc75ef",
                         "549888a9e268dd5ca6544cabc8266148ff0d8728c3aa0f1c68f9f8bcb116e53d") and
 not process.thread.Ext.call_stack_final_user_module.path :
                        ("?:\\Program Files\\*",
                         "?:\\Program Files (x86)\\*",
                         "?:\\windows\\system32\\*",
                         "?:\\windows\\syswow64\\*",
                         "\\Program Files\\*",
                         "\\Program Files (x86)\\*",
                         "\\windows\\system32\\*",
                         "\\windows\\syswow64\\*",
                         "?:\\windows\\explorer.exe",
                         "\\windows\\explorer.exe",
                         "*\\windows\\systemapps\\*",
                         "c:\\windows\\microsoft.net\\framework*\\clr.dll",
                         "*\\windows\\assembly\\*",
                         "?:\\windows\\systemapps\\*.dll",
                         "?:\\Windows\\WinSxS\\*.dll",
                         "?:\\windows\\assembly\\*.dll",
                         "\\windows\\systemapps\\*.dll",
                         "\\Windows\\WinSxS\\*.dll",
                         "\\windows\\assembly\\*.dll",
                         "\\windows\\shellexperiences\\*.dll",
                         "?:\\progra~?\\citrix\\icacli~?\\vdkbhook.dll",
                         "?:\\windows\\shellexperiences\\*.dll",
                         "\\windows\\shellexperiences\\*.dll",
                         "?:\\windows\\jmesoft\\keyhook.dll",
                         "?:\\users\\*\\appdata\\local\\microsoft\\teams\\current\\d3dcompiler_??.dll",
                         "\\device\\mup\\*",
                         "?:\\windows\\immersivecontrolpanel\\systemsettings.dll") and
    not process.thread.Ext.call_stack_final_user_module.name : ("Unknown", "Undetermined") and
    not process.thread.Ext.call_stack_final_user_module.protection_provenance : ("hmpalert.dll", "kernel") and
    not process.executable :
                ("?:\\Program Files\\workspacer\\workspacer.exe",
                 "?:\\Program Files (x86)\\Do It Again\\DoItAgain.exe",
                 "?:\\Program Files (x86)\\HP\\HP LaserJet Pro MFP *\\bin\\HPScan.exe",
                 "?:\\Program Files (x86)\\Avaya\\Avaya IX Workplace\\fTarget\\Avaya.BrowserExtension.exe") and
    not _arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature, $entry, $entry.status : "trusted")

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.thread.Ext.call_stack_final_user_module.code_signaturearray_any(no value, null check)excludes:process.thread.Ext.call_stack_final_user_module.code_signature
process.code_signature.statuseqtrustedexcludes:process.code_signature.status field:"process.code_signature.status" value:"trusted"
process.executablewildcard?:\Program Files\workspacer\workspacer.exe, ?:\Program Files (x86)\Do It Again\DoItAgain.exe, ?:\Program Files (x86)\HP\HP LaserJet Pro MFP *\bin\HPScan.exe, ?:\Program Files (x86)\Avaya\Avaya IX Workplace\fTarget\Avaya.BrowserExtension.exeexcludes:process.executable
process.thread.Ext.call_stack_final_user_module.hash.sha256in0d083e72eb0e8cbcec2c347840bff815513eecf29648065163b08c600f6c95ff, 1683394a15b58815a01bbe030dfc1e441a9b0f7f38d18bd5c13d41d573d58f53, 38011e713b4be8577576062754cad03e9899859488932ae4c9c83e5fbb5cb7d2, 465d3985e1dd8bc69137e2a8c5a4a6ba16b0ff99c647245ca66942750ccc75ef, 549888a9e268dd5ca6544cabc8266148ff0d8728c3aa0f1c68f9f8bcb116e53d, b67e006287fba2278f897d242ff58548b7d6b15ac490a91c26318c6f396da195, bec3b34c8e9c04a1da28c623fb06cee45739113a38a1eae52d2a3b208c4baa6f, feaf9479260db6f41d1e6443d0d80826eeee4905ef97a1cab78c16bc304248a5excludes:process.thread.Ext.call_stack_final_user_module.hash.sha256
process.thread.Ext.call_stack_final_user_module.nameeqUnknown, Undeterminedexcludes:process.thread.Ext.call_stack_final_user_module.name field:"process.thread.Ext.call_stack_final_user_module.name" value:"Unknown" field:"process.thread.Ext.call_stack_final_user_module.name" value:"Undetermined"
process.thread.Ext.call_stack_final_user_module.pathwildcard?:\Program Files\*, ?:\Program Files (x86)\*, ?:\windows\system32\*, ?:\windows\syswow64\*, \Program Files\*, \Program Files (x86)\*, \windows\system32\*, \windows\syswow64\*, ?:\windows\explorer.exe, \windows\explorer.exe, *\windows\systemapps\*, c:\windows\microsoft.net\framework*\clr.dll, *\windows\assembly\*, ?:\windows\systemapps\*.dll, ?:\Windows\WinSxS\*.dll, ?:\windows\assembly\*.dll, \windows\systemapps\*.dll, \Windows\WinSxS\*.dll, \windows\assembly\*.dll, \windows\shellexperiences\*.dll, ?:\progra~?\citrix\icacli~?\vdkbhook.dll, ?:\windows\shellexperiences\*.dll, \windows\shellexperiences\*.dll, ?:\windows\jmesoft\keyhook.dll, ?:\users\*\appdata\local\microsoft\teams\current\d3dcompiler_??.dll, \device\mup\*, ?:\windows\immersivecontrolpanel\systemsettings.dllexcludes:process.thread.Ext.call_stack_final_user_module.path
process.thread.Ext.call_stack_final_user_module.protection_provenanceeqhmpalert.dll, kernelexcludes:process.thread.Ext.call_stack_final_user_module.protection_provenance field:"process.thread.Ext.call_stack_final_user_module.protection_provenance" value:"hmpalert.dll" field:"process.thread.Ext.call_stack_final_user_module.protection_provenance" value:"kernel"
process.thread.Ext.call_stack_summarywildcard*user32.dll|explorer.exe|user32.dll*, *user32.dll|tabskb.dll|kernel32.dll*, *user32.dll|taskbar.dll*, win32u.dll|user32.dll|pilotshubapp.dll, *win32u.dll|user32.dll|mtb.exe|mfc90u.dll|mtb.exe*, win32u.dll|user32.dll|powertoy*, win32u.dll|user32.dll|rdclientax.dl*, *qt6gui.dll|qt6core.dll*, win32u.dll|user32.dll|rwsfoundation_x64.dll|ucrtbase.dll|kernel32.dll|ntdll.dll, win32u.dll|user32.dll|autohotkey*.exe|kernel32.dll|ntdll.dllexcludes:process.thread.Ext.call_stack_summary

Microsoft Entra ID Impossible Travel Sign-in

#
Status
production
Severity
high
Time window
90m
Group by
azure.signinlogs.properties.user_principal_name, source.geo.country_name, source.geo.region_name
Author
Elastic
Source
github.com/elastic/detection-rules

Detects successful Microsoft Entra ID interactive sign-ins for the same user from two geographically separated locations within a 90-minute window, where the implied travel speed between the two points exceeds what is physically possible (>=800 km/h, faster than modern commercial airliners) and the geographic separation is at least 500 km. This pattern indicates either VPN/proxy use or an adversary signing in to a compromised account from a different location than the legitimate user. Non-interactive sign-in categories are excluded because backend token refresh activity routinely egresses through cloud regions unrelated to the user. This activity is often observed from AiTM phishing kits or successful phishing campaigns.

Known False Positives

  • Users on VPN or proxy egress that geo-resolves through a region distant from the user's physical location. Mobile clients on cellular carrier networks that peer through regional hubs may geo-resolve to a different region than the user's physical location. Corporate AWS Workspaces / VDI deployments where employees interactively sign in from a cloud-provider ASN.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2026/05/15"
integration = ["azure"]
maturity = "production"
min_stack_version = "9.4.0"
min_stack_comments = "ES|QL FIRST and LAST aggregation functions are GA in 9.4."
updated_date = "2026/05/15"

[rule]
author = ["Elastic"]
description = """
Detects successful Microsoft Entra ID interactive sign-ins for the same user from two geographically separated locations
within a 90-minute window, where the implied travel speed between the two points exceeds what is physically possible
(>=800 km/h, faster than modern commercial airliners) and the geographic separation is at least 500 km. This pattern
indicates either VPN/proxy use or an adversary signing in to a compromised account from a different location than the
legitimate user. Non-interactive sign-in categories are excluded because backend token refresh activity routinely
egresses through cloud regions unrelated to the user. This activity is often observed from AiTM phishing kits or
successful phishing campaigns.
"""
false_positives = [
    """
    Users on VPN or proxy egress that geo-resolves through a region distant from the user's physical location. Mobile
    clients on cellular carrier networks that peer through regional hubs may geo-resolve to a different region than the
    user's physical location. Corporate AWS Workspaces / VDI deployments where employees interactively sign in from a
    cloud-provider ASN.
    """,
]
from = "now-90m"
interval = "30m"
language = "esql"
license = "Elastic License v2"
name = "Microsoft Entra ID Impossible Travel Sign-in"
note = """## Triage and analysis

### Investigating Microsoft Entra ID Impossible Travel Sign-in

Microsoft Entra ID is accessible globally; legitimate users authenticate from one location at a time. Two successful interactive sign-ins for the same user separated by a distance and time delta implying travel faster than a commercial airliner cannot be the same human physically moving, and indicate either a VPN/proxy egress mismatch or a compromised account being accessed from a separate location by an adversary.

This rule scopes to `SignInLogs` (interactive sign-ins) only; non-interactive token refresh activity is excluded because backend service calls routinely egress through cloud regions unrelated to the user.

### Possible investigation steps

- Identify the user (`azure.signinlogs.properties.user_principal_name`) and the geographic separation observed: `Esql.distance_km`, `Esql.travel_kmh`, `Esql.window_minutes` (bbox path over region centroids), and the set of distinct countries, regions, and cities (`Esql.source_geo_country_name_values`, `Esql.source_geo_region_name_values`, `Esql.source_geo_city_name_values`).
- Cross-check `Esql.honest_distance_km`, `Esql.honest_travel_kmh`, `Esql.honest_window_minutes` -- these measure the real great-circle distance between the user's actual first and last sign-in events with timestamps locked to those same events. When the honest distance is small but the bbox distance is large, the user appeared in an outlier region in the middle of the window (A->B->A pattern -- typical AiTM kit replay). When both agree, it's a clean two-region case.
- Pull all `azure.signinlogs` events with `azure.signinlogs.category: SignInLogs` for the user across the alert window. Sort by `@timestamp` and inspect each `source.ip`, `source.as.organization.name`, `source.geo.country_name`, `user_agent.original`, `azure.signinlogs.properties.device_detail.browser`, and `azure.signinlogs.properties.device_detail.operating_system`.
- Determine which sign-ins are consistent with the user's baseline (corporate VPN egress, home ISP, mobile carrier) and which are not. Pay close attention to UA / browser / OS divergence between the two geographic clusters — adversary sessions almost always show a distinct fingerprint from the legitimate user's.
- For each non-baseline sign-in: check the ASN. Hosting-provider ASNs (Clouvider, Host Telecom, Alibaba, cheap-VPS providers, and AWS/Azure/GCP rented compute) for interactive sign-ins are high-fidelity suspicious because legitimate end users do not typically egress through those networks.
- Inspect `Esql.app_id_values`, `Esql.app_display_name_values`, `Esql.resource_id_values`, and `Esql.resource_display_name_values` for the apps and resources touched from each geo. Microsoft Graph, Azure PowerShell, or Azure Resource Manager access from a non-baseline geo immediately after a baseline sign-in is the post-auth recon signature.
- Cross-reference Entra audit logs (`logs-azure.auditlogs-*`) for `add service principal`, `consent to application`, OAuth consent grants, MFA method registration, or recovery email/phone changes for the same user near the same window. Adversaries routinely add persistence immediately after authentication.
- Confirm with the user whether the sign-ins are theirs (VPN, travel) or unexpected.

### False positive analysis

- Users on VPN or proxy infrastructure egressing through a distant region: validate against the user's known VPN ranges and consider excluding by ASN at the rule-exception layer (not in the base query).
- Mobile carriers that geo-resolve outside the user's home country (cellular providers often peer through regional hubs): validate by user-agent (mobile UA fingerprint) and source ASN (carrier networks).
- AWS Workspaces / VDI / corporate-cloud deployments where employees interactively sign in from a cloud ASN: validate the AS organization name and the tenant's cloud footprint, then except the specific ASN per-tenant rather than blanket-excluding cloud ASNs (which would also suppress adversary sign-ins from rented compute).

### Response and remediation

- If the pattern is unexpected, immediately revoke all refresh tokens for the user (`Revoke-AzureADUserAllRefreshToken` or `Revoke-MgUserSignInSession`) and force re-authentication, then reset the password and clear any recovery methods.
- Investigate any OAuth consent grants minted to the user around the same window — these survive password resets if not explicitly revoked.
- Review Entra audit logs for any newly registered authentication methods (FIDO key, authenticator app, phone number) added near the same window: these are adversary persistence vectors.
- Review device registration events (`Add registered owner to device`, `Add registered users to device`) — adversary device joins establish persistence that survives password rotation if the underlying refresh tokens were not revoked.
- Cross-check Azure activity logs (`logs-azure.activitylogs-*`) for any resource changes by the user from a non-baseline `source.ip` in the same window.
"""
references = ["https://any.run/malware-trends/tycoon/"]
risk_score = 73
rule_id = "bc9f5144-0ead-476e-ba6e-cef295601195"
severity = "high"
tags = [
    "Domain: Cloud",
    "Domain: Identity",
    "Data Source: Azure",
    "Data Source: Microsoft Entra ID",
    "Data Source: Microsoft Entra ID Sign-in Logs",
    "Use Case: Threat Detection",
    "Use Case: Identity and Access Audit",
    "Tactic: Initial Access",
    "Tactic: Credential Access",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"

query = '''
// successful interactive sign-ins with country + region populated.
from logs-azure.signinlogs-*
| where data_stream.dataset == "azure.signinlogs"
    and event.outcome == "success"
    and azure.signinlogs.category == "SignInLogs"
    and azure.signinlogs.properties.user_principal_name is not null
    and source.geo.location is not null
    and source.geo.region_name is not null

| eval Esql.source_geo_lat = st_y(source.geo.location),
       Esql.source_geo_lon = st_x(source.geo.location)

// collapse each (user, country, region) into one centroid + the actual lat/lon
// of the first and last event in that region. FIRST/LAST lock coords to the
// timestamp ordering so we can later build the honest event pair.
| stats
    Esql.region_centroid_lat = avg(Esql.source_geo_lat),
    Esql.region_centroid_lon = avg(Esql.source_geo_lon),
    Esql.region_first_lat    = first(Esql.source_geo_lat, @timestamp),
    Esql.region_first_lon    = first(Esql.source_geo_lon, @timestamp),
    Esql.region_last_lat     = last(Esql.source_geo_lat,  @timestamp),
    Esql.region_last_lon     = last(Esql.source_geo_lon,  @timestamp),
    Esql.region_first_seen   = min(@timestamp),
    Esql.region_last_seen    = max(@timestamp),
    Esql.region_event_count  = count(*),
    Esql.region_city_values   = values(source.geo.city_name),
    Esql.region_asn_values    = values(source.`as`.organization.name),
    Esql.region_ip_values     = values(source.ip),
    Esql.region_ua_values     = values(user_agent.original),
    Esql.region_app_id_values = values(azure.signinlogs.properties.app_id),
    Esql.region_app_display_name_values = values(azure.signinlogs.properties.app_display_name),
    Esql.region_client_app_used_values  = values(azure.signinlogs.properties.client_app_used),
    Esql.region_resource_id_values      = values(azure.signinlogs.properties.resource_id),
    Esql.region_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name),
    Esql.region_browser_values = values(azure.signinlogs.properties.device_detail.browser),
    Esql.region_os_values      = values(azure.signinlogs.properties.device_detail.operating_system)
  by azure.signinlogs.properties.user_principal_name,
     source.geo.country_name,
     source.geo.region_name

// roll up to the user. two parallel measurements:
// bbox: corners over region centroids. catches A->B->A because B is still
// a centroid in the set even when first/last events are in A.
| stats
    Esql.min_lat = min(Esql.region_centroid_lat),
    Esql.max_lat = max(Esql.region_centroid_lat),
    Esql.min_lon = min(Esql.region_centroid_lon),
    Esql.max_lon = max(Esql.region_centroid_lon),
    Esql.honest_first_lat = first(Esql.region_first_lat, Esql.region_first_seen),
    Esql.honest_first_lon = first(Esql.region_first_lon, Esql.region_first_seen),
    Esql.honest_last_lat  = last(Esql.region_last_lat,   Esql.region_last_seen),
    Esql.honest_last_lon  = last(Esql.region_last_lon,   Esql.region_last_seen),
    Esql.timestamp_first_seen = min(Esql.region_first_seen),
    Esql.timestamp_last_seen  = max(Esql.region_first_seen), // first arrival in last region > tighter bbox window
    Esql.honest_last_time     = max(Esql.region_last_seen),  // user's actual last event > honest window
    Esql.region_count  = count_distinct(source.geo.region_name),
    Esql.country_count = count_distinct(source.geo.country_name),
    Esql.event_count   = sum(Esql.region_event_count),
    Esql.source_geo_country_name_values     = values(source.geo.country_name),
    Esql.source_geo_region_name_values      = values(source.geo.region_name),
    Esql.source_geo_city_name_values        = values(Esql.region_city_values),
    Esql.source_as_organization_name_values = values(Esql.region_asn_values),
    Esql.source_ip_values                   = values(Esql.region_ip_values),
    Esql.user_agent_original_values         = values(Esql.region_ua_values),
    Esql.app_id_values                      = values(Esql.region_app_id_values),
    Esql.app_display_name_values            = values(Esql.region_app_display_name_values),
    Esql.client_app_used_values             = values(Esql.region_client_app_used_values),
    Esql.resource_id_values                 = values(Esql.region_resource_id_values),
    Esql.resource_display_name_values       = values(Esql.region_resource_display_name_values),
    Esql.device_detail_browser_values       = values(Esql.region_browser_values),
    Esql.device_detail_operating_system_values = values(Esql.region_os_values)
  by azure.signinlogs.properties.user_principal_name

// need at least 2 regions to have anything to compare. cap at 5 because regions
// are finer-grained than countries (a traveling employee can hit 3-4 in 90m via
// carrier hub bouncing) > bbox drift stays bounded below this.
| where Esql.region_count >= 2 and Esql.region_count <= 5

// bbox path (primary trigger): corners over region centroids.
| eval Esql.p1 = to_geopoint(concat("POINT(", to_string(Esql.min_lon), " ", to_string(Esql.min_lat), ")")),
       Esql.p2 = to_geopoint(concat("POINT(", to_string(Esql.max_lon), " ", to_string(Esql.max_lat), ")"))
| eval Esql.distance_km    = round(st_distance(Esql.p1, Esql.p2) / 1000.0, 0),
       Esql.window_minutes = date_diff("minute", Esql.timestamp_first_seen, Esql.timestamp_last_seen),
       Esql.travel_kmh     = case(Esql.window_minutes > 0,
                                  round(Esql.distance_km * 60.0 / Esql.window_minutes, 0), null)

// honest pair (triage signal): real coords at the user's actual first and last
// events, time locked to those same two events
| eval Esql.honest_p1 = to_geopoint(concat("POINT(", to_string(Esql.honest_first_lon), " ", to_string(Esql.honest_first_lat), ")")),
       Esql.honest_p2 = to_geopoint(concat("POINT(", to_string(Esql.honest_last_lon),  " ", to_string(Esql.honest_last_lat),  ")"))
| eval Esql.honest_distance_km     = round(st_distance(Esql.honest_p1, Esql.honest_p2) / 1000.0, 0),
       Esql.honest_window_minutes  = date_diff("minute", Esql.timestamp_first_seen, Esql.honest_last_time),
       Esql.honest_travel_kmh      = case(Esql.honest_window_minutes > 0,
                                          round(Esql.honest_distance_km * 60.0 / Esql.honest_window_minutes, 0), null)

// 500 km separation + faster than a commercial airliner. bbox is the trigger
// purely as triage signal.
| where Esql.distance_km >= 500 and Esql.travel_kmh >= 800

| keep azure.signinlogs.properties.user_principal_name,
    Esql.source_geo_country_name_values,
    Esql.source_geo_region_name_values,
    Esql.source_geo_city_name_values,
    Esql.source_as_organization_name_values,
    Esql.source_ip_values,
    Esql.user_agent_original_values,
    Esql.app_id_values,
    Esql.app_display_name_values,
    Esql.client_app_used_values,
    Esql.resource_id_values,
    Esql.resource_display_name_values,
    Esql.device_detail_browser_values,
    Esql.device_detail_operating_system_values,
    Esql.country_count,
    Esql.region_count,
    Esql.event_count,
    Esql.timestamp_first_seen,
    Esql.timestamp_last_seen,
    Esql.window_minutes,
    Esql.distance_km,
    Esql.travel_kmh,
    Esql.honest_distance_km,
    Esql.honest_travel_kmh,
    Esql.honest_window_minutes
'''

[rule.alert_suppression]
group_by = ["azure.signinlogs.properties.user_principal_name"]
duration = {value = 30, unit = "m"}
missing_fields_strategy = "suppress"

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



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

[[rule.threat.technique]]
id = "T1557"
name = "Adversary-in-the-Middle"
reference = "https://attack.mitre.org/techniques/T1557/"


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

[rule.investigation_fields]
field_names = ["azure.signinlogs.properties.user_principal_name"]

Stages and Predicates

Stage 1: from

from logs-azure.signinlogs-*

Stage 2: where

| where data_stream.dataset == "azure.signinlogs"
    and event.outcome == "success"
    and azure.signinlogs.category == "SignInLogs"
    and azure.signinlogs.properties.user_principal_name is not null
    and source.geo.location is not null
    and source.geo.region_name is not null

Stage 3: eval

| eval Esql.source_geo_lat = st_y(source.geo.location),
       Esql.source_geo_lon = st_x(source.geo.location)

Stage 4: stats

| stats
    Esql.region_centroid_lat = avg(Esql.source_geo_lat),
    Esql.region_centroid_lon = avg(Esql.source_geo_lon),
    Esql.region_first_lat    = first(Esql.source_geo_lat, @timestamp),
    Esql.region_first_lon    = first(Esql.source_geo_lon, @timestamp),
    Esql.region_last_lat     = last(Esql.source_geo_lat,  @timestamp),
    Esql.region_last_lon     = last(Esql.source_geo_lon,  @timestamp),
    Esql.region_first_seen   = min(@timestamp),
    Esql.region_last_seen    = max(@timestamp),
    Esql.region_event_count  = count(*),
    Esql.region_city_values   = values(source.geo.city_name),
    Esql.region_asn_values    = values(source.`as`.organization.name),
    Esql.region_ip_values     = values(source.ip),
    Esql.region_ua_values     = values(user_agent.original),
    Esql.region_app_id_values = values(azure.signinlogs.properties.app_id),
    Esql.region_app_display_name_values = values(azure.signinlogs.properties.app_display_name),
    Esql.region_client_app_used_values  = values(azure.signinlogs.properties.client_app_used),
    Esql.region_resource_id_values      = values(azure.signinlogs.properties.resource_id),
    Esql.region_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name),
    Esql.region_browser_values = values(azure.signinlogs.properties.device_detail.browser),
    Esql.region_os_values      = values(azure.signinlogs.properties.device_detail.operating_system)
  by azure.signinlogs.properties.user_principal_name,
     source.geo.country_name,
     source.geo.region_name

Stage 5: stats

| stats
    Esql.min_lat = min(Esql.region_centroid_lat),
    Esql.max_lat = max(Esql.region_centroid_lat),
    Esql.min_lon = min(Esql.region_centroid_lon),
    Esql.max_lon = max(Esql.region_centroid_lon),
    Esql.honest_first_lat = first(Esql.region_first_lat, Esql.region_first_seen),
    Esql.honest_first_lon = first(Esql.region_first_lon, Esql.region_first_seen),
    Esql.honest_last_lat  = last(Esql.region_last_lat,   Esql.region_last_seen),
    Esql.honest_last_lon  = last(Esql.region_last_lon,   Esql.region_last_seen),
    Esql.timestamp_first_seen = min(Esql.region_first_seen),
    Esql.timestamp_last_seen  = max(Esql.region_first_seen),
    Esql.honest_last_time     = max(Esql.region_last_seen),
    Esql.region_count  = count_distinct(source.geo.region_name),
    Esql.country_count = count_distinct(source.geo.country_name),
    Esql.event_count   = sum(Esql.region_event_count),
    Esql.source_geo_country_name_values     = values(source.geo.country_name),
    Esql.source_geo_region_name_values      = values(source.geo.region_name),
    Esql.source_geo_city_name_values        = values(Esql.region_city_values),
    Esql.source_as_organization_name_values = values(Esql.region_asn_values),
    Esql.source_ip_values                   = values(Esql.region_ip_values),
    Esql.user_agent_original_values         = values(Esql.region_ua_values),
    Esql.app_id_values                      = values(Esql.region_app_id_values),
    Esql.app_display_name_values            = values(Esql.region_app_display_name_values),
    Esql.client_app_used_values             = values(Esql.region_client_app_used_values),
    Esql.resource_id_values                 = values(Esql.region_resource_id_values),
    Esql.resource_display_name_values       = values(Esql.region_resource_display_name_values),
    Esql.device_detail_browser_values       = values(Esql.region_browser_values),
    Esql.device_detail_operating_system_values = values(Esql.region_os_values)
  by azure.signinlogs.properties.user_principal_name

Stage 6: where

| where Esql.region_count >= 2 and Esql.region_count <= 5

Stage 7: eval

| eval Esql.p1 = to_geopoint(concat("POINT(", to_string(Esql.min_lon), " ", to_string(Esql.min_lat), ")")),
       Esql.p2 = to_geopoint(concat("POINT(", to_string(Esql.max_lon), " ", to_string(Esql.max_lat), ")"))

Stage 8: eval

| eval Esql.distance_km    = round(st_distance(Esql.p1, Esql.p2) / 1000.0, 0),
       Esql.window_minutes = date_diff("minute", Esql.timestamp_first_seen, Esql.timestamp_last_seen),
       Esql.travel_kmh     = case(Esql.window_minutes > 0,
                                  round(Esql.distance_km * 60.0 / Esql.window_minutes, 0), null)
Esql.travel_kmh =
ifEsql.window_minutes > 0round(Esql.distance_km * 60.0 / Esql.window_minutes, 0)
elsenull

Stage 9: eval

| eval Esql.honest_p1 = to_geopoint(concat("POINT(", to_string(Esql.honest_first_lon), " ", to_string(Esql.honest_first_lat), ")")),
       Esql.honest_p2 = to_geopoint(concat("POINT(", to_string(Esql.honest_last_lon),  " ", to_string(Esql.honest_last_lat),  ")"))

Stage 10: eval

| eval Esql.honest_distance_km     = round(st_distance(Esql.honest_p1, Esql.honest_p2) / 1000.0, 0),
       Esql.honest_window_minutes  = date_diff("minute", Esql.timestamp_first_seen, Esql.honest_last_time),
       Esql.honest_travel_kmh      = case(Esql.honest_window_minutes > 0,
                                          round(Esql.honest_distance_km * 60.0 / Esql.honest_window_minutes, 0), null)
Esql.honest_travel_kmh =
ifEsql.honest_window_minutes > 0round(Esql.honest_distance_km * 60.0 / Esql.honest_window_minutes, 0)
elsenull

Stage 11: where

| where Esql.distance_km >= 500 and Esql.travel_kmh >= 800

Stage 12: keep

| keep azure.signinlogs.properties.user_principal_name,
    Esql.source_geo_country_name_values,
    Esql.source_geo_region_name_values,
    Esql.source_geo_city_name_values,
    Esql.source_as_organization_name_values,
    Esql.source_ip_values,
    Esql.user_agent_original_values,
    Esql.app_id_values,
    Esql.app_display_name_values,
    Esql.client_app_used_values,
    Esql.resource_id_values,
    Esql.resource_display_name_values,
    Esql.device_detail_browser_values,
    Esql.device_detail_operating_system_values,
    Esql.country_count,
    Esql.region_count,
    Esql.event_count,
    Esql.timestamp_first_seen,
    Esql.timestamp_last_seen,
    Esql.window_minutes,
    Esql.distance_km,
    Esql.travel_kmh,
    Esql.honest_distance_km,
    Esql.honest_travel_kmh,
    Esql.honest_window_minutes

Indicators

These rows show field, operator, and value matches.

Output Fields

These fields are emitted when the rule matches.

FieldSource
azure.signinlogs.properties.user_principal_nameKEEP azure.signinlogs.properties.user_principal_name
Esql.source_geo_country_name_valuesKEEP Esql.source_geo_country_name_values
Esql.source_geo_region_name_valuesKEEP Esql.source_geo_region_name_values
Esql.source_geo_city_name_valuesKEEP Esql.source_geo_city_name_values
Esql.source_as_organization_name_valuesKEEP Esql.source_as_organization_name_values
Esql.source_ip_valuesKEEP Esql.source_ip_values
Esql.user_agent_original_valuesKEEP Esql.user_agent_original_values
Esql.app_id_valuesKEEP Esql.app_id_values
Esql.app_display_name_valuesKEEP Esql.app_display_name_values
Esql.client_app_used_valuesKEEP Esql.client_app_used_values
Esql.resource_id_valuesKEEP Esql.resource_id_values
Esql.resource_display_name_valuesKEEP Esql.resource_display_name_values
Esql.device_detail_browser_valuesKEEP Esql.device_detail_browser_values
Esql.device_detail_operating_system_valuesKEEP Esql.device_detail_operating_system_values
Esql.country_countKEEP Esql.country_count
Esql.region_countKEEP Esql.region_count
Esql.event_countKEEP Esql.event_count
Esql.timestamp_first_seenKEEP Esql.timestamp_first_seen
Esql.timestamp_last_seenKEEP Esql.timestamp_last_seen
Esql.window_minutesKEEP Esql.window_minutes
Esql.distance_kmKEEP Esql.distance_km
Esql.travel_kmhKEEP Esql.travel_kmh
Esql.honest_distance_kmKEEP Esql.honest_distance_km
Esql.honest_travel_kmhKEEP Esql.honest_travel_kmh
Esql.honest_window_minutesKEEP Esql.honest_window_minutes

NotificationCenter Silenced via Killall Binary

#
Source
github.com/elastic/protections-artifacts

Detects when the killall process is spawned in order to kill NotificationCenter messages that provide users with pop up system notifications like security warnings etc.

MITRE ATT&CK Coverage

TacticTechniques
Defense Impairment

Telemetry Coverage

Rule Body

[rule]
description = """
Detects when the killall process is spawned in order to kill NotificationCenter messages that provide users with pop up
system notifications like security warnings etc.
"""
id = "5399e933-d4d7-47e5-a816-5d850729c26c"
license = "Elastic License v2"
name = "NotificationCenter Silenced via Killall Binary"
os_list = ["macos"]
reference = ["https://securelist.com/new-macos-backdoor-crypto-stealer/111778/"]
version = "1.0.6"

query = '''
process where event.type == "start" and event.action == "exec" and process.name == "killall" and
 process.args like "NotificationCenter" and
 (process.parent.executable like ("/Applications/*", "/Volumes/*", "/Users/*", "/private/tmp/*", "/tmp/*") or
  process.Ext.effective_parent.executable like ("/Applications/*", "/Volumes/*", "/Users/*", "/private/tmp/*", "/tmp/*")) and
  not (process.parent.code_signature.trusted == true and process.parent.code_signature.team_id in ("8CA6NAN723", "Y75Z7G683Y", "7JVNAY4725")) and
  not process.Ext.effective_parent.executable == "/Applications/Airtame.app/Contents/MacOS/Airtame"
'''

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 = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[[threat.technique.subtechnique]]
id = "T1562.006"
name = "Indicator Blocking"
reference = "https://attack.mitre.org/techniques/T1562/006/"



[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.type == "start" and event.action == "exec" and process.name == "killall" and
 process.args like "NotificationCenter" and
 (process.parent.executable like ("/Applications/*", "/Volumes/*", "/Users/*", "/private/tmp/*", "/tmp/*") or
  process.Ext.effective_parent.executable like ("/Applications/*", "/Volumes/*", "/Users/*", "/private/tmp/*", "/tmp/*")) and
  not (process.parent.code_signature.trusted == true and process.parent.code_signature.team_id in ("8CA6NAN723", "Y75Z7G683Y", "7JVNAY4725")) and
  not process.Ext.effective_parent.executable == "/Applications/Airtame.app/Contents/MacOS/Airtame"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • exec corpus 547 (elastic 547)
field:"EventType" kind:eq value:"exec"
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.Ext.effective_parent.executablewildcard
  • /Applications/* corpus 2 (elastic 2)
  • /Users/*
  • /Volumes/* corpus 2 (elastic 2)
  • /private/tmp/*
  • /tmp/*
field:"process.Ext.effective_parent.executable" kind:wildcard
process.argswildcard
  • NotificationCenter
field:"process.args" kind:wildcard value:"NotificationCenter"
process.nameeq
  • killall corpus 3 (elastic 3)
field:"process_basename" kind:eq value:"killall"
process.parent.executablewildcard
  • /Applications/* corpus 2 (elastic 2)
  • /Users/* corpus 2 (elastic 2)
  • /Volumes/* corpus 5 (elastic 5)
  • /private/tmp/* corpus 2 (elastic 2)
  • /tmp/* corpus 13 (elastic 13)
field:"ParentImage" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

Potential Browser Credentials Stealer

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

Identifies the creation of files with names related to web browser's credential store data. Adversaries may steal credentials from web browsers by reading files specific to the target browser.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the creation of files with names related to web browser's credential store data. Adversaries may steal
credentials from web browsers by reading files specific to the target browser.
"""
id = "d154bb87-dc5d-4e6e-8be8-24f631ef09ff"
license = "Elastic License v2"
name = "Potential Browser Credentials Stealer"
os_list = ["windows"]
version = "1.0.5"

query = '''
sequence by process.entity_id with maxspan=1s
[file where event.action == "creation" and process.pid != 4 and process.executable != null and process.name != null and
  not process.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*") and
  file.name : ("creditcards.db", "passwords.db", "autofilldata.db", "Google_Chome_Default.txt",
              "creditcards.txt", "passwords.txt", "autofilldata.txt", "AutoFill.txt", "Bookmarks.txt", "Cards.txt") and
  not (
    process.executable : (
      "C:\\Program Files (x86)\\Genesys\\GenesysCloud\\GenesysCloud.exe",
      "C:\\Program Files\\Genesys\\GenesysCloudBackgroundAssistant\\GcbaBrowser.exe",
      "C:\\Program Files (x86)\\Genesys\\GenesysCloudBackgroundAssistant\\GcbaBrowser.exe",
      "C:\\Program Files (x86)\\NWEA\\NWEA Secure Testing Browser\\NWEA Secure Testing Browser.exe") and
    file.name : "passwords.txt"
  )]
[file where event.action == "creation" and process.pid != 4 and process.executable != null and process.name != null and
  not process.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*") and
  file.name : ("creditcards.db", "passwords.db", "autofilldata.db", "Google_Chome_Default.txt",
               "creditcards.txt", "passwords.txt", "autofilldata.txt", "AutoFill.txt", "Bookmarks.txt", "Cards.txt")]
'''

min_endpoint_version = "8.1.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 = "T1539"
name = "Steal Web Session Cookie"
reference = "https://attack.mitre.org/techniques/T1539/"

[[threat.technique]]
id = "T1552"
name = "Unsecured Credentials"
reference = "https://attack.mitre.org/techniques/T1552/"
[[threat.technique.subtechnique]]
id = "T1552.001"
name = "Credentials In Files"
reference = "https://attack.mitre.org/techniques/T1552/001/"


[[threat.technique]]
id = "T1555"
name = "Credentials from Password Stores"
reference = "https://attack.mitre.org/techniques/T1555/"
[[threat.technique.subtechnique]]
id = "T1555.003"
name = "Credentials from Web Browsers"
reference = "https://attack.mitre.org/techniques/T1555/003/"



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

[internal]
min_endpoint_version = "8.1.0"

Stages and Predicates

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

Stage 1: file

[file where event.action == "creation" and process.pid != 4 and process.executable != null and process.name != null and
  not process.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*") and
  file.name : ("creditcards.db", "passwords.db", "autofilldata.db", "Google_Chome_Default.txt",
              "creditcards.txt", "passwords.txt", "autofilldata.txt", "AutoFill.txt", "Bookmarks.txt", "Cards.txt") and
  not (
    process.executable : (
      "C:\\Program Files (x86)\\Genesys\\GenesysCloud\\GenesysCloud.exe",
      "C:\\Program Files\\Genesys\\GenesysCloudBackgroundAssistant\\GcbaBrowser.exe",
      "C:\\Program Files (x86)\\Genesys\\GenesysCloudBackgroundAssistant\\GcbaBrowser.exe",
      "C:\\Program Files (x86)\\NWEA\\NWEA Secure Testing Browser\\NWEA Secure Testing Browser.exe") and
    file.name : "passwords.txt"
  )]

Stage 2: file

[file where event.action == "creation" and process.pid != 4 and process.executable != null and process.name != null and
  not process.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*") and
  file.name : ("creditcards.db", "passwords.db", "autofilldata.db", "Google_Chome_Default.txt",
               "creditcards.txt", "passwords.txt", "autofilldata.txt", "AutoFill.txt", "Bookmarks.txt", "Cards.txt")]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • creation corpus 50 (elastic 50)
field:"EventType" kind:eq value:"creation"
file.namewildcard
  • AutoFill.txt
  • Bookmarks.txt
  • Cards.txt
  • Google_Chome_Default.txt
  • autofilldata.db
  • autofilldata.txt
  • creditcards.db
  • creditcards.txt
  • passwords.db
  • passwords.txt
field:"file.name" kind:wildcard
process.executableis_not_null
  • (no value, null check)
field:"Image" kind:is_not_null
process.nameis_not_null
  • (no value, null check)
field:"process_basename" kind:is_not_null
process.pidne
  • 4 transforms: number corpus 44 (elastic 44)
field:"process_id" kind:ne value:"4"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
file.nameeqpasswords.txtexcludes:file.name field:"file.name" value:"passwords.txt"
process.executableeqC:\Program Files (x86)\Genesys\GenesysCloud\GenesysCloud.exe, C:\Program Files\Genesys\GenesysCloudBackgroundAssistant\GcbaBrowser.exe, C:\Program Files (x86)\Genesys\GenesysCloudBackgroundAssistant\GcbaBrowser.exe, C:\Program Files (x86)\NWEA\NWEA Secure Testing Browser\NWEA Secure Testing Browser.exeexcludes:process.executable
process.code_signature.statuswildcardtrusted, errorExpired, errorCode_endpoint*excludes:process.code_signature.status field:"process.code_signature.status" value:"trusted" field:"process.code_signature.status" value:"errorExpired" field:"process.code_signature.status" value:"errorCode_endpoint*"

Potential Chroot Container Escape via Mount

#
Status
production
Severity
high
Time window
5m
Sequence by
host.id, process.parent.entity_id
Author
Elastic
Source
github.com/elastic/detection-rules

Monitors for the execution of a file system mount followed by a chroot execution. Given enough permissions, a user within a container is capable of mounting the root file system of the host, and leveraging chroot to escape its containarized environment. This behavior pattern is very uncommon and should be investigated.

MITRE ATT&CK Coverage

TacticTechniques
Privilege Escalation

Rule Body

[metadata]
creation_date = "2024/01/15"
integration = ["endpoint", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/04/27"

[rule]
author = ["Elastic"]
description = """
Monitors for the execution of a file system mount followed by a chroot execution. Given enough permissions, a user
within a container is capable of mounting the root file system of the host, and leveraging chroot to escape its
containarized environment. This behavior pattern is very uncommon and should be investigated.
"""
from = "now-9m"
index = ["logs-endpoint.events.process*", "logs-sentinel_one_cloud_funnel.*", "logs-crowdstrike.fdr*"]
language = "eql"
license = "Elastic License v2"
name = "Potential Chroot Container Escape via Mount"
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 Chroot Container Escape via Mount

Chroot and mount are Linux utilities that can isolate processes and manage file systems, respectively. Adversaries may exploit these to escape containerized environments by mounting the host's root file system and using chroot to change the root directory, gaining unauthorized access. The detection rule identifies this rare sequence by monitoring for mount and chroot executions within a short timeframe, signaling potential privilege escalation attempts.

### Possible investigation steps

- Review the alert details to identify the specific host.id and process.parent.entity_id associated with the alert to understand which system and parent process are involved.
- Examine the process execution timeline to confirm the sequence of the mount and chroot commands, ensuring they occurred within the specified maxspan of 5 minutes.
- Investigate the process.args field for the mount command to determine the specific device or file system being targeted, especially focusing on any /dev/sd* entries that suggest attempts to access physical disks.
- Check the user permissions and roles associated with the process.parent.name (e.g., bash, dash, sh) to assess if the user had sufficient privileges to perform such operations.
- Analyze the broader context of the host.os.type to identify any recent changes or anomalies in the Linux environment that could have facilitated this behavior.
- Correlate with other security logs or alerts from the same host to identify any additional suspicious activities or patterns that might indicate a broader attack or compromise.

### False positive analysis

- System maintenance scripts may trigger the rule if they involve mounting and chroot operations. Review scheduled tasks and scripts to identify legitimate use and consider excluding these specific processes from the rule.
- Backup or recovery operations that require mounting file systems and changing root directories can also cause false positives. Identify these operations and create exceptions for the associated processes or users.
- Development or testing environments where users frequently perform mount and chroot operations for legitimate purposes may trigger alerts. Evaluate the necessity of these actions and exclude known safe processes or users.
- Automated deployment tools that use mount and chroot as part of their setup routines can be mistaken for malicious activity. Verify the tools and their processes, then add them to an exclusion list if they are deemed safe.
- Custom scripts executed by trusted users that involve mount and chroot should be reviewed. If these scripts are part of regular operations, consider excluding them from the detection rule.

### Response and remediation

- Immediately isolate the affected container to prevent further unauthorized access or potential lateral movement within the host system.
- Terminate any suspicious processes identified as executing the mount or chroot commands within the container to halt any ongoing escape attempts.
- Conduct a thorough review of the container's permissions and configurations to ensure that only necessary privileges are granted, reducing the risk of similar exploits.
- Inspect the host system for any signs of compromise or unauthorized access, focusing on logs and system changes around the time of the detected activity.
- Restore the container from a known good backup if any unauthorized changes or compromises are detected, ensuring the environment is clean and secure.
- Update and patch the container and host systems to address any known vulnerabilities that could be exploited for privilege escalation or container escape.
- Escalate the incident to the security operations team for further analysis and to determine if additional monitoring or security measures are required to prevent future occurrences."""
references = [
    "https://book.hacktricks.xyz/v/portugues-ht/linux-hardening/privilege-escalation/escaping-from-limited-bash",
]
risk_score = 73
rule_id = "5ae02ebc-a5de-4eac-afe6-c88de696477d"
setup = """## Setup


This rule requires data coming in from Elastic Defend.

### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.

#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).

#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).

Session View uses process data collected by the Elastic Defend integration, but this data is not always collected by default. Session View is available on enterprise subscription for versions 8.3 and above.
#### To confirm that Session View data is enabled:
- Go to “Manage → Policies”, and edit one or more of your Elastic Defend integration policies.
- Select the” Policy settings” tab, then scroll down to the “Linux event collection” section near the bottom.
- Check the box for “Process events”, and turn on the “Include session data” toggle.
- If you want to include file and network alerts in Session View, check the boxes for “Network and File events”.
- If you want to enable terminal output capture, turn on the “Capture terminal output” toggle.
For more information about the additional fields collected when this setting is enabled and the usage of Session View for Analysis refer to the [helper guide](https://www.elastic.co/guide/en/security/current/session-view.html).
"""
severity = "high"
tags = [
  "Domain: Endpoint",
  "OS: Linux",
  "Use Case: Threat Detection",
  "Tactic: Privilege Escalation",
  "Domain: Container",
  "Data Source: Elastic Defend",
  "Data Source: SentinelOne",
  "Resources: Investigation Guide",
  "Data Source: Crowdstrike",
]
type = "eql"

query = '''
sequence by host.id, process.parent.entity_id with maxspan=5m
  [process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "start", "ProcessRollup2") and
   process.name == "mount" and process.args : "/dev/sd*" and process.args_count >= 3 and
   process.parent.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish")]
  [process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "start", "ProcessRollup2") and
   process.name == "chroot"]
'''


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


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

Stages and Predicates

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

Stage 1: process

[process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "start", "ProcessRollup2") and
   process.name == "mount" and process.args : "/dev/sd*" and process.args_count >= 3 and
   process.parent.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish")]

Stage 2: process

[process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "start", "ProcessRollup2") and
   process.name == "chroot"]

Indicators

These rows show field, operator, and value matches.

Potential DLL Hollowing from a Writable Image

#
Source
github.com/elastic/protections-artifacts

Identifies attempts to stealthily execute malicious code using DLL hollowing technique from a writable image.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = "Identifies attempts to stealthily execute malicious code using DLL hollowing technique from a writable image."
id = "9d0b29fc-df7a-4ebb-b082-3d6579193beb"
license = "Elastic License v2"
name = "Potential DLL Hollowing from a Writable Image"
os_list = ["windows"]
reference = ["https://www.elastic.co/blog/process-ghosting-a-new-executable-image-tampering-attack"]
version = "1.0.4"

query = '''
library where
  dll.Ext.defense_evasions : "Process Tampering: Image is writable" and
  dll.Ext.defense_evasions : "Process Tampering: Image has write sharing" and
  dll.Ext.defense_evasions : "Process Tampering: Image has been accessed before mapping"
'''

min_endpoint_version = "8.7.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true

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

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

[[threat.technique]]
id = "T1211"
name = "Exploitation for Defense Evasion"
reference = "https://attack.mitre.org/techniques/T1211/"

[[threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"


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

[internal]
min_endpoint_version = "8.7.0"

Stages and Predicates

Stage 1: library

library where
  dll.Ext.defense_evasions : "Process Tampering: Image is writable" and
  dll.Ext.defense_evasions : "Process Tampering: Image has write sharing" and
  dll.Ext.defense_evasions : "Process Tampering: Image has been accessed before mapping"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
dll.Ext.defense_evasionswildcard
  • Process Tampering: Image has been accessed before mapping corpus 2 (elastic 2)
  • Process Tampering: Image has write sharing
  • Process Tampering: Image is writable corpus 2 (elastic 2)
field:"dll.Ext.defense_evasions" kind:wildcard

Potential Injection via Asynchronous Procedure Call

#
Source
github.com/elastic/protections-artifacts

Identifies attempts to queue an Asynchronous Procedure Call (APC) to a remote process. This may indicate a remote code injection attack.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies attempts to queue an Asynchronous Procedure Call (APC) to a remote process. This may indicate a remote code
injection attack.
"""
id = "2316b571-731d-4745-97ac-4fd6922d32df"
license = "Elastic License v2"
name = "Potential Injection via Asynchronous Procedure Call"
os_list = ["windows"]
reference = [
    "https://www.elastic.co/security-labs/doubling-down-etw-callstacks",
    "https://www.ired.team/offensive-security/code-injection-process-injection/apc-queue-code-injection",
]
version = "1.0.7"

query = '''
api where process.pid != 4 and process.Ext.api.behaviors == "cross-process" and
 (
  (process.Ext.api.name == "QueueUserAPC" and process.Ext.api.behaviors == "execute_shellcode" and process.Ext.api.summary like "*Unbacked*NULL*") or
  (process.Ext.api.name == "NtQueueApcThread" and process.Ext.api.summary like "*ntdll.dll!RtlEncodeRemotePointer*")
  )
'''

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

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"
[[threat.technique.subtechnique]]
id = "T1055.004"
name = "Asynchronous Procedure Call"
reference = "https://attack.mitre.org/techniques/T1055/004/"



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

[internal]
min_endpoint_version = "8.8.0"

Stages and Predicates

Stage 1: api

api where process.pid != 4 and process.Ext.api.behaviors == "cross-process" and
 (
  (process.Ext.api.name == "QueueUserAPC" and process.Ext.api.behaviors == "execute_shellcode" and process.Ext.api.summary like "*Unbacked*NULL*") or
  (process.Ext.api.name == "NtQueueApcThread" and process.Ext.api.summary like "*ntdll.dll!RtlEncodeRemotePointer*")
  )

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
process.Ext.api.behaviorseq
  • cross-process corpus 18 (elastic 18)
  • execute_shellcode corpus 2 (elastic 2)
field:"process.Ext.api.behaviors" kind:eq
process.Ext.api.nameeq
  • NtQueueApcThread
  • QueueUserAPC
field:"process.Ext.api.name" kind:eq
process.Ext.api.summarywildcard
  • *Unbacked*NULL*
  • *ntdll.dll!RtlEncodeRemotePointer*
field:"process.Ext.api.summary" kind:wildcard
process.pidne
  • 4 transforms: number corpus 44 (elastic 44)
field:"process_id" kind:ne value:"4"

Potential Linux Tunneling and/or Port Forwarding via Command Line

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

This rule monitors for potential tunneling and/or port forwarding activity on Linux systems via command line utilities. Attackers may use various tools to create covert communication channels, allowing them to bypass network security measures and maintain persistent access to compromised systems. By leveraging these utilities, attackers can tunnel traffic through legitimate protocols, making detection more challenging.

MITRE ATT&CK Coverage

TacticTechniques
Command & Control

Rule Body

[metadata]
creation_date = "2025/12/12"
integration = ["endpoint", "crowdstrike", "sentinel_one_cloud_funnel", "auditd_manager"]
maturity = "production"
updated_date = "2026/03/24"

[transform]
[[transform.osquery]]
label = "Osquery - Retrieve Listening Ports"
query = "SELECT pid, address, port, socket, protocol, path FROM listening_ports"

[[transform.osquery]]
label = "Osquery - Retrieve Open Sockets"
query = "SELECT pid, family, remote_address, remote_port, socket, state FROM process_open_sockets"

[[transform.osquery]]
label = "Osquery - Retrieve Information for a Specific User"
query = "SELECT * FROM users WHERE username = {{user.name}}"

[[transform.osquery]]
label = "Osquery - Investigate the Account Authentication Status"
query = "SELECT * FROM logged_in_users WHERE user = {{user.name}}"

[[transform.osquery]]
label = "Osquery - Retrieve Running Processes by User"
query = "SELECT pid, username, name FROM processes p JOIN users u ON u.uid = p.uid ORDER BY username"

[[transform.osquery]]
label = "Osquery - Retrieve Process Info"
query = "SELECT name, cmdline, parent, path, uid FROM processes"


[rule]
author = ["Elastic"]
description = """
This rule monitors for potential tunneling and/or port forwarding activity on Linux systems via command line utilities. Attackers may use
various tools to create covert communication channels, allowing them to bypass network security measures and maintain persistent access
to compromised systems. By leveraging these utilities, attackers can tunnel traffic through legitimate protocols, making detection more
challenging.
"""
from = "now-9m"
index = [
    "endgame-*",
    "logs-crowdstrike.fdr*",
    "logs-endpoint.events.process*",
    "logs-sentinel_one_cloud_funnel.*",
    "auditbeat-*",
    "logs-auditd_manager.auditd-*",
]
language = "eql"
license = "Elastic License v2"
name = "Potential Linux Tunneling and/or Port Forwarding via Command Line"
note = """## Triage and analysis

### Investigating Potential Linux Tunneling and/or Port Forwarding via Command Line

Attackers can leverage many utilities to clandestinely tunnel network communications and evade security measures, potentially gaining unauthorized access to sensitive systems.

This rule looks for several utilities that are capable of setting up tunnel network communications by analyzing process names or command line arguments. 

> **Note**:
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/current/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.
> This investigation guide uses [placeholder fields](https://www.elastic.co/guide/en/security/current/osquery-placeholder-fields.html) to dynamically pass alert data into Osquery queries. Placeholder fields were introduced in Elastic Stack version 8.7.0. If you're using Elastic Stack version 8.6.0 or earlier, you'll need to manually adjust this investigation guide's queries to ensure they properly run.

#### Possible investigation steps

- Identify any signs of suspicious network activity or anomalies that may indicate protocol tunneling. This could include unexpected traffic patterns or unusual network behavior.
  - Investigate listening ports and open sockets to look for potential protocol tunneling, reverse shells, or data exfiltration.
    - $osquery_0
    - $osquery_1
- Identify the user account that performed the action, analyze it, and check whether it should perform this kind of action.
  - $osquery_2
- Investigate whether the user is currently logged in and active.
  - $osquery_3
- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence and whether they are located in expected locations.
  - $osquery_4
  - $osquery_5
- Investigate other alerts associated with the user/host during the past 48 hours.
  - If scripts or executables were dropped, retrieve the files and determine if they are malicious:
    - Use a private sandboxed malware analysis system to perform analysis.
      - Observe and collect information about the following activities:
        - Attempts to contact external domains and addresses.
          - Check if the domain is newly registered or unexpected.
          - Check the reputation of the domain or IP address.
        - File access, modification, and creation activities.

### Related rules

- Potential Linux Tunneling and/or Port Forwarding via SSH Option - ef395dff-be12-4a6e-8919-d87d627c2174
- Potential Linux Tunneling and/or Port Forwarding - 6ee947e9-de7e-4281-a55d-09289bdf947e
- Potential Protocol Tunneling via Chisel Client - 3f12325a-4cc6-410b-8d4c-9fbbeb744cfd
- Potential Protocol Tunneling via Chisel Server - ac8805f6-1e08-406c-962e-3937057fa86f
- Potential Protocol Tunneling via EarthWorm - 9f1c4ca3-44b5-481d-ba42-32dc215a2769
- Suspicious Utility Launched via ProxyChains - 6ace94ba-f02c-4d55-9f53-87d99b6f9af4
- ProxyChains Activity - 4b868f1f-15ff-4ba3-8c11-d5a7a6356d37

### False positive analysis

- If this activity is related to new benign software installation activity, consider adding exceptions — preferably with a combination of user and command line conditions.
- If this activity is related to a system administrator or developer who uses port tunneling/forwarding for benign purposes, consider adding exceptions for specific user accounts or hosts. 
- Try to understand the context of the execution by thinking about the user, machine, or business purpose. A small number of endpoints, such as servers with unique software, might appear unusual but satisfy a specific business need.

### Response and remediation

- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- If the triage identified malware, search the environment for additional compromised hosts.
  - Implement temporary network rules, procedures, and segmentation to contain the malware.
  - Stop suspicious processes.
  - Immediately block the identified indicators of compromise (IoCs).
  - Inspect the affected systems for additional malware backdoors, such as reverse shells, reverse proxies, or droppers, that attackers could use to reinfect the system.
- Remove and block malicious artifacts identified during triage.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Leverage the incident response data and logging to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
references = [
    "https://blog.bitsadmin.com/living-off-the-foreign-land-windows-as-offensive-platform",
    "https://book.hacktricks.xyz/generic-methodologies-and-resources/tunneling-and-port-forwarding",
    "https://github.com/erebe/wstunnel"
]
risk_score = 47
rule_id = "8c8df61f-ed2a-4832-87b8-ee30812606e0"
setup = """## Setup

This rule requires data coming in from Elastic Defend.

### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.

#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).

#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Command and Control",
    "Data Source: Elastic Defend",
    "Data Source: Elastic Endgame",
    "Data Source: Crowdstrike",
    "Data Source: SentinelOne",
    "Data Source: Auditd Manager",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "exec_event", "start", "ProcessRollup2", "executed", "process_started") and 
process.command_line regex """.*[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:[0-9]{1,5}:[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:[0-9]{1,5}.*"""
'''

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

[[rule.threat.technique]]
id = "T1090"
name = "Proxy"
reference = "https://attack.mitre.org/techniques/T1090/"

[[rule.threat.technique]]
id = "T1572"
name = "Protocol Tunneling"
reference = "https://attack.mitre.org/techniques/T1572/"

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

Stages and Predicates

Stage 1: process

process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "exec_event", "start", "ProcessRollup2", "executed", "process_started") and 
process.command_line regex """.*[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:[0-9]{1,5}:[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:[0-9]{1,5}.*"""

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actionin
  • ProcessRollup2
  • exec
  • exec_event
  • executed
  • process_started
  • start
field:"EventType" kind:in
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
process.command_lineregex_match
  • .*[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}:[0-9]{1,5}:[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}:[0-9]{1,5}.*
field:"CommandLine" kind:regex_match value:".*[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}:[0-9]{1,5}:[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}:[0-9]{1,5}.*"

Potential PowerShell Obfuscation via High Special Character Proportion

#
Status
production
Kind
building block (feeds higher-level correlation rules; not a standalone alert)
Severity
low
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies PowerShell script block content with an unusually high proportion of non-alphanumeric characters, often produced by encoding, string mangling, or dynamic code generation. Attackers use special-character heavy obfuscation to conceal payloads and hinder static analysis and AMSI.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

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

[rule]
author = ["Elastic"]
building_block_type = "default"
description = """
Identifies PowerShell script block content with an unusually high proportion of non-alphanumeric characters, often
produced by encoding, string mangling, or dynamic code generation. Attackers use special-character heavy obfuscation to
conceal payloads and hinder static analysis and AMSI.
"""
from = "now-9m"
language = "esql"
license = "Elastic License v2"
name = "Potential PowerShell Obfuscation via High Special Character Proportion"
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 Potential PowerShell Obfuscation via High Special Character Proportion

This rule alerts on PowerShell Script Block Logging content where non-alphanumeric characters make up an unusually large share of the script text. This pattern is frequently produced by encoding, aggressive escaping, string mangling, or dynamic code generation intended to hinder inspection.

The alert includes scoring and script-shape fields that help distinguish benign embedded data from suspicious deobfuscation/execution logic. Treat the script block text as potentially untrusted content and focus on reconstructing the full script and identifying downstream behavior through correlation.

#### 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_ratio`: Proportion of the script block's characters that match the alert's target character set, divided by total script length (0-1).
- `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 scope and execution context:
  - Review `@timestamp` to set an investigation window and identify preceding/follow-on activity.
  - Identify the affected `host.id`/`host.name` and the executing `user.id`/`user.name`/`user.domain`.
  - Determine whether the user/host pairing is expected for PowerShell usage in your environment and whether the account is privileged or widely used.

- Interpret the alert scoring and "shape" signals:
  - Review `Esql.script_block_ratio` and `Esql.script_block_pattern_count` alongside `powershell.file.script_block_length` to understand how extreme the special-character density is.
  - Use `Esql.script_block_tmp` to quickly assess whether the special characters cluster in a single region (for example, one embedded blob) or are distributed throughout the script (for example, pervasive mangling).
  - Use `powershell.file.script_block_entropy_bits`, `powershell.file.script_block_unique_symbols`, and `powershell.file.script_block_surprisal_stdev` to guide prioritization:
    - High entropy with many unique symbols commonly aligns with encoded/compressed/encrypted blobs embedded in the script.
    - High special-character ratio with lower entropy can align with heavy escaping, string concatenation, or code generation.
    - Low surprisal variability (low standard deviation) can indicate uniformly random-looking content typical of dense encoding.

- Reconstruct the full script block before making a determination:
  - Pivot on `powershell.file.script_block_id` to collect all fragments for the script block.
  - Reassemble fragments in order using `powershell.sequence` and confirm completeness using `powershell.total`.
  - If fragments are missing, treat the visible content as incomplete and continue collection/scoping before concluding intent.

- Analyze `powershell.file.script_block_text` for intent and technique:
  - Identify whether the content is primarily data (for example, long opaque strings) or executable logic (functions, control flow, and invocation).
  - Look for common deobfuscation and dynamic execution patterns, such as:
    - Decoding/decompression routines (for example, Base64 decoding, byte/char transformations, compression streams).
    - Dynamic invocation or staged execution (for example, `Invoke-Expression`/`IEX`, reflection, `.Invoke()`, `Add-Type`).
    - Retrieval of remote content or secondary payloads (for example, web request/client usage, download-and-execute flow).
  - If the script includes clear indicators (domains, URLs, IP addresses, file paths, file names), capture them from the script text for pivoting and scoping.

- Determine provenance and expectedness using available file context:
  - If `file.path`/`file.directory`/`file.name` are present, assess whether the location and naming align with known administrative scripts or approved automation.
  - If file fields are absent, treat the activity as potentially interactive or in-memory and prioritize identifying what initiated PowerShell through adjacent host telemetry.

- Correlate with adjacent telemetry (as available in your environment) to confirm impact:
  - Process activity on the same host and time window to determine the initiating process and whether PowerShell was launched indirectly.
  - Network activity to identify outbound connections consistent with download, staging, or command-and-control behavior.
  - File and registry activity to identify dropped artifacts or persistence-related changes.
  - Authentication activity for the same `user.id` to identify suspicious logons or lateral movement preceding the script execution.

- Expand scope across the environment:
  - Search for additional script block events on the same `host.id` and `user.id` near the alert time to identify staged execution (for example, decoding in one block, execution in another).
  - Hunt for similar script content using stable substrings from `powershell.file.script_block_text`, and group by `file.name` or `file.path` when present to identify reuse.

### False positive analysis

- False positives are most likely when scripts embed or manipulate large non-code payloads (for example, serialized objects, structured data, certificates, or compressed content) or when tooling auto-generates scripts with heavy escaping and templating.
- Validate benign hypotheses by confirming a consistent execution pattern over time (recurring `host.id` and `user.id`), expected provenance (`file.path`/`file.name` when present), and script content that performs known administrative functions rather than decoding and executing newly generated code.
- Treat unexpected execution context (new user/host pairing) combined with high entropy and opaque content as higher risk, even if the script text does not immediately reveal its final payload.

### Response and remediation

- If malicious or suspicious activity is confirmed:
  - Contain the affected host to prevent additional execution and lateral movement.
  - Preserve evidence from the alert, including `powershell.file.script_block_text`, reconstructed fragments (if applicable), `powershell.file.script_block_id`, and the scoring fields (`Esql.script_block_ratio`, `Esql.script_block_pattern_count`, `powershell.file.script_block_entropy_bits`).
  - Identify and remediate follow-on behavior discovered during correlation (downloaded payloads, dropped files, persistence changes, or suspicious network destinations).
  - Scope the intrusion by searching for similar script content across the environment using stable substrings from `powershell.file.script_block_text`, and by pivoting on `user.id`, `host.id`, `file.path`, and `file.name`.
  - If account compromise is suspected, reset credentials for the affected user and review other recent activity for that `user.id`.

- If the activity is determined benign:
  - Document the responsible script or workflow, expected execution context, and typical frequency.
  - Monitor for deviations such as new hosts, new users, or materially different script content that may indicate abuse of a legitimate mechanism.
"""
risk_score = 21
rule_id = "f9753455-8d55-4ad8-b70a-e07b6f18deea"
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",
    "Rule Type: BBR",
    "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 > 1000

// 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
// Excludes spaces, #, = and - as they are heavily used in scripts for formatting
| eval Esql.script_block_tmp = replace(powershell.file.script_block_text, """[^0-9A-Za-z\s#=-]""", "🔥")

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

// Calculate the ratio of special characters to total length
| eval Esql.script_block_ratio = Esql.script_block_pattern_count::double / Esql.script_block_length::double

// 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_ratio,
    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 with high special character ratio
| where Esql.script_block_ratio > 0.35

// Exclude Noisy Patterns
| where not file.directory like "C:\\\\ProgramData\\\\Microsoft\\\\Windows Defender Advanced Threat Protection\\\\DataCollection\\\\*"
  // 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 > 1000

Stage 5: eval

| eval Esql.script_block_tmp = replace(powershell.file.script_block_text, """[^0-9A-Za-z\s#=-]""", "🔥")

Stage 6: eval

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

Stage 7: eval

| eval Esql.script_block_ratio = Esql.script_block_pattern_count::double / Esql.script_block_length::double

Stage 8: keep

| keep
    Esql.script_block_pattern_count,
    Esql.script_block_length,
    Esql.script_block_ratio,
    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 9: where

| where Esql.script_block_ratio > 0.35

Stage 10: where

| where not file.directory like "C:\\\\ProgramData\\\\Microsoft\\\\Windows Defender Advanced Threat Protection\\\\DataCollection\\\\*"
  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_ratioKEEP Esql.script_block_ratio
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

Potential PowerShell Obfuscation via Reverse Keywords

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

Detects PowerShell scripts containing reversed keyword strings associated with execution or network activity (for example, ekovni, noisserpxe, daolnwod, tcejbo-wen, tcejboimw, etc.). Attackers reverse keywords and reconstruct them at runtime to hide intent and evade static detection and AMSI.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

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

[rule]
author = ["Elastic"]
description = """
Detects PowerShell scripts containing reversed keyword strings associated with execution or network activity (for
example, ekovni, noisserpxe, daolnwod, tcejbo-wen, tcejboimw, etc.). Attackers reverse keywords and reconstruct them at
runtime to hide intent and evade static detection and AMSI.
"""
from = "now-9m"
language = "esql"
license = "Elastic License v2"
name = "Potential PowerShell Obfuscation via Reverse Keywords"
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 Potential PowerShell Obfuscation via Reverse Keywords

This alert indicates PowerShell script block content contains multiple reversed keyword strings commonly associated with execution, string manipulation, environment discovery, or networking. Reversing strings is frequently paired with runtime reconstruction (for example, reversing character arrays or joining string fragments) to reduce readability and evade simple content inspection.

Determine whether the script is part of expected administrative automation, software tooling, or an unauthorized execution chain. Prioritize analysis that reconstructs the full script, deobfuscates the reversed tokens, and identifies any follow-on behaviors such as dynamic execution, network access, or system discovery.

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

- Identify the execution scope and ownership:
  - Review `host.name` / `host.id` to confirm the affected endpoint and its criticality.
  - Review `user.id` (and `user.name` / `user.domain` if available) to understand the account context and whether this user is expected to run PowerShell on this host.
- Prioritize based on obfuscation signals:
  - Review `Esql.script_block_pattern_count`; higher counts suggest more extensive keyword hiding and can increase suspicion.
  - Use `powershell.file.script_block_length`, `powershell.file.script_block_entropy_bits`, `powershell.file.script_block_unique_symbols`, and `powershell.file.script_block_surprisal_stdev` to gauge how heavily obfuscated or machine-generated the content may be (treat these as supporting context, not proof of maliciousness).
- Reconstruct the full script content when split:
  - If `powershell.total` is greater than 1, retrieve all events with the same `powershell.file.script_block_id` and order them by `powershell.sequence` to rebuild the complete script block content.
  - Preserve both the reconstructed script and the original per-event `powershell.file.script_block_text` to maintain context and ordering.
- Deobfuscate and interpret intent:
  - Review `powershell.file.script_block_text` for reversed tokens and reverse them to identify the intended keywords and operations (for example, indicators of dynamic execution, downloads, socket/connection handling, WMI usage, or Win32 references).
  - Look for runtime string reconstruction patterns in the script content (for example, joins, character array operations, or replace operations) that turn reversed fragments into executable commands or parameters.
  - Use `Esql.script_block_tmp` to quickly locate the matched areas, then validate findings against `powershell.file.script_block_text`.
- Evaluate file-origin context (when present):
  - Review `file.path` (and `file.directory` / `file.name` if available) to determine whether the script is associated with an on-disk file and whether that location aligns with your organization's expected script locations and deployment practices.
  - If an on-disk script is indicated, coordinate collection of the referenced file for offline analysis and determine whether it is present on other systems.
- Extract and operationalize indicators:
  - From `powershell.file.script_block_text`, extract any embedded indicators such as hostnames, IP addresses, URLs, ports, file paths, or encoded blobs.
  - Use extracted indicators to scope for related activity on the same `host.id` and across other hosts where the same `user.id` is active, focusing on the alert timeframe and immediately adjacent activity.
- Correlate with adjacent telemetry to identify the execution chain and impact (as available in your environment):
  - Process activity: identify the PowerShell host process and the initiating parent process to understand whether execution was interactive, scheduled, or launched by another program.
  - Network activity: look for outbound connections aligned with the alert timestamp, especially if deobfuscated content suggests downloads or socket connections.
  - File and registry activity: look for payload staging, new or modified files, or persistence-related changes that occur shortly after the script block execution.
  - Authentication activity: review for suspicious logons, remote session creation, or lateral movement attempts around the same time on the affected host.
- Determine severity and next actions:
  - If the deobfuscated content indicates remote retrieval, execution of downloaded content, credential access, persistence, or lateral movement, treat the alert as potentially malicious and escalate for response.
  - If the script appears benign, document the validated purpose, expected owner, and any recurring identifiers (such as file location patterns) to support future triage.

### False positive analysis

- Internal scripts or tooling may use reversed strings as lightweight obfuscation to conceal configuration values or reduce casual readability. Validate the script's ownership, change history, and whether its presence and execution timing are expected for `host.id` and `user.id`.
- Commercial software, endpoint management agents, or security tooling may generate or embed obfuscated PowerShell during installation, updates, or health checks. Validate whether the activity aligns with known maintenance windows, expected endpoints, and consistent script content and `file.path` patterns.
- Authorized security testing may intentionally use string reversal. Confirm the scope, timing, and target hosts with the appropriate stakeholders before closing the alert.

### Response and remediation

- If activity is suspicious or unauthorized, contain the affected host to prevent further script execution and potential follow-on actions.
- Preserve evidence:
  - Retain the full `powershell.file.script_block_text` (including all segments reconstructed via `powershell.file.script_block_id`, `powershell.sequence`, and `powershell.total`).
  - Retain `file.path` context and the alert metadata needed to pivot (such as `host.id` and `user.id`).
- Identify and remediate the execution source:
  - Determine how PowerShell was launched (interactive, scheduled, or by another process) using correlated telemetry, and remove the triggering mechanism.
  - If an on-disk script is involved, remediate the file at `file.path` and any associated payloads or artifacts identified during analysis.
- Scope and hunt:
  - Search for the same or similar obfuscated content and extracted indicators across other endpoints, prioritizing systems accessed by the same `user.id` and systems with similar `file.path` patterns.
- Account actions:
  - If account misuse is suspected, follow organizational procedures to contain the account (for example, credential reset and session revocation) and review recent activity for additional suspicious behavior.
- Recovery and hardening:
  - Verify PowerShell logging coverage and retention are sufficient for incident response, and monitor for recurrence of similar reversed-keyword patterns on affected hosts and users.
"""
risk_score = 21
rule_id = "f38633f4-3b31-4c80-b13d-e77c70ce8254"
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 for scripts that contains these keywords using MATCH, boosts the query performance,
// match will ignore the | and look for the individual words
| where powershell.file.script_block_text : "rahc|metsys|stekcos|tcejboimw|ecalper|ecnerferpe|noitcennoc|nioj|eman|vne|gnirts|tcejbo-wen|_23niw|noisserpxe|ekovni|daolnwod"

// 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)(rahc|metsys|stekcos|tcejboimw|ecalper|ecnerferpe|noitcennoc|nioj|eman\.|:vne$|gnirts|tcejbo-wen|_23niw|noisserpxe|ekovni|daolnwod)""",
    "🔥"
)

// 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_tmp,
    powershell.file.*,
    file.path,
    powershell.sequence,
    powershell.total,
    _id,
    _version,
    _index,
    host.name,
    host.id,
    agent.id,
    user.id

// Filter for scripts that match the pattern at least twice
| where Esql.script_block_pattern_count >= 2
'''


[[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: where

| where powershell.file.script_block_text : "rahc|metsys|stekcos|tcejboimw|ecalper|ecnerferpe|noitcennoc|nioj|eman|vne|gnirts|tcejbo-wen|_23niw|noisserpxe|ekovni|daolnwod"

Stage 4: eval

| eval Esql.script_block_tmp = replace(
    powershell.file.script_block_text,
    """(?i)(rahc|metsys|stekcos|tcejboimw|ecalper|ecnerferpe|noitcennoc|nioj|eman\.|:vne$|gnirts|tcejbo-wen|_23niw|noisserpxe|ekovni|daolnwod)""",
    "🔥"
)

Stage 5: eval

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

Stage 6: keep

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

Stage 7: where

| where Esql.script_block_pattern_count >= 2

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_tmpKEEP Esql.script_block_tmp
powershell.file.*KEEP powershell.file.*
file.pathKEEP file.path
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

Potential WinRAR CVE-2023-38831 Exploitation

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

Identifies suspicious child processes of the WinRAR process. This may indicate the successful exploitation of the WinRAR vulnerability CVE-2023-38831.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies suspicious child processes of the WinRAR process. This may indicate the successful exploitation of the WinRAR
vulnerability CVE-2023-38831.
"""
id = "1a3b0389-eeb3-46f6-a304-e1983a4dae09"
license = "Elastic License v2"
name = "Potential WinRAR CVE-2023-38831 Exploitation"
os_list = ["windows"]
reference = [
    "https://www.group-ib.com/blog/cve-2023-38831-winrar-zero-day/",
    "https://github.com/b1tg/CVE-2023-38831-winrar-exploit/tree/main",
]
version = "1.0.5"

query = '''
sequence with maxspan=10s
 [file where event.action == "creation" and process.name : "WinRAR.exe" and
  file.path : "?:\\Users\\*\\AppData\\Local\\Temp\\Rar$*\\*" and
  not file.extension :  ("exe", "cmd", "bat ", "vbs", "js", "scr ", "com", "wsh", "hta", "pif", "cpl")] by process.entity_id as event0
 [file where event.action == "creation" and process.name : "WinRAR.exe" and
  file.path : "?:\\Users\\*\\AppData\\Local\\Temp\\Rar$*\\*" and
  file.extension :  ("exe", "cmd", "bat ", "vbs", "js", "scr ", "com", "wsh", "hta", "pif", "cpl") and
  startswith~(file.name, concat(event0.file.name, " "))] by process.entity_id
 [process where event.action == "start" and
  process.parent.name : "winrar.exe" and process.args : "?:\\Users\\*\\AppData\\Local\\Temp\\Rar$*"] by process.parent.entity_id
'''

min_endpoint_version = "8.4.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 2

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

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



[threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1203"
name = "Exploitation for Client Execution"
reference = "https://attack.mitre.org/techniques/T1203/"


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

[internal]
min_endpoint_version = "8.4.0"

Stages and Predicates

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

Stage 1: file

[file where event.action == "creation" and process.name : "WinRAR.exe" and
  file.path : "?:\\Users\\*\\AppData\\Local\\Temp\\Rar$*\\*" and
  not file.extension :  ("exe", "cmd", "bat ", "vbs", "js", "scr ", "com", "wsh", "hta", "pif", "cpl")] by process.entity_id as event0

Stage 2: file

[file where event.action == "creation" and process.name : "WinRAR.exe" and
  file.path : "?:\\Users\\*\\AppData\\Local\\Temp\\Rar$*\\*" and
  file.extension :  ("exe", "cmd", "bat ", "vbs", "js", "scr ", "com", "wsh", "hta", "pif", "cpl") and
  startswith~(file.name, concat(event0.file.name, " "))] by process.entity_id

Stage 3: process

[process where event.action == "start" and
  process.parent.name : "winrar.exe" and process.args : "?:\\Users\\*\\AppData\\Local\\Temp\\Rar$*"] by process.parent.entity_id

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • creation corpus 50 (elastic 50)
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq
file.extensionwildcard
  • bat
  • cmd corpus 15 (elastic 15)
  • com corpus 16 (elastic 16)
  • cpl corpus 19 (elastic 19)
  • exe corpus 32 (elastic 32)
  • hta corpus 20 (elastic 20)
  • js corpus 22 (elastic 22)
  • pif corpus 18 (elastic 18)
  • scr
  • vbs corpus 19 (elastic 19)
  • wsh corpus 16 (elastic 16)
field:"file.extension" kind:wildcard
file.namestarts_with
  • concat(event0.file.name, " ") (expression)
field:"file.name" kind:starts_with
file.pathwildcard
  • ?:\Users\*\AppData\Local\Temp\Rar$*\*
field:"TargetFilename" kind:wildcard value:"?:\Users\*\AppData\Local\Temp\Rar$*\*"
process.argswildcard
  • ?:\Users\*\AppData\Local\Temp\Rar$* corpus 2 (elastic 2)
field:"process.args" kind:wildcard value:"?:\Users\*\AppData\Local\Temp\Rar$*"
process.namewildcard
  • WinRAR.exe corpus 9 (elastic 9)
field:"process_basename" kind:wildcard value:"WinRAR.exe"
process.parent.namewildcard
  • winrar.exe corpus 15 (elastic 14, splunk 1)
field:"parent_process_basename" kind:wildcard value:"winrar.exe"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
file.extensioneqexe, cmd, bat , vbs, js, scr , com, wsh, hta, pif, cplexcludes:file.extension

Successful SSH Authentication from Unusual User

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

This rule leverages the new_terms rule type to detect successful SSH authentications by a user who has not been authenticated in the last 5 days. This behavior may indicate an attacker attempting to gain access to the system using a valid account.

Known False Positives

  • This rule may trigger in cases where a user has routine work patterns that result in infrequent authentications.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2025/02/21"
integration = ["system"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
This rule leverages the new_terms rule type to detect successful SSH authentications by a user
who has not been authenticated in the last 5 days. This behavior may indicate an attacker
attempting to gain access to the system using a valid account.
"""
false_positives = [
    """
    This rule may trigger in cases where a user has routine work patterns that result in infrequent authentications.
    """,
]
from = "now-9m"
index = ["logs-system.auth-*", "filebeat-*"]
language = "kuery"
license = "Elastic License v2"
name = "Successful SSH Authentication from Unusual User"
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 Successful SSH Authentication from Unusual User

SSH (Secure Shell) is a protocol used to securely access and manage Linux systems. Adversaries may exploit valid user accounts to gain unauthorized access, bypassing traditional security measures. The detection rule identifies unusual SSH logins by flagging users who haven't logged in for over 10 days, indicating potential misuse of credentials. This proactive approach helps in early detection of unauthorized access attempts.

### Possible investigation steps

- Review the specific user account involved in the alert to determine if the login is expected or authorized, considering the user's typical login patterns and responsibilities.
- Check the source IP address of the SSH login to see if it is recognized or associated with previous legitimate access, or if it appears unusual or suspicious.
- Analyze the timing of the login event to see if it coincides with any known maintenance windows or scheduled activities that could explain the access.
- Investigate any recent changes to the user's account, such as password resets or modifications to permissions, that could indicate potential compromise.
- Correlate the SSH login event with other logs or alerts from the same timeframe to identify any additional suspicious activities or patterns that could suggest a broader security incident.

### False positive analysis

- Users returning from extended leave or vacation may trigger the rule. To manage this, create exceptions for users with known absence periods.
- System administrators or service accounts that log in infrequently for maintenance tasks can be excluded by identifying and documenting these accounts.
- Automated scripts or processes that authenticate sporadically might be flagged. Review and whitelist these processes if they are legitimate and necessary for operations.
- Temporary contractors or consultants with limited access periods may cause alerts. Ensure their access is documented and create exceptions for their accounts during their engagement period.
- Accounts used for testing or development purposes that are not regularly active can be excluded by maintaining a list of such accounts and updating it as needed.

### Response and remediation

- Immediately isolate the affected system from the network to prevent further unauthorized access or lateral movement by the attacker.
- Terminate the active SSH session associated with the unusual login to cut off the attacker's access.
- Reset the password for the compromised user account and any other accounts that may have been accessed using the same credentials.
- Conduct a thorough review of the affected system's logs and configurations to identify any unauthorized changes or additional compromised accounts.
- Escalate the incident to the security operations team for further investigation and to determine if additional systems or accounts have been affected.
- Implement multi-factor authentication (MFA) for SSH access to enhance security and prevent similar unauthorized access attempts in the future.
- Update and enhance monitoring rules to detect similar unusual login patterns, ensuring early detection of potential threats.
"""
risk_score = 21
rule_id = "5b8d7b94-23c6-4e3f-baed-3a4d0da4f19d"
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Initial Access",
    "Data Source: Elastic Defend",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
event.category:authentication and host.os.type:linux and event.action:ssh_login and event.outcome:success
'''

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

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

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

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

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

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

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

[rule.threat.tactic]
id = "TA0008"
name = "Lateral Movement"
reference = "https://attack.mitre.org/tactics/TA0008/"
[rule.new_terms]
field = "new_terms_fields"
value = ["related.user"]

[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-5d"

Stages and Predicates

Stage 1: new_terms

event.category:authentication and host.os.type:linux and event.action:ssh_login and event.outcome:success

Indicators

These rows show field, operator, and value matches.

Suspicious Execution via Microsoft OfficeCmd URL Handler

#
Source
github.com/elastic/protections-artifacts

Identifies Microsoft Local Bridge executable with suspicious arguments that may indicate an attempt to exploit Microsoft ms-officecmd URL handler via an argument injection vulnerability.

MITRE ATT&CK Coverage

TacticTechniques
Initial Access

Rule Body

[rule]
description = """
Identifies Microsoft Local Bridge executable with suspicious arguments that may indicate an attempt to exploit Microsoft
ms-officecmd URL handler via an argument injection vulnerability.
"""
id = "12e6ac2e-a429-4f54-abb2-eaa5713a4d06"
license = "Elastic License v2"
name = "Suspicious Execution via Microsoft OfficeCmd URL Handler"
os_list = ["windows"]
reference = ["https://positive.security/blog/ms-officecmd-rce"]
version = "1.0.27"

query = '''
process where event.action == "start" and
 (process.name : "LocalBridge.exe" and process.command_line : "*ms-officecmd*LaunchOfficeAppForResult*--gpu-launcher*") or
 (process.parent.name : "LocalBridge.exe" and process.parent.command_line : "*ms-officecmd*LaunchOfficeAppForResult*--gpu-launcher*") or
 /* generic condition to capture abuses of Electron Apps --gpu-launcher switch for proxy execution */
 (process.parent.command_line : "*--disable-gpu-sandbox*--gpu-launcher=*" and not process.parent.name : "LocalBridge.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 = "T1189"
name = "Drive-by Compromise"
reference = "https://attack.mitre.org/techniques/T1189/"


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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Stage 1: process

process where event.action == "start" and
 (process.name : "LocalBridge.exe" and process.command_line : "*ms-officecmd*LaunchOfficeAppForResult*--gpu-launcher*") or
 (process.parent.name : "LocalBridge.exe" and process.parent.command_line : "*ms-officecmd*LaunchOfficeAppForResult*--gpu-launcher*") or
 (process.parent.command_line : "*--disable-gpu-sandbox*--gpu-launcher=*" and not process.parent.name : "LocalBridge.exe")

Indicators

These rows show field, operator, and value matches.

Suspicious Execution via Windows Services

#
Source
github.com/elastic/protections-artifacts

Identifies the execution of commonly abused Windows programs and suspicious execution paths via a Windows service. This may indicate an attempt to elevate privileges via Windows services.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the execution of commonly abused Windows programs and suspicious execution paths via a Windows service. This
may indicate an attempt to elevate privileges via Windows services.
"""
id = "84595d39-df78-49d6-a999-48792482b255"
license = "Elastic License v2"
name = "Suspicious Execution via Windows Services"
os_list = ["windows"]
version = "1.0.46"

query = '''
process where event.action == "start" and
  process.parent.executable : "?:\\Windows\\System32\\services.exe" and
  (
    /* Lolbas */
    process.name : ("mshta.exe", "msbuild.exe", "installutil.exe", "rundll32.exe", "regsvr32.exe", "regasm.exe",
                    "wuauclt.exe", "wmic.exe") or

    /* Suspicious Paths */
    (process.executable : ("?:\\Users\\Public\\*", "?:\\ProgramData\\*", "?:\\Users\\*\\AppData\\*",
                           "?:\\Users\\*\\Pictures\\*", "?:\\Users\\*\\Music\\*", "?:\\Windows\\Tasks\\*",
                           "?:\\Windows\\System32\\tasks\\*", "?:\\Windows\\Temp\\*") and

     /* noisy - excluding subdirs of ProgramData  */
     not process.executable : "?:\\ProgramData\\*\\*") or

    /* Shell Command Interpreters */
    (
     process.name : ("cmd.exe", "powershell.exe") and
     process.command_line : ("*http*://*", "* -enc *", "* -e *", "*/c *powershell*", "*/c *rundll32*", "*lsass*",
                             "*/c *Microsoft.NET*", "*-exec bypass*", "*Windows\\INF\\*", "*\\Users\\Public\\*")
     ) or

     /* programfiles unquoted Service path hijack */
     process.executable : ("?:\\Program", "?:\\Program.exe", "?:\\Program.scr", "?:\\Program.com", "?:\\Program:*") or

     /* Exec from Alternate DataStream */
     process.name : "*:*" or

     /* known malware patterns */
     /* ZenPack */
     (process.executable : "?:\\Windows\\SysWOW64\\*.exe" and process.command_line : "*.exe /d\"?:\\*") or

     /* DirtyMoe */
     (process.executable : "?:\\Windows\\*.exe" and process.args : ("-a", "-auto") and
      process.args_count == 2 and process.code_signature.exists == false) or

     /* execution from windir currentdir and unsigned*/
     (process.executable : "?:\\Windows\\*" and not process.executable : "?:\\Windows\\*\\*" and
      process.code_signature.exists == false and
      not process.pe.original_file_name in ("VPDAgent_x64.exe", "PAExec.exe") and
      not process.executable : "?:\\Windows\\tenable_mw_scan_*.exe") or

     /* execution from systemdir currentdir and untrusted codesign */
     (process.executable : ("?:\\Windows\\System32\\*", "?:\\Windows\\SysWOW64\\*") and
      not process.executable :("?:\\Windows\\System32\\*\\*", "?:\\Windows\\SysWOW64\\*\\*") and
      process.code_signature.trusted == false) or

     /* rogue Ammyy Admin */
     (process.args : "-service" and process.args : "-lunch" and process.code_signature.exists == false and
      not process.executable : ("?:\\Program Files\\*.exe", "?:\\Program Files (x86)\\*.exe"))
   )
   and
   not process.hash.sha256 in
	         ("c9ef35bed70ffa0981bafd0071185b56fdad8f9c97f3582a4dae9b420959fb97",
	          "18dc098895ccc8246d417445a36d933c5f8487419b848ebe651fd0e11cb22afa",
	          "ea98309a35f92443b9c50736ce208656ec72af114ec8aceeb02dfa041ec2d6bc",
	          "bcf07679ea026f1dfba6f9ab63251e4834dc007bd2c5b9039deb9d900fe1c5e6",
	          "1c6af94b26f369e2c10819eefb869f873e5540e2c1b7bf4c7c632fc03d67368a",
	          "7f8e465edd27cdcd1d28292c35440d745b8bd528e21d6f56eb683b65d922eaed",
	          "ff361a79111795eabf24b7a8789347f1d043dac814cd6ff6531d47f268b72651",
	          "0c85d3e19ca3303a36187fba963235a03c36af61336a5a95d8b55ef05817b9d3",
	          "ae0fb4bf4a6faa4b808794b6e6ccbdf9f10c1ce01a86ccece002ac63cf09ff29",
	          "5859b114d96800a2b98ef9d19eaa573a786a422dad324547ef25be181389df01",
	          "f2949996bcd03858627fb196fc6751c0a88f1a2fa1a082c885a3be4b94e7f5b1",
	          "eabf1a97222db3a85269ef36c82f2ff44c91b18e6459b9e411e198b51fd9cef2",
	          "cd5ff596b7bacb117f90893f94fd8c542b659cc58f90ed1fbd0471fe85148bff",
	          "d99ae6b2da11fb89672906ccdb3ef2dde4534ca1406219285784c275af5e7014",
	          "e2bfdefbafe2445693f85af28c825c2aacba769c18393fd640386abde587498f",
	          "08d019e46a8755c33ad9ff9b96b5409a9005d87ba4e3cc58bdd8cf10eb0cd987",
	          "693c6c0f54bf5a2c14dc6e4e0cef3562c735b584c01204ff56d70e5d90502382",
	          "8a203d0dd4821b42ca399140e093919348b60ac43140e92f88d047263e2c57b4",
	          "e68743f3a0c299024e1540add1bcd9d3658ebbdbf172d74e1bf8fcd8c8c0406b",
	          "685a30cfd98e7636f145e1bfd7616d63a8a99e0d5c9bdb3a1171665bfc53491d",
	          "769603162b93de2d11888c1a820f0eef385b3a2c113f1bb24f939c79edc1ce62",
	          "422aa4268713b6c99581365985d403a62f6ccd9f0b5a23f9d963d1947dc77aee",
	          "c71ddd9aeaed18b6a3e6c80119504ececdfa329328e4a814913be6113c8efb1d",
	          "c4c6b0db707020364cd398d2a7a3eb2516cfeb0a011557dce3393e25eaa90be4",
	          "4208e349ff97a2dc6100ee9e5e61e23ab650b316e62dd4a25d1119a08a59f298",
	          "8850f6c649bd4d69d7ddb1f817865d67ee1de340e8c397f587a67fbcbba35cdd",
	          "2b25e0331289460dbaed2d851b92f43e6999f694bf17964a8786f3a4cce602a6",
	          "99b3e6d71329624cb75a88bb66e3249510f6008a38de5535ca5ccb8f580519e0",
	          "9dbd07d864d31d13b96f1bd61bf83dcd04b43f5266019c99592671cd819968e6",
	          "70da895606ecde4b0ceaee6d19ddcc42be35ec32fa3667f3efbe2f79457de9c4",
	          "a74dd36806499b164906b0b9a7b7118fb19a02562a7229c544d77dd946449881",
	          "9860f515da98b85f61d2ee816271717b77245a1163ba498d5253974d9f7c78b3",
	          "5205617f86113f84df0c6d750f06e8284a58d4c781ba3993175a5f68b00600de",
	          "d68553c0525323e804344a4cb77b8bf0b35ce5f2349a2340ba482380d785e19b",
	          "dac28f4a11429f99705bfbf0e49f586c3c3a43a5535c387f6ab01cfea3386dff",
	          "8db84b45c31f64f03ffef9728a39eae8e32c9b3fd21cc4fa914aab22c0104de1",
	          "d699dc58c91ce4c886a858addf54b2501bf55f4d4be91deac4e57a5be31b1a94",
	          "f689ee9af94b00e9e3f0bb072b34caaf207f32dcb4f5782fc9ca351df9a06c97",
	          "c0cfeb9b627dddd81f403d8848e70e54e4fe5c67da07e3ed1b16c1bb665b5e42",
	          "84c073bfc86cf51aa8c33fa91b43ef2091a6e41482fa9c257204547955dcb4ca",
	          "f94d16f63262ea3999997d35a5fa84a1863f889f1d2a429ce0d4faf7bb79825c",
	          "afd293b75c5adfbff1183b08033d36fc0845c554e5ba41f0c1c647eb78a5952e",
	          "f52c72a3c8c4592cbb6552c076a225f5956e287b096ae8b000da333ad8773b13",
	          "c34f400023783127e5181d5e65083adc1f3abf28127eb560e4d03c547fa5a2c2",
	          "7365cd76ce2b2cd2aeb998ff53c5faff144e8a06b698a3d156b686f2ff640691",
	          "121ed90aec5135af04b1e5f8b26a4e25278232a93c45ef09ae226629ad1de64f",
	          "03978563fcd327059ef3df101ca1defa60b0f3c86b5fa72b01d31f802ad81856",
	          "7e0ff000ce7cacd201a76a017ee669f34e71f557fa468280cf27b0d2370dd8ad",
	          "42aa6483ad8f0d091141e0fd05631e79600f5d37a25bf260b493a8cfa99adf1b",
	          "9d2e4a42cbcdd9315b6c86a36af632c86293940287dc26930e1c7932eb7c6cb2",
	          "cd1dd8cff168b57aebbd59a62e48e592be8571082e1e5416613cd6ad27edc2ce",
	          "5fc1af2ed768d259612242c76dee2a29fd84379a7eb1a30da13cbc036f16385e",
	          "41292975a38a69c0afc8b22b8622209e40ffb8cb6017fa16f15be8d94639fb93",
	          "cdcdcd2866eb4156875cb8a2304d2dce9d9ba764f67e5a79c98556c9efa2aeaa",
	          "4aa716bf7c4c1e164d6f58cef08a69118dbf22cca00def1c604b6e090a302520",
	          "fd2c88a7d7e9a6bab6c0c9a725e12e1d1fcc9f2f6dd88eaf6c204952a570001e",
	          "022cb167a29a32dae848be91aef721c74f1975af151807dafcc5ed832db246b7",
	          "9c89e90a6a649cbe41aaae468aab6bdb1400620bee498b151b282c411fc11357",
	          "c0908b08a80f031c49a50f873a8d4a9426c0100fb4fa7a46f7b34540191684ce",
	          "ca3056bbec01c0610b7f7f169ee1081c72cc210df169c9cc36e9bcfc38f94ceb",
	          "acd55c44b8b0d66d66defed85ca18082c092f048d3621da827fce593305c11fd",
	          "bb3830b14df80838fb201c611abf0c1f3714c6b8b103ed084eafc170036631be",
	          "488df57af2d0a29d555b3ad233e5ac17058582ef040b3a89471d4c519b9b4db7",
	          "92512032cefa1fd63490ab00eb974b15ae557578d901faf4aa6c3ff4c214a239",
	          "7e46a30ec382d6973695520a3c88337bed3f33d5d30b64cac689fb83ebd29d8f", 
	          "1186244a77bd08d3a5aad8f24f9cf59ae228782adde32467e0622c5236586190", 
	          "ae16d853600d647688f414e023ce8644ceacf1d6ada050792ee665c4465c939b", 
	          "cf41501fa77ffece7a67b9cd996b6a3fceafefb44bf192c9078a2f0e30e01f97",
	          "88f1612d7e774e0bbd6708ca946bcdb3c671a18048b2a4f5ad33c6a7c2db02de",
	          "73a91d7dbdff150632a9501c94b4f328e61fc8a8e52d27b2646921ddee8acae2",
	          "e72f59681ef6dd09608772cde8bb0dcbb42e97118ad58ad8fe2d3501d73bcd2e",
	          "b75268bc78de915eff442611f9c7503b4f872b22d7c54547694923cce6427b4e",
	          "854ed6e135b1405329003f0595c3ca462faf5381ac5d6f93bccfece61d6a2d88",
	          "be132253fb111600acedb58fa96fd18af69a8a8395880b0d8d89ff13ba30455b",
	          "4eb8a5b3ba5b30b7c4e4e1db60af75f7cac808aa3bc0cd326bf4863535659def",
	          "46122ee39283dbca52dde436ef04d47fd962271424726b491ad8584389461177",
	          "3c16784f9b827aa6583d529f8585c431cd39e7e3a96e31c7b9882d5b48c00087",
	          "d71fce8dc14cfb082041c2ddd6184baa6e1bc535582e36174bc0a80be9f7a879",
	          "73f834726b1091494d8151ff053eeb4dc6f79dd49525f23a5583c2bdeb176eb8", 
			  "7e1c9498c44a60315c3f5e41c9a8247d605c66328653cef4560277592de79e93", 
			  "e501b3cc3f0a32e14ba475038712e24c312c9468780eaf36f47aa73a16bf5f1f", 
			  "64a080388fcd44c14246de991b9a90f0541f9878d2164469d7bf7499c568ca32") and

  not (process.pe.original_file_name :
                ("OneDriveStandaloneUpdater.exe",
                 "Microsoft.SharePoint.Migration.ClientService.exe",
                 "process.pe.original_file_name") and
       process.code_signature.subject_name : ("Microsoft Windows", "Microsoft Corporation") and process.code_signature.trusted == true) and

  not (process.code_signature.subject_name : ("Practical Dental Solutions LLC", "ISL Online Ltd.", "Nanosystems S.r.l.",
   "Opera Software AS", "Kaspersky Lab JSC", "AO Kaspersky Lab", "LogMeIn, Inc.", "Bright Data Ltd", "Malwarebytes Inc",
   "SEIKO EPSON CORPORATION", "KOINO Co., Ltd.", "Panda Security S.L.", "Endgame, Inc.",
   "Acrosync LLC", "Midassoft Corporation Limted", "ForensiT Limited", "ConnectWise, LLC", "ScreenConnect Software",
   "Beijing Duyou Science and Technology Co.,Ltd.", "N-ABLE TECHNOLOGIES LTD", "Icona S.R.L.", "Dropbox, Inc", "ISL Online",
   "CodeLathe, LLC", "Google LLC", "Connectwise, LLC", "Mozilla Corporation", "Huawei Technologies Co., Ltd.", "Icona srl",
   "Plarium Global LTD", "Trend Micro, Inc.", "HeroSpeed Digital Technology Co.,Ltd", "IDrive, Inc.", "Secure By Design Inc.",
   "SecureLink, Inc.", "Google Inc", "Wondershare Technology Group Co.,Ltd", "Malwarebytes Inc.", "Suse LLC", "FLEXTECH INC.",
   "DameWare Development, LLC.", "Acronis International GmbH", "Broadcom Inc", "Symantec Corporation", "Ivanti, Inc.",
   "Rsupport Co., Ltd.", "SAP", "VMware, Inc.", "Private trade unitary enterprise LST",
   "Solarwinds Worldwide, LLC", "Techinline Limited", "ZOHO CORPORATION PRIVATE LIMITED", "Canon Inc.",
   "Sikka Software Corporation", "TeamViewer Germany GmbH", "Brother Industries, Ltd.", "Pro Softnet Corporation", "Raman Karpuk",
   "ATEMPO SAS", "TeamViewer", "WireGuard LLC", "MetaQuotes Ltd", "NinjaOne LLC",
   "ForensiT Software Limited", "Opera Norway AS", "Veeam Software Group GmbH", "Copermatica SL", "SimplyCore LLC", "SimplyCore, LLC",
   "") and
   process.code_signature.trusted == true) and

   not (process.name : "RUNDLL32.EXE" and
        process.args : ("aepdu.dll,AePduRunUpdate",
                        "Windows.Storage.ApplicationData.dll,CleanupTemporaryState",
                        "srrstr.dll,ExecuteScheduledSPPCreation",
                        "WSClient.dll,WSpTLR",
                        "WSClient.dll,RefreshBannedAppsList",
                        "acproxy.dll,PerformAutochkOperations",
                        "invagent.dll,RunUpdate",
                        "Startupscan.dll,SusRunTask",
                        "dfdts.dll,DfdGetDefaultPolicyAndSMART",
                        "appraiser.dll,DoScheduledTelemetryRun",
                        "?:\\Windows\\system32\\pla.dll,PlaHost",
                        "?:\\Windows\\system32\\invagent.dll,RunUpdate",
                        "tsworkspace,TaskUpdateWorkspaces2",
                        "tsworkspace,WorkspaceStatusNotify2",
                        "sysmain.dll,PfSvWsSwapAssessmentTask",
                        "ndfapi.dll,NdfRunDllDuplicateIPDefendingSystem")) and

   not (process.name : ("wscript.exe", "cscript.exe") and
        process.args : ("?:\\Program Files\\Intel\\*.vbs", "?:\\Windows\\system32\\calluxxprovider.vbs")) and
   not (process.executable : "?:\\Windows\\*.exe" and process.code_signature.status : ("errorExpired", "errorCode_endpoint*", "errorChaining")) and
   not (process.name : ("wscript.exe", "cscript.exe") and process.working_directory : "\\\\*") and 
   not (process.executable : "?:\\Windows\\Temp\\*" and process.code_signature.trusted == true) and
   not process.executable : ("?:\\Windows\\System32\\sppsvc.exe", "?:\\Windows\\ise-exec-svc.exe") and
   not (process.name == "cmd.exe" and process.command_line like "*pzaS5TZXJ2aWNlTmFtZSA9ICJPMjRBVVRIIjs*")
'''

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

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"
[[threat.technique.subtechnique]]
id = "T1543.003"
name = "Windows Service"
reference = "https://attack.mitre.org/techniques/T1543/003/"



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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Stage 1: process

process where event.action == "start" and
  process.parent.executable : "?:\\Windows\\System32\\services.exe" and
  (
    process.name : ("mshta.exe", "msbuild.exe", "installutil.exe", "rundll32.exe", "regsvr32.exe", "regasm.exe",
                    "wuauclt.exe", "wmic.exe") or
    (process.executable : ("?:\\Users\\Public\\*", "?:\\ProgramData\\*", "?:\\Users\\*\\AppData\\*",
                           "?:\\Users\\*\\Pictures\\*", "?:\\Users\\*\\Music\\*", "?:\\Windows\\Tasks\\*",
                           "?:\\Windows\\System32\\tasks\\*", "?:\\Windows\\Temp\\*") and
     not process.executable : "?:\\ProgramData\\*\\*") or
    (
     process.name : ("cmd.exe", "powershell.exe") and
     process.command_line : ("*http*://*", "* -enc *", "* -e *", "*/c *powershell*", "*/c *rundll32*", "*lsass*",
                             "*/c *Microsoft.NET*", "*-exec bypass*", "*Windows\\INF\\*", "*\\Users\\Public\\*")
     ) or
     process.executable : ("?:\\Program", "?:\\Program.exe", "?:\\Program.scr", "?:\\Program.com", "?:\\Program:*") or
     process.name : "*:*" or
     (process.executable : "?:\\Windows\\SysWOW64\\*.exe" and process.command_line : "*.exe /d\"?:\\*") or
     (process.executable : "?:\\Windows\\*.exe" and process.args : ("-a", "-auto") and
      process.args_count == 2 and process.code_signature.exists == false) or
     (process.executable : "?:\\Windows\\*" and not process.executable : "?:\\Windows\\*\\*" and
      process.code_signature.exists == false and
      not process.pe.original_file_name in ("VPDAgent_x64.exe", "PAExec.exe") and
      not process.executable : "?:\\Windows\\tenable_mw_scan_*.exe") or
     (process.executable : ("?:\\Windows\\System32\\*", "?:\\Windows\\SysWOW64\\*") and
      not process.executable :("?:\\Windows\\System32\\*\\*", "?:\\Windows\\SysWOW64\\*\\*") and
      process.code_signature.trusted == false) or
     (process.args : "-service" and process.args : "-lunch" and process.code_signature.exists == false and
      not process.executable : ("?:\\Program Files\\*.exe", "?:\\Program Files (x86)\\*.exe"))
   )
   and
   not process.hash.sha256 in
	         ("c9ef35bed70ffa0981bafd0071185b56fdad8f9c97f3582a4dae9b420959fb97",
	          "18dc098895ccc8246d417445a36d933c5f8487419b848ebe651fd0e11cb22afa",
	          "ea98309a35f92443b9c50736ce208656ec72af114ec8aceeb02dfa041ec2d6bc",
	          "bcf07679ea026f1dfba6f9ab63251e4834dc007bd2c5b9039deb9d900fe1c5e6",
	          "1c6af94b26f369e2c10819eefb869f873e5540e2c1b7bf4c7c632fc03d67368a",
	          "7f8e465edd27cdcd1d28292c35440d745b8bd528e21d6f56eb683b65d922eaed",
	          "ff361a79111795eabf24b7a8789347f1d043dac814cd6ff6531d47f268b72651",
	          "0c85d3e19ca3303a36187fba963235a03c36af61336a5a95d8b55ef05817b9d3",
	          "ae0fb4bf4a6faa4b808794b6e6ccbdf9f10c1ce01a86ccece002ac63cf09ff29",
	          "5859b114d96800a2b98ef9d19eaa573a786a422dad324547ef25be181389df01",
	          "f2949996bcd03858627fb196fc6751c0a88f1a2fa1a082c885a3be4b94e7f5b1",
	          "eabf1a97222db3a85269ef36c82f2ff44c91b18e6459b9e411e198b51fd9cef2",
	          "cd5ff596b7bacb117f90893f94fd8c542b659cc58f90ed1fbd0471fe85148bff",
	          "d99ae6b2da11fb89672906ccdb3ef2dde4534ca1406219285784c275af5e7014",
	          "e2bfdefbafe2445693f85af28c825c2aacba769c18393fd640386abde587498f",
	          "08d019e46a8755c33ad9ff9b96b5409a9005d87ba4e3cc58bdd8cf10eb0cd987",
	          "693c6c0f54bf5a2c14dc6e4e0cef3562c735b584c01204ff56d70e5d90502382",
	          "8a203d0dd4821b42ca399140e093919348b60ac43140e92f88d047263e2c57b4",
	          "e68743f3a0c299024e1540add1bcd9d3658ebbdbf172d74e1bf8fcd8c8c0406b",
	          "685a30cfd98e7636f145e1bfd7616d63a8a99e0d5c9bdb3a1171665bfc53491d",
	          "769603162b93de2d11888c1a820f0eef385b3a2c113f1bb24f939c79edc1ce62",
	          "422aa4268713b6c99581365985d403a62f6ccd9f0b5a23f9d963d1947dc77aee",
	          "c71ddd9aeaed18b6a3e6c80119504ececdfa329328e4a814913be6113c8efb1d",
	          "c4c6b0db707020364cd398d2a7a3eb2516cfeb0a011557dce3393e25eaa90be4",
	          "4208e349ff97a2dc6100ee9e5e61e23ab650b316e62dd4a25d1119a08a59f298",
	          "8850f6c649bd4d69d7ddb1f817865d67ee1de340e8c397f587a67fbcbba35cdd",
	          "2b25e0331289460dbaed2d851b92f43e6999f694bf17964a8786f3a4cce602a6",
	          "99b3e6d71329624cb75a88bb66e3249510f6008a38de5535ca5ccb8f580519e0",
	          "9dbd07d864d31d13b96f1bd61bf83dcd04b43f5266019c99592671cd819968e6",
	          "70da895606ecde4b0ceaee6d19ddcc42be35ec32fa3667f3efbe2f79457de9c4",
	          "a74dd36806499b164906b0b9a7b7118fb19a02562a7229c544d77dd946449881",
	          "9860f515da98b85f61d2ee816271717b77245a1163ba498d5253974d9f7c78b3",
	          "5205617f86113f84df0c6d750f06e8284a58d4c781ba3993175a5f68b00600de",
	          "d68553c0525323e804344a4cb77b8bf0b35ce5f2349a2340ba482380d785e19b",
	          "dac28f4a11429f99705bfbf0e49f586c3c3a43a5535c387f6ab01cfea3386dff",
	          "8db84b45c31f64f03ffef9728a39eae8e32c9b3fd21cc4fa914aab22c0104de1",
	          "d699dc58c91ce4c886a858addf54b2501bf55f4d4be91deac4e57a5be31b1a94",
	          "f689ee9af94b00e9e3f0bb072b34caaf207f32dcb4f5782fc9ca351df9a06c97",
	          "c0cfeb9b627dddd81f403d8848e70e54e4fe5c67da07e3ed1b16c1bb665b5e42",
	          "84c073bfc86cf51aa8c33fa91b43ef2091a6e41482fa9c257204547955dcb4ca",
	          "f94d16f63262ea3999997d35a5fa84a1863f889f1d2a429ce0d4faf7bb79825c",
	          "afd293b75c5adfbff1183b08033d36fc0845c554e5ba41f0c1c647eb78a5952e",
	          "f52c72a3c8c4592cbb6552c076a225f5956e287b096ae8b000da333ad8773b13",
	          "c34f400023783127e5181d5e65083adc1f3abf28127eb560e4d03c547fa5a2c2",
	          "7365cd76ce2b2cd2aeb998ff53c5faff144e8a06b698a3d156b686f2ff640691",
	          "121ed90aec5135af04b1e5f8b26a4e25278232a93c45ef09ae226629ad1de64f",
	          "03978563fcd327059ef3df101ca1defa60b0f3c86b5fa72b01d31f802ad81856",
	          "7e0ff000ce7cacd201a76a017ee669f34e71f557fa468280cf27b0d2370dd8ad",
	          "42aa6483ad8f0d091141e0fd05631e79600f5d37a25bf260b493a8cfa99adf1b",
	          "9d2e4a42cbcdd9315b6c86a36af632c86293940287dc26930e1c7932eb7c6cb2",
	          "cd1dd8cff168b57aebbd59a62e48e592be8571082e1e5416613cd6ad27edc2ce",
	          "5fc1af2ed768d259612242c76dee2a29fd84379a7eb1a30da13cbc036f16385e",
	          "41292975a38a69c0afc8b22b8622209e40ffb8cb6017fa16f15be8d94639fb93",
	          "cdcdcd2866eb4156875cb8a2304d2dce9d9ba764f67e5a79c98556c9efa2aeaa",
	          "4aa716bf7c4c1e164d6f58cef08a69118dbf22cca00def1c604b6e090a302520",
	          "fd2c88a7d7e9a6bab6c0c9a725e12e1d1fcc9f2f6dd88eaf6c204952a570001e",
	          "022cb167a29a32dae848be91aef721c74f1975af151807dafcc5ed832db246b7",
	          "9c89e90a6a649cbe41aaae468aab6bdb1400620bee498b151b282c411fc11357",
	          "c0908b08a80f031c49a50f873a8d4a9426c0100fb4fa7a46f7b34540191684ce",
	          "ca3056bbec01c0610b7f7f169ee1081c72cc210df169c9cc36e9bcfc38f94ceb",
	          "acd55c44b8b0d66d66defed85ca18082c092f048d3621da827fce593305c11fd",
	          "bb3830b14df80838fb201c611abf0c1f3714c6b8b103ed084eafc170036631be",
	          "488df57af2d0a29d555b3ad233e5ac17058582ef040b3a89471d4c519b9b4db7",
	          "92512032cefa1fd63490ab00eb974b15ae557578d901faf4aa6c3ff4c214a239",
	          "7e46a30ec382d6973695520a3c88337bed3f33d5d30b64cac689fb83ebd29d8f",
	          "1186244a77bd08d3a5aad8f24f9cf59ae228782adde32467e0622c5236586190",
	          "ae16d853600d647688f414e023ce8644ceacf1d6ada050792ee665c4465c939b",
	          "cf41501fa77ffece7a67b9cd996b6a3fceafefb44bf192c9078a2f0e30e01f97",
	          "88f1612d7e774e0bbd6708ca946bcdb3c671a18048b2a4f5ad33c6a7c2db02de",
	          "73a91d7dbdff150632a9501c94b4f328e61fc8a8e52d27b2646921ddee8acae2",
	          "e72f59681ef6dd09608772cde8bb0dcbb42e97118ad58ad8fe2d3501d73bcd2e",
	          "b75268bc78de915eff442611f9c7503b4f872b22d7c54547694923cce6427b4e",
	          "854ed6e135b1405329003f0595c3ca462faf5381ac5d6f93bccfece61d6a2d88",
	          "be132253fb111600acedb58fa96fd18af69a8a8395880b0d8d89ff13ba30455b",
	          "4eb8a5b3ba5b30b7c4e4e1db60af75f7cac808aa3bc0cd326bf4863535659def",
	          "46122ee39283dbca52dde436ef04d47fd962271424726b491ad8584389461177",
	          "3c16784f9b827aa6583d529f8585c431cd39e7e3a96e31c7b9882d5b48c00087",
	          "d71fce8dc14cfb082041c2ddd6184baa6e1bc535582e36174bc0a80be9f7a879",
	          "73f834726b1091494d8151ff053eeb4dc6f79dd49525f23a5583c2bdeb176eb8",
			  "7e1c9498c44a60315c3f5e41c9a8247d605c66328653cef4560277592de79e93",
			  "e501b3cc3f0a32e14ba475038712e24c312c9468780eaf36f47aa73a16bf5f1f",
			  "64a080388fcd44c14246de991b9a90f0541f9878d2164469d7bf7499c568ca32") and
  not (process.pe.original_file_name :
                ("OneDriveStandaloneUpdater.exe",
                 "Microsoft.SharePoint.Migration.ClientService.exe",
                 "process.pe.original_file_name") and
       process.code_signature.subject_name : ("Microsoft Windows", "Microsoft Corporation") and process.code_signature.trusted == true) and
  not (process.code_signature.subject_name : ("Practical Dental Solutions LLC", "ISL Online Ltd.", "Nanosystems S.r.l.",
   "Opera Software AS", "Kaspersky Lab JSC", "AO Kaspersky Lab", "LogMeIn, Inc.", "Bright Data Ltd", "Malwarebytes Inc",
   "SEIKO EPSON CORPORATION", "KOINO Co., Ltd.", "Panda Security S.L.", "Endgame, Inc.",
   "Acrosync LLC", "Midassoft Corporation Limted", "ForensiT Limited", "ConnectWise, LLC", "ScreenConnect Software",
   "Beijing Duyou Science and Technology Co.,Ltd.", "N-ABLE TECHNOLOGIES LTD", "Icona S.R.L.", "Dropbox, Inc", "ISL Online",
   "CodeLathe, LLC", "Google LLC", "Connectwise, LLC", "Mozilla Corporation", "Huawei Technologies Co., Ltd.", "Icona srl",
   "Plarium Global LTD", "Trend Micro, Inc.", "HeroSpeed Digital Technology Co.,Ltd", "IDrive, Inc.", "Secure By Design Inc.",
   "SecureLink, Inc.", "Google Inc", "Wondershare Technology Group Co.,Ltd", "Malwarebytes Inc.", "Suse LLC", "FLEXTECH INC.",
   "DameWare Development, LLC.", "Acronis International GmbH", "Broadcom Inc", "Symantec Corporation", "Ivanti, Inc.",
   "Rsupport Co., Ltd.", "SAP", "VMware, Inc.", "Private trade unitary enterprise LST",
   "Solarwinds Worldwide, LLC", "Techinline Limited", "ZOHO CORPORATION PRIVATE LIMITED", "Canon Inc.",
   "Sikka Software Corporation", "TeamViewer Germany GmbH", "Brother Industries, Ltd.", "Pro Softnet Corporation", "Raman Karpuk",
   "ATEMPO SAS", "TeamViewer", "WireGuard LLC", "MetaQuotes Ltd", "NinjaOne LLC",
   "ForensiT Software Limited", "Opera Norway AS", "Veeam Software Group GmbH", "Copermatica SL", "SimplyCore LLC", "SimplyCore, LLC",
   "") and
   process.code_signature.trusted == true) and
   not (process.name : "RUNDLL32.EXE" and
        process.args : ("aepdu.dll,AePduRunUpdate",
                        "Windows.Storage.ApplicationData.dll,CleanupTemporaryState",
                        "srrstr.dll,ExecuteScheduledSPPCreation",
                        "WSClient.dll,WSpTLR",
                        "WSClient.dll,RefreshBannedAppsList",
                        "acproxy.dll,PerformAutochkOperations",
                        "invagent.dll,RunUpdate",
                        "Startupscan.dll,SusRunTask",
                        "dfdts.dll,DfdGetDefaultPolicyAndSMART",
                        "appraiser.dll,DoScheduledTelemetryRun",
                        "?:\\Windows\\system32\\pla.dll,PlaHost",
                        "?:\\Windows\\system32\\invagent.dll,RunUpdate",
                        "tsworkspace,TaskUpdateWorkspaces2",
                        "tsworkspace,WorkspaceStatusNotify2",
                        "sysmain.dll,PfSvWsSwapAssessmentTask",
                        "ndfapi.dll,NdfRunDllDuplicateIPDefendingSystem")) and
   not (process.name : ("wscript.exe", "cscript.exe") and
        process.args : ("?:\\Program Files\\Intel\\*.vbs", "?:\\Windows\\system32\\calluxxprovider.vbs")) and
   not (process.executable : "?:\\Windows\\*.exe" and process.code_signature.status : ("errorExpired", "errorCode_endpoint*", "errorChaining")) and
   not (process.name : ("wscript.exe", "cscript.exe") and process.working_directory : "\\\\*") and
   not (process.executable : "?:\\Windows\\Temp\\*" and process.code_signature.trusted == true) and
   not process.executable : ("?:\\Windows\\System32\\sppsvc.exe", "?:\\Windows\\ise-exec-svc.exe") and
   not (process.name == "cmd.exe" and process.command_line like "*pzaS5TZXJ2aWNlTmFtZSA9ICJPMjRBVVRIIjs*")

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
  • -a corpus 5 (elastic 5)
  • -auto
  • -lunch
  • -service
field:"process.args" kind:wildcard
process.args_counteq
  • 2 transforms: number corpus 35 (elastic 35)
field:"process.args_count" kind:eq value:"2"
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.command_linewildcard
  • * -e * corpus 4 (elastic 4)
  • * -enc * corpus 4 (elastic 4)
  • *-exec bypass*
  • *.exe /d"?:\*
  • */c *Microsoft.NET*
  • */c *powershell*
  • */c *rundll32*
  • *Windows\INF\*
  • *\Users\Public\*
  • *http*://* corpus 2 (elastic 2)
  • *lsass*
field:"CommandLine" kind:wildcard
process.executablewildcard
  • ?:\Program
  • ?:\Program.com
  • ?:\Program.exe
  • ?:\Program.scr
  • ?:\Program:*
  • ?:\ProgramData\* corpus 18 (elastic 18)
  • ?:\Users\*\AppData\* corpus 12 (elastic 12)
  • ?:\Users\*\Music\*
  • ?:\Users\*\Pictures\* corpus 2 (elastic 2)
  • ?:\Users\Public\* corpus 22 (elastic 22)
  • ?:\Windows\* corpus 5 (elastic 5)
  • ?:\Windows\*.exe corpus 3 (elastic 3)
  • ?:\Windows\SysWOW64\* corpus 6 (elastic 6)
  • ?:\Windows\SysWOW64\*.exe corpus 6 (elastic 6)
  • ?:\Windows\System32\* corpus 6 (elastic 6)
  • ?:\Windows\System32\tasks\* corpus 3 (elastic 3)
  • ?:\Windows\Tasks\* corpus 7 (elastic 7)
  • ?:\Windows\Temp\* corpus 7 (elastic 7)
field:"Image" kind:wildcard
process.namewildcard
  • *:*
  • cmd.exe corpus 122 (elastic 93, splunk 29)
  • installutil.exe corpus 36 (elastic 32, splunk 4)
  • msbuild.exe corpus 39 (elastic 36, splunk 3)
  • mshta.exe corpus 84 (elastic 80, splunk 4)
  • powershell.exe corpus 187 (elastic 140, splunk 44, kusto 3)
  • regasm.exe corpus 25 (elastic 24, splunk 1)
  • regsvr32.exe corpus 74 (elastic 69, splunk 5)
  • rundll32.exe corpus 123 (elastic 100, splunk 23)
  • wmic.exe corpus 66 (elastic 39, splunk 27)
  • wuauclt.exe corpus 7 (elastic 7)
field:"process_basename" kind:wildcard
process.parent.executablewildcard
  • ?:\Windows\System32\services.exe corpus 3 (elastic 3)
field:"ParentImage" kind:wildcard value:"?:\Windows\System32\services.exe"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argseqaepdu.dll,AePduRunUpdate, Windows.Storage.ApplicationData.dll,CleanupTemporaryState, srrstr.dll,ExecuteScheduledSPPCreation, WSClient.dll,WSpTLR, WSClient.dll,RefreshBannedAppsList, acproxy.dll,PerformAutochkOperations, invagent.dll,RunUpdate, Startupscan.dll,SusRunTask, dfdts.dll,DfdGetDefaultPolicyAndSMART, appraiser.dll,DoScheduledTelemetryRun, ?:\Windows\system32\pla.dll,PlaHost, ?:\Windows\system32\invagent.dll,RunUpdate, tsworkspace,TaskUpdateWorkspaces2, tsworkspace,WorkspaceStatusNotify2, sysmain.dll,PfSvWsSwapAssessmentTask, ndfapi.dll,NdfRunDllDuplicateIPDefendingSystemexcludes:process.args
process.nameeqRUNDLL32.EXEexcludes:process.name field:"process.name" value:"RUNDLL32.EXE"
process.argswildcard?:\Program Files\Intel\*.vbs, ?:\Windows\system32\calluxxprovider.vbsexcludes:process.args field:"process.args" value:"?:\Program Files\Intel\*.vbs" field:"process.args" value:"?:\Windows\system32\calluxxprovider.vbs"
process.nameeqwscript.exe, cscript.exeexcludes:process.name field:"process.name" value:"wscript.exe" field:"process.name" value:"cscript.exe"
process.code_signature.statuswildcarderrorExpired, errorCode_endpoint*, errorChainingexcludes:process.code_signature.status field:"process.code_signature.status" value:"errorExpired" field:"process.code_signature.status" value:"errorCode_endpoint*" field:"process.code_signature.status" value:"errorChaining"
process.executablewildcard?:\Windows\*.exeexcludes:process.executable field:"process.executable" value:"?:\Windows\*.exe"
process.code_signature.subject_nameeqMicrosoft Windows, Microsoft Corporationexcludes:process.code_signature.subject_name field:"process.code_signature.subject_name" value:"Microsoft Windows" field:"process.code_signature.subject_name" value:"Microsoft Corporation"
process.code_signature.trustedeqtrueexcludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true"
process.pe.original_file_nameeqOneDriveStandaloneUpdater.exe, Microsoft.SharePoint.Migration.ClientService.exe, process.pe.original_file_nameexcludes:process.pe.original_file_name field:"process.pe.original_file_name" value:"OneDriveStandaloneUpdater.exe" field:"process.pe.original_file_name" value:"Microsoft.SharePoint.Migration.ClientService.exe" field:"process.pe.original_file_name" value:"process.pe.original_file_name"
process.code_signature.subject_namewildcardPractical Dental Solutions LLC, ISL Online Ltd., Nanosystems S.r.l., Opera Software AS, Kaspersky Lab JSC, AO Kaspersky Lab, LogMeIn, Inc., Bright Data Ltd, Malwarebytes Inc, SEIKO EPSON CORPORATION, KOINO Co., Ltd., Panda Security S.L., Endgame, Inc., Acrosync LLC, Midassoft Corporation Limted, ForensiT Limited, ConnectWise, LLC, ScreenConnect Software, Beijing Duyou Science and Technology Co.,Ltd., N-ABLE TECHNOLOGIES LTD, Icona S.R.L., Dropbox, Inc, ISL Online, CodeLathe, LLC, Google LLC, Connectwise, LLC, Mozilla Corporation, Huawei Technologies Co., Ltd., Icona srl, Plarium Global LTD, Trend Micro, Inc., HeroSpeed Digital Technology Co.,Ltd, IDrive, Inc., Secure By Design Inc., SecureLink, Inc., Google Inc, Wondershare Technology Group Co.,Ltd, Malwarebytes Inc., Suse LLC, FLEXTECH INC., DameWare Development, LLC., Acronis International GmbH, Broadcom Inc, Symantec Corporation, Ivanti, Inc., Rsupport Co., Ltd., SAP, VMware, Inc., Private trade unitary enterprise LST, Solarwinds Worldwide, LLC, Techinline Limited, ZOHO CORPORATION PRIVATE LIMITED, Canon Inc., Sikka Software Corporation, TeamViewer Germany GmbH, Brother Industries, Ltd., Pro Softnet Corporation, Raman Karpuk, ATEMPO SAS, TeamViewer, WireGuard LLC, MetaQuotes Ltd, NinjaOne LLC, ForensiT Software Limited, Opera Norway AS, Veeam Software Group GmbH, Copermatica SL, SimplyCore LLC, SimplyCore, LLCexcludes:process.code_signature.subject_name
process.executablestarts_with?:\Windows\Temp\excludes:process.executable field:"process.executable" value:"?:\Windows\Temp\"
process.command_linematchpzaS5TZXJ2aWNlTmFtZSA9ICJPMjRBVVRIIjsexcludes:process.command_line field:"process.command_line" value:"pzaS5TZXJ2aWNlTmFtZSA9ICJPMjRBVVRIIjs"
process.nameeqcmd.exeexcludes:process.name field:"process.name" value:"cmd.exe"
process.working_directorystarts_with\\excludes:process.working_directory field:"process.working_directory" value:"\\"
process.executableeq?:\Windows\System32\sppsvc.exe, ?:\Windows\ise-exec-svc.exeexcludes:process.executable field:"process.executable" value:"?:\Windows\System32\sppsvc.exe" field:"process.executable" value:"?:\Windows\ise-exec-svc.exe"
process.hash.sha256in022cb167a29a32dae848be91aef721c74f1975af151807dafcc5ed832db246b7, 03978563fcd327059ef3df101ca1defa60b0f3c86b5fa72b01d31f802ad81856, 08d019e46a8755c33ad9ff9b96b5409a9005d87ba4e3cc58bdd8cf10eb0cd987, 0c85d3e19ca3303a36187fba963235a03c36af61336a5a95d8b55ef05817b9d3, 1186244a77bd08d3a5aad8f24f9cf59ae228782adde32467e0622c5236586190, 121ed90aec5135af04b1e5f8b26a4e25278232a93c45ef09ae226629ad1de64f, 18dc098895ccc8246d417445a36d933c5f8487419b848ebe651fd0e11cb22afa, 1c6af94b26f369e2c10819eefb869f873e5540e2c1b7bf4c7c632fc03d67368a, 2b25e0331289460dbaed2d851b92f43e6999f694bf17964a8786f3a4cce602a6, 3c16784f9b827aa6583d529f8585c431cd39e7e3a96e31c7b9882d5b48c00087, 41292975a38a69c0afc8b22b8622209e40ffb8cb6017fa16f15be8d94639fb93, 4208e349ff97a2dc6100ee9e5e61e23ab650b316e62dd4a25d1119a08a59f298, 422aa4268713b6c99581365985d403a62f6ccd9f0b5a23f9d963d1947dc77aee, 42aa6483ad8f0d091141e0fd05631e79600f5d37a25bf260b493a8cfa99adf1b, 46122ee39283dbca52dde436ef04d47fd962271424726b491ad8584389461177, 488df57af2d0a29d555b3ad233e5ac17058582ef040b3a89471d4c519b9b4db7, 4aa716bf7c4c1e164d6f58cef08a69118dbf22cca00def1c604b6e090a302520, 4eb8a5b3ba5b30b7c4e4e1db60af75f7cac808aa3bc0cd326bf4863535659def, 5205617f86113f84df0c6d750f06e8284a58d4c781ba3993175a5f68b00600de, 5859b114d96800a2b98ef9d19eaa573a786a422dad324547ef25be181389df01, 5fc1af2ed768d259612242c76dee2a29fd84379a7eb1a30da13cbc036f16385e, 64a080388fcd44c14246de991b9a90f0541f9878d2164469d7bf7499c568ca32, 685a30cfd98e7636f145e1bfd7616d63a8a99e0d5c9bdb3a1171665bfc53491d, 693c6c0f54bf5a2c14dc6e4e0cef3562c735b584c01204ff56d70e5d90502382, 70da895606ecde4b0ceaee6d19ddcc42be35ec32fa3667f3efbe2f79457de9c4, 7365cd76ce2b2cd2aeb998ff53c5faff144e8a06b698a3d156b686f2ff640691, 73a91d7dbdff150632a9501c94b4f328e61fc8a8e52d27b2646921ddee8acae2, 73f834726b1091494d8151ff053eeb4dc6f79dd49525f23a5583c2bdeb176eb8, 769603162b93de2d11888c1a820f0eef385b3a2c113f1bb24f939c79edc1ce62, 7e0ff000ce7cacd201a76a017ee669f34e71f557fa468280cf27b0d2370dd8ad, 7e1c9498c44a60315c3f5e41c9a8247d605c66328653cef4560277592de79e93, 7e46a30ec382d6973695520a3c88337bed3f33d5d30b64cac689fb83ebd29d8f, 7f8e465edd27cdcd1d28292c35440d745b8bd528e21d6f56eb683b65d922eaed, 84c073bfc86cf51aa8c33fa91b43ef2091a6e41482fa9c257204547955dcb4ca, 854ed6e135b1405329003f0595c3ca462faf5381ac5d6f93bccfece61d6a2d88, 8850f6c649bd4d69d7ddb1f817865d67ee1de340e8c397f587a67fbcbba35cdd, 88f1612d7e774e0bbd6708ca946bcdb3c671a18048b2a4f5ad33c6a7c2db02de, 8a203d0dd4821b42ca399140e093919348b60ac43140e92f88d047263e2c57b4, 8db84b45c31f64f03ffef9728a39eae8e32c9b3fd21cc4fa914aab22c0104de1, 92512032cefa1fd63490ab00eb974b15ae557578d901faf4aa6c3ff4c214a239, 9860f515da98b85f61d2ee816271717b77245a1163ba498d5253974d9f7c78b3, 99b3e6d71329624cb75a88bb66e3249510f6008a38de5535ca5ccb8f580519e0, 9c89e90a6a649cbe41aaae468aab6bdb1400620bee498b151b282c411fc11357, 9d2e4a42cbcdd9315b6c86a36af632c86293940287dc26930e1c7932eb7c6cb2, 9dbd07d864d31d13b96f1bd61bf83dcd04b43f5266019c99592671cd819968e6, a74dd36806499b164906b0b9a7b7118fb19a02562a7229c544d77dd946449881, acd55c44b8b0d66d66defed85ca18082c092f048d3621da827fce593305c11fd, ae0fb4bf4a6faa4b808794b6e6ccbdf9f10c1ce01a86ccece002ac63cf09ff29, ae16d853600d647688f414e023ce8644ceacf1d6ada050792ee665c4465c939b, afd293b75c5adfbff1183b08033d36fc0845c554e5ba41f0c1c647eb78a5952e, b75268bc78de915eff442611f9c7503b4f872b22d7c54547694923cce6427b4e, bb3830b14df80838fb201c611abf0c1f3714c6b8b103ed084eafc170036631be, bcf07679ea026f1dfba6f9ab63251e4834dc007bd2c5b9039deb9d900fe1c5e6, be132253fb111600acedb58fa96fd18af69a8a8395880b0d8d89ff13ba30455b, c0908b08a80f031c49a50f873a8d4a9426c0100fb4fa7a46f7b34540191684ce, c0cfeb9b627dddd81f403d8848e70e54e4fe5c67da07e3ed1b16c1bb665b5e42, c34f400023783127e5181d5e65083adc1f3abf28127eb560e4d03c547fa5a2c2, c4c6b0db707020364cd398d2a7a3eb2516cfeb0a011557dce3393e25eaa90be4, c71ddd9aeaed18b6a3e6c80119504ececdfa329328e4a814913be6113c8efb1d, c9ef35bed70ffa0981bafd0071185b56fdad8f9c97f3582a4dae9b420959fb97, ca3056bbec01c0610b7f7f169ee1081c72cc210df169c9cc36e9bcfc38f94ceb, cd1dd8cff168b57aebbd59a62e48e592be8571082e1e5416613cd6ad27edc2ce, cd5ff596b7bacb117f90893f94fd8c542b659cc58f90ed1fbd0471fe85148bff, cdcdcd2866eb4156875cb8a2304d2dce9d9ba764f67e5a79c98556c9efa2aeaa, cf41501fa77ffece7a67b9cd996b6a3fceafefb44bf192c9078a2f0e30e01f97, d68553c0525323e804344a4cb77b8bf0b35ce5f2349a2340ba482380d785e19b, d699dc58c91ce4c886a858addf54b2501bf55f4d4be91deac4e57a5be31b1a94, d71fce8dc14cfb082041c2ddd6184baa6e1bc535582e36174bc0a80be9f7a879, d99ae6b2da11fb89672906ccdb3ef2dde4534ca1406219285784c275af5e7014, dac28f4a11429f99705bfbf0e49f586c3c3a43a5535c387f6ab01cfea3386dff, e2bfdefbafe2445693f85af28c825c2aacba769c18393fd640386abde587498f, e501b3cc3f0a32e14ba475038712e24c312c9468780eaf36f47aa73a16bf5f1f, e68743f3a0c299024e1540add1bcd9d3658ebbdbf172d74e1bf8fcd8c8c0406b, e72f59681ef6dd09608772cde8bb0dcbb42e97118ad58ad8fe2d3501d73bcd2e, ea98309a35f92443b9c50736ce208656ec72af114ec8aceeb02dfa041ec2d6bc, eabf1a97222db3a85269ef36c82f2ff44c91b18e6459b9e411e198b51fd9cef2, f2949996bcd03858627fb196fc6751c0a88f1a2fa1a082c885a3be4b94e7f5b1, f52c72a3c8c4592cbb6552c076a225f5956e287b096ae8b000da333ad8773b13, f689ee9af94b00e9e3f0bb072b34caaf207f32dcb4f5782fc9ca351df9a06c97, f94d16f63262ea3999997d35a5fa84a1863f889f1d2a429ce0d4faf7bb79825c, fd2c88a7d7e9a6bab6c0c9a725e12e1d1fcc9f2f6dd88eaf6c204952a570001e, ff361a79111795eabf24b7a8789347f1d043dac814cd6ff6531d47f268b72651excludes:process.hash.sha256

Suspicious JavaScript Execution via Deno

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

Detects execution of JavaScript via Deno with suspicious command-line patterns (base64, eval, http, or import in a javascript context). Adversaries may abuse Deno to run malicious JavaScript for execution or staging.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

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

[rule]
author = ["Elastic"]
description = """
Detects execution of JavaScript via Deno with suspicious command-line patterns (base64, eval, http, or import in a
javascript context). Adversaries may abuse Deno to run malicious JavaScript for execution or staging.
"""
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.sysmon_operational-*",
    "winlogbeat-*",
]
language = "eql"
license = "Elastic License v2"
name = "Suspicious JavaScript Execution via Deno"
references = [
    "https://reliaquest.com/blog/threat-spotlight-casting-a-wider-net-clickfix-deno-and-leaknets-scaling-threat",
    "https://deno.com/"
]
risk_score = 73
rule_id = "ff18d24b-2ba6-4691-a17f-75c4380d0965"
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Execution",
    "Resources: Investigation Guide",
    "Data Source: Elastic Defend",
    "Data Source: Sysmon",
    "Data Source: SentinelOne",
    "Data Source: Microsoft Defender XDR",
    "Data Source: Crowdstrike",
    "Data Source: Elastic Endgame", 
    "Data Source: Windows Security Event Logs"
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
process where host.os.type == "windows" and event.type == "start" and
 (process.name : "deno.exe" or ?process.pe.original_file_name == "deno.exe" or ?process.code_signature.subject_name == "Deno Land Inc.") and
 process.command_line : ("*javascript*base64*", "*eval(*", "*http*", "*javascript*import*")
'''

note = """## Triage and analysis

### Investigating Suspicious JavaScript Execution via Deno

#### Possible investigation steps

- What execution mode and permission scope did Deno use?
  - Focus: `process.command_line`: inline `eval(`, `data:application/javascript;base64`, remote `http` / `https`, inline JavaScript `import`, local `.js` / `.ts` targets, and broad `-A` or `--allow-*` flags.
  - Implication: escalate faster when inline/base64 code or remote-code strings pair with broad permissions; lower concern only for a stable local task with narrow permissions. Treat `http` alone as unresolved until later evidence shows import, callback, or benign package retrieval.

- Is the runtime the expected Deno binary and path?
  - Focus: `process.executable`, `process.hash.sha256`, `process.pe.original_file_name`, `process.code_signature.subject_name`, and `process.code_signature.trusted` for `Deno Land Inc.`, portable copies, renamed binaries, or user-writable paths.
  - Implication: escalate when identity, signer, path, or hash history suggests a renamed or opportunistic runtime; lower concern when signed path and hash history match a managed install. Runtime identity never clears suspicious arguments.

- Does launch lineage fit development/build or social-engineered execution?
  - Focus: `process.parent.executable`, `process.parent.command_line`, `user.id`, `host.name`, and child recovery; separate terminals, IDEs, and CI runners from VBS, PowerShell, MSI, browser, chat, or document launchers.
  - Implication: escalate when Deno follows a script host, installer, browser, chat client, or document process on a non-developer endpoint; lower concern when user, host, parent, and command pattern match a recognized developer, build, or lab host.

- Did Deno start follow-on processes?
  - Focus: child events from `process.entity_id`; if absent, use `host.id`, `process.parent.pid`, and a tight alert window. Review child `process.executable`, `process.command_line`, and `process.hash.sha256`. $investigate_2
  - Implication: escalate when Deno spawns shells, downloaders, installers, schedulers, PsExec-like tools, `klist`, or other utilities; keep scope narrower when the tree ends at Deno and no suspicious child process appears.

- Do DNS/network destinations fit the Deno command mode?
  - Focus: DNS/network events for `process.entity_id`; if absent, use `host.id`, `process.pid`, and a tight alert window. Review `dns.question.name`, `dns.resolved_ip`, `destination.ip`, and `destination.port`. $investigate_3
  - Hint: separate DNS lookups from connections, then map `dns.resolved_ip` to `destination.ip` before judging module source/callback fit.
  - Implication: escalate when Deno reaches rare user/host domains, public hosting, new module sources, S3-like staging, or polling/C2 endpoints unrelated to the task; lower concern when traffic stays with recognized internal registries, package mirrors, or vendor services. Missing network telemetry is unresolved, not benign.

- Did Deno stage scripts, modules, or persistence artifacts?
  - Focus: file events for `process.entity_id`; if absent, use `host.id`, `process.pid`, and a tight alert window. Review `file.path`, `file.origin_url`, `file.Ext.windows.zone_identifier`, and later `process.executable` reuse of written paths. $investigate_4
  - Range: start with the alert window; after the first suspicious write, check later execution of that artifact.
  - Implication: escalate when Deno writes scripts, binaries, cache content, or startup material into user-writable or persistence paths, or provenance shows internet delivery; lower concern when artifacts stay inside a recognized source tree, build workspace, or Deno cache expected for the command. Missing file telemetry is unresolved, not benign.

- Do related alerts change scope?
  - Focus: related alerts for the same `user.id` in 48 hours; compare Deno path, parent launcher, command mode, permission flags, and module or destination pattern. $investigate_0
  - Hint: if user scope is quiet or ambiguous, compare related alerts for the same `host.id` in 48 hours to see whether the pattern stays local or recurs in execution alerts. $investigate_1
  - Implication: broaden response when the same Deno path, flags, launcher, or remote-code pattern appears in other suspicious alerts; keep the case local only when local evidence fits one recognized workflow and alert history does not contradict it.

- Escalate for broad permissions, abnormal lineage, follow-on execution, remote code retrieval, staging, repeated delivery, or related-alert expansion; close only when all evidence binds to one recognized developer, build, or lab workflow; preserve evidence and escalate on conflict or incomplete visibility.

### False positive analysis

- Developer workstations and CI/build runners can legitimately use Deno. Confirm only when runtime identity, parent launcher, command/permission scope, and available DNS/network evidence align with the same repository, package registry, internal module host, or build workflow, with no suspicious child process or off-workspace artifact. Require available repository metadata, build definitions, or developer-host inventory; without them, do not close on recurrence alone. Use prior alerts only after alert-local and recovered evidence bind activity to one exact workflow, and require outside confirmation where telemetry cannot prove it.
- Authorized lab or automation testing can use inline eval, remote imports, or data URLs, but should stay on lab/automation hosts with bounded permissions. Confirm only when broad `-A` or `--allow-all` is absent or test-harness-justified, the parent launcher fits that lab, file/network evidence shows no callback or staging, and `user.id` or `host.id` scope explains the activity.
- Build exceptions from the minimum confirmed workflow: stable `process.executable` or `process.code_signature.subject_name`, `process.parent.executable`, exact `process.command_line` permission/import pattern, and proven `user.id` or `host.id` scope. Avoid exceptions on `process.name`, `user.name`, `deno.exe`, signer, or broad permission flags alone.

### Response and remediation

- If confirmed benign, reverse temporary containment and record evidence proving the workflow: runtime identity, command mode and permissions, parent launcher, `user.id` / `host.id` scope, and available destination or artifact evidence. Create an exception only after that same narrow workflow recurs across prior alerts from this rule.
- If suspicious but unconfirmed, preserve the alert document, process tree, exact command line, parent and child process events, Deno cache/workspace artifacts, and available file/DNS/network records before containment. Apply reversible containment first: temporary blocking of the confirmed module or callback destination, heightened monitoring on affected `host.id` and `user.id`, or host isolation only when follow-on execution, payload staging, or repeated suspicious destinations indicate active compromise and asset tolerates isolation.
- If confirmed malicious, isolate the host when operationally tolerable or terminate Deno only after preserving volatile process evidence. Block confirmed malicious domains, IPs, hashes, executable paths, and staged artifact paths; then review hosts/users for the same parent launcher, Deno command mode, permission pattern, and destination set before removing staged scripts, unauthorized Deno runtimes, startup material, scheduled tasks, or persistence tied to the chain.
- Post-incident hardening: restrict Deno to recognized developer, build, and lab hosts; review whether `-A` or broad `--allow-*` permissions are necessary; retain process plus file/network telemetry needed for triage; and record adjacent variants such as `data:` URLs, remote `https:` imports, `npm:` / `jsr:` modules, and Deno launched from script hosts with the case outcome.
"""

setup = """## Setup

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

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

### Additional data sources

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

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

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "host.name",
    "host.id",
    "user.id",
    "process.entity_id",
    "process.pid",
    "process.executable",
    "process.command_line",
    "process.pe.original_file_name",
    "process.code_signature.subject_name",
    "process.code_signature.trusted",
    "process.parent.executable",
    "process.parent.command_line",
]

[transform]

[[transform.investigate]]
label = "Alerts associated with the user"
description = ""
providers = [
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
  ]
]
relativeFrom = "now-48h/h"
relativeTo = "now"

[[transform.investigate]]
label = "Alerts associated with the host"
description = ""
providers = [
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
  ]
]
relativeFrom = "now-48h/h"
relativeTo = "now"

[[transform.investigate]]
label = "Child process events from Deno"
description = ""
providers = [
  [
    { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

[[transform.investigate]]
label = "Network events from Deno"
description = ""
providers = [
  [
    { excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

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

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

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

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

[[rule.threat.technique]]
id = "T1105"
name = "Ingress Tool Transfer"
reference = "https://attack.mitre.org/techniques/T1105/"

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

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

Stages and Predicates

Stage 1: process

process where host.os.type == "windows" and event.type == "start" and
 (process.name : "deno.exe" or ?process.pe.original_file_name == "deno.exe" or ?process.code_signature.subject_name == "Deno Land Inc.") and
 process.command_line : ("*javascript*base64*", "*eval(*", "*http*", "*javascript*import*")

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.code_signature.subject_nameeq
  • Deno Land Inc. corpus 2 (elastic 2)
field:"Signature" kind:eq value:"Deno Land Inc."
process.command_linewildcard
  • *eval(* corpus 6 (elastic 6)
  • *http* corpus 5 (elastic 5)
  • *javascript*base64* corpus 2 (elastic 2)
  • *javascript*import* corpus 3 (elastic 3)
field:"CommandLine" kind:wildcard
process.namewildcard
  • deno.exe corpus 3 (elastic 3)
field:"process_basename" kind:wildcard value:"deno.exe"
process.pe.original_file_nameeq
  • deno.exe corpus 2 (elastic 2)
field:"OriginalFileName" kind:eq value:"deno.exe"

Suspicious Microsoft Antimalware Service Execution

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

Identifies suspicious execution of the Microsoft Antimalware Service Executable (MsMpEng.exe) from non-standard paths or renamed instances. This may indicate an attempt to evade defenses through DLL side-loading or by masquerading as the antimalware process.

Known False Positives

  • Microsoft Antimalware Service Executable installed on non default installation path.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2021/07/07"
integration = ["endpoint", "windows", "m365_defender", "crowdstrike"]
maturity = "production"
updated_date = "2026/04/29"

[rule]
author = ["Elastic", "Dennis Perto"]
description = """
Identifies suspicious execution of the Microsoft Antimalware Service Executable (MsMpEng.exe) from non-standard paths or
renamed instances. This may indicate an attempt to evade defenses through DLL side-loading or by masquerading as the
antimalware process.
"""
false_positives = ["Microsoft Antimalware Service Executable installed on non default installation path."]
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 = "Suspicious Microsoft Antimalware Service Execution"
references = [
    "https://news.sophos.com/en-us/2021/07/04/independence-day-revil-uses-supply-chain-exploit-to-attack-hundreds-of-businesses/",
]
risk_score = 73
rule_id = "053a0387-f3b5-4ba5-8245-8002cca2bd08"
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Defense Evasion",
    "Data Source: Elastic Endgame",
    "Data Source: Elastic Defend",
    "Data Source: Sysmon",
    "Data Source: Microsoft Defender XDR",
    "Data Source: Crowdstrike",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
process where host.os.type == "windows" and event.type == "start" and
(
  (process.pe.original_file_name == "MsMpEng.exe" and not process.name : "MsMpEng.exe") or
  (
    process.name : "MsMpEng.exe" and
    not process.executable : (
            "?:\\ProgramData\\Microsoft\\Windows Defender\\*.exe",
            "?:\\Program Files\\Windows Defender\\*.exe",
            "?:\\Program Files (x86)\\Windows Defender\\*.exe",
            "?:\\Program Files\\Microsoft Security Client\\*.exe",
            "?:\\Program Files (x86)\\Microsoft Security Client\\*.exe",

            /* Crowdstrike specific exclusion as it uses NT Object paths */
            "\\Device\\HarddiskVolume*\\ProgramData\\Microsoft\\Windows Defender\\*.exe",
            "\\Device\\HarddiskVolume*\\Program Files\\Windows Defender\\*.exe",
            "\\Device\\HarddiskVolume*\\Program Files (x86)\\Windows Defender\\*.exe",
            "\\Device\\HarddiskVolume*\\Program Files\\Microsoft Security Client\\*.exe",
            "\\Device\\HarddiskVolume*\\Program Files (x86)\\Microsoft Security Client\\*.exe"
    )
  )
)
'''

note = """## Triage and analysis

### Investigating Suspicious Microsoft Antimalware Service Execution

#### Possible investigation steps

- Which Defender identity anomaly did the alert capture?
  - Focus: `process.name`, `process.pe.original_file_name`, `process.executable`, `process.code_signature.subject_name`, and `process.code_signature.trusted`.
  - Implication: escalate when `process.pe.original_file_name` is "MsMpEng.exe" under renamed `process.name`, or `process.name` is "MsMpEng.exe" outside Defender/Microsoft Security Client paths, even with trusted Microsoft signing; lower suspicion only when exact path, signer, and name pattern fit controlled packaging, recovery, or malware-analysis copy.
- Does the path, file timing, and parent context look like staged Defender abuse?
  - Why: unusual-path Defender binaries can load same-folder DLLs through search-order behavior, so path and parent context separate masquerading or side-loading from controlled copies.
  - Focus: `process.executable`, `process.Ext.relative_file_creation_time`, `process.Ext.relative_file_name_modify_time`, `process.parent.executable`, and `process.parent.command_line`.
  - Implication: escalate when the binary is fresh, recently renamed, or launched from user-writable, temp, share, archive, agent working, or Windows staging paths by a script, archive tool, RMM agent, or dropper parent; path age and parent context support benign closure only if later side-loading and launcher checks do not contradict them.
- Does the user, token, and session context fit Defender service execution?
  - Focus: `user.id`, `user.name`, `process.Ext.session_info.logon_type`, and `process.Ext.token.integrity_level_name`.
  - Implication: escalate when the process runs under an interactive/domain user, a non-service logon, or a user-level token that does not fit antimalware service startup; SYSTEM or service context lowers only the session concern and does not clear the unusual path by itself.
- If file or library telemetry is available, is there same-directory staging or DLL side-loading evidence?
  - Focus: recover file and library events with `host.id` plus `process.entity_id` when present, or `host.id` plus `process.pid` and a tight alert window; inspect `file.path`, `dll.path`, `dll.name`, `dll.code_signature.trusted`, and `dll.Ext.relative_file_creation_time`. $investigate_0
  - Hint: missing file or library telemetry is unresolved, not benign; prioritize same-folder DLLs whose path, signer, or creation time does not fit the product layout, plus artifacts created before `process.executable` started.
  - Implication: escalate when the unusual Defender copy loads a recent, unsigned/untrusted same-folder DLL or the directory contains newly staged executables, DLLs, scripts, archives, or renamed files; complete recovery with only expected Microsoft components lowers side-loading concern.
- Does the process act as a launcher rather than a passive service component?
  - Focus: child process events where `process.parent.entity_id` matches suspicious `process.entity_id`, repeated starts from `process.executable` on `host.id`, and child `process.name`, `process.executable`, and `process.command_line`.
    - $investigate_1
    - $investigate_2
  - Implication: escalate when it starts shells, PowerShell, certutil, netsh, installers, encryption tooling, or other hands-on-keyboard utilities, or when repeated launches suggest staged execution; no child or repeat behavior lowers launcher concern but does not clear the path anomaly.
- If local findings stay suspicious or unresolved, do related alerts show path reuse or host compromise?
  - Focus: related alerts for `process.executable`, especially unusual-path Defender, masquerading, or side-loading detections.
    - $investigate_3
  - Hint: also review related alerts for `host.id` or `user.id`, especially staging, persistence, credential-access, ransomware, or other masquerading detections.
    - $investigate_4
    - $investigate_5
  - Implication: broaden scope when the same path appears on unrelated hosts or the host has precursor or follow-on alerts; keep the case local only when related alerts show no reuse or follow-on activity and all local evidence is clean.

- Escalate when Defender identity/path evidence plus one meaningful corroborator supports masquerading or DLL side-loading; close only when exact path, signer, parent, session, host/user scope, and optional outside confirmation tie to one controlled workflow with no contradictory telemetry; preserve artifacts and escalate when findings stay mixed or visibility is incomplete.

### False positive analysis

- A non-default Defender installation, controlled security packaging, recovery, or malware-analysis validation can stage Microsoft antimalware binaries outside default paths. Confirm the same workflow by matching exact `process.executable`, `process.hash.sha256` or `process.code_signature.thumbprint_sha256`, Microsoft `process.code_signature.subject_name`, `process.code_signature.trusted`, `process.parent.executable`, `process.parent.command_line`, `user.id`, `host.id`, and session pattern; without outside records, require recurrence across prior rule alerts without side-loading, launcher, or related-alert contradictions.
- Treat production execution from temp, user-writable, share, archive, agent working, or Windows staging paths as an operational anti-pattern unless a controlled workflow proves why the copy exists. Do not close as benign when same-folder DLLs, child tooling, recent rename timing, or unrelated related alerts contradict it.
- Build exceptions only from the minimum confirmed workflow pattern; avoid exceptions on `process.name`, `process.pe.original_file_name`, signer subject alone, or host alone.

### Response and remediation

- If confirmed benign, reverse any temporary containment and document the exact workflow: executable path, Microsoft signer or hash, parent process, session context, user/host scope, and any controlled packaging, recovery, or lab record that corroborated the telemetry. Create an exception only after the same narrow workflow pattern is stable across prior alerts.
- If suspicious but unconfirmed, preserve the alert details, process tree, command line, binary copy and hash, parent context, directory listing, same-folder DLLs, and related-alert timeline before containment. Apply reversible containment first, such as execution prevention on the suspicious path or temporary host isolation when active launcher behavior or side-loading creates continuing risk and the host role can tolerate interruption.
- If confirmed malicious, preserve process and artifact evidence first, including the suspicious Defender copy, same-folder DLLs, support files, launcher context, and related-alert timeline. Then isolate the host or apply an equivalent endpoint containment control, terminate only the suspicious non-default-path or renamed Defender instance, quarantine the suspicious executable and supporting files, remove launcher or persistence artifacts found during scoping, and restore the legitimate security product from known-good media if the masquerading copy replaced or shadowed a trusted component.
- After containment, restrict execution from user-writable, temporary, share, archive, and agent working directories where feasible, retain process/file/library telemetry that affected this case, and document the confirmed benign workflow or malicious artifact set for future triage.
"""

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

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "host.name",
    "host.id",
    "user.name",
    "user.id",
    "process.entity_id",
    "process.pid",
    "process.name",
    "process.executable",
    "process.command_line",
    "process.pe.original_file_name",
    "process.parent.executable",
    "process.parent.command_line",
    "process.code_signature.subject_name",
    "process.code_signature.trusted",
]

[transform]

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

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

[[transform.investigate]]
label = "Process events for the suspicious executable path"
description = ""
providers = [
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "process.executable", queryType = "phrase", value = "{{process.executable}}", valueType = "string" },
    { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
  ]
]
relativeFrom = "now-48h/h"
relativeTo = "now"

[[transform.investigate]]
label = "Alerts associated with the suspicious executable path"
description = ""
providers = [
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "process.executable", queryType = "phrase", value = "{{process.executable}}", valueType = "string" }
  ]
]
relativeFrom = "now-48h/h"
relativeTo = "now"

[[transform.investigate]]
label = "Alerts associated with the host"
description = ""
providers = [
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
  ]
]
relativeFrom = "now-48h/h"
relativeTo = "now"

[[transform.investigate]]
label = "Alerts associated with the user"
description = ""
providers = [
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
  ]
]
relativeFrom = "now-48h/h"
relativeTo = "now"

[[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.subtechnique]]
id = "T1036.005"
name = "Match Legitimate Resource Name or Location"
reference = "https://attack.mitre.org/techniques/T1036/005/"

[[rule.threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"

[[rule.threat.technique.subtechnique]]
id = "T1574.001"
name = "DLL"
reference = "https://attack.mitre.org/techniques/T1574/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 == "MsMpEng.exe" and not process.name : "MsMpEng.exe") or
  (
    process.name : "MsMpEng.exe" and
    not process.executable : (
            "?:\\ProgramData\\Microsoft\\Windows Defender\\*.exe",
            "?:\\Program Files\\Windows Defender\\*.exe",
            "?:\\Program Files (x86)\\Windows Defender\\*.exe",
            "?:\\Program Files\\Microsoft Security Client\\*.exe",
            "?:\\Program Files (x86)\\Microsoft Security Client\\*.exe",
            "\\Device\\HarddiskVolume*\\ProgramData\\Microsoft\\Windows Defender\\*.exe",
            "\\Device\\HarddiskVolume*\\Program Files\\Windows Defender\\*.exe",
            "\\Device\\HarddiskVolume*\\Program Files (x86)\\Windows Defender\\*.exe",
            "\\Device\\HarddiskVolume*\\Program Files\\Microsoft Security Client\\*.exe",
            "\\Device\\HarddiskVolume*\\Program Files (x86)\\Microsoft Security Client\\*.exe"
    )
  )
)

Indicators

These rows show field, operator, and value matches.

Suspicious Python Shell Command Execution

#
Status
production
Severity
medium
Time window
9m
Group by
Esql.time_window_date_trunc, agent.id, host.name, process.parent.entity_id
Author
Elastic
Source
github.com/elastic/detection-rules

Detects the execution of suspicious shell commands via the Python interpreter. Attackers may use Python to execute shell commands to gain access to the system or to perform other malicious activities, such as credential access, data exfiltration, or lateral movement.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2026/03/26"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Detects the execution of suspicious shell commands via the Python interpreter. Attackers 
may use Python to execute shell commands to gain access to the system or to perform other
malicious activities, such as credential access, data exfiltration, or lateral movement.
"""
from = "now-9m"
language = "esql"
license = "Elastic License v2"
name = "Suspicious Python Shell Command Execution"
note = """## Triage and analysis

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

### Investigating Suspicious Python Shell Command Execution

This rule flags Linux or macOS activity where Python rapidly launches multiple shell commands through sh/bash-style interpreters, a strong sign that a script is driving hands-on execution rather than normal application behavior. An attacker might use a Python backdoor to run `sh -c` commands such as `whoami`, `uname`, `env`, `find`, and `curl` in quick succession to profile the host, locate data, and pull down follow-on tools.

### Possible investigation steps

- Reconstruct the full process tree around the Python parent to identify the originating script or module, execution path, user context, and whether it was launched by an interactive session, scheduled task, service, container runtime, or approved automation.
- Review the Python code or script content that spawned the shells, along with recent file creation or modification and package installation activity, to determine whether it is legitimate application logic or an unexpected payload introduced in temporary, user, or application directories.
- Compare the clustered shell commands with any immediate follow-on behavior such as outbound network connections, tool downloads, archive creation, credential store access, or additional interpreter launches to assess whether the activity moved from discovery into payload delivery or exfiltration.
- Pivot on the same host and Python execution lineage for prior and subsequent events to uncover persistence or lateral movement indicators, including cron or systemd changes, launchd modifications, SSH activity, or repeated execution patterns across other endpoints.
- Validate with the asset or application owner whether the behavior matches known deployment, build, or administrative workflows, and if it does not, isolate the host and collect memory, script artifacts, and shell history for deeper analysis.

### False positive analysis

- A legitimate Python administration or deployment script may call `sh -c` to run discovery and download commands such as `whoami`, `uname`, `env`, `find`, or `curl` during host setup; verify the parent Python script path, user, and working directory match an approved maintenance job and that the command set is expected for that script.
- A Python application on Linux or macOS may spawn shell wrappers during startup, diagnostics, or update checks and generate several distinct commands within a minute; confirm the Python executable and child shell activity originate from the expected application directory and correlate with a recent authorized install, upgrade, or troubleshooting session.

### Response and remediation

- Isolate the affected Linux or macOS host from the network, terminate the malicious Python process and any spawned `sh -c` or `bash -c` children, and block any external IPs, domains, or download URLs the script contacted.
- Preserve and quarantine the Python script, shell history, downloaded payloads, and files created in temporary, user, or application directories, then remove attacker persistence such as cron jobs, systemd service or timer units, launchd plists, login scripts, and unauthorized `authorized_keys` entries.
- Restore the system to a known-good state by removing attacker-created files only after collection, reinstalling or repairing modified packages and startup items, and reimaging the host if system binaries, security tools, or core configuration files were altered.
- Rotate credentials and secrets exposed on the host, including local accounts, SSH keys, API tokens, and application or cloud credentials, especially if the shell activity included `env`, keychain access, history review, or reads from credential files.
- Escalate to incident response immediately if the Python-launched shells used `curl` or `wget` to fetch payloads, established outbound sessions to untrusted infrastructure, touched multiple endpoints, or showed evidence of credential theft, persistence, or data collection.
- Harden the environment by restricting Python and shell execution from temporary or user-writable paths, limiting which users and services can invoke shell interpreters, tightening egress controls, and adding detections for Python spawning shell commands, new cron or launchd items, and unauthorized SSH key changes.
"""
risk_score = 47
rule_id = "b42e4b88-fc4a-417b-a45e-4d4a3db9fd41"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "OS: macOS",
    "Use Case: Threat Detection",
    "Tactic: Execution",
    "Data Source: Elastic Defend",
    "Resources: Investigation Guide",
]
type = "esql"
query = '''
FROM logs-endpoint.events.process-* METADATA _id, _version, _index

| WHERE host.os.type in ("linux", "macos") and event.type == "start" and TO_LOWER(process.parent.name) like "python*" and
  process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox") and
  KQL("""event.action:"exec" and process.args:("-c" or "-cl" or "-lc")""")

// truncate timestamp to 1-minute window
| EVAL Esql.time_window_date_trunc = DATE_TRUNC(1 minutes, @timestamp)

| EVAL Esql.process_command_line_patterns = CASE(
  process.command_line like "*grep*", "grep",
  process.command_line like "*find*", "find",
  process.command_line like "*curl*", "curl",
  process.command_line like "*env *", "environment_enumeration",
  process.command_line like "*wget*", "wget",
  process.command_line like "*whoami*" or process.command_line like "*uname*" or process.command_line like "*hostname*", "discovery", "other"
)

| KEEP
    @timestamp,
    _id,
    _index,
    _version,
    Esql.process_command_line_patterns,
    Esql.time_window_date_trunc,
    host.os.type,
    event.type,
    event.action,
    process.parent.name,
    process.working_directory,
    process.parent.working_directory,
    process.name,
    process.executable,
    process.command_line,
    process.parent.executable,
    process.parent.entity_id,
    agent.id,
    host.name,
    data_stream.dataset,
    data_stream.namespace

| STATS
  Esql.process_command_line_count_distinct = COUNT_DISTINCT(process.command_line),
  Esql.patterns_count_distinct = COUNT_DISTINCT(Esql.process_command_line_patterns),
  Esql.process_command_line_values = VALUES(process.command_line),
  Esql.host_name_values = values(host.name),
  Esql.agent_id_values = values(agent.id),
  Esql.data_stream_dataset_values = values(data_stream.dataset),
  Esql.data_stream_namespace_values = values(data_stream.namespace)
  BY process.parent.entity_id, agent.id, host.name, Esql.time_window_date_trunc

| SORT Esql.process_command_line_count_distinct DESC
| WHERE Esql.process_command_line_count_distinct >= 5 AND Esql.patterns_count_distinct >= 4
'''

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

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

Stages and Predicates

Stage 1: from

FROM logs-endpoint.events.process-* METADATA _id, _version, _index

Stage 2: where

| WHERE host.os.type in ("linux", "macos") and event.type == "start" and TO_LOWER(process.parent.name) like "python*" and
  process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox") and
  KQL("""event.action:"exec" and process.args:("-c" or "-cl" or "-lc")""")

Stage 3: eval

| EVAL Esql.time_window_date_trunc = DATE_TRUNC(1 minutes, @timestamp)

Stage 4: eval

| EVAL Esql.process_command_line_patterns = CASE(
  process.command_line like "*grep*", "grep",
  process.command_line like "*find*", "find",
  process.command_line like "*curl*", "curl",
  process.command_line like "*env *", "environment_enumeration",
  process.command_line like "*wget*", "wget",
  process.command_line like "*whoami*" or process.command_line like "*uname*" or process.command_line like "*hostname*", "discovery", "other"
)
Esql.process_command_line_patterns =
ifprocess.command_line like "*grep*""grep"
elifprocess.command_line like "*find*""find"
elifprocess.command_line like "*curl*""curl"
elifprocess.command_line like "*env *""environment_enumeration"
elifprocess.command_line like "*wget*""wget"
elifprocess.command_line like "*whoami*" or process.command_line like "*uname*" or process.command_line like "*hostname*""discovery"
else"other"

Stage 5: keep

| KEEP
    @timestamp,
    _id,
    _index,
    _version,
    Esql.process_command_line_patterns,
    Esql.time_window_date_trunc,
    host.os.type,
    event.type,
    event.action,
    process.parent.name,
    process.working_directory,
    process.parent.working_directory,
    process.name,
    process.executable,
    process.command_line,
    process.parent.executable,
    process.parent.entity_id,
    agent.id,
    host.name,
    data_stream.dataset,
    data_stream.namespace

Stage 6: stats

| STATS
  Esql.process_command_line_count_distinct = COUNT_DISTINCT(process.command_line),
  Esql.patterns_count_distinct = COUNT_DISTINCT(Esql.process_command_line_patterns),
  Esql.process_command_line_values = VALUES(process.command_line),
  Esql.host_name_values = values(host.name),
  Esql.agent_id_values = values(agent.id),
  Esql.data_stream_dataset_values = values(data_stream.dataset),
  Esql.data_stream_namespace_values = values(data_stream.namespace)
  BY process.parent.entity_id, agent.id, host.name, Esql.time_window_date_trunc

Stage 7: sort

| SORT Esql.process_command_line_count_distinct DESC

Stage 8: where

| WHERE Esql.process_command_line_count_distinct >= 5 AND Esql.patterns_count_distinct >= 4

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
Esql.patterns_count_distinctge
  • 4
field:"Esql.patterns_count_distinct" kind:ge value:"4"
Esql.process_command_line_count_distinctge
  • 5
field:"Esql.process_command_line_count_distinct" kind:ge value:"5"
event.actioneq
  • exec corpus 37 (elastic 22, sigma 15)
field:"EventType" kind:eq value:"exec"
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.argsin
  • -c corpus 4 (elastic 4)
  • -cl corpus 2 (elastic 2)
  • -lc corpus 2 (elastic 2)
field:"process.args" kind:in
process.namein
  • bash corpus 181 (elastic 181)
  • busybox corpus 67 (elastic 67)
  • csh corpus 148 (elastic 148)
  • dash corpus 150 (elastic 150)
  • fish corpus 151 (elastic 151)
  • ksh corpus 149 (elastic 149)
  • sh corpus 180 (elastic 180)
  • tcsh corpus 145 (elastic 145)
  • zsh corpus 180 (elastic 180)
field:"process_basename" kind:in

Output Fields

These fields are emitted when the rule matches.

FieldSource
Esql.process_command_line_count_distinctSTATS Esql.process_command_line_count_distinct = COUNT_DISTINCT(process.command_line)
Esql.patterns_count_distinctSTATS Esql.patterns_count_distinct = COUNT_DISTINCT(Esql.process_command_line_patterns)
Esql.process_command_line_valuesSTATS Esql.process_command_line_values = VALUES(process.command_line)
Esql.host_name_valuesSTATS Esql.host_name_values = values(host.name)
Esql.agent_id_valuesSTATS Esql.agent_id_values = values(agent.id)
Esql.data_stream_dataset_valuesSTATS Esql.data_stream_dataset_values = values(data_stream.dataset)
Esql.data_stream_namespace_valuesSTATS Esql.data_stream_namespace_values = values(data_stream.namespace)
process.parent.entity_idSTATS BY
agent.idSTATS BY
host.nameSTATS BY
Esql.time_window_date_truncSTATS BY

Svchost spawning Cmd

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

Identifies a suspicious parent child process relationship with cmd.exe descending from svchost.exe

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2020/02/18"
integration = ["endpoint", "windows", "system", "m365_defender", "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 = "Identifies a suspicious parent child process relationship with cmd.exe descending from svchost.exe"
from = "now-9m"
index = [
    "logs-endpoint.events.process-*",
    "winlogbeat-*",
    "logs-windows.forwarded*",
    "logs-windows.sysmon_operational-*",
    "endgame-*",
    "logs-system.security*",
    "logs-m365_defender.event-*",
    "logs-sentinel_one_cloud_funnel.*",
]
language = "kuery"
license = "Elastic License v2"
name = "Svchost spawning Cmd"
note = """## Triage and analysis

### Investigating Svchost spawning Cmd

The Service Host process (SvcHost) is a system process that can host one, or multiple, Windows services in the Windows NT family of operating systems. Note that `Svchost.exe` is reserved for use by the operating system and should not be used by non-Windows services.

This rule looks for the creation of the `cmd.exe` process with `svchost.exe` as its parent process. This is an unusual behavior that can indicate the masquerading of a malicious process as `svchost.exe` or exploitation for privilege escalation.

> **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.
- Investigate potentially compromised accounts. Analysts can do this by searching for login events (for example, 4624) to the target host after the registry modification.


### False positive analysis

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

### Response and remediation

- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- If the triage identified malware, search the environment for additional compromised hosts.
  - Implement temporary network rules, procedures, and segmentation to contain the malware.
  - Stop suspicious processes.
  - Immediately block the identified indicators of compromise (IoCs).
  - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that attackers could use to reinfect the system.
- 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:

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

references = [
    "https://nasbench.medium.com/demystifying-the-svchost-exe-process-and-its-command-line-options-508e9114e747",
]
risk_score = 21
rule_id = "fd7a6052-58fa-4397-93c3-4795249ccfa2"
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Execution",
    "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",
]
timeline_id = "e70679c2-6cde-4510-9764-4823df18f7db"
timeline_title = "Comprehensive Process Timeline"
timestamp_override = "event.ingested"
type = "new_terms"

query = '''
host.os.type:windows and event.category:process and event.type:start and process.parent.name:svchost.exe and 
process.name:(CMD.EXE or Cmd.exe or cmd.exe) and 
process.command_line:(* and not "\"cmd.exe\" /C sc control hptpsmarthealthservice 211") and 
not process.args:(".\inetsrv\iissetup.exe /keygen " or "C:\Program" or "C:\Program Files (x86)\Kaspersky Lab\NetworkAgent\klmover.exe" or "C:\Program Files (x86)\Sentry\SA\adluminupdater.exe" or "C:\Program Files\WinRAR" or "C:\Program Files\WinRAR\uninstall.exe" or "hpdiags://BatteryStatusTest" or hptpsmarthealthservice or icacls or taskkill or w32tm or *.BAT* or *.CMD* or *.bat* or *.cmd*)
'''



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

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

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

[[rule.threat.technique.subtechnique]]
id = "T1569.002"
name = "Service Execution"
reference = "https://attack.mitre.org/techniques/T1569/002/"

[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[rule.new_terms]
field = "new_terms_fields"
value = ["process.command_line"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-5d"

Stages and Predicates

Stage 1: new_terms

host.os.type:windows and event.category:process and event.type:start and process.parent.name:svchost.exe and 
process.name:(CMD.EXE or Cmd.exe or cmd.exe) and 
process.command_line:(* and not "\"cmd.exe\" /C sc control hptpsmarthealthservice 211") and 
not process.args:(".\inetsrv\iissetup.exe /keygen " or "C:\Program" or "C:\Program Files (x86)\Kaspersky Lab\NetworkAgent\klmover.exe" or "C:\Program Files (x86)\Sentry\SA\adluminupdater.exe" or "C:\Program Files\WinRAR" or "C:\Program Files\WinRAR\uninstall.exe" or "hpdiags://BatteryStatusTest" or hptpsmarthealthservice or icacls or taskkill or w32tm or *.BAT* or *.CMD* or *.bat* or *.cmd*)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.categoryeq
  • process corpus 105 (elastic 105)
field:"event.category" kind:eq value:"process"
event.typeeq
  • start corpus 67 (elastic 67)
field:"event.type" kind:eq value:"start"
process.command_lineis_not_null
  • (no value, null check)
field:"CommandLine" kind:is_not_null
process.namein
  • CMD.EXE corpus 122 (elastic 93, splunk 29)
  • Cmd.exe corpus 122 (elastic 93, splunk 29)
  • cmd.exe corpus 122 (elastic 93, splunk 29)
field:"process_basename" kind:in
process.parent.nameeq
  • svchost.exe corpus 15 (elastic 10, splunk 5)
field:"parent_process_basename" kind:eq value:"svchost.exe"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argseq.\inetsrv\iissetup.exe /keygen excludes:process.args field:"process.args" value:".\inetsrv\iissetup.exe /keygen "
process.argseqC:\Program Files (x86)\Kaspersky Lab\NetworkAgent\klmover.exeexcludes:process.args field:"process.args" value:"C:\Program Files (x86)\Kaspersky Lab\NetworkAgent\klmover.exe"
process.argseqC:\Program Files (x86)\Sentry\SA\adluminupdater.exeexcludes:process.args field:"process.args" value:"C:\Program Files (x86)\Sentry\SA\adluminupdater.exe"
process.argseqC:\Program Files\WinRARexcludes:process.args field:"process.args" value:"C:\Program Files\WinRAR"
process.argseqC:\Program Files\WinRAR\uninstall.exeexcludes:process.args field:"process.args" value:"C:\Program Files\WinRAR\uninstall.exe"
process.argseqC:\Programexcludes:process.args field:"process.args" value:"C:\Program"
process.argseqhpdiags://BatteryStatusTestexcludes:process.args field:"process.args" value:"hpdiags://BatteryStatusTest"
process.argseqhptpsmarthealthserviceexcludes:process.args field:"process.args" value:"hptpsmarthealthservice"
process.argseqicaclsexcludes:process.args field:"process.args" value:"icacls"
process.argseqtaskkillexcludes:process.args field:"process.args" value:"taskkill"
process.argseqw32tmexcludes:process.args field:"process.args" value:"w32tm"
process.argsmatch.BATexcludes:process.args field:"process.args" value:".BAT"
process.argsmatch.CMDexcludes:process.args field:"process.args" value:".CMD"
process.argsmatch.batexcludes:process.args field:"process.args" value:".bat"
process.argsmatch.cmdexcludes:process.args field:"process.args" value:".cmd"
process.command_lineeq"cmd.exe" /C sc control hptpsmarthealthservice 211excludes:process.command_line

Unusual Web Request

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

A machine learning job detected a rare and unusual URL that indicates unusual web browsing activity. This can be due to initial access, persistence, command-and-control, or exfiltration activity. For example, in a strategic web compromise or watering hole attack, when a trusted website is compromised to target a particular sector or organization, targeted users may receive emails with uncommon URLs for trusted websites. These URLs can be used to download and run a payload. When malware is already running, it may send requests to uncommon URLs on trusted websites the malware uses for command-and-control communication. When rare URLs are observed being requested for a local web server by a remote source, these can be due to web scanning, enumeration or attack traffic, or they can be due to bots and web scrapers which are part of common Internet background traffic.

Known False Positives

  • Web activity that occurs rarely in small quantities can trigger this alert. Possible examples are browsing technical support or vendor URLs that are used very sparsely. A user who visits a new and unique web destination may trigger this alert when the activity is sparse. Web applications that generate URLs unique to a transaction may trigger this when they are used sparsely. Web domains can be excluded in cases such as these.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2020/03/25"
integration = ["endpoint", "network_traffic"]
maturity = "production"
min_stack_version = "9.4.0"
min_stack_comments = "Use EA (Entity Analytics) fields"
updated_date = "2026/07/27"

[rule]
anomaly_threshold = 50
author = ["Elastic"]
description = """
A machine learning job detected a rare and unusual URL that indicates unusual web browsing activity. This can be due to
initial access, persistence, command-and-control, or exfiltration activity. For example, in a strategic web compromise
or watering hole attack, when a trusted website is compromised to target a particular sector or organization, targeted
users may receive emails with uncommon URLs for trusted websites. These URLs can be used to download and run a payload.
When malware is already running, it may send requests to uncommon URLs on trusted websites the malware uses for
command-and-control communication. When rare URLs are observed being requested for a local web server by a remote
source, these can be due to web scanning, enumeration or attack traffic, or they can be due to bots and web scrapers
which are part of common Internet background traffic.
"""
false_positives = [
    """
    Web activity that occurs rarely in small quantities can trigger this alert. Possible examples are browsing technical
    support or vendor URLs that are used very sparsely. A user who visits a new and unique web destination may trigger
    this alert when the activity is sparse. Web applications that generate URLs unique to a transaction may trigger this
    when they are used sparsely. Web domains can be excluded in cases such as these.
    """,
]
from = "now-45m"
interval = "15m"
license = "Elastic License v2"
machine_learning_job_id = "packetbeat_rare_urls_ea"
name = "Unusual Web Request"
setup = """## Setup

This rule requires the installation of associated Machine Learning jobs, as well as data coming in from one of the following integrations:
- Elastic Defend
- Network Packet Capture

### Anomaly Detection Setup

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

### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.

#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).

#### The following steps should be executed in order to add the Elastic Defend integration to your system:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/current/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).

### Network Packet Capture Integration Setup
The Network Packet Capture integration sniffs network packets on a host and dissects known protocols. Monitoring the network traffic is critical to gaining observability and securing your environment — ensuring high levels of performance and security. The Network Packet Capture integration captures the network traffic between your application servers, decodes common application layer protocols and records the interesting fields for each transaction.

#### The following steps should be executed in order to add the Elastic Agent System integration "network_traffic" to your system:
- Go to the Kibana home page and click “Add integrations”.
- In the query bar, search for “Network Packet Capture” and select the integration to see more details about it.
- Click “Add Network Packet Capture”.
- Configure the integration name and optionally add a description.
- Review optional and advanced settings accordingly.
- Add the newly installed “network_traffic” to an existing or a new agent policy, and deploy the agent on your system from which network log files are desirable.
- Click “Save and Continue”.
- For more details on the integration refer to the [helper guide](https://docs.elastic.co/integrations/network_traffic).
"""
references = ["https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html"]
risk_score = 21
rule_id = "91f02f01-969f-4167-8f55-07827ac3acc9"
severity = "low"
tags = [
    "Data Source: Elastic Defend",
    "Data Source: Network Packet Capture",
    "Use Case: Threat Detection",
    "Rule Type: ML",
    "Rule Type: Machine Learning",
    "Tactic: Command and Control",
    "Resources: Investigation Guide",
]
type = "machine_learning"
note = """## Triage and analysis

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

### Investigating Unusual Web Request
The 'Unusual Web Request' detection leverages machine learning to identify rare URLs that deviate from typical web activity, potentially signaling malicious actions like initial access or data exfiltration. Adversaries exploit trusted sites by embedding uncommon URLs for payload delivery or command-and-control. This rule flags such anomalies, aiding in early threat detection and response.

### Possible investigation steps

- Review the alert details to identify the specific rare URL that triggered the detection and note any associated IP addresses or domains.
- Check historical logs to determine if the rare URL has been accessed previously and identify any patterns or trends in its usage.
- Investigate the source of the request by examining the user agent, referrer, and originating IP address to assess whether it aligns with known legitimate traffic or appears suspicious.
- Analyze the destination of the URL to determine if it is associated with known malicious activity or if it has been flagged in threat intelligence databases.
- Correlate the unusual web request with other security events or alerts to identify potential connections to broader attack campaigns or ongoing threats.
- Assess the impacted systems or users to determine if there are any signs of compromise, such as unexpected processes, network connections, or data exfiltration attempts.
- Consider reaching out to the user or system owner to verify if the access to the rare URL was intentional and legitimate, providing additional context for the investigation.

### False positive analysis

- Web scraping tools and bots can trigger false positives by making requests to uncommon URLs as part of routine internet background traffic.
- Legitimate web scanning or enumeration activities by security teams may be flagged; these should be reviewed and whitelisted if verified as non-threatening.
- Automated processes or scripts that access rare URLs for legitimate business purposes can be excluded by identifying and documenting these activities.
- Frequent access to uncommon URLs by trusted internal applications or services should be monitored and added to exception lists to prevent unnecessary alerts.
- Regularly review and update the list of excluded URLs to ensure it reflects current legitimate activities and does not inadvertently allow malicious traffic.

### Response and remediation

- Isolate the affected system from the network to prevent further communication with the suspicious URL and potential data exfiltration.
- Conduct a thorough scan of the isolated system using updated antivirus and anti-malware tools to identify and remove any malicious payloads or software.
- Review and block the identified unusual URL at the network perimeter to prevent other systems from accessing it.
- Analyze network logs to identify any other systems that may have communicated with the suspicious URL and apply similar containment measures.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if the threat is part of a larger attack campaign.
- Implement enhanced monitoring for similar unusual web requests across the network to detect and respond to potential threats more quickly in the future.
- Review and update firewall and intrusion detection/prevention system (IDS/IPS) rules to better detect and block uncommon URLs associated with command-and-control activities."""
[[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 = "T1102"
name = "Web Service"
reference = "https://attack.mitre.org/techniques/T1102/"

[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 = "T1189"
name = "Drive-by Compromise"
reference = "https://attack.mitre.org/techniques/T1189/"

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

World Writeable Directory File Creation and Outbound Connection

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

This rule detects the creation of a file in a world-writable directory followed by an outbound network connection via that same file. Attackers may write executables or scripts to world-writable directories to use for temporary execution.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
This rule detects the creation of a file in a world-writable directory followed by an outbound network connection via
that same file. Attackers may write executables or scripts to world-writable directories to use for temporary execution.
"""
id = "c194da29-0aa4-463b-8c87-3094bc7ecd6d"
license = "Elastic License v2"
name = "World Writeable Directory File Creation and Outbound Connection"
os_list = ["linux"]
version = "1.0.5"

query = '''
sequence by process.parent.entity_id with maxspan=3s
  [file where event.type == "creation" and file.path like ("/tmp/*", "/var/tmp/*", "/dev/shm/*")] as event0
  [network where event.type == "start" and event.action == "connection_attempted" and
   startswith~(process.executable, event0.file.path) and
   not (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"
     ) or
     process.executable like~ (
       "/tmp/go-build*", "/tmp/regctl", "/tmp/token_handler", "/tmp/tmp.*/rustup-init", "/tmp/tmp.*/juliainstaller",
       "/tmp/nix-shell-*/go-build*/gobld", "/var/tmp/go-build*", "/opt/ruby/*", "/tmp/oryx/platforms/ruby/*/bin/gem",
       "/tmp/level-linux-amd64", "/tmp/*/.vscode-server/.vscode-server/cli/servers/*/server/node"
     )
   )]
'''

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

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

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

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

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



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


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

[internal]
min_endpoint_version = "8.6.0"

Stages and Predicates

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

Stage 1: file

[file where event.type == "creation" and file.path like ("/tmp/*", "/var/tmp/*", "/dev/shm/*")] as event0

Stage 2: network

[network where event.type == "start" and event.action == "connection_attempted" and
   startswith~(process.executable, event0.file.path) and
   not (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"
     ) or
     process.executable like~ (
       "/tmp/go-build*", "/tmp/regctl", "/tmp/token_handler", "/tmp/tmp.*/rustup-init", "/tmp/tmp.*/juliainstaller",
       "/tmp/nix-shell-*/go-build*/gobld", "/var/tmp/go-build*", "/opt/ruby/*", "/tmp/oryx/platforms/ruby/*/bin/gem",
       "/tmp/level-linux-amd64", "/tmp/*/.vscode-server/.vscode-server/cli/servers/*/server/node"
     )
   )]

Indicators

These rows show field, operator, and value matches.

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/go-build*, /tmp/regctl, /tmp/token_handler, /tmp/tmp.*/rustup-init, /tmp/tmp.*/juliainstaller, /tmp/nix-shell-*/go-build*/gobld, /var/tmp/go-build*, /opt/ruby/*, /tmp/oryx/platforms/ruby/*/bin/gem, /tmp/level-linux-amd64, /tmp/*/.vscode-server/.vscode-server/cli/servers/*/server/nodeexcludes:process.executable

Back to all Elastic rules