Detection rules › Elastic

Elastic rules: 0y

AWS Detective Graph Deleted

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

Detects the deletion of an Amazon Detective behavior graph via the DeleteGraph API. Amazon Detective automatically collects log data from AWS services and uses machine learning, statistical analysis, and graph theory to build an interactive model of resource behaviors and interactions. Deleting a behavior graph destroys its historical analysis data and removes the ability to investigate security incidents using Detective's relationship mapping. An attacker with sufficient IAM permissions may delete the Detective graph to impair forensic investigation of a compromise.

Known False Positives

  • Legitimate decommissioning of an AWS account, regional consolidation, or removal of an unused Detective deployment may trigger this rule. Validate the caller identity and confirm a corresponding change management ticket exists before closing.

MITRE ATT&CK Coverage

TacticTechniques
Defense Impairment

Telemetry Coverage

Rule Body

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

[rule]
author = ["Elastic"]
description = """
Detects the deletion of an Amazon Detective behavior graph via the DeleteGraph API. Amazon
Detective automatically collects log data from AWS services and uses machine learning, statistical
analysis, and graph theory to build an interactive model of resource behaviors and interactions.
Deleting a behavior graph destroys its historical analysis data and removes the ability to
investigate security incidents using Detective's relationship mapping. An attacker with sufficient
IAM permissions may delete the Detective graph to impair forensic investigation of a compromise.
"""
false_positives = [
    """
    Legitimate decommissioning of an AWS account, regional consolidation, or removal of an unused
    Detective deployment may trigger this rule. Validate the caller identity and confirm a
    corresponding change management ticket exists before closing.
    """,
]
from = "now-6m"
index = ["logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS Detective Graph Deleted"
note = """## Triage and analysis

### Investigating AWS Detective Graph Deleted

Amazon Detective builds a behavior graph from CloudTrail, VPC Flow Logs, and GuardDuty findings, enabling investigation teams to trace the full scope and timeline of a security incident. `DeleteGraph` is a rare, irreversible operation — the historical graph data cannot be recovered after deletion. An adversary who deletes the Detective graph removes a key forensic investigation tool, making it harder to understand the scope of a compromise.

### Possible investigation steps

- Identify the caller in `aws.cloudtrail.user_identity.arn` and `user.name`. Confirm whether this is an authorized cloud administrator or an anomalous identity.
- Check whether the deletion was preceded by other defense-evasion actions in the same time window: GuardDuty detector deletion, CloudTrail StopLogging, Security Hub disable.
- Determine how long the Detective graph had been active and what historical data was lost.
- Review all IAM actions by this identity in the 24 hours before the deletion.

### False positive analysis

- Account decommissioning workflows may include Detective graph deletion as part of teardown. Verify via change management records.

### Response and remediation

- Re-enable Amazon Detective for the affected account and region.
- Reconstruct investigation context from raw CloudTrail, VPC Flow Logs, and GuardDuty findings.
- Revoke active sessions for the deleting identity if the action was unauthorized.
- Add an SCP restricting `detective:DeleteGraph` to break-glass administrator roles.
"""
references = [
    "https://docs.aws.amazon.com/detective/latest/APIReference/API_DeleteGraph.html",
]
risk_score = 21
rule_id = "fa0177e5-b065-444a-a94e-872cbb28ffee"
setup = "The AWS integration must be ingesting management events into `logs-aws.cloudtrail-*`. Amazon Detective must be enabled in the account for this event to appear."
severity = "low"
tags = [
    "Domain: Cloud",
    "Platform: AWS",
    "Data Source: AWS CloudTrail",
    "Service: AWS Detective",
    "Rule Type: Custom Query (KQL)",
    "Tactic: Defense Evasion",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

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


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[[rule.threat.technique.subtechnique]]
id = "T1562.001"
name = "Disable or Modify Tools"
reference = "https://attack.mitre.org/techniques/T1562/001/"

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

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

Stages and Predicates

Stage 1: query

data_stream.dataset: "aws.cloudtrail"
    and event.provider: "detective.amazonaws.com"
    and event.action: "DeleteGraph"
    and event.outcome: "success"

Indicators

These rows show field, operator, and value matches.

AWS IAM User Self-Created Access Key Subsequently Used

#
Status
production
Severity
medium
Time window
35m
Group by
Esql_priv.aws_cloudtrail_access_key_id_correlation, aws.cloudtrail.user_identity.arn, cloud.account.id
Author
Elastic
Source
github.com/elastic/detection-rules

Detects an AWS IAM user using an existing credential to create a new access key for itself and subsequently using the new key within one hour. This behavior can indicate an adversary converting compromised credentials into an additional long-term credential for persistence. Unlike a standalone self-service key creation alert, requiring subsequent use of the new key reduces noise from unused or abandoned credential-rotation operations.

Known False Positives

  • Approved credential-rotation automation may create and immediately validate or use a replacement access key. Confirm the principal, source addresses, user agents, timing, and change records. Exclude only verified rotation workflows.

MITRE ATT&CK Coverage

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2026/07/13"
integration = ["aws"]
maturity = "production"
updated_date = "2026/07/13"

[rule]
author = ["Elastic"]
description = """
Detects an AWS IAM user using an existing credential to create a new access key for itself and subsequently using the
new key within one hour. This behavior can indicate an adversary converting compromised credentials into an additional
long-term credential for persistence. Unlike a standalone self-service key creation alert, requiring subsequent use of
the new key reduces noise from unused or abandoned credential-rotation operations.
"""
false_positives = [
    """
    Approved credential-rotation automation may create and immediately validate or use a replacement access key. Confirm
    the principal, source addresses, user agents, timing, and change records. Exclude only verified rotation workflows.
    """,
]
from = "now-35m"
language = "esql"
license = "Elastic License v2"
name = "AWS IAM User Self-Created Access Key Subsequently Used"
note = """## Triage and analysis

### Investigating AWS IAM User Self-Created Access Key Subsequently Used

This rule detects an IAM user using an existing access key (Token A) to create a new access key for itself (Token B), followed by an AWS API request authenticated with Token B within one hour. The creation event proves that Token A was used to request the additional credential, while the subsequent CloudTrail event confirms that Token B became active.

This sequence can indicate persistence after an IAM user's credentials are compromised. An adversary can use the compromised key to create another long-term credential, then continue accessing the account through the new key even after the original credential is identified and disabled.

### Possible investigation steps

- Identify the IAM user and AWS account using `aws.cloudtrail.user_identity.arn` and `cloud.account.id`.
- Review Token A in `Esql_priv.aws_cloudtrail_user_identity_access_key_id_creator_values`. Determine whether it is an expected credential for the IAM user and whether it was previously observed from unusual infrastructure.
- Confirm that the key in `Esql_priv.aws_cloudtrail_response_elements_access_key_access_key_id_values` matches the subsequently used key in `Esql_priv.aws_cloudtrail_user_identity_access_key_id_created_key_use_values`.
- Compare `Esql.source_ip_self_access_key_creation_values` with `Esql.source_ip_created_access_key_use_values`. A rapid change in source IP, ASN, geography, or hosting provider increases suspicion.
- Compare `Esql.user_agent_original_self_access_key_creation_values` with `Esql.user_agent_original_created_access_key_use_values` to identify changes between the creation and use clients.
- Review `Esql.event_action_created_access_key_use_values` to determine what Token B accessed or modified after creation.
- Examine nearby CloudTrail activity for IAM reconnaissance, MFA changes, login-profile changes, policy modifications, or attempts to create additional credentials.
- Confirm whether the activity corresponds to an approved credential-rotation workflow and whether the user is permitted to create its own long-term access keys.

### False positive analysis

- Approved credential-rotation automation may create and immediately test or use a replacement access key.
- Developer onboarding or recovery workflows may create a key and validate it with an initial AWS API request.
- Validate the principal, source addresses, user agents, timing, and change records before excluding the activity. Prefer narrowly scoped exceptions for verified automation rather than excluding the IAM user broadly.

### Response and remediation

- If unauthorized, deactivate or delete Token B immediately.
- Rotate or disable Token A and investigate how it was exposed or compromised.
- Review every CloudTrail event authenticated with Token B and determine whether it accessed data, changed IAM permissions, created resources, or established additional persistence.
- Review the IAM user's policies and remove unnecessary `iam:CreateAccessKey` permissions.
- Prefer temporary credentials and IAM Identity Center for human access instead of long-term IAM user access keys.
- Preserve the relevant CloudTrail events, access key IDs, source addresses, and user-agent values for incident response.
"""
references = [
    "https://hackingthe.cloud/aws/exploitation/iam_privilege_escalation/#iamcreateaccesskey",
    "https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateAccessKey.html",
    "https://github.com/RhinoSecurityLabs/pacu/tree/master/pacu/modules/iam__backdoor_users_keys",
]
risk_score = 47
rule_id = "dfb7dc0b-2caf-4186-9b59-5752bc59bc19"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Data Source: AWS",
    "Data Source: Amazon Web Services",
    "Data Source: AWS IAM",
    "Use Case: Identity and Access Audit",
    "Tactic: Persistence",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"

query = '''
FROM logs-aws.cloudtrail-*
| WHERE data_stream.dataset == "aws.cloudtrail"
    AND (
      (
        event.provider == "iam.amazonaws.com"
        AND event.action == "CreateAccessKey"
        AND event.outcome == "success"
        AND aws.cloudtrail.user_identity.type == "IAMUser"
      )
      OR (
        aws.cloudtrail.user_identity.type == "IAMUser"
        AND aws.cloudtrail.user_identity.access_key_id LIKE "AKIA*"
        AND NOT (
          event.provider == "iam.amazonaws.com"
          AND event.action == "CreateAccessKey"
        )
      )
    )
| GROK aws.cloudtrail.response_elements """.*accessKeyId=(?<Esql_priv.aws_cloudtrail_response_elements_access_key_access_key_id>AKIA[A-Z0-9]{16}).*"""
| EVAL
    Esql.aws_cloudtrail_self_access_key_creation_flag = CASE(
      event.provider == "iam.amazonaws.com"
        AND event.action == "CreateAccessKey"
        AND event.outcome == "success"
        AND aws.cloudtrail.user_identity.type == "IAMUser"
        AND (
          user.target.name IS NULL
          OR user.name == user.target.name
        )
        AND Esql_priv.aws_cloudtrail_response_elements_access_key_access_key_id IS NOT NULL,
      1,
      0
    ),
    Esql.aws_cloudtrail_created_access_key_use_flag = CASE(
      aws.cloudtrail.user_identity.type == "IAMUser"
        AND aws.cloudtrail.user_identity.access_key_id LIKE "AKIA*"
        AND NOT (
          event.provider == "iam.amazonaws.com"
          AND event.action == "CreateAccessKey"
        ),
      1,
      0
    )
| EVAL
    Esql_priv.aws_cloudtrail_user_identity_access_key_id_creator = CASE(
      Esql.aws_cloudtrail_self_access_key_creation_flag == 1,
      aws.cloudtrail.user_identity.access_key_id,
      null
    ),
    Esql_priv.aws_cloudtrail_access_key_id_correlation = CASE(
      Esql.aws_cloudtrail_self_access_key_creation_flag == 1,
      Esql_priv.aws_cloudtrail_response_elements_access_key_access_key_id,
      aws.cloudtrail.user_identity.access_key_id
    )
| WHERE Esql_priv.aws_cloudtrail_access_key_id_correlation IS NOT NULL
    AND aws.cloudtrail.user_identity.arn IS NOT NULL
| STATS
    Esql.aws_cloudtrail_self_access_key_creation_count =
      COUNT(*) WHERE Esql.aws_cloudtrail_self_access_key_creation_flag == 1,
    Esql.aws_cloudtrail_created_access_key_use_count =
      COUNT(*) WHERE Esql.aws_cloudtrail_created_access_key_use_flag == 1,
    Esql_priv.aws_cloudtrail_user_identity_access_key_id_creator_values =
      VALUES(Esql_priv.aws_cloudtrail_user_identity_access_key_id_creator)
      WHERE Esql.aws_cloudtrail_self_access_key_creation_flag == 1,
    Esql_priv.aws_cloudtrail_response_elements_access_key_access_key_id_values =
      VALUES(Esql_priv.aws_cloudtrail_response_elements_access_key_access_key_id)
      WHERE Esql.aws_cloudtrail_self_access_key_creation_flag == 1,
    Esql_priv.aws_cloudtrail_user_identity_access_key_id_created_key_use_values =
      VALUES(aws.cloudtrail.user_identity.access_key_id)
      WHERE Esql.aws_cloudtrail_created_access_key_use_flag == 1,
    Esql.timestamp_self_access_key_creation_min =
      MIN(@timestamp)
      WHERE Esql.aws_cloudtrail_self_access_key_creation_flag == 1,
    Esql.timestamp_created_access_key_use_min =
      MIN(@timestamp)
      WHERE Esql.aws_cloudtrail_created_access_key_use_flag == 1,
    Esql.source_ip_self_access_key_creation_values =
      VALUES(source.ip)
      WHERE Esql.aws_cloudtrail_self_access_key_creation_flag == 1,
    Esql.source_ip_created_access_key_use_values =
      VALUES(source.ip)
      WHERE Esql.aws_cloudtrail_created_access_key_use_flag == 1,
    Esql.user_agent_original_self_access_key_creation_values =
      VALUES(user_agent.original)
      WHERE Esql.aws_cloudtrail_self_access_key_creation_flag == 1,
    Esql.user_agent_original_created_access_key_use_values =
      VALUES(user_agent.original)
      WHERE Esql.aws_cloudtrail_created_access_key_use_flag == 1,
    Esql.event_action_created_access_key_use_values =
      VALUES(event.action)
      WHERE Esql.aws_cloudtrail_created_access_key_use_flag == 1
  BY cloud.account.id,
     aws.cloudtrail.user_identity.arn,
     Esql_priv.aws_cloudtrail_access_key_id_correlation
| WHERE Esql.aws_cloudtrail_self_access_key_creation_count > 0
    AND Esql.aws_cloudtrail_created_access_key_use_count > 0
    AND Esql.timestamp_created_access_key_use_min >
        Esql.timestamp_self_access_key_creation_min
    AND DATE_DIFF(
      "seconds",
      Esql.timestamp_self_access_key_creation_min,
      Esql.timestamp_created_access_key_use_min
    ) <= 3600
| KEEP
    cloud.account.id,
    aws.cloudtrail.user_identity.arn,
    Esql.*,
    Esql_priv.*
'''


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



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

[rule.alert_suppression]
group_by = ["aws.cloudtrail.user_identity.arn","cloud.account.id"]
missing_fields_strategy = "suppress"
[rule.alert_suppression.duration]
unit = "m"
value = 35

[rule.investigation_fields]
field_names = [
    "cloud.account.id",
    "aws.cloudtrail.user_identity.arn",
    "Esql_priv.aws_cloudtrail_user_identity_access_key_id_creator_values",
    "Esql_priv.aws_cloudtrail_response_elements_access_key_access_key_id_values",
    "Esql_priv.aws_cloudtrail_user_identity_access_key_id_created_key_use_values",
    "Esql.timestamp_self_access_key_creation_min",
    "Esql.timestamp_created_access_key_use_min",
    "Esql.source_ip_self_access_key_creation_values",
    "Esql.source_ip_created_access_key_use_values",
    "Esql.user_agent_original_self_access_key_creation_values",
    "Esql.user_agent_original_created_access_key_use_values",
    "Esql.event_action_created_access_key_use_values",
]

Stages and Predicates

Stage 1: from

FROM logs-aws.cloudtrail-*

Stage 2: where

| WHERE data_stream.dataset == "aws.cloudtrail"
    AND (
      (
        event.provider == "iam.amazonaws.com"
        AND event.action == "CreateAccessKey"
        AND event.outcome == "success"
        AND aws.cloudtrail.user_identity.type == "IAMUser"
      )
      OR (
        aws.cloudtrail.user_identity.type == "IAMUser"
        AND aws.cloudtrail.user_identity.access_key_id LIKE "AKIA*"
        AND NOT (
          event.provider == "iam.amazonaws.com"
          AND event.action == "CreateAccessKey"
        )
      )
    )

Stage 3: grok

| GROK aws.cloudtrail.response_elements """.*accessKeyId=(?<Esql_priv.aws_cloudtrail_response_elements_access_key_access_key_id>AKIA[A-Z0-9]{16}).*"""

Stage 4: eval

| EVAL
    Esql.aws_cloudtrail_self_access_key_creation_flag = CASE(
      event.provider == "iam.amazonaws.com"
        AND event.action == "CreateAccessKey"
        AND event.outcome == "success"
        AND aws.cloudtrail.user_identity.type == "IAMUser"
        AND (
          user.target.name IS NULL
          OR user.name == user.target.name
        )
        AND Esql_priv.aws_cloudtrail_response_elements_access_key_access_key_id IS NOT NULL,
      1,
      0
    ),
    Esql.aws_cloudtrail_created_access_key_use_flag = CASE(
      aws.cloudtrail.user_identity.type == "IAMUser"
        AND aws.cloudtrail.user_identity.access_key_id LIKE "AKIA*"
        AND NOT (
          event.provider == "iam.amazonaws.com"
          AND event.action == "CreateAccessKey"
        ),
      1,
      0
    )
Esql.aws_cloudtrail_created_access_key_use_flag =
ifaws.cloudtrail.user_identity.type == "IAMUser" AND aws.cloudtrail.user_identity.access_key_id LIKE "AKIA*" AND NOT ( event.provider == "iam.amazonaws.com" AND event.action == "CreateAccessKey" )1
else0
Esql.aws_cloudtrail_self_access_key_creation_flag =
ifevent.provider == "iam.amazonaws.com" AND event.action == "CreateAccessKey" AND event.outcome == "success" AND aws.cloudtrail.user_identity.type == "IAMUser" AND ( user.target.name IS NULL OR user.name == user.target.name ) AND Esql_priv.aws_cloudtrail_response_elements_access_key_access_key_id IS NOT NULL1
else0

Stage 5: eval

| EVAL
    Esql_priv.aws_cloudtrail_user_identity_access_key_id_creator = CASE(
      Esql.aws_cloudtrail_self_access_key_creation_flag == 1,
      aws.cloudtrail.user_identity.access_key_id,
      null
    ),
    Esql_priv.aws_cloudtrail_access_key_id_correlation = CASE(
      Esql.aws_cloudtrail_self_access_key_creation_flag == 1,
      Esql_priv.aws_cloudtrail_response_elements_access_key_access_key_id,
      aws.cloudtrail.user_identity.access_key_id
    )
Esql_priv.aws_cloudtrail_access_key_id_correlation =
ifEsql.aws_cloudtrail_self_access_key_creation_flag == 1Esql_priv.aws_cloudtrail_response_elements_access_key_access_key_id
elseaws.cloudtrail.user_identity.access_key_id
Esql_priv.aws_cloudtrail_user_identity_access_key_id_creator =
ifEsql.aws_cloudtrail_self_access_key_creation_flag == 1aws.cloudtrail.user_identity.access_key_id
elsenull

Stage 6: where

| WHERE Esql_priv.aws_cloudtrail_access_key_id_correlation IS NOT NULL
    AND aws.cloudtrail.user_identity.arn IS NOT NULL

Stage 7: stats

| STATS
    Esql.aws_cloudtrail_self_access_key_creation_count =
      COUNT(*) WHERE Esql.aws_cloudtrail_self_access_key_creation_flag == 1,
    Esql.aws_cloudtrail_created_access_key_use_count =
      COUNT(*) WHERE Esql.aws_cloudtrail_created_access_key_use_flag == 1,
    Esql_priv.aws_cloudtrail_user_identity_access_key_id_creator_values =
      VALUES(Esql_priv.aws_cloudtrail_user_identity_access_key_id_creator)
      WHERE Esql.aws_cloudtrail_self_access_key_creation_flag == 1,
    Esql_priv.aws_cloudtrail_response_elements_access_key_access_key_id_values =
      VALUES(Esql_priv.aws_cloudtrail_response_elements_access_key_access_key_id)
      WHERE Esql.aws_cloudtrail_self_access_key_creation_flag == 1,
    Esql_priv.aws_cloudtrail_user_identity_access_key_id_created_key_use_values =
      VALUES(aws.cloudtrail.user_identity.access_key_id)
      WHERE Esql.aws_cloudtrail_created_access_key_use_flag == 1,
    Esql.timestamp_self_access_key_creation_min =
      MIN(@timestamp)
      WHERE Esql.aws_cloudtrail_self_access_key_creation_flag == 1,
    Esql.timestamp_created_access_key_use_min =
      MIN(@timestamp)
      WHERE Esql.aws_cloudtrail_created_access_key_use_flag == 1,
    Esql.source_ip_self_access_key_creation_values =
      VALUES(source.ip)
      WHERE Esql.aws_cloudtrail_self_access_key_creation_flag == 1,
    Esql.source_ip_created_access_key_use_values =
      VALUES(source.ip)
      WHERE Esql.aws_cloudtrail_created_access_key_use_flag == 1,
    Esql.user_agent_original_self_access_key_creation_values =
      VALUES(user_agent.original)
      WHERE Esql.aws_cloudtrail_self_access_key_creation_flag == 1,
    Esql.user_agent_original_created_access_key_use_values =
      VALUES(user_agent.original)
      WHERE Esql.aws_cloudtrail_created_access_key_use_flag == 1,
    Esql.event_action_created_access_key_use_values =
      VALUES(event.action)
      WHERE Esql.aws_cloudtrail_created_access_key_use_flag == 1
  BY cloud.account.id,
     aws.cloudtrail.user_identity.arn,
     Esql_priv.aws_cloudtrail_access_key_id_correlation

Stage 8: where

| WHERE Esql.aws_cloudtrail_self_access_key_creation_count > 0
    AND Esql.aws_cloudtrail_created_access_key_use_count > 0
    AND Esql.timestamp_created_access_key_use_min >
        Esql.timestamp_self_access_key_creation_min
    AND DATE_DIFF(
      "seconds",
      Esql.timestamp_self_access_key_creation_min,
      Esql.timestamp_created_access_key_use_min
    ) <= 3600

Stage 9: keep

| KEEP
    cloud.account.id,
    aws.cloudtrail.user_identity.arn,
    Esql.*,
    Esql_priv.*

Indicators

These rows show field, operator, and value matches.

Output Fields

These fields are emitted when the rule matches.

FieldSource
cloud.account.idKEEP cloud.account.id
aws.cloudtrail.user_identity.arnKEEP aws.cloudtrail.user_identity.arn
Esql.*KEEP Esql.*
Esql_priv.*KEEP Esql_priv.*

Azure Storage Account Blob Public Access Enabled

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

Identifies when Azure Storage Account Blob public access is enabled, allowing external access to blob containers. This technique was observed in cloud ransom-based campaigns where threat actors modified storage accounts to expose non-remotely accessible accounts to the internet for data exfiltration. Adversaries abuse the Microsoft.Storage/storageAccounts/write operation to modify public access settings.

Known False Positives

  • Storage administrators may legitimately enable public access for specific business requirements such as hosting public content or CDN integration. Verify that the configuration change was expected and follows organizational policies. Consider exceptions for approved storage accounts.

MITRE ATT&CK Coverage

TacticTechniques
Collection

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2025/09/22"
integration = ["azure"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Identifies when Azure Storage Account Blob public access is enabled, allowing external access to blob containers. This
technique was observed in cloud ransom-based campaigns where threat actors modified storage accounts to expose
non-remotely accessible accounts to the internet for data exfiltration. Adversaries abuse the
Microsoft.Storage/storageAccounts/write operation to modify public access settings.
"""
false_positives = [
    """
    Storage administrators may legitimately enable public access for specific business requirements such as hosting
    public content or CDN integration. Verify that the configuration change was expected and follows organizational
    policies. Consider exceptions for approved storage accounts.
    """,
]
from = "now-9m"
index = ["logs-azure.activitylogs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Azure Storage Account Blob Public Access Enabled"
note = """## Triage and analysis

### Investigating Azure Storage Account Blob Public Access Enabled

Azure Storage Accounts provide cloud storage solutions with various access control mechanisms. The public access setting, when enabled, allows anonymous internet access to blob containers, bypassing authentication requirements. Adversaries exploit this feature to expose sensitive data for exfiltration or to establish persistent external access. This detection monitors for successful modifications that enable public blob access, a technique notably used in STORM-0501 cloud ransom-based campaigns.

### Possible investigation steps

- Review the Azure activity logs to identify the user or service principal that initiated the storage account modification by examining the principal ID, UPN and user agent fields.
- Check the specific storage account name in `azure.resource.name` to understand which storage resources were affected and assess the sensitivity of data stored there.
- Investigate the timing of the event to correlate with any other suspicious activities, such as unusual login patterns or privilege escalation attempts.
- Examine the request or response body details to understand the full scope of changes made to the storage account configuration beyond public access settings.
- Review access logs for the affected storage account to identify any subsequent data access or exfiltration attempts following the public access enablement.
- Verify if the storage account modification aligns with approved change requests or maintenance windows in your organization.
- Check for other storage accounts modified by the same principal to identify potential lateral movement or widespread configuration changes.
- Pivot into related activity for the storage account and/or container such as data deletion, encryption or further permission changes.

### False positive analysis

- Legitimate CDN integration or public website hosting may require enabling public blob access. Document approved storage accounts used for public content delivery and create exceptions for these specific resources.
- DevOps automation tools might temporarily enable public access during deployment processes. Identify service principals used by CI/CD pipelines and consider time-based exceptions during deployment windows.
- Testing and development environments may have different access requirements. Consider filtering out non-production storage accounts if public access is acceptable in those environments.
- Migration activities might require temporary public access. Coordinate with infrastructure teams to understand planned migrations and create temporary exceptions with defined expiration dates.

### Response and remediation

- Immediately disable public blob access on the affected storage account using Azure Portal IaC, or Azure CLI command.
- Audit all blob containers within the affected storage account to identify which data may have been exposed and assess the potential impact of the exposure.
- Review Azure Activity Logs and storage access logs to determine if any data was accessed or exfiltrated while public access was enabled.
- Rotate any credentials, keys, or sensitive data that may have been stored in the exposed blob containers.
- If unauthorized modification is confirmed, disable the compromised user account or service principal and investigate how the credentials were obtained.
- Implement Azure Policy to prevent enabling public blob access on storage accounts containing sensitive data, using built-in policy definitions for storage account public access restrictions.
- Consider implementing private endpoints for storage accounts that should never be publicly accessible, ensuring network-level isolation.
"""
references = [
    "https://www.microsoft.com/en-us/security/blog/2025/08/27/storm-0501s-evolving-techniques-lead-to-cloud-based-ransomware/",
    "https://docs.microsoft.com/en-us/azure/storage/blobs/anonymous-read-access-configure",
]
risk_score = 47
rule_id = "4c5a4e8b-3f2d-4a6e-9b5c-7d8f9e0a1b2c"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Domain: Storage",
    "Data Source: Azure",
    "Data Source: Azure Activity Logs",
    "Use Case: Threat Detection",
    "Tactic: Collection",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"

query = '''
data_stream.dataset: "azure.activitylogs" and
event.action: "MICROSOFT.STORAGE/STORAGEACCOUNTS/WRITE" and
event.outcome: "success" and
azure.activitylogs.properties.responseBody: *\"allowBlobPublicAccess\"\:true*
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1530"
name = "Data from Cloud Storage"
reference = "https://attack.mitre.org/techniques/T1530/"


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

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

Stages and Predicates

Stage 1: new_terms

data_stream.dataset: "azure.activitylogs" and
event.action: "MICROSOFT.STORAGE/STORAGEACCOUNTS/WRITE" and
event.outcome: "success" and
azure.activitylogs.properties.responseBody: *\"allowBlobPublicAccess\"\:true*

Indicators

These rows show field, operator, and value matches.

Creation of Hidden Login Item via Apple Script

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

Identifies the execution of osascript to create a hidden login item. This may indicate an attempt to persist a malicious program while concealing its presence.

MITRE ATT&CK Coverage

Rule Body

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

[rule]
author = ["Elastic"]
description = """
Identifies the execution of osascript to create a hidden login item. This may indicate an attempt to persist a malicious
program while concealing its presence.
"""
from = "now-9m"
index = ["logs-endpoint.events.process*"]
language = "eql"
license = "Elastic License v2"
name = "Creation of Hidden Login Item via Apple Script"
risk_score = 47
rule_id = "f24bcae1-8980-4b30-b5dd-f851b055c9e7"
setup = """## Setup

This rule requires data coming in from Elastic Defend.

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

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

#### The following steps should be executed in order to add the Elastic Defend integration on a macOS System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, for MacOS it is recommended to select "Traditional Endpoints".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/current/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: macOS",
    "Use Case: Threat Detection",
    "Tactic: Persistence",
    "Tactic: Execution",
    "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 == "osascript" and
 process.command_line : "osascript*login item*hidden:true*"
'''
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 Creation of Hidden Login Item via Apple Script

AppleScript is a scripting language for automating tasks on macOS, including managing login items. Adversaries exploit this by creating hidden login items to maintain persistence without detection. The detection rule identifies suspicious use of `osascript` to create such items, focusing on command patterns that specify hidden attributes, thus flagging potential stealthy persistence attempts.

### Possible investigation steps

- Review the process details to confirm the presence of 'osascript' in the command line, specifically looking for patterns like "login item" and "hidden:true" to verify the alert's accuracy.
- Investigate the parent process of the 'osascript' execution to determine if it was initiated by a legitimate application or a potentially malicious source.
- Check the user account associated with the process to assess whether the activity aligns with typical user behavior or if it suggests unauthorized access.
- Examine recent login items and system logs to identify any new or unusual entries that could indicate persistence mechanisms being established.
- Correlate the event with other security alerts or logs from the same host to identify any related suspicious activities or patterns.
- If possible, retrieve and analyze the AppleScript code executed to understand its purpose and potential impact on the system.

### False positive analysis

- Legitimate applications or scripts that automate login item management may trigger this rule. Review the process command line details to verify if the application is trusted.
- System administrators or IT management tools might use AppleScript for legitimate configuration tasks. Confirm if the activity aligns with scheduled maintenance or deployment activities.
- Users with advanced scripting knowledge might create custom scripts for personal use. Check if the script is part of a known user workflow and consider excluding it if verified as non-threatening.
- Frequent triggers from the same source could indicate a benign automation process. Implement exceptions for specific scripts or processes after thorough validation to prevent unnecessary alerts.

### Response and remediation

- Immediately isolate the affected macOS system from the network to prevent potential lateral movement or data exfiltration.
- Terminate the suspicious osascript process identified in the alert to halt any ongoing malicious activity.
- Remove the hidden login item created by the osascript to eliminate the persistence mechanism. This can be done by accessing the user's login items and deleting any unauthorized entries.
- Conduct a thorough scan of the system using updated antivirus or endpoint detection and response (EDR) tools to identify and remove any additional malicious files or processes.
- Review system logs and the user's recent activity to identify any other signs of compromise or related suspicious behavior.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if additional systems are affected.
- Implement enhanced monitoring for osascript usage and login item modifications across the network to detect similar threats in the future."""


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

[[rule.threat.technique]]
id = "T1547"
name = "Boot or Logon Autostart Execution"
reference = "https://attack.mitre.org/techniques/T1547/"

[[rule.threat.technique.subtechnique]]
id = "T1547.015"
name = "Login Items"
reference = "https://attack.mitre.org/techniques/T1547/015/"

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

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

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

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

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

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

[[rule.threat.technique]]
id = "T1647"
name = "Plist File Modification"
reference = "https://attack.mitre.org/techniques/T1647/"

[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 == "macos" and event.type in ("start", "process_started") and process.name == "osascript" and
 process.command_line : "osascript*login item*hidden:true*"

Indicators

These rows show field, operator, and value matches.

CyberArk Privileged Access Security Error

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

Identifies the occurrence of a CyberArk Privileged Access Security (PAS) error level audit event. The event.code correlates to the CyberArk Vault Audit Action Code.

Known False Positives

  • To tune this rule, add exceptions to exclude any event.code which should not trigger this rule.

MITRE ATT&CK Coverage

TacticTechniques
Initial Access
Privilege Escalation

Rule Body

[metadata]
creation_date = "2021/06/23"
integration = ["cyberarkpas"]
maturity = "production"
promotion = true
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Identifies the occurrence of a CyberArk Privileged Access Security (PAS) error level audit event. The event.code
correlates to the CyberArk Vault Audit Action Code.
"""
false_positives = ["To tune this rule, add exceptions to exclude any event.code which should not trigger this rule."]
from = "now-30m"
index = ["filebeat-*", "logs-cyberarkpas.audit*"]
language = "kuery"
license = "Elastic License v2"
name = "CyberArk Privileged Access Security Error"
note = """## Setup

The CyberArk Privileged Access Security (PAS) Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.

## Triage and analysis

This is a promotion rule for CyberArk error events, which are alertable events per the vendor.
Consult vendor documentation on interpreting specific events.
"""
references = [
    "https://docs.cyberark.com/Product-Doc/OnlineHelp/PAS/Latest/en/Content/PASREF/Vault%20Audit%20Action%20Codes.htm?tocpath=Administration%7CReferences%7C_____3",
]
risk_score = 73
rule_id = "3f0e5410-a4bf-4e8c-bcfc-79d67a285c54"
rule_name_override = "event.action"
severity = "high"
tags = [
    "Data Source: CyberArk PAS",
    "Use Case: Log Auditing",
    "Use Case: Threat Detection",
    "Tactic: Privilege Escalation",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset:cyberarkpas.audit and event.type:error
'''


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


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

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

Stages and Predicates

Stage 1: query

data_stream.dataset:cyberarkpas.audit and event.type:error

Indicators

These rows show field, operator, and value matches.

Egress Network Connection from Default DPKG Directory

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

This rule monitors for network connections from processes that are executed from the /var/lib/dpkg/info/ directory. This directory is used to store information about installed packages. Attackers can backdoor the installation scripts of packages to establish network connections during the installation process to maintain persistence or to establish command and control.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
This rule monitors for network connections from processes that are executed from the /var/lib/dpkg/info/ directory. This
directory is used to store information about installed packages. Attackers can backdoor the installation scripts of
packages to establish network connections during the installation process to maintain persistence or to establish
command and control.
"""
id = "947b70bb-8e01-4f1b-994d-5af9488556bb"
license = "Elastic License v2"
name = "Egress Network Connection from Default DPKG Directory"
os_list = ["linux"]
reference = ["https://www.makeuseof.com/how-deb-packages-are-backdoored-how-to-detect-it/"]
version = "1.0.10"

query = '''
sequence with maxspan=3s
  [process where event.type == "start" and event.action == "exec" and
   process.parent.executable like "/var/lib/dpkg/info/*" and not (
     process.executable like ("/usr/sbin/runuser", "/opt/vivaldi/*", "/usr/bin/syslog-ng-update-virtualenv") or
     process.parent.executable == "/var/lib/dpkg/info/falco.postinst" or
     process.parent.executable like (
       "/var/lib/dpkg/info/percona-server-server-*.postinst", "/var/lib/dpkg/info/vivaldi*",
       "/var/lib/dpkg/info/percona-xtradb-cluster-server*", "/var/lib/dpkg/info/univention-updater*",
       "/var/lib/dpkg/info/microsoft-edge-beta.postinst"
     ) or
     process.parent.name in ("mdatp.postinst", "mdatp.postrm") or
     process.args like ("/var/lib/dpkg/info/percona-xtradb-cluster-server-*.postinst", "/etc/cron.daily/*")
   )
  ] by process.entity_id
  [network where event.type == "start" and event.action == "connection_attempted" 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", "172.31.0.0/16"
     ) or
     process.executable in (
       "/usr/bin/apt-get", "/bin/apt-get", "/opt/cisco/amp/etc/ampinsthelper", "/opt/teleport/system/bin/tsh",
       "/usr/lib/apt/methods/https"
     )
   )] by process.parent.entity_id
'''

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1195"
name = "Supply Chain Compromise"
reference = "https://attack.mitre.org/techniques/T1195/"
[[threat.technique.subtechnique]]
id = "T1195.002"
name = "Compromise Software Supply Chain"
reference = "https://attack.mitre.org/techniques/T1195/002/"



[threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"

[[threat.technique]]
id = "T1546"
name = "Event Triggered Execution"
reference = "https://attack.mitre.org/techniques/T1546/"
[[threat.technique.subtechnique]]
id = "T1546.016"
name = "Installer Packages"
reference = "https://attack.mitre.org/techniques/T1546/016/"


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


[threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[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.entity_id, process.parent.entity_id.

Stage 1: process

[process where event.type == "start" and event.action == "exec" and
   process.parent.executable like "/var/lib/dpkg/info/*" and not (
     process.executable like ("/usr/sbin/runuser", "/opt/vivaldi/*", "/usr/bin/syslog-ng-update-virtualenv") or
     process.parent.executable == "/var/lib/dpkg/info/falco.postinst" or
     process.parent.executable like (
       "/var/lib/dpkg/info/percona-server-server-*.postinst", "/var/lib/dpkg/info/vivaldi*",
       "/var/lib/dpkg/info/percona-xtradb-cluster-server*", "/var/lib/dpkg/info/univention-updater*",
       "/var/lib/dpkg/info/microsoft-edge-beta.postinst"
     ) or
     process.parent.name in ("mdatp.postinst", "mdatp.postrm") or
     process.args like ("/var/lib/dpkg/info/percona-xtradb-cluster-server-*.postinst", "/etc/cron.daily/*")
   )
  ] by process.entity_id

Stage 2: network

[network where event.type == "start" and event.action == "connection_attempted" 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", "172.31.0.0/16"
     ) or
     process.executable in (
       "/usr/bin/apt-get", "/bin/apt-get", "/opt/cisco/amp/etc/ampinsthelper", "/opt/teleport/system/bin/tsh",
       "/usr/lib/apt/methods/https"
     )
   )] by process.parent.entity_id

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argswildcard/var/lib/dpkg/info/percona-xtradb-cluster-server-*.postinst, /etc/cron.daily/*excludes:process.args field:"process.args" value:"/var/lib/dpkg/info/percona-xtradb-cluster-server-*.postinst" field:"process.args" value:"/etc/cron.daily/*"
process.executablewildcard/usr/sbin/runuser, /opt/vivaldi/*, /usr/bin/syslog-ng-update-virtualenvexcludes:process.executable field:"process.executable" value:"/usr/sbin/runuser" field:"process.executable" value:"/opt/vivaldi/*" field:"process.executable" value:"/usr/bin/syslog-ng-update-virtualenv"
process.parent.executableeq/var/lib/dpkg/info/falco.postinstexcludes:process.parent.executable field:"process.parent.executable" value:"/var/lib/dpkg/info/falco.postinst"
process.parent.executablewildcard/var/lib/dpkg/info/percona-server-server-*.postinst, /var/lib/dpkg/info/vivaldi*, /var/lib/dpkg/info/percona-xtradb-cluster-server*, /var/lib/dpkg/info/univention-updater*, /var/lib/dpkg/info/microsoft-edge-beta.postinstexcludes:process.parent.executable
process.parent.nameinmdatp.postinst, mdatp.postrmexcludes:process.parent.name field:"process.parent.name" value:"mdatp.postinst" field:"process.parent.name" value:"mdatp.postrm"
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::/8, 172.31.0.0/16excludes: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.executablein/bin/apt-get, /opt/cisco/amp/etc/ampinsthelper, /opt/teleport/system/bin/tsh, /usr/bin/apt-get, /usr/lib/apt/methods/httpsexcludes:process.executable

Executable File Extracted to Temporary Directory

#
Source
github.com/elastic/protections-artifacts

Detects a compressed executable file is extracted to a tmp directory. Threat actors will sometimes drop a compressed file and extract its contents (usually containing a payload) to a tmp directory in order to avoid being seen on the system.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Detects a compressed executable file is extracted to a tmp directory. Threat actors will sometimes drop a compressed
file and extract its contents (usually containing a payload) to a tmp directory in order to avoid being seen on the
system.
"""
id = "24fa0f80-7e3a-4b27-801a-30ef53f190bf"
license = "Elastic License v2"
name = "Executable File Extracted to Temporary Directory"
os_list = ["macos"]
reference = [
    "https://www.jamf.com/blog/cryptojacking-macos-malware-discovered-by-jamf-threat-labs/?utm_source=twitter&utm_medium=social&utm_campaign=blog-promo&utm_content=2023-02-23_shared_",
]
version = "1.0.37"

query = '''
file where event.action != "deletion" and 
 process.name in ("bsdtar", "tar", "unzip", "Archive Utility", "ArchiveService") and
 file.path like ("/tmp/*", "/private/var/tmp/*", "/var/tmp/*") and
 file.Ext.header_bytes like~ ("cffaedfe*", "cafebabe*") and
 not file.path like~ "/private/var/tmp/*bazel*" and
 not Effective_process.executable in ("/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon",
                                      "/Applications/NinjaRMMAgent/programfiles/ninjarmm-macagent",
                                      "/Library/Application Support/TrendMicro/RPD/RecoveryPackDownloader.app/Contents/MacOS/RecoveryPackDownloader",
                                      "/Applications/Utilities/NacAgent.app/Contents/MacOS/NacAgent",
                                      "/Applications/Warp.app/Contents/MacOS/stable",
                                      "/usr/libexec/xpcproxy",
                                      "/Library/Developer/PrivateFrameworks/CoreSimulator.framework/Versions/A/XPCServices/SimulatorTrampoline.xpc/Contents/MacOS/SimulatorTrampoline",
                                      "/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfManagementService.app/Contents/MacOS/JamfManagementService",
                                      "/Library/Kandji/Kandji Agent.app/Contents/Helpers/Kandji Library Manager.app/Contents/MacOS/kandji-library-manager",
                                      "/opt/jc/bin/jumpcloud-agent",
                                      "/Library/Iru/Iru Agent.app/Contents/Helpers/Iru Library Manager.app/Contents/MacOS/kandji-library-manager")
'''

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

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

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



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

[internal]
min_endpoint_version = "8.10.2"

Stages and Predicates

Stage 1: file

file where event.action != "deletion" and 
 process.name in ("bsdtar", "tar", "unzip", "Archive Utility", "ArchiveService") and
 file.path like ("/tmp/*", "/private/var/tmp/*", "/var/tmp/*") and
 file.Ext.header_bytes like~ ("cffaedfe*", "cafebabe*") and
 not file.path like~ "/private/var/tmp/*bazel*" and
 not Effective_process.executable in ("/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon",
                                      "/Applications/NinjaRMMAgent/programfiles/ninjarmm-macagent",
                                      "/Library/Application Support/TrendMicro/RPD/RecoveryPackDownloader.app/Contents/MacOS/RecoveryPackDownloader",
                                      "/Applications/Utilities/NacAgent.app/Contents/MacOS/NacAgent",
                                      "/Applications/Warp.app/Contents/MacOS/stable",
                                      "/usr/libexec/xpcproxy",
                                      "/Library/Developer/PrivateFrameworks/CoreSimulator.framework/Versions/A/XPCServices/SimulatorTrampoline.xpc/Contents/MacOS/SimulatorTrampoline",
                                      "/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfManagementService.app/Contents/MacOS/JamfManagementService",
                                      "/Library/Kandji/Kandji Agent.app/Contents/Helpers/Kandji Library Manager.app/Contents/MacOS/kandji-library-manager",
                                      "/opt/jc/bin/jumpcloud-agent",
                                      "/Library/Iru/Iru Agent.app/Contents/Helpers/Iru Library Manager.app/Contents/MacOS/kandji-library-manager")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actionne
  • deletion
field:"EventType" kind:ne value:"deletion"
file.Ext.header_byteswildcard
  • cafebabe*
  • cffaedfe*
field:"file.Ext.header_bytes" kind:wildcard
file.pathwildcard
  • /private/var/tmp/*
  • /tmp/*
  • /var/tmp/*
field:"TargetFilename" kind:wildcard
process.namein
  • Archive Utility
  • ArchiveService
  • bsdtar
  • tar
  • unzip
field:"process_basename" kind:in

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
Effective_process.executablein/Applications/NinjaRMMAgent/programfiles/ninjarmm-macagent, /Applications/Utilities/NacAgent.app/Contents/MacOS/NacAgent, /Applications/Warp.app/Contents/MacOS/stable, /Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon, /Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfManagementService.app/Contents/MacOS/JamfManagementService, /Library/Application Support/TrendMicro/RPD/RecoveryPackDownloader.app/Contents/MacOS/RecoveryPackDownloader, /Library/Developer/PrivateFrameworks/CoreSimulator.framework/Versions/A/XPCServices/SimulatorTrampoline.xpc/Contents/MacOS/SimulatorTrampoline, /Library/Iru/Iru Agent.app/Contents/Helpers/Iru Library Manager.app/Contents/MacOS/kandji-library-manager, /Library/Kandji/Kandji Agent.app/Contents/Helpers/Kandji Library Manager.app/Contents/MacOS/kandji-library-manager, /opt/jc/bin/jumpcloud-agent, /usr/libexec/xpcproxyexcludes:Effective_process.executable
file.pathwildcard/private/var/tmp/*bazel*excludes:file.path field:"file.path" value:"/private/var/tmp/*bazel*"

File Permission Modification in Writable Directory

#
Status
production
Severity
high
Time window
9m
Group by
host.id, process.command_line, process.parent.executable
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies file permission modifications in common writable directories by a non-root user. Adversaries often drop files or payloads into a writable directory and change permissions prior to execution.

Known False Positives

  • Certain programs or applications may modify files or change ownership in writable directories. These can be exempted by username.

MITRE ATT&CK Coverage

Rule Body

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

[rule]
author = ["Elastic"]
description = """
Identifies file permission modifications in common writable directories by a non-root user. Adversaries often drop files
or payloads into a writable directory and change permissions prior to execution.
"""
false_positives = [
    """
    Certain programs or applications may modify files or change ownership in writable directories. These can be exempted
    by username.
    """,
]
from = "now-9m"
index = ["logs-endpoint.events.*"]
language = "kuery"
license = "Elastic License v2"
name = "File Permission Modification in Writable Directory"
risk_score = 73
rule_id = "9f9a2a82-93a8-4b1a-8778-1780895626d4"
setup = """## Setup

This rule requires data coming in from one of the following integrations:
- Elastic Defend
- Auditbeat

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

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

#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest 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).

### Auditbeat Setup
Auditbeat is a lightweight shipper that you can install on your servers to audit the activities of users and processes on your systems. For example, you can use Auditbeat to collect and centralize audit events from the Linux Audit Framework. You can also use Auditbeat to detect changes to critical files, like binaries and configuration files, and identify potential security policy violations.

#### The following steps should be executed in order to add the Auditbeat on a Linux System:
- Elastic provides repositories available for APT and YUM-based distributions. Note that we provide binary packages, but no source packages.
- To install the APT and YUM repositories follow the setup instructions in this [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/setup-repositories.html).
- To run Auditbeat on Docker follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/running-on-docker.html).
- To run Auditbeat on Kubernetes follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/running-on-kubernetes.html).
- For complete “Setup and Run Auditbeat” information refer to the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/setting-up-and-running.html).
"""
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Defense Evasion",
    "Data Source: Elastic Defend",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
host.os.type:"linux" and event.category:process and event.type:"start" and event.action:"exec" and
process.name:("chattr" or "chgrp" or "chmod") and process.working_directory:("/dev/shm" or "/tmp" or "/var/tmp") and
not (
  process.args:(
    "+r" or "640" or /tmp/apt-key-gpghome* or "/usr/bin/coreutils" or "/opt/eset/eei/uninstall.sh" or /tmp/era.repository.*.bin
  ) or
  process.parent.args:"/var/illumio_pce/illumio/scripts/consul" or
  process.parent.name:(
    apt-key or update-motd-updates-available or apt-get or java or pilot or PassengerAgent or nginx
  ) or
  process.parent.executable:(
    "/usr/local/bin/afb-ssh-setup-keys.sh" or "/usr/local/bin/afb-ssh-setup-keys.sh" or "/opt/puppetlabs/puppet/bin/ruby" or
    "/usr/sbin/update-exim4.conf" or "/bin/dracut"
  )
)
'''
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 File Permission Modification in Writable Directory

In Linux environments, writable directories like /tmp or /var/tmp are often used for temporary file storage. Adversaries exploit these by modifying file permissions to execute malicious payloads. The detection rule identifies non-root users altering permissions in these directories using commands like chmod or chown, excluding benign processes, to flag potential threats. This helps in identifying unauthorized permission changes indicative of defense evasion tactics.

### Possible investigation steps

- Review the process details to identify the non-root user who executed the permission modification command (chattr, chgrp, chmod, or chown) in the specified writable directories (/dev/shm, /tmp, or /var/tmp).
- Examine the parent process of the detected command to determine if it is associated with any known malicious activity or if it deviates from typical user behavior, ensuring it is not one of the excluded benign processes (apt-key, update-motd-updates-available, apt-get).
- Investigate the specific file or directory whose permissions were altered to assess its legitimacy and check for any associated suspicious files or payloads.
- Analyze recent activities by the identified user to detect any other anomalous behavior or unauthorized access attempts that could indicate a broader compromise.
- Cross-reference the event with other security logs and alerts to identify any correlated incidents or patterns that might suggest a coordinated attack or persistent threat.

### False positive analysis

- System updates and maintenance scripts may trigger permission changes in writable directories. Exclude processes like apt-key, update-motd-updates-available, and apt-get to reduce noise from legitimate system activities.
- Development and testing environments often involve frequent permission changes by non-root users. Consider excluding specific user accounts or processes known to be part of regular development workflows.
- Automated backup or synchronization tools might modify file permissions as part of their operations. Identify and exclude these tools if they are verified to be non-threatening.
- Custom scripts or applications that require permission changes for functionality should be reviewed and, if deemed safe, added to an exception list to prevent false alerts.
- Regularly review and update the exclusion list to ensure it reflects current operational practices and does not inadvertently allow malicious activities.

### Response and remediation

- Immediately isolate the affected system from the network to prevent further unauthorized access or lateral movement.
- Terminate any suspicious processes identified in the alert that are associated with unauthorized permission changes.
- Revert any unauthorized file permission changes in the writable directories to their original state to prevent execution of malicious payloads.
- Conduct a thorough scan of the affected directories (/dev/shm, /tmp, /var/tmp) for any malicious files or payloads and remove them.
- Review user accounts and permissions to ensure that only authorized users have access to modify file permissions in sensitive directories.
- Escalate the incident to the security operations team for further investigation and to determine if additional systems are affected.
- Implement enhanced monitoring and logging for file permission changes in writable directories to detect similar threats in the future."""

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

[[rule.threat.technique]]
id = "T1222"
name = "File and Directory Permissions Modification"
reference = "https://attack.mitre.org/techniques/T1222/"

[[rule.threat.technique.subtechnique]]
id = "T1222.002"
name = "Linux and Mac File and Directory Permissions Modification"
reference = "https://attack.mitre.org/techniques/T1222/002/"

[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[rule.new_terms]
field = "new_terms_fields"
value = ["host.id", "process.parent.executable", "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:"linux" and event.category:process and event.type:"start" and event.action:"exec" and
process.name:("chattr" or "chgrp" or "chmod") and process.working_directory:("/dev/shm" or "/tmp" or "/var/tmp") and
not (
  process.args:(
    "+r" or "640" or /tmp/apt-key-gpghome* or "/usr/bin/coreutils" or "/opt/eset/eei/uninstall.sh" or /tmp/era.repository.*.bin
  ) or
  process.parent.args:"/var/illumio_pce/illumio/scripts/consul" or
  process.parent.name:(
    apt-key or update-motd-updates-available or apt-get or java or pilot or PassengerAgent or nginx
  ) or
  process.parent.executable:(
    "/usr/local/bin/afb-ssh-setup-keys.sh" or "/usr/local/bin/afb-ssh-setup-keys.sh" or "/opt/puppetlabs/puppet/bin/ruby" or
    "/usr/sbin/update-exim4.conf" or "/bin/dracut"
  )
)

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argseq+rexcludes:process.args field:"process.args" value:"+r"
process.argseq/opt/eset/eei/uninstall.shexcludes:process.args field:"process.args" value:"/opt/eset/eei/uninstall.sh"
process.argseq/usr/bin/coreutilsexcludes:process.args field:"process.args" value:"/usr/bin/coreutils"
process.argseq640excludes:process.args field:"process.args" value:"640"
process.argsstarts_with/tmp/apt-key-gpghomeexcludes:process.args field:"process.args" value:"/tmp/apt-key-gpghome"
process.argswildcard/tmp/era.repository.*.binexcludes:process.args field:"process.args" value:"/tmp/era.repository.*.bin"
process.parent.argseq/var/illumio_pce/illumio/scripts/consulexcludes:process.parent.args field:"process.parent.args" value:"/var/illumio_pce/illumio/scripts/consul"
process.parent.executablein/bin/dracut, /opt/puppetlabs/puppet/bin/ruby, /usr/local/bin/afb-ssh-setup-keys.sh, /usr/sbin/update-exim4.confexcludes:process.parent.executable
process.parent.nameinPassengerAgent, apt-get, apt-key, java, nginx, pilot, update-motd-updates-availableexcludes:process.parent.name

Kerberos Traffic from Unusual Process

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

Identifies network connections to the standard Kerberos port from an unusual process. On Windows, the only process that normally performs Kerberos traffic from a domain joined host is lsass.exe.

Known False Positives

  • HTTP traffic on a non standard port. Verify that the destination IP address is not related to a Domain Controller.

MITRE ATT&CK Coverage

Telemetry Coverage

ProviderRecord / event type
SysmonEvent ID 3: Network connection

Rule Body

[metadata]
creation_date = "2020/11/02"
integration = ["endpoint", "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 network connections to the standard Kerberos port from an unusual process. On Windows, the only process that
normally performs Kerberos traffic from a domain joined host is lsass.exe.
"""
false_positives = [
    """
    HTTP traffic on a non standard port. Verify that the destination IP address is not related to a Domain Controller.
    """,
]
from = "now-9m"
index = ["logs-endpoint.events.network-*", "logs-sentinel_one_cloud_funnel.*"]
language = "eql"
license = "Elastic License v2"
name = "Kerberos Traffic from Unusual Process"
note = """## Triage and analysis

### Investigating Kerberos Traffic from Unusual Process

Kerberos is the default authentication protocol in Active Directory, designed to provide strong authentication for client/server applications by using secret-key cryptography.

Domain-joined hosts usually perform Kerberos traffic using the `lsass.exe` process. This rule detects the occurrence of traffic on the Kerberos port (88) by processes other than `lsass.exe` to detect the unusual request and usage of Kerberos tickets.

> **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.
- Check if the Destination IP is related to a Domain Controller.
- Review event ID 4769 for suspicious ticket requests.
- 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 rule uses a Kerberos-related port but does not identify the protocol used on that port. HTTP traffic on a non-standard port or destination IP address unrelated to Domain controllers can create false positives.
- Exceptions can be added for noisy/frequent connections.

### 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.
- 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.
  - Ticket requests can be used to investigate potentially compromised accounts.
- 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:

- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
"""

risk_score = 47
rule_id = "897dc6b5-b39f-432a-8d75-d3730d50c782"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Resources: Investigation Guide",
    "Data Source: Elastic Defend",
    "Data Source: SentinelOne",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
network where host.os.type == "windows" and event.type == "start" and network.direction == "egress" and
  destination.port == 88 and source.port >= 49152 and process.pid != 4 and destination.address : "*" and
  not 
  (
    process.executable : (
        "\\device\\harddiskvolume?\\program files (x86)\\nmap\\nmap.exe",
        "\\device\\harddiskvolume?\\program files (x86)\\nmap oem\\nmap.exe",
        "\\device\\harddiskvolume?\\windows\\system32\\lsass.exe",
        "?:\\Program Files\\Amazon Corretto\\jdk1*\\bin\\java.exe",
        "?:\\Program Files\\BlackBerry\\UEM\\Proxy Server\\bin\\prunsrv.exe",
        "?:\\Program Files\\BlackBerry\\UEM\\Core\\tomcat-core\\bin\\tomcat9.exe",
        "?:\\Program Files\\DBeaver\\dbeaver.exe",
        "?:\\Program Files\\Docker\\Docker\\resources\\com.docker.backend.exe",
        "?:\\Program Files\\Docker\\Docker\\resources\\com.docker.vpnkit.exe",
        "?:\\Program Files\\Docker\\Docker\\resources\\vpnkit.exe",
        "?:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
        "?:\\Program Files\\Internet Explorer\\iexplore.exe",
        "?:\\Program Files\\JetBrains\\PyCharm Community Edition*\\bin\\pycharm64.exe",
        "?:\\Program Files\\Mozilla Firefox\\firefox.exe",
        "?:\\Program Files\\Oracle\\VirtualBox\\VirtualBoxVM.exe",
        "?:\\Program Files\\Puppet Labs\\Puppet\\puppet\\bin\\ruby.exe",
        "?:\\Program Files\\rapid7\\nexpose\\nse\\.DLLCACHE\\nseserv.exe",
        "?:\\Program Files\\Silverfort\\Silverfort AD Adapter\\SilverfortServer.exe",
        "?:\\Program Files\\Tenable\\Nessus\\nessusd.exe",
        "?:\\Program Files\\VMware\\VMware View\\Server\\bin\\ws_TomcatService.exe",
        "?:\\Program Files (x86)\\Advanced Port Scanner\\advanced_port_scanner.exe",
        "?:\\Program Files (x86)\\DesktopCentral_Agent\\bin\\dcpatchscan.exe",
        "?:\\Program Files (x86)\\GFI\\LanGuard 12 Agent\\lnsscomm.exe",
        "?:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
        "?:\\Program Files (x86)\\Internet Explorer\\iexplore.exe",
        "?:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe",
        "?:\\Program Files (x86)\\Microsoft\\EdgeUpdate\\MicrosoftEdgeUpdate.exe",
        "?:\\Program Files (x86)\\Microsoft Silverlight\\sllauncher.exe",
        "?:\\Program Files (x86)\\Nmap\\nmap.exe",
        "?:\\Program Files (x86)\\Nmap OEM\\nmap.exe",
        "?:\\Program Files (x86)\\nwps\\NetScanTools Pro\\NSTPRO.exe",
        "?:\\Program Files (x86)\\SAP BusinessObjects\\tomcat\\bin\\tomcat9.exe",
        "?:\\Program Files (x86)\\SuperScan\\scanner.exe",
        "?:\\Program Files (x86)\\Zscaler\\ZSATunnel\\ZSATunnel.exe",
        "?:\\Windows\\System32\\lsass.exe",
        "?:\\Windows\\System32\\MicrosoftEdgeCP.exe",
        "?:\\Windows\\System32\\svchost.exe",
        "?:\\Windows\\SysWOW64\\vmnat.exe",
        "?:\\Windows\\SystemApps\\Microsoft.MicrosoftEdge_*\\MicrosoftEdge.exe",
        "System"
    ) and process.code_signature.trusted == true
  ) and
 destination.address != "127.0.0.1" and destination.address != "::1"
'''


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

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

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

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

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

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

[[rule.threat.technique.subtechnique]]
id = "T1550.003"
name = "Pass the Ticket"
reference = "https://attack.mitre.org/techniques/T1550/003/"

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

Stages and Predicates

Stage 1: network

network where host.os.type == "windows" and event.type == "start" and network.direction == "egress" and
  destination.port == 88 and source.port >= 49152 and process.pid != 4 and destination.address : "*" and
  not 
  (
    process.executable : (
        "\\device\\harddiskvolume?\\program files (x86)\\nmap\\nmap.exe",
        "\\device\\harddiskvolume?\\program files (x86)\\nmap oem\\nmap.exe",
        "\\device\\harddiskvolume?\\windows\\system32\\lsass.exe",
        "?:\\Program Files\\Amazon Corretto\\jdk1*\\bin\\java.exe",
        "?:\\Program Files\\BlackBerry\\UEM\\Proxy Server\\bin\\prunsrv.exe",
        "?:\\Program Files\\BlackBerry\\UEM\\Core\\tomcat-core\\bin\\tomcat9.exe",
        "?:\\Program Files\\DBeaver\\dbeaver.exe",
        "?:\\Program Files\\Docker\\Docker\\resources\\com.docker.backend.exe",
        "?:\\Program Files\\Docker\\Docker\\resources\\com.docker.vpnkit.exe",
        "?:\\Program Files\\Docker\\Docker\\resources\\vpnkit.exe",
        "?:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
        "?:\\Program Files\\Internet Explorer\\iexplore.exe",
        "?:\\Program Files\\JetBrains\\PyCharm Community Edition*\\bin\\pycharm64.exe",
        "?:\\Program Files\\Mozilla Firefox\\firefox.exe",
        "?:\\Program Files\\Oracle\\VirtualBox\\VirtualBoxVM.exe",
        "?:\\Program Files\\Puppet Labs\\Puppet\\puppet\\bin\\ruby.exe",
        "?:\\Program Files\\rapid7\\nexpose\\nse\\.DLLCACHE\\nseserv.exe",
        "?:\\Program Files\\Silverfort\\Silverfort AD Adapter\\SilverfortServer.exe",
        "?:\\Program Files\\Tenable\\Nessus\\nessusd.exe",
        "?:\\Program Files\\VMware\\VMware View\\Server\\bin\\ws_TomcatService.exe",
        "?:\\Program Files (x86)\\Advanced Port Scanner\\advanced_port_scanner.exe",
        "?:\\Program Files (x86)\\DesktopCentral_Agent\\bin\\dcpatchscan.exe",
        "?:\\Program Files (x86)\\GFI\\LanGuard 12 Agent\\lnsscomm.exe",
        "?:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
        "?:\\Program Files (x86)\\Internet Explorer\\iexplore.exe",
        "?:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe",
        "?:\\Program Files (x86)\\Microsoft\\EdgeUpdate\\MicrosoftEdgeUpdate.exe",
        "?:\\Program Files (x86)\\Microsoft Silverlight\\sllauncher.exe",
        "?:\\Program Files (x86)\\Nmap\\nmap.exe",
        "?:\\Program Files (x86)\\Nmap OEM\\nmap.exe",
        "?:\\Program Files (x86)\\nwps\\NetScanTools Pro\\NSTPRO.exe",
        "?:\\Program Files (x86)\\SAP BusinessObjects\\tomcat\\bin\\tomcat9.exe",
        "?:\\Program Files (x86)\\SuperScan\\scanner.exe",
        "?:\\Program Files (x86)\\Zscaler\\ZSATunnel\\ZSATunnel.exe",
        "?:\\Windows\\System32\\lsass.exe",
        "?:\\Windows\\System32\\MicrosoftEdgeCP.exe",
        "?:\\Windows\\System32\\svchost.exe",
        "?:\\Windows\\SysWOW64\\vmnat.exe",
        "?:\\Windows\\SystemApps\\Microsoft.MicrosoftEdge_*\\MicrosoftEdge.exe",
        "System"
    ) and process.code_signature.trusted == true
  ) and
 destination.address != "127.0.0.1" and destination.address != "::1"

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.code_signature.trustedeqtrueexcludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true"
process.executablewildcard\device\harddiskvolume?\program files (x86)\nmap\nmap.exe, \device\harddiskvolume?\program files (x86)\nmap oem\nmap.exe, \device\harddiskvolume?\windows\system32\lsass.exe, ?:\Program Files\Amazon Corretto\jdk1*\bin\java.exe, ?:\Program Files\BlackBerry\UEM\Proxy Server\bin\prunsrv.exe, ?:\Program Files\BlackBerry\UEM\Core\tomcat-core\bin\tomcat9.exe, ?:\Program Files\DBeaver\dbeaver.exe, ?:\Program Files\Docker\Docker\resources\com.docker.backend.exe, ?:\Program Files\Docker\Docker\resources\com.docker.vpnkit.exe, ?:\Program Files\Docker\Docker\resources\vpnkit.exe, ?:\Program Files\Google\Chrome\Application\chrome.exe, ?:\Program Files\Internet Explorer\iexplore.exe, ?:\Program Files\JetBrains\PyCharm Community Edition*\bin\pycharm64.exe, ?:\Program Files\Mozilla Firefox\firefox.exe, ?:\Program Files\Oracle\VirtualBox\VirtualBoxVM.exe, ?:\Program Files\Puppet Labs\Puppet\puppet\bin\ruby.exe, ?:\Program Files\rapid7\nexpose\nse\.DLLCACHE\nseserv.exe, ?:\Program Files\Silverfort\Silverfort AD Adapter\SilverfortServer.exe, ?:\Program Files\Tenable\Nessus\nessusd.exe, ?:\Program Files\VMware\VMware View\Server\bin\ws_TomcatService.exe, ?:\Program Files (x86)\Advanced Port Scanner\advanced_port_scanner.exe, ?:\Program Files (x86)\DesktopCentral_Agent\bin\dcpatchscan.exe, ?:\Program Files (x86)\GFI\LanGuard 12 Agent\lnsscomm.exe, ?:\Program Files (x86)\Google\Chrome\Application\chrome.exe, ?:\Program Files (x86)\Internet Explorer\iexplore.exe, ?:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe, ?:\Program Files (x86)\Microsoft\EdgeUpdate\MicrosoftEdgeUpdate.exe, ?:\Program Files (x86)\Microsoft Silverlight\sllauncher.exe, ?:\Program Files (x86)\Nmap\nmap.exe, ?:\Program Files (x86)\Nmap OEM\nmap.exe, ?:\Program Files (x86)\nwps\NetScanTools Pro\NSTPRO.exe, ?:\Program Files (x86)\SAP BusinessObjects\tomcat\bin\tomcat9.exe, ?:\Program Files (x86)\SuperScan\scanner.exe, ?:\Program Files (x86)\Zscaler\ZSATunnel\ZSATunnel.exe, ?:\Windows\System32\lsass.exe, ?:\Windows\System32\MicrosoftEdgeCP.exe, ?:\Windows\System32\svchost.exe, ?:\Windows\SysWOW64\vmnat.exe, ?:\Windows\SystemApps\Microsoft.MicrosoftEdge_*\MicrosoftEdge.exe, Systemexcludes:process.executable

Kubelet Certificate File Access Detected via Defend for Containers

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

This rule detects the access of the Kubelet certificate file inside a container. The Kubelet certificate file is used to authenticate the container to the Kubernetes API server, and may be used by an adversary to gain access to the Kubernetes API server or other resources within the cluster. These files are a common target for adversaries to gain access to the cluster. There is a current limitation in the defend for containers file sensor that prevents file open events from being logged for file open events without write intent.

MITRE ATT&CK Coverage

Rule Body

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

[rule]
author = ["Elastic"]
description = """
This rule detects the access of the Kubelet certificate file inside a container. The Kubelet certificate file is
used to authenticate the container to the Kubernetes API server, and may be used by an adversary to gain access
to the Kubernetes API server or other resources within the cluster. These files are a common target for adversaries
to gain access to the cluster. There is a current limitation in the defend for containers file sensor that prevents
file open events from being logged for file open events without write intent. 
"""
from = "now-6m"
index = ["logs-cloud_defend.file*", "logs-cloud_defend.process*"]
interval = "5m"
language = "eql"
license = "Elastic License v2"
name = "Kubelet Certificate File Access Detected via Defend for Containers"
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 Kubelet Certificate File Access Detected via Defend for Containers

This detection flags a process inside a Linux container opening files under `/var/lib/kubelet/pki/`, which includes the kubelet client certificate and key used to authenticate to the Kubernetes API. Attackers who obtain these credentials can impersonate the node, enumerate cluster resources, and pivot to secrets or workloads. A common pattern is an operator exec’ing into a compromised pod, locating the kubelet cert/key pair, copying it out, then using it to query the API server from outside the container.

### Possible investigation steps

- Identify the pod/namespace/node and owning controller for the container, then confirm whether it should ever have access to host kubelet PKI (e.g., privileged DaemonSet, hostPath mount, node-agent tooling) or if this is an unexpected breakout indicator.
- Review the interactive session context (exec/attach/ssh), including who initiated it and the command history/TTY telemetry around the alert time, to determine whether this was routine debugging or suspicious enumeration.
- Inspect the container filesystem and recent file operations for evidence of credential harvesting (reads of kubelet client cert/key pairs, copies to temporary paths, archive creation, or outbound transfer tooling) and preserve artifacts for forensics.
- Correlate immediately after the access event for Kubernetes API activity using node credentials (unusual discovery, secret access, or cluster-wide queries) originating from the same workload identity, node, or egress address.
- Validate whether kubelet credentials were reused by reviewing API server audit logs for unexpected node identity actions, and rotate kubelet client certs/keys and isolate the workload if misuse is suspected.

### False positive analysis

- A cluster operator or SRE may exec into a privileged pod (e.g., a DaemonSet with hostPath access to `/var/lib/kubelet`) for node troubleshooting and use interactive shell commands to inspect or validate kubelet PKI files during incident response or routine maintenance.
- A legitimate containerized node-management or diagnostic workflow that runs interactively (e.g., invoked manually for verification) may open files under `/var/lib/kubelet/pki/` as part of validating kubelet certificate presence/permissions after upgrades, certificate rotation, or node reconfiguration.

### Response and remediation

- Immediately isolate the affected workload by scaling the pod/controller to zero or cordoning and draining the node if a privileged pod has host access to `/var/lib/kubelet/pki/`, and preserve the container filesystem and process list for forensics before teardown.  
- Remove the execution path that enabled access by deleting or patching the pod/DaemonSet to drop `privileged`, `hostPID/hostNetwork`, and any `hostPath` mounts that expose `/var/lib/kubelet` and redeploy only from a known-good image and manifest.  
- Rotate and reissue kubelet client certificates/keys on the impacted node(s) (or replace the node from autoscaling/immutable infrastructure) and verify the old credentials can no longer authenticate to the Kubernetes API server.  
- Review Kubernetes API server audit logs for activity using the node identity around the access time (cluster-wide discovery, secret reads, token reviews, exec into other pods) and revoke/rotate any exposed service account tokens or secrets accessed during the window.  
- Escalate to the Kubernetes platform/on-call security team immediately if the files include a kubelet client key, if the pod was privileged or had host mounts, or if API audit logs show node credential use from unexpected sources or unusual resource enumeration.  
- Harden the cluster by enforcing policies that block hostPath access to `/var/lib/kubelet` and privileged pods (Pod Security Admission/Gatekeeper/Kyverno), limiting interactive exec/attach via RBAC, and monitoring for subsequent access attempts to kubelet PKI paths and related credential exfiltration tooling.
"""
references = [
    "https://heilancoos.github.io/research/2025/12/16/kubernetes.html#kubelet-api",
    "https://www.cyberark.com/resources/threat-research-blog/using-kubelet-client-to-attack-the-kubernetes-cluster",
    "https://www.aquasec.com/blog/kubernetes-exposed-exploiting-the-kubelet-api/"
]
risk_score = 21
rule_id = "42de0740-8ed8-4b8b-995c-635b56a8bbf4"
severity = "low"
tags = [
    "Data Source: Elastic Defend for Containers",
    "Domain: Container",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Discovery",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
any where host.os.type == "linux" and container.id like "*" and (
  (event.category == "file" and event.type == "change" and event.action == "open" and file.path like "/var/lib/kubelet/pki/*") or
  (event.category == "process" and event.type == "start" and event.action == "exec" and
  (
    process.name in ("cat", "head", "tail", "more", "less", "sed", "awk") or
    process.args in (
      "cat", "/bin/cat", "/usr/bin/cat", "/usr/local/bin/cat",
      "head", "/bin/head", "/usr/bin/head", "/usr/local/bin/head",
      "tail", "/bin/tail", "/usr/bin/tail", "/usr/local/bin/tail",
      "more", "/bin/more", "/usr/bin/more", "/usr/local/bin/more",
      "less", "/bin/less", "/usr/bin/less", "/usr/local/bin/less",
      "sed", "/bin/sed", "/usr/bin/sed", "/usr/local/bin/sed",
      "awk", "/bin/awk", "/usr/bin/awk", "/usr/local/bin/awk"
    )
  ) and process.args like "*/var/lib/kubelet/pki/*")
)
'''

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

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

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

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

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

Stages and Predicates

Stage 1: any

any where host.os.type == "linux" and container.id like "*" and (
  (event.category == "file" and event.type == "change" and event.action == "open" and file.path like "/var/lib/kubelet/pki/*") or
  (event.category == "process" and event.type == "start" and event.action == "exec" and
  (
    process.name in ("cat", "head", "tail", "more", "less", "sed", "awk") or
    process.args in (
      "cat", "/bin/cat", "/usr/bin/cat", "/usr/local/bin/cat",
      "head", "/bin/head", "/usr/bin/head", "/usr/local/bin/head",
      "tail", "/bin/tail", "/usr/bin/tail", "/usr/local/bin/tail",
      "more", "/bin/more", "/usr/bin/more", "/usr/local/bin/more",
      "less", "/bin/less", "/usr/bin/less", "/usr/local/bin/less",
      "sed", "/bin/sed", "/usr/bin/sed", "/usr/local/bin/sed",
      "awk", "/bin/awk", "/usr/bin/awk", "/usr/local/bin/awk"
    )
  ) and process.args like "*/var/lib/kubelet/pki/*")
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
container.idwildcard
  • *
field:"container.id" kind:wildcard value:"*"
event.actioneq
  • exec
  • open
field:"EventType" kind:eq
event.categoryeq
  • file
  • process
field:"event.category" kind:eq
event.typeeq
  • change
  • start
field:"event.type" kind:eq
file.pathwildcard
  • /var/lib/kubelet/pki/*
field:"TargetFilename" kind:wildcard value:"/var/lib/kubelet/pki/*"
process.argsin
  • /bin/awk
  • /bin/cat
  • /bin/head
  • /bin/less
  • /bin/more
  • /bin/sed
  • /bin/tail
  • /usr/bin/awk
  • /usr/bin/cat
  • /usr/bin/head
  • /usr/bin/less
  • /usr/bin/more
  • /usr/bin/sed
  • /usr/bin/tail
  • /usr/local/bin/awk
  • /usr/local/bin/cat
  • /usr/local/bin/head
  • /usr/local/bin/less
  • /usr/local/bin/more
  • /usr/local/bin/sed
  • /usr/local/bin/tail
  • awk
  • cat
  • head
  • less
  • more
  • sed
  • tail
field:"process.args" kind:in
process.argswildcard
  • */var/lib/kubelet/pki/*
field:"process.args" kind:wildcard value:"*/var/lib/kubelet/pki/*"
process.namein
  • awk
  • cat
  • head
  • less
  • more
  • sed
  • tail
field:"process_basename" kind:in

New Okta Identity Provider (IdP) Added by Admin

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

Detects the creation of a new Identity Provider (IdP) by a Super Administrator or Organization Administrator within Okta.

MITRE ATT&CK Coverage

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

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

[rule]
author = ["Elastic"]
description = """
Detects the creation of a new Identity Provider (IdP) by a Super Administrator or Organization Administrator within
Okta.
"""
from = "now-30m"
index = ["filebeat-*", "logs-okta*"]
interval = "15m"
language = "kuery"
license = "Elastic License v2"
name = "New Okta Identity Provider (IdP) Added by Admin"
note = """## Triage and analysis

### Investigating New Okta Identity Provider (IdP) Added by Admin

This rule detects the creation of a new Identity Provider (IdP) by a Super Administrator or Organization Administrator within Okta.

#### Possible investigation steps:
- Identify the actor associated with the IdP creation by examining the `okta.actor.id`, `okta.actor.type`, `okta.actor.alternate_id`, and `okta.actor.display_name` fields.
- Identify the IdP added by reviewing the `okta.target` field and determing if this IdP is authorized.
- Determine the client used by the actor. Review the `okta.client.ip`, `okta.client.user_agent.raw_user_agent`, `okta.client.zone`, `okta.client.device`, and `okta.client.id` fields.
- If the client is a device, check the `okta.device.id`, `okta.device.name`, `okta.device.os_platform`, `okta.device.os_version`, and `okta.device.managed` fields.
- Review the past activities of the actor involved in this action by checking their previous actions logged in the `okta.target` field.
- Examine the `okta.request.ip_chain` field to potentially determine if the actor used a proxy or VPN to perform this action.
- Evaluate the actions that happened just before and after this event in the `okta.event_type` field to help understand the full context of the activity.

### False positive analysis:
- It might be a false positive if the action was part of a planned activity or performed by an authorized person.
- Several unsuccessful attempts prior to this success, may indicate an adversary attempting to add an unauthorized IdP multiple times.

### Response and remediation:
- If the IdP is unauthorized, deactivate it immediately via the Okta console.
- If the IdP is authorized, ensure that the actor who created it is authorized to do so.
- If the actor is unauthorized, deactivate their account via the Okta console.
- If the actor is authorized, ensure that the actor's account is not compromised.
- Reset the user's password and enforce MFA re-enrollment, if applicable.
- Block the IP address or device used in the attempts if they appear suspicious, using the data from the `okta.client.ip` and `okta.device.id` fields.
- Conduct a review of Okta policies and ensure they are in accordance with security best practices.
- If the deactivated IdP was crucial to the organization, consider adding a new IdP and removing the unauthorized IdP.

## Setup

The Okta Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.
"""
references = [
    "https://blog.cloudflare.com/cloudflare-investigation-of-the-january-2022-okta-compromise/",
    "https://www.elastic.co/security-labs/testing-okta-visibility-and-detection-dorothy",
    "https://sec.okta.com/articles/2023/08/cross-tenant-impersonation-prevention-and-detection",
    "https://unit42.paloaltonetworks.com/muddled-libra/",
    "https://www.elastic.co/security-labs/monitoring-okta-threats-with-elastic-security",
    "https://www.elastic.co/security-labs/starter-guide-to-understanding-okta",
]
risk_score = 47
rule_id = "29b53942-7cd4-11ee-b70e-f661ea17fbcd"
severity = "medium"
tags = [
    "Use Case: Identity and Access Audit",
    "Tactic: Persistence",
    "Data Source: Okta",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset: "okta.system" and event.action: "system.idp.lifecycle.create" and okta.outcome.result: "SUCCESS"
'''


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

[[rule.threat.technique]]
id = "T1556"
name = "Modify Authentication Process"
reference = "https://attack.mitre.org/techniques/T1556/"

[[rule.threat.technique.subtechnique]]
id = "T1556.007"
name = "Hybrid Identity"
reference = "https://attack.mitre.org/techniques/T1556/007/"

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

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

[[rule.threat.technique]]
id = "T1484"
name = "Domain or Tenant Policy Modification"
reference = "https://attack.mitre.org/techniques/T1484/"

[[rule.threat.technique.subtechnique]]
id = "T1484.002"
name = "Trust Modification"
reference = "https://attack.mitre.org/techniques/T1484/002/"

[[rule.threat.technique]]
id = "T1556"
name = "Modify Authentication Process"
reference = "https://attack.mitre.org/techniques/T1556/"

[[rule.threat.technique.subtechnique]]
id = "T1556.007"
name = "Hybrid Identity"
reference = "https://attack.mitre.org/techniques/T1556/007/"

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

Stages and Predicates

Stage 1: query

data_stream.dataset: "okta.system" and event.action: "system.idp.lifecycle.create" and okta.outcome.result: "SUCCESS"

Indicators

These rows show field, operator, and value matches.

Potential Data Exfiltration via Rclone

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

Identifies abuse of rclone (or a renamed copy, e.g. disguised as a security or backup utility) to exfiltrate data to cloud storage or remote endpoints. Rclone is a legitimate file sync tool; threat actors rename it to blend with administrative traffic and use copy/sync with cloud backends (e.g. :s3:) and include filters to exfiltrate specific file types.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

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

[rule]
author = ["Elastic"]
description = """
Identifies abuse of rclone (or a renamed copy, e.g. disguised as a security or backup utility) to exfiltrate data to
cloud storage or remote endpoints. Rclone is a legitimate file sync tool; threat actors rename it to blend with
administrative traffic and use copy/sync with cloud backends (e.g. :s3:) and include filters to exfiltrate specific
file types.
"""
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 = "Potential Data Exfiltration via Rclone"
note = """## Triage and analysis

### Investigating Potential Data Exfiltration via Rclone

Rclone is a legitimate file synchronization tool. Threat actors abuse it (often renamed, e.g. to TrendFileSecurityCheck.exe) to exfiltrate data to S3, HTTP endpoints, or other cloud backends, using `copy`/`sync` with `--include` filters and high `--transfers` to move specific file types at scale.

### Possible investigation steps

- Confirm the command line for `copy`/`sync`, cloud backend (e.g. `:s3:`, `:http`), and options like `--include`, `--transfers`, `-P`.
- If the process name is not `rclone.exe`, compare with `process.pe.original_file_name`; a mismatch indicates a renamed copy used to evade name-based detection.
- From the command line, identify the source path (e.g. UNC or local) and the remote backend (S3 bucket, HTTP endpoint) as the exfil destination.
- Review `--include`/`--exclude` and `--max-age`/`--max-size` to understand what data was targeted (documents, CAD, archives, etc.).
- Correlate with the process executable path (recently dropped?), parent process, and user; look for outbound network to the same backend.

### False positive analysis

- Legitimate backup or sync jobs using rclone from a known path and config may trigger; allowlist by process path or `--config` path for approved rclone usage.

### Response and remediation

- Terminate the rclone process and isolate the host if exfiltration is confirmed.
- Identify and revoke access to the destination (S3 bucket, API keys, etc.); preserve logs for the exfil session.
- Determine scope of data exposed and notify stakeholders; rotate credentials and secrets that may have been in exfiltrated paths.
"""

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

references = [
    "https://attack.mitre.org/techniques/T1048/",
    "https://rclone.org/commands/rclone_copy/",
]
risk_score = 47
rule_id = "3f4c2b18-9d2e-4b7a-a3c1-8e6d9f2b5c7e"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Exfiltration",
    "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 : "rclone.exe" or ?process.pe.original_file_name == "rclone.exe") and process.args : ("copy", "sync") and
  not process.args : ("--config=?:\\Program Files\\rclone\\config\\rclone\\rclone.conf", "--config=?:\\Program Files (x86)\\rclone\\config\\rclone\\rclone.conf") and 
  not process.executable : ("?:\\Program Files*", "\\Device\\HarddiskVolume*\\Program Files*")
'''


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

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

[[rule.threat.technique]]
id = "T1567"
name = "Exfiltration Over Web Service"
reference = "https://attack.mitre.org/techniques/T1567/"

[[rule.threat.technique.subtechnique]]
id = "T1567.002"
name = "Exfiltration to Cloud Storage"
reference = "https://attack.mitre.org/techniques/T1567/002/"

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

[[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.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 : "rclone.exe" or ?process.pe.original_file_name == "rclone.exe") and process.args : ("copy", "sync") and
  not process.args : ("--config=?:\\Program Files\\rclone\\config\\rclone\\rclone.conf", "--config=?:\\Program Files (x86)\\rclone\\config\\rclone\\rclone.conf") and 
  not process.executable : ("?:\\Program Files*", "\\Device\\HarddiskVolume*\\Program Files*")

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argseq--config=?:\Program Files\rclone\config\rclone\rclone.conf, --config=?:\Program Files (x86)\rclone\config\rclone\rclone.confexcludes:process.args field:"process.args" value:"--config=?:\Program Files\rclone\config\rclone\rclone.conf" field:"process.args" value:"--config=?:\Program Files (x86)\rclone\config\rclone\rclone.conf"
process.executablewildcard?:\Program Files*, \Device\HarddiskVolume*\Program Files*excludes:process.executable field:"process.executable" value:"?:\Program Files*" field:"process.executable" value:"\Device\HarddiskVolume*\Program Files*"

Potential Injection from a LUA Script

#
Source
github.com/elastic/protections-artifacts

Identifies potential code injection from a LUA script interpreter. This may indicate an attempt to evade defenses.

MITRE ATT&CK Coverage

TacticTechniques
Stealth

Rule Body

[rule]
description = "Identifies potential code injection from a LUA script interpreter. This may indicate an attempt to evade defenses."
id = "88c2aeed-e5c1-4e0d-98d4-e22ff972e55b"
license = "Elastic License v2"
name = "Potential Injection from a LUA Script"
os_list = ["windows"]
version = "1.0.10"

query = '''
api where
  process.Ext.api.behaviors in ("shellcode", "allocate_shellcode", "execute_shellcode", "unbacked_rwx") and
  process.thread.Ext.call_stack_summary like ("*|luacom.dll*", "*|lua?.?.dll*", "*|lua??.dll*") and
  not process.executable :
               ("?:\\Windows\\System32\\cmd.exe",
                "C:\\Windows\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe",
                "?:\\Program Files\\dotnet\\dotnet.exe",
                "C:\\Program Files (x86)\\Steam\\steamapps\\common\\Balatro\\Balatro.exe",
                "C:\\Program Files (x86)\\ILLiad\\ILLiadClient.exe") and
  not process.thread.Ext.call_stack_final_user_module.protection_provenance like ("kernel", "Kernel|*") and
  not process.thread.Ext.call_stack_final_user_module.name in ("Kernel", "Unknown") and
  not process.thread.Ext.call_stack_final_user_module.hash.sha256 in
                                             ("423bde5692d39b68e38292439962804537e673aebf946c1cc12dcf4f34712939",
                                              "3b3558c408c57be332c9595624f6d49413fe0dd43d3d5fa4626041851f77216a") and
  not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info: "c:\\program files\\wireshark\\lua??.dll!*") and
  not (process.code_signature.trusted == true and process.code_signature.subject_name == "COJALI SL")
'''

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

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

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


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

[internal]
min_endpoint_version = "8.10.0"

Stages and Predicates

Stage 1: api

api where
  process.Ext.api.behaviors in ("shellcode", "allocate_shellcode", "execute_shellcode", "unbacked_rwx") and
  process.thread.Ext.call_stack_summary like ("*|luacom.dll*", "*|lua?.?.dll*", "*|lua??.dll*") and
  not process.executable :
               ("?:\\Windows\\System32\\cmd.exe",
                "C:\\Windows\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe",
                "?:\\Program Files\\dotnet\\dotnet.exe",
                "C:\\Program Files (x86)\\Steam\\steamapps\\common\\Balatro\\Balatro.exe",
                "C:\\Program Files (x86)\\ILLiad\\ILLiadClient.exe") and
  not process.thread.Ext.call_stack_final_user_module.protection_provenance like ("kernel", "Kernel|*") and
  not process.thread.Ext.call_stack_final_user_module.name in ("Kernel", "Unknown") and
  not process.thread.Ext.call_stack_final_user_module.hash.sha256 in
                                             ("423bde5692d39b68e38292439962804537e673aebf946c1cc12dcf4f34712939",
                                              "3b3558c408c57be332c9595624f6d49413fe0dd43d3d5fa4626041851f77216a") and
  not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info: "c:\\program files\\wireshark\\lua??.dll!*") and
  not (process.code_signature.trusted == true and process.code_signature.subject_name == "COJALI SL")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
process.Ext.api.behaviorsin
  • allocate_shellcode corpus 15 (elastic 15)
  • execute_shellcode corpus 10 (elastic 10)
  • shellcode corpus 15 (elastic 15)
  • unbacked_rwx corpus 2 (elastic 2)
field:"process.Ext.api.behaviors" kind:in
process.thread.Ext.call_stack_summarywildcard
  • *|lua?.?.dll*
  • *|lua??.dll*
  • *|luacom.dll*
field:"process.thread.Ext.call_stack_summary" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.code_signature.subject_nameeqCOJALI SLexcludes:process.code_signature.subject_name field:"process.code_signature.subject_name" value:"COJALI SL"
process.code_signature.trustedeqtrueexcludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true"
process.thread.Ext.call_stackarray_any(no value, null check)excludes:process.thread.Ext.call_stack
process.executableeq?:\Windows\System32\cmd.exe, C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe, ?:\Program Files\dotnet\dotnet.exe, C:\Program Files (x86)\Steam\steamapps\common\Balatro\Balatro.exe, C:\Program Files (x86)\ILLiad\ILLiadClient.exeexcludes:process.executable
process.thread.Ext.call_stack_final_user_module.hash.sha256in3b3558c408c57be332c9595624f6d49413fe0dd43d3d5fa4626041851f77216a, 423bde5692d39b68e38292439962804537e673aebf946c1cc12dcf4f34712939excludes:process.thread.Ext.call_stack_final_user_module.hash.sha256 field:"process.thread.Ext.call_stack_final_user_module.hash.sha256" value:"3b3558c408c57be332c9595624f6d49413fe0dd43d3d5fa4626041851f77216a" field:"process.thread.Ext.call_stack_final_user_module.hash.sha256" value:"423bde5692d39b68e38292439962804537e673aebf946c1cc12dcf4f34712939"
process.thread.Ext.call_stack_final_user_module.nameinKernel, Unknownexcludes:process.thread.Ext.call_stack_final_user_module.name field:"process.thread.Ext.call_stack_final_user_module.name" value:"Kernel" field:"process.thread.Ext.call_stack_final_user_module.name" value:"Unknown"
process.thread.Ext.call_stack_final_user_module.protection_provenancewildcardkernel, Kernel|*excludes:process.thread.Ext.call_stack_final_user_module.protection_provenance field:"process.thread.Ext.call_stack_final_user_module.protection_provenance" value:"kernel" field:"process.thread.Ext.call_stack_final_user_module.protection_provenance" value:"Kernel|*"

Potential Local Privilege Escalation via a Suspicious Descendant Process

#
Source
github.com/elastic/protections-artifacts

Detects a potential local privilege escalation from a suspicious descendant process. This rule checks for an exec event as uid=0 (root), as a descendant of a suspicious process execution by a non-root user from a user- or world-writeable directory. This may indicate the execution of a potential local privilege escalation exploit.

MITRE ATT&CK Coverage

TacticTechniques
Privilege Escalation

Rule Body

[rule]
description = """
Detects a potential local privilege escalation from a suspicious descendant process. This rule checks for an exec event
as uid=0 (root), as a descendant of a suspicious process execution by a non-root user from a user- or world-writeable
directory. This may indicate the execution of a potential local privilege escalation exploit.
"""
id = "2d5d9b4b-01ac-41c4-b5c2-6a9d1fe93aae"
license = "Elastic License v2"
name = "Potential Local Privilege Escalation via a Suspicious Descendant Process"
os_list = ["linux"]
version = "1.0.6"

query = '''
process where event.type == "start" and event.action == "exec" and process.interactive == true and
user.id == 0 and (
  process.parent.user.id >= 1000 or
  process.parent.user.name in (
    "apache", "www-data", "httpd", "nginx", "lighttpd", "tomcat", "tomcat8", "tomcat9", "ftp", "ftpuser", "ftpd"
  )
) and (
  process.parent.group.id >= 1000 or
  process.parent.group.name in (
    "apache", "www-data", "httpd", "nginx", "lighttpd", "tomcat", "tomcat8", "tomcat9", "ftp", "ftpuser", "ftpd"
  )
) and
not process.executable in ("/usr/bin/sudo", "/bin/sudo", "/tmp/newroot/newroot/newroot/usr/bin/sudo", "/tmp/newroot/usr/bin/sudo") and
(
  descendant of [
    process where event.type == "start" and event.action == "exec" and user.id != 0 and
    process.executable like (".*", "/tmp/*", "/dev/shm/*", "/var/tmp/*", "/home/*/*", "/run/user/*", "/var/run/user/*")
  ] or
  process.parent.executable like (".*", "/tmp/*", "/dev/shm/*", "/var/tmp/*", "/home/*/*", "/run/user/*", "/var/run/user/*") or
  process.executable like (".*", "/tmp/*", "/dev/shm/*", "/var/tmp/*", "/home/*/*", "/run/user/*", "/var/run/user/*")
) and
not (
  process.parent.executable like (
    "/home/*/.conda/envs/fmf_server_agent/bin/python*", "/home/*/.local/share/uv/python/cpython-*-linux-x86_64-gnu/bin/python*",
    "/home/*/.local/share/mise/installs/node/*/bin/node", "/usr/local/bin/tm_sandbox", "./merged/var/lib/containers/storage/overlay/*",
    "/home/*/.local/share/containers/storage/overlay/*", "/home/*/Downloads/*/balena-etcher", "/opt/brave.com/brave/brave", "/var/lib/snapd/snap/node/*/bin/node",
    "/home/linuxbrew/.linuxbrew/Cellar/*", "/home/*/.npm-global/lib/node_modules/@anthropic-ai/claude-code/bin/claude.exe",
    "/oracle/KG2/*/bin/oracle", "/home/*/.codex/*/bin/codex", "/home/*/.please/*/please", "/opt/microsoft/msedge/msedge",
    "/usr/local/bin/obsidian", "/home/*/.opencode/bin/opencode", "/usr/local/bin/cursor", "/usr/share/code/code", "/usr/share/codium/codium"
  ) or
  process.executable like (
    "/usr/bin/mount", "/usr/bin/fusermount3", "/tmp/newroot/usr/bin/sudo", "/usr/bin/nvidia-modprobe", "/usr/bin/fusermount",
    "/snap/core/*/usr/lib/snapd/snap-confine", "/usr/bin/newuidmap", "/usr/bin/newgidmap", "/opt/google/chrome-beta/chrome-sandbox",
    "/usr/libexec/singularity/bin/starter-suid", "/usr/lib/cargo/bin/sudo", "/run/user/*/.bubblewrap/*", "/tmp/newroot/newroot/usr/bin/sudo",
    "/tmp/newroot/usr/bin/su", "/tmp/newroot/usr/bin/fusermount3", "/tmp/newroot/usr/bin/fusermount", "/usr/bin/vmware-user-suid-wrapper",
    "/tmp/newroot/usr/lib/polkit-1/polkit-agent-helper-1", "/usr/bin/ping", "/bin/crontab", "/usr/bin/tcpdump", "/tmp/newroot/usr/sbin/grub2-set-bootflag",
    "/tmp/newroot/newroot/newroot/usr/lib/xorg/Xorg.wrap", "/home/*/chrome-sandbox", "/usr/lib/polkit-1/polkit-agent-helper-1", "/home/*/sqllib/adm/db2syscr",
    "/home/*/sqllib/adm/db2stop", "/home/*/sqllib/adm/db2start", "/usr/lib/xorg/Xorg.wrap", "/usr/local/sbin/uid_gid_mapping",
    "/home/*/.crc/bin/crc-admin-helper-linux-amd64", "/usr/bin/sg", "/usr/bin/crontab", "/sas/*/bin/elssrv", "/usr/lpp/mmfs/bin/tslsquota",
    "/usr/lib/snapd/snap-confine", "/u01/*/client/scheduler/execution_agent/bin/jssu", "./merged/home/*/.local/share/containers/storage/overlay/*",
    "/tmp/newroot/usr/share/antigravity/chrome-sandbox", "/usr/lib/x86_64-linux-gnu/singularity/bin/starter-suid", "/home/*/cdunix/ndm/bin/ndmumgr",
    "/tmp/newroot/usr/lib/xorg/Xorg.wrap", "/usr/bin/apt-get", "/usr/bin/install", "/usr/bin/pkexec", "/usr/bin/containerlab", "/usr/bin/kmod"
  ) or
  process.parent.command_line like "*/home/*/.claude/shell-snapshots/snapshot-*" or
  process.command_line == "newgrp docker" or
  process.parent.args like ("/home/*/.vscode-server/cli/servers/Stable-*", "/home/*/.cursor-server/bin/*", "pkexec*") or
  (process.name == "pkexec" and process.args in ("apt-get", "/usr/bin/rpm")) or
  (process.parent.executable like "/home/*/bin/san" and process.executable == "/bin/mount") or
  (process.parent.executable like "/tmp/newroot/*" and process.executable like "/tmp/newroot/*") or
  (process.parent.executable == "/usr/bin/i3lock" and process.executable == "/usr/bin/unix_chkpwd") or
  (
    process.executable == "/bin/fusermount" and
    process.parent.executable like ("/home/*/.local/bin/nvim", "/home/*/bin/Obsidian-*.AppImage")
  ) or
  (
    process.executable == "/opt/google/chrome/chrome-sandbox" and
    process.parent.executable == "/opt/google/chrome/chrome"
  ) or
  (
    process.executable == "/usr/share/cursor/chrome-sandbox" and
    process.command_line == "/usr/share/cursor/chrome-sandbox /usr/share/cursor/cursor --type=zygote"
  ) or
  (
    process.command_line == "netstat -ant" and
    process.parent.command_line == "/home/uniagent/bin/start.sh agentmain"
  ) or
  process.parent.executable like "*/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex" or
  process.parent.command_line like (
    "cursor --force --install-extension anthropic.claude-code",
    "*/codium * /home/*/.claude/skills/*"
  )
)
'''

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

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1068"
name = "Exploitation for Privilege Escalation"
reference = "https://attack.mitre.org/techniques/T1068/"


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

[internal]
min_endpoint_version = "8.2.0"

Stages and Predicates

Stage 1: process

process where event.type == "start" and event.action == "exec" and process.interactive == true and
user.id == 0 and (
  process.parent.user.id >= 1000 or
  process.parent.user.name in (
    "apache", "www-data", "httpd", "nginx", "lighttpd", "tomcat", "tomcat8", "tomcat9", "ftp", "ftpuser", "ftpd"
  )
) and (
  process.parent.group.id >= 1000 or
  process.parent.group.name in (
    "apache", "www-data", "httpd", "nginx", "lighttpd", "tomcat", "tomcat8", "tomcat9", "ftp", "ftpuser", "ftpd"
  )
) and
not process.executable in ("/usr/bin/sudo", "/bin/sudo", "/tmp/newroot/newroot/newroot/usr/bin/sudo", "/tmp/newroot/usr/bin/sudo") and
(
  descendant of [
    process where event.type == "start" and event.action == "exec" and user.id != 0 and
    process.executable like (".*", "/tmp/*", "/dev/shm/*", "/var/tmp/*", "/home/*/*", "/run/user/*", "/var/run/user/*")
  ] or
  process.parent.executable like (".*", "/tmp/*", "/dev/shm/*", "/var/tmp/*", "/home/*/*", "/run/user/*", "/var/run/user/*") or
  process.executable like (".*", "/tmp/*", "/dev/shm/*", "/var/tmp/*", "/home/*/*", "/run/user/*", "/var/run/user/*")
) and
not (
  process.parent.executable like (
    "/home/*/.conda/envs/fmf_server_agent/bin/python*", "/home/*/.local/share/uv/python/cpython-*-linux-x86_64-gnu/bin/python*",
    "/home/*/.local/share/mise/installs/node/*/bin/node", "/usr/local/bin/tm_sandbox", "./merged/var/lib/containers/storage/overlay/*",
    "/home/*/.local/share/containers/storage/overlay/*", "/home/*/Downloads/*/balena-etcher", "/opt/brave.com/brave/brave", "/var/lib/snapd/snap/node/*/bin/node",
    "/home/linuxbrew/.linuxbrew/Cellar/*", "/home/*/.npm-global/lib/node_modules/@anthropic-ai/claude-code/bin/claude.exe",
    "/oracle/KG2/*/bin/oracle", "/home/*/.codex/*/bin/codex", "/home/*/.please/*/please", "/opt/microsoft/msedge/msedge",
    "/usr/local/bin/obsidian", "/home/*/.opencode/bin/opencode", "/usr/local/bin/cursor", "/usr/share/code/code", "/usr/share/codium/codium"
  ) or
  process.executable like (
    "/usr/bin/mount", "/usr/bin/fusermount3", "/tmp/newroot/usr/bin/sudo", "/usr/bin/nvidia-modprobe", "/usr/bin/fusermount",
    "/snap/core/*/usr/lib/snapd/snap-confine", "/usr/bin/newuidmap", "/usr/bin/newgidmap", "/opt/google/chrome-beta/chrome-sandbox",
    "/usr/libexec/singularity/bin/starter-suid", "/usr/lib/cargo/bin/sudo", "/run/user/*/.bubblewrap/*", "/tmp/newroot/newroot/usr/bin/sudo",
    "/tmp/newroot/usr/bin/su", "/tmp/newroot/usr/bin/fusermount3", "/tmp/newroot/usr/bin/fusermount", "/usr/bin/vmware-user-suid-wrapper",
    "/tmp/newroot/usr/lib/polkit-1/polkit-agent-helper-1", "/usr/bin/ping", "/bin/crontab", "/usr/bin/tcpdump", "/tmp/newroot/usr/sbin/grub2-set-bootflag",
    "/tmp/newroot/newroot/newroot/usr/lib/xorg/Xorg.wrap", "/home/*/chrome-sandbox", "/usr/lib/polkit-1/polkit-agent-helper-1", "/home/*/sqllib/adm/db2syscr",
    "/home/*/sqllib/adm/db2stop", "/home/*/sqllib/adm/db2start", "/usr/lib/xorg/Xorg.wrap", "/usr/local/sbin/uid_gid_mapping",
    "/home/*/.crc/bin/crc-admin-helper-linux-amd64", "/usr/bin/sg", "/usr/bin/crontab", "/sas/*/bin/elssrv", "/usr/lpp/mmfs/bin/tslsquota",
    "/usr/lib/snapd/snap-confine", "/u01/*/client/scheduler/execution_agent/bin/jssu", "./merged/home/*/.local/share/containers/storage/overlay/*",
    "/tmp/newroot/usr/share/antigravity/chrome-sandbox", "/usr/lib/x86_64-linux-gnu/singularity/bin/starter-suid", "/home/*/cdunix/ndm/bin/ndmumgr",
    "/tmp/newroot/usr/lib/xorg/Xorg.wrap", "/usr/bin/apt-get", "/usr/bin/install", "/usr/bin/pkexec", "/usr/bin/containerlab", "/usr/bin/kmod"
  ) or
  process.parent.command_line like "*/home/*/.claude/shell-snapshots/snapshot-*" or
  process.command_line == "newgrp docker" or
  process.parent.args like ("/home/*/.vscode-server/cli/servers/Stable-*", "/home/*/.cursor-server/bin/*", "pkexec*") or
  (process.name == "pkexec" and process.args in ("apt-get", "/usr/bin/rpm")) or
  (process.parent.executable like "/home/*/bin/san" and process.executable == "/bin/mount") or
  (process.parent.executable like "/tmp/newroot/*" and process.executable like "/tmp/newroot/*") or
  (process.parent.executable == "/usr/bin/i3lock" and process.executable == "/usr/bin/unix_chkpwd") or
  (
    process.executable == "/bin/fusermount" and
    process.parent.executable like ("/home/*/.local/bin/nvim", "/home/*/bin/Obsidian-*.AppImage")
  ) or
  (
    process.executable == "/opt/google/chrome/chrome-sandbox" and
    process.parent.executable == "/opt/google/chrome/chrome"
  ) or
  (
    process.executable == "/usr/share/cursor/chrome-sandbox" and
    process.command_line == "/usr/share/cursor/chrome-sandbox /usr/share/cursor/cursor --type=zygote"
  ) or
  (
    process.command_line == "netstat -ant" and
    process.parent.command_line == "/home/uniagent/bin/start.sh agentmain"
  ) or
  process.parent.executable like "*/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex" or
  process.parent.command_line like (
    "cursor --force --install-extension anthropic.claude-code",
    "*/codium * /home/*/.claude/skills/*"
  )
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • exec
field:"EventType" kind:eq value:"exec"
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
process.executablewildcard
  • .*
  • /dev/shm/*
  • /home/*/*
  • /run/user/*
  • /tmp/*
  • /var/run/user/*
  • /var/tmp/*
field:"Image" kind:wildcard
process.interactiveeq
  • true transforms: boolean
field:"process.interactive" kind:eq value:"true"
process.parent.executablewildcard
  • .*
  • /dev/shm/*
  • /home/*/*
  • /run/user/*
  • /tmp/*
  • /var/run/user/*
  • /var/tmp/*
field:"ParentImage" kind:wildcard
process.parent.group.idge
  • 1000 transforms: number
field:"process.parent.group.id" kind:ge value:"1000"
process.parent.group.namein
  • apache
  • ftp
  • ftpd
  • ftpuser
  • httpd
  • lighttpd
  • nginx
  • tomcat
  • tomcat8
  • tomcat9
  • www-data
field:"process.parent.group.name" kind:in
process.parent.user.idge
  • 1000 transforms: number
field:"process.parent.user.id" kind:ge value:"1000"
process.parent.user.namein
  • apache
  • ftp
  • ftpd
  • ftpuser
  • httpd
  • lighttpd
  • nginx
  • tomcat
  • tomcat8
  • tomcat9
  • www-data
field:"process.parent.user.name" kind:in
user.ideq
  • 0 transforms: number
field:"user.id" kind:eq value:"0"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argsin/usr/bin/rpm, apt-getexcludes:process.args field:"process.args" value:"/usr/bin/rpm" field:"process.args" value:"apt-get"
process.nameeqpkexecexcludes:process.name field:"process.name" value:"pkexec"
process.command_lineeq/usr/share/cursor/chrome-sandbox /usr/share/cursor/cursor --type=zygoteexcludes:process.command_line field:"process.command_line" value:"/usr/share/cursor/chrome-sandbox /usr/share/cursor/cursor --type=zygote"
process.executableeq/usr/share/cursor/chrome-sandboxexcludes:process.executable field:"process.executable" value:"/usr/share/cursor/chrome-sandbox"
process.command_lineeqnetstat -antexcludes:process.command_line field:"process.command_line" value:"netstat -ant"
process.parent.command_lineeq/home/uniagent/bin/start.sh agentmainexcludes:process.parent.command_line field:"process.parent.command_line" value:"/home/uniagent/bin/start.sh agentmain"
process.executableeq/bin/fusermountexcludes:process.executable field:"process.executable" value:"/bin/fusermount"
process.parent.executablewildcard/home/*/.local/bin/nvim, /home/*/bin/Obsidian-*.AppImageexcludes:process.parent.executable field:"process.parent.executable" value:"/home/*/.local/bin/nvim" field:"process.parent.executable" value:"/home/*/bin/Obsidian-*.AppImage"
process.executableeq/bin/mountexcludes:process.executable field:"process.executable" value:"/bin/mount"
process.parent.executablewildcard/home/*/bin/sanexcludes:process.parent.executable field:"process.parent.executable" value:"/home/*/bin/san"
process.executableeq/opt/google/chrome/chrome-sandboxexcludes:process.executable field:"process.executable" value:"/opt/google/chrome/chrome-sandbox"
process.parent.executableeq/opt/google/chrome/chromeexcludes:process.parent.executable field:"process.parent.executable" value:"/opt/google/chrome/chrome"
process.executableeq/usr/bin/unix_chkpwdexcludes:process.executable field:"process.executable" value:"/usr/bin/unix_chkpwd"
process.parent.executableeq/usr/bin/i3lockexcludes:process.parent.executable field:"process.parent.executable" value:"/usr/bin/i3lock"
process.executablestarts_with/tmp/newroot/excludes:process.executable field:"process.executable" value:"/tmp/newroot/"
process.parent.executablestarts_with/tmp/newroot/excludes:process.parent.executable field:"process.parent.executable" value:"/tmp/newroot/"
process.command_lineeqnewgrp dockerexcludes:process.command_line field:"process.command_line" value:"newgrp docker"
process.executablewildcard/usr/bin/mount, /usr/bin/fusermount3, /tmp/newroot/usr/bin/sudo, /usr/bin/nvidia-modprobe, /usr/bin/fusermount, /snap/core/*/usr/lib/snapd/snap-confine, /usr/bin/newuidmap, /usr/bin/newgidmap, /opt/google/chrome-beta/chrome-sandbox, /usr/libexec/singularity/bin/starter-suid, /usr/lib/cargo/bin/sudo, /run/user/*/.bubblewrap/*, /tmp/newroot/newroot/usr/bin/sudo, /tmp/newroot/usr/bin/su, /tmp/newroot/usr/bin/fusermount3, /tmp/newroot/usr/bin/fusermount, /usr/bin/vmware-user-suid-wrapper, /tmp/newroot/usr/lib/polkit-1/polkit-agent-helper-1, /usr/bin/ping, /bin/crontab, /usr/bin/tcpdump, /tmp/newroot/usr/sbin/grub2-set-bootflag, /tmp/newroot/newroot/newroot/usr/lib/xorg/Xorg.wrap, /home/*/chrome-sandbox, /usr/lib/polkit-1/polkit-agent-helper-1, /home/*/sqllib/adm/db2syscr, /home/*/sqllib/adm/db2stop, /home/*/sqllib/adm/db2start, /usr/lib/xorg/Xorg.wrap, /usr/local/sbin/uid_gid_mapping, /home/*/.crc/bin/crc-admin-helper-linux-amd64, /usr/bin/sg, /usr/bin/crontab, /sas/*/bin/elssrv, /usr/lpp/mmfs/bin/tslsquota, /usr/lib/snapd/snap-confine, /u01/*/client/scheduler/execution_agent/bin/jssu, ./merged/home/*/.local/share/containers/storage/overlay/*, /tmp/newroot/usr/share/antigravity/chrome-sandbox, /usr/lib/x86_64-linux-gnu/singularity/bin/starter-suid, /home/*/cdunix/ndm/bin/ndmumgr, /tmp/newroot/usr/lib/xorg/Xorg.wrap, /usr/bin/apt-get, /usr/bin/install, /usr/bin/pkexec, /usr/bin/containerlab, /usr/bin/kmodexcludes:process.executable
process.parent.argswildcard/home/*/.vscode-server/cli/servers/Stable-*, /home/*/.cursor-server/bin/*, pkexec*excludes:process.parent.args field:"process.parent.args" value:"/home/*/.vscode-server/cli/servers/Stable-*" field:"process.parent.args" value:"/home/*/.cursor-server/bin/*" field:"process.parent.args" value:"pkexec*"
process.parent.command_linewildcard*/home/*/.claude/shell-snapshots/snapshot-*excludes:process.parent.command_line field:"process.parent.command_line" value:"*/home/*/.claude/shell-snapshots/snapshot-*"
process.parent.command_linewildcardcursor --force --install-extension anthropic.claude-code, */codium * /home/*/.claude/skills/*excludes:process.parent.command_line field:"process.parent.command_line" value:"cursor --force --install-extension anthropic.claude-code" field:"process.parent.command_line" value:"*/codium * /home/*/.claude/skills/*"
process.parent.executableends_with/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codexexcludes:process.parent.executable field:"process.parent.executable" value:"/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex"
process.parent.executablewildcard/home/*/.conda/envs/fmf_server_agent/bin/python*, /home/*/.local/share/uv/python/cpython-*-linux-x86_64-gnu/bin/python*, /home/*/.local/share/mise/installs/node/*/bin/node, /usr/local/bin/tm_sandbox, ./merged/var/lib/containers/storage/overlay/*, /home/*/.local/share/containers/storage/overlay/*, /home/*/Downloads/*/balena-etcher, /opt/brave.com/brave/brave, /var/lib/snapd/snap/node/*/bin/node, /home/linuxbrew/.linuxbrew/Cellar/*, /home/*/.npm-global/lib/node_modules/@anthropic-ai/claude-code/bin/claude.exe, /oracle/KG2/*/bin/oracle, /home/*/.codex/*/bin/codex, /home/*/.please/*/please, /opt/microsoft/msedge/msedge, /usr/local/bin/obsidian, /home/*/.opencode/bin/opencode, /usr/local/bin/cursor, /usr/share/code/code, /usr/share/codium/codiumexcludes:process.parent.executable
process.executablein/bin/sudo, /tmp/newroot/newroot/newroot/usr/bin/sudo, /tmp/newroot/usr/bin/sudo, /usr/bin/sudoexcludes:process.executable

Remote File Execution via MSIEXEC

#
Time window
1m
Source
github.com/elastic/protections-artifacts

Identifies the execution of the built-in Windows Installer, MSIEXEC, with a url in the command line. Adversaries may abuse msiexec.exe to launch local or network accessible MSI files.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the execution of the built-in Windows Installer, MSIEXEC, with a url in the command line. Adversaries may
abuse msiexec.exe to launch local or network accessible MSI files.
"""
id = "8ba98e28-d83e-451e-8df7-f0964f7e69b6"
license = "Elastic License v2"
name = "Remote File Execution via MSIEXEC"
os_list = ["windows"]
reference = [
    "https://lolbas-project.github.io/lolbas/Binaries/Msiexec/",
    "https://lolbas-project.github.io/lolbas/OtherMSBinaries/Devinit/",
    "https://www.elastic.co/security-labs/spring-cleaning-with-latrodectus",
    "https://www.guardicore.com/labs/purple-fox-rootkit-now-propagates-as-a-worm/",
]
version = "1.0.47"

query = '''
sequence with maxspan=1m
[process where event.action == "start" and
 (
 ((process.pe.original_file_name : "devinit.dll" or process.name : "devinit.exe") and
   process.args : "msi-install" and process.command_line : "*http*") or

 (process.name : "msiexec.exe" and process.args :("/i", "-i") and
  process.args : ("/q", "-q", "/qn", "-qn") and process.args : "\\\\*@*\\*.msi") or

 (process.name : "msiexec.exe" and process.args : ("-PaCKagE", "/PaCKagE", "-fv") and
  process.args : ("/qn", "-qn", "-q", "/q", "/quiet") and process.command_line : "*http*") or

 (process.name : "msiexec.exe" and process.args :("/i", "-i") and
  process.args : ("/qn", "-qn", "-q", "/q") and
  process.command_line : ("*transforms*http:*", "*transforms*https:*", "*http*INSTALLDIR=%LOCALAPPDATA%*") and
  not process.parent.executable : ("D:\\Visma\\Install\\FDN\\PIN\\Client\\Base\\SW\\24200\\PublicInstallerNextGen.exe",
                                   "C:\\Program Files (x86)\\ManageEngine\\UEMS_Agent\\Updates\\AgentUpgrader.exe"))  or

 (process.name : "powershell.exe" and process.command_line : "*WindowsInstaller*" and
  process.command_line : "*http*" and process.command_line : "*InstallProduct*")  or

 (process.name : "msiexec.exe" and
  process.parent.name : ("explorer.exe", "python.exe") and process.args : ("/i", "-i") and
  process.command_line : "*http*") or

 ((process.pe.original_file_name : "msiexec.exe" or process.name : "msiexec.exe") and
  process.command_line : "*http*" and process.args_count <= 5 and
  (
   (process.args : ("/i", "-i") and process.args : ("/q", "/quiet", "/qn", "-q", "-quiet", "-qn", "-Q+")) or
   process.args : ("*-Q-I*", "*-I-Q*", "*/q-i*", "*-q/i*", "*/q/i*") or
   (process.parent.name : "cmd.exe" and process.parent.args : "/v/r*")
   )
    and
  not descendant of
       [process where event.action == "start" and process.name : "*setup*" and process.code_signature.trusted == true] and
  not process.Ext.token.integrity_level_name == "system")
) and
not process.args :
          ("https://download.microsoft.com/download/*.msi",
           "APIURL=http*",
           "TRANSFORMS=C:\\Program Files (x86)\\ManageEngine\\UEMS_Agent\\\\Updates\\UEMSAgent.mst",
           "SERVERNAME=*.manageengine.com", 
           "C:\\Program Files (x86)\\ManageEngine\\UEMS_DistributionServer\\\\Updates\\UEMSDistributionServer.msi",
           "https://awscli.amazonaws.com/AWSCLIV2.msi",
           "SERVERURL=https://*.apparmor.com",
           "INSTALLARGS=--url=https://*.fleet.us-east-2.aws.elastic-cloud.com:443*",
           "https://cdn.zabbix.com/zabbix/binaries/stable/*.msi",
           "INSTALLARGS=--url=https://*--enrollment-token=*",
           "C:\\WINDOWS\\_ScriptingFramework\\Logs\\Software\\*.log",
           "?:\\*\\http*.msi",
           "C:\\WINDOWS\\ccmcache\\*.msi",
           "C:\\Windows\\Temp\\*.msi",
           "\\\\*\\NETLOGON\\*.msi") and
not process.parent.executable :
                     ("C:\\Program Files (x86)\\Novell\\ZENworks\\bin\\ZenworksWindowsService.exe",
                      "C:\\Program Files (x86)\\ManageEngine\\UEMS_Agent\\Updates\\AgentUpgrader.exe",
                      "C:\\Program Files (x86)\\FastTrack Software\\Admin By Request\\AdminByRequest.exe") and
not process.executable : "C:\\Program Files (x86)\\AMS Services\\TransactNOW\\OALaunch.exe"
]
[process where event.action in ("start", "already_running") and
 (
  (process.name : "msiexec.exe" and process.args == "/V") or

  (process.parent.name : "msiexec.exe" and process.parent.args == "/V")
  )]
'''

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

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

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

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"
[[threat.technique.subtechnique]]
id = "T1218.007"
name = "Msiexec"
reference = "https://attack.mitre.org/techniques/T1218/007/"



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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Stage 1: process

[process where event.action == "start" and
 (
 ((process.pe.original_file_name : "devinit.dll" or process.name : "devinit.exe") and
   process.args : "msi-install" and process.command_line : "*http*") or

 (process.name : "msiexec.exe" and process.args :("/i", "-i") and
  process.args : ("/q", "-q", "/qn", "-qn") and process.args : "\\\\*@*\\*.msi") or

 (process.name : "msiexec.exe" and process.args : ("-PaCKagE", "/PaCKagE", "-fv") and
  process.args : ("/qn", "-qn", "-q", "/q", "/quiet") and process.command_line : "*http*") or

 (process.name : "msiexec.exe" and process.args :("/i", "-i") and
  process.args : ("/qn", "-qn", "-q", "/q") and
  process.command_line : ("*transforms*http:*", "*transforms*https:*", "*http*INSTALLDIR=%LOCALAPPDATA%*") and
  not process.parent.executable : ("D:\\Visma\\Install\\FDN\\PIN\\Client\\Base\\SW\\24200\\PublicInstallerNextGen.exe",
                                   "C:\\Program Files (x86)\\ManageEngine\\UEMS_Agent\\Updates\\AgentUpgrader.exe"))  or

 (process.name : "powershell.exe" and process.command_line : "*WindowsInstaller*" and
  process.command_line : "*http*" and process.command_line : "*InstallProduct*")  or

 (process.name : "msiexec.exe" and
  process.parent.name : ("explorer.exe", "python.exe") and process.args : ("/i", "-i") and
  process.command_line : "*http*") or

 ((process.pe.original_file_name : "msiexec.exe" or process.name : "msiexec.exe") and
  process.command_line : "*http*" and process.args_count <= 5 and
  (
   (process.args : ("/i", "-i") and process.args : ("/q", "/quiet", "/qn", "-q", "-quiet", "-qn", "-Q+")) or
   process.args : ("*-Q-I*", "*-I-Q*", "*/q-i*", "*-q/i*", "*/q/i*") or
   (process.parent.name : "cmd.exe" and process.parent.args : "/v/r*")
   )
    and
  not descendant of
       [process where event.action == "start" and process.name : "*setup*" and process.code_signature.trusted == true] and
  not process.Ext.token.integrity_level_name == "system")
) and
not process.args :
          ("https://download.microsoft.com/download/*.msi",
           "APIURL=http*",
           "TRANSFORMS=C:\\Program Files (x86)\\ManageEngine\\UEMS_Agent\\\\Updates\\UEMSAgent.mst",
           "SERVERNAME=*.manageengine.com", 
           "C:\\Program Files (x86)\\ManageEngine\\UEMS_DistributionServer\\\\Updates\\UEMSDistributionServer.msi",
           "https://awscli.amazonaws.com/AWSCLIV2.msi",
           "SERVERURL=https://*.apparmor.com",
           "INSTALLARGS=--url=https://*.fleet.us-east-2.aws.elastic-cloud.com:443*",
           "https://cdn.zabbix.com/zabbix/binaries/stable/*.msi",
           "INSTALLARGS=--url=https://*--enrollment-token=*",
           "C:\\WINDOWS\\_ScriptingFramework\\Logs\\Software\\*.log",
           "?:\\*\\http*.msi",
           "C:\\WINDOWS\\ccmcache\\*.msi",
           "C:\\Windows\\Temp\\*.msi",
           "\\\\*\\NETLOGON\\*.msi") and
not process.parent.executable :
                     ("C:\\Program Files (x86)\\Novell\\ZENworks\\bin\\ZenworksWindowsService.exe",
                      "C:\\Program Files (x86)\\ManageEngine\\UEMS_Agent\\Updates\\AgentUpgrader.exe",
                      "C:\\Program Files (x86)\\FastTrack Software\\Admin By Request\\AdminByRequest.exe") and
not process.executable : "C:\\Program Files (x86)\\AMS Services\\TransactNOW\\OALaunch.exe"
]

Stage 2: process

[process where event.action in ("start", "already_running") and
 (
  (process.name : "msiexec.exe" and process.args == "/V") or

  (process.parent.name : "msiexec.exe" and process.parent.args == "/V")
  )]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq value:"start"
event.actionin
  • already_running corpus 3 (elastic 3)
  • start corpus 157 (elastic 157)
field:"EventType" kind:in
process.argseq
  • /V corpus 2 (elastic 2)
field:"process.args" kind:eq value:"/V"
process.argswildcard
  • *-I-Q*
  • *-Q-I*
  • *-q/i*
  • */q-i*
  • */q/i*
  • -PaCKagE
  • -Q+ corpus 2 (elastic 2)
  • -fv
  • -i corpus 8 (elastic 8)
  • -q corpus 4 (elastic 4)
  • -qn corpus 4 (elastic 4)
  • -quiet corpus 2 (elastic 2)
  • /PaCKagE
  • /i corpus 4 (elastic 4)
  • /q corpus 7 (elastic 7)
  • /qn corpus 4 (elastic 4)
  • /quiet corpus 5 (elastic 5)
  • \\*@*\*.msi
  • msi-install
field:"process.args" kind:wildcard
process.args_countle
  • 5 transforms: number corpus 3 (elastic 3)
field:"process.args_count" kind:le value:"5"
process.command_linewildcard
  • *InstallProduct*
  • *WindowsInstaller*
  • *http* corpus 45 (sigma 34, elastic 10, splunk 1)
  • *http*INSTALLDIR=%LOCALAPPDATA%*
  • *transforms*http:*
  • *transforms*https:*
field:"CommandLine" kind:wildcard
process.namewildcard
  • devinit.exe
  • msiexec.exe corpus 45 (elastic 40, splunk 5)
  • powershell.exe corpus 187 (elastic 140, splunk 44, kusto 3)
field:"process_basename" kind:wildcard
process.parent.argseq
  • /V corpus 2 (elastic 2)
field:"process.parent.args" kind:eq value:"/V"
process.parent.argswildcard
  • /v/r*
field:"process.parent.args" kind:wildcard value:"/v/r*"
process.parent.namewildcard
  • cmd.exe corpus 37 (elastic 32, splunk 4, kusto 1)
  • explorer.exe corpus 50 (elastic 50)
  • msiexec.exe corpus 18 (elastic 14, splunk 3, kusto 1)
  • python.exe corpus 4 (elastic 4)
field:"parent_process_basename" kind:wildcard
process.pe.original_file_namewildcard
  • devinit.dll corpus 2 (elastic 2)
  • msiexec.exe corpus 18 (elastic 9, sigma 5, splunk 4)
field:"OriginalFileName" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argswildcardhttps://download.microsoft.com/download/*.msi, APIURL=http*, TRANSFORMS=C:\Program Files (x86)\ManageEngine\UEMS_Agent\\Updates\UEMSAgent.mst, SERVERNAME=*.manageengine.com, C:\Program Files (x86)\ManageEngine\UEMS_DistributionServer\\Updates\UEMSDistributionServer.msi, https://awscli.amazonaws.com/AWSCLIV2.msi, SERVERURL=https://*.apparmor.com, INSTALLARGS=--url=https://*.fleet.us-east-2.aws.elastic-cloud.com:443*, https://cdn.zabbix.com/zabbix/binaries/stable/*.msi, INSTALLARGS=--url=https://*--enrollment-token=*, C:\WINDOWS\_ScriptingFramework\Logs\Software\*.log, ?:\*\http*.msi, C:\WINDOWS\ccmcache\*.msi, C:\Windows\Temp\*.msi, \\*\NETLOGON\*.msiexcludes:process.args
process.executableeqC:\Program Files (x86)\AMS Services\TransactNOW\OALaunch.exeexcludes:process.executable field:"process.executable" value:"C:\Program Files (x86)\AMS Services\TransactNOW\OALaunch.exe"
process.parent.executableeqC:\Program Files (x86)\Novell\ZENworks\bin\ZenworksWindowsService.exe, C:\Program Files (x86)\ManageEngine\UEMS_Agent\Updates\AgentUpgrader.exe, C:\Program Files (x86)\FastTrack Software\Admin By Request\AdminByRequest.exeexcludes:process.parent.executable field:"process.parent.executable" value:"C:\Program Files (x86)\Novell\ZENworks\bin\ZenworksWindowsService.exe" field:"process.parent.executable" value:"C:\Program Files (x86)\ManageEngine\UEMS_Agent\Updates\AgentUpgrader.exe" field:"process.parent.executable" value:"C:\Program Files (x86)\FastTrack Software\Admin By Request\AdminByRequest.exe"

Runuser Executed via Suspicious Parent

#
Source
github.com/elastic/protections-artifacts

Identifies the execution of the runuser command via a suspicious parent process. This may be used by malicious actors to gain access to a user's account without requiring the user to enter their password, after collecting the user's password, potentially via a social engineering attack.

MITRE ATT&CK Coverage

TacticTechniques
Credential Access

Rule Body

[rule]
description = """
Identifies the execution of the runuser command via a suspicious parent process. This may be used by malicious actors to
gain access to a user's account without requiring the user to enter their password, after collecting the user's
password, potentially via a social engineering attack.
"""
id = "5e30b945-8059-4086-979e-e440c5304174"
license = "Elastic License v2"
name = "Runuser Executed via Suspicious Parent"
os_list = ["linux"]
reference = ["https://www.wiz.io/blog/threat-actors-target-crypto-orgs"]
version = "1.0.2"

query = '''
process where event.type == "start" and event.action == "exec" and process.name == "runuser" and
process.parent.executable like ("/tmp/*", "/var/tmp/*", "/dev/shm/*", "/run/user/*", "/var/run/user/*", "/home/*/*", "/root/*") and
not (
  process.parent.executable like (
    "/home/*/.local/share/uv/python/cpython-*-linux-x86_64-gnu/bin/python3*", "/tmp/newroot/var/lib/dpkg/info/*.postinst",
    "/root/.codex/packages/standalone/releases/*-x86_64-unknown-linux-musl/bin/codex", "/tmp/newroot/usr/sbin/akmods",
    "/root/.gxsetup/cvpkgadd/install"
  ) or
  process.parent.command_line == "/bin/bash /root/startup.sh"
)
'''

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

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

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



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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Stage 1: process

process where event.type == "start" and event.action == "exec" and process.name == "runuser" and
process.parent.executable like ("/tmp/*", "/var/tmp/*", "/dev/shm/*", "/run/user/*", "/var/run/user/*", "/home/*/*", "/root/*") and
not (
  process.parent.executable like (
    "/home/*/.local/share/uv/python/cpython-*-linux-x86_64-gnu/bin/python3*", "/tmp/newroot/var/lib/dpkg/info/*.postinst",
    "/root/.codex/packages/standalone/releases/*-x86_64-unknown-linux-musl/bin/codex", "/tmp/newroot/usr/sbin/akmods",
    "/root/.gxsetup/cvpkgadd/install"
  ) or
  process.parent.command_line == "/bin/bash /root/startup.sh"
)

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.parent.command_lineeq/bin/bash /root/startup.shexcludes:process.parent.command_line field:"process.parent.command_line" value:"/bin/bash /root/startup.sh"
process.parent.executablewildcard/home/*/.local/share/uv/python/cpython-*-linux-x86_64-gnu/bin/python3*, /tmp/newroot/var/lib/dpkg/info/*.postinst, /root/.codex/packages/standalone/releases/*-x86_64-unknown-linux-musl/bin/codex, /tmp/newroot/usr/sbin/akmods, /root/.gxsetup/cvpkgadd/installexcludes:process.parent.executable

Shell Command Piped to Osascript via Shell Script

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

Detects when shell commands are piped to osascript for execution. This technique can be used by adversaries to execute AppleScript commands indirectly through shell scripts.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[rule]
description = """
Detects when shell commands are piped to osascript for execution. This technique can be used by adversaries to execute
AppleScript commands indirectly through shell scripts.
"""
id = "2b6eac2a-c533-463c-bcbb-098d40fe3854"
license = "Elastic License v2"
name = "Shell Command Piped to Osascript via Shell Script"
os_list = ["macos"]
version = "1.0.4"

query = '''
sequence with maxspan = 10s
[process where event.type == "start" and event.action == "exec" and process.parent.name in ("bash", "sh", "zsh") and process.name == "osascript" and process.args_count == 1] by process.entity_id
[process where event.type == "start" and event.action == "exec" and process.name in ("bash", "sh", "zsh") and process.args == "-c"] by process.parent.entity_id
'''

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

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

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

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

[internal]
min_endpoint_version = "8.16.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: process

[process where event.type == "start" and event.action == "exec" and process.parent.name in ("bash", "sh", "zsh") and process.name == "osascript" and process.args_count == 1] by process.entity_id

Stage 2: process

[process where event.type == "start" and event.action == "exec" and process.name in ("bash", "sh", "zsh") and process.args == "-c"] by process.parent.entity_id

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.argseq
  • -c corpus 91 (elastic 91)
field:"process.args" kind:eq value:"-c"
process.args_counteq
  • 1 transforms: number corpus 50 (elastic 50)
field:"process.args_count" kind:eq value:"1"
process.nameeq
  • osascript corpus 41 (elastic 41)
field:"process_basename" kind:eq value:"osascript"
process.namein
  • bash corpus 181 (elastic 181)
  • sh corpus 180 (elastic 180)
  • zsh corpus 180 (elastic 180)
field:"process_basename" kind:in
process.parent.namein
  • bash corpus 60 (elastic 60)
  • sh corpus 60 (elastic 60)
  • zsh corpus 60 (elastic 60)
field:"parent_process_basename" kind:in

Startup Folder Persistence via Unsigned Process

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

Identifies files written or modified in the startup folder by unsigned processes. Adversaries may abuse this technique to maintain persistence in an environment.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2020/11/29"
integration = ["endpoint"]
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 files written or modified in the startup folder by unsigned processes. Adversaries may abuse this technique
to maintain persistence in an environment.
"""
from = "now-9m"
index = ["logs-endpoint.events.process-*", "logs-endpoint.events.file-*"]
language = "eql"
license = "Elastic License v2"
name = "Startup Folder Persistence via Unsigned Process"
note = """## Triage and analysis

### Investigating Startup Folder Persistence via Unsigned Process

The Windows Startup folder is a special folder in Windows. Programs added to this folder are executed during account logon, without user interaction, providing an excellent way for attackers to maintain persistence.

This rule looks for unsigned processes writing to the Startup folder locations.

> **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.
- Validate if the activity is not related to planned patches, updates, network administrator activity, or legitimate software installations.
- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.
- Examine the host for derived artifacts that indicate suspicious activities:
  - Analyze the file 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

- There is a high possibility of benign legitimate programs being added to Startup folders. This activity could be based on new software installations, patches, or any kind of network administrator related activity. Before undertaking further investigation, verify that this activity is not benign.

### Related rules

- Suspicious Startup Shell Folder Modification - c8b150f0-0164-475b-a75e-74b47800a9ff
- Persistent Scripts in the Startup Directory - f7c4dc5a-a58d-491d-9f14-9b66507121c0

### 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.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""

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

risk_score = 47
rule_id = "2fba96c0-ade5-4bce-b92f-a5df2509da3f"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Persistence",
    "Tactic: Defense Evasion",
    "Resources: Investigation Guide",
    "Data Source: Elastic Defend",
]
type = "eql"

query = '''
sequence by host.id, process.entity_id with maxspan=5s
  [process where host.os.type == "windows" and event.type == "start" and process.code_signature.trusted == false and
  /* suspicious paths can be added here  */
   process.executable : ("C:\\Users\\*.exe",
                         "C:\\ProgramData\\*.exe",
                         "C:\\Windows\\Temp\\*.exe",
                         "C:\\Windows\\Tasks\\*.exe",
                         "C:\\Intel\\*.exe",
                         "C:\\PerfLogs\\*.exe")
   ]
   [file where host.os.type == "windows" and event.type != "deletion" and user.domain != "NT AUTHORITY" and
    file.path : ("C:\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\*",
                 "C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\StartUp\\*")
   ]
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1547"
name = "Boot or Logon Autostart Execution"
reference = "https://attack.mitre.org/techniques/T1547/"
[[rule.threat.technique.subtechnique]]
id = "T1547.001"
name = "Registry Run Keys / Startup Folder"
reference = "https://attack.mitre.org/techniques/T1547/001/"



[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[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.001"
name = "Invalid Code Signature"
reference = "https://attack.mitre.org/techniques/T1036/001/"



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

Stages and Predicates

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

Stage 1: process

[process where host.os.type == "windows" and event.type == "start" and process.code_signature.trusted == false and
   process.executable : ("C:\\Users\\*.exe",
                         "C:\\ProgramData\\*.exe",
                         "C:\\Windows\\Temp\\*.exe",
                         "C:\\Windows\\Tasks\\*.exe",
                         "C:\\Intel\\*.exe",
                         "C:\\PerfLogs\\*.exe")
   ]

Stage 2: file

[file where host.os.type == "windows" and event.type != "deletion" and user.domain != "NT AUTHORITY" and
    file.path : ("C:\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\*",
                 "C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\StartUp\\*")
   ]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
event.typene
  • deletion corpus 33 (elastic 33)
field:"event.type" kind:ne value:"deletion"
file.pathwildcard
  • C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\* corpus 3 (elastic 3)
  • C:\Users\*\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\* corpus 3 (elastic 3)
field:"TargetFilename" kind:wildcard
process.code_signature.trustedeq
  • false transforms: boolean corpus 114 (elastic 114)
field:"process.code_signature.trusted" kind:eq value:"false"
process.executablewildcard
  • C:\Intel\*.exe
  • C:\PerfLogs\*.exe
  • C:\ProgramData\*.exe corpus 3 (elastic 3)
  • C:\Users\*.exe corpus 3 (elastic 3)
  • C:\Windows\Tasks\*.exe
  • C:\Windows\Temp\*.exe
field:"Image" kind:wildcard
user.domainne
  • NT AUTHORITY corpus 5 (elastic 5)
field:"TargetDomainName" kind:ne value:"NT AUTHORITY"

Startup Persistence from Backed RWX Memory

#
Source
github.com/elastic/protections-artifacts

Identifies when a process is writing to commonly abused persistence locations (registry run keys and startup folder) from a thread running from a memory section with read, write and execute permissions. This may indicate an attempt to persist from a packed or injected program.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies when a process is writing to commonly abused persistence locations (registry run keys and startup folder)
from a thread running from a memory section with read, write and execute permissions. This may indicate an attempt to
persist from a packed or injected program.
"""
id = "15c48f2d-e461-40a9-accd-090a0863ea10"
license = "Elastic License v2"
name = "Startup Persistence from Backed RWX Memory"
os_list = ["windows"]
version = "1.0.14"

query = '''
any where event.category in ("registry", "file") and process.executable != null and
 not event.action in ("deletion", "query") and process.thread.Ext.call_stack_summary like "?*" and
 not process.code_signature.status like ("trusted", "errorExpired", "errorCode_endpoint*") and
 not process.thread.Ext.call_stack_summary like ("*Unbacked*", "*clr.dll*", "*Unknown*", "*|kernelbase.dll|irsetup.exe*", 
                                              "*issetup.dll|isrt.dll*", "*adobepim.dll|set-up.dat*") and
 _arraysearch(process.thread.Ext.call_stack, $entry, $entry.protection : "RWX") and
   (
    (registry.data.strings != null and
     registry.path :
        ("H*\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\*", 
	 "H*\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run\\*", 
         "H*\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run\\*", 
	 "H*\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run\\*")) or
    (file.name != null and file.path : "?:\\*\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\*")
   ) and
   not (process.executable : "?:\\Windows\\Sys*\\msiexec.exe" and
       _arraysearch(process.thread.Ext.call_stack, $entry,
	                $entry.protection : "RWX" and $entry.symbol_info : ("?:\\Windows\\Temp\\*", "?:\\Windows\\Installer\\*"))) and 
   not _arraysearch(process.thread.Ext.call_stack, $entry,
	                $entry.protection : "RWX" and
	                $entry.symbol_info : ("?:\\Windows\\Installer\\*",
	                                      "?:\\Users\\*\\AppData\\Local\\Temp\\*\\isrt.dll!_RegSetKeyValue+*",
	                                      "?:\\Users\\*\\AppData\\Local\\Temp\\{*}\\ISSetup.dll!InstallEngineTypelib*",
	                                      "?:\\Program Files (x86)\\Gizmo\\gdrive.dll!Remount_Startup_Images*")) and
   not registry.data.strings : ("?:\\windows\\Twain_32\\fjscan32\\FjtwMkup.exe /Station", "\"C:\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Webex\\Webex.lnk\" /minimized /autostartedWithWindows=true") and
   not (process.executable :  "?:\\Windows\\SysWOW64\\DWRCS.EXE" and registry.data.strings : "?:\\WINDOWS\\SysWOW64\\DWRCST.exe") and
   not process.executable : ("?:\\Program Files (x86)\\*.exe", "?:\\Program Files\\*.exe")
'''

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

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1547"
name = "Boot or Logon Autostart Execution"
reference = "https://attack.mitre.org/techniques/T1547/"
[[threat.technique.subtechnique]]
id = "T1547.001"
name = "Registry Run Keys / Startup Folder"
reference = "https://attack.mitre.org/techniques/T1547/001/"



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

[internal]
min_endpoint_version = "8.7.0"

Stages and Predicates

Stage 1: any

any where event.category in ("registry", "file") and process.executable != null and
 not event.action in ("deletion", "query") and process.thread.Ext.call_stack_summary like "?*" and
 not process.code_signature.status like ("trusted", "errorExpired", "errorCode_endpoint*") and
 not process.thread.Ext.call_stack_summary like ("*Unbacked*", "*clr.dll*", "*Unknown*", "*|kernelbase.dll|irsetup.exe*", 
                                              "*issetup.dll|isrt.dll*", "*adobepim.dll|set-up.dat*") and
 _arraysearch(process.thread.Ext.call_stack, $entry, $entry.protection : "RWX") and
   (
    (registry.data.strings != null and
     registry.path :
        ("H*\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\*", 
	 "H*\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run\\*", 
         "H*\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run\\*", 
	 "H*\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run\\*")) or
    (file.name != null and file.path : "?:\\*\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\*")
   ) and
   not (process.executable : "?:\\Windows\\Sys*\\msiexec.exe" and
       _arraysearch(process.thread.Ext.call_stack, $entry,
	                $entry.protection : "RWX" and $entry.symbol_info : ("?:\\Windows\\Temp\\*", "?:\\Windows\\Installer\\*"))) and 
   not _arraysearch(process.thread.Ext.call_stack, $entry,
	                $entry.protection : "RWX" and
	                $entry.symbol_info : ("?:\\Windows\\Installer\\*",
	                                      "?:\\Users\\*\\AppData\\Local\\Temp\\*\\isrt.dll!_RegSetKeyValue+*",
	                                      "?:\\Users\\*\\AppData\\Local\\Temp\\{*}\\ISSetup.dll!InstallEngineTypelib*",
	                                      "?:\\Program Files (x86)\\Gizmo\\gdrive.dll!Remount_Startup_Images*")) and
   not registry.data.strings : ("?:\\windows\\Twain_32\\fjscan32\\FjtwMkup.exe /Station", "\"C:\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Webex\\Webex.lnk\" /minimized /autostartedWithWindows=true") and
   not (process.executable :  "?:\\Windows\\SysWOW64\\DWRCS.EXE" and registry.data.strings : "?:\\WINDOWS\\SysWOW64\\DWRCST.exe") and
   not process.executable : ("?:\\Program Files (x86)\\*.exe", "?:\\Program Files\\*.exe")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.categoryin
  • file corpus 15 (elastic 15)
  • registry corpus 10 (elastic 10)
field:"event.category" kind:in
file.nameis_not_null
  • (no value, null check)
field:"file.name" kind:is_not_null
file.pathwildcard
  • ?:\*\Microsoft\Windows\Start Menu\Programs\Startup\* corpus 9 (elastic 9)
field:"TargetFilename" kind:wildcard value:"?:\*\Microsoft\Windows\Start Menu\Programs\Startup\*"
process.executableis_not_null
  • (no value, null check)
field:"Image" kind:is_not_null
process.thread.Ext.call_stack_summarywildcard
  • ?* corpus 5 (elastic 5)
field:"process.thread.Ext.call_stack_summary" kind:wildcard value:"?*"
registry.data.stringsis_not_null
  • (no value, null check)
field:"Details" kind:is_not_null
registry.pathwildcard
  • H*\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run\* corpus 11 (elastic 11)
  • H*\Software\Microsoft\Windows\CurrentVersion\Run\* corpus 12 (elastic 12)
  • H*\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run\* corpus 11 (elastic 11)
  • H*\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Run\* corpus 11 (elastic 11)
field:"TargetObject" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.thread.Ext.call_stackarray_any(no value, null check)excludes:process.thread.Ext.call_stack
process.executablewildcard?:\Windows\Sys*\msiexec.exeexcludes:process.executable field:"process.executable" value:"?:\Windows\Sys*\msiexec.exe"
process.executableeq?:\Windows\SysWOW64\DWRCS.EXEexcludes:process.executable field:"process.executable" value:"?:\Windows\SysWOW64\DWRCS.EXE"
registry.data.stringseq?:\WINDOWS\SysWOW64\DWRCST.exeexcludes:registry.data.strings field:"registry.data.strings" value:"?:\WINDOWS\SysWOW64\DWRCST.exe"
event.actionindeletion, queryexcludes:event.action field:"event.action" value:"deletion" field:"event.action" value:"query"
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*"
process.executablewildcard?:\Program Files (x86)\*.exe, ?:\Program Files\*.exeexcludes:process.executable field:"process.executable" value:"?:\Program Files (x86)\*.exe" field:"process.executable" value:"?:\Program Files\*.exe"
process.thread.Ext.call_stack_summarymatchUnbacked, clr.dll, Unknown, |kernelbase.dll|irsetup.exe, issetup.dll|isrt.dll, adobepim.dll|set-up.datexcludes:process.thread.Ext.call_stack_summary
registry.data.stringswildcard?:\windows\Twain_32\fjscan32\FjtwMkup.exe /Station, "C:\Users\*\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Webex\Webex.lnk" /minimized /autostartedWithWindows=trueexcludes:registry.data.strings

Suspicious Installer Package Spawns Network Event

#
Status
production
Severity
medium
Time window
15s
Sequence by
host.id, process.entity_id
Author
Elastic
Source
github.com/elastic/detection-rules

Detects the execution of a MacOS installer package with an abnormal child process (e.g bash) followed immediately by a network connection via a suspicious process (e.g curl). Threat actors will build and distribute malicious MacOS installer packages, which have a .pkg extension, many times imitating valid software in order to persuade and infect their victims often using the package files (e.g pre/post install scripts etc.) to download additional tools or malicious software. If this rule fires it should indicate the installation of a malicious or suspicious package.

Known False Positives

  • Custom organization-specific macOS packages that use .pkg files to run cURL could trigger this rule. If known behavior is causing false positives, it can be excluded from the rule.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2021/02/23"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
Detects the execution of a MacOS installer package with an abnormal child process (e.g bash) followed immediately by a
network connection via a suspicious process (e.g curl). Threat actors will build and distribute malicious MacOS
installer packages, which have a .pkg extension, many times imitating valid software in order to persuade and infect
their victims often using the package files (e.g pre/post install scripts etc.) to download additional tools or
malicious software. If this rule fires it should indicate the installation of a malicious or suspicious package.
"""
false_positives = [
    """
    Custom organization-specific macOS packages that use .pkg files to run cURL could trigger this rule. If known
    behavior is causing false positives, it can be excluded from the rule.
    """,
]
from = "now-9m"
index = ["logs-endpoint.events.network*", "logs-endpoint.events.process*"]
language = "eql"
license = "Elastic License v2"
name = "Suspicious Installer Package Spawns Network Event"
references = [
    "https://redcanary.com/blog/clipping-silver-sparrows-wings",
    "https://posts.specterops.io/introducing-mystikal-4fbd2f7ae520",
    "https://github.com/D00MFist/Mystikal",
]
risk_score = 47
rule_id = "99239e7d-b0d4-46e3-8609-acafcf99f68c"
setup = """## Setup

This rule requires data coming in from Elastic Defend.

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

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

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

query = '''
sequence by host.id, process.entity_id with maxspan=15s
[process where host.os.type == "macos" and event.type == "start" and event.action == "exec" and process.parent.name like~ ("installer", "package_script_service") and ((process.name in ("bash", "sh", "zsh") and process.args == "-c") or (process.name like~ ("python*", "osascript", "tclsh*", "curl", "nscurl")))]
[network where host.os.type == "macos" and event.type == "start"]
'''
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 Installer Package Spawns Network Event

MacOS installer packages, often with a .pkg extension, are used to distribute software. Adversaries exploit this by embedding scripts to execute additional commands or download malicious payloads. The detection rule identifies suspicious behavior by monitoring for installer packages spawning shell processes followed by network activity, indicating potential malicious activity.

### Possible investigation steps

- Review the process details to identify the parent process name and entity ID, focusing on processes like "installer" or "package_script_service" that initiated the suspicious activity.
- Examine the child process that was spawned, such as "bash", "sh", or "python", to determine the commands executed and assess if they align with typical installation behavior or appear malicious.
- Investigate the network activity associated with the suspicious process, particularly looking at processes like "curl" or "wget", to identify any external connections made and the destination IP addresses or domains.
- Check the timestamp and sequence of events to confirm if the network activity closely followed the process execution, indicating a potential download or data exfiltration attempt.
- Analyze any downloaded files or payloads for malicious content using threat intelligence tools or sandbox environments to determine their intent and potential impact.
- Correlate the findings with known threat actor tactics or campaigns, leveraging threat intelligence sources to assess if the activity matches any known patterns or indicators of compromise.

### False positive analysis

- Legitimate software installations may trigger this rule if they use scripts to configure network settings or download updates. Users can create exceptions for known safe software by whitelisting specific installer package names or hashes.
- System administrators often use scripts to automate software deployment and updates, which might involve network activity. To reduce false positives, exclude processes initiated by trusted administrative tools or scripts.
- Development environments on macOS might execute scripts that connect to the internet for dependencies or updates. Users can mitigate this by excluding processes associated with known development tools or environments.
- Some security tools or monitoring software may use scripts to perform network checks or updates. Identify and exclude these processes if they are verified as non-threatening.
- Frequent updates from trusted software vendors might trigger this rule. Users should maintain an updated list of trusted vendors and exclude their processes from triggering alerts.

### Response and remediation

- Isolate the affected MacOS system from the network immediately to prevent further malicious activity or data exfiltration.
- Terminate any suspicious processes identified in the alert, such as those initiated by the installer package, to halt ongoing malicious actions.
- Conduct a thorough review of the installed applications and remove any unauthorized or suspicious software, especially those with a .pkg extension.
- Restore the system from a known good backup if available, ensuring that the backup predates the installation of the malicious package.
- Update and patch the MacOS system and all installed applications to the latest versions to mitigate vulnerabilities that could be exploited by similar threats.
- Monitor network traffic for any signs of command and control communication or data exfiltration attempts, using the indicators identified in the alert.
- Escalate the incident to the security operations team for further investigation and to assess the potential impact on other systems within the network."""


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

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

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

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

Stages and Predicates

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

Stage 1: process

[process where host.os.type == "macos" and event.type == "start" and event.action == "exec" and process.parent.name like~ ("installer", "package_script_service") and ((process.name in ("bash", "sh", "zsh") and process.args == "-c") or (process.name like~ ("python*", "osascript", "tclsh*", "curl", "nscurl")))]

Stage 2: network

[network where host.os.type == "macos" and event.type == "start"]

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.argseq
  • -c corpus 91 (elastic 91)
field:"process.args" kind:eq value:"-c"
process.namein
  • bash corpus 181 (elastic 181)
  • sh corpus 180 (elastic 180)
  • zsh corpus 180 (elastic 180)
field:"process_basename" kind:in
process.namewildcard
  • curl corpus 28 (elastic 28)
  • nscurl corpus 15 (elastic 15)
  • osascript corpus 31 (elastic 31)
  • python* corpus 51 (elastic 51)
  • tclsh* corpus 10 (elastic 10)
field:"process_basename" kind:wildcard
process.parent.namewildcard
  • installer
  • package_script_service
field:"parent_process_basename" kind:wildcard

Suspicious Script Execution via VBSEdit Launcher

#
Source
github.com/elastic/protections-artifacts

Identifies the execution of a Script via VbsEdit Script Launcher utility and from unusual path. Malware may abuse this legit utility to bypass security solutions monitoring malicious scripts execution via the Windows built-in Script interpreters (cscript or wscript).

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the execution of a Script via VbsEdit Script Launcher utility and from unusual path. Malware may abuse this
legit utility to bypass security solutions monitoring malicious scripts execution via the Windows built-in Script
interpreters (cscript or wscript).
"""
id = "d4715380-5857-4062-980d-c44052ff5180"
license = "Elastic License v2"
name = "Suspicious Script Execution via VBSEdit Launcher"
os_list = ["windows"]
reference = ["https://www.vbsedit.com/", "https://malpedia.caad.fkie.fraunhofer.de/details/win.vjw0rm"]
version = "1.0.25"

query = '''
process where event.type == "start" and
 (process.pe.original_file_name == "launcher.exe" and process.code_signature.subject_name : "Adersoft") and
 not process.executable : ("?:\\Program Files\\*.exe", "?:\\Program Files (x86)\\*.exe") and
 not user.id in ("S-1-5-18", "S-1-5-19", "S-1-5-20") and
 not process.executable : "?:\\RANOCCHI\\GiDesk\\Gis\\System\\Rtf\\Doc\\RCbase64.exe"
'''

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

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

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

[[threat.technique.subtechnique]]
id = "T1059.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"



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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Stage 1: process

process where event.type == "start" and
 (process.pe.original_file_name == "launcher.exe" and process.code_signature.subject_name : "Adersoft") and
 not process.executable : ("?:\\Program Files\\*.exe", "?:\\Program Files (x86)\\*.exe") and
 not user.id in ("S-1-5-18", "S-1-5-19", "S-1-5-20") and
 not process.executable : "?:\\RANOCCHI\\GiDesk\\Gis\\System\\Rtf\\Doc\\RCbase64.exe"

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

Back to all Elastic rules