Detection rules › Elastic
Elastic rules: 14
Anomalous Process For a Windows Population
#Searches for rare processes running on multiple hosts in an entire fleet or network. This reduces the detection of false positives since automated maintenance processes usually only run occasionally on a single machine but are common to all or many hosts in a fleet.
Known False Positives
- A newly installed program or one that runs rarely as part of a monthly or quarterly workflow could trigger this alert.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Persistence |
Rule Body
[metadata]
creation_date = "2020/03/25"
integration = ["endpoint", "windows"]
maturity = "production"
updated_date = "2026/07/27"
min_stack_version = "9.4.0"
min_stack_comments = "Use EA (Entity Analytics) fields"
[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 '%LocalSyste' OR user_account LIKE '%LocalService' OR user_account LIKE '%NetworkService' OR
user_account == null)
"""
[[transform.osquery]]
label = "Retrieve Service Unisgned Executables with Virustotal Link"
query = """
SELECT concat('https://www.virustotal.com/gui/file/', sha1) AS VtLink, name, description, start_type, status, pid,
services.path FROM services JOIN authenticode ON services.path = authenticode.path OR services.module_path =
authenticode.path JOIN hash ON services.path = hash.path WHERE authenticode.result != 'trusted'
"""
[rule]
anomaly_threshold = 50
author = ["Elastic"]
description = """
Searches for rare processes running on multiple hosts in an entire fleet or network. This reduces the detection of false
positives since automated maintenance processes usually only run occasionally on a single machine but are common to all
or many hosts in a fleet.
"""
false_positives = [
"""
A newly installed program or one that runs rarely as part of a monthly or quarterly workflow could trigger this
alert.
""",
]
from = "now-45m"
interval = "15m"
license = "Elastic License v2"
machine_learning_job_id = ["v3_windows_anomalous_process_all_hosts_ea"]
name = "Anomalous Process For a Windows Population"
note = """## Triage and analysis
### Investigating Anomalous Process For a Windows Population
Searching for abnormal Windows processes is a good methodology to find potentially malicious activity within a network. Understanding what is commonly run within an environment and developing baselines for legitimate activity can help uncover potential malware and suspicious behaviors.
This rule uses a machine learning job to detect a Windows process that is rare and unusual for all of the monitored Windows hosts in your environment.
> **Note**:
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/current/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.
#### Possible investigation steps
- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.
- If the parent process is a legitimate system utility or service, this could be related to software updates or system management. If the parent process is something user-facing like an Office application, this process could be more suspicious.
- Investigate the process metadata — such as the digital signature, directory, etc. — to obtain more context that can indicate whether the executable is associated with an expected software vendor or package.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Consider the user as identified by the `user.name` field. Is this program part of an expected workflow for the user who ran this program on this host?
- Validate the activity is not related to planned patches, updates, network administrator activity, or legitimate software installations.
- Validate if the activity has a consistent cadence (for example, if it runs monthly or quarterly), as it could be part of a monthly or quarterly business process.
- Examine the arguments and working directory of the process. These may provide indications as to the source of the program or the nature of the tasks it is performing.
- Examine the host for derived artifacts that indicate suspicious activities:
- Analyze the process executable using a private sandboxed analysis system.
- Observe and collect information about the following activities in both the sandbox and the alert subject host:
- Attempts to contact external domains and addresses.
- Use the Elastic Defend network events to determine domains and addresses contacted by the subject process by filtering by the process' `process.entity_id`.
- Examine the DNS cache for suspicious or anomalous entries.
- $osquery_0
- Use the Elastic Defend registry events to examine registry keys accessed, modified, or created by the related processes in the process tree.
- Examine the host services for suspicious or anomalous entries.
- $osquery_1
- $osquery_2
- $osquery_3
- Retrieve the files' SHA-256 hash values using the PowerShell `Get-FileHash` cmdlet and search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.
### False Positive Analysis
- If this activity is related to new benign software installation activity, consider adding exceptions — preferably with a combination of user and command line conditions.
- Try to understand the context of the execution by thinking about the user, machine, or business purpose. A small number of endpoints, such as servers with unique software, might appear unusual but satisfy a specific business need.
### Related Rules
- Unusual Process For a Windows Host - 6d448b96-c922-4adb-b51c-b767f1ea5b76
- Unusual Windows Path Activity - 445a342e-03fb-42d0-8656-0367eb2dead5
- Unusual Windows Process Calling the Metadata Service - abae61a8-c560-4dbd-acca-1e1438bff36b
### Response and Remediation
- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved hosts to prevent further post-compromise behavior.
- If the triage identified malware, search the environment for additional compromised hosts.
- Implement temporary network rules, procedures, and segmentation to contain the malware.
- Stop suspicious processes.
- Immediately block the identified indicators of compromise (IoCs).
- Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that attackers could use to reinfect the system.
- Remove and block malicious artifacts identified during triage.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
references = ["https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html"]
risk_score = 21
rule_id = "6e40d56f-5c0e-4ac6-aece-bee96645b172"
setup = """## Setup
This rule requires the installation of associated Machine Learning jobs, as well as data coming in from one of the following integrations:
- Elastic Defend
- Windows
### Anomaly Detection Setup
Once the rule is enabled, the associated Machine Learning job will start automatically. You can view the Machine Learning job linked under the "Definition" panel of the detection rule. If the job does not start due to an error, the issue must be resolved for the job to commence successfully. For more details on setting up anomaly detection jobs, refer to the [helper guide](https://www.elastic.co/guide/en/kibana/current/xpack-ml-anomalies.html).
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration to your system:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/current/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
### Windows Integration Setup
The Windows integration allows you to monitor the Windows OS, services, applications, and more.
#### The following steps should be executed in order to add the Elastic Agent System integration "windows" to your system:
- Go to the Kibana home page and click “Add integrations”.
- In the query bar, search for “Windows” and select the integration to see more details about it.
- Click “Add Windows”.
- Configure the integration name and optionally add a description.
- Review optional and advanced settings accordingly.
- Add the newly installed “windows” to an existing or a new agent policy, and deploy the agent on your system from which windows log files are desirable.
- Click “Save and Continue”.
- For more details on the integration refer to the [helper guide](https://docs.elastic.co/integrations/windows).
"""
severity = "low"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Data Source: Elastic Defend",
"Data Source: Windows Security Event Logs",
"Use Case: Threat Detection",
"Rule Type: ML",
"Rule Type: Machine Learning",
"Tactic: Persistence",
"Tactic: Execution",
"Resources: Investigation Guide",
]
type = "machine_learning"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1204"
name = "User Execution"
reference = "https://attack.mitre.org/techniques/T1204/"
[[rule.threat.technique.subtechnique]]
id = "T1204.002"
name = "Malicious File"
reference = "https://attack.mitre.org/techniques/T1204/002/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
AWS Root Console Login Password Spraying
#Identifies failed authentication attempts against the AWS Management Console root user from the same source IP address targeting multiple AWS accounts. Password spraying uses few attempts per target across many accounts to avoid lockout, making per-account volume an unreliable signal. This rule detects the cross-account breadth pattern: a single source IP generating root ConsoleLogin failures across two or more distinct AWS accounts. Requires an AWS Organizations-level CloudTrail trail aggregating events from member accounts.
Known False Positives
- Administrators behind a shared egress address, such as a corporate NAT gateway or VPN concentrator, can trigger this rule when separate people mistype root passwords for different accounts within the window, since a single failure per account is sufficient. An administrator who legitimately holds root credentials for several accounts can also match. Verify whether the source IP is an expected corporate or administrator address, and whether the targeted accounts correspond to that person's scope, before escalating. Repeated failures against a single account do not trigger this rule and are covered by the separate brute-force rule.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
- AWS Authentication From CrowdStrike Unmanaged Device (Panther)
- AWS Authentication from CrowdStrike Unmanaged Device (Panther)
- AWS Authentication from CrowdStrike Unmanaged Device (crowdstrike_fdrevent table) (Panther)
- AWS EC2 Instance Console Login via Assumed Role (Elastic)
- AWS GetFederationToken Followed by Console Login via Federation Exchange (Elastic)
- AWS IAM User Console Login from Multiple Geolocations (Elastic)
- AWS IAM User Console Login Without MFA (Elastic)
- AWS Management Console Brute Force of Root User Identity (Elastic)
Rule Body
[metadata]
creation_date = "2026/09/01"
integration = ["aws"]
maturity = "production"
updated_date = "2026/09/01"
[rule]
author = ["Elastic"]
description = """
Identifies failed authentication attempts against the AWS Management Console root user from the same source IP address
targeting multiple AWS accounts. Password spraying uses few attempts per target across many accounts to avoid lockout,
making per-account volume an unreliable signal. This rule detects the cross-account breadth pattern: a single source IP
generating root ConsoleLogin failures across two or more distinct AWS accounts. Requires an AWS Organizations-level
CloudTrail trail aggregating events from member accounts.
"""
false_positives = [
"""
Administrators behind a shared egress address, such as a corporate NAT gateway or VPN
concentrator, can trigger this rule when separate people mistype root passwords for different
accounts within the window, since a single failure per account is sufficient. An administrator
who legitimately holds root credentials for several accounts can also match. Verify whether the
source IP is an expected corporate or administrator address, and whether the targeted accounts
correspond to that person's scope, before escalating. Repeated failures against a single account
do not trigger this rule and are covered by the separate brute-force rule.
""",
]
from = "now-1h"
index = ["logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS Root Console Login Password Spraying"
note = """## Triage and analysis
### Investigating AWS Root Console Login Password Spraying
Password spraying is a credential access technique where an attacker tries a small number of commonly used or leaked passwords across many accounts. Unlike brute force, the per-account attempt count is intentionally low — often 2–8 attempts — to stay below lockout thresholds and evade high-volume detections. Attackers targeting AWS root accounts typically hold a pre-enumerated list of root account email addresses and route attempts through proxy or residential IP infrastructure.
This rule fires when a single source IP generates failed root `ConsoleLogin` events against two or more distinct AWS accounts within a 1 hour window, requiring an AWS Organizations-level CloudTrail trail. The cross-account breadth is the defining spray signal; brute force against a single account is covered by a separate rule.
#### Possible investigation steps
- **Assess the source IP.**
Determine whether the IP belongs to a known corporate range, VPN, or expected admin location. Use threat intelligence tools to check if it is flagged as a proxy, Tor exit node, or residential proxy service.
- **Review the user agent string.**
Outdated browser user agents (for example, Chrome 85 or Firefox 120) are common indicators of spray-campaign tooling. Cross-reference `user_agent.original` across the contributing events in Timeline.
- **Check for a subsequent successful login.**
Query CloudTrail for a `ConsoleLogin` success for the root identity in the same timeframe. A success immediately after failures indicates the spray succeeded — escalate immediately.
- **Examine follow-on API calls.**
If a successful login did occur, review high-risk API calls that followed: `CreateUser`, `CreateAccessKey`, `AttachRolePolicy`, `DeleteTrail`, or `StopLogging`.
- **Widen the scope across accounts.**
If your organization uses AWS Organizations, check whether the same source IP triggered root login failures in other member accounts during the same window.
### False positive analysis
- **Mistyped credentials.** A root credential custodian mistyping the password multiple times is the most likely benign cause. Confirm whether the source IP is a known admin location and whether a successful login followed shortly after.
- **Stale automation.** Misconfigured scripts or browser sessions with cached root credentials may retry on failure. Check whether the user agent matches known internal tooling.
### Response and remediation
- **If no successful root login is found:**
- Rotate the root password to a strong, unique credential stored in an offline vault.
- Confirm MFA is enabled and enforced on the root account.
- Block the source IP at AWS WAF or network ACLs if confirmed malicious.
- **If a successful root login is found:**
- Treat as Priority-1 account compromise and immediately follow the *AWS Management Console Root Login* investigation guide.
- Initiate an emergency root password reset and MFA re-enrollment.
- Preserve all CloudTrail events from ±1 hour around the login in an immutable evidence bucket.
- Audit all API calls made during the session for persistence: new users, access keys, policy changes.
### Additional information
- [AWS root user best practices](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html)
- [AWS IR Playbooks — Credential Compromise](https://github.com/aws-samples/aws-incident-response-playbooks)
"""
setup = """## Setup
This rule requires an AWS Organizations-level CloudTrail trail that aggregates management events from all member accounts into a single destination. A single-account trail will only ever contain one `cloud.account.id` value and the cross-account cardinality signal will never fire.
To configure an org-level trail: in the AWS CloudTrail console, create a trail scoped to your AWS Organization and enable it in all regions. Ensure the Elastic AWS integration is ingesting from the aggregated trail destination."""
references = [
"https://securitylabs.datadoghq.com/articles/aws-root-user-bruteforce-campaign/",
]
risk_score = 47
rule_id = "171d3cdd-0c04-47c2-b392-65719284ae25"
severity = "medium"
tags = [
"Domain: Cloud",
"Domain: Identity",
"Platform: AWS",
"Data Source: AWS CloudTrail",
"Use Case: Identity and Access Audit",
"Tactic: Credential Access",
"Rule Type: Threshold",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "threshold"
query = '''
data_stream.dataset:aws.cloudtrail and
event.provider:signin.amazonaws.com and
event.action:ConsoleLogin and
aws.cloudtrail.user_identity.type:Root and
event.outcome:failure
'''
[rule.investigation_fields]
field_names = [
"source.ip",
"user_agent.original",
"cloud.account.id",
"aws.cloudtrail.user_identity.type",
"event.outcome",
"aws.cloudtrail.error_message",
"@timestamp",
]
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1110"
name = "Brute Force"
reference = "https://attack.mitre.org/techniques/T1110/"
[[rule.threat.technique.subtechnique]]
id = "T1110.003"
name = "Password Spraying"
reference = "https://attack.mitre.org/techniques/T1110/003/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[rule.threshold]
field = ["source.ip"]
value = 1
[[rule.threshold.cardinality]]
field = "cloud.account.id"
value = 2
[rule.alert_suppression]
duration = {value = 1, unit = "h"}
Stages and Predicates
Stage 1: query
data_stream.dataset:aws.cloudtrail and
event.provider:signin.amazonaws.com and
event.action:ConsoleLogin and
aws.cloudtrail.user_identity.type:Root and
event.outcome:failure
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
aws.cloudtrail.user_identity.type | eq |
| field:"aws::userIdentity.type" kind:eq value:"Root" |
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"aws.cloudtrail" |
event.action | eq |
| field:"EventType" kind:eq value:"ConsoleLogin" |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"failure" |
event.provider | eq |
| field:"Provider_Name" kind:eq value:"signin.amazonaws.com" |
AWS SES Full Access Policy Attached to IAM Entity by Unusual User
#Detects the first occurrence in 7 days of an AWS identity attaching the managed policy AmazonSESFullAccess to an IAM user, role, or group. AmazonSESFullAccess grants unrestricted permission to send email, manage identities and templates, manage suppression lists, and access SES account-level settings. Granting this policy to an unexpected IAM entity, particularly a newly created user or a role not previously associated with email operations, is a documented technique used by threat actors to establish phishing infrastructure on compromised AWS accounts, enabling them to send email on behalf of the victim organization's trusted sending domain. Using new terms on the calling identity suppresses recurring attachments by known email automation while surfacing identities performing this action for the first time.
Known False Positives
- Legitimate email service automation may attach AmazonSESFullAccess to a service account. Validate the target IAM entity against known email automation roles and CI/CD pipeline identities. Because this is a new terms rule keyed on the calling identity, recurring attachments by the same automation will not re-alert within the 7-day history window; first-time attachments by administrators performing legitimate setup may still trigger and should be validated against change management records.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Resource Development | |
| Persistence |
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
- AWS Compromised IAM Key Quarantine (Panther)
- AWS IAM AdministratorAccess Policy Attached to Group (Elastic)
- AWS IAM AdministratorAccess Policy Attached to Role (Elastic)
- AWS IAM AdministratorAccess Policy Attached to User (Elastic)
- AWS IAM Customer-Managed Policy Attached to Role by Rare User (Elastic)
- AWS IAM Sensitive Operations via Lambda Execution Role (Elastic)
- AWS Sensitive IAM Operations Performed via CloudShell (Elastic)
- IAM Admin Policy Attached (Sigma)
Rule Body
[metadata]
creation_date = "2026/08/31"
integration = ["aws"]
maturity = "production"
updated_date = "2026/08/31"
[rule]
author = ["Elastic"]
description = """
Detects the first occurrence in 7 days of an AWS identity attaching the managed policy
AmazonSESFullAccess to an IAM user, role, or group. AmazonSESFullAccess grants unrestricted
permission to send email, manage identities and templates, manage suppression lists, and access
SES account-level settings. Granting this policy to an unexpected IAM entity, particularly a newly
created user or a role not previously associated with email operations, is a documented technique
used by threat actors to establish phishing infrastructure on compromised AWS accounts, enabling
them to send email on behalf of the victim organization's trusted sending domain. Using new terms
on the calling identity suppresses recurring attachments by known email automation while
surfacing identities performing this action for the first time.
"""
false_positives = [
"""
Legitimate email service automation may attach AmazonSESFullAccess to a service account.
Validate the target IAM entity against known email automation roles and CI/CD pipeline identities.
Because this is a new terms rule keyed on the calling identity, recurring attachments by the
same automation will not re-alert within the 7-day history window; first-time attachments by
administrators performing legitimate setup may still trigger and should be validated against
change management records.
""",
]
from = "now-6m"
index = ["logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS SES Full Access Policy Attached to IAM Entity by Unusual User"
note = """## Triage and analysis
### Investigating AWS SES Full Access Policy Attached to IAM Entity by Unusual User
AWS Simple Email Service (SES) is a cost-effective bulk email platform with a reputation built on a customer's verified sending domains. Threat actors who compromise an AWS account often establish phishing infrastructure by granting SES access to a new or existing IAM identity and then using that identity's credentials to send phishing emails under the victim organization's trusted domain. Attaching the managed policy `AmazonSESFullAccess` is the simplest way to grant the full range of SES capabilities (send, manage identities, manage suppression lists, configure sending settings).
This is a new terms rule that alerts only when the calling identity (`aws.cloudtrail.user_identity.arn`) has not attached this policy within the previous 7 days, prioritizing anomalous or first-time activity over recurring automation.
### Possible investigation steps
- Identify the caller in `aws.cloudtrail.user_identity.arn` and `user.name`. Determine whether the caller is a legitimate administrator or an anomalous identity.
- Identify the target IAM entity in `user.target.name` and `aws.cloudtrail.flattened.request_parameters.userName` (or `groupName` or `roleName`). Is this a known email automation account, or an entity created recently?
- Query CloudTrail for all SES API calls (`event.provider: ses.amazonaws.com`) from the target entity in the time window after this attachment. Look for `SendEmail`, `SendRawEmail`, `VerifyEmailIdentity`, `SetIdentityMailFromDomain`, or `UpdateAccountSendingEnabled`.
- Review whether the attachment corresponds to a legitimate change management process. Check for a corresponding IAM change window ticket.
- Verify whether SES sending is enabled for the account (`ses:GetAccountSendingEnabled`) and whether there are existing or recently created SES identities.
### False positive analysis
- Legitimate email automation services (transactional email, notification services) may attach AmazonSESFullAccess. Confirm the target entity is a known service role.
- CI/CD pipelines that manage email notification infrastructure may attach this policy. Validate via pipeline execution logs and source IP.
### Response and remediation
- If unauthorized, immediately detach AmazonSESFullAccess from the target entity and review all SES calls made under that identity.
- Review SES account sending status and disable sending if any unauthorized email was sent.
- Check SES suppression list for any unauthorized modifications (attackers may add or remove entries to influence deliverability).
- Rotate all credentials associated with both the calling identity and the target entity.
- Enable SES event publishing to review any emails sent during the unauthorized period.
"""
references = [
"https://docs.aws.amazon.com/ses/latest/dg/control-user-access.html"
]
risk_score = 47
rule_id = "d2e3f4a5-b6c7-8901-bcde-f23456789012"
setup = "The AWS integration must be ingesting management events into `logs-aws.cloudtrail-*`. No additional data event selectors are required — `iam:AttachUserPolicy`, `iam:AttachRolePolicy`, and `iam:AttachGroupPolicy` are management-plane APIs logged by default."
severity = "medium"
tags = [
"Domain: Cloud",
"Platform: AWS",
"Data Source: AWS",
"Data Source: Amazon Web Services",
"Service: AWS IAM",
"Service: AWS SES",
"Rule Type: New Terms",
"Tactic: Persistence",
"Tactic: Resource Development",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
data_stream.dataset: "aws.cloudtrail"
and event.provider: "iam.amazonaws.com"
and event.action: ("AttachUserPolicy" or "AttachRolePolicy" or "AttachGroupPolicy")
and event.outcome: "success"
and aws.cloudtrail.flattened.request_parameters.policyArn: "arn:aws:iam::aws:policy/AmazonSESFullAccess"
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[[rule.threat.technique.subtechnique]]
id = "T1098.003"
name = "Additional Cloud Roles"
reference = "https://attack.mitre.org/techniques/T1098/003/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1608"
name = "Stage Capabilities"
reference = "https://attack.mitre.org/techniques/T1608/"
[rule.threat.tactic]
id = "TA0042"
name = "Resource Development"
reference = "https://attack.mitre.org/tactics/TA0042/"
[rule.new_terms]
field = "new_terms_fields"
value = ["aws.cloudtrail.user_identity.arn"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-7d"
[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",
"user.target.name",
"event.action",
"event.outcome",
"aws.cloudtrail.request_parameters",
"source.ip",
"cloud.region",
"cloud.account.id",
]
Stages and Predicates
Stage 1: new_terms
data_stream.dataset: "aws.cloudtrail"
and event.provider: "iam.amazonaws.com"
and event.action: ("AttachUserPolicy" or "AttachRolePolicy" or "AttachGroupPolicy")
and event.outcome: "success"
and aws.cloudtrail.flattened.request_parameters.policyArn: "arn:aws:iam::aws:policy/AmazonSESFullAccess"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
aws.cloudtrail.flattened.request_parameters.policyArn | eq |
| field:"aws.cloudtrail.flattened.request_parameters.policyArn" kind:eq value:"arn:aws:iam::aws:policy/AmazonSESFullAccess" |
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"aws.cloudtrail" |
event.action | in |
| field:"EventType" kind:in |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"success" |
event.provider | eq |
| field:"Provider_Name" kind:eq value:"iam.amazonaws.com" |
Azure Storage Account Keys Accessed by Privileged User
#Identifies unusual high-privileged access to Azure Storage Account keys by users with Owner, Contributor, or Storage Account Contributor roles. This technique was observed in STORM-0501 ransomware campaigns where compromised identities with high-privilege Azure RBAC roles retrieved access keys to perform unauthorized operations on Storage Accounts. Microsoft recommends using Shared Access Signature (SAS) models instead of direct key access for improved security. This rule detects when a user principal with high-privilege roles accesses storage keys for the first time in 7 days.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Credential Access |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2025/09/23"
integration = ["azure"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
Identifies unusual high-privileged access to Azure Storage Account keys by users with Owner, Contributor, or Storage
Account Contributor roles. This technique was observed in STORM-0501 ransomware campaigns where compromised identities
with high-privilege Azure RBAC roles retrieved access keys to perform unauthorized operations on Storage Accounts.
Microsoft recommends using Shared Access Signature (SAS) models instead of direct key access for improved security.
This rule detects when a user principal with high-privilege roles accesses storage keys for the first time in 7 days.
"""
from = "now-9m"
index = ["logs-azure.activitylogs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Azure Storage Account Keys Accessed by Privileged User"
note = """## Triage and Analysis
### Investigating Azure Storage Account Keys Accessed by Privileged User
Azure Storage Account keys provide full administrative access to storage resources. While legitimate administrators may occasionally need to access these keys, Microsoft recommends using more granular access methods like Shared Access Signatures (SAS) or Azure AD authentication. This detection identifies when users with high-privilege roles (Owner, Contributor, Storage Account Contributor, or User Access Administrator) access storage account keys, particularly focusing on unusual patterns that may indicate compromise. This technique was notably observed in STORM-0501 ransomware campaigns where compromised identities retrieved keys for unauthorized storage operations.
### Possible investigation steps
- Review the `azure.activitylogs.identity.authorization.evidence.principal_id` to identify the specific user who accessed the storage account keys.
- Examine the `azure.resource.name` field to determine which storage account's keys were accessed and assess the sensitivity of data stored there.
- Check the `azure.activitylogs.identity.authorization.evidence.role` to confirm the user's assigned role and whether this level of access is justified for their job function.
- Investigate the timing and frequency of the key access event - multiple key retrievals in a short timeframe may indicate automated exfiltration attempts.
- Review the source IP address and geographic location of the access request to identify any anomalous access patterns or locations.
- Correlate this event with other activities by the same principal ID, looking for patterns such as permission escalations, unusual data access, or configuration changes.
- Check Azure AD sign-in logs for the user around the same timeframe to identify any suspicious authentication events or MFA bypasses.
- Examine subsequent storage account activities to determine if the retrieved keys were used for data access, modification, or exfiltration.
### False positive analysis
- DevOps and infrastructure teams may legitimately access storage keys during deployment or migration activities. Document these planned activities and consider creating exceptions for specific time windows.
- Emergency troubleshooting scenarios may require administrators to retrieve storage keys. Establish a process for documenting these emergency accesses and review them regularly.
- Automated backup or disaster recovery systems might use high-privilege service accounts that occasionally need key access. Consider using managed identities or service principals with more restricted permissions instead.
- Legacy applications that haven't been migrated to use SAS tokens or Azure AD authentication may still require key-based access. Plan to modernize these applications and track them as exceptions in the meantime.
- New storage account provisioning by administrators will often include initial key retrieval. Consider the age of the storage account when evaluating the risk level.
### Response and remediation
- Immediately rotate the storage account keys that were accessed using Azure Portal or Azure CLI.
- Review all recent activities on the affected storage account to identify any unauthorized data access, modification, or exfiltration attempts.
- If unauthorized access is confirmed, disable the compromised user account and initiate password reset procedures.
- Audit all storage accounts accessible by the compromised identity and rotate keys for any accounts that may have been accessed.
- Implement Entra ID authentication or SAS tokens for applications currently using storage account keys to reduce future risk.
- Configure Azure Policy to restrict the listKeys operation to specific roles or require additional approval workflows.
- Review and potentially restrict the assignment of high-privilege roles like Owner and Contributor, following the principle of least privilege.
- Enable diagnostic logging for all storage accounts to maintain detailed audit trails of access and operations.
- Consider implementing Privileged Identity Management (PIM) for just-in-time access to high-privilege roles that can list storage keys.
"""
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/common/storage-account-keys-manage"
]
risk_score = 47
rule_id = "8b4d6c3a-2e9f-4b7c-9a5d-6f8e3c1b4d2a"
severity = "medium"
tags = [
"Domain: Cloud",
"Domain: Identity",
"Use Case: Threat Detection",
"Data Source: Azure",
"Data Source: Azure Activity Logs",
"Tactic: Credential Access",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
data_stream.dataset: "azure.activitylogs" and
azure.activitylogs.operation_name: "MICROSOFT.STORAGE/STORAGEACCOUNTS/LISTKEYS/ACTION" and
azure.activitylogs.identity.authorization.evidence.principal_type: "User" and
azure.activitylogs.identity.authorization.evidence.role: (
"Owner" or
"Contributor" or
"Storage Account Contributor" or
"User Access Administrator"
) and event.outcome: "success"
'''
[rule.new_terms]
field = "new_terms_fields"
value = ["azure.activitylogs.identity.authorization.evidence.principal_id", "azure.resource.name"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-7d"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1555"
name = "Credentials from Password Stores"
reference = "https://attack.mitre.org/techniques/T1555/"
[[rule.threat.technique.subtechnique]]
id = "T1555.006"
name = "Cloud Secrets Management Stores"
reference = "https://attack.mitre.org/techniques/T1555/006/"
[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 = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"
[[rule.threat.technique.subtechnique]]
id = "T1078.004"
name = "Cloud Accounts"
reference = "https://attack.mitre.org/techniques/T1078/004/"
[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
Stages and Predicates
Stage 1: new_terms
data_stream.dataset: "azure.activitylogs" and
azure.activitylogs.operation_name: "MICROSOFT.STORAGE/STORAGEACCOUNTS/LISTKEYS/ACTION" and
azure.activitylogs.identity.authorization.evidence.principal_type: "User" and
azure.activitylogs.identity.authorization.evidence.role: (
"Owner" or
"Contributor" or
"Storage Account Contributor" or
"User Access Administrator"
) and event.outcome: "success"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
azure.activitylogs.identity.authorization.evidence.principal_type | eq |
| field:"azure.activitylogs.identity.authorization.evidence.principal_type" kind:eq value:"User" |
azure.activitylogs.identity.authorization.evidence.role | in |
| field:"azure.activitylogs.identity.authorization.evidence.role" kind:in |
azure.activitylogs.operation_name | eq |
| field:"azure.activitylogs.operation_name" kind:eq value:"MICROSOFT.STORAGE/STORAGEACCOUNTS/LISTKEYS/ACTION" |
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"azure.activitylogs" |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"success" |
Command and Scripting Interpreter via Windows Scripts
#Identifies PowerShell, PowerShell ISE, or Cmd execution spawned from Windows Script Host or MSHTA.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Stealth |
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 1: Process creation |
| Security-Auditing | Event ID 4688: A new process has been created. |
Rule Body
[metadata]
creation_date = "2024/09/09"
integration = ["windows", "system", "sentinel_one_cloud_funnel", "m365_defender", "crowdstrike"]
maturity = "production"
updated_date = "2026/05/03"
[rule]
author = ["Elastic"]
description = "Identifies PowerShell, PowerShell ISE, or Cmd execution spawned from Windows Script Host or MSHTA."
from = "now-9m"
index = [
"logs-m365_defender.event-*",
"logs-sentinel_one_cloud_funnel.*",
"logs-system.security*",
"logs-windows.forwarded*",
"logs-windows.sysmon_operational-*",
"winlogbeat-*",
"endgame-*",
"logs-crowdstrike.fdr*",
]
language = "eql"
license = "Elastic License v2"
name = "Command and Scripting Interpreter via Windows Scripts"
risk_score = 73
rule_id = "2d62889e-e758-4c5e-b57e-c735914ee32a"
severity = "high"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Execution",
"Resources: Investigation Guide",
"Data Source: Windows Security Event Logs",
"Data Source: Sysmon",
"Data Source: SentinelOne",
"Data Source: Microsoft Defender XDR",
"Data Source: Elastic Endgame",
"Data Source: Crowdstrike",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "windows" and event.type == "start" and
process.command_line != null and
(
process.name : ("powershell.exe", "pwsh.exe", "powershell_ise.exe", "cmd.exe") or
?process.pe.original_file_name : ("powershell.exe", "pwsh.dll", "powershell_ise.exe", "Cmd.Exe")
) and
process.parent.name : ("wscript.exe", "mshta.exe") and
not (
process.args : (
"C:\\Program Files\\Intel\\SUR\\QUEENCREEK\\x64\\task.bat",
"\"C:\\Program Files\\Intel\\SUR\\QUEENCREEK\\x64\\task.bat\""
) or
process.command_line : (
"\"C:\\Windows\\system32\\cmd.exe\" /c auditpol.exe /set /SUBCATEGORY:*",
"\"C:\\Windows\\system32\\cmd.exe\" /c auditpol.exe /get*",
"\"C:\\Windows\\system32\\cmd.exe\" /c exit\""
) or
(process.args == "-File" and process.args == "-ExecutionPolicy")
)
and
not (
?user.id == "S-1-5-18" and
/* Don't apply the user.id exclusion to Sysmon for compatibility */
not data_stream.dataset : ("windows.sysmon_operational", "windows.sysmon")
)
'''
note = """## Triage and analysis
### Investigating Command and Scripting Interpreter via Windows Scripts
#### Possible investigation steps
- What script-host-to-interpreter chain did the alert capture?
- Focus: `process.parent.name`, `process.parent.executable`, `process.parent.command_line`, `process.name`, and `process.command_line`.
- Implication: escalate when "wscript.exe" or "mshta.exe" launches PowerShell/pwsh/ISE/cmd from user-writable script/HTA, archive, download path, or URL; lower suspicion only when parent source, child command, `user.id`, and `host.id` fit one recognized logon, deployment, or vendor workflow.
- Does the child command express staging, retrieval, persistence, or defense evasion?
- Focus: `process.command_line`: "-EncodedCommand"/"-e", "-NoProfile", hidden windows, execution-policy bypass, Invoke-Expression/DownloadString, cmd "/c" chaining, curl/bitsadmin retrieval, or schtasks/sc.exe changes.
- Hint: decode or reconstruct encoded or inline PowerShell before deciding intent; use script-block logs as optional corroboration.
- Follow-on: inspect child starts from `process.entity_id`; PID-only matches are timestamp-bound candidates. $investigate_2
- Implication: escalate when the command fetches content, decodes or executes inline script, launches another shell, or changes tasks/services; lower risk only when it runs a local script from the same logon, deployment, or vendor source without staging or unexpected egress.
- Does the child binary identity fit the observed command line and location?
- Focus: `process.executable`, `process.pe.original_file_name`, `process.hash.sha256`, `process.code_signature.subject_name`, and `process.code_signature.trusted`.
- Implication: escalate when the child is renamed, unsigned or untrusted from a user-writable path, or mismatched to original file name; lower identity risk when signer, path, and hash history fit the expected interpreter, but identity alone never clears suspicious command intent.
- Did the alerting process stage scripts, archives, or follow-on payloads?
- Focus: file events scoped by `host.id` plus `process.entity_id`, or `host.id` plus `process.pid` in a tight window, checking `file.path`, `file.Ext.original.path`, `file.Ext.original.extension`, `file.Ext.header_bytes`, and `file.Ext.windows.zone_identifier`. $investigate_0
- Hint: for PID fallback, require file time within the child lifetime.
- Implication: escalate when the child writes or renames scriptable or executable content under temp, profile, public, startup, or deceptive paths, especially with internet provenance or type/extension mismatch; absent file telemetry is unresolved, not benign.
- Did same-process network events show retrieval, staging, or callback behavior?
- Focus: network events scoped by `host.id` plus `process.entity_id`, or `host.id` plus `process.pid` in a tight window, separating DNS `dns.question.name` and `dns.resolved_ip` from connection `destination.ip`, `destination.port`, and `destination.as.organization.name`. $investigate_1
- Hint: map DNS `dns.resolved_ip` to later connections before treating a domain as confirmed.
- Implication: escalate when the process reaches external script-delivery, paste, storage, or C2 infra unrelated to the workflow; lower network risk when connections stay on recognized internal, proxy, or vendor services. Missing network telemetry is unresolved, not benign.
- If local evidence stays suspicious or unresolved, does the same pattern appear in related alerts?
- Focus: related alerts for `user.id`, checking execution, persistence, defense-evasion, or outbound context before comparing preserved `process.parent.executable`, `process.parent.command_line`, or `process.command_line` fragments. $investigate_3
- Hint: use `host.id` alerts to test whether the chain is isolated, repeats with suspicious activity, or appears as adjacent variants such as "cscript.exe" launchers or delayed descendant shells. $investigate_4
- Implication: broaden scope when the same user or host shows repeated script-host launches, task or service changes, persistence, or outbound staging; keep local only when the pattern is isolated and local evidence supports one recognized workflow.
- Escalate when parent provenance, command intent, identity, artifacts, destinations, or related alerts support proxy execution or second-stage activity; close only when alert-local evidence and recovery bind one recognized workflow, with outside confirmation for telemetry gaps; preserve artifacts and escalate when evidence conflicts or visibility is incomplete.
### False positive analysis
- Logon scripts and deployment wrappers can legitimately launch cmd or PowerShell through Windows Script Host. Confirm only when `process.parent.executable`, `process.parent.command_line`, `process.command_line`, `user.id`, `host.id`, and same-process `file.path` or `destination.ip` recovered through `host.id` plus `process.entity_id`, or `host.id` plus `process.pid` in a tight window, align with one recognized workflow. If file or network telemetry is absent, use outside confirmation. Stable recurrence for that parent source, child command, user, and host can support closure when script inventory or change context exists; first-observed workflows need outside confirmation before exceptioning. Any mismatch keeps the case suspicious.
- Vendor/installer/hardware-diagnostic HTA/VBS launchers can trigger this rule. Confirm only when `process.executable`, `process.pe.original_file_name`, `process.hash.sha256`, `process.code_signature.subject_name`, parent script path, file writes, and destinations match one vendor package. Without package context, recurring signer/hash, parent source, child command, and host cohort can support closure; first-observed packages need outside confirmation.
- For exceptions, validate: `process.parent.executable`, `process.parent.command_line`, child `process.executable`, stable `process.command_line` fragment, `process.code_signature.subject_name`, `user.id`, and `host.id`. Avoid exceptions on `process.name`, child `process.executable`, or parent process name alone.
### Response and remediation
- If confirmed benign, reverse temporary containment and record the parent script path, child command pattern, signer, `user.id`, and `host.id` proving the workflow. Create exceptions only for exact workflows recurring in prior rule alerts.
- If suspicious but unconfirmed, preserve the process event, `process.entity_id` or `process.pid` with `host.id` and time, command lines, suspicious `file.path` values, and confirmed `dns.question.name`, `destination.ip`, or `destination.port` before response. Apply reversible containment first: temporary destination blocking, disabling newly created scripts or tasks, or heightened host monitoring. Isolate only when corroborating staging, persistence, or outbound activity is confirmed and interruption is tolerable. Avoid destructive cleanup until scope is clearer.
- If confirmed malicious, preserve `process.entity_id`, `process.parent.entity_id`, command lines, written `file.path` artifacts, and confirmed destinations, then isolate the host or block destinations based on staging and network evidence. Terminate malicious child or descendant processes after evidence capture; if direct endpoint response is unavailable, hand off artifacts for isolation or destination blocking.
- Review related hosts and users for the same parent-child command pattern, confirmed destinations, and confirmed staged files only when endpoint file telemetry or related alerts preserve them. Then remove malicious scripts, HTA content, scheduled tasks, or dropped payloads, and remediate the delivery path.
- Post-incident hardening: restrict unsupported "mshta.exe" and Windows Script Host use on workstations, retain process/file/network telemetry needed for this investigation, and record adjacent variants found during triage.
"""
setup = """## Setup
This rule requires telemetry from one of the configured source integrations to be enabled and ingested.
### Supported data sources
This rule can use the following data sources. For setup instructions, refer to the links below:
- [CrowdStrike](https://ela.st/crowdstrike-integration)
- [Microsoft Defender XDR](https://ela.st/m365-defender)
- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
- [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
- [Windows Process Creation Logs](https://ela.st/audit-process-creation)
"""
[rule.investigation_fields]
field_names = [
"@timestamp",
"host.id",
"user.id",
"process.entity_id",
"process.pid",
"process.executable",
"process.command_line",
"process.pe.original_file_name",
"process.hash.sha256",
"process.code_signature.subject_name",
"process.code_signature.trusted",
"process.parent.name",
"process.parent.executable",
"process.parent.command_line",
"process.parent.args",
]
[transform]
[[transform.investigate]]
label = "File events for the script-launched process"
description = ""
providers = [
[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
{ excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" }
],
[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
{ excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" }
]
]
relativeFrom = "now-1h"
relativeTo = "now"
[[transform.investigate]]
label = "Network events for the script-launched process"
description = ""
providers = [
[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
{ excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" }
],
[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
{ excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" }
]
]
relativeFrom = "now-1h"
relativeTo = "now"
[[transform.investigate]]
label = "Child process events for the script-launched process"
description = ""
providers = [
[
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
{ excluded = false, field = "event.type", queryType = "phrase", value = "start", valueType = "string" },
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
],
[
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
{ excluded = false, field = "event.type", queryType = "phrase", value = "start", valueType = "string" },
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.parent.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
]
]
relativeFrom = "now-1h"
relativeTo = "now"
[[transform.investigate]]
label = "Alerts associated with the user"
description = ""
providers = [
[
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
{ excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
]
]
relativeFrom = "now-48h/h"
relativeTo = "now"
[[transform.investigate]]
label = "Alerts associated with the host"
description = ""
providers = [
[
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
]
]
relativeFrom = "now-48h/h"
relativeTo = "now"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"
[[rule.threat.technique.subtechnique]]
id = "T1059.003"
name = "Windows Command Shell"
reference = "https://attack.mitre.org/techniques/T1059/003/"
[[rule.threat.technique.subtechnique]]
id = "T1059.005"
name = "Visual Basic"
reference = "https://attack.mitre.org/techniques/T1059/005/"
[[rule.threat.technique.subtechnique]]
id = "T1059.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"
[[rule.threat.technique.subtechnique]]
id = "T1218.005"
name = "Mshta"
reference = "https://attack.mitre.org/techniques/T1218/005/"
[rule.threat.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.command_line != null and
(
process.name : ("powershell.exe", "pwsh.exe", "powershell_ise.exe", "cmd.exe") or
?process.pe.original_file_name : ("powershell.exe", "pwsh.dll", "powershell_ise.exe", "Cmd.Exe")
) and
process.parent.name : ("wscript.exe", "mshta.exe") and
not (
process.args : (
"C:\\Program Files\\Intel\\SUR\\QUEENCREEK\\x64\\task.bat",
"\"C:\\Program Files\\Intel\\SUR\\QUEENCREEK\\x64\\task.bat\""
) or
process.command_line : (
"\"C:\\Windows\\system32\\cmd.exe\" /c auditpol.exe /set /SUBCATEGORY:*",
"\"C:\\Windows\\system32\\cmd.exe\" /c auditpol.exe /get*",
"\"C:\\Windows\\system32\\cmd.exe\" /c exit\""
) or
(process.args == "-File" and process.args == "-ExecutionPolicy")
)
and
not (
?user.id == "S-1-5-18" and
not data_stream.dataset : ("windows.sysmon_operational", "windows.sysmon")
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | wildcard |
| field:"data_stream.dataset" kind:wildcard |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.command_line | is_not_null | field:"CommandLine" kind:is_not_null | |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard |
process.pe.original_file_name | wildcard |
| field:"OriginalFileName" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
data_stream.dataset | eq | windows.sysmon_operational, windows.sysmon | excludes:data_stream.dataset field:"data_stream.dataset" value:"windows.sysmon_operational" field:"data_stream.dataset" value:"windows.sysmon" |
user.id | eq | S-1-5-18 | excludes:user.id field:"user.id" value:"S-1-5-18" |
process.args | eq | -ExecutionPolicy | excludes:process.args field:"process.args" value:"-ExecutionPolicy" |
process.args | eq | -File | excludes:process.args field:"process.args" value:"-File" |
process.args | eq | C:\Program Files\Intel\SUR\QUEENCREEK\x64\task.bat, "C:\Program Files\Intel\SUR\QUEENCREEK\x64\task.bat" | excludes:process.args |
process.command_line | wildcard | "C:\Windows\system32\cmd.exe" /c auditpol.exe /set /SUBCATEGORY:*, "C:\Windows\system32\cmd.exe" /c auditpol.exe /get*, "C:\Windows\system32\cmd.exe" /c exit" | excludes:process.command_line |
Curl Execution via CommandLine Shell Script
#Detects when curl is executed as part of a shell script that gets executed via a forked shell interpreter. The activity has been observed in many different samples of the malware known as Shlayer. Shlayer uses this technique in order to avoid traditional scanning and command line detections. The Shlayer malware brings along an encoded shell script within a, usually, signed or sometimes valid application that gets decoded and passed to a forked shell interpreter (to avoid process lineage detections) for execution via the "-c" command parameter.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Command & Control |
Telemetry Coverage
Rule Body
[rule]
description = """
Detects when curl is executed as part of a shell script that gets executed via a forked shell interpreter. The activity
has been observed in many different samples of the malware known as Shlayer. Shlayer uses this technique in order to
avoid traditional scanning and command line detections. The Shlayer malware brings along an encoded shell script within
a, usually, signed or sometimes valid application that gets decoded and passed to a forked shell interpreter (to avoid
process lineage detections) for execution via the "-c" command parameter.
"""
id = "14f0cd76-79cc-46e8-b059-fcca9e41a804"
license = "Elastic License v2"
name = "Curl Execution via CommandLine Shell Script"
os_list = ["macos"]
reference = [
"https://www.sentinelone.com/blog/coming-out-of-your-shell-from-shlayer-to-zshlayer/",
"https://www.uptycs.com/blog/macos-bashed-apples-of-shlayer-and-bundlore",
]
version = "1.0.5"
query = '''
sequence by process.entity_id with maxspan=30s
[process where event.type == "start" and event.action == "fork" and
process.name in ("bash", "sh", "zsh") and
process.args == "-c" and process.args_count == 3 and
process.command_line == null and
process.parent.name in ("bash", "sh", "zsh")]
[process where event.type == "start" and event.action == "exec" and
process.name in ("curl", "nscurl")]
'''
min_endpoint_version = "8.7.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 = "T1105"
name = "Ingress Tool Transfer"
reference = "https://attack.mitre.org/techniques/T1105/"
[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[internal]
min_endpoint_version = "8.7.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 30s, correlated by process.entity_id.
Stage 1: process
[process where event.type == "start" and event.action == "fork" and
process.name in ("bash", "sh", "zsh") and
process.args == "-c" and process.args_count == 3 and
process.command_line == null and
process.parent.name in ("bash", "sh", "zsh")]
Stage 2: process
[process where event.type == "start" and event.action == "exec" and
process.name in ("curl", "nscurl")]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | eq |
| field:"process.args" kind:eq value:"-c" |
process.args_count | eq |
| field:"process.args_count" kind:eq value:"3" |
process.command_line | is_null | field:"CommandLine" kind:is_null | |
process.name | in |
| field:"process_basename" kind:in |
process.parent.name | in |
| field:"parent_process_basename" kind:in |
Decoy Document Creation via Curl
#Detects when Curl is seen creating a .pdf or .doc file in a suspicious directory like /tmp or /users/shared. A recent DPRK sample was seen downloading a decoy document via Curl like this.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution |
Telemetry Coverage
Rule Body
[rule]
description = """
Detects when Curl is seen creating a .pdf or .doc file in a suspicious directory like /tmp or /users/shared. A recent
DPRK sample was seen downloading a decoy document via Curl like this.
"""
id = "a39d0c2f-30d0-4a32-b198-41b135f85bad"
license = "Elastic License v2"
name = "Decoy Document Creation via Curl"
os_list = ["macos"]
reference = ["https://www.kandji.io/blog/todoswift-disguises-malware-download-behind-bitcoin-pdf"]
version = "1.0.14"
query = '''
sequence by process.entity_id with maxspan=1m
[process where event.type == "start" and event.action == "exec" and process.name in ("curl", "nscurl")]
[file where event.action == "modification" and file.path like ("/tmp/*", "/private/tmp/*", "/Users/Shared/*", "/Users/*/Library/*") and
file.extension in ("pdf", "doc") and process.name in ("curl", "nscurl") and
not Effective_process.executable like~ (
"/Applications/Cursor.app/Contents/MacOS/Cursor",
"/Applications/Codex.app/Contents/MacOS/*",
"/Applications/ChatGPT.app/Contents/MacOS/ChatGPT",
"/Applications/Visual Studio Code.app/Contents/MacOS/Code",
"/Users/*/Library/Application Support/Claude/claude-code/*/claude.app/Contents/MacOS/claude",
"/Applications/Visual Studio Code.app/Contents/MacOS/Electron",
"/Users/*/.local/share/claude/versions/*"
) and not
(Effective_process.executable like "/Applications/Microsoft Word.app/Contents/MacOS/Microsoft Word" and
file.path like "/Users/*/Library/Containers/com.microsoft.Word/Data/tmp/Content.MSO/*") and
not file.path like "/private/tmp/claude*"]
'''
min_endpoint_version = "8.11.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "Effective_process.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1204"
name = "User Execution"
reference = "https://attack.mitre.org/techniques/T1204/"
[[threat.technique.subtechnique]]
id = "T1204.002"
name = "Malicious File"
reference = "https://attack.mitre.org/techniques/T1204/002/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[internal]
min_endpoint_version = "8.11.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 1m, correlated by process.entity_id.
Stage 1: process
[process where event.type == "start" and event.action == "exec" and process.name in ("curl", "nscurl")]
Stage 2: file
[file where event.action == "modification" and file.path like ("/tmp/*", "/private/tmp/*", "/Users/Shared/*", "/Users/*/Library/*") and
file.extension in ("pdf", "doc") and process.name in ("curl", "nscurl") and
not Effective_process.executable like~ (
"/Applications/Cursor.app/Contents/MacOS/Cursor",
"/Applications/Codex.app/Contents/MacOS/*",
"/Applications/ChatGPT.app/Contents/MacOS/ChatGPT",
"/Applications/Visual Studio Code.app/Contents/MacOS/Code",
"/Users/*/Library/Application Support/Claude/claude-code/*/claude.app/Contents/MacOS/claude",
"/Applications/Visual Studio Code.app/Contents/MacOS/Electron",
"/Users/*/.local/share/claude/versions/*"
) and not
(Effective_process.executable like "/Applications/Microsoft Word.app/Contents/MacOS/Microsoft Word" and
file.path like "/Users/*/Library/Containers/com.microsoft.Word/Data/tmp/Content.MSO/*") and
not file.path like "/private/tmp/claude*"]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
file.extension | in |
| field:"file.extension" kind:in |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard |
process.name | in |
| field:"process_basename" kind:in |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
Effective_process.executable | eq | /Applications/Microsoft Word.app/Contents/MacOS/Microsoft Word | excludes:Effective_process.executable field:"Effective_process.executable" value:"/Applications/Microsoft Word.app/Contents/MacOS/Microsoft Word" |
file.path | wildcard | /Users/*/Library/Containers/com.microsoft.Word/Data/tmp/Content.MSO/* | excludes:file.path field:"file.path" value:"/Users/*/Library/Containers/com.microsoft.Word/Data/tmp/Content.MSO/*" |
Effective_process.executable | wildcard | /Applications/Cursor.app/Contents/MacOS/Cursor, /Applications/Codex.app/Contents/MacOS/*, /Applications/ChatGPT.app/Contents/MacOS/ChatGPT, /Applications/Visual Studio Code.app/Contents/MacOS/Code, /Users/*/Library/Application Support/Claude/claude-code/*/claude.app/Contents/MacOS/claude, /Applications/Visual Studio Code.app/Contents/MacOS/Electron, /Users/*/.local/share/claude/versions/* | excludes:Effective_process.executable |
file.path | starts_with | /private/tmp/claude | excludes:file.path field:"file.path" value:"/private/tmp/claude" |
DNS Request for IP Lookup Service via Unsigned Binary
#Detects when a DNS request is made for an IP lookup service to determine the external IP address of the system via an unsigned or untrusted binary. This is commonly used by malware for reconnaissance before establishing C2 connections.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Discovery |
Rule Body
[metadata]
creation_date = "2026/01/30"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/05/08"
[rule]
author = ["Elastic"]
description = """
Detects when a DNS request is made for an IP lookup service to determine the external IP address of the
system via an unsigned or untrusted binary. This is commonly used by malware for reconnaissance before
establishing C2 connections.
"""
from = "now-9m"
index = ["logs-endpoint.events.network-*"]
language = "eql"
license = "Elastic License v2"
name = "DNS Request for IP Lookup Service via Unsigned Binary"
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 DNS Request for IP Lookup Service via Unsigned Binary
This detects an unsigned or untrusted process on macOS performing DNS lookups for common “what is my public IP” and geolocation services, a frequent reconnaissance step before external communications. It matters because malware uses the host’s external IP and region to choose C2 infrastructure, gate payload delivery, or evade sandboxing. A typical pattern is a dropped, unsigned Mach-O or script resolving api.ipify.org or ipinfo.io immediately after execution, then initiating outbound beacons.
### Possible investigation steps
- Identify the initiating process and parent chain, then validate whether the binary is expected for the host/user and whether it is actually unsigned versus a transient signature collection issue.
- Review the same process’s near-term network activity for follow-on HTTP(S) requests to the resolved service and any subsequent connections to rare/new domains or IPs that could indicate C2 staging.
- Pivot from the resolved domain to other endpoints to determine prevalence and timing, then prioritize isolated single-host hits with recent first-seen binaries.
- Examine how the binary was introduced by correlating with recent downloads, archive mounts, installer executions, or quarantine/Gatekeeper events around the process start time.
- Acquire and analyze the binary (hash reputation, static strings, entitlements, persistence mechanisms, and launch agents/daemons) to confirm intent and scope of compromise.
### False positive analysis
- A developer-built or locally compiled macOS utility/script (run from a user directory) performs a “what is my public IP” DNS lookup for telemetry, diagnostics, or environment detection, and is flagged because it lacks a trusted code signature.
- An unsigned helper binary dropped by a legitimate installer/updater workflow briefly runs during setup to validate external connectivity or geolocation by resolving an IP-lookup domain, and is detected before the binary is signed or placed in its final trusted location.
### Response and remediation
- Isolate the affected macOS host from the network if the unsigned process continues to resolve IP-lookup domains (e.g., api.ipify.org, ipinfo.io) or initiates new outbound connections immediately after the lookup.
- Quarantine the unsigned executable and any associated scripts from disk (preserving path, hashes, and a copy for analysis) and remove its persistence artifacts such as newly created LaunchAgents/LaunchDaemons, login items, or cron entries tied to the same binary.
- Block the observed IP-lookup domains used by the unsigned process at DNS/web egress and add temporary deny rules for any follow-on suspicious destinations the process contacted after resolution.
- Reset compromised credentials and invalidate active sessions for the logged-in user if the process originated from user-writable locations (Downloads, Desktop, /tmp) or if additional discovery/collection behavior is found on the host.
- Reimage or restore the endpoint from a known-good state when persistence or tampering is confirmed, then verify Gatekeeper/XProtect status, re-enable security tooling, and monitor for recurrence of the same binary hash or domain pattern.
- Escalate to the incident response team if the unsigned binary is newly seen in the environment, appears on multiple hosts, or is followed by connections to rare domains/IPs indicative of staging or command-and-control.
"""
risk_score = 47
rule_id = "47e46d85-3963-44a0-b856-bccff48f8676"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: macOS",
"Use Case: Threat Detection",
"Tactic: Discovery",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
network where host.os.type == "macos" and event.action == "lookup_result" and
(process.code_signature.trusted == false or process.code_signature.exists == false) and
dns.question.name like~ ("*ip-api.com*", "*ipwho.is*", "*checkip.dyndns.org*", "*api.ipify.org*",
"*api.npoint.io*", "*whatismyip.akamai.com*", "*bot.whatismyipaddress.com*",
"*ifcfg.me*", "*ifconfig.me*", "*ident.me*", "*ipof.in*", "*ip.tyk.nu*",
"*ipwhois.app*", "*freeipapi.com*", "*icanhazip.com*", "*curlmyip.com*",
"*wgetip.com*", "*eth0.me*", "*ipecho.net*", "*ip.appspot.com*",
"*api.myip.com*", "*geoiptool.com*", "*api.2ip.ua*", "*api.ip.sb*",
"*ipinfo.io*", "*checkip.amazonaws.com*", "*wtfismyip.com*", "*iplogger.*",
"*freegeoip.net*", "*freegeoip.app*", "*myip.ipip.net*", "*geoplugin.net*",
"*myip.dnsomatic.com*", "*www.geoplugin.net*", "*api64.ipify.org*",
"*ip4.seeip.org*", "*.geojs.io*", "*portmap.io*", "*api.db-ip.com*",
"*geolocation-db.com*", "*inet-ip.info*", "*httpbin.org*", "*myip.opendns.com*") and
not process.executable like "/Users/*/Library/Developer/CoreSimulator/*"
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[rule.threat.tactic]
name = "Discovery"
id = "TA0007"
reference = "https://attack.mitre.org/tactics/TA0007/"
[[rule.threat.technique]]
name = "System Network Configuration Discovery"
id = "T1016"
reference = "https://attack.mitre.org/techniques/T1016/"
[[rule.threat.technique.subtechnique]]
name = "Internet Connection Discovery"
id = "T1016.001"
reference = "https://attack.mitre.org/techniques/T1016/001/"
Stages and Predicates
Stage 1: network
network where host.os.type == "macos" and event.action == "lookup_result" and
(process.code_signature.trusted == false or process.code_signature.exists == false) and
dns.question.name like~ ("*ip-api.com*", "*ipwho.is*", "*checkip.dyndns.org*", "*api.ipify.org*",
"*api.npoint.io*", "*whatismyip.akamai.com*", "*bot.whatismyipaddress.com*",
"*ifcfg.me*", "*ifconfig.me*", "*ident.me*", "*ipof.in*", "*ip.tyk.nu*",
"*ipwhois.app*", "*freeipapi.com*", "*icanhazip.com*", "*curlmyip.com*",
"*wgetip.com*", "*eth0.me*", "*ipecho.net*", "*ip.appspot.com*",
"*api.myip.com*", "*geoiptool.com*", "*api.2ip.ua*", "*api.ip.sb*",
"*ipinfo.io*", "*checkip.amazonaws.com*", "*wtfismyip.com*", "*iplogger.*",
"*freegeoip.net*", "*freegeoip.app*", "*myip.ipip.net*", "*geoplugin.net*",
"*myip.dnsomatic.com*", "*www.geoplugin.net*", "*api64.ipify.org*",
"*ip4.seeip.org*", "*.geojs.io*", "*portmap.io*", "*api.db-ip.com*",
"*geolocation-db.com*", "*inet-ip.info*", "*httpbin.org*", "*myip.opendns.com*") and
not process.executable like "/Users/*/Library/Developer/CoreSimulator/*"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
dns.question.name | wildcard |
| field:"QueryName" kind:wildcard |
event.action | eq |
| field:"EventType" kind:eq value:"lookup_result" |
process.code_signature.exists | eq |
| field:"process.code_signature.exists" kind:eq value:"false" |
process.code_signature.trusted | eq |
| field:"process.code_signature.trusted" kind:eq value:"false" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.executable | wildcard | /Users/*/Library/Developer/CoreSimulator/* | excludes:process.executable field:"process.executable" value:"/Users/*/Library/Developer/CoreSimulator/*" |
Entra ID Multiple Device Registrations by a Single User
#Detects multiple Microsoft Entra ID device registrations by a single user, where three or more distinct devices are registered within a 15-minute window. A legitimate user enrolling a device produces a single "Register device" event; registering multiple distinct devices in quick succession is uncommon and is the fingerprint behavior of adversary-in-the-middle (AiTM) phishing kits and stolen-token replay tooling (for example Kali365), which mint a new Azure AD-joined device, and therefore a new Primary Refresh Token (PRT), per relay or replay attempt. Each registered device is a separate certificate-bound principal whose PRT survives user-level session revocation and password resets, so multiple registrations on a single low-privilege identity establish device-bound persistence at scale.
Known False Positives
- A user legitimately enrolling several devices in a short window (for example, a new laptop and phone during onboarding, or re-registering a device after a wipe) can produce three or more registrations. Validate against the user's device inventory and onboarding activity, and consider raising the threshold or tightening the window if benign multi-device enrollment is common in the environment.
- Bulk provisioning workflows, autopilot/MDM rollouts, or device-management tooling that registers devices on behalf of users may generate multiple registrations across many users at once. Suppress during planned rollout windows.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Persistence | |
| Credential Access |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Azure | Register device |
Rules Detecting the Same Action
These rules filter on the same operation.
- Azure Device No Longer Managed or Compliant (Sigma)
- Azure Device or Configuration Modified or Deleted (Sigma)
- Entra ID AiTM Phishing-Kit Chain Detected (Elastic)
- Entra ID Device Registration with Phishing Kit Default OS Build (Elastic)
- Entra ID Device Registration with ROADtools Default OS Build (Elastic)
- Entra ID Deviceless Windows Hello Sign-in Followed by Device Registration (Elastic)
- Entra ID Protection User Alert and Device Registration (Elastic)
- Entra ID Register Device with Unusual User Agent (Azure AD Join) (Elastic)
Rule Body
[metadata]
creation_date = "2026/06/26"
integration = ["azure"]
maturity = "production"
updated_date = "2026/07/06"
[rule]
author = ["Elastic"]
description = """
Detects multiple Microsoft Entra ID device registrations by a single user, where three or more distinct devices are
registered within a 15-minute window. A legitimate user enrolling a device produces a single "Register device" event;
registering multiple distinct devices in quick succession is uncommon and is the fingerprint behavior of
adversary-in-the-middle (AiTM) phishing kits and stolen-token replay tooling (for example Kali365), which mint a new
Azure AD-joined device, and therefore a new Primary Refresh Token (PRT), per relay or replay attempt. Each registered
device is a separate certificate-bound principal whose PRT survives user-level session revocation and password resets,
so multiple registrations on a single low-privilege identity establish device-bound persistence at scale.
"""
false_positives = [
"""
A user legitimately enrolling several devices in a short window (for example, a new laptop and phone during
onboarding, or re-registering a device after a wipe) can produce three or more registrations. Validate against the
user's device inventory and onboarding activity, and consider raising the threshold or tightening the window if
benign multi-device enrollment is common in the environment.
""",
"""
Bulk provisioning workflows, autopilot/MDM rollouts, or device-management tooling that registers devices on behalf
of users may generate multiple registrations across many users at once. Suppress during planned rollout windows.
""",
]
from = "now-30m"
language = "esql"
license = "Elastic License v2"
name = "Entra ID Multiple Device Registrations by a Single User"
note = """## Triage and analysis
### Investigating Entra ID Multiple Device Registrations by a Single User
A single Entra ID "Register device" event is routine: a user enrolling one device emits one registration. Concentrating three or more distinct device registrations onto one user inside a 15-minute window is uncommon for legitimate activity and is the fingerprint of either:
- An AiTM phishing-kit relay session that, after capturing the victim's sign-in, registers one or more Azure AD-joined devices of its own from the kit infrastructure within minutes (observed cadence of roughly one device every 2-6 minutes, e.g. Kali365 registering five devices in ~12 minutes).
- Token-replay tooling driving multiple device joins in quick succession off a stolen refresh token or PRT.
Each registered device is a separate principal with its own certificate-bound PRT. Because user-level controls (`revokeSignInSessions`, password reset) do not invalidate device-bound PRTs, every device left in place is an independent, persistent foothold.
### Possible investigation steps
- Identify the user (`azure.auditlogs.properties.initiated_by.user.userPrincipalName`) and review the registered devices in `Esql.device_name_values`. Tool-driven joins frequently use default Windows-style names such as `DESKTOP-<6 alphanumeric>` and a homogeneous, hardcoded OS build.
- Inspect `Esql.user_agent_values` from the `Register device` events. A spoofed Windows device-registration client string (`Dsreg/10.0 (Windows <build>)`) or a raw HTTP client (`axios/*`, `python-requests/*`, `Microsoft.OData.Client/*`) instead of a genuine browser/endpoint user agent is high-fidelity tooling.
- Pivot to the paired `Add device` events for each device (correlate via `azure.correlation_id`) and review the modified properties: `DeviceOSType`, `DeviceOSVersion`/`CloudDeviceOSVersion`, and `DeviceTrustType`. A `DeviceTrustType` of `AzureAd` (full join) on a low-privilege user, and an identical hardcoded OS build across all devices in the window, are strong indicators.
- Review the origin surfaced on the alert: `Esql.source_ip_values`, `Esql.source_as_number_values`, `Esql.source_as_organization_values`, and `Esql.source_country_values`/`Esql.source_city_values`/`Esql.source_region_values`. Hosting/VPS ASNs (for example Tencent, Alibaba, or other cloud providers) and unexpected geographies for a device-registration event are high-fidelity suspicious. A single source IP/ASN across every registration in the window is consistent with one piece of kit infrastructure driving the joins.
- Cross-reference `logs-azure.signinlogs-*` for the same user around the registration window. The registrations are brokered through the `Microsoft Authentication Broker` application against the `Device Registration Service` resource; confirm whether the broker was subsequently used to mint tokens for other resources (for example Microsoft Graph) from the same source.
- Cross-reference `logs-azure.auditlogs-*` for a security-info / MFA method registration (`User registered security info`) by the same user near the registration window; AiTM kits commonly plant their own MFA method alongside the device persistence.
- Confirm with the user whether they performed a multi-device enrollment or onboarding action during the window.
### False positive analysis
- New-device or onboarding flows where a user enrolls three or more devices in a short window can fire. Validate against the user's known device inventory and any onboarding or device-refresh events.
- Bulk provisioning, autopilot, or MDM rollouts can register multiple devices per user concurrently. Consider suppression during planned rollouts.
- If benign multi-device enrollment is routine in the environment, raise the distinct-device threshold or shorten the window.
### Response and remediation
- Treat as likely AiTM compromise or token replay until proven otherwise. Remove the rogue device registrations BEFORE revoking sessions, because device-bound PRTs survive `revokeSignInSessions` and a device left in place re-establishes access.
- `GET /v1.0/users/{id}/registeredDevices` and `/ownedDevices`, then `DELETE /v1.0/devices/{deviceObjectId}` for each unrecognized device in the window.
- Revoke refresh tokens and sessions, then reset credentials and re-register MFA.
- `POST /v1.0/users/{id}/revokeSignInSessions`.
- Temporarily disable the account if activity must be halted during investigation.
- `PATCH /v1.0/users/{id}` with body `{"accountEnabled": false}`.
- Remove other attacker persistence established alongside the device joins: attacker-registered MFA methods, malicious inbox/forwarding rules, and OAuth consents.
- Hunt for the same device-name pattern, OS build, and registration user agent across other users and tenants, and apply Conditional Access to restrict device registration (require a compliant/managed device or trusted network).
"""
references = [
"https://any.run/malware-trends/kali365/",
"https://www.huntress.com/blog/kali365-device-code-phishing-kit",
"https://www.ic3.gov/PSA/2026/PSA260521",
"https://arcticwolf.com/resources/blog/token-bingo-dont-let-your-code-be-the-winner/"
]
risk_score = 47
rule_id = "960b1cef-f94d-4150-863d-b1dc311739de"
severity = "medium"
tags = [
"Domain: Cloud",
"Domain: Identity",
"Data Source: Azure",
"Data Source: Microsoft Entra ID",
"Data Source: Microsoft Entra ID Audit Logs",
"Use Case: Identity and Access Audit",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Tactic: Initial Access",
"Tactic: Credential Access",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-azure.auditlogs-*
| where data_stream.dataset == "azure.auditlogs"
and azure.auditlogs.operation_name == "Register device"
and azure.auditlogs.properties.initiated_by.user.userPrincipalName is not null
// For "Register device" the registered device is the primary target resource (index 0);
// target_resources is a numeric-indexed object array in this integration, so wildcard/name-based matching is not available.
and `azure.auditlogs.properties.target_resources.0.display_name` is not null
| eval Esql.bucket_window = date_trunc(15 minutes, @timestamp)
| stats
Esql.count_distinct_devices = count_distinct(`azure.auditlogs.properties.target_resources.0.display_name`),
Esql.device_name_values = values(`azure.auditlogs.properties.target_resources.0.display_name`),
Esql.user_agent_values = values(azure.auditlogs.properties.userAgent),
Esql.source_ip_values = values(source.ip),
Esql.source_as_number_values = values(source.`as`.number),
Esql.source_as_organization_values = values(source.`as`.organization.name),
Esql.source_country_values = values(source.geo.country_name),
Esql.source_city_values = values(source.geo.city_name),
Esql.source_region_values = values(source.geo.region_name),
Esql.correlation_id_values = values(azure.correlation_id),
Esql.timestamp_first_seen = min(@timestamp),
Esql.timestamp_last_seen = max(@timestamp),
Esql.event_count = count(*)
by azure.auditlogs.properties.initiated_by.user.userPrincipalName, Esql.bucket_window
| where Esql.count_distinct_devices >= 3
| keep azure.auditlogs.properties.initiated_by.user.userPrincipalName, Esql.*
'''
[[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.005"
name = "Device Registration"
reference = "https://attack.mitre.org/techniques/T1098/005/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"
[[rule.threat.technique.subtechnique]]
id = "T1078.004"
name = "Cloud Accounts"
reference = "https://attack.mitre.org/techniques/T1078/004/"
[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1557"
name = "Adversary-in-the-Middle"
reference = "https://attack.mitre.org/techniques/T1557/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[rule.investigation_fields]
field_names = [
"azure.auditlogs.properties.initiated_by.user.userPrincipalName",
"Esql.count_distinct_devices",
"Esql.device_name_values",
"Esql.user_agent_values",
"Esql.source_ip_values",
"Esql.source_as_organization_values",
]
Stages and Predicates
Stage 1: from
from logs-azure.auditlogs-*
Stage 2: where
| where data_stream.dataset == "azure.auditlogs"
and azure.auditlogs.operation_name == "Register device"
and azure.auditlogs.properties.initiated_by.user.userPrincipalName is not null
and `azure.auditlogs.properties.target_resources.0.display_name` is not null
Stage 3: eval
| eval Esql.bucket_window = date_trunc(15 minutes, @timestamp)
Stage 4: stats
| stats
Esql.count_distinct_devices = count_distinct(`azure.auditlogs.properties.target_resources.0.display_name`),
Esql.device_name_values = values(`azure.auditlogs.properties.target_resources.0.display_name`),
Esql.user_agent_values = values(azure.auditlogs.properties.userAgent),
Esql.source_ip_values = values(source.ip),
Esql.source_as_number_values = values(source.`as`.number),
Esql.source_as_organization_values = values(source.`as`.organization.name),
Esql.source_country_values = values(source.geo.country_name),
Esql.source_city_values = values(source.geo.city_name),
Esql.source_region_values = values(source.geo.region_name),
Esql.correlation_id_values = values(azure.correlation_id),
Esql.timestamp_first_seen = min(@timestamp),
Esql.timestamp_last_seen = max(@timestamp),
Esql.event_count = count(*)
by azure.auditlogs.properties.initiated_by.user.userPrincipalName, Esql.bucket_window
Stage 5: where
| where Esql.count_distinct_devices >= 3
Stage 6: keep
| keep azure.auditlogs.properties.initiated_by.user.userPrincipalName, Esql.*
Indicators
These rows show field, operator, and value matches.
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
azure.auditlogs.properties.initiated_by.user.userPrincipalName | KEEP azure.auditlogs.properties.initiated_by.user.userPrincipalName |
Esql.* | KEEP Esql.* |
Entra ID User Sign-in with Unusual Client
#Detects rare non-interactive sign-ins where an Entra ID client application authenticates on behalf of a principal user using an application (client) ID that is not commonly associated with that user's historical sign-in behavior. Adversaries with stolen credentials or OAuth tokens may abuse Entra ID–managed or first-party client IDs to perform on-behalf-of (OBO) authentication, blending into legitimate cloud traffic while avoiding traditional interactive sign-in flows. This technique is commonly observed in OAuth phishing, token theft, and access broker operations, and may precede lateral movement, persistence, or data access via Microsoft Graph or other cloud resources. The rule uses a New Terms approach to identify first-seen combinations of the UPN and Client ID within a defined history window, helping surface unexpected client usage that may indicate compromised identities, malicious automation, or unauthorized application impersonation.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Stealth | |
| Credential Access | |
| Lateral Movement |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2025/03/10"
integration = ["azure"]
maturity = "production"
updated_date = "2026/08/12"
[rule]
author = ["Elastic"]
description = """
Detects rare non-interactive sign-ins where an Entra ID client application authenticates on behalf of a principal user
using an application (client) ID that is not commonly associated with that user's historical sign-in behavior.
Adversaries with stolen credentials or OAuth tokens may abuse Entra ID–managed or first-party client IDs to perform
on-behalf-of (OBO) authentication, blending into legitimate cloud traffic while avoiding traditional interactive sign-in
flows. This technique is commonly observed in OAuth phishing, token theft, and access broker operations, and may precede
lateral movement, persistence, or data access via Microsoft Graph or other cloud resources. The rule uses a New Terms
approach to identify first-seen combinations of the UPN and Client ID within a defined history window, helping surface
unexpected client usage that may indicate compromised identities, malicious automation, or unauthorized application
impersonation.
"""
from = "now-9m"
index = ["filebeat-*", "logs-azure.signinlogs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Entra ID User Sign-in with Unusual Client"
note = """## Triage and analysis
### Investigating Entra ID User Sign-in with Unusual Client
This rule identifies rare Azure Entra apps IDs requesting authentication on-behalf-of a principal user. An adversary with stolen credentials may specify an Azure-managed app ID to authenticate on-behalf-of a user. This is a rare event and may indicate an attempt to bypass conditional access policies (CAP) and multi-factor authentication (MFA) requirements. The app ID specified may not be commonly used by the user based on their historical sign-in activity.
### Possible investigation steps
- Identify the source IP address from which the failed login attempts originated by reviewing `source.ip`. Determine if the IP is associated with known malicious activity using threat intelligence sources or if it belongs to a corporate VPN, proxy, or automation process.
- Analyze affected user accounts by reviewing `azure.signinlogs.properties.user_principal_name` to determine if they belong to privileged roles or high-value users. Look for patterns indicating multiple failed attempts across different users, which could suggest a password spraying attempt.
- Examine the authentication method used in `azure.signinlogs.properties.authentication_details` to identify which authentication protocols were attempted and why they failed. Legacy authentication methods may be more susceptible to brute-force attacks.
- Review the authentication error codes found in `azure.signinlogs.properties.status.error_code` to understand why the login attempts failed. Common errors include `50126` for invalid credentials, `50053` for account lockouts, `50055` for expired passwords, and `50056` for users without a password.
- Correlate failed logins with other sign-in activity by looking at `event.outcome`. Identify if there were any successful logins from the same user shortly after multiple failures or if there are different geolocations or device fingerprints associated with the same account.
- Review `azure.signinlogs.properties.app_id` to identify which applications were initiating the authentication attempts. Determine if these applications are Microsoft-owned, third-party, or custom applications and if they are authorized to access the resources.
- Check for any conditional access policies that may have been triggered by the failed login attempts by reviewing `azure.signinlogs.properties.authentication_requirement`. This can help identify if the failed attempts were due to policy enforcement or misconfiguration.
## False positive analysis
- Automated scripts or applications using non-interactive authentication may trigger this detection, particularly if they rely on legacy authentication protocols recorded in `azure.signinlogs.properties.authentication_protocol`.
- Corporate proxies or VPNs may cause multiple users to authenticate from the same IP, appearing as repeated failed attempts under `source.ip`.
- User account lockouts from forgotten passwords or misconfigured applications may show multiple authentication failures in `azure.signinlogs.properties.status.error_code`.
- Exclude known trusted IPs, such as corporate infrastructure, from alerts by filtering `source.ip`.
- Exclude known custom applications from `azure.signinlogs.properties.app_id` that are authorized to use non-interactive authentication.
- Microsoft Feedback Portal UX generates benign first-seen client activity through PRT-based, non-interactive sign-ins and is excluded by application ID.
- Microsoft Teams routinely requests tokens for its internal Teams Services, IC3 Gateway, Chat Aggregator, and CMD Services resources; these client-resource combinations are excluded.
- Managed Windows devices routinely request OfficeHome PRTs with Microsoft 365 Copilot scopes through the standard Microsoft 365 desktop client; this combination is excluded.
- Ignore principals with a history of failed logins due to legitimate reasons, such as expired passwords or account lockouts, by filtering `azure.signinlogs.properties.user_principal_name`.
- Correlate sign-in failures with password reset events or normal user behavior before triggering an alert.
## Response and remediation
- Block the source IP address in `source.ip` if determined to be malicious.
- Reset passwords for all affected user accounts listed in `azure.signinlogs.properties.user_principal_name` and enforce stronger password policies.
- Ensure basic authentication is disabled for all applications using legacy authentication protocols listed in `azure.signinlogs.properties.authentication_protocol`.
- Enable multi-factor authentication (MFA) for impacted accounts to mitigate credential-based attacks.
- Review conditional access policies to ensure they are correctly configured to block unauthorized access attempts recorded in `azure.signinlogs.properties.authentication_requirement`.
- Review Conditional Access policies to enforce risk-based authentication and block unauthorized access attempts recorded in `azure.signinlogs.properties.authentication_requirement`.
- Implement a zero-trust security model by enforcing least privilege access and continuous authentication.
- Regularly review and update conditional access policies to ensure they are effective against evolving threats.
- Restrict the use of legacy authentication protocols by disabling authentication methods listed in `azure.signinlogs.properties.client_app_used`.
- Regularly audit authentication logs in `azure.signinlogs` to detect abnormal login behavior and ensure early detection of potential attacks.
- Regularly rotate client credentials and secrets for applications using non-interactive authentication to reduce the risk of credential theft.
"""
references = ["https://securityscorecard.com/wp-content/uploads/2025/02/MassiveBotnet-Report_022125_03.pdf"]
risk_score = 47
rule_id = "c766bc56-fdca-11ef-b194-f661ea17fbcd"
severity = "medium"
tags = [
"Domain: Cloud",
"Domain: Identity",
"Data Source: Azure",
"Data Source: Entra ID",
"Data Source: Entra ID Sign-in",
"Platform: Entra ID",
"Use Case: Identity and Access Audit",
"Use Case: Threat Detection",
"Tactic: Initial Access",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
data_stream.dataset: "azure.signinlogs" and event.category: "authentication"
and azure.signinlogs.properties.is_interactive: false
and azure.signinlogs.properties.user_type: "Member"
and not azure.signinlogs.properties.client_app_used: "Browser"
and not source.as.organization.name: "MICROSOFT-CORP-MSN-AS-BLOCK"
and not azure.signinlogs.properties.app_id: (
"1b3c667f-cde3-4090-b60b-3d2abd0117f0" or
"26a7ee05-5602-4d76-a7ba-eae8b7b67941" or
"4b0964e4-58f1-47f4-a552-e2e1fc56dcd7" or
"ecd6b820-32c2-49b6-98a6-444530e5a77a" or
"268761a2-03f3-40df-8a8b-c3db24145b6b" or
"fc0f3af4-6835-4174-b806-f7db311fd2f3" or
"de50c81f-5f80-4771-b66b-cebd28ccdfc1" or
"ab9b8c07-8f02-4f72-87fa-80105867a763" or
"6f7e0f60-9401-4f5b-98e2-cf15bd5fd5e3" or
"d7b530a4-7680-4c23-a8bf-c52c121d2e87" or
"52c2e0b5-c7b6-4d11-a89c-21e42bcec444" or
"38aa3b87-a06d-4817-b275-7a316988d93b" or
"27922004-5251-4030-b22d-91ecd9a37ea4" or
"9ba1a5c7-f17a-4de9-a1f1-6178c8d51223" or
"cab96880-db5b-4e15-90a7-f3f1d62ffe39" or
"3a4d129e-7f50-4e0d-a7fd-033add0a29f4" or
"29d9ed98-a469-4536-ade2-f981bc1d605e" or
"c0ab8ce9-e9a0-42e7-b064-33d422df41f1" or
"9ea1ad79-fdb6-4f9a-8bc3-2b70f96e34c7" or
"4813382a-8fa7-425e-ab75-3b753aab3abb" or
"08e18876-6177-487e-b8b5-cf950c1e598c" or
"0ec893e0-5785-4de6-99da-4ed124e5296c" or
"d3590ed6-52b3-4102-aeff-aad2292ab01c" or
"0dc2408a-bbc0-4238-871e-13b372f0200f" or
"af124e86-4e96-495a-b70a-90f90ab96707" or
"e9c51622-460d-4d3d-952d-966a5b1da34c" or
"f44b1140-bc5e-48c6-8dc0-5cf5a53c0e34" or
"e2ef5054-0287-4db6-afa3-013d96881fd3" or
"82864fa0-ed49-4711-8395-a0e6003dca1f" or
"60c8bde5-3167-4f92-8fdb-059f6176dc0f" or
"5d661950-3475-41cd-a2c3-d671a3162bc1" or
"145fc680-eb72-4bcf-b4d5-8277021a1ce8" or
"c1c74fed-04c9-4704-80dc-9f79a2e515cb" or
"a2760c41-63c9-42b5-8d58-bfa1fd9e2eb3" or
"6dec647e-42c4-45a6-8f13-e8250d34e033" or
"c98e5057-edde-4666-b301-186a01b4dc58" or
"0a31c71e-0abf-4238-add7-b1a24c165dc1" or
"a8759234-4b8b-4d94-8c0a-ee1ab73af270" or
"dae89220-69ba-4957-a77a-47b78695e883" or
"fd5f78f6-a28f-450b-abc7-777f3dbbfcba" or
"821caec6-bec3-4542-bead-d3c5fb6b4ef0" or
"a40d7d7d-59aa-447e-a655-679a4107e548" or
"bed12bc0-3a62-470d-998c-e47546e7b039" or
"f4060917-6abe-40d7-baa6-f634c0eda4ac" or
"b26aadf8-566f-4478-926f-589f601d9c74" or
"1f7f6f43-2f81-429c-8499-293566d0ab0c" or
"75f31797-37c9-498e-8dc9-53c16a36afca" or
"3e050dd7-7815-46a0-8263-b73168a42c10" or
"243c63a3-247d-41c5-9d83-7788c43f1c43" or
"75efb5bc-18a1-4e7b-8a66-2ad2503d79c6" or
"d32f3b53-b7d7-48df-8d0f-f8bf233b3f1f" or
"95de633a-083e-42f5-b444-a4295d8e9314" or
"3ff8e6ba-7dc3-4e9e-ba40-ee12b60d6d48" or
"871c010f-5e61-4fb1-83ac-98610a7e9110" or
"3e62f81e-590b-425b-9531-cad6683656cf" or
"8ec6bc83-69c8-4392-8f08-b3c986009232" or
"d326c1ce-6cc6-4de2-bebc-4591e5e13ef0" or
"dd762716-544d-4aeb-a526-687b73838a22" or
"7f8f922d-7ee4-40a6-b435-aad8b84ebde0" or
"f8d98a96-0999-43f5-8af3-69971c7bb423" or
"aa580612-c342-4ace-9055-8edee43ccb89" or
"7f67af8a-fedc-4b08-8b4e-37c4d127b6cf" or
"00bf137d-f689-4c5d-83d9-7fc31904a7ea" or
"ceb96695-e468-48ba-ba21-35e2a242d396" or
"7fba38f4-ec1f-458d-906c-f4e3c4f41335" or
"a2a1fecc-b06e-4a1e-95c1-2afd94bcadff" or
"15ddab63-ba81-45db-9bb6-6f8bc445c459" or
"bc59ab01-8403-45c6-8796-ac3ef710b3e3" or
"00000003-0000-0ff1-ce00-000000000000" or
"4e291c71-d680-4d0e-9640-0a3358e31177" or
"4fb5cc57-dbbc-4cdc-9595-748adff5f414" or
"22098786-6e16-43cc-a27d-191a01a1e3b5" or
"ebde7daf-df42-4ade-81a4-d67b339b49e9" or
"c0d2a505-13b8-4ae0-aa9e-cddd5eab0b12" or
"a672d62c-fc7b-4e81-a576-e60dc46e951d" or
"0b1df6d3-2deb-44d4-b44b-7101937e0726" or
"04f0c124-f2bc-4f59-8241-bf6df9866bbd" or
"86f4c005-6582-4559-b6cf-8b3111236736" or
"a0a3c1d3-7b82-4010-bdb0-e7048fb8f1fe" or
"a187e399-0c36-4b98-8f04-1edc167a0996" or
"2d4d3d8e-2be3-4bef-9f87-7875a61c29de" or
"c475db56-f463-48d8-931a-cfa7cd642289" or
"71a7c376-13e6-4100-968e-92ce98c5d3d2"
)
and not (
azure.signinlogs.properties.app_id: "1fec8e78-bce4-4aaf-ab1b-5451cc387264" and
azure.signinlogs.properties.resource_id: (
"cc15fd57-2c6c-4117-a88c-83b1d56b4bbe" or
"39aaf054-81a5-48c7-a4f8-0293012095b9" or
"b1379a75-ce5e-4fa3-80c6-89bb39bf646c" or
"6bc3b958-689b-49f5-9006-36d165f30e00"
)
)
and not (
azure.signinlogs.properties.app_id: "4765445b-32c6-49b0-83e6-1d93765276ca" and
azure.signinlogs.properties.resource_id: "4765445b-32c6-49b0-83e6-1d93765276ca" and
azure.signinlogs.properties.authentication_processing_details: *M365Copilot.Read.All* and
azure.signinlogs.properties.incoming_token_type: "primaryRefreshToken" and
azure.signinlogs.properties.client_app_used: "Mobile Apps and Desktop clients" and
azure.signinlogs.properties.device_detail.is_managed: true and
azure.signinlogs.properties.device_detail.operating_system: "Windows10" and
user_agent.original: Mozilla*Edge/18.*
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"
[[rule.threat.technique.subtechnique]]
id = "T1078.004"
name = "Cloud Accounts"
reference = "https://attack.mitre.org/techniques/T1078/004/"
[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1528"
name = "Steal Application Access Token"
reference = "https://attack.mitre.org/techniques/T1528/"
[rule.threat.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.001"
name = "Application Access Token"
reference = "https://attack.mitre.org/techniques/T1550/001/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[rule.investigation_fields]
field_names = [
"azure.signinlogs.properties.user_principal_name",
"azure.signinlogs.properties.user_id",
"azure.signinlogs.properties.app_id",
"azure.signinlogs.properties.app_display_name",
"azure.signinlogs.properties.client_app_used",
"azure.signinlogs.properties.incoming_token_type",
"azure.signinlogs.properties.authentication_protocol",
"azure.signinlogs.properties.authentication_requirement",
"azure.signinlogs.properties.token_issuer_type",
"azure.signinlogs.properties.resource_display_name",
"source.ip",
"source.as.number",
"source.geo.country_name",
"azure.signinlogs.properties.correlation_id",
"azure.signinlogs.properties.session_id",
]
[rule.new_terms]
field = "new_terms_fields"
value = ["azure.signinlogs.properties.user_principal_name", "azure.signinlogs.properties.app_id"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-14d"
Stages and Predicates
Stage 1: new_terms
data_stream.dataset: "azure.signinlogs" and event.category: "authentication"
and azure.signinlogs.properties.is_interactive: false
and azure.signinlogs.properties.user_type: "Member"
and not azure.signinlogs.properties.client_app_used: "Browser"
and not source.as.organization.name: "MICROSOFT-CORP-MSN-AS-BLOCK"
and not azure.signinlogs.properties.app_id: (
"1b3c667f-cde3-4090-b60b-3d2abd0117f0" or
"26a7ee05-5602-4d76-a7ba-eae8b7b67941" or
"4b0964e4-58f1-47f4-a552-e2e1fc56dcd7" or
"ecd6b820-32c2-49b6-98a6-444530e5a77a" or
"268761a2-03f3-40df-8a8b-c3db24145b6b" or
"fc0f3af4-6835-4174-b806-f7db311fd2f3" or
"de50c81f-5f80-4771-b66b-cebd28ccdfc1" or
"ab9b8c07-8f02-4f72-87fa-80105867a763" or
"6f7e0f60-9401-4f5b-98e2-cf15bd5fd5e3" or
"d7b530a4-7680-4c23-a8bf-c52c121d2e87" or
"52c2e0b5-c7b6-4d11-a89c-21e42bcec444" or
"38aa3b87-a06d-4817-b275-7a316988d93b" or
"27922004-5251-4030-b22d-91ecd9a37ea4" or
"9ba1a5c7-f17a-4de9-a1f1-6178c8d51223" or
"cab96880-db5b-4e15-90a7-f3f1d62ffe39" or
"3a4d129e-7f50-4e0d-a7fd-033add0a29f4" or
"29d9ed98-a469-4536-ade2-f981bc1d605e" or
"c0ab8ce9-e9a0-42e7-b064-33d422df41f1" or
"9ea1ad79-fdb6-4f9a-8bc3-2b70f96e34c7" or
"4813382a-8fa7-425e-ab75-3b753aab3abb" or
"08e18876-6177-487e-b8b5-cf950c1e598c" or
"0ec893e0-5785-4de6-99da-4ed124e5296c" or
"d3590ed6-52b3-4102-aeff-aad2292ab01c" or
"0dc2408a-bbc0-4238-871e-13b372f0200f" or
"af124e86-4e96-495a-b70a-90f90ab96707" or
"e9c51622-460d-4d3d-952d-966a5b1da34c" or
"f44b1140-bc5e-48c6-8dc0-5cf5a53c0e34" or
"e2ef5054-0287-4db6-afa3-013d96881fd3" or
"82864fa0-ed49-4711-8395-a0e6003dca1f" or
"60c8bde5-3167-4f92-8fdb-059f6176dc0f" or
"5d661950-3475-41cd-a2c3-d671a3162bc1" or
"145fc680-eb72-4bcf-b4d5-8277021a1ce8" or
"c1c74fed-04c9-4704-80dc-9f79a2e515cb" or
"a2760c41-63c9-42b5-8d58-bfa1fd9e2eb3" or
"6dec647e-42c4-45a6-8f13-e8250d34e033" or
"c98e5057-edde-4666-b301-186a01b4dc58" or
"0a31c71e-0abf-4238-add7-b1a24c165dc1" or
"a8759234-4b8b-4d94-8c0a-ee1ab73af270" or
"dae89220-69ba-4957-a77a-47b78695e883" or
"fd5f78f6-a28f-450b-abc7-777f3dbbfcba" or
"821caec6-bec3-4542-bead-d3c5fb6b4ef0" or
"a40d7d7d-59aa-447e-a655-679a4107e548" or
"bed12bc0-3a62-470d-998c-e47546e7b039" or
"f4060917-6abe-40d7-baa6-f634c0eda4ac" or
"b26aadf8-566f-4478-926f-589f601d9c74" or
"1f7f6f43-2f81-429c-8499-293566d0ab0c" or
"75f31797-37c9-498e-8dc9-53c16a36afca" or
"3e050dd7-7815-46a0-8263-b73168a42c10" or
"243c63a3-247d-41c5-9d83-7788c43f1c43" or
"75efb5bc-18a1-4e7b-8a66-2ad2503d79c6" or
"d32f3b53-b7d7-48df-8d0f-f8bf233b3f1f" or
"95de633a-083e-42f5-b444-a4295d8e9314" or
"3ff8e6ba-7dc3-4e9e-ba40-ee12b60d6d48" or
"871c010f-5e61-4fb1-83ac-98610a7e9110" or
"3e62f81e-590b-425b-9531-cad6683656cf" or
"8ec6bc83-69c8-4392-8f08-b3c986009232" or
"d326c1ce-6cc6-4de2-bebc-4591e5e13ef0" or
"dd762716-544d-4aeb-a526-687b73838a22" or
"7f8f922d-7ee4-40a6-b435-aad8b84ebde0" or
"f8d98a96-0999-43f5-8af3-69971c7bb423" or
"aa580612-c342-4ace-9055-8edee43ccb89" or
"7f67af8a-fedc-4b08-8b4e-37c4d127b6cf" or
"00bf137d-f689-4c5d-83d9-7fc31904a7ea" or
"ceb96695-e468-48ba-ba21-35e2a242d396" or
"7fba38f4-ec1f-458d-906c-f4e3c4f41335" or
"a2a1fecc-b06e-4a1e-95c1-2afd94bcadff" or
"15ddab63-ba81-45db-9bb6-6f8bc445c459" or
"bc59ab01-8403-45c6-8796-ac3ef710b3e3" or
"00000003-0000-0ff1-ce00-000000000000" or
"4e291c71-d680-4d0e-9640-0a3358e31177" or
"4fb5cc57-dbbc-4cdc-9595-748adff5f414" or
"22098786-6e16-43cc-a27d-191a01a1e3b5" or
"ebde7daf-df42-4ade-81a4-d67b339b49e9" or
"c0d2a505-13b8-4ae0-aa9e-cddd5eab0b12" or
"a672d62c-fc7b-4e81-a576-e60dc46e951d" or
"0b1df6d3-2deb-44d4-b44b-7101937e0726" or
"04f0c124-f2bc-4f59-8241-bf6df9866bbd" or
"86f4c005-6582-4559-b6cf-8b3111236736" or
"a0a3c1d3-7b82-4010-bdb0-e7048fb8f1fe" or
"a187e399-0c36-4b98-8f04-1edc167a0996" or
"2d4d3d8e-2be3-4bef-9f87-7875a61c29de" or
"c475db56-f463-48d8-931a-cfa7cd642289" or
"71a7c376-13e6-4100-968e-92ce98c5d3d2"
)
and not (
azure.signinlogs.properties.app_id: "1fec8e78-bce4-4aaf-ab1b-5451cc387264" and
azure.signinlogs.properties.resource_id: (
"cc15fd57-2c6c-4117-a88c-83b1d56b4bbe" or
"39aaf054-81a5-48c7-a4f8-0293012095b9" or
"b1379a75-ce5e-4fa3-80c6-89bb39bf646c" or
"6bc3b958-689b-49f5-9006-36d165f30e00"
)
)
and not (
azure.signinlogs.properties.app_id: "4765445b-32c6-49b0-83e6-1d93765276ca" and
azure.signinlogs.properties.resource_id: "4765445b-32c6-49b0-83e6-1d93765276ca" and
azure.signinlogs.properties.authentication_processing_details: *M365Copilot.Read.All* and
azure.signinlogs.properties.incoming_token_type: "primaryRefreshToken" and
azure.signinlogs.properties.client_app_used: "Mobile Apps and Desktop clients" and
azure.signinlogs.properties.device_detail.is_managed: true and
azure.signinlogs.properties.device_detail.operating_system: "Windows10" and
user_agent.original: Mozilla*Edge/18.*
)
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
azure.signinlogs.properties.app_id | eq | 1fec8e78-bce4-4aaf-ab1b-5451cc387264 | excludes:azure.signinlogs.properties.app_id field:"azure.signinlogs.properties.app_id" value:"1fec8e78-bce4-4aaf-ab1b-5451cc387264" |
azure.signinlogs.properties.resource_id | in | 39aaf054-81a5-48c7-a4f8-0293012095b9, 6bc3b958-689b-49f5-9006-36d165f30e00, b1379a75-ce5e-4fa3-80c6-89bb39bf646c, cc15fd57-2c6c-4117-a88c-83b1d56b4bbe | excludes:azure.signinlogs.properties.resource_id |
azure.signinlogs.properties.app_id | eq | 4765445b-32c6-49b0-83e6-1d93765276ca | excludes:azure.signinlogs.properties.app_id field:"azure.signinlogs.properties.app_id" value:"4765445b-32c6-49b0-83e6-1d93765276ca" |
azure.signinlogs.properties.authentication_processing_details | match | M365Copilot.Read.All | excludes:azure.signinlogs.properties.authentication_processing_details field:"azure.signinlogs.properties.authentication_processing_details" value:"M365Copilot.Read.All" |
azure.signinlogs.properties.client_app_used | eq | Mobile Apps and Desktop clients | excludes:azure.signinlogs.properties.client_app_used field:"azure.signinlogs.properties.client_app_used" value:"Mobile Apps and Desktop clients" |
azure.signinlogs.properties.device_detail.is_managed | eq | true | excludes:azure.signinlogs.properties.device_detail.is_managed field:"azure.signinlogs.properties.device_detail.is_managed" value:"true" |
azure.signinlogs.properties.device_detail.operating_system | eq | Windows10 | excludes:azure.signinlogs.properties.device_detail.operating_system field:"azure.signinlogs.properties.device_detail.operating_system" value:"Windows10" |
azure.signinlogs.properties.incoming_token_type | eq | primaryRefreshToken | excludes:azure.signinlogs.properties.incoming_token_type field:"azure.signinlogs.properties.incoming_token_type" value:"primaryRefreshToken" |
azure.signinlogs.properties.resource_id | eq | 4765445b-32c6-49b0-83e6-1d93765276ca | excludes:azure.signinlogs.properties.resource_id field:"azure.signinlogs.properties.resource_id" value:"4765445b-32c6-49b0-83e6-1d93765276ca" |
user_agent.original | wildcard | Mozilla*Edge/18.* | excludes:user_agent.original field:"user_agent.original" value:"Mozilla*Edge/18.*" |
azure.signinlogs.properties.app_id | in | 00000003-0000-0ff1-ce00-000000000000, 00bf137d-f689-4c5d-83d9-7fc31904a7ea, 04f0c124-f2bc-4f59-8241-bf6df9866bbd, 08e18876-6177-487e-b8b5-cf950c1e598c, 0a31c71e-0abf-4238-add7-b1a24c165dc1, 0b1df6d3-2deb-44d4-b44b-7101937e0726, 0dc2408a-bbc0-4238-871e-13b372f0200f, 0ec893e0-5785-4de6-99da-4ed124e5296c, 145fc680-eb72-4bcf-b4d5-8277021a1ce8, 15ddab63-ba81-45db-9bb6-6f8bc445c459, 1b3c667f-cde3-4090-b60b-3d2abd0117f0, 1f7f6f43-2f81-429c-8499-293566d0ab0c, 22098786-6e16-43cc-a27d-191a01a1e3b5, 243c63a3-247d-41c5-9d83-7788c43f1c43, 268761a2-03f3-40df-8a8b-c3db24145b6b, 26a7ee05-5602-4d76-a7ba-eae8b7b67941, 27922004-5251-4030-b22d-91ecd9a37ea4, 29d9ed98-a469-4536-ade2-f981bc1d605e, 2d4d3d8e-2be3-4bef-9f87-7875a61c29de, 38aa3b87-a06d-4817-b275-7a316988d93b, 3a4d129e-7f50-4e0d-a7fd-033add0a29f4, 3e050dd7-7815-46a0-8263-b73168a42c10, 3e62f81e-590b-425b-9531-cad6683656cf, 3ff8e6ba-7dc3-4e9e-ba40-ee12b60d6d48, 4813382a-8fa7-425e-ab75-3b753aab3abb, 4b0964e4-58f1-47f4-a552-e2e1fc56dcd7, 4e291c71-d680-4d0e-9640-0a3358e31177, 4fb5cc57-dbbc-4cdc-9595-748adff5f414, 52c2e0b5-c7b6-4d11-a89c-21e42bcec444, 5d661950-3475-41cd-a2c3-d671a3162bc1, 60c8bde5-3167-4f92-8fdb-059f6176dc0f, 6dec647e-42c4-45a6-8f13-e8250d34e033, 6f7e0f60-9401-4f5b-98e2-cf15bd5fd5e3, 71a7c376-13e6-4100-968e-92ce98c5d3d2, 75efb5bc-18a1-4e7b-8a66-2ad2503d79c6, 75f31797-37c9-498e-8dc9-53c16a36afca, 7f67af8a-fedc-4b08-8b4e-37c4d127b6cf, 7f8f922d-7ee4-40a6-b435-aad8b84ebde0, 7fba38f4-ec1f-458d-906c-f4e3c4f41335, 821caec6-bec3-4542-bead-d3c5fb6b4ef0, 82864fa0-ed49-4711-8395-a0e6003dca1f, 86f4c005-6582-4559-b6cf-8b3111236736, 871c010f-5e61-4fb1-83ac-98610a7e9110, 8ec6bc83-69c8-4392-8f08-b3c986009232, 95de633a-083e-42f5-b444-a4295d8e9314, 9ba1a5c7-f17a-4de9-a1f1-6178c8d51223, 9ea1ad79-fdb6-4f9a-8bc3-2b70f96e34c7, a0a3c1d3-7b82-4010-bdb0-e7048fb8f1fe, a187e399-0c36-4b98-8f04-1edc167a0996, a2760c41-63c9-42b5-8d58-bfa1fd9e2eb3, a2a1fecc-b06e-4a1e-95c1-2afd94bcadff, a40d7d7d-59aa-447e-a655-679a4107e548, a672d62c-fc7b-4e81-a576-e60dc46e951d, a8759234-4b8b-4d94-8c0a-ee1ab73af270, aa580612-c342-4ace-9055-8edee43ccb89, ab9b8c07-8f02-4f72-87fa-80105867a763, af124e86-4e96-495a-b70a-90f90ab96707, b26aadf8-566f-4478-926f-589f601d9c74, bc59ab01-8403-45c6-8796-ac3ef710b3e3, bed12bc0-3a62-470d-998c-e47546e7b039, c0ab8ce9-e9a0-42e7-b064-33d422df41f1, c0d2a505-13b8-4ae0-aa9e-cddd5eab0b12, c1c74fed-04c9-4704-80dc-9f79a2e515cb, c475db56-f463-48d8-931a-cfa7cd642289, c98e5057-edde-4666-b301-186a01b4dc58, cab96880-db5b-4e15-90a7-f3f1d62ffe39, ceb96695-e468-48ba-ba21-35e2a242d396, d326c1ce-6cc6-4de2-bebc-4591e5e13ef0, d32f3b53-b7d7-48df-8d0f-f8bf233b3f1f, d3590ed6-52b3-4102-aeff-aad2292ab01c, d7b530a4-7680-4c23-a8bf-c52c121d2e87, dae89220-69ba-4957-a77a-47b78695e883, dd762716-544d-4aeb-a526-687b73838a22, de50c81f-5f80-4771-b66b-cebd28ccdfc1, e2ef5054-0287-4db6-afa3-013d96881fd3, e9c51622-460d-4d3d-952d-966a5b1da34c, ebde7daf-df42-4ade-81a4-d67b339b49e9, ecd6b820-32c2-49b6-98a6-444530e5a77a, f4060917-6abe-40d7-baa6-f634c0eda4ac, f44b1140-bc5e-48c6-8dc0-5cf5a53c0e34, f8d98a96-0999-43f5-8af3-69971c7bb423, fc0f3af4-6835-4174-b806-f7db311fd2f3, fd5f78f6-a28f-450b-abc7-777f3dbbfcba | excludes:azure.signinlogs.properties.app_id |
azure.signinlogs.properties.client_app_used | eq | Browser | excludes:azure.signinlogs.properties.client_app_used field:"azure.signinlogs.properties.client_app_used" value:"Browser" |
source.as.organization.name | eq | MICROSOFT-CORP-MSN-AS-BLOCK | excludes:source.as.organization.name field:"source.as.organization.name" value:"MICROSOFT-CORP-MSN-AS-BLOCK" |
Execution via Electron Child Process Node.js Module
#Identifies attempts to execute a child process from within the context of an Electron application using the child_process Node.js module. Adversaries may abuse this technique to inherit permissions from parent processes.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Privilege Escalation |
Telemetry Coverage
Rule Body
[rule]
description = """
Identifies attempts to execute a child process from within the context of an Electron application using the
child_process Node.js module. Adversaries may abuse this technique to inherit permissions from parent processes.
"""
id = "1d43f87d-2466-4714-8fef-d52816cc25fb"
license = "Elastic License v2"
name = "Execution via Electron Child Process Node.js Module"
os_list = ["macos"]
reference = [
"https://www.matthewslipper.com/2019/09/22/everything-you-wanted-electron-child-process.html",
"https://www.trustedsec.com/blog/macos-injection-via-third-party-frameworks/",
"https://nodejs.org/api/child_process.html",
]
version = "1.0.36"
query = '''
process where event.action == "exec" and
process.args == "-e" and process.command_line like~ "*require*child_process*" and
process.command_line like~ "*spawn*" and
(
/* Spawning shells with inline commands */
process.command_line like~ ("*spawn*bash*-c*", "*spawn*sh*-c*", "*spawn*zsh*-c*") or
/* Spawning curl/wget for download */
process.command_line like~ ("*spawn*curl*", "*spawn*wget*") or
/* Spawning osascript */
process.command_line like~ "*spawn*osascript*" or
/* Spawning python with inline code */
process.command_line like~ "*spawn*python*-c*" or
/* Base64 decode patterns */
process.command_line like~ "*spawn*base64*" or
/* Execution from suspicious staging paths */
process.command_line like~ ("*spawn*/tmp/*", "*spawn*/Users/Shared/*", "*spawn*/private/tmp/*", "*spawn*/var/tmp/*")
) and
not process.executable like
("/usr/bin/grep",
"/Applications/Docker.app/Contents/Resources/bin/docker",
"/Applications/Docker.app/Contents/Resources/bin/com.docker.cli") and
not process.Ext.effective_parent.executable like
("/Users/*/Library/Application Support/Claude/claude-code/*/claude.app/Contents/MacOS/claude",
"/Applications/ChatGPT.app/Contents/MacOS/ChatGPT")
'''
min_endpoint_version = "8.10.2"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1548"
name = "Abuse Elevation Control Mechanism"
reference = "https://attack.mitre.org/techniques/T1548/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "8.10.2"
Stages and Predicates
Stage 1: process
process where event.action == "exec" and
process.args == "-e" and process.command_line like~ "*require*child_process*" and
process.command_line like~ "*spawn*" and
(
process.command_line like~ ("*spawn*bash*-c*", "*spawn*sh*-c*", "*spawn*zsh*-c*") or
process.command_line like~ ("*spawn*curl*", "*spawn*wget*") or
process.command_line like~ "*spawn*osascript*" or
process.command_line like~ "*spawn*python*-c*" or
process.command_line like~ "*spawn*base64*" or
process.command_line like~ ("*spawn*/tmp/*", "*spawn*/Users/Shared/*", "*spawn*/private/tmp/*", "*spawn*/var/tmp/*")
) and
not process.executable like
("/usr/bin/grep",
"/Applications/Docker.app/Contents/Resources/bin/docker",
"/Applications/Docker.app/Contents/Resources/bin/com.docker.cli") and
not process.Ext.effective_parent.executable like
("/Users/*/Library/Application Support/Claude/claude-code/*/claude.app/Contents/MacOS/claude",
"/Applications/ChatGPT.app/Contents/MacOS/ChatGPT")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
process.args | eq |
| field:"process.args" kind:eq value:"-e" |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.Ext.effective_parent.executable | wildcard | /Users/*/Library/Application Support/Claude/claude-code/*/claude.app/Contents/MacOS/claude, /Applications/ChatGPT.app/Contents/MacOS/ChatGPT | excludes:process.Ext.effective_parent.executable field:"process.Ext.effective_parent.executable" value:"/Users/*/Library/Application Support/Claude/claude-code/*/claude.app/Contents/MacOS/claude" field:"process.Ext.effective_parent.executable" value:"/Applications/ChatGPT.app/Contents/MacOS/ChatGPT" |
process.executable | eq | /usr/bin/grep, /Applications/Docker.app/Contents/Resources/bin/docker, /Applications/Docker.app/Contents/Resources/bin/com.docker.cli | excludes:process.executable field:"process.executable" value:"/usr/bin/grep" field:"process.executable" value:"/Applications/Docker.app/Contents/Resources/bin/docker" field:"process.executable" value:"/Applications/Docker.app/Contents/Resources/bin/com.docker.cli" |
GCP Firewall Rule Deletion
#Identifies when a firewall rule is deleted in Google Cloud Platform (GCP) for Virtual Private Cloud (VPC) or App Engine. These firewall rules can be configured to allow or deny connections to or from virtual machine (VM) instances or specific applications. An adversary may delete a firewall rule in order to weaken their target's security controls.
Known False Positives
- Firewall rules may be deleted by system administrators. Verify that the firewall configuration change was expected. Exceptions can be added to this rule to filter expected behavior.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2020/09/21"
integration = ["gcp"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
Identifies when a firewall rule is deleted in Google Cloud Platform (GCP) for Virtual Private Cloud (VPC) or App Engine.
These firewall rules can be configured to allow or deny connections to or from virtual machine (VM) instances or
specific applications. An adversary may delete a firewall rule in order to weaken their target's security controls.
"""
false_positives = [
"""
Firewall rules may be deleted by system administrators. Verify that the firewall configuration change was expected.
Exceptions can be added to this rule to filter expected behavior.
""",
]
index = ["filebeat-*", "logs-gcp*"]
language = "kuery"
license = "Elastic License v2"
name = "GCP Firewall Rule Deletion"
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating GCP Firewall Rule Deletion
In GCP, firewall rules are crucial for controlling network traffic to and from VM instances and applications, ensuring robust security. Adversaries may delete these rules to bypass security measures, facilitating unauthorized access or data exfiltration. The detection rule monitors audit logs for deletion actions, flagging potential defense evasion attempts by identifying specific deletion events in VPC or App Engine environments.
### Possible investigation steps
- Review the audit logs for the specific event.dataset:gcp.audit to confirm the deletion action and gather details such as the timestamp, user identity, and source IP address associated with the event.
- Investigate the event.action field to determine whether the deletion occurred in the VPC or App Engine environment, and identify the specific firewall rule that was deleted.
- Check the user or service account activity around the time of the deletion to identify any suspicious behavior or unauthorized access attempts.
- Assess the impact of the deleted firewall rule by reviewing the network traffic patterns and security posture before and after the deletion.
- Collaborate with the network security team to determine if the deletion was part of a legitimate change management process or if it indicates a potential security incident.
### False positive analysis
- Routine maintenance or updates by authorized personnel may trigger firewall rule deletions. To manage this, create exceptions for known maintenance windows or specific user accounts responsible for these tasks.
- Automated scripts or tools used for infrastructure management might delete and recreate firewall rules as part of their normal operation. Identify these scripts and exclude their actions from triggering alerts by using service accounts or tags associated with these tools.
- Changes in application deployment processes, especially in environments like App Engine, can lead to legitimate firewall rule deletions. Review deployment logs and processes to identify patterns and exclude these from alerts.
- Organizational policy changes that involve restructuring network security may result in bulk deletions of firewall rules. Coordinate with network security teams to understand planned changes and temporarily adjust detection rules during these periods.
- Test environments often have dynamic configurations where firewall rules are frequently added and removed. Exclude specific projects or environments designated for testing from the detection rule to reduce noise.
### Response and remediation
- Immediately isolate affected VM instances or applications by applying restrictive firewall rules to prevent further unauthorized access or data exfiltration.
- Review audit logs to identify the source of the deletion action, including user accounts and IP addresses involved, and verify if the action was authorized.
- Recreate the deleted firewall rules based on the last known good configuration to restore security controls and prevent unauthorized access.
- Conduct a security review of the affected environment to identify any additional unauthorized changes or indicators of compromise.
- Escalate the incident to the security operations team for further investigation and to determine if additional systems or data were impacted.
- Implement enhanced monitoring and alerting for firewall rule changes to detect and respond to similar threats more quickly in the future.
- Review and update access controls and permissions for users and service accounts to ensure that only authorized personnel can modify firewall rules.
## Setup
The GCP Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
references = [
"https://cloud.google.com/vpc/docs/firewalls",
"https://cloud.google.com/appengine/docs/standard/python/understanding-firewalls",
]
risk_score = 47
rule_id = "ff9b571e-61d6-4f6c-9561-eb4cca3bafe1"
severity = "medium"
tags = [
"Domain: Cloud",
"Data Source: GCP",
"Data Source: Google Cloud Platform",
"Use Case: Configuration Audit",
"Tactic: Defense Evasion",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:gcp.audit and event.action:(*.compute.firewalls.delete or google.appengine.*.Firewall.Delete*Rule)
'''
[[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.007"
name = "Disable or Modify Cloud Firewall"
reference = "https://attack.mitre.org/techniques/T1562/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:gcp.audit and event.action:(*.compute.firewalls.delete or google.appengine.*.Firewall.Delete*Rule)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"gcp.audit" |
event.action | wildcard |
| field:"EventType" kind:wildcard |
Incoming Execution via PowerShell Remoting
#Identifies remote execution via Windows PowerShell remoting. Windows PowerShell remoting allows a user to run any Windows PowerShell command on one or more remote computers. This could be an indication of lateral movement.
Known False Positives
- PowerShell remoting is a dual-use protocol that can be used for benign or malicious activity. It's important to baseline your environment to determine the amount of noise to expect from this tool.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Lateral Movement |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2020/11/24"
integration = ["endpoint", "windows", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2026/05/04"
[rule]
author = ["Elastic"]
description = """
Identifies remote execution via Windows PowerShell remoting. Windows PowerShell remoting allows a user to run any
Windows PowerShell command on one or more remote computers. This could be an indication of lateral movement.
"""
false_positives = [
"""
PowerShell remoting is a dual-use protocol that can be used for benign or malicious activity. It's important to
baseline your environment to determine the amount of noise to expect from this tool.
""",
]
from = "now-9m"
index = [
"winlogbeat-*",
"logs-endpoint.events.process-*",
"logs-endpoint.events.network-*",
"logs-windows.sysmon_operational-*",
"logs-sentinel_one_cloud_funnel.*",
]
language = "eql"
license = "Elastic License v2"
name = "Incoming Execution via PowerShell Remoting"
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 Incoming Execution via PowerShell Remoting
PowerShell Remoting enables administrators to execute commands on remote Windows systems, facilitating efficient management. However, adversaries can exploit this feature for lateral movement within a network. The detection rule identifies suspicious activity by monitoring network traffic on specific ports and processes initiated by PowerShell Remoting, flagging potential unauthorized remote executions.
### Possible investigation steps
- Review the network traffic logs to identify the source IP address involved in the alert, ensuring it is not a known or authorized management system.
- Check the destination port (5985 or 5986) to confirm it aligns with PowerShell Remoting activity and verify if the connection was expected or authorized.
- Investigate the process tree on the affected host to determine if the process initiated by wsmprovhost.exe is legitimate or if it shows signs of suspicious activity.
- Examine the parent process of wsmprovhost.exe to identify any unusual or unauthorized processes that may have triggered the PowerShell Remoting session.
- Correlate the event with user activity logs to determine if the remote execution was performed by a legitimate user or if there are signs of compromised credentials.
- Assess the risk score and severity in the context of the organization's environment to prioritize the response and determine if further containment or remediation actions are necessary.
### False positive analysis
- Legitimate administrative tasks using PowerShell Remoting can trigger the rule. To manage this, identify and whitelist known administrative IP addresses or user accounts that frequently perform remote management tasks.
- Automated scripts or scheduled tasks that use PowerShell Remoting for system maintenance might be flagged. Review and document these scripts, then create exceptions for their specific process names or execution paths.
- Security tools or monitoring solutions that leverage PowerShell Remoting for legitimate purposes may cause alerts. Verify these tools and exclude their associated network traffic or processes from the detection rule.
- Internal IT support activities that involve remote troubleshooting using PowerShell Remoting can be mistaken for threats. Maintain a list of support personnel and their IP addresses to exclude them from triggering alerts.
- Regular software updates or patch management processes that utilize PowerShell Remoting should be considered. Identify these processes and exclude their network traffic or process executions to prevent false positives.
### Response and remediation
- Isolate the affected host immediately from the network to prevent further lateral movement by the adversary.
- Terminate any suspicious PowerShell processes identified, especially those initiated by wsmprovhost.exe, to stop unauthorized remote executions.
- Conduct a thorough review of recent user activity and access logs on the affected host to identify any unauthorized access or changes.
- Reset credentials for any accounts that were used in the suspicious activity to prevent further unauthorized access.
- Apply patches and updates to the affected systems to address any vulnerabilities that may have been exploited.
- Enhance monitoring on the network for unusual activity on ports 5985 and 5986 to detect any future attempts at unauthorized PowerShell Remoting.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if additional systems are compromised."""
references = [
"https://docs.microsoft.com/en-us/powershell/scripting/learn/remoting/running-remote-commands?view=powershell-7.1",
]
risk_score = 47
rule_id = "2772264c-6fb9-4d9d-9014-b416eed21254"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Lateral Movement",
"Tactic: Execution",
"Data Source: Elastic Defend",
"Data Source: Sysmon",
"Data Source: SentinelOne",
"Resources: Investigation Guide",
]
type = "eql"
query = '''
sequence by host.id with maxspan = 30s
[network where host.os.type == "windows" and network.direction : ("incoming", "ingress") and destination.port in (5985, 5986) and
source.ip != "127.0.0.1" and source.ip != "::1"]
[process where host.os.type == "windows" and
event.type == "start" and process.parent.name : "wsmprovhost.exe" and not process.executable : "?:\\Windows\\System32\\conhost.exe"]
'''
setup = """## Setup
This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
Setup instructions: https://ela.st/install-elastic-defend
### Additional data sources
This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
- [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
- [Sysmon Event ID 3 - Network Connection](https://ela.st/sysmon-event-3-setup)
"""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1021"
name = "Remote Services"
reference = "https://attack.mitre.org/techniques/T1021/"
[[rule.threat.technique.subtechnique]]
id = "T1021.006"
name = "Windows Remote Management"
reference = "https://attack.mitre.org/techniques/T1021/006/"
[rule.threat.tactic]
id = "TA0008"
name = "Lateral Movement"
reference = "https://attack.mitre.org/tactics/TA0008/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
Stages and Predicates
Ordered sequence: each step below must occur in order within 30s, correlated by host.id.
Stage 1: network
[network where host.os.type == "windows" and network.direction : ("incoming", "ingress") and destination.port in (5985, 5986) and
source.ip != "127.0.0.1" and source.ip != "::1"]
Stage 2: process
[process where host.os.type == "windows" and
event.type == "start" and process.parent.name : "wsmprovhost.exe" and not process.executable : "?:\\Windows\\System32\\conhost.exe"]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
destination.port | in |
| field:"DestinationPort" kind:in |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
network.direction | wildcard |
| field:"Initiated" kind:wildcard |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard value:"wsmprovhost.exe" |
source.ip | ne |
| field:"src_ip" kind:ne |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.executable | eq | ?:\Windows\System32\conhost.exe | excludes:process.executable field:"process.executable" value:"?:\Windows\System32\conhost.exe" |
KDE AutoStart Script or Desktop File Creation
#Identifies the creation or modification of a K Desktop Environment (KDE) AutoStart script or desktop file that will execute upon each user logon. Adversaries may abuse this method for persistence.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence |
Rule Body
[metadata]
creation_date = "2021/01/06"
integration = ["endpoint", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2026/03/24"
[transform]
[[transform.osquery]]
label = "Osquery - Retrieve File Listing Information"
query = """
SELECT * FROM file WHERE ( path LIKE '/home/%/.config/autostart/%.sh' OR path LIKE '/home/%/.config/autostart/%.desktop'
OR path LIKE '/root/.config/autostart/%.sh' OR path LIKE '/root/.config/autostart/%.desktop' OR path LIKE
'/home/%/.kde/Autostart/%.sh' OR path LIKE '/home/%/.kde/Autostart/%.desktop' OR path LIKE '/root/.kde/Autostart/%.sh'
OR path LIKE '/root/.kde/Autostart/%.desktop' OR path LIKE '/home/%/.kde4/Autostart/%.sh' OR path LIKE
'/home/%/.kde4/Autostart/%.desktop' OR path LIKE '/root/.kde4/Autostart/%.sh' OR path LIKE
'/root/.kde4/Autostart/%.desktop' OR path LIKE '/home/%/.kde/share/autostart/%.sh' OR path LIKE
'/home/%/.kde/share/autostart/%.desktop' OR path LIKE '/root/.kde/share/autostart/%.sh' OR path LIKE
'/root/.kde/share/autostart/%.desktop' OR path LIKE '/home/%/.kde4/share/autostart/%.sh' OR path LIKE
'/home/%/.kde4/share/autostart/%.desktop' OR path LIKE '/root/.kde4/share/autostart/%.sh' OR path LIKE
'/root/.kde4/share/autostart/%.desktop' OR path LIKE '/home/%/.local/share/autostart/%.sh' OR path LIKE
'/home/%/.local/share/autostart/%.desktop' OR path LIKE '/root/.local/share/autostart/%.sh' OR path LIKE
'/root/.local/share/autostart/%.desktop' OR path LIKE '/home/%/.config/autostart-scripts/%.sh' OR path LIKE
'/home/%/.config/autostart-scripts/%.desktop' OR path LIKE '/root/.config/autostart-scripts/%.sh' OR path LIKE
'/root/.config/autostart-scripts/%.desktop' OR path LIKE '/etc/xdg/autostart/%.sh' OR path LIKE
'/etc/xdg/autostart/%.desktop' OR path LIKE '/usr/share/autostart/%.sh' OR path LIKE '/usr/share/autostart/%.desktop' )
"""
[[transform.osquery]]
label = "Osquery - Retrieve Additional File Listing Information"
query = """
SELECT f.path, u.username AS file_owner, g.groupname AS group_owner, datetime(f.atime, 'unixepoch') AS
file_last_access_time, datetime(f.mtime, 'unixepoch') AS file_last_modified_time, datetime(f.ctime, 'unixepoch') AS
file_last_status_change_time, datetime(f.btime, 'unixepoch') AS file_created_time, f.size AS size_bytes FROM file f LEFT
JOIN users u ON f.uid = u.uid LEFT JOIN groups g ON f.gid = g.gid WHERE ( path LIKE '/home/%/.config/autostart/%.sh' OR
path LIKE '/home/%/.config/autostart/%.desktop' OR path LIKE '/root/.config/autostart/%.sh' OR path LIKE
'/root/.config/autostart/%.desktop' OR path LIKE '/home/%/.kde/Autostart/%.sh' OR path LIKE
'/home/%/.kde/Autostart/%.desktop' OR path LIKE '/root/.kde/Autostart/%.sh' OR path LIKE
'/root/.kde/Autostart/%.desktop' OR path LIKE '/home/%/.kde4/Autostart/%.sh' OR path LIKE
'/home/%/.kde4/Autostart/%.desktop' OR path LIKE '/root/.kde4/Autostart/%.sh' OR path LIKE
'/root/.kde4/Autostart/%.desktop' OR path LIKE '/home/%/.kde/share/autostart/%.sh' OR path LIKE
'/home/%/.kde/share/autostart/%.desktop' OR path LIKE '/root/.kde/share/autostart/%.sh' OR path LIKE
'/root/.kde/share/autostart/%.desktop' OR path LIKE '/home/%/.kde4/share/autostart/%.sh' OR path LIKE
'/home/%/.kde4/share/autostart/%.desktop' OR path LIKE '/root/.kde4/share/autostart/%.sh' OR path LIKE
'/root/.kde4/share/autostart/%.desktop' OR path LIKE '/home/%/.local/share/autostart/%.sh' OR path LIKE
'/home/%/.local/share/autostart/%.desktop' OR path LIKE '/root/.local/share/autostart/%.sh' OR path LIKE
'/root/.local/share/autostart/%.desktop' OR path LIKE '/home/%/.config/autostart-scripts/%.sh' OR path LIKE
'/home/%/.config/autostart-scripts/%.desktop' OR path LIKE '/root/.config/autostart-scripts/%.sh' OR path LIKE
'/root/.config/autostart-scripts/%.desktop' OR path LIKE '/etc/xdg/autostart/%.sh' OR path LIKE
'/etc/xdg/autostart/%.desktop' OR path LIKE '/usr/share/autostart/%.sh' OR path LIKE '/usr/share/autostart/%.desktop' )
"""
[[transform.osquery]]
label = "Osquery - Retrieve Running Processes by User"
query = "SELECT pid, username, name FROM processes p JOIN users u ON u.uid = p.uid ORDER BY username"
[[transform.osquery]]
label = "Osquery - Retrieve Crontab Information"
query = "SELECT * FROM crontab"
[[transform.osquery]]
label = "Osquery - Retrieve Listening Ports"
query = "SELECT pid, address, port, socket, protocol, path FROM listening_ports"
[[transform.osquery]]
label = "Osquery - Retrieve Open Sockets"
query = "SELECT pid, family, remote_address, remote_port, socket, state FROM process_open_sockets"
[[transform.osquery]]
label = "Osquery - Retrieve Information for a Specific User"
query = "SELECT * FROM users WHERE username = {{user.name}}"
[[transform.osquery]]
label = "Osquery - Investigate the Account Authentication Status"
query = "SELECT * FROM logged_in_users WHERE user = {{user.name}}"
[rule]
author = ["Elastic"]
description = """
Identifies the creation or modification of a K Desktop Environment (KDE) AutoStart script or desktop file that will
execute upon each user logon. Adversaries may abuse this method for persistence.
"""
from = "now-9m"
index = ["auditbeat-*", "endgame-*", "logs-endpoint.events.file*", "logs-sentinel_one_cloud_funnel.*"]
language = "eql"
license = "Elastic License v2"
name = "KDE AutoStart Script or Desktop File Creation"
note = """## Triage and analysis
### Investigating KDE AutoStart Script or Desktop File Creation
K Desktop Environment (KDE) is a popular graphical desktop environment for Linux systems. It supports AutoStart scripts and desktop files that execute automatically upon user logon.
Adversaries may exploit this feature to maintain persistence on a compromised system by creating or modifying these files.
The detection rule 'KDE AutoStart Script or Desktop File Creation' is designed to identify such activities by monitoring file events on Linux systems. It specifically targets the creation or modification of files with extensions ".sh" or ".desktop" in various AutoStart directories. By detecting these events, the rule helps security analysts identify potential abuse of KDE AutoStart functionality by malicious actors.
> **Note**:
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/current/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.
> This investigation guide uses [placeholder fields](https://www.elastic.co/guide/en/security/current/osquery-placeholder-fields.html) to dynamically pass alert data into Osquery queries. Placeholder fields were introduced in Elastic Stack version 8.7.0. If you're using Elastic Stack version 8.6.0 or earlier, you'll need to manually adjust this investigation guide's queries to ensure they properly run.
### Possible investigation steps
- Investigate the file that was created or modified.
- $osquery_0
- $osquery_1
- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence and whether they are located in expected locations.
- $osquery_2
- Investigate other alerts associated with the user/host during the past 48 hours.
- Validate the activity is not related to planned patches, updates, network administrator activity, or legitimate software installations.
- Investigate whether the altered scripts call other malicious scripts elsewhere on the file system.
- If scripts or executables were dropped, retrieve the files and determine if they are malicious:
- Use a private sandboxed malware analysis system to perform analysis.
- Observe and collect information about the following activities:
- Attempts to contact external domains and addresses.
- Check if the domain is newly registered or unexpected.
- Check the reputation of the domain or IP address.
- File access, modification, and creation activities.
- Cron jobs, services and other persistence mechanisms.
- $osquery_3
- Investigate abnormal behaviors by the subject process/user such as network connections, file modifications, and any other spawned child processes.
- Investigate listening ports and open sockets to look for potential command and control traffic or data exfiltration.
- $osquery_4
- $osquery_5
- Identify the user account that performed the action, analyze it, and check whether it should perform this kind of action.
- $osquery_6
- Investigate whether the user is currently logged in and active.
- $osquery_7
### False positive analysis
- If this activity is related to new benign software installation activity, consider adding exceptions — preferably with a combination of user and command line conditions.
- If this activity is related to a system administrator who uses cron jobs for administrative purposes, consider adding exceptions for this specific administrator user account.
- Try to understand the context of the execution by thinking about the user, machine, or business purpose. A small number of endpoints, such as servers with unique software, might appear unusual but satisfy a specific business need.
### Response and Remediation
- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- If the triage identified malware, search the environment for additional compromised hosts.
- Implement temporary network rules, procedures, and segmentation to contain the malware.
- Stop suspicious processes.
- Immediately block the identified indicators of compromise (IoCs).
- Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that attackers could use to reinfect the system.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Leverage the incident response data and logging to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
references = [
"https://userbase.kde.org/System_Settings/Autostart",
"https://www.amnesty.org/en/latest/research/2020/09/german-made-finspy-spyware-found-in-egypt-and-mac-and-linux-versions-revealed/",
"https://www.intezer.com/blog/research/operation-electrorat-attacker-creates-fake-companies-to-drain-your-crypto-wallets/",
"https://www.elastic.co/security-labs/primer-on-persistence-mechanisms",
]
risk_score = 47
rule_id = "e3e904b3-0a8e-4e68-86a8-977a163e21d3"
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).
#### Custom Ingest Pipeline
For versions <8.2, you need to add a custom ingest pipeline to populate `event.ingested` with @timestamp for non-elastic-agent indexes, like auditbeats/filebeat/winlogbeat etc. For more details to add a custom ingest pipeline refer to the [guide](https://www.elastic.co/guide/en/fleet/current/data-streams-pipeline-tutorial.html).
"""
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Data Source: Elastic Endgame",
"Data Source: Elastic Defend",
"Data Source: SentinelOne",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
file where host.os.type == "linux" and event.type == "creation" and process.executable != null and
file.extension in ("sh", "desktop") and
file.path like (
"/home/*/.config/autostart/*", "/root/.config/autostart/*",
"/home/*/.kde/Autostart/*", "/root/.kde/Autostart/*",
"/home/*/.kde4/Autostart/*", "/root/.kde4/Autostart/*",
"/home/*/.kde/share/autostart/*", "/root/.kde/share/autostart/*",
"/home/*/.kde4/share/autostart/*", "/root/.kde4/share/autostart/*",
"/home/*/.local/share/autostart/*", "/root/.local/share/autostart/*",
"/home/*/.config/autostart-scripts/*", "/root/.config/autostart-scripts/*",
"/etc/xdg/autostart/*", "/usr/share/autostart/*"
) and
not (
process.name in (
"yum", "dpkg", "install", "dnf", "teams", "yum-cron", "dnf-automatic", "docker", "dockerd", "rpm", "pacman",
"podman", "nautilus", "remmina", "cinnamon-settings.py", "executor", "xfce4-clipman", "jetbrains-toolbox",
"ansible-admin", "apk"
) or
process.executable in (
"/usr/bin/dnf5", "/usr/libexec/xdg-desktop-portal", "/usr/sbin/mkhomedir_helper", "/sbin/mkhomedir_helper",
"/usr/bin/crio", "/usr/sbin/useradd", "/usr/bin/nextcloud", "/usr/bin/sealert", "/opt/google/chrome/chrome",
"/usr/bin/pamac-daemon", "/usr/sbin/sshd", "/usr/sbin/gdm", "/usr/libexec/platform-python"
) or
process.executable like "/home/*/.MathWorks/*/glnxa64/mlcpostinstall"
)
'''
[[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.013"
name = "XDG Autostart Entries"
reference = "https://attack.mitre.org/techniques/T1547/013/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
Stages and Predicates
Stage 1: file
file where host.os.type == "linux" and event.type == "creation" and process.executable != null and
file.extension in ("sh", "desktop") and
file.path like (
"/home/*/.config/autostart/*", "/root/.config/autostart/*",
"/home/*/.kde/Autostart/*", "/root/.kde/Autostart/*",
"/home/*/.kde4/Autostart/*", "/root/.kde4/Autostart/*",
"/home/*/.kde/share/autostart/*", "/root/.kde/share/autostart/*",
"/home/*/.kde4/share/autostart/*", "/root/.kde4/share/autostart/*",
"/home/*/.local/share/autostart/*", "/root/.local/share/autostart/*",
"/home/*/.config/autostart-scripts/*", "/root/.config/autostart-scripts/*",
"/etc/xdg/autostart/*", "/usr/share/autostart/*"
) and
not (
process.name in (
"yum", "dpkg", "install", "dnf", "teams", "yum-cron", "dnf-automatic", "docker", "dockerd", "rpm", "pacman",
"podman", "nautilus", "remmina", "cinnamon-settings.py", "executor", "xfce4-clipman", "jetbrains-toolbox",
"ansible-admin", "apk"
) or
process.executable in (
"/usr/bin/dnf5", "/usr/libexec/xdg-desktop-portal", "/usr/sbin/mkhomedir_helper", "/sbin/mkhomedir_helper",
"/usr/bin/crio", "/usr/sbin/useradd", "/usr/bin/nextcloud", "/usr/bin/sealert", "/opt/google/chrome/chrome",
"/usr/bin/pamac-daemon", "/usr/sbin/sshd", "/usr/sbin/gdm", "/usr/libexec/platform-python"
) or
process.executable like "/home/*/.MathWorks/*/glnxa64/mlcpostinstall"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"creation" |
file.extension | in |
| field:"file.extension" kind:in |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard |
process.executable | is_not_null | field:"Image" kind:is_not_null |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.executable | in | /opt/google/chrome/chrome, /sbin/mkhomedir_helper, /usr/bin/crio, /usr/bin/dnf5, /usr/bin/nextcloud, /usr/bin/pamac-daemon, /usr/bin/sealert, /usr/libexec/platform-python, /usr/libexec/xdg-desktop-portal, /usr/sbin/gdm, /usr/sbin/mkhomedir_helper, /usr/sbin/sshd, /usr/sbin/useradd | excludes:process.executable |
process.executable | wildcard | /home/*/.MathWorks/*/glnxa64/mlcpostinstall | excludes:process.executable field:"process.executable" value:"/home/*/.MathWorks/*/glnxa64/mlcpostinstall" |
process.name | in | ansible-admin, apk, cinnamon-settings.py, dnf, dnf-automatic, docker, dockerd, dpkg, executor, install, jetbrains-toolbox, nautilus, pacman, podman, remmina, rpm, teams, xfce4-clipman, yum, yum-cron | excludes:process.name |
Kubernetes Container Created with Excessive Linux Capabilities
#This rule detects a container deployed with one or more dangerously permissive Linux capabilities. An attacker with the ability to deploy a container with added capabilities could use this for further execution, lateral movement, or privilege escalation within a cluster. The capabilities detected in this rule have been used in container escapes to the host machine.
Known False Positives
- Some container images require the addition of privileged capabilities. This rule leaves space for the exception of trusted container images. To add an exception, add the trusted container image name to the query field, kubernetes.audit.requestObject.spec.containers.image.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Privilege Escalation |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Kubernetes | create-pods: create pods |
Rules Detecting the Same Action
These rules filter on the same operation.
- Azure AKS Attempted User Exec into Pod (Elastic)
- Container With A hostPath Mount Created (Sigma)
- Creation Of Pod In System Namespace (Sigma)
- Direct Interactive Kubernetes API Request by Unusual Utilities (Elastic)
- Exec into Pod (Panther)
- GCP Break-glass Container Workload Deployed (Sigma)
- GCP K8s Pod Attached To Node Host Network (Panther)
- GCP K8S Pod Create Or Modify Host Path Volume Mount (Panther)
Rule Body
[metadata]
creation_date = "2022/09/20"
integration = ["kubernetes"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
This rule detects a container deployed with one or more dangerously permissive Linux capabilities. An attacker with the
ability to deploy a container with added capabilities could use this for further execution, lateral movement, or
privilege escalation within a cluster. The capabilities detected in this rule have been used in container escapes to the
host machine.
"""
false_positives = [
"""
Some container images require the addition of privileged capabilities. This rule leaves space for the exception of
trusted container images. To add an exception, add the trusted container image name to the query field,
kubernetes.audit.requestObject.spec.containers.image.
""",
]
index = ["logs-kubernetes.audit_logs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Kubernetes Container Created with Excessive Linux Capabilities"
note = """## Triage and analysis
### Investigating Kubernetes Container Created with Excessive Linux Capabilities
Linux capabilities were designed to divide root privileges into smaller units. Each capability grants a thread just enough power to perform specific privileged tasks. In Kubernetes, containers are given a set of default capabilities that can be dropped or added to at the time of creation. Added capabilities entitle containers in a pod with additional privileges that can be used to change
core processes, change network settings of a cluster, or directly access the underlying host. The following have been used in container escape techniques:
BPF - Allow creating BPF maps, loading BPF Type Format (BTF) data, retrieve JITed code of BPF programs, and more.
DAC_READ_SEARCH - Bypass file read permission checks and directory read and execute permission checks.
NET_ADMIN - Perform various network-related operations.
SYS_ADMIN - Perform a range of system administration operations.
SYS_BOOT - Use reboot(2) and kexec_load(2), reboot and load a new kernel for later execution.
SYS_MODULE - Load and unload kernel modules.
SYS_PTRACE - Trace arbitrary processes using ptrace(2).
SYS_RAWIO - Perform I/O port operations (iopl(2) and ioperm(2)).
SYSLOG - Perform privileged syslog(2) operations.
### False positive analysis
- While these capabilities are not included by default in containers, some legitimate images may need to add them. This rule leaves space for the exception of trusted container images. To add an exception, add the trusted container image name to the query field, kubernetes.audit.requestObject.spec.containers.image.
## Setup
The Kubernetes Fleet integration with Audit Logs enabled or similarly structured data is required to be compatible with this rule."""
references = [
"https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container",
"https://0xn3va.gitbook.io/cheat-sheets/container/escaping/excessive-capabilities",
"https://man7.org/linux/man-pages/man7/capabilities.7.html",
"https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities",
]
risk_score = 47
rule_id = "7164081a-3930-11ed-a261-0242ac120002"
severity = "medium"
tags = [
"Data Source: Kubernetes",
"Domain: Kubernetes",
"Use Case: Threat Detection",
"Tactic: Execution",
"Tactic: Privilege Escalation",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset: kubernetes.audit_logs and kubernetes.audit.annotations.authorization_k8s_io/decision:"allow" and
kubernetes.audit.verb: create and kubernetes.audit.objectRef.resource: pods and
kubernetes.audit.requestObject.spec.containers.securityContext.capabilities.add: ("BPF" or "DAC_READ_SEARCH" or "NET_ADMIN" or "SYS_ADMIN" or "SYS_BOOT" or "SYS_MODULE" or "SYS_PTRACE" or "SYS_RAWIO" or "SYSLOG") and
not (
kubernetes.audit.requestObject.spec.containers.image : (docker.elastic.co/beats/elastic-agent* or rancher/klipper-lb* or "") or
kubernetes.audit.objectRef.namespace:"kube-system" or
(kubernetes.audit.objectRef.namespace:datadog and kubernetes.audit.requestObject.spec.containers.image:*datadog-agent*) or
(kubernetes.audit.objectRef.namespace:kubearmor and kubernetes.audit.requestObject.spec.containers.image:(*kubearmor\:kubearmor* or kubearmor/kubearmor-snitch*)) or
(kubernetes.audit.objectRef.namespace:defender and kubernetes.audit.requestObject.spec.containers.image:*fp-prisma\:defender-defender*) or
(kubernetes.audit.objectRef.namespace:metallb-system and kubernetes.audit.requestObject.spec.containers.image:(quay.io/frrouting* or quay.io/metallb/speaker*)) or
(kubernetes.audit.objectRef.namespace:longhorn-system and kubernetes.audit.requestObject.spec.containers.image:rancher/mirrored-longhornio*)
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1611"
name = "Escape to Host"
reference = "https://attack.mitre.org/techniques/T1611/"
[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1610"
name = "Deploy Container"
reference = "https://attack.mitre.org/techniques/T1610/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1610"
name = "Deploy Container"
reference = "https://attack.mitre.org/techniques/T1610/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Stage 1: query
data_stream.dataset: kubernetes.audit_logs and kubernetes.audit.annotations.authorization_k8s_io/decision:"allow" and
kubernetes.audit.verb: create and kubernetes.audit.objectRef.resource: pods and
kubernetes.audit.requestObject.spec.containers.securityContext.capabilities.add: ("BPF" or "DAC_READ_SEARCH" or "NET_ADMIN" or "SYS_ADMIN" or "SYS_BOOT" or "SYS_MODULE" or "SYS_PTRACE" or "SYS_RAWIO" or "SYSLOG") and
not (
kubernetes.audit.requestObject.spec.containers.image : (docker.elastic.co/beats/elastic-agent* or rancher/klipper-lb* or "") or
kubernetes.audit.objectRef.namespace:"kube-system" or
(kubernetes.audit.objectRef.namespace:datadog and kubernetes.audit.requestObject.spec.containers.image:*datadog-agent*) or
(kubernetes.audit.objectRef.namespace:kubearmor and kubernetes.audit.requestObject.spec.containers.image:(*kubearmor\:kubearmor* or kubearmor/kubearmor-snitch*)) or
(kubernetes.audit.objectRef.namespace:defender and kubernetes.audit.requestObject.spec.containers.image:*fp-prisma\:defender-defender*) or
(kubernetes.audit.objectRef.namespace:metallb-system and kubernetes.audit.requestObject.spec.containers.image:(quay.io/frrouting* or quay.io/metallb/speaker*)) or
(kubernetes.audit.objectRef.namespace:longhorn-system and kubernetes.audit.requestObject.spec.containers.image:rancher/mirrored-longhornio*)
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"kubernetes.audit_logs" |
kubernetes.audit.annotations.authorization_k8s_io/decision | eq |
| field:"kubernetes.audit.annotations.authorization_k8s_io/decision" kind:eq value:"allow" |
kubernetes.audit.objectRef.resource | eq |
| field:"kubernetes.audit.objectRef.resource" kind:eq value:"pods" |
kubernetes.audit.requestObject.spec.containers.securityContext.capabilities.add | in |
| field:"kubernetes.audit.requestObject.spec.containers.securityContext.capabilities.add" kind:in |
kubernetes.audit.verb | eq |
| field:"kubernetes.audit.verb" kind:eq value:"create" |
Exclusions
The rule actively suppresses these predicates.
Kubernetes Pod Exec Cloud Instance Metadata Access
#Detects Kubernetes pod exec sessions whose decoded command line references cloud instance metadata endpoints or equivalent hostnames and paths. Workloads that reach the link-local metadata IP, AWS IMDS paths, GCP computeMetadata, Azure IMDS token routes, or encoded variants are often attempting to harvest role credentials, tokens, or instance attributes from the underlying node or hypervisor boundary. That behavior is high risk in multi-tenant and regulated environments because it can expose short-lived cloud credentials to code running inside a container. The rule classifies a coarse cloud target label and whether the string looks like credential retrieval versus lighter reconnaissance.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Credential Access |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Kubernetes | get-pods-exec: get pods/exec |
| Kubernetes | create-pods-exec: create pods/exec |
Rules Detecting the Same Action
These rules filter on the same operation.
- Kubernetes Multi-Resource Discovery (Elastic)
- Kubernetes Pod Exec Potential Reverse Shell (Elastic)
- Kubernetes Pod Exec Sensitive File or Credential Path Access (Elastic)
- Kubernetes Pod Exec with Curl or Wget to HTTPS (Elastic)
- Unauthorized Kubernetes Pod Execution (Panther)
- Unauthorized Kubernetes Pod Execution (Panther)
Rule Body
[metadata]
creation_date = "2026/04/23"
integration = ["kubernetes"]
maturity = "production"
updated_date = "2026/08/18"
[rule]
author = ["Elastic"]
description = """
Detects Kubernetes pod exec sessions whose decoded command line references cloud instance metadata endpoints or
equivalent hostnames and paths. Workloads that reach the link-local metadata IP, AWS IMDS paths, GCP computeMetadata,
Azure IMDS token routes, or encoded variants are often attempting to harvest role credentials, tokens, or instance
attributes from the underlying node or hypervisor boundary. That behavior is high risk in multi-tenant and regulated
environments because it can expose short-lived cloud credentials to code running inside a container. The rule
classifies a coarse cloud target label and whether the string looks like credential retrieval versus lighter
reconnaissance.
"""
from = "now-6m"
interval = "5m"
language = "esql"
license = "Elastic License v2"
name = "Kubernetes Pod Exec Cloud Instance Metadata Access"
note = """## Triage and analysis
### Investigating Kubernetes Pod Exec Cloud Instance Metadata Access
This alert fires when an audited exec requestURI, after URL decoding and command reconstruction, matches patterns
associated with instance metadata services across AWS, GCP, and Azure. Use it to catch interactive or scripted access
from inside a pod to metadata surfaces that should usually be blocked by network policy or not needed by application
code.
### Possible investigation steps
- Confirm the Kubernetes identity that performed exec: user name, groups, impersonation, source IP, and user agent.
- Map the pod and namespace to a workload owner, image digest, and entrypoint; determine whether the container should
ever call metadata endpoints.
- Inspect Esql.cloud_target and Esql.is_credential_theft in the alert document and expand the timeline for the same
identity for secret reads, IAM changes, or data egress.
- Correlate with cloud audit logs on the node identity or instance profile for STS or token issuance around the event
time.
### False positive analysis
- Break-glass debugging from platform engineers may include curl to 169.254.169.254; validate change tickets and
bastion use.
- Misconfigured agents or bootstrap scripts in bespoke images can touch metadata during startup; baseline approved
images and tune exclusions narrowly.
### Response and remediation
- If unauthorized, terminate the session, isolate the workload, revoke or rotate instance and workload credentials that
could have been read, and tighten RBAC on pods exec plus network policies that deny link-local metadata from pods.
"""
references = [
"https://attack.mitre.org/techniques/T1552/005/",
"https://hardenedsecurity.io/blog/aws-imds-vulnerabilities-and-mitigations/",
]
risk_score = 73
rule_id = "a8e7d6c5-b4a3-2918-0f9e-8d7c6b5a4032"
severity = "high"
tags = [
"Data Source: Kubernetes",
"Data Source: Kubernetes API Server Audit Logs",
"Domain: Kubernetes",
"Platform: Kubernetes",
"Domain: Cloud",
"Use Case: Threat Detection",
"Tactic: Credential Access",
"Tactic: Execution",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
FROM logs-kubernetes.audit_logs-* metadata _id, _index, _version
| WHERE kubernetes.audit.objectRef.subresource == "exec"
AND kubernetes.audit.requestURI LIKE "*command=*"
| EVAL Esql.decoded_uri = URL_DECODE(kubernetes.audit.requestURI)
| GROK Esql.decoded_uri "%{DATA}/exec\\?%{DATA:raw_commands}&(?:container|stdin|stdout|stderr)=%{GREEDYDATA}"
| EVAL command = REPLACE(raw_commands, "command=", "")
| EVAL command = REPLACE(command, "&", " ")
| EVAL Esql.executed_command = REPLACE(command, "\\+", " ")
| WHERE Esql.executed_command IS NOT NULL
AND Esql.executed_command RLIKE """.*(169\.254\.169\.254|2852039166|0xa9fea9fe|/latest/api/token|/latest/meta-data|/latest/user-data|/latest/dynamic/instance-identity|computeMetadata/v1|metadata\.google\.internal|metadata/identity/oauth2/token|metadata/instance).*"""
| EVAL Esql.cloud_target = CASE(
Esql.executed_command RLIKE """.*(169\.254\.169\.254|2852039166|0xa9fea9fe|/latest/meta-data|/latest/api/token|/latest/user-data|/latest/dynamic).*""", "AWS_IMDS",
Esql.executed_command RLIKE """.*(computeMetadata/v1|metadata\.google\.internal).*""", "GCP_METADATA",
Esql.executed_command RLIKE """.*metadata/identity/oauth2/token.*""", "AZURE_IMDS",
"UNKNOWN"
)
| EVAL Esql.is_credential_theft = CASE(
Esql.executed_command RLIKE """.*(security-credentials|/api/token|oauth2/token|service-accounts/.*/token).*""", "yes",
"recon"
)
| KEEP Esql.*, user.name, user_agent.original, event.*, source.ip, kubernetes.audit.*, _id, _version, _index, data_stream.namespace
'''
[[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.005"
name = "Cloud Instance Metadata API"
reference = "https://attack.mitre.org/techniques/T1552/005/"
[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 = "T1609"
name = "Container Administration Command"
reference = "https://attack.mitre.org/techniques/T1609/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
Stages and Predicates
Stage 1: from
FROM logs-kubernetes.audit_logs-* metadata _id, _index, _version
Stage 2: where
| WHERE kubernetes.audit.objectRef.subresource == "exec"
AND kubernetes.audit.requestURI LIKE "*command=*"
Stage 3: eval
| EVAL Esql.decoded_uri = URL_DECODE(kubernetes.audit.requestURI)
Stage 4: grok
| GROK Esql.decoded_uri "%{DATA}/exec\\?%{DATA:raw_commands}&(?:container|stdin|stdout|stderr)=%{GREEDYDATA}"
Stage 5: eval
| EVAL command = REPLACE(raw_commands, "command=", "")
Stage 6: eval
| EVAL command = REPLACE(command, "&", " ")
Stage 7: eval
| EVAL Esql.executed_command = REPLACE(command, "\\+", " ")
Stage 8: where
| WHERE Esql.executed_command IS NOT NULL
AND Esql.executed_command RLIKE """.*(169\.254\.169\.254|2852039166|0xa9fea9fe|/latest/api/token|/latest/meta-data|/latest/user-data|/latest/dynamic/instance-identity|computeMetadata/v1|metadata\.google\.internal|metadata/identity/oauth2/token|metadata/instance).*"""
Stage 9: eval
| EVAL Esql.cloud_target = CASE(
Esql.executed_command RLIKE """.*(169\.254\.169\.254|2852039166|0xa9fea9fe|/latest/meta-data|/latest/api/token|/latest/user-data|/latest/dynamic).*""", "AWS_IMDS",
Esql.executed_command RLIKE """.*(computeMetadata/v1|metadata\.google\.internal).*""", "GCP_METADATA",
Esql.executed_command RLIKE """.*metadata/identity/oauth2/token.*""", "AZURE_IMDS",
"UNKNOWN"
)
Esql.cloud_target =Esql.executed_command RLIKE """.*(169\.254\.169\.254|2852039166|0xa9fea9fe|/latest/meta-data|/latest/api/token|/latest/user-data|/latest/dynamic).*""""AWS_IMDS"Esql.executed_command RLIKE """.*(computeMetadata/v1|metadata\.google\.internal).*""""GCP_METADATA"Esql.executed_command RLIKE """.*metadata/identity/oauth2/token.*""""AZURE_IMDS""UNKNOWN"Stage 10: eval
| EVAL Esql.is_credential_theft = CASE(
Esql.executed_command RLIKE """.*(security-credentials|/api/token|oauth2/token|service-accounts/.*/token).*""", "yes",
"recon"
)
Esql.is_credential_theft =Esql.executed_command RLIKE """.*(security-credentials|/api/token|oauth2/token|service-accounts/.*/token).*""""yes""recon"Stage 11: keep
| KEEP Esql.*, user.name, user_agent.original, event.*, source.ip, kubernetes.audit.*, _id, _version, _index, data_stream.namespace
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Esql.executed_command | is_not_null | field:"Esql.executed_command" kind:is_not_null | |
Esql.executed_command | regex_match |
| field:"Esql.executed_command" kind:regex_match value:".*(169.254.169.254|2852039166|0xa9fea9fe|/latest/api/token|/latest/meta-data|/latest/user-data|/latest/dynamic/instance-identity|computeMetadata/v1|metadata.google.internal|metadata/identity/oauth2/token|metadata/instance).*" |
kubernetes.audit.objectRef.subresource | eq |
| field:"kubernetes.audit.objectRef.subresource" kind:eq value:"exec" |
kubernetes.audit.requestURI | wildcard |
| field:"kubernetes.audit.requestURI" kind:wildcard value:"*command=*" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Esql.* | KEEP Esql.* |
user.name | KEEP user.name |
user_agent.original | KEEP user_agent.original |
event.* | KEEP event.* |
source.ip | KEEP source.ip |
kubernetes.audit.* | KEEP kubernetes.audit.* |
_id | KEEP _id |
_version | KEEP _version |
_index | KEEP _index |
data_stream.namespace | KEEP data_stream.namespace |
M365 Identity Global Administrator Role Assigned
#Identifies when the Microsoft 365 Global Administrator or Company Administrator role is assigned to a user or service principal. The Global Administrator role has extensive privileges across Entra ID and Microsoft 365 services, making it a high-value target for adversaries seeking persistent access. Successful assignments of this role may indicate potential privilege escalation or unauthorized access attempts, especially if performed by accounts that do not typically manage high-privilege roles.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Privilege Escalation |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Microsoft 365 | Add member to role. |
Rules Detecting the Same Action
These rules filter on the same operation.
Rule Body
[metadata]
creation_date = "2022/01/06"
integration = ["o365"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
Identifies when the Microsoft 365 Global Administrator or Company Administrator role is assigned to a user or service
principal. The Global Administrator role has extensive privileges across Entra ID and Microsoft 365 services, making it
a high-value target for adversaries seeking persistent access. Successful assignments of this role may indicate
potential privilege escalation or unauthorized access attempts, especially if performed by accounts that do not
typically manage high-privilege roles.
"""
from = "now-9m"
index = ["logs-o365.audit-*"]
language = "kuery"
license = "Elastic License v2"
name = "M365 Identity Global Administrator Role Assigned"
note = """## Triage and Analysis
### Investigating M365 Identity Global Administrator Role Assigned
The Microsoft 365 Global Administrator role grants comprehensive administrative access across Entra ID and services such as Microsoft 365 Defender, Exchange, SharePoint, and Skype for Business. Adversaries who compromise an account may assign this role to themselves or other users to ensure persistent and privileged access. This rule identifies successful assignments of this role by inspecting audit logs from Azure Active Directory (Entra ID) where the role display name matches "Administrator."
### Possible investigation steps
- Review the `user.id` and `user.name` fields to determine who performed the role assignment. Assess whether this user normally has permissions to modify high-privilege roles.
- Confirm the `event.action` is `"Add member to role."` and that the `Role_DisplayName.NewValue` is `"Global Administrator"` or a similarly privileged role.
- Review the `user.target.id` and `user.target.name` fields to identify the user or service principal that received the role.
- Inspect `o365.audit.ExtendedProperties.additionalDetails` for context on how the action was performed (e.g., via Admin Portal, Graph API).
- Pivot to sign-in logs for the assigning account to check for recent anomalies such as logins from new geolocations, unrecognized devices, or suspicious IP ranges.
- Investigate if the account assignment occurred outside of known change windows, during non-business hours, or by a user with no change history.
- Correlate with other role assignments or directory changes to check for broader role abuse or privilege escalation campaigns.
### False positive analysis
- Role assignments by IT administrators as part of routine maintenance or incident response may appear suspicious in environments without change tracking or ticket correlation.
- PIM (Privileged Identity Management) activations may temporarily elevate accounts to Global Administrator and then revoke the role afterward.
- Onboarding processes or internal audits may require temporary elevation to Global Administrator for legitimate users.
- Automation tools and scripts may trigger this alert if misconfigured to assign Global Administrator privileges during provisioning or sync jobs.
### Response and remediation
- If the assignment is unapproved or suspicious, immediately revoke the Global Administrator role from the assigned user or service principal.
- Reset credentials and initiate containment steps for the assigning account, especially if compromise is suspected.
- Enable or verify enforcement of MFA for both assigning and assigned accounts.
- Review Azure AD activity logs for additional signs of privilege misuse or suspicious directory changes.
- Notify the appropriate identity and security operations teams to investigate further and begin incident response procedures.
- Limit the number of Global Administrator accounts and enforce role-based access control (RBAC) using least privilege principles.
- Consider implementing conditional access policies to limit role assignment actions to specific networks, devices, or user groups.
"""
references = [
"https://docs.microsoft.com/en-us/azure/active-directory/roles/permissions-reference#global-administrator",
"https://learn.microsoft.com/en-us/purview/audit-log-activities",
"https://www.blackhat.com/us-24/briefings/schedule/#unoauthorized-a-technique-to-privilege-escalation-to-global-administrator-39231"
]
risk_score = 47
rule_id = "88671231-6626-4e1b-abb7-6e361a171fbb"
severity = "medium"
tags = [
"Domain: Cloud",
"Domain: SaaS",
"Domain: Identity",
"Data Source: Microsoft 365",
"Data Source: Microsoft 365 Audit Logs",
"Use Case: Identity and Access Audit",
"Tactic: Persistence",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:o365.audit
and event.code:"AzureActiveDirectory"
and event.action:"Add member to role."
and event.outcome: "success"
and o365.audit.ModifiedProperties.Role_DisplayName.NewValue: (
"Global Administrator" or "Company Administrator"
)
and o365.audit.AzureActiveDirectoryEventType: 1
and o365.audit.RecordType: 8
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[[rule.threat.technique.subtechnique]]
id = "T1098.003"
name = "Additional Cloud Roles"
reference = "https://attack.mitre.org/techniques/T1098/003/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[[rule.threat.technique.subtechnique]]
id = "T1098.003"
name = "Additional Cloud Roles"
reference = "https://attack.mitre.org/techniques/T1098/003/"
[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
Stages and Predicates
Stage 1: query
data_stream.dataset:o365.audit
and event.code:"AzureActiveDirectory"
and event.action:"Add member to role."
and event.outcome: "success"
and o365.audit.ModifiedProperties.Role_DisplayName.NewValue: (
"Global Administrator" or "Company Administrator"
)
and o365.audit.AzureActiveDirectoryEventType: 1
and o365.audit.RecordType: 8
Indicators
These rows show field, operator, and value matches.
Managed .NET Code Execution via Windows Script Interpreter
#Identifies a suspicious managed code hosting process which could indicate code injection or other form of suspicious code execution via Windows scripts.
MITRE ATT&CK Coverage
Rule Body
[rule]
description = """
Identifies a suspicious managed code hosting process which could indicate code injection or other form of suspicious
code execution via Windows scripts.
"""
id = "5a898048-d98c-44c6-b7ba-f63a31eb3571"
license = "Elastic License v2"
name = "Managed .NET Code Execution via Windows Script Interpreter"
os_list = ["windows"]
reference = ["https://github.com/med0x2e/GadgetToJScript", "https://github.com/mdsecactivebreach/SharpShooter"]
version = "1.0.29"
query = '''
sequence by process.entity_id with maxspan=2m
[process where event.type == "start" and
process.name : ("wscript.exe", "cscript.exe", "mshta.exe", "wmic.exe", "cmstp.exe", "msxsl.exe") and
/* Only FPs observed so far, similar FPs can be handled via user custom applied exclusions */
not (process.name : "mshta.exe" and process.parent.name : "Explorer.exe" and
process.working_directory : "H:\\Code\\SignatureGen\\") and
not (process.name : "wscript.exe" and process.parent.name : "wscript.exe" and
process.parent.args : "/ChangedHostBitness" and process.parent.args : "/ALL")]
[file where event.action == "creation" and
file.path : "?:\\Users\\*\\Microsoft\\CLR_*\\UsageLogs\\*.exe.log" and
/*
CLR Usage Logs are created only for the first time
the program executes .NET which should reduce noise compared to clr.dll imageload
*/
file.name : ("wscript.exe.log",
"cscript.exe.log",
"mshta.exe.log",
"wmic.exe.log",
"cmstp.exe.log",
"msxsl.exe.log")]
'''
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/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"
[[threat.technique]]
id = "T1220"
name = "XSL Script Processing"
reference = "https://attack.mitre.org/techniques/T1220/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 2m, correlated by process.entity_id.
Stage 1: process
[process where event.type == "start" and
process.name : ("wscript.exe", "cscript.exe", "mshta.exe", "wmic.exe", "cmstp.exe", "msxsl.exe") and
not (process.name : "mshta.exe" and process.parent.name : "Explorer.exe" and
process.working_directory : "H:\\Code\\SignatureGen\\") and
not (process.name : "wscript.exe" and process.parent.name : "wscript.exe" and
process.parent.args : "/ChangedHostBitness" and process.parent.args : "/ALL")]
Stage 2: file
[file where event.action == "creation" and
file.path : "?:\\Users\\*\\Microsoft\\CLR_*\\UsageLogs\\*.exe.log" and
/*
CLR Usage Logs are created only for the first time
the program executes .NET which should reduce noise compared to clr.dll imageload
*/
file.name : ("wscript.exe.log",
"cscript.exe.log",
"mshta.exe.log",
"wmic.exe.log",
"cmstp.exe.log",
"msxsl.exe.log")]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"creation" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
file.name | wildcard |
| field:"file.name" kind:wildcard |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard value:"?:\Users\*\Microsoft\CLR_*\UsageLogs\*.exe.log" |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.name | eq | mshta.exe | excludes:process.name field:"process.name" value:"mshta.exe" |
process.parent.name | eq | Explorer.exe | excludes:process.parent.name field:"process.parent.name" value:"Explorer.exe" |
process.working_directory | eq | H:\Code\SignatureGen\ | excludes:process.working_directory field:"process.working_directory" value:"H:\Code\SignatureGen\" |
process.name | eq | wscript.exe | excludes:process.name field:"process.name" value:"wscript.exe" |
process.parent.args | eq | /ALL | excludes:process.parent.args field:"process.parent.args" value:"/ALL" |
process.parent.args | eq | /ChangedHostBitness | excludes:process.parent.args field:"process.parent.args" value:"/ChangedHostBitness" |
process.parent.name | eq | wscript.exe | excludes:process.parent.name field:"process.parent.name" value:"wscript.exe" |
Network Connect API from Unbacked Memory
#Identifies attempts to perform a network connection from a suspicious unbacked memory block. This may be the result of code injection.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule Body
[rule]
description = """
Identifies attempts to perform a network connection from a suspicious unbacked memory block. This may be the result of
code injection.
"""
id = "720e0265-03bc-4cb7-9116-7fad5ea9cdfc"
license = "Elastic License v2"
name = "Network Connect API from Unbacked Memory"
os_list = ["windows"]
version = "1.0.18"
query = '''
api where process.Ext.api.name == "connect" and process.Ext.api.summary: "*ipv4*" and
process.thread.Ext.call_stack_final_user_module.name == "Unbacked" and
(
process.thread.Ext.call_stack_summary :
("ntdll.dll|mswsock.dll|ws2_32.dll|Unbacked",
"ntdll.dll|mswsock.dll|Unbacked",
"wow64cpu.dll|wow64.dll|ntdll.dll|mswsock.dll|ws2_32.dll|Unbacked",
"wow64cpu.dll|wow64.dll|ntdll.dll|mswsock.dll|Unbacked") or
((process.code_signature.trusted == false or process.code_signature.exists == false) and
startswith~(process.thread.Ext.call_stack_summary, concat("wow64cpu.dll|wow64.dll|ntdll.dll|mswsock.dll|ws2_32.dll|Unbacked|", process.name))) or
((process.code_signature.trusted == false or process.code_signature.exists == false) and
startswith~(process.thread.Ext.call_stack_summary, concat("ntdll.dll|mswsock.dll|ws2_32.dll|Unbacked", process.name)))
) and
/* trailing bytes are not null */
_arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info : "Unbacked*" and $entry.callsite_trailing_bytes : "?*") and
/* excluding signed final usermod */
not _arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature, $entry, $entry.trusted == true) and
process.thread.Ext.call_stack_final_user_module.hash.sha256 != null and
not process.thread.Ext.call_stack_final_user_module.hash.sha256 in
("02ecce804add1da0a9e7be506f7369d3d5753c51c80abe32b24be05c321c5ff7",
"f823fc285b259fd0a5391a5c807279e90fe5317e6cfd7b00a49f07c278832cbc",
"236b9ab2b531da7312da1429cba1bd9f45cae4ed46cba1792924013b9919f8cf",
"5d4708e841bdd2523c963e45932555ba98e203c6a99f242573f251374f73cb63",
"ff4dd86a9ef8ccedd9a01dee516775eea75edcef0ff313b718df3dc4a026f395",
"0e675101b1814b932f8c1209b5e355636c18767da413a261667ce2bedd3c7914",
"aeda6c3b3b1dc1e91d1cbbea6863eaf5fe02eef74827fe533f4b7d55e388a9b1",
"99f9058c1481370d03a511a8863a9b6e36c34d4f0066b17ad0f6666c86eed152",
"9b1865415f947505eff3084830193d1a6bf317d8e704d401b1a8ffb91a3d9277",
"7f28d5f5d96183ed01c345fdc5d28e82ae255aa19ecb329ab9fa9ecdf10f79de",
"5ec183e4e31a18a7788ffa4514e1e555d458725e4521160221ea36df5e29a35f",
"5d1ace7a28fb13f34a4f56045f41285b2f07764f42e09fc4d5ce72b10ffbed38",
"df13445949901d9f43575ad8fd5005a490e9a2fa68e27e26e6ea6d4014b83635",
"8b354c30a6fccb12963cf2bf06fcf60efcc2bef7e3b735cab36f4b26e8cd105b",
"c809da8be3cad745801f3668df829bddc39e7ffb0c526fe98ada697b60811922",
"b4e067d5b1f09821e7a3b6106547ee23572f64e604ffa29041b8cbc7e63b58a7",
"dcfa8e77235026558f65e6ab82d2b9e69768f023204062f628234b2b5506fd32",
"617b0977d387472a4ca0948f1ba19640a21d1fa1dca52e3047c5e630af231062",
"50f903bc4b496b94051b9cba15eccd9c25bb963c7424f2845fbc0897bd7d391d",
"c094179af7a6a3bfae751fc30ff13b711e055ffa563fc98b3d3b3aa57584a424",
"2fe43a4716927f4600f44bfc7ffa43584fb5bea404ff5624d4bb5efaddec174a",
"bb55748883f650e45921b875a546e0174ff8251d77043d3cab4de60eff7cd9f8",
"f2c8fbd754527f3411c31068975f316970fcb3bb7ba611d5d2f20d17489e6d32",
"c160ce8529cd5131f1c349bc92c5b3e989b0cac7fcbdd1318eb484eb3b4ca49f",
"3d86479ab47b249241e7d392ef5daf2263b341f4a77755ac285c629dfc71f06c",
"bf85b58dada12a821a8ee445a6d7b97b7e984eb4db88a9bcb3e3fa698c88d345",
"a87b3f02042de4d655f72af65ed5242fae5c675bebd19e962978c13e6d99ba00",
"eb70e1f2aad9d66f0ca71b3b57ad6b8c6f7fa623155a589afe82a899f7dd88c4",
"bbff088a88a0a754dc9d312e52ef7e60dd93537d78d73f79c89aa5b5091457fc",
"c817a4c49167176bfa6335b950d629b31ff553e943b9ab835b88f6c2ee09fc82",
"7dd3acf9f47641ce621e4db5980ab8f7a3f67c9a4f008f36b56d59afefbedfa9",
"0be7c1898ca40070ba6807cdc95722a35cbee79fa08399abd714b90a5b5239d5",
"9ce7991f13bf252648ea4766299cb59ab291771937b11a7a7a04df2c540d565d",
"3f74481e6991404f951ff5168c6726a521c566eb408a654d776109afdb963655",
"6e7533220f0715156b9baa401fb13a71735aabfb1443dad6a3835ab8a38750bf",
"7b5e0b0bc2ca257071210ddb787cb18d65621bb7d1034ea946937ca565977bbd",
"c9e303d84e5fa603c85abee0caefa8b0ef393aab6805e2ea5098ca927fa2b6cf",
"6e79c9271cddc0a4bb3e8af619967d54ea6df7067798fd5da9ccca233b221da0",
"fddac9c6330518eb74b92abeee411e91ef3189fb3ed04508a9f3ebd5991fdb30",
"335790ae673d41cc7d4b3c6c1a9c16c7bb3260fc24d4caced80dbe4cfd9a4f6e",
"6f7d83b779e164ddf58c2bff7a719caba1887c6c92dc72fd2eb4e1394fbf51c4",
"26e5c00c35c5c3edc86dfc0a720aed109a13b1b7c67ac654a0ce8ff82a1f2c16",
"fdff5c5612e0bcbc8aba52720e5d37e5c3821267179e2fa7341084148ad4b1ea",
"834b0fce44e8db2367967f8d5262a0dafe45e7c5bd69c98f1a9eeec2136dcbc1",
"7eb92b8b9ce2d44a500c56ea04e805cb78614c572dc723c79c59ca93315ba709",
"3eb37ba3fc39f5749bbb3f17382d0966adf2e061f4f0d1757ebd75fed1302dd6",
"0b29ecbb5277629a1be89193941ec9d58867118ab7ef6a9d0235f7c5388904d7",
"0f4828417f3c8f8c6a5d74c39cb1dc746b241901e8bdd53bb09808858b7b0a08",
"cd08541db31221a2e26238cd6a2bcd6a9ebb9a4c4205c09b1b2050fde409f284",
"f834e4447d0b4c421ac2a0a9b10304a47688f358a6db9c1281bffe44957bcc4e",
"d0615bcbcaf0c64b2613c224924fce9e891a62287acc243a9b142ee0d021b207",
"7c71327ab87990b1ac0446813f2f1e69c33cc634afab5857cfa9fca17d0cc37e",
"ecbd9f72fe48043302f547643b26e2da9c12c4d8030d28e53f1651fb0e06a2ca",
"c11d8f8d419aee8d67166ae9eeed3999364fa41a7d701ede076f2d2ad8acb8be",
"ad71a3681f0fa629133a67f04d64c626d995da07d04322238aa4997a2671735a",
/* Benign .NET / line-of-business self-JIT connect FPs (final user module == app's own image) */
"69ace587844c0aa44ea1dee8940511551e87e8fbb3a932849edce65fd50847d9",
"ed31c93ea887979c30f1f1cce1cc89511d43ba8ee1a773e3222e715983de21b3",
"7b0574df592f2f9bd4aa48c2cd539c2b9de446ad35ccf251febb600c0d60504d",
"b1e85acdf8534d1e212eb718bc4c9a8f4a6f43946ef5848033e760a80b32498d",
"99def4498e85e1d743de4617cbd92f466a4e44cd63bd1903f8dc9188383d510f",
"3a93f916e0d1ace1bb58ca3f43f795a810b63e612c0111a3f6ba89f9200f6a6f",
"05ef99be431f5c9b358d441c16e768935d1985575b17da389e16c86846abf2d3",
"70b2465ae7ea0e4c1305444461d7e288408672dbb7c89dd1fdfb15811f4cf301",
"fef5877c154ea2c659b208c18858f41a02645afd76cd4c4b8c78743c448d2ea0",
"fb281ac7ace96aa7c861c50817129be075ebf324f75ae80325cad09ff7c93fc7",
"7034ceeb12f7424cd823613644f75b4730fd01de2acd34f21eaec5a1b5bf477f",
"bbb81a7eca67cb4c0ea4ca96bcecd6cf6e0ccab0900836fd412ea932056d45c6",
"2b578ecba28f0170ce30d54b394069da0994ff21411567dc30a45b8a480fe00d",
"c779c56ed1a67711518bd6216e0966bc0ec1ab8d7a236645d5861d9d55bb6278",
"920ef6ece9c965246e8386fd45dd85aa799a572d810a03fdac711b0eea6640d9",
"13090ed9a4bbdb2bb1a23f5b21d89d71bbabe474b9556ba62f517e010ed700f7") and
not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info : "Unbacked*" and
$entry.callsite_trailing_bytes :
("*85f60f95c10fb6c9894dac488bcce82f000000908b45*",
"*8bc641c6470c01488b558849895710488d65c85b5e5f415c41",
"c2280090b808001a00ba408f*d2c2240090b809001c00ba408f*",
"41c6470c01833d*5e8bc641c6470c01488b558849895710488d65*",
"81bbc40000002afb0149742a33c08d55f450ff8d78ffffff6a0252e8e27c100083c408588b955cffffff64891500000000e96703000085c00f842d020000e89f",
"8bd8488d8d28ffffffff15f40a04009033c0488945b033c0488945b8ff15591304008bc8ff154113040085db0f95c30fb6db807dc000740e488b4d184c8d1de0",
"488b9550ffffffc6420c01833d3efbd15f007406ff150a18d15f89855cffffffe8a7f4535f908b8d5cffffff898d70ffffff83bd70ffffff000f95c10fb6c989",
"41c6470c01833dd1b6055c007406ff15310a055c488b8d70ffffff49894f108bd833c0488945b033c0488945b848b850652addfd7f0000ffd08bc8e87dcaa15b",
"41c6470c01833dc8c42649007406ff1540d026498bf0e8a11a8d488bc641c6470c01488b558849895710488d65c85b5e5f415c415d415e415f5dc30019130a00")) and
not process.thread.Ext.call_stack_final_user_module.protection_provenance like ("Unknown", "Kernel", "Kernel|*", "*.ni.dll", "coreclr.dll", "Undetermined", "hmpalert.dll", "em003_64.dll") and
not process.executable : ("C:\\Program Files\\Veeam\\Backup and Replication\\Backup\\Veeam.Backup.Service.exe",
"C:\\Program Files\\Citrix\\Broker\\Service\\BrokerService.exe",
"C:\\Program Files\\Qlik\\Sense\\ServiceDispatcher\\dotnet\\dotnet.exe",
"C:\\Program Files\\Solari di Udine\\Inout Integration Service\\INOUT.Integration.Service.exe",
"C:\\Program Files\\Intel\\SUR\\QUEENCREEK\\SurSvc.exe",
"C:\\Program Files (x86)\\AdRem\\NetCrunch\\Console\\*\\NCConsole.exe",
"C:\\Program Files\\Epic Games\\MarvelRivalsjKtnW\\MarvelGame\\Marvel\\Binaries\\Win64\\Marvel-Win64-Shipping.exe",
"C:\\Program Files\\winacme\\wacs.exe") and
not process.thread.Ext.call_stack_final_user_module.protection_provenance == "inprocessclient64.dll"
'''
min_endpoint_version = "8.14.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/"
[[threat]]
framework = "MITRE ATT&CK"
[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[internal]
min_endpoint_version = "8.14.0"
Stages and Predicates
Stage 1: api
api where process.Ext.api.name == "connect" and process.Ext.api.summary: "*ipv4*" and
process.thread.Ext.call_stack_final_user_module.name == "Unbacked" and
(
process.thread.Ext.call_stack_summary :
("ntdll.dll|mswsock.dll|ws2_32.dll|Unbacked",
"ntdll.dll|mswsock.dll|Unbacked",
"wow64cpu.dll|wow64.dll|ntdll.dll|mswsock.dll|ws2_32.dll|Unbacked",
"wow64cpu.dll|wow64.dll|ntdll.dll|mswsock.dll|Unbacked") or
((process.code_signature.trusted == false or process.code_signature.exists == false) and
startswith~(process.thread.Ext.call_stack_summary, concat("wow64cpu.dll|wow64.dll|ntdll.dll|mswsock.dll|ws2_32.dll|Unbacked|", process.name))) or
((process.code_signature.trusted == false or process.code_signature.exists == false) and
startswith~(process.thread.Ext.call_stack_summary, concat("ntdll.dll|mswsock.dll|ws2_32.dll|Unbacked", process.name)))
) and
_arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info : "Unbacked*" and $entry.callsite_trailing_bytes : "?*") and
not _arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature, $entry, $entry.trusted == true) and
process.thread.Ext.call_stack_final_user_module.hash.sha256 != null and
not process.thread.Ext.call_stack_final_user_module.hash.sha256 in
("02ecce804add1da0a9e7be506f7369d3d5753c51c80abe32b24be05c321c5ff7",
"f823fc285b259fd0a5391a5c807279e90fe5317e6cfd7b00a49f07c278832cbc",
"236b9ab2b531da7312da1429cba1bd9f45cae4ed46cba1792924013b9919f8cf",
"5d4708e841bdd2523c963e45932555ba98e203c6a99f242573f251374f73cb63",
"ff4dd86a9ef8ccedd9a01dee516775eea75edcef0ff313b718df3dc4a026f395",
"0e675101b1814b932f8c1209b5e355636c18767da413a261667ce2bedd3c7914",
"aeda6c3b3b1dc1e91d1cbbea6863eaf5fe02eef74827fe533f4b7d55e388a9b1",
"99f9058c1481370d03a511a8863a9b6e36c34d4f0066b17ad0f6666c86eed152",
"9b1865415f947505eff3084830193d1a6bf317d8e704d401b1a8ffb91a3d9277",
"7f28d5f5d96183ed01c345fdc5d28e82ae255aa19ecb329ab9fa9ecdf10f79de",
"5ec183e4e31a18a7788ffa4514e1e555d458725e4521160221ea36df5e29a35f",
"5d1ace7a28fb13f34a4f56045f41285b2f07764f42e09fc4d5ce72b10ffbed38",
"df13445949901d9f43575ad8fd5005a490e9a2fa68e27e26e6ea6d4014b83635",
"8b354c30a6fccb12963cf2bf06fcf60efcc2bef7e3b735cab36f4b26e8cd105b",
"c809da8be3cad745801f3668df829bddc39e7ffb0c526fe98ada697b60811922",
"b4e067d5b1f09821e7a3b6106547ee23572f64e604ffa29041b8cbc7e63b58a7",
"dcfa8e77235026558f65e6ab82d2b9e69768f023204062f628234b2b5506fd32",
"617b0977d387472a4ca0948f1ba19640a21d1fa1dca52e3047c5e630af231062",
"50f903bc4b496b94051b9cba15eccd9c25bb963c7424f2845fbc0897bd7d391d",
"c094179af7a6a3bfae751fc30ff13b711e055ffa563fc98b3d3b3aa57584a424",
"2fe43a4716927f4600f44bfc7ffa43584fb5bea404ff5624d4bb5efaddec174a",
"bb55748883f650e45921b875a546e0174ff8251d77043d3cab4de60eff7cd9f8",
"f2c8fbd754527f3411c31068975f316970fcb3bb7ba611d5d2f20d17489e6d32",
"c160ce8529cd5131f1c349bc92c5b3e989b0cac7fcbdd1318eb484eb3b4ca49f",
"3d86479ab47b249241e7d392ef5daf2263b341f4a77755ac285c629dfc71f06c",
"bf85b58dada12a821a8ee445a6d7b97b7e984eb4db88a9bcb3e3fa698c88d345",
"a87b3f02042de4d655f72af65ed5242fae5c675bebd19e962978c13e6d99ba00",
"eb70e1f2aad9d66f0ca71b3b57ad6b8c6f7fa623155a589afe82a899f7dd88c4",
"bbff088a88a0a754dc9d312e52ef7e60dd93537d78d73f79c89aa5b5091457fc",
"c817a4c49167176bfa6335b950d629b31ff553e943b9ab835b88f6c2ee09fc82",
"7dd3acf9f47641ce621e4db5980ab8f7a3f67c9a4f008f36b56d59afefbedfa9",
"0be7c1898ca40070ba6807cdc95722a35cbee79fa08399abd714b90a5b5239d5",
"9ce7991f13bf252648ea4766299cb59ab291771937b11a7a7a04df2c540d565d",
"3f74481e6991404f951ff5168c6726a521c566eb408a654d776109afdb963655",
"6e7533220f0715156b9baa401fb13a71735aabfb1443dad6a3835ab8a38750bf",
"7b5e0b0bc2ca257071210ddb787cb18d65621bb7d1034ea946937ca565977bbd",
"c9e303d84e5fa603c85abee0caefa8b0ef393aab6805e2ea5098ca927fa2b6cf",
"6e79c9271cddc0a4bb3e8af619967d54ea6df7067798fd5da9ccca233b221da0",
"fddac9c6330518eb74b92abeee411e91ef3189fb3ed04508a9f3ebd5991fdb30",
"335790ae673d41cc7d4b3c6c1a9c16c7bb3260fc24d4caced80dbe4cfd9a4f6e",
"6f7d83b779e164ddf58c2bff7a719caba1887c6c92dc72fd2eb4e1394fbf51c4",
"26e5c00c35c5c3edc86dfc0a720aed109a13b1b7c67ac654a0ce8ff82a1f2c16",
"fdff5c5612e0bcbc8aba52720e5d37e5c3821267179e2fa7341084148ad4b1ea",
"834b0fce44e8db2367967f8d5262a0dafe45e7c5bd69c98f1a9eeec2136dcbc1",
"7eb92b8b9ce2d44a500c56ea04e805cb78614c572dc723c79c59ca93315ba709",
"3eb37ba3fc39f5749bbb3f17382d0966adf2e061f4f0d1757ebd75fed1302dd6",
"0b29ecbb5277629a1be89193941ec9d58867118ab7ef6a9d0235f7c5388904d7",
"0f4828417f3c8f8c6a5d74c39cb1dc746b241901e8bdd53bb09808858b7b0a08",
"cd08541db31221a2e26238cd6a2bcd6a9ebb9a4c4205c09b1b2050fde409f284",
"f834e4447d0b4c421ac2a0a9b10304a47688f358a6db9c1281bffe44957bcc4e",
"d0615bcbcaf0c64b2613c224924fce9e891a62287acc243a9b142ee0d021b207",
"7c71327ab87990b1ac0446813f2f1e69c33cc634afab5857cfa9fca17d0cc37e",
"ecbd9f72fe48043302f547643b26e2da9c12c4d8030d28e53f1651fb0e06a2ca",
"c11d8f8d419aee8d67166ae9eeed3999364fa41a7d701ede076f2d2ad8acb8be",
"ad71a3681f0fa629133a67f04d64c626d995da07d04322238aa4997a2671735a",
"69ace587844c0aa44ea1dee8940511551e87e8fbb3a932849edce65fd50847d9",
"ed31c93ea887979c30f1f1cce1cc89511d43ba8ee1a773e3222e715983de21b3",
"7b0574df592f2f9bd4aa48c2cd539c2b9de446ad35ccf251febb600c0d60504d",
"b1e85acdf8534d1e212eb718bc4c9a8f4a6f43946ef5848033e760a80b32498d",
"99def4498e85e1d743de4617cbd92f466a4e44cd63bd1903f8dc9188383d510f",
"3a93f916e0d1ace1bb58ca3f43f795a810b63e612c0111a3f6ba89f9200f6a6f",
"05ef99be431f5c9b358d441c16e768935d1985575b17da389e16c86846abf2d3",
"70b2465ae7ea0e4c1305444461d7e288408672dbb7c89dd1fdfb15811f4cf301",
"fef5877c154ea2c659b208c18858f41a02645afd76cd4c4b8c78743c448d2ea0",
"fb281ac7ace96aa7c861c50817129be075ebf324f75ae80325cad09ff7c93fc7",
"7034ceeb12f7424cd823613644f75b4730fd01de2acd34f21eaec5a1b5bf477f",
"bbb81a7eca67cb4c0ea4ca96bcecd6cf6e0ccab0900836fd412ea932056d45c6",
"2b578ecba28f0170ce30d54b394069da0994ff21411567dc30a45b8a480fe00d",
"c779c56ed1a67711518bd6216e0966bc0ec1ab8d7a236645d5861d9d55bb6278",
"920ef6ece9c965246e8386fd45dd85aa799a572d810a03fdac711b0eea6640d9",
"13090ed9a4bbdb2bb1a23f5b21d89d71bbabe474b9556ba62f517e010ed700f7") and
not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info : "Unbacked*" and
$entry.callsite_trailing_bytes :
("*85f60f95c10fb6c9894dac488bcce82f000000908b45*",
"*8bc641c6470c01488b558849895710488d65c85b5e5f415c41",
"c2280090b808001a00ba408f*d2c2240090b809001c00ba408f*",
"41c6470c01833d*5e8bc641c6470c01488b558849895710488d65*",
"81bbc40000002afb0149742a33c08d55f450ff8d78ffffff6a0252e8e27c100083c408588b955cffffff64891500000000e96703000085c00f842d020000e89f",
"8bd8488d8d28ffffffff15f40a04009033c0488945b033c0488945b8ff15591304008bc8ff154113040085db0f95c30fb6db807dc000740e488b4d184c8d1de0",
"488b9550ffffffc6420c01833d3efbd15f007406ff150a18d15f89855cffffffe8a7f4535f908b8d5cffffff898d70ffffff83bd70ffffff000f95c10fb6c989",
"41c6470c01833dd1b6055c007406ff15310a055c488b8d70ffffff49894f108bd833c0488945b033c0488945b848b850652addfd7f0000ffd08bc8e87dcaa15b",
"41c6470c01833dc8c42649007406ff1540d026498bf0e8a11a8d488bc641c6470c01488b558849895710488d65c85b5e5f415c415d415e415f5dc30019130a00")) and
not process.thread.Ext.call_stack_final_user_module.protection_provenance like ("Unknown", "Kernel", "Kernel|*", "*.ni.dll", "coreclr.dll", "Undetermined", "hmpalert.dll", "em003_64.dll") and
not process.executable : ("C:\\Program Files\\Veeam\\Backup and Replication\\Backup\\Veeam.Backup.Service.exe",
"C:\\Program Files\\Citrix\\Broker\\Service\\BrokerService.exe",
"C:\\Program Files\\Qlik\\Sense\\ServiceDispatcher\\dotnet\\dotnet.exe",
"C:\\Program Files\\Solari di Udine\\Inout Integration Service\\INOUT.Integration.Service.exe",
"C:\\Program Files\\Intel\\SUR\\QUEENCREEK\\SurSvc.exe",
"C:\\Program Files (x86)\\AdRem\\NetCrunch\\Console\\*\\NCConsole.exe",
"C:\\Program Files\\Epic Games\\MarvelRivalsjKtnW\\MarvelGame\\Marvel\\Binaries\\Win64\\Marvel-Win64-Shipping.exe",
"C:\\Program Files\\winacme\\wacs.exe") and
not process.thread.Ext.call_stack_final_user_module.protection_provenance == "inprocessclient64.dll"
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.thread.Ext.call_stack | array_any | excludes:process.thread.Ext.call_stack | |
process.thread.Ext.call_stack_final_user_module.code_signature | array_any | excludes:process.thread.Ext.call_stack_final_user_module.code_signature | |
process.executable | wildcard | C:\Program Files\Veeam\Backup and Replication\Backup\Veeam.Backup.Service.exe, C:\Program Files\Citrix\Broker\Service\BrokerService.exe, C:\Program Files\Qlik\Sense\ServiceDispatcher\dotnet\dotnet.exe, C:\Program Files\Solari di Udine\Inout Integration Service\INOUT.Integration.Service.exe, C:\Program Files\Intel\SUR\QUEENCREEK\SurSvc.exe, C:\Program Files (x86)\AdRem\NetCrunch\Console\*\NCConsole.exe, C:\Program Files\Epic Games\MarvelRivalsjKtnW\MarvelGame\Marvel\Binaries\Win64\Marvel-Win64-Shipping.exe, C:\Program Files\winacme\wacs.exe | excludes:process.executable |
process.thread.Ext.call_stack_final_user_module.hash.sha256 | in | 02ecce804add1da0a9e7be506f7369d3d5753c51c80abe32b24be05c321c5ff7, 05ef99be431f5c9b358d441c16e768935d1985575b17da389e16c86846abf2d3, 0b29ecbb5277629a1be89193941ec9d58867118ab7ef6a9d0235f7c5388904d7, 0be7c1898ca40070ba6807cdc95722a35cbee79fa08399abd714b90a5b5239d5, 0e675101b1814b932f8c1209b5e355636c18767da413a261667ce2bedd3c7914, 0f4828417f3c8f8c6a5d74c39cb1dc746b241901e8bdd53bb09808858b7b0a08, 13090ed9a4bbdb2bb1a23f5b21d89d71bbabe474b9556ba62f517e010ed700f7, 236b9ab2b531da7312da1429cba1bd9f45cae4ed46cba1792924013b9919f8cf, 26e5c00c35c5c3edc86dfc0a720aed109a13b1b7c67ac654a0ce8ff82a1f2c16, 2b578ecba28f0170ce30d54b394069da0994ff21411567dc30a45b8a480fe00d, 2fe43a4716927f4600f44bfc7ffa43584fb5bea404ff5624d4bb5efaddec174a, 335790ae673d41cc7d4b3c6c1a9c16c7bb3260fc24d4caced80dbe4cfd9a4f6e, 3a93f916e0d1ace1bb58ca3f43f795a810b63e612c0111a3f6ba89f9200f6a6f, 3d86479ab47b249241e7d392ef5daf2263b341f4a77755ac285c629dfc71f06c, 3eb37ba3fc39f5749bbb3f17382d0966adf2e061f4f0d1757ebd75fed1302dd6, 3f74481e6991404f951ff5168c6726a521c566eb408a654d776109afdb963655, 50f903bc4b496b94051b9cba15eccd9c25bb963c7424f2845fbc0897bd7d391d, 5d1ace7a28fb13f34a4f56045f41285b2f07764f42e09fc4d5ce72b10ffbed38, 5d4708e841bdd2523c963e45932555ba98e203c6a99f242573f251374f73cb63, 5ec183e4e31a18a7788ffa4514e1e555d458725e4521160221ea36df5e29a35f, 617b0977d387472a4ca0948f1ba19640a21d1fa1dca52e3047c5e630af231062, 69ace587844c0aa44ea1dee8940511551e87e8fbb3a932849edce65fd50847d9, 6e7533220f0715156b9baa401fb13a71735aabfb1443dad6a3835ab8a38750bf, 6e79c9271cddc0a4bb3e8af619967d54ea6df7067798fd5da9ccca233b221da0, 6f7d83b779e164ddf58c2bff7a719caba1887c6c92dc72fd2eb4e1394fbf51c4, 7034ceeb12f7424cd823613644f75b4730fd01de2acd34f21eaec5a1b5bf477f, 70b2465ae7ea0e4c1305444461d7e288408672dbb7c89dd1fdfb15811f4cf301, 7b0574df592f2f9bd4aa48c2cd539c2b9de446ad35ccf251febb600c0d60504d, 7b5e0b0bc2ca257071210ddb787cb18d65621bb7d1034ea946937ca565977bbd, 7c71327ab87990b1ac0446813f2f1e69c33cc634afab5857cfa9fca17d0cc37e, 7dd3acf9f47641ce621e4db5980ab8f7a3f67c9a4f008f36b56d59afefbedfa9, 7eb92b8b9ce2d44a500c56ea04e805cb78614c572dc723c79c59ca93315ba709, 7f28d5f5d96183ed01c345fdc5d28e82ae255aa19ecb329ab9fa9ecdf10f79de, 834b0fce44e8db2367967f8d5262a0dafe45e7c5bd69c98f1a9eeec2136dcbc1, 8b354c30a6fccb12963cf2bf06fcf60efcc2bef7e3b735cab36f4b26e8cd105b, 920ef6ece9c965246e8386fd45dd85aa799a572d810a03fdac711b0eea6640d9, 99def4498e85e1d743de4617cbd92f466a4e44cd63bd1903f8dc9188383d510f, 99f9058c1481370d03a511a8863a9b6e36c34d4f0066b17ad0f6666c86eed152, 9b1865415f947505eff3084830193d1a6bf317d8e704d401b1a8ffb91a3d9277, 9ce7991f13bf252648ea4766299cb59ab291771937b11a7a7a04df2c540d565d, a87b3f02042de4d655f72af65ed5242fae5c675bebd19e962978c13e6d99ba00, ad71a3681f0fa629133a67f04d64c626d995da07d04322238aa4997a2671735a, aeda6c3b3b1dc1e91d1cbbea6863eaf5fe02eef74827fe533f4b7d55e388a9b1, b1e85acdf8534d1e212eb718bc4c9a8f4a6f43946ef5848033e760a80b32498d, b4e067d5b1f09821e7a3b6106547ee23572f64e604ffa29041b8cbc7e63b58a7, bb55748883f650e45921b875a546e0174ff8251d77043d3cab4de60eff7cd9f8, bbb81a7eca67cb4c0ea4ca96bcecd6cf6e0ccab0900836fd412ea932056d45c6, bbff088a88a0a754dc9d312e52ef7e60dd93537d78d73f79c89aa5b5091457fc, bf85b58dada12a821a8ee445a6d7b97b7e984eb4db88a9bcb3e3fa698c88d345, c094179af7a6a3bfae751fc30ff13b711e055ffa563fc98b3d3b3aa57584a424, c11d8f8d419aee8d67166ae9eeed3999364fa41a7d701ede076f2d2ad8acb8be, c160ce8529cd5131f1c349bc92c5b3e989b0cac7fcbdd1318eb484eb3b4ca49f, c779c56ed1a67711518bd6216e0966bc0ec1ab8d7a236645d5861d9d55bb6278, c809da8be3cad745801f3668df829bddc39e7ffb0c526fe98ada697b60811922, c817a4c49167176bfa6335b950d629b31ff553e943b9ab835b88f6c2ee09fc82, c9e303d84e5fa603c85abee0caefa8b0ef393aab6805e2ea5098ca927fa2b6cf, cd08541db31221a2e26238cd6a2bcd6a9ebb9a4c4205c09b1b2050fde409f284, d0615bcbcaf0c64b2613c224924fce9e891a62287acc243a9b142ee0d021b207, dcfa8e77235026558f65e6ab82d2b9e69768f023204062f628234b2b5506fd32, df13445949901d9f43575ad8fd5005a490e9a2fa68e27e26e6ea6d4014b83635, eb70e1f2aad9d66f0ca71b3b57ad6b8c6f7fa623155a589afe82a899f7dd88c4, ecbd9f72fe48043302f547643b26e2da9c12c4d8030d28e53f1651fb0e06a2ca, ed31c93ea887979c30f1f1cce1cc89511d43ba8ee1a773e3222e715983de21b3, f2c8fbd754527f3411c31068975f316970fcb3bb7ba611d5d2f20d17489e6d32, f823fc285b259fd0a5391a5c807279e90fe5317e6cfd7b00a49f07c278832cbc, f834e4447d0b4c421ac2a0a9b10304a47688f358a6db9c1281bffe44957bcc4e, fb281ac7ace96aa7c861c50817129be075ebf324f75ae80325cad09ff7c93fc7, fddac9c6330518eb74b92abeee411e91ef3189fb3ed04508a9f3ebd5991fdb30, fdff5c5612e0bcbc8aba52720e5d37e5c3821267179e2fa7341084148ad4b1ea, fef5877c154ea2c659b208c18858f41a02645afd76cd4c4b8c78743c448d2ea0, ff4dd86a9ef8ccedd9a01dee516775eea75edcef0ff313b718df3dc4a026f395 | excludes:process.thread.Ext.call_stack_final_user_module.hash.sha256 |
process.thread.Ext.call_stack_final_user_module.protection_provenance | eq | inprocessclient64.dll | excludes:process.thread.Ext.call_stack_final_user_module.protection_provenance field:"process.thread.Ext.call_stack_final_user_module.protection_provenance" value:"inprocessclient64.dll" |
process.thread.Ext.call_stack_final_user_module.protection_provenance | wildcard | Unknown, Kernel, Kernel|*, *.ni.dll, coreclr.dll, Undetermined, hmpalert.dll, em003_64.dll | excludes:process.thread.Ext.call_stack_final_user_module.protection_provenance |
Osascript Payload Drop and Execute
#Detects when a payload is dropped to a temporary location and executed via osascript. This technique is used by malware like Apfell agent to establish new callbacks.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Command & Control |
Telemetry Coverage
Rule Body
[rule]
description = """
Detects when a payload is dropped to a temporary location and executed via osascript. This technique is used by malware
like Apfell agent to establish new callbacks.
"""
id = "2cf4a0ba-6d6e-4984-963e-ee4785f8c9b6"
license = "Elastic License v2"
name = "Osascript Payload Drop and Execute"
os_list = ["macos"]
reference = [
"https://github.com/MythicAgents/apfell/",
"https://github.com/MythicAgents/apfell/blob/master/documentation-payload/apfell/commands/spawn_drop_and_execute.md",
"https://www.elastic.co/security-labs/beyond-the-wail",
]
version = "1.0.20"
query = '''
sequence with maxspan=15s
[file where event.action == "modification" and
(file.path like~ ("/Users/Shared/*",
"/tmp/*",
"/private/tmp/*",
"/var/tmp/*",
"/private/var/tmp/*",
"/Users/*/Library/Assistant/CustomVocabulary/*",
"/private/var/folders/*",
"/var/folders/*") or
file.name like ".*") and
file.extension in ("scpt", "sh", "js", "lock") and
not file.path like~ ("/tmp/claude/*", "/private/tmp/claude/*", "/private/tmp/claude-*/*")] as event0
[process where event.type == "start" and event.action == "exec" and
process.name == "osascript" and stringcontains~(process.command_line, event0.file.name) and
not process.args == "-e" and
not (process.parent.name in ("zsh", "bash", "sh") and process.parent.command_line : (
"*/.claude/shell-snapshots/*",
"*/.codex/shell_snapshots/*",
"*/.cursor/shell-snapshots/*"))]
'''
min_endpoint_version = "8.11.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 1
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1105"
name = "Ingress Tool Transfer"
reference = "https://attack.mitre.org/techniques/T1105/"
[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[internal]
min_endpoint_version = "8.11.0"
Stages and Predicates
Stage 1: file
[file where event.action == "modification" and
(file.path like~ ("/Users/Shared/*",
"/tmp/*",
"/private/tmp/*",
"/var/tmp/*",
"/private/var/tmp/*",
"/Users/*/Library/Assistant/CustomVocabulary/*",
"/private/var/folders/*",
"/var/folders/*") or
file.name like ".*") and
file.extension in ("scpt", "sh", "js", "lock") and
not file.path like~ ("/tmp/claude/*", "/private/tmp/claude/*", "/private/tmp/claude-*/*")] as event0
Stage 2: process
[process where event.type == "start" and event.action == "exec" and
process.name == "osascript" and stringcontains~(process.command_line, event0.file.name) and
not process.args == "-e" and
not (process.parent.name in ("zsh", "bash", "sh") and process.parent.command_line : (
"*/.claude/shell-snapshots/*",
"*/.codex/shell_snapshots/*",
"*/.cursor/shell-snapshots/*"))]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
file.extension | in |
| field:"file.extension" kind:in |
file.name | wildcard |
| field:"file.name" kind:wildcard value:".*" |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard |
process.command_line | contains |
| field:"CommandLine" kind:contains value:"event0.file.name" |
process.name | eq |
| field:"process_basename" kind:eq value:"osascript" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
file.path | wildcard | /tmp/claude/*, /private/tmp/claude/*, /private/tmp/claude-*/* | excludes:file.path field:"file.path" value:"/tmp/claude/*" field:"file.path" value:"/private/tmp/claude/*" field:"file.path" value:"/private/tmp/claude-*/*" |
process.parent.command_line | match | /.claude/shell-snapshots/, /.codex/shell_snapshots/, /.cursor/shell-snapshots/ | excludes:process.parent.command_line field:"process.parent.command_line" value:"/.claude/shell-snapshots/" field:"process.parent.command_line" value:"/.codex/shell_snapshots/" field:"process.parent.command_line" value:"/.cursor/shell-snapshots/" |
process.parent.name | in | bash, sh, zsh | excludes:process.parent.name field:"process.parent.name" value:"bash" field:"process.parent.name" value:"sh" field:"process.parent.name" value:"zsh" |
process.args | eq | -e | excludes:process.args field:"process.args" value:"-e" |
Potential Credential Discovery via Recursive Grep
#Identifies recursive grep activity on Linux or macOS where the command line suggests hunting for secrets, credentials, keys, tokens, or sensitive paths (for example .env, .git, .aws). Events are aggregated per host, user, parent process, and one-minute window, the rule surfaces activity only when at least three distinct grep command lines match in the same bucket, to reduce noise from one-off searches.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access | |
| Discovery |
Rule Body
[metadata]
creation_date = "2026/03/25"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/25"
[rule]
author = ["Elastic"]
description = """
Identifies recursive grep activity on Linux or macOS where the command line suggests hunting for secrets, credentials,
keys, tokens, or sensitive paths (for example .env, .git, .aws). Events are aggregated per host, user, parent process,
and one-minute window, the rule surfaces activity only when at least three distinct grep command lines match in the same
bucket, to reduce noise from one-off searches.
"""
from = "now-9m"
interval = "5m"
language = "esql"
license = "Elastic License v2"
name = "Potential Credential Discovery via Recursive Grep"
note = """## Triage and analysis
### Investigating Potential Credential Discovery via Recursive Grep
Adversaries and insider threats sometimes use `grep -r` (or `--recursive`, `-R`) across directories to find passwords,
API keys, private keys, cloud tokens, or repository and environment files. This rule looks for `grep`/`egrep` process
starts with recursive flags and command-line patterns associated with credential and secret discovery, then requires
**three or more distinct command lines** in the same one-minute bucket per host, user, and parent process.
### Possible investigation steps
- Review **Esql.cmd_values** for the exact patterns searched (paths, regex, file globs).
- Inspect **Esql.pcmd_values** and **process.parent.name** to see the launch context (interactive shell, script, IDE, CI).
- Confirm whether the user and host normally run security scans, audits, or developer tooling that legitimately greps for secrets.
- If suspicious, search the same host for file access, archive exfiltration, or cloud API use in the surrounding timeframe.
### False positive analysis
- Security scanners, secret scanners (e.g. in CI), and compliance scripts may match. Tune by **parent process**, **user**,
**working directory**, or organizational allowlists.
- Legitimate searches in documentation for the word "password" can match; the **unique_cmd >= 3** threshold reduces but
does not eliminate this.
### Response and remediation
- If unauthorized: contain the host, reset or rotate any credentials that may have been exposed, and review VCS and
cloud audit logs for follow-on abuse.
"""
references = [
"https://attack.mitre.org/techniques/T1552/001/",
"https://attack.mitre.org/techniques/T1083/",
]
risk_score = 73
rule_id = "b8e4c2a1-7f3d-4e9b-8c5a-1d0e6f2a4b8c"
severity = "high"
tags = [
"Domain: Endpoint",
"OS: Linux",
"OS: macOS",
"Use Case: Threat Detection",
"Tactic: Credential Access",
"Tactic: Discovery",
"Resources: Investigation Guide",
"Data Source: Elastic Defend",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-endpoint.events.process-* metadata _id, _version, _index
| where host.os.type in ("linux", "macos")
and event.category == "process"
and process.name in ("grep", "egrep")
and (to_lower(process.command_line) like "* -r*" or to_lower(process.command_line) like "*--recursive*")
and (
process.command_line like "*password*"
or process.command_line like "*passwd*"
or process.command_line like "*pwd*"
or process.command_line like "*secret*"
or process.command_line like "*token*"
or process.command_line like "*apikey*"
or process.command_line like "*api_key*"
or process.command_line like "*api.key*"
or process.command_line like "*access_key*"
or process.command_line like "*private_key*"
or process.command_line like "*client_secret*"
or process.command_line like "*credential*"
or process.command_line like "*auth*"
or process.command_line like "*bearer*"
or process.command_line like "*BEGIN*PRIVATE*KEY*"
or process.command_line like "*ssh-rsa*"
or process.command_line like "*ghp_*"
or process.command_line like "*github_pat*"
or process.command_line like "*xoxb-*"
or process.command_line like "*hooks.slack.com*"
or process.command_line like "*discord.com/api/webhooks*"
or process.command_line like "*/.aws/*"
or process.command_line like "*/.git/*"
or process.command_line like "*/.env*"
)
and (process.parent.command_line is null or not (to_lower(process.parent.command_line) like "*shell-snapshots*" and process.parent.name in ("bash", "sh", "zsh")))
| eval Esql.time_bucket = date_trunc(1 minute, @timestamp)
| stats Esql.unique_cmd = count_distinct(process.command_line),
Esql.cmd_values = values(process.command_line),
Esql.pcmd_values = values(process.parent.command_line)
by process.name, host.id, host.name, agent.id, process.parent.name, user.name, Esql.time_bucket
| where Esql.unique_cmd >= 3
| keep host.id, host.name, agent.id, user.name, process.parent.name, Esql.*
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1552"
name = "Unsecured Credentials"
reference = "https://attack.mitre.org/techniques/T1552/"
[[rule.threat.technique.subtechnique]]
id = "T1552.001"
name = "Credentials In Files"
reference = "https://attack.mitre.org/techniques/T1552/001/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1083"
name = "File and Directory Discovery"
reference = "https://attack.mitre.org/techniques/T1083/"
[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
Stages and Predicates
Stage 1: from
from logs-endpoint.events.process-* metadata _id, _version, _index
Stage 2: where
| where host.os.type in ("linux", "macos")
and event.category == "process"
and process.name in ("grep", "egrep")
and (to_lower(process.command_line) like "* -r*" or to_lower(process.command_line) like "*--recursive*")
and (
process.command_line like "*password*"
or process.command_line like "*passwd*"
or process.command_line like "*pwd*"
or process.command_line like "*secret*"
or process.command_line like "*token*"
or process.command_line like "*apikey*"
or process.command_line like "*api_key*"
or process.command_line like "*api.key*"
or process.command_line like "*access_key*"
or process.command_line like "*private_key*"
or process.command_line like "*client_secret*"
or process.command_line like "*credential*"
or process.command_line like "*auth*"
or process.command_line like "*bearer*"
or process.command_line like "*BEGIN*PRIVATE*KEY*"
or process.command_line like "*ssh-rsa*"
or process.command_line like "*ghp_*"
or process.command_line like "*github_pat*"
or process.command_line like "*xoxb-*"
or process.command_line like "*hooks.slack.com*"
or process.command_line like "*discord.com/api/webhooks*"
or process.command_line like "*/.aws/*"
or process.command_line like "*/.git/*"
or process.command_line like "*/.env*"
)
and (process.parent.command_line is null or not (to_lower(process.parent.command_line) like "*shell-snapshots*" and process.parent.name in ("bash", "sh", "zsh")))
Stage 3: eval
| eval Esql.time_bucket = date_trunc(1 minute, @timestamp)
Stage 4: stats
| stats Esql.unique_cmd = count_distinct(process.command_line),
Esql.cmd_values = values(process.command_line),
Esql.pcmd_values = values(process.parent.command_line)
by process.name, host.id, host.name, agent.id, process.parent.name, user.name, Esql.time_bucket
Stage 5: where
| where Esql.unique_cmd >= 3
Stage 6: keep
| keep host.id, host.name, agent.id, user.name, process.parent.name, Esql.*
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Esql.unique_cmd | ge |
| field:"Esql.unique_cmd" kind:ge value:"3" |
event.category | eq |
| field:"event.category" kind:eq value:"process" |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard |
process.name | in |
| field:"process_basename" kind:in |
process.parent.command_line | is_null | field:"ParentCommandLine" kind:is_null |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
host.id | KEEP host.id |
host.name | KEEP host.name |
agent.id | KEEP agent.id |
user.name | KEEP user.name |
process.parent.name | KEEP process.parent.name |
Esql.* | KEEP Esql.* |
Potential Defense Evasion via CMSTP.exe
#The Microsoft Connection Manager Profile Installer (CMSTP.exe) is a command-line program to install Connection Manager service profiles, which accept installation information file (INF) files. Adversaries may abuse CMSTP to proxy the execution of malicious code by supplying INF files that contain malicious commands.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 1: Process creation |
| Security-Auditing | Event ID 4688: A new process has been created. |
Rule Body
[metadata]
bypass_bbr_timing = true
creation_date = "2023/08/24"
integration = ["endpoint", "windows", "system"]
maturity = "production"
updated_date = "2025/03/20"
[rule]
author = ["Elastic"]
building_block_type = "default"
description = """
The Microsoft Connection Manager Profile Installer (CMSTP.exe) is a command-line program to install Connection Manager
service profiles, which accept installation information file (INF) files. Adversaries may abuse CMSTP to proxy the
execution of malicious code by supplying INF files that contain malicious commands.
"""
from = "now-9m"
index = [
"endgame-*",
"logs-endpoint.events.process-*",
"logs-system.security*",
"logs-windows.sysmon_operational-*",
"winlogbeat-*",
]
language = "eql"
license = "Elastic License v2"
name = "Potential Defense Evasion via CMSTP.exe"
references = ["https://attack.mitre.org/techniques/T1218/003/"]
risk_score = 21
rule_id = "bd3d058d-5405-4cee-b890-337f09366ba2"
severity = "low"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Defense Evasion",
"Data Source: Elastic Defend",
"Rule Type: BBR",
"Data Source: Sysmon",
"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 : "cmstp.exe" and process.args == "/s"
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"
[[rule.threat.technique.subtechnique]]
id = "T1218.003"
name = "CMSTP"
reference = "https://attack.mitre.org/techniques/T1218/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 : "cmstp.exe" and process.args == "/s"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | eq |
| field:"process.args" kind:eq value:"/s" |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:"cmstp.exe" |
Potential DNS Rebinding from Public to Private Address
#Identifies a client resolving the same public registered domain to both a public IP address and a private, loopback, link-local, unique-local IPv6, or shared address. This includes both address classes being observed at the same timestamp, and a public answer followed within five minutes by a private answer where the minimum TTL across all answer records in the private-answer events is 60 seconds or less. Either pattern is consistent with DNS rebinding that pivots browser or application trust to internal resources.
Known False Positives
- Split-horizon DNS, VPN transitions, service discovery, failover, hairpin NAT, and dual-stack names that publish a public A record with a unique-local AAAA record can legitimately produce public and private answers for the same name. Recursive resolvers, DNS forwarders, and localhost listeners can also aggregate many endpoints under one client address. Security products may sinkhole suspicious domains to loopback or private addresses with short TTLs. Confirm the domain, resolver placement, and client identity before adding an exception, and scope exceptions by registered domain or client rather than globally.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
Rule Body
[metadata]
creation_date = "2026/08/20"
integration = ["network_traffic", "zeek"]
maturity = "production"
updated_date = "2026/08/25"
[rule]
author = ["Elastic"]
description = """
Identifies a client resolving the same public registered domain to both a public IP address and a private, loopback,
link-local, unique-local IPv6, or shared address. This includes both address classes being observed at the same
timestamp, and a public answer followed within five minutes by a private answer where the minimum TTL across all answer
records in the private-answer events is 60 seconds or less. Either pattern is consistent with DNS rebinding that pivots
browser or application trust to internal resources.
"""
false_positives = [
"""
Split-horizon DNS, VPN transitions, service discovery, failover, hairpin NAT, and dual-stack names that publish a
public A record with a unique-local AAAA record can legitimately produce public and private answers for the same
name. Recursive resolvers, DNS forwarders, and localhost listeners can also aggregate many endpoints under one
client address. Security products may sinkhole suspicious domains to loopback or private addresses with short TTLs.
Confirm the domain, resolver placement, and client identity before adding an exception, and scope exceptions by
registered domain or client rather than globally.
""",
]
from = "now-15m"
language = "esql"
license = "Elastic License v2"
name = "Potential DNS Rebinding from Public to Private Address"
note = """## Triage and analysis
### Investigating Potential DNS Rebinding from Public to Private Address
DNS rebinding uses attacker-controlled public names that resolve to internal addresses so a victim browser or client
reaches RFC1918, loopback, link-local, unique-local IPv6, or shared-address targets. This rule alerts on two patterns
for the same client and fully qualified domain name: public and internal addresses whose first observations have the
same timestamp, or a public answer followed by an internal answer within five minutes. Sequential transitions also
require the minimum TTL across all DNS answer records in the private-answer events to be 60 seconds or less. Equal
timestamps often represent a mixed-answer response, but do not prove that the addresses came from one DNS transaction;
parallel A and AAAA events can share a timestamp. Equal-timestamp matches do not require the TTL or five-minute gates.
`Esql.client_ip` is `client.ip` when present and otherwise `source.ip`. Depending on sensor placement this value may
identify an endpoint, a recursive resolver, a forwarder, or a localhost DNS listener such as `127.0.0.1`. Resolver or
loopback identities can merge many hosts into one bucket.
### Possible investigation steps
- Review `dns.question.name`, `dns.question.registered_domain`, `Esql.public_ips`, and `Esql.private_ips` to confirm the
same name resolved to both a public and an internal address.
- Check `Esql.same_timestamp`. A value of `true` means both address classes were first observed at the same timestamp,
but does not establish that they came from one DNS transaction. Compare `Esql.first_public_answer`,
`Esql.first_private_answer`, `Esql.transition_seconds`, and `Esql.min_private_event_ttl` for sequential transitions.
Short transitions and TTL values near zero increase confidence.
- Use `Esql.resolved_ip_observation_count`, `Esql.resolved_ip_count`, `Esql.dataset_values`, and
`Esql.observer_name_values` to assess observation volume, distinct IP cardinality, and the integrations and sensors
that contributed to the alert.
- Identify the requesting client using `Esql.client_ip`. Confirm whether that address is an endpoint rather than a
recursive resolver, forwarder, or localhost DNS service before attributing the activity to one host.
- Determine whether the registered domain is attacker-controlled or a legitimate split-horizon or failover domain.
- Check the requesting host for browser or application connections to the resolved private address immediately after
the private answer.
- Review the targeted internal service for requests carrying the public domain in the HTTP Host header or TLS SNI and
for unauthorized access, state changes, or sensitive-data retrieval.
### False positive analysis
- Split-horizon DNS, VPN transitions, service discovery, failover, and hairpin NAT can legitimately cause a public
registered domain to alternate between public and private answers. Confirm the domain and resolver behavior with DNS
administrators.
- Dual-stack names may publish a public IPv4 address and a unique-local IPv6 address under the same question name.
- Security products may intentionally sinkhole suspicious domains to loopback or private addresses with short TTLs.
- Exclude confirmed internal domains, approved sinkholes, and controlled security-testing infrastructure by registered
domain or client only after validation. Do not exclude a resolver address until the originating endpoint is known.
### Response and remediation
- Block or sinkhole the queried name at recursive resolvers if it is confirmed malicious.
- Patch or isolate affected internal services reached through the rebound name.
- Restrict outbound DNS for clients that should not resolve arbitrary external names directly.
"""
references = ["https://owasp.org/www-community/attacks/DNS_Rebinding", "https://portswigger.net/web-security/ssrf"]
risk_score = 47
rule_id = "c485ceb7-b0e3-4540-9e8c-e9c655406e68"
setup = """## Setup
This rule requires DNS transaction events from one of the following passive network integrations:
- Elastic Network Packet Capture (`network_traffic.dns`) in `logs-network_traffic.dns-*`
- Zeek (`zeek.dns`) in `logs-zeek.dns-*`
- Legacy Packetbeat DNS events in `packetbeat-*`
Enable DNS logging so that `dns.question.registered_domain` and `dns.resolved_ip` are populated. Populate
`dns.answers.ttl` to detect sequential public-to-private transitions; equal-timestamp matches do not require TTL data.
Place the sensor where it observes endpoint-to-resolver DNS traffic. If the sensor is upstream of a recursive resolver,
or if the captured client is a localhost listener such as `127.0.0.1`, `Esql.client_ip` may identify shared DNS
infrastructure instead of the originating endpoint and can merge answers from many hosts.
DNS-over-HTTPS (DoH), DNS-over-TLS (DoT), and other encrypted DNS traffic are not visible to packet capture unless the
sensor receives decrypted DNS telemetry or equivalent resolver logs mapped to ECS.
"""
severity = "medium"
tags = [
"Domain: Network",
"Use Case: Threat Detection",
"Use Case: Network Security Monitoring",
"Tactic: Initial Access",
"Rule Type: ESQL",
"Data Source: Network Packet Capture",
"Data Source: Network Traffic",
"Data Source: Zeek",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-network_traffic.dns-*, logs-zeek.dns-*, packetbeat-*
| where
(
data_stream.dataset in ("network_traffic.dns", "zeek.dns") or
event.dataset == "dns"
) and
dns.question.name is not null and
dns.question.registered_domain is not null and
dns.resolved_ip is not null and
TO_UPPER(dns.response_code) == "NOERROR" and
TO_UPPER(dns.question.type) in ("A", "AAAA")
| eval
Esql.client_ip = COALESCE(client.ip, source.ip),
Esql.dataset = COALESCE(data_stream.dataset, event.dataset)
| where Esql.client_ip is not null
| mv_expand dns.resolved_ip
| eval Esql.is_private = CIDR_MATCH(
dns.resolved_ip,
"0.0.0.0/32",
"10.0.0.0/8",
"100.64.0.0/10",
"127.0.0.0/8",
"169.254.0.0/16",
"172.16.0.0/12",
"192.168.0.0/16",
"::1/128",
"fc00::/7",
"fe80::/10"
)
| eval
Esql.private_time = CASE(Esql.is_private, @timestamp, null),
Esql.public_time = CASE(not Esql.is_private, @timestamp, null),
Esql.private_event_ttl = CASE(Esql.is_private, MV_MIN(dns.answers.ttl), null),
Esql.private_ip = CASE(Esql.is_private, dns.resolved_ip, null),
Esql.public_ip = CASE(not Esql.is_private, dns.resolved_ip, null)
| stats
Esql.resolved_ip_observation_count = COUNT(*),
Esql.resolved_ip_count = COUNT_DISTINCT(dns.resolved_ip),
Esql.first_public_answer = MIN(Esql.public_time),
Esql.first_private_answer = MIN(Esql.private_time),
Esql.min_private_event_ttl = MIN(Esql.private_event_ttl),
Esql.public_ips = MV_SLICE(VALUES(Esql.public_ip), 0, 100),
Esql.private_ips = MV_SLICE(VALUES(Esql.private_ip), 0, 100),
Esql.dataset_values = MV_SLICE(VALUES(Esql.dataset), 0, 10),
Esql.observer_name_values = MV_SLICE(VALUES(observer.name), 0, 20)
by Esql.client_ip, dns.question.name, dns.question.registered_domain
| eval
Esql.same_timestamp = Esql.first_public_answer == Esql.first_private_answer,
Esql.transition_seconds = DATE_DIFF("seconds", Esql.first_public_answer, Esql.first_private_answer)
| where
Esql.first_public_answer is not null and
Esql.first_private_answer is not null and
(
Esql.same_timestamp or
(
Esql.first_public_answer < Esql.first_private_answer and
Esql.min_private_event_ttl is not null and
Esql.min_private_event_ttl <= 60 and
Esql.transition_seconds <= 300
)
)
| keep Esql.*, dns.*
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1189"
name = "Drive-by Compromise"
reference = "https://attack.mitre.org/techniques/T1189/"
[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[rule.investigation_fields]
field_names = [
"Esql.client_ip",
"dns.question.name",
"dns.question.registered_domain",
"Esql.resolved_ip_observation_count",
"Esql.resolved_ip_count",
"Esql.first_public_answer",
"Esql.first_private_answer",
"Esql.transition_seconds",
"Esql.same_timestamp",
"Esql.min_private_event_ttl",
"Esql.public_ips",
"Esql.private_ips",
"Esql.dataset_values",
"Esql.observer_name_values",
]
Stages and Predicates
Stage 1: from
from logs-network_traffic.dns-*, logs-zeek.dns-*, packetbeat-*
Stage 2: where
| where
(
data_stream.dataset in ("network_traffic.dns", "zeek.dns") or
event.dataset == "dns"
) and
dns.question.name is not null and
dns.question.registered_domain is not null and
dns.resolved_ip is not null and
TO_UPPER(dns.response_code) == "NOERROR" and
TO_UPPER(dns.question.type) in ("A", "AAAA")
Stage 3: eval
| eval
Esql.client_ip = COALESCE(client.ip, source.ip),
Esql.dataset = COALESCE(data_stream.dataset, event.dataset)
Stage 4: where
| where Esql.client_ip is not null
Stage 5: mv_expand
| mv_expand dns.resolved_ip
Stage 6: eval
| eval Esql.is_private = CIDR_MATCH(
dns.resolved_ip,
"0.0.0.0/32",
"10.0.0.0/8",
"100.64.0.0/10",
"127.0.0.0/8",
"169.254.0.0/16",
"172.16.0.0/12",
"192.168.0.0/16",
"::1/128",
"fc00::/7",
"fe80::/10"
)
Stage 7: eval
| eval
Esql.private_time = CASE(Esql.is_private, @timestamp, null),
Esql.public_time = CASE(not Esql.is_private, @timestamp, null),
Esql.private_event_ttl = CASE(Esql.is_private, MV_MIN(dns.answers.ttl), null),
Esql.private_ip = CASE(Esql.is_private, dns.resolved_ip, null),
Esql.public_ip = CASE(not Esql.is_private, dns.resolved_ip, null)
Esql.private_event_ttl =Esql.is_privateMV_MIN(dns.answers.ttl)nullEsql.private_ip =Esql.is_privatedns.resolved_ipnullEsql.private_time =Esql.is_private@timestampnullEsql.public_ip =not Esql.is_privatedns.resolved_ipnullEsql.public_time =not Esql.is_private@timestampnullStage 8: stats
| stats
Esql.resolved_ip_observation_count = COUNT(*),
Esql.resolved_ip_count = COUNT_DISTINCT(dns.resolved_ip),
Esql.first_public_answer = MIN(Esql.public_time),
Esql.first_private_answer = MIN(Esql.private_time),
Esql.min_private_event_ttl = MIN(Esql.private_event_ttl),
Esql.public_ips = MV_SLICE(VALUES(Esql.public_ip), 0, 100),
Esql.private_ips = MV_SLICE(VALUES(Esql.private_ip), 0, 100),
Esql.dataset_values = MV_SLICE(VALUES(Esql.dataset), 0, 10),
Esql.observer_name_values = MV_SLICE(VALUES(observer.name), 0, 20)
by Esql.client_ip, dns.question.name, dns.question.registered_domain
Stage 9: eval
| eval
Esql.same_timestamp = Esql.first_public_answer == Esql.first_private_answer,
Esql.transition_seconds = DATE_DIFF("seconds", Esql.first_public_answer, Esql.first_private_answer)
Stage 10: where
| where
Esql.first_public_answer is not null and
Esql.first_private_answer is not null and
(
Esql.same_timestamp or
(
Esql.first_public_answer < Esql.first_private_answer and
Esql.min_private_event_ttl is not null and
Esql.min_private_event_ttl <= 60 and
Esql.transition_seconds <= 300
)
)
Stage 11: keep
| keep Esql.*, dns.*
Indicators
These rows show field, operator, and value matches.
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Esql.* | KEEP Esql.* |
dns.* | KEEP dns.* |
Potential Proxy Execution via Systemd-run
#This rule detects the execution of a command or binary through the systemd-run binary. Systemd-run can schedule commands to be executed in the background through systemd. Attackers may use this technique to execute commands while attempting to evade detection.
MITRE ATT&CK Coverage
Rule Body
[metadata]
creation_date = "2026/07/02"
integration = ["endpoint", "auditd_manager", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/07/06"
[rule]
author = ["Elastic"]
description = """
This rule detects the execution of a command or binary through the systemd-run binary. Systemd-run can schedule commands
to be executed in the background through systemd. Attackers may use this technique to execute commands while attempting
to evade detection.
"""
from = "now-9m"
index = [
"auditbeat-*",
"endgame-*",
"logs-auditd_manager.auditd-*",
"logs-endpoint.events.process*",
"logs-sentinel_one_cloud_funnel.*",
"logs-crowdstrike.fdr*",
]
language = "eql"
license = "Elastic License v2"
name = "Potential Proxy Execution via Systemd-run"
note = """ ## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Potential Proxy Execution via Systemd-run
This alert fires when a Linux process launches another command through systemd-run instead of executing it directly, which can hide execution behind a trusted system utility and detach it into a transient service or scope. An attacker might use systemd-run --user or a transient unit to start a shell, downloader, or credential-harvesting script in the background from an interactive session, reducing visibility into the real payload and parent-child chain.
### Possible investigation steps
- Reconstruct the full process tree around the event to determine which user, shell, script, service, or remote access session invoked systemd-run and whether the ancestry aligns with normal administrative or automation activity on that host.
- Review the exact command passed through systemd-run, including flags such as --user, --scope, scheduling options, or custom unit names, and classify the spawned payload as expected software management, benign interactive use, or suspicious shell, downloader, or persistence behavior.
- Query systemd and journal artifacts for the transient unit that was created, including unit properties, start time, execution account, service output, and whether the unit remained active, failed, or was configured to run again.
- Correlate the execution with nearby events from the same user or host such as logins, sudo activity, file creation in writable locations, outbound network connections, or follow-on launches of interpreters and admin tools to identify a broader intrusion sequence.
- If the activity is unauthorized or unclear, inspect the referenced binary or script for path reputation, package ownership, hash prevalence, and recent modification history, then stop the transient unit and contain any files or persistence it introduced.
### False positive analysis
- A legitimate administrator or maintenance script may use `systemd-run` to launch a transient unit for package updates, cache rebuilds, or controlled service restarts, so verify the initiating user, the parent script or shell history, and nearby package-management or scheduled change activity.
- A normal desktop or user session can invoke `systemd-run --user` or `--scope` to start an application, terminal, or session task in a transient scope, so confirm the parent process belongs to the logged-in user’s graphical session and that the spawned command matches expected interactive activity in systemd or journal logs.
### Response and remediation
- Isolate the affected Linux host from the network except for approved management channels, terminate the malicious `systemd-run` transient unit or scope, and kill any child shell, downloader, or script it launched.
- Remove attacker persistence by deleting unauthorized unit files and drop-ins from `/etc/systemd/system/`, `/run/systemd/transient/`, `/var/lib/systemd/`, and affected users’ `~/.config/systemd/user/` directories, then run `systemctl daemon-reload` and disable any malicious timers or services.
- Preserve and quarantine the executed payload, related scripts, and any files created from writable locations such as `/tmp`, `/var/tmp`, `/dev/shm`, or a user home directory, and revoke exposed access by resetting compromised passwords, SSH keys, tokens, and sudo access tied to the initiating account.
- Restore the system to a known-good state by reimaging or rebuilding the host from a trusted baseline if the command ran as `root`, modified security tooling, or executed an unknown binary, and validate that only approved packages, services, and startup entries remain before returning it to production.
- Escalate to incident response immediately if the `systemd-run` activity spawned a reverse shell, downloader, credential access tool, or lateral movement utility, if similar transient units appear on multiple hosts, or if the affected account has privileged or production access.
- Harden the environment by restricting who can invoke `systemd-run` through sudoers and privileged group membership, enforcing MFA and least privilege for administrative access, monitoring for new transient units and unexpected `--user` executions, and blocking execution from world-writable paths where the payload was staged.
"""
risk_score = 21
rule_id = "a2e5e290-f534-4b71-bc3f-2dd1932b4cd6"
setup = """## Setup
This rule requires data coming in from one of the following integrations:
- Elastic Defend
- Auditbeat
- Auditd Manager
- CrowdStrike
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "low"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Defense Evasion",
"Tactic: Execution",
"Data Source: Elastic Endgame",
"Data Source: Elastic Defend",
"Data Source: Auditd Manager",
"Data Source: SentinelOne",
"Data Source: Crowdstrike",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "linux" and event.type == "start" and
event.action in ("exec", "exec_event", "executed", "process_started", "start", "ProcessRollup2") and
process.name == "systemd-run" and ?process.parent.executable != null and
not (
?process.parent.executable in (
"/usr/lib/systemd", "/lib/systemd/systemd", "/opt/saltstack/salt/run/run", "/etc/update-motd.d/70-available-updates",
"/tmp/newroot/usr/libexec/ptyxis-agent", "/usr/local/sbin/clamscan.sh", "/opt/sentinelone/bin/sentinelone-agent",
"/usr/local/bin/salt-minion", "/var/vanta/launcher", "/opt/traps/bin/pmd", "/usr/sbin/gdm", "/usr/bin/salt-minion",
"/opt/GC_Ext/GC/gc_linux_service", "/usr/lib/plesk-task-manager", "/opt/forticlient/epctrl", "/usr/lib/snapd/snap-exec",
"/usr/bin/yay", "/usr/local/bin/hexnode_agent", "/opt/halcyon/halcyonar/agent", "/usr/local/bin/qsetup", "/usr/bin/pamac",
"/usr/bin/elephant", "/usr/bin/Hyprland"
) or
?process.parent.executable like (
"/opt/tableau/tableau_server/packages/scripts.*/after-install", "/opt/acronis/bin/acp-update-controller", "/snap/*",
"/var/lib/amagent/*", "/opt/msp-agent/msp-agent-core", "/opt/beyondtrust/*", "/var/lib/rancher/k3s/*/bin/k3s"
) or
?process.parent.name like "platform-python*" or
?process.parent.name in (
"udevadm", "daemon.start", "snap", "systemd", "ptyxis-agent", "run-slack", "run-firefox", "dbus.service", "k3s-server",
"systemd-udevd", "kubelet", "hyperkube", "kthreadd", "gnome-shell", "xdg-desktop-portal", "firefox", "picus_updater",
"rpm-ostree", "prompt-agent"
) or
?process.command_line in (
"/usr/bin/systemd-run /usr/bin/systemctl start man-db-cache-update", "systemd-run env",
"systemd-run --user dnf-automatic-notifyonly.timer", "systemd-run --user systemctl suspend", "systemd-run /var/lib/aws-replication-agent/uninstall-agent.sh",
"systemd-run --on-active=10 --timer-property=AccuracySec=100ms --slice=system.slice systemctl start gc-agent",
"systemd-run --user --scope --unit=tmux-server -- tmux", "systemd-run bash -c sleep 60 && reboot"
) or
?process.command_line like~ (
"systemd-run --scope -p CPUQuota=10% rpm -qa*", "systemd-run --scope -p CPUQuota=10% dpkg -l*"
) or
?process.parent.command_line in ("runc init", "/usr/local/bin/main") or
?process.parent.command_line like ("*/var/lib/waagent/*", "bash ./run.sh") or
process.args in (
"--help", "list-timers", "/usr/lib/udev/kdump-udev-throttler", "kubectl", "--unit=ngt_guest_agent_upgrade", "i3-zoom", "google-chrome",
"thunar", "/usr/bin/google-chrome-stable", "snap.lxd.workaround", "--unit=firefox", "--unit=slack", "--slice=zoom.slice",
"autorandr-launcher", "--unit=restart-dbus", "--unit=autorandr-debounce"
) or
process.args like ("--unit=app-Hyprland-wezterm-*.scope", "--unit=app-Hyprland-swaybg-*.scope", "--unit=rmf_sim_*") or
?process.working_directory == "/opt/Tychon/Endpoint/bin" or
(process.args in ("rpm", "dpkg") and process.args like~ "CPUQuota=*") or
(process.args == "--slice=app-graphical.slice" and process.args == "--description=xdg-terminal-exec")
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[rule.threat.tactic]
name = "Defense Evasion"
id = "TA0005"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[rule.threat.technique]]
id = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"
[[rule.threat.technique]]
name = "Hijack Execution Flow"
id = "T1574"
reference = "https://attack.mitre.org/techniques/T1574/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[rule.threat.tactic]
name = "Execution"
id = "TA0002"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
name = "Unix Shell"
id = "T1059.004"
reference = "https://attack.mitre.org/techniques/T1059/004/"
Stages and Predicates
Stage 1: process
process where host.os.type == "linux" and event.type == "start" and
event.action in ("exec", "exec_event", "executed", "process_started", "start", "ProcessRollup2") and
process.name == "systemd-run" and ?process.parent.executable != null and
not (
?process.parent.executable in (
"/usr/lib/systemd", "/lib/systemd/systemd", "/opt/saltstack/salt/run/run", "/etc/update-motd.d/70-available-updates",
"/tmp/newroot/usr/libexec/ptyxis-agent", "/usr/local/sbin/clamscan.sh", "/opt/sentinelone/bin/sentinelone-agent",
"/usr/local/bin/salt-minion", "/var/vanta/launcher", "/opt/traps/bin/pmd", "/usr/sbin/gdm", "/usr/bin/salt-minion",
"/opt/GC_Ext/GC/gc_linux_service", "/usr/lib/plesk-task-manager", "/opt/forticlient/epctrl", "/usr/lib/snapd/snap-exec",
"/usr/bin/yay", "/usr/local/bin/hexnode_agent", "/opt/halcyon/halcyonar/agent", "/usr/local/bin/qsetup", "/usr/bin/pamac",
"/usr/bin/elephant", "/usr/bin/Hyprland"
) or
?process.parent.executable like (
"/opt/tableau/tableau_server/packages/scripts.*/after-install", "/opt/acronis/bin/acp-update-controller", "/snap/*",
"/var/lib/amagent/*", "/opt/msp-agent/msp-agent-core", "/opt/beyondtrust/*", "/var/lib/rancher/k3s/*/bin/k3s"
) or
?process.parent.name like "platform-python*" or
?process.parent.name in (
"udevadm", "daemon.start", "snap", "systemd", "ptyxis-agent", "run-slack", "run-firefox", "dbus.service", "k3s-server",
"systemd-udevd", "kubelet", "hyperkube", "kthreadd", "gnome-shell", "xdg-desktop-portal", "firefox", "picus_updater",
"rpm-ostree", "prompt-agent"
) or
?process.command_line in (
"/usr/bin/systemd-run /usr/bin/systemctl start man-db-cache-update", "systemd-run env",
"systemd-run --user dnf-automatic-notifyonly.timer", "systemd-run --user systemctl suspend", "systemd-run /var/lib/aws-replication-agent/uninstall-agent.sh",
"systemd-run --on-active=10 --timer-property=AccuracySec=100ms --slice=system.slice systemctl start gc-agent",
"systemd-run --user --scope --unit=tmux-server -- tmux", "systemd-run bash -c sleep 60 && reboot"
) or
?process.command_line like~ (
"systemd-run --scope -p CPUQuota=10% rpm -qa*", "systemd-run --scope -p CPUQuota=10% dpkg -l*"
) or
?process.parent.command_line in ("runc init", "/usr/local/bin/main") or
?process.parent.command_line like ("*/var/lib/waagent/*", "bash ./run.sh") or
process.args in (
"--help", "list-timers", "/usr/lib/udev/kdump-udev-throttler", "kubectl", "--unit=ngt_guest_agent_upgrade", "i3-zoom", "google-chrome",
"thunar", "/usr/bin/google-chrome-stable", "snap.lxd.workaround", "--unit=firefox", "--unit=slack", "--slice=zoom.slice",
"autorandr-launcher", "--unit=restart-dbus", "--unit=autorandr-debounce"
) or
process.args like ("--unit=app-Hyprland-wezterm-*.scope", "--unit=app-Hyprland-swaybg-*.scope", "--unit=rmf_sim_*") or
?process.working_directory == "/opt/Tychon/Endpoint/bin" or
(process.args in ("rpm", "dpkg") and process.args like~ "CPUQuota=*") or
(process.args == "--slice=app-graphical.slice" and process.args == "--description=xdg-terminal-exec")
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | in |
| field:"EventType" kind:in |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.name | eq |
| field:"process_basename" kind:eq value:"systemd-run" |
process.parent.executable | is_not_null | field:"ParentImage" kind:is_not_null |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | eq | --description=xdg-terminal-exec | excludes:process.args field:"process.args" value:"--description=xdg-terminal-exec" |
process.args | eq | --slice=app-graphical.slice | excludes:process.args field:"process.args" value:"--slice=app-graphical.slice" |
process.args | in | dpkg, rpm | excludes:process.args field:"process.args" value:"dpkg" field:"process.args" value:"rpm" |
process.args | starts_with | CPUQuota= | excludes:process.args field:"process.args" value:"CPUQuota=" |
process.args | in | --help, --slice=zoom.slice, --unit=autorandr-debounce, --unit=firefox, --unit=ngt_guest_agent_upgrade, --unit=restart-dbus, --unit=slack, /usr/bin/google-chrome-stable, /usr/lib/udev/kdump-udev-throttler, autorandr-launcher, google-chrome, i3-zoom, kubectl, list-timers, snap.lxd.workaround, thunar | excludes:process.args |
process.args | wildcard | --unit=app-Hyprland-wezterm-*.scope, --unit=app-Hyprland-swaybg-*.scope, --unit=rmf_sim_* | excludes:process.args field:"process.args" value:"--unit=app-Hyprland-wezterm-*.scope" field:"process.args" value:"--unit=app-Hyprland-swaybg-*.scope" field:"process.args" value:"--unit=rmf_sim_*" |
process.command_line | in | /usr/bin/systemd-run /usr/bin/systemctl start man-db-cache-update, systemd-run --on-active=10 --timer-property=AccuracySec=100ms --slice=system.slice systemctl start gc-agent, systemd-run --user --scope --unit=tmux-server -- tmux, systemd-run --user dnf-automatic-notifyonly.timer, systemd-run --user systemctl suspend, systemd-run /var/lib/aws-replication-agent/uninstall-agent.sh, systemd-run bash -c sleep 60 && reboot, systemd-run env | excludes:process.command_line |
process.command_line | starts_with | systemd-run --scope -p CPUQuota=10% rpm -qa, systemd-run --scope -p CPUQuota=10% dpkg -l | excludes:process.command_line field:"process.command_line" value:"systemd-run --scope -p CPUQuota=10% rpm -qa" field:"process.command_line" value:"systemd-run --scope -p CPUQuota=10% dpkg -l" |
process.parent.command_line | in | /usr/local/bin/main, runc init | excludes:process.parent.command_line field:"process.parent.command_line" value:"/usr/local/bin/main" field:"process.parent.command_line" value:"runc init" |
process.parent.command_line | wildcard | */var/lib/waagent/*, bash ./run.sh | excludes:process.parent.command_line field:"process.parent.command_line" value:"*/var/lib/waagent/*" field:"process.parent.command_line" value:"bash ./run.sh" |
process.parent.executable | in | /etc/update-motd.d/70-available-updates, /lib/systemd/systemd, /opt/GC_Ext/GC/gc_linux_service, /opt/forticlient/epctrl, /opt/halcyon/halcyonar/agent, /opt/saltstack/salt/run/run, /opt/sentinelone/bin/sentinelone-agent, /opt/traps/bin/pmd, /tmp/newroot/usr/libexec/ptyxis-agent, /usr/bin/Hyprland, /usr/bin/elephant, /usr/bin/pamac, /usr/bin/salt-minion, /usr/bin/yay, /usr/lib/plesk-task-manager, /usr/lib/snapd/snap-exec, /usr/lib/systemd, /usr/local/bin/hexnode_agent, /usr/local/bin/qsetup, /usr/local/bin/salt-minion, /usr/local/sbin/clamscan.sh, /usr/sbin/gdm, /var/vanta/launcher | excludes:process.parent.executable |
process.parent.executable | wildcard | /opt/tableau/tableau_server/packages/scripts.*/after-install, /opt/acronis/bin/acp-update-controller, /snap/*, /var/lib/amagent/*, /opt/msp-agent/msp-agent-core, /opt/beyondtrust/*, /var/lib/rancher/k3s/*/bin/k3s | excludes:process.parent.executable |
process.parent.name | in | daemon.start, dbus.service, firefox, gnome-shell, hyperkube, k3s-server, kthreadd, kubelet, picus_updater, prompt-agent, ptyxis-agent, rpm-ostree, run-firefox, run-slack, snap, systemd, systemd-udevd, udevadm, xdg-desktop-portal | excludes:process.parent.name |
process.parent.name | starts_with | platform-python | excludes:process.parent.name field:"process.parent.name" value:"platform-python" |
process.working_directory | eq | /opt/Tychon/Endpoint/bin | excludes:process.working_directory field:"process.working_directory" value:"/opt/Tychon/Endpoint/bin" |
Potential Suspended Process Code Injection
#Identifies attemtps to write to the address space of a remote process that was started in a suspended state and by an unsigned or untrusted final user module. This behavior is consistent with remote code injection attacks.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule Body
[rule]
description = """
Identifies attemtps to write to the address space of a remote process that was started in a suspended state and by an
unsigned or untrusted final user module. This behavior is consistent with remote code injection attacks.
"""
id = "47167118-ba42-48e8-8555-dd50d98d21c4"
license = "Elastic License v2"
name = "Potential Suspended Process Code Injection"
os_list = ["windows"]
version = "1.0.17"
query = '''
api where process.Ext.api.name == "WriteProcessMemory" and
process.Ext.api.parameters.size >= 4000 and
/* target process created suspended */
Target.process.Ext.created_suspended == true and process.Ext.api.behaviors == "cross-process" and
/* WPM triggers multiple times at process creation */
not _arraysearch(process.thread.Ext.call_stack, $entry,
$entry.symbol_info like ("*\\kernelbase.dll!CreateProcess*", "*\\kernelbase.dll+0x*", "c:\\windows\\*\\advapi32.dll!CreateProcessAsUser*", "*\\kernel32.dll!CreateProcess*")) and
not (process.Ext.api.summary like ("*PEB*", "*PEB32*", "*ProcessStartupInfo*") and process.thread.Ext.call_stack_summary like "*Unknown*") and
/* unsigned or untrusted code signature */
_arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature, $entry, $entry.trusted == false or $entry.exists == false) and
/* excluding multiple unsigned third party modules from programfiles */
not process.thread.Ext.call_stack_final_user_module.path like
("?:\\windows\\assembly\\nativeimages_*.dll",
"?:\\program files\\*",
"?:\\program files (x86)\\*",
"c:\\windows\\apppatch\\ummon.dll",
"c:\\windows\\apppatch\\apppatch64\\ummon.dll",
"c:\\windows\\system32\\ctiuser.dll",
"c:\\windows\\syswow64\\ctiuser.dll",
"c:\\windows\\system32\\lsasrv.dll") and
not process.thread.Ext.call_stack_final_user_module.protection_provenance == "mfehcthe.dll" and
/* once 8.15.0 schemas are added remove mfehcthe.dll exclusion and add the following line */
/* add the following exclusion */
/* not process.thread.Ext.call_stack_final_user_module.protection_provenance_path like ("?:\\program files\\*", "?:\\program files (x86)\\*") and */
not process.thread.Ext.call_stack_final_user_module.name in ("Unknown", "Undetermined", "Kernel") and
/* bash and gbp */
not (process.Ext.api.metadata.target_address_name like ("Data", "msys-*", "cyg*.dll") and
process.thread.Ext.call_stack_summary like
("ntdll.dll|kernelbase.dll|msys-?.?.dll|*Unknown",
"ntdll.dll|kernelbase.dll|cygwin?.dll|*Unknown",
"ntdll.dll|kernelbase.dll|cygwin?.dll|bash.exe",
"ntdll.dll|kernelbase.dll|cygwin?.dll",
"ntdll.dll|kernelbase.dll|msys-?.0.dll")) and
not process.thread.Ext.call_stack_final_user_module.hash.sha256 in
("27fe00d32f773a95e6d50986e5e7499917f66ce881e46054c77652ef4bdf3512",
"a59e039e1520b74254a454bf48c2bceeafe7bd7ac6e5886baa482a52f86a29bf",
"f01bb9aba3f9daf4d8f5551a3b753d8011e16072a1103cf5303d617a9f866424",
"16184cf6f54d6ac4eb0a31c0e9ee8ae775bae6dfdc632e283e832f3e89de595d",
"c983d11ad519a851aca2d37739110b7913819bea1ddf2cc3ec69efe3ed3b609f",
"c3cd2439a6175ce28192904e72b14523b02559d8083a710b5e82aee400626d1a",
"7396f943823494d2ec5f2260329daa2d35b1764f01cdefd95f84ae320986a8f3",
"efd03f2525e69cdc30b5736af74d9485728b8a94d5624da87f1431b3706980ab",
"8eb0721092af3131a940f1e23bc2871e09362980e0b71a7ed7dab6e8accd1f30",
"6edb20df25d1cf0fd1b27052f2604a05db1d7ca5a3f074e7bacc229e28d17667",
"67435999749d9e6908a4029321c0c6f9e915135e98e01a7e499a1c55a960bc68",
"914299dd77f4322c99f62c37df1317ea3424d9a747d4635d10c1d3f003f6abd4",
"51b63860fd996d6d5b1753ba6bb7f3a4303f13187fbfecc96ba2b6bae52a7410",
"0255b5bf7ad66aa090be145f0ad41a0f4e33409ff5c2970081fccd863c720779",
"925a5cd982933bae1b271e1aaaa887ab469397701cd299f4397ddd8af5a351f9",
"9cb1208f1747963dc57e8bf8a8fe82b3aaa856caae3d151b6a6b97b23369f5a6",
"681303f5b5688075b5b504819d8b3c343c78e3240a3bccf371e03228970ffb10",
"30b59303bec45b020b4878b2d33d63bd719d89820456a7ee0a920178efe089f4",
"8ee5bd6fea98577bd29c15055e96ec17c62ca415f4a5d26065b25a922b19d3b1",
"57854d83b50ff0a23d47c077d6da875874ea78f88f28168d8e99ffbf9f1c3153",
"c4788275a5ed2c1576e69b59e6e267ce573450ff07e54b799ec4c4edef40b502",
"a4637935f895de601850c6868d952977a84076a7b1719d0deb519f1fc0871be4",
"a99ac2554c1e392ffe3cd53f7f72f76638948533795fc04f7e15454c386b7eec",
"b031da6137f9442a6cc9f4b4546b4057b666726cb7c9224c4ca857a60f2ec1e1",
"586d8eeaec3a439978836a512bf2f5a987cbe2ba72e5bb10322d04cd65fe8d09",
"ebdc2c2cedd5e549ba8d5e3f474d29204e1cf073e2b26e75f60bb429d2b5a088",
"80eb757f729a943ff0919df1eb980b80f8419f76648407834d95c76adfd21624",
"e71eb30f24c82bc4fa1c645eecbe343f5a44526043fc3a13047183dac5f212f3",
"c46f9f3c710ff2baabea480670220e0328e7bcc2aa3c598c3f982728e0b5652d",
"7f1ab7572a89534366172df3ae5f0182aab1ae3ef992b684a84c5c1a10e8315f",
"d7624e57820ccd1bae7881e08af40bc3522971278018fdfbe0ca98302292165c",
"e0f11ad44d1c1e11f9308f9aaee4d8bcac86ff6e0b4a41d1e75879f6cfd56049",
"2266a567ba921d1c2661258cd5b31150274cb781ac01413c34a471557123ba65",
"1f2e936a57994e16b457f249a64af4786877f7beaab003fb521a20e45031f408",
"e8eaf74988082b8c8222dabed68218069c8eb4e93acd3619a776bc28d39e5ce5",
"39fdb47a5f349e06bbb7dc1cedcc81a051d1dffe373956871325f8327e858afa",
"f7af5eac1d34a2ddc619dd0c3172ec28334b8d79efc1f8ad758124b7e5aae0d5",
"8f3d19065d0d1295bbfbf7591aa02af3a5dc70fde74bac670c18ccd8f7306008",
"d6b771bedda261bcfe9dd1d1402b7d33b5cd2764cd53d941957e32920cfbeb19",
"3e02857de5a59331e1f7fc7e1ddf5ae58e8680d298bb44b49bd316e0b3a1f024",
"954b4385cf4faecfbf9cd04e01c059eb09113a78ee727149b63a65b495a28a6c",
"8851b734602eb00da5b1cfc1e40d38f1cb32e0add2df257ff9d7dbd520b4d5da",
"b2d86212afab00e7b9bf19b7931277130b653c9258ac419a7a24d749471ea5ac",
"5231df995d71991ee4108937bb12e4d3f344a96fb0c4cd82c14e18061d6c4730",
"4daef5be9503c580697b36b0b60a702c109e23840c0632ca00ef4a233603018e",
"fd788a077e026905f1565e0d2a65dfc6c55699c098a59879d6b0b3f3b8459ae8",
"dc641636d5d782b31d29ce823e951d1a2164c86ee06bf2f65a841360fb7af356",
"fb4a05ce7d50721c71f66c37e0ab7e52cd46034a2e394940b3f60c9c2afb079a",
"862a7e8c68f05b91ecf3a43ac5b60c6f57ee50fa98ad1b539480d541628f5c2e",
"44c87532cbb511c369b38a105fc5a84b1d89dba9dfdd5a62c311d6176fe93201",
"73395b6c3fa9fa73e8e3665f108b3a92c564da9c1b9ce7834832adbb5e658a87",
"862b75fd4ebed41378d3af00784ef9bde4362e27d6f2aee384b99286f6beb0bd",
"7214d926419fe847a4795a74f9b73209990e4927bb5b56128cf30703be68cde7",
"96dca741745683eb5c2ad857e2520ccf62ab2d08eae359f6928495073925faee",
"8c1ae6ac63865e603e04a3a4f0ab0178e6422615a42e011bfd8453fc78f1fd58",
"ab7ba2df709c5ff7ee16a1038deaf1d795977b035a1ba08cc6d32ea9ff87bd80",
"1bbd271d777f59f1233e4124991dae126ba183ffca404e74084d29dc46b65b38",
"929365d4c30b1cb3f8458d3b1bd48536260942ef9e3cab33286a1540088105e4",
"34b9970af6ce3fb7e81ad42fcaf852d9d7e341a624f988409a36323329222751",
"ec5aa260268e7c596adc7be56792af587da44bd897ce4f38f616ebc3d2f22a88",
"e0e4fd3650aa15f92aad1d1e7567f2447f03e9c009ae4ee955afb980ec991912",
"379952ec8113b3692872ffb9d07c242968ee1edfac9b3b888496c1480033be91",
"802de2c196b779f0c10827bc37186a4d1db3e46841d27682865c6dbaf28bba46",
"2813d00f34d60d17b5b192acd3450720966fa103fb0669c3f69c36c67204a66b",
"bf740678008401deeb4b017d0641fb32f5747dfca9be0b8c5228366814ee7f67",
"e1e8dac7bb356121152e7d0315659c4340cacab2a46d32a736c1ad254c9274ea",
"8532f5aa7eb3d492ffac5416ed618be439136e9a1c9d0514417e26a6ab9d311f",
"bee38a315667379528705aaa3edb3899cbfaaaea8e19db3214d3735d00240e71",
"c8f04efd583ac2649db79902e680d8476939a0663b1e8b076e391303fef074c9")
'''
min_endpoint_version = "8.14.0"
[[actions]]
action = "kill_process"
field = "Target.process.entity_id"
state = 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.14.0"
Stages and Predicates
Stage 1: api
api where process.Ext.api.name == "WriteProcessMemory" and
process.Ext.api.parameters.size >= 4000 and
Target.process.Ext.created_suspended == true and process.Ext.api.behaviors == "cross-process" and
not _arraysearch(process.thread.Ext.call_stack, $entry,
$entry.symbol_info like ("*\\kernelbase.dll!CreateProcess*", "*\\kernelbase.dll+0x*", "c:\\windows\\*\\advapi32.dll!CreateProcessAsUser*", "*\\kernel32.dll!CreateProcess*")) and
not (process.Ext.api.summary like ("*PEB*", "*PEB32*", "*ProcessStartupInfo*") and process.thread.Ext.call_stack_summary like "*Unknown*") and
_arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature, $entry, $entry.trusted == false or $entry.exists == false) and
not process.thread.Ext.call_stack_final_user_module.path like
("?:\\windows\\assembly\\nativeimages_*.dll",
"?:\\program files\\*",
"?:\\program files (x86)\\*",
"c:\\windows\\apppatch\\ummon.dll",
"c:\\windows\\apppatch\\apppatch64\\ummon.dll",
"c:\\windows\\system32\\ctiuser.dll",
"c:\\windows\\syswow64\\ctiuser.dll",
"c:\\windows\\system32\\lsasrv.dll") and
not process.thread.Ext.call_stack_final_user_module.protection_provenance == "mfehcthe.dll" and
not process.thread.Ext.call_stack_final_user_module.name in ("Unknown", "Undetermined", "Kernel") and
not (process.Ext.api.metadata.target_address_name like ("Data", "msys-*", "cyg*.dll") and
process.thread.Ext.call_stack_summary like
("ntdll.dll|kernelbase.dll|msys-?.?.dll|*Unknown",
"ntdll.dll|kernelbase.dll|cygwin?.dll|*Unknown",
"ntdll.dll|kernelbase.dll|cygwin?.dll|bash.exe",
"ntdll.dll|kernelbase.dll|cygwin?.dll",
"ntdll.dll|kernelbase.dll|msys-?.0.dll")) and
not process.thread.Ext.call_stack_final_user_module.hash.sha256 in
("27fe00d32f773a95e6d50986e5e7499917f66ce881e46054c77652ef4bdf3512",
"a59e039e1520b74254a454bf48c2bceeafe7bd7ac6e5886baa482a52f86a29bf",
"f01bb9aba3f9daf4d8f5551a3b753d8011e16072a1103cf5303d617a9f866424",
"16184cf6f54d6ac4eb0a31c0e9ee8ae775bae6dfdc632e283e832f3e89de595d",
"c983d11ad519a851aca2d37739110b7913819bea1ddf2cc3ec69efe3ed3b609f",
"c3cd2439a6175ce28192904e72b14523b02559d8083a710b5e82aee400626d1a",
"7396f943823494d2ec5f2260329daa2d35b1764f01cdefd95f84ae320986a8f3",
"efd03f2525e69cdc30b5736af74d9485728b8a94d5624da87f1431b3706980ab",
"8eb0721092af3131a940f1e23bc2871e09362980e0b71a7ed7dab6e8accd1f30",
"6edb20df25d1cf0fd1b27052f2604a05db1d7ca5a3f074e7bacc229e28d17667",
"67435999749d9e6908a4029321c0c6f9e915135e98e01a7e499a1c55a960bc68",
"914299dd77f4322c99f62c37df1317ea3424d9a747d4635d10c1d3f003f6abd4",
"51b63860fd996d6d5b1753ba6bb7f3a4303f13187fbfecc96ba2b6bae52a7410",
"0255b5bf7ad66aa090be145f0ad41a0f4e33409ff5c2970081fccd863c720779",
"925a5cd982933bae1b271e1aaaa887ab469397701cd299f4397ddd8af5a351f9",
"9cb1208f1747963dc57e8bf8a8fe82b3aaa856caae3d151b6a6b97b23369f5a6",
"681303f5b5688075b5b504819d8b3c343c78e3240a3bccf371e03228970ffb10",
"30b59303bec45b020b4878b2d33d63bd719d89820456a7ee0a920178efe089f4",
"8ee5bd6fea98577bd29c15055e96ec17c62ca415f4a5d26065b25a922b19d3b1",
"57854d83b50ff0a23d47c077d6da875874ea78f88f28168d8e99ffbf9f1c3153",
"c4788275a5ed2c1576e69b59e6e267ce573450ff07e54b799ec4c4edef40b502",
"a4637935f895de601850c6868d952977a84076a7b1719d0deb519f1fc0871be4",
"a99ac2554c1e392ffe3cd53f7f72f76638948533795fc04f7e15454c386b7eec",
"b031da6137f9442a6cc9f4b4546b4057b666726cb7c9224c4ca857a60f2ec1e1",
"586d8eeaec3a439978836a512bf2f5a987cbe2ba72e5bb10322d04cd65fe8d09",
"ebdc2c2cedd5e549ba8d5e3f474d29204e1cf073e2b26e75f60bb429d2b5a088",
"80eb757f729a943ff0919df1eb980b80f8419f76648407834d95c76adfd21624",
"e71eb30f24c82bc4fa1c645eecbe343f5a44526043fc3a13047183dac5f212f3",
"c46f9f3c710ff2baabea480670220e0328e7bcc2aa3c598c3f982728e0b5652d",
"7f1ab7572a89534366172df3ae5f0182aab1ae3ef992b684a84c5c1a10e8315f",
"d7624e57820ccd1bae7881e08af40bc3522971278018fdfbe0ca98302292165c",
"e0f11ad44d1c1e11f9308f9aaee4d8bcac86ff6e0b4a41d1e75879f6cfd56049",
"2266a567ba921d1c2661258cd5b31150274cb781ac01413c34a471557123ba65",
"1f2e936a57994e16b457f249a64af4786877f7beaab003fb521a20e45031f408",
"e8eaf74988082b8c8222dabed68218069c8eb4e93acd3619a776bc28d39e5ce5",
"39fdb47a5f349e06bbb7dc1cedcc81a051d1dffe373956871325f8327e858afa",
"f7af5eac1d34a2ddc619dd0c3172ec28334b8d79efc1f8ad758124b7e5aae0d5",
"8f3d19065d0d1295bbfbf7591aa02af3a5dc70fde74bac670c18ccd8f7306008",
"d6b771bedda261bcfe9dd1d1402b7d33b5cd2764cd53d941957e32920cfbeb19",
"3e02857de5a59331e1f7fc7e1ddf5ae58e8680d298bb44b49bd316e0b3a1f024",
"954b4385cf4faecfbf9cd04e01c059eb09113a78ee727149b63a65b495a28a6c",
"8851b734602eb00da5b1cfc1e40d38f1cb32e0add2df257ff9d7dbd520b4d5da",
"b2d86212afab00e7b9bf19b7931277130b653c9258ac419a7a24d749471ea5ac",
"5231df995d71991ee4108937bb12e4d3f344a96fb0c4cd82c14e18061d6c4730",
"4daef5be9503c580697b36b0b60a702c109e23840c0632ca00ef4a233603018e",
"fd788a077e026905f1565e0d2a65dfc6c55699c098a59879d6b0b3f3b8459ae8",
"dc641636d5d782b31d29ce823e951d1a2164c86ee06bf2f65a841360fb7af356",
"fb4a05ce7d50721c71f66c37e0ab7e52cd46034a2e394940b3f60c9c2afb079a",
"862a7e8c68f05b91ecf3a43ac5b60c6f57ee50fa98ad1b539480d541628f5c2e",
"44c87532cbb511c369b38a105fc5a84b1d89dba9dfdd5a62c311d6176fe93201",
"73395b6c3fa9fa73e8e3665f108b3a92c564da9c1b9ce7834832adbb5e658a87",
"862b75fd4ebed41378d3af00784ef9bde4362e27d6f2aee384b99286f6beb0bd",
"7214d926419fe847a4795a74f9b73209990e4927bb5b56128cf30703be68cde7",
"96dca741745683eb5c2ad857e2520ccf62ab2d08eae359f6928495073925faee",
"8c1ae6ac63865e603e04a3a4f0ab0178e6422615a42e011bfd8453fc78f1fd58",
"ab7ba2df709c5ff7ee16a1038deaf1d795977b035a1ba08cc6d32ea9ff87bd80",
"1bbd271d777f59f1233e4124991dae126ba183ffca404e74084d29dc46b65b38",
"929365d4c30b1cb3f8458d3b1bd48536260942ef9e3cab33286a1540088105e4",
"34b9970af6ce3fb7e81ad42fcaf852d9d7e341a624f988409a36323329222751",
"ec5aa260268e7c596adc7be56792af587da44bd897ce4f38f616ebc3d2f22a88",
"e0e4fd3650aa15f92aad1d1e7567f2447f03e9c009ae4ee955afb980ec991912",
"379952ec8113b3692872ffb9d07c242968ee1edfac9b3b888496c1480033be91",
"802de2c196b779f0c10827bc37186a4d1db3e46841d27682865c6dbaf28bba46",
"2813d00f34d60d17b5b192acd3450720966fa103fb0669c3f69c36c67204a66b",
"bf740678008401deeb4b017d0641fb32f5747dfca9be0b8c5228366814ee7f67",
"e1e8dac7bb356121152e7d0315659c4340cacab2a46d32a736c1ad254c9274ea",
"8532f5aa7eb3d492ffac5416ed618be439136e9a1c9d0514417e26a6ab9d311f",
"bee38a315667379528705aaa3edb3899cbfaaaea8e19db3214d3735d00240e71",
"c8f04efd583ac2649db79902e680d8476939a0663b1e8b076e391303fef074c9")
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.Ext.api.metadata.target_address_name | wildcard | Data, msys-*, cyg*.dll | excludes:process.Ext.api.metadata.target_address_name field:"process.Ext.api.metadata.target_address_name" value:"Data" field:"process.Ext.api.metadata.target_address_name" value:"msys-*" field:"process.Ext.api.metadata.target_address_name" value:"cyg*.dll" |
process.thread.Ext.call_stack_summary | wildcard | ntdll.dll|kernelbase.dll|msys-?.?.dll|*Unknown, ntdll.dll|kernelbase.dll|cygwin?.dll|*Unknown, ntdll.dll|kernelbase.dll|cygwin?.dll|bash.exe, ntdll.dll|kernelbase.dll|cygwin?.dll, ntdll.dll|kernelbase.dll|msys-?.0.dll | excludes:process.thread.Ext.call_stack_summary |
process.Ext.api.summary | match | PEB, PEB32, ProcessStartupInfo | excludes:process.Ext.api.summary field:"process.Ext.api.summary" value:"PEB" field:"process.Ext.api.summary" value:"PEB32" field:"process.Ext.api.summary" value:"ProcessStartupInfo" |
process.thread.Ext.call_stack_summary | match | Unknown | excludes:process.thread.Ext.call_stack_summary field:"process.thread.Ext.call_stack_summary" value:"Unknown" |
process.thread.Ext.call_stack | array_any | excludes:process.thread.Ext.call_stack | |
process.thread.Ext.call_stack_final_user_module.hash.sha256 | in | 0255b5bf7ad66aa090be145f0ad41a0f4e33409ff5c2970081fccd863c720779, 16184cf6f54d6ac4eb0a31c0e9ee8ae775bae6dfdc632e283e832f3e89de595d, 1bbd271d777f59f1233e4124991dae126ba183ffca404e74084d29dc46b65b38, 1f2e936a57994e16b457f249a64af4786877f7beaab003fb521a20e45031f408, 2266a567ba921d1c2661258cd5b31150274cb781ac01413c34a471557123ba65, 27fe00d32f773a95e6d50986e5e7499917f66ce881e46054c77652ef4bdf3512, 2813d00f34d60d17b5b192acd3450720966fa103fb0669c3f69c36c67204a66b, 30b59303bec45b020b4878b2d33d63bd719d89820456a7ee0a920178efe089f4, 34b9970af6ce3fb7e81ad42fcaf852d9d7e341a624f988409a36323329222751, 379952ec8113b3692872ffb9d07c242968ee1edfac9b3b888496c1480033be91, 39fdb47a5f349e06bbb7dc1cedcc81a051d1dffe373956871325f8327e858afa, 3e02857de5a59331e1f7fc7e1ddf5ae58e8680d298bb44b49bd316e0b3a1f024, 44c87532cbb511c369b38a105fc5a84b1d89dba9dfdd5a62c311d6176fe93201, 4daef5be9503c580697b36b0b60a702c109e23840c0632ca00ef4a233603018e, 51b63860fd996d6d5b1753ba6bb7f3a4303f13187fbfecc96ba2b6bae52a7410, 5231df995d71991ee4108937bb12e4d3f344a96fb0c4cd82c14e18061d6c4730, 57854d83b50ff0a23d47c077d6da875874ea78f88f28168d8e99ffbf9f1c3153, 586d8eeaec3a439978836a512bf2f5a987cbe2ba72e5bb10322d04cd65fe8d09, 67435999749d9e6908a4029321c0c6f9e915135e98e01a7e499a1c55a960bc68, 681303f5b5688075b5b504819d8b3c343c78e3240a3bccf371e03228970ffb10, 6edb20df25d1cf0fd1b27052f2604a05db1d7ca5a3f074e7bacc229e28d17667, 7214d926419fe847a4795a74f9b73209990e4927bb5b56128cf30703be68cde7, 73395b6c3fa9fa73e8e3665f108b3a92c564da9c1b9ce7834832adbb5e658a87, 7396f943823494d2ec5f2260329daa2d35b1764f01cdefd95f84ae320986a8f3, 7f1ab7572a89534366172df3ae5f0182aab1ae3ef992b684a84c5c1a10e8315f, 802de2c196b779f0c10827bc37186a4d1db3e46841d27682865c6dbaf28bba46, 80eb757f729a943ff0919df1eb980b80f8419f76648407834d95c76adfd21624, 8532f5aa7eb3d492ffac5416ed618be439136e9a1c9d0514417e26a6ab9d311f, 862a7e8c68f05b91ecf3a43ac5b60c6f57ee50fa98ad1b539480d541628f5c2e, 862b75fd4ebed41378d3af00784ef9bde4362e27d6f2aee384b99286f6beb0bd, 8851b734602eb00da5b1cfc1e40d38f1cb32e0add2df257ff9d7dbd520b4d5da, 8c1ae6ac63865e603e04a3a4f0ab0178e6422615a42e011bfd8453fc78f1fd58, 8eb0721092af3131a940f1e23bc2871e09362980e0b71a7ed7dab6e8accd1f30, 8ee5bd6fea98577bd29c15055e96ec17c62ca415f4a5d26065b25a922b19d3b1, 8f3d19065d0d1295bbfbf7591aa02af3a5dc70fde74bac670c18ccd8f7306008, 914299dd77f4322c99f62c37df1317ea3424d9a747d4635d10c1d3f003f6abd4, 925a5cd982933bae1b271e1aaaa887ab469397701cd299f4397ddd8af5a351f9, 929365d4c30b1cb3f8458d3b1bd48536260942ef9e3cab33286a1540088105e4, 954b4385cf4faecfbf9cd04e01c059eb09113a78ee727149b63a65b495a28a6c, 96dca741745683eb5c2ad857e2520ccf62ab2d08eae359f6928495073925faee, 9cb1208f1747963dc57e8bf8a8fe82b3aaa856caae3d151b6a6b97b23369f5a6, a4637935f895de601850c6868d952977a84076a7b1719d0deb519f1fc0871be4, a59e039e1520b74254a454bf48c2bceeafe7bd7ac6e5886baa482a52f86a29bf, a99ac2554c1e392ffe3cd53f7f72f76638948533795fc04f7e15454c386b7eec, ab7ba2df709c5ff7ee16a1038deaf1d795977b035a1ba08cc6d32ea9ff87bd80, b031da6137f9442a6cc9f4b4546b4057b666726cb7c9224c4ca857a60f2ec1e1, b2d86212afab00e7b9bf19b7931277130b653c9258ac419a7a24d749471ea5ac, bee38a315667379528705aaa3edb3899cbfaaaea8e19db3214d3735d00240e71, bf740678008401deeb4b017d0641fb32f5747dfca9be0b8c5228366814ee7f67, c3cd2439a6175ce28192904e72b14523b02559d8083a710b5e82aee400626d1a, c46f9f3c710ff2baabea480670220e0328e7bcc2aa3c598c3f982728e0b5652d, c4788275a5ed2c1576e69b59e6e267ce573450ff07e54b799ec4c4edef40b502, c8f04efd583ac2649db79902e680d8476939a0663b1e8b076e391303fef074c9, c983d11ad519a851aca2d37739110b7913819bea1ddf2cc3ec69efe3ed3b609f, d6b771bedda261bcfe9dd1d1402b7d33b5cd2764cd53d941957e32920cfbeb19, d7624e57820ccd1bae7881e08af40bc3522971278018fdfbe0ca98302292165c, dc641636d5d782b31d29ce823e951d1a2164c86ee06bf2f65a841360fb7af356, e0e4fd3650aa15f92aad1d1e7567f2447f03e9c009ae4ee955afb980ec991912, e0f11ad44d1c1e11f9308f9aaee4d8bcac86ff6e0b4a41d1e75879f6cfd56049, e1e8dac7bb356121152e7d0315659c4340cacab2a46d32a736c1ad254c9274ea, e71eb30f24c82bc4fa1c645eecbe343f5a44526043fc3a13047183dac5f212f3, e8eaf74988082b8c8222dabed68218069c8eb4e93acd3619a776bc28d39e5ce5, ebdc2c2cedd5e549ba8d5e3f474d29204e1cf073e2b26e75f60bb429d2b5a088, ec5aa260268e7c596adc7be56792af587da44bd897ce4f38f616ebc3d2f22a88, efd03f2525e69cdc30b5736af74d9485728b8a94d5624da87f1431b3706980ab, f01bb9aba3f9daf4d8f5551a3b753d8011e16072a1103cf5303d617a9f866424, f7af5eac1d34a2ddc619dd0c3172ec28334b8d79efc1f8ad758124b7e5aae0d5, fb4a05ce7d50721c71f66c37e0ab7e52cd46034a2e394940b3f60c9c2afb079a, fd788a077e026905f1565e0d2a65dfc6c55699c098a59879d6b0b3f3b8459ae8 | excludes:process.thread.Ext.call_stack_final_user_module.hash.sha256 |
process.thread.Ext.call_stack_final_user_module.name | in | Kernel, Undetermined, Unknown | excludes: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:"Undetermined" field:"process.thread.Ext.call_stack_final_user_module.name" value:"Unknown" |
process.thread.Ext.call_stack_final_user_module.path | wildcard | ?:\windows\assembly\nativeimages_*.dll, ?:\program files\*, ?:\program files (x86)\*, c:\windows\apppatch\ummon.dll, c:\windows\apppatch\apppatch64\ummon.dll, c:\windows\system32\ctiuser.dll, c:\windows\syswow64\ctiuser.dll, c:\windows\system32\lsasrv.dll | excludes:process.thread.Ext.call_stack_final_user_module.path |
process.thread.Ext.call_stack_final_user_module.protection_provenance | eq | mfehcthe.dll | excludes:process.thread.Ext.call_stack_final_user_module.protection_provenance field:"process.thread.Ext.call_stack_final_user_module.protection_provenance" value:"mfehcthe.dll" |
Potential Windows Error Manager Masquerading
#Identifies suspicious instances of the Windows Error Reporting process (WerFault.exe or Wermgr.exe) with matching command-line and process executable values performing outgoing network connections. This may be indicative of a masquerading attempt to evade suspicious child process behavior detections.
Known False Positives
- Legit Application Crash with rare Werfault commandline value
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2020/08/24"
integration = ["endpoint", "windows"]
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 suspicious instances of the Windows Error Reporting process (WerFault.exe or Wermgr.exe) with matching
command-line and process executable values performing outgoing network connections. This may be indicative of a
masquerading attempt to evade suspicious child process behavior detections.
"""
false_positives = ["Legit Application Crash with rare Werfault commandline value"]
from = "now-9m"
index = [
"winlogbeat-*",
"logs-endpoint.events.process-*",
"logs-endpoint.events.network-*",
"logs-windows.sysmon_operational-*",
]
language = "eql"
license = "Elastic License v2"
name = "Potential Windows Error Manager Masquerading"
note = """## Triage and analysis
### Investigating Potential Windows Error Manager Masquerading
By examining the specific traits of Windows binaries -- such as process trees, command lines, network connections, registry modifications, and so on -- it's possible to establish a baseline of normal activity. Deviations from this baseline can indicate malicious activity, such as masquerading and deserve further investigation.
This rule identifies a potential malicious process masquerading as `wermgr.exe` or `WerFault.exe`, by looking for a process creation with no arguments followed by a network connection.
> **Note**:
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/current/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.
#### Possible investigation steps
- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Investigate any abnormal behavior by the subject process such as network connections, registry or file modifications, and any spawned child processes.
- Examine the host for derived artifacts that indicate suspicious activities:
- Analyze the process executable using a private sandboxed analysis system.
- Observe and collect information about the following activities in both the sandbox and the alert subject host:
- Attempts to contact external domains and addresses.
- Use the Elastic Defend network events to determine domains and addresses contacted by the subject process by filtering by the process' `process.entity_id`.
- Examine the DNS cache for suspicious or anomalous entries.
- $osquery_0
- Use the Elastic Defend registry events to examine registry keys accessed, modified, or created by the related processes in the process tree.
- Examine the host services for suspicious or anomalous entries.
- $osquery_1
- $osquery_2
- $osquery_3
- Retrieve the files' SHA-256 hash values using the PowerShell `Get-FileHash` cmdlet and search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.
- Investigate potentially compromised accounts. Analysts can do this by searching for login events (for example, 4624) to the target host after the registry modification.
### False positive analysis
- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.
### Response and remediation
- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- If the triage identified malware, search the environment for additional compromised hosts.
- Implement temporary network rules, procedures, and segmentation to contain the malware.
- Stop suspicious processes.
- Immediately block the identified indicators of compromise (IoCs).
- Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that attackers could use to reinfect the system.
- Remove and block malicious artifacts identified during triage.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
setup = """## Setup
This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
Setup instructions: https://ela.st/install-elastic-defend
### Additional data sources
This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
- [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
- [Sysmon Event ID 3 - Network Connection](https://ela.st/sysmon-event-3-setup)
"""
references = [
"https://twitter.com/SBousseaden/status/1235533224337641473",
"https://www.hexacorn.com/blog/2019/09/20/werfault-command-line-switches-v0-1/",
"https://app.any.run/tasks/26051d84-b68e-4afb-8a9a-76921a271b81/",
"https://www.elastic.co/security-labs/elastic-security-uncovers-blister-malware-campaign",
]
risk_score = 47
rule_id = "6ea41894-66c3-4df7-ad6b-2c5074eb3df8"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Defense Evasion",
"Resources: Investigation Guide",
"Data Source: Elastic Defend",
"Data Source: Sysmon",
]
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.name : ("wermgr.exe", "WerFault.exe") and
(process.args_count == 1 and
/* Excludes bug where a missing closing quote sets args_count to 1 despite extra args */
not process.command_line regex~ """\".*\.exe[^\"].*""")]
[network where host.os.type == "windows" and process.name : ("wermgr.exe", "WerFault.exe") and network.protocol != "dns" and
network.direction : ("outgoing", "egress") and destination.ip !="::1" and destination.ip !="127.0.0.1"
]
'''
[[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.005"
name = "Match Legitimate Resource Name or Location"
reference = "https://attack.mitre.org/techniques/T1036/005/"
[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.name : ("wermgr.exe", "WerFault.exe") and
(process.args_count == 1 and
not process.command_line regex~ """\".*\.exe[^\"].*""")]
Stage 2: network
[network where host.os.type == "windows" and process.name : ("wermgr.exe", "WerFault.exe") and network.protocol != "dns" and
network.direction : ("outgoing", "egress") and destination.ip !="::1" and destination.ip !="127.0.0.1"
]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
destination.ip | ne |
| field:"dest_ip" kind:ne |
event.type | wildcard |
| field:"event.type" kind:wildcard value:"start" |
network.direction | wildcard |
| field:"Initiated" kind:wildcard |
network.protocol | ne |
| field:"DestinationPortName" kind:ne value:"dns" |
process.args_count | eq |
| field:"process.args_count" kind:eq value:"1" |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.command_line | regex_match | \".*.exe[^\"].* | excludes:process.command_line |
Suspicious Curl File Download and Execution
#Detects when Curl downloads a file to a suspicious directory and that file is immediately executed via the same effective parent process. This behavior is often used by threat actors to download and execute additional payloads or tooling on a target system. While the use of Curl is not inherently malicious, the combination of downloading to temporary or shared directories followed by immediate execution is indicative of potentially malicious activity.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Command & Control |
Telemetry Coverage
Rule Body
[rule]
description = """
Detects when Curl downloads a file to a suspicious directory and that file is immediately executed via the same
effective parent process. This behavior is often used by threat actors to download and execute additional payloads or
tooling on a target system. While the use of Curl is not inherently malicious, the combination of downloading to
temporary or shared directories followed by immediate execution is indicative of potentially malicious activity.
"""
id = "ce1df6f8-9ddc-492d-8de3-7c663856c9ca"
license = "Elastic License v2"
name = "Suspicious Curl File Download and Execution"
os_list = ["macos"]
version = "1.0.7"
query = '''
sequence with maxspan=15s
[file where event.action == "modification" and process.name in ("curl", "nscurl") and file.path like ("/Users/Shared/*", "/tmp/*", "/private/tmp/*", "/var/tmp/*", "/private/var/tmp/*") and
not Effective_process.executable like ("/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon",
"/usr/local/jamf/bin/jamf") and
not file.extension == "pkg"] as event0
[process where event.type == "start" and event.action == "exec" and process.name in ("bash", "sh", "zsh") and stringcontains~(event0.file.name, process.command_line)]
'''
min_endpoint_version = "8.16.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "Effective_process.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1105"
name = "Ingress Tool Transfer"
reference = "https://attack.mitre.org/techniques/T1105/"
[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[internal]
min_endpoint_version = "8.16.0"
Stages and Predicates
Stage 1: file
[file where event.action == "modification" and process.name in ("curl", "nscurl") and file.path like ("/Users/Shared/*", "/tmp/*", "/private/tmp/*", "/var/tmp/*", "/private/var/tmp/*") and
not Effective_process.executable like ("/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon",
"/usr/local/jamf/bin/jamf") and
not file.extension == "pkg"] as event0
Stage 2: process
[process where event.type == "start" and event.action == "exec" and process.name in ("bash", "sh", "zsh") and stringcontains~(event0.file.name, process.command_line)]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
event0.file.name | contains |
| field:"event0.file.name" kind:contains value:"process.command_line" |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard |
process.name | in |
| field:"process_basename" kind:in |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
Effective_process.executable | eq | /Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon, /usr/local/jamf/bin/jamf | excludes:Effective_process.executable field:"Effective_process.executable" value:"/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon" field:"Effective_process.executable" value:"/usr/local/jamf/bin/jamf" |
file.extension | eq | pkg | excludes:file.extension field:"file.extension" value:"pkg" |
Suspicious Inter-Process Communication via Outlook
#Detects Inter-Process Communication with Outlook via Component Object Model from an unusual process. Adversaries may target user email to collect sensitive information or send email on their behalf via API.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Collection |
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 1: Process creation |
| Security-Auditing | Event ID 4688: A new process has been created. |
Rule Body
[metadata]
creation_date = "2023/01/11"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/07/28"
[rule]
author = ["Elastic"]
description = """
Detects Inter-Process Communication with Outlook via Component Object Model from an unusual process. Adversaries may
target user email to collect sensitive information or send email on their behalf via API.
"""
from = "now-9m"
index = ["logs-endpoint.events.process-*"]
language = "eql"
license = "Elastic License v2"
name = "Suspicious Inter-Process Communication via Outlook"
references = [
"https://github.com/center-for-threat-informed-defense/adversary_emulation_library/blob/master/apt29/Archive/CALDERA_DIY/evals/payloads/stepSeventeen_email.ps1",
]
risk_score = 47
rule_id = "1dee0500-4aeb-44ca-b24b-4a285d7b6ba1"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Collection",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
type = "eql"
query = '''
sequence with maxspan=1m
[process where host.os.type == "windows" and event.action == "start" and
(
process.name : (
"rundll32.exe", "mshta.exe", "powershell.exe", "pwsh.exe",
"cmd.exe", "regsvr32.exe", "cscript.exe", "wscript.exe"
) or
(
(process.code_signature.trusted == false or process.code_signature.exists == false) and
(process.Ext.relative_file_creation_time <= 500 or process.Ext.relative_file_name_modify_time <= 500)
)
) and
not (
process.executable : "?:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" and
process.parent.executable : "?:\\Program Files (x86)\\CyberCNSAgent\\cybercnsagent.exe" and
user.id == "S-1-5-18"
)
] by process.entity_id
[process where host.os.type == "windows" and event.action == "start" and process.name : "OUTLOOK.EXE" and
process.Ext.effective_parent.name != null] by process.Ext.effective_parent.entity_id
'''
setup = """## Setup
This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
Setup instructions: https://ela.st/install-elastic-defend
"""
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Suspicious Inter-Process Communication via Outlook
Outlook's integration with the Component Object Model (COM) allows processes to automate tasks like sending emails. Adversaries exploit this by using unusual processes to interact with Outlook, potentially to exfiltrate data or send unauthorized emails. The detection rule identifies such anomalies by monitoring for unexpected processes initiating communication with Outlook, especially those lacking trusted signatures or recently modified, indicating potential malicious activity.
### Possible investigation steps
- Review the process entity ID to identify the specific process that initiated communication with Outlook and determine if it is one of the unusual processes listed, such as rundll32.exe, mshta.exe, or powershell.exe.
- Check the code signature status of the initiating process. If the process is unsigned or has an untrusted signature, investigate the source and legitimacy of the executable.
- Analyze the relative file creation and modification times of the initiating process. If the process was created or modified recently (within 500 seconds), it may indicate a newly introduced or altered executable, warranting further scrutiny.
- Investigate the effective parent process of OUTLOOK.EXE to understand the context of how Outlook was launched. Determine if the parent process is expected or if it is an unusual or suspicious process.
- Correlate the alert with any recent user activity or changes on the host to identify potential user actions or system changes that could explain the process behavior.
- Examine any network activity associated with the initiating process to identify potential data exfiltration or unauthorized email sending attempts.
- Review any additional alerts or logs related to the host or user account to identify patterns or additional indicators of compromise.
### False positive analysis
- Legitimate administrative scripts or tools may trigger the rule if they use processes like PowerShell or cmd.exe to automate tasks involving Outlook. To manage this, identify and whitelist these scripts or tools by their specific file paths or hashes.
- Software updates or installations might cause processes to appear as recently modified, leading to false positives. Regularly update the list of trusted software and exclude these known update processes from triggering alerts.
- Custom in-house applications that interact with Outlook for business purposes may be flagged. Ensure these applications are signed with a trusted certificate or add them to an exception list based on their unique identifiers.
- Security tools or monitoring software that perform regular checks on Outlook might be misidentified. Verify these tools and exclude them by their process names or signatures to prevent unnecessary alerts.
### Response and remediation
- Immediately isolate the affected system from the network to prevent further unauthorized access or data exfiltration.
- Terminate any suspicious processes identified in the alert, particularly those interacting with Outlook, such as rundll32.exe, mshta.exe, or powershell.exe.
- Conduct a thorough review of the email account associated with the affected Outlook process to identify any unauthorized access or email activity. Reset the account credentials if necessary.
- Analyze the process code signatures and file modification times to determine if any legitimate applications have been compromised. Reinstall or update these applications as needed.
- 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 additional monitoring on the affected system and similar endpoints to detect any recurrence of the suspicious activity.
- Review and update endpoint protection policies to ensure that similar threats are detected and blocked in the future, leveraging the MITRE ATT&CK framework for guidance on email collection techniques."""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1114"
name = "Email Collection"
reference = "https://attack.mitre.org/techniques/T1114/"
[[rule.threat.technique.subtechnique]]
id = "T1114.001"
name = "Local Email Collection"
reference = "https://attack.mitre.org/techniques/T1114/001/"
[rule.threat.tactic]
id = "TA0009"
name = "Collection"
reference = "https://attack.mitre.org/tactics/TA0009/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1559"
name = "Inter-Process Communication"
reference = "https://attack.mitre.org/techniques/T1559/"
[[rule.threat.technique.subtechnique]]
id = "T1559.001"
name = "Component Object Model"
reference = "https://attack.mitre.org/techniques/T1559/001/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
Stages and Predicates
Ordered sequence: each step below must occur in order within 1m, correlated by process.Ext.effective_parent.entity_id, process.entity_id.
Stage 1: process
[process where host.os.type == "windows" and event.action == "start" and
(
process.name : (
"rundll32.exe", "mshta.exe", "powershell.exe", "pwsh.exe",
"cmd.exe", "regsvr32.exe", "cscript.exe", "wscript.exe"
) or
(
(process.code_signature.trusted == false or process.code_signature.exists == false) and
(process.Ext.relative_file_creation_time <= 500 or process.Ext.relative_file_name_modify_time <= 500)
)
) and
not (
process.executable : "?:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" and
process.parent.executable : "?:\\Program Files (x86)\\CyberCNSAgent\\cybercnsagent.exe" and
user.id == "S-1-5-18"
)
] by process.entity_id
Stage 2: process
[process where host.os.type == "windows" and event.action == "start" and process.name : "OUTLOOK.EXE" and
process.Ext.effective_parent.name != null] by process.Ext.effective_parent.entity_id
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.Ext.effective_parent.name | is_not_null | field:"process.Ext.effective_parent.name" kind:is_not_null | |
process.Ext.relative_file_creation_time | le |
| field:"process.Ext.relative_file_creation_time" kind:le value:"500" |
process.Ext.relative_file_name_modify_time | le |
| field:"process.Ext.relative_file_name_modify_time" kind:le value:"500" |
process.code_signature.exists | eq |
| field:"process.code_signature.exists" kind:eq value:"false" |
process.code_signature.trusted | eq |
| field:"process.code_signature.trusted" kind:eq value:"false" |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.executable | eq | ?:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe | excludes:process.executable field:"process.executable" value:"?:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" |
process.parent.executable | eq | ?:\Program Files (x86)\CyberCNSAgent\cybercnsagent.exe | excludes:process.parent.executable field:"process.parent.executable" value:"?:\Program Files (x86)\CyberCNSAgent\cybercnsagent.exe" |
user.id | eq | S-1-5-18 | excludes:user.id field:"user.id" value:"S-1-5-18" |
Suspicious Python Path Configuration File (.pth) Creation
#Detects creation or change of a Python path configuration file (.pth) with a suspicious import preface, file size or entropy. This rule matches .pth files whose leading bytes correspond to UTF-8 text beginning with an import-style preface (for example, the string starting with "import os, subpr" as used before subprocess or similar calls). That pattern is atypical and may indicate code execution via the .pth mechanism.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Persistence |
Rule Body
[rule]
description = """
Detects creation or change of a Python path configuration file (.pth) with a suspicious import preface, file size or
entropy. This rule matches .pth files whose leading bytes correspond to UTF-8 text beginning with an import-style
preface (for example, the string starting with "import os, subpr" as used before subprocess or similar calls). That
pattern is atypical and may indicate code execution via the .pth mechanism.
"""
id = "983dc90f-7eb0-4832-a537-3854b40d31fa"
license = "Elastic License v2"
name = "Suspicious Python Path Configuration File (.pth) Creation"
os_list = ["linux"]
reference = [
"https://dfir.ch/posts/publish_python_pth_extension/",
"https://www.volexity.com/blog/2024/04/12/zero-day-exploitation-of-unauthenticated-remote-code-execution-vulnerability-in-globalprotect-cve-2024-3400/",
"https://futuresearch.ai/blog/litellm-pypi-supply-chain-attack/",
"https://www.virustotal.com/gui/file/71e35aef03099cd1f2d6446734273025a163597de93912df321ef118bf135238",
]
version = "1.0.2"
query = '''
file where event.type in ("change", "creation") and file.extension like "pth" and (
file.Ext.header_bytes like "696d706f7274206f732c207375627072" or
(
file.path like "*site-packages*" and
(file.size >= 30000 or file.Ext.entropy >= 5.5)
)
) and
not (
file.path like (
"*/site-packages/torchmetrics/functional/image/lpips_models/*.pth",
"*/site-packages/lpips/weights/*/*.pth"
) and
file.Ext.header_bytes like "80028a0a6cfc9c46f9206aa850192e80"
)
'''
min_endpoint_version = "9.3.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.006"
name = "Python"
reference = "https://attack.mitre.org/techniques/T1059/006/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1546"
name = "Event Triggered Execution"
reference = "https://attack.mitre.org/techniques/T1546/"
[[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/"
[internal]
min_endpoint_version = "9.3.0"
Stages and Predicates
Stage 1: file
file where event.type in ("change", "creation") and file.extension like "pth" and (
file.Ext.header_bytes like "696d706f7274206f732c207375627072" or
(
file.path like "*site-packages*" and
(file.size >= 30000 or file.Ext.entropy >= 5.5)
)
) and
not (
file.path like (
"*/site-packages/torchmetrics/functional/image/lpips_models/*.pth",
"*/site-packages/lpips/weights/*/*.pth"
) and
file.Ext.header_bytes like "80028a0a6cfc9c46f9206aa850192e80"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | in |
| field:"event.type" kind:in |
file.Ext.entropy | ge |
| field:"file.Ext.entropy" kind:ge value:"5.5" |
file.Ext.header_bytes | wildcard |
| field:"file.Ext.header_bytes" kind:wildcard value:"696d706f7274206f732c207375627072" |
file.extension | wildcard |
| field:"file.extension" kind:wildcard value:"pth" |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard value:"*site-packages*" |
file.size | ge |
| field:"file.size" kind:ge value:"30000" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
file.Ext.header_bytes | eq | 80028a0a6cfc9c46f9206aa850192e80 | excludes:file.Ext.header_bytes field:"file.Ext.header_bytes" value:"80028a0a6cfc9c46f9206aa850192e80" |
file.path | wildcard | */site-packages/torchmetrics/functional/image/lpips_models/*.pth, */site-packages/lpips/weights/*/*.pth | excludes:file.path field:"file.path" value:"*/site-packages/torchmetrics/functional/image/lpips_models/*.pth" field:"file.path" value:"*/site-packages/lpips/weights/*/*.pth" |
Suspicious Remote Process Thread Access
#Identifies attempt to open a remote process thread with THREAD_SET_LIMITED_INFORMATION desired access. This may indicate an attempt to hijack the remote thread execution priority.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule Body
[rule]
description = """
Identifies attempt to open a remote process thread with THREAD_SET_LIMITED_INFORMATION desired access. This may indicate
an attempt to hijack the remote thread execution priority.
"""
id = "f01594de-1d8e-4995-87e5-dd9e5edb8f88"
license = "Elastic License v2"
name = "Suspicious Remote Process Thread Access"
os_list = ["windows"]
reference = ["https://github.com/Octoberfest7/ThreadCPUAssignment_POC/tree/main"]
version = "1.0.3"
query = '''
api where process.Ext.api.behaviors == "cross-process" and
process.Ext.api.name == "OpenThread" and process.Ext.api.parameters.desired_access == "THREAD_SET_LIMITED_INFORMATION" and
Target.process.Ext.token.integrity_level_name == "system" and Target.process.pid != 4 and
not _arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature, $entry, $entry.trusted == true) and
not (process.executable :("?:\\Windows\\System32\\csrss.exe", "\\\\?\\Volume{*}\\Windows\\System32\\csrss.exe") and user.id == "S-1-5-18")
'''
min_endpoint_version = "8.18.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "8.18.0"
Stages and Predicates
Stage 1: api
api where process.Ext.api.behaviors == "cross-process" and
process.Ext.api.name == "OpenThread" and process.Ext.api.parameters.desired_access == "THREAD_SET_LIMITED_INFORMATION" and
Target.process.Ext.token.integrity_level_name == "system" and Target.process.pid != 4 and
not _arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature, $entry, $entry.trusted == true) and
not (process.executable :("?:\\Windows\\System32\\csrss.exe", "\\\\?\\Volume{*}\\Windows\\System32\\csrss.exe") and user.id == "S-1-5-18")
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.executable | wildcard | ?:\Windows\System32\csrss.exe, \\?\Volume{*}\Windows\System32\csrss.exe | excludes:process.executable field:"process.executable" value:"?:\Windows\System32\csrss.exe" field:"process.executable" value:"\\?\Volume{*}\Windows\System32\csrss.exe" |
user.id | eq | S-1-5-18 | excludes:user.id field:"user.id" value:"S-1-5-18" |
process.thread.Ext.call_stack_final_user_module.code_signature | array_any | excludes:process.thread.Ext.call_stack_final_user_module.code_signature |
Suspicious Shortcut File Overwrite
#Identifies the overwrite of a Windows shortcut (lnk) file by processes that defaults to handle archive extraction. This could be the result of an attempt to bypass bypass Microsoft SmartScreen protection.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Execution |
Rule Body
[rule]
description = """
Identifies the overwrite of a Windows shortcut (lnk) file by processes that defaults to handle archive extraction. This
could be the result of an attempt to bypass bypass Microsoft SmartScreen protection.
"""
id = "7e1113a3-8f6a-4450-a95e-343c0c75a639"
license = "Elastic License v2"
name = "Suspicious Shortcut File Overwrite"
os_list = ["windows"]
reference = ["https://www.elastic.co/security-labs/dismantling-smart-app-control"]
version = "1.0.4"
query = '''
file where event.action == "overwrite" and file.extension : "lnk" and
process.name :("explorer.exe", "7zFM.exe", "WinRAR.exe", "Bandizip.exe") and file.Ext.header_bytes : "4c0000000114020000000000c0000000" and
process.thread.Ext.call_stack_summary : "ntdll.dll|*|windows.storage.dll|shell32.dll|*" and
(
file.path : ("?:\\Users\\*\\Downloads\\*.lnk", "?:\\Users\\*\\AppData\\Local\\Temp\\*.lnk") or
file.Ext.windows.zone_identifier == 3
) and
not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info: "*windows.storage.dll!RebaseOnVolumeID*")
'''
actions = []
min_endpoint_version = "8.7.0"
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1566"
name = "Phishing"
reference = "https://attack.mitre.org/techniques/T1566/"
[[threat.technique.subtechnique]]
id = "T1566.001"
name = "Spearphishing Attachment"
reference = "https://attack.mitre.org/techniques/T1566/001/"
[[threat.technique.subtechnique]]
id = "T1566.002"
name = "Spearphishing Link"
reference = "https://attack.mitre.org/techniques/T1566/002/"
[threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1204"
name = "User Execution"
reference = "https://attack.mitre.org/techniques/T1204/"
[[threat.technique.subtechnique]]
id = "T1204.001"
name = "Malicious Link"
reference = "https://attack.mitre.org/techniques/T1204/001/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[internal]
min_endpoint_version = "8.7.0"
Stages and Predicates
Stage 1: file
file where event.action == "overwrite" and file.extension : "lnk" and
process.name :("explorer.exe", "7zFM.exe", "WinRAR.exe", "Bandizip.exe") and file.Ext.header_bytes : "4c0000000114020000000000c0000000" and
process.thread.Ext.call_stack_summary : "ntdll.dll|*|windows.storage.dll|shell32.dll|*" and
(
file.path : ("?:\\Users\\*\\Downloads\\*.lnk", "?:\\Users\\*\\AppData\\Local\\Temp\\*.lnk") or
file.Ext.windows.zone_identifier == 3
) and
not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info: "*windows.storage.dll!RebaseOnVolumeID*")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"overwrite" |
file.Ext.header_bytes | wildcard |
| field:"file.Ext.header_bytes" kind:wildcard value:"4c0000000114020000000000c0000000" |
file.Ext.windows.zone_identifier | eq |
| field:"file.Ext.windows.zone_identifier" kind:eq value:"3" |
file.extension | wildcard |
| field:"file.extension" kind:wildcard value:"lnk" |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
process.thread.Ext.call_stack_summary | wildcard |
| field:"process.thread.Ext.call_stack_summary" kind:wildcard value:"ntdll.dll|*|windows.storage.dll|shell32.dll|*" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.thread.Ext.call_stack | array_any | excludes:process.thread.Ext.call_stack |
Suspicious Startup Shell Folder Modification
#Identifies suspicious startup shell folder modifications to change the default Startup directory in order to bypass detections monitoring file creation in the Windows Startup folder.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2021/03/15"
integration = ["endpoint", "windows", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/05/03"
[rule]
author = ["Elastic"]
description = """
Identifies suspicious startup shell folder modifications to change the default Startup directory in order to bypass
detections monitoring file creation in the Windows Startup folder.
"""
from = "now-9m"
index = [
"logs-endpoint.events.registry-*",
"endgame-*",
"logs-windows.sysmon_operational-*",
"winlogbeat-*",
"logs-m365_defender.event-*",
"logs-sentinel_one_cloud_funnel.*",
"logs-crowdstrike.fdr*",
]
language = "eql"
license = "Elastic License v2"
name = "Suspicious Startup Shell Folder Modification"
references = [
"https://www.elastic.co/security-labs/elastic-security-uncovers-blister-malware-campaign",
"https://www.elastic.co/security-labs/revisiting-blister-new-developments-of-the-blister-loader",
]
risk_score = 73
rule_id = "c8b150f0-0164-475b-a75e-74b47800a9ff"
severity = "high"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Resources: Investigation Guide",
"Data Source: Elastic Endgame",
"Data Source: Elastic Defend",
"Data Source: Sysmon",
"Data Source: Microsoft Defender XDR",
"Data Source: SentinelOne",
"Data Source: Crowdstrike",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
registry where host.os.type == "windows" and event.type == "change" and
registry.value : ("Common Startup", "Startup") and
registry.path : (
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Common Startup",
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Common Startup",
"HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Startup",
"HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Startup",
"HKU\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Startup",
"HKU\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Startup",
"HKCU\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Startup",
"HKCU\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Startup",
"\\REGISTRY\\MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Common Startup",
"\\REGISTRY\\MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Common Startup",
"\\REGISTRY\\USER\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Startup",
"\\REGISTRY\\USER\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Startup",
"MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Common Startup",
"MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Common Startup",
"USER\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Startup",
"USER\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Startup"
) and
registry.data.strings != null and
/* Normal Startup Folder Paths */
not registry.data.strings : (
"C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
"%ProgramData%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
"%USERPROFILE%\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
"%%USERPROFILE%%\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
"C:\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
"\\\\*"
)
'''
note = """## Triage and analysis
### Investigating Suspicious Startup Shell Folder Modification
#### Possible investigation steps
- What shell-folder scope changed, and which local path now receives Startup items?
- Why: `registry.value` separates per-user "Startup" from all-users "Common Startup"; all-users scope broadens persistence beyond one profile.
- Focus: `registry.path`, `registry.value`, `registry.hive`, `registry.data.type`, `registry.data.strings`.
- Implication: escalate when `registry.data.strings` points to a user-writable, hidden, deceptive, or all-users local path; lower concern here only for a recognized managed redirection target, then continue through process and user/host checks.
- Which process and lineage changed the shell-folder value?
- Focus: `process.executable`, `process.command_line`, `process.parent.executable`, `process.parent.command_line`, `process.code_signature.subject_name`.
- Implication: escalate when the writer is a COM broker such as dllhost.exe, script host, LOLBin, renamed binary, user-writable executable, or unrelated parent chain; lower concern for management or packaging tooling only when command line and lineage explain this exact shell-folder write. Signed identity never clears the behavior by itself.
- Was a startup artifact staged or executed from the redirected path?
- Why: the registry change can be setup only; persistence is proven by startup content in the redirected directory, and delayed staging or value reversion can hide the chain.
- Focus: same-process activity, redirected-directory file events, and command lines referencing `registry.data.strings`.
- $investigate_0
- $investigate_1
- $investigate_2
- Hint: if file telemetry is available, check file-event writes to that directory; missing file-event visibility is unresolved, not benign.
- Implication: escalate when the modifier or later process writes, launches, or reverts around shortcuts, scripts, or binaries in the redirected directory.
- Does the creating identity and host context fit one recognized redirection workflow?
- Focus: `user.id`, `user.name`, `user.domain`, `host.id`, `host.name`.
- Implication: escalate when an interactive or ad hoc identity changes Startup resolution on a host that does not normally customize shell folders; lower concern only when identity, host cohort, path, and lineage converge on one recognized management or packaging workflow.
- If local evidence is suspicious or unresolved, does same-host activity change scope?
- Why: sibling autostart `registry.path` changes can preserve persistence if the redirected Startup folder is noticed, restored, or cleaned.
- Focus: use $investigate_3 for the same `host.id`, then filter for the exact `registry.data.strings` path, sibling autostart `registry.path` changes, and process starts referencing the redirected path.
- Implication: broaden response when the host shows additional shell-folder or Run-key changes, execution from the redirected path, or repeated attempts to use it; keep scope local only when the pivot finds no matching autostart or execution evidence.
- Do the path, process, payload-use, and context findings support startup-folder evasion?
- Implication: escalate for an unexpected process or actor, suspicious local path, shortcut/script/binary content, redirected-path execution, or same-host persistence/evasion; close only when telemetry narrows the case to one exact recognized workflow and outside confirmation verifies legitimacy where telemetry alone cannot; preserve and escalate when file visibility, process context, or workflow evidence is incomplete.
### False positive analysis
- Managed shell-folder redirection or application packaging can repoint "Startup" or "Common Startup" to a nondefault local path, but this is operationally sensitive. Treat these explanations as benign only when alert-window telemetry proves the exact redirected folder, process lineage, expected startup content, and managed host cohort all match one management or packaging job. Use deployment records, management configuration, packaging job logs, or owner confirmation when telemetry alone cannot prove legitimacy; do not close on a management label without this evidence.
- Before exceptioning, validate recurrence of the same `registry.value`, `registry.data.strings`, `process.executable`, `process.command_line`, `process.parent.executable`, `user.id`, and `host.id` pattern after confirming the benign workflow. Build the exception from that minimum workflow, and avoid exceptions on all Startup shell-folder modifications, the whole Explorer shell-folder key family, or the rule name alone.
### Response and remediation
- If confirmed benign, record the exact registry path/value/data, process lineage, `user.id`, and `host.id` pattern that proved the recognized workflow, then reverse temporary containment. Keep any exception narrow and require recurrence of that same workflow.
- If suspicious but unconfirmed, preserve the alert, Timeline or case exports, the current shell-folder value, process tree, command line, and redirected-directory contents or metadata when available before changing state. Apply reversible containment first, such as blocking execution from the redirected directory or increasing monitoring on the host. Restore the legitimate Startup path only after evidence capture, dependency review, and validation of the correct per-user or Common Startup path. Isolate the host only when payload execution or related alerts show active compromise.
- If confirmed malicious, collect staged shortcuts, scripts, binaries, hashes, and registry evidence before eradication. Contain the endpoint when its role allows, contain the creating account when the evidence shows account misuse, validate the correct per-user or Common Startup value, restore that value, and remove only the artifacts identified in the investigation. If direct response is unavailable, escalate with the preserved evidence to the team that can act on the host.
- Before cleanup, review other user profiles and the all-users Startup scope for the same redirected path, then verify no process execution still points to that directory. After recovery, restrict shell-folder redirection to controlled management tooling, retain registry/process and available file telemetry needed to connect redirection to later payload staging, and document delayed-staging or value-reversion blind spots for future cases.
"""
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 Registry Events](https://ela.st/sysmon-event-reg-setup)
"""
[rule.investigation_fields]
field_names = [
"@timestamp",
"host.id",
"user.id",
"process.entity_id",
"process.pid",
"process.executable",
"process.command_line",
"process.parent.executable",
"process.parent.command_line",
"process.code_signature.subject_name",
"registry.path",
"registry.hive",
"registry.value",
"registry.data.type",
"registry.data.strings",
]
[transform]
[[transform.investigate]]
label = "Activity from this process instance on this host"
description = ""
providers = [
[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
],
[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
]
]
relativeFrom = "now-24h/h"
relativeTo = "now"
[[transform.investigate]]
label = "File events in the redirected Startup path"
description = ""
providers = [
[
{ excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" },
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "file.directory", queryType = "phrase", value = "{{registry.data.strings}}", valueType = "string" }
]
]
relativeFrom = "now-24h/h"
relativeTo = "now"
[[transform.investigate]]
label = "Process command lines referencing the redirected path"
description = ""
providers = [
[
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.command_line", queryType = "phrase", value = "{{registry.data.strings}}", valueType = "string" }
]
]
relativeFrom = "now-24h/h"
relativeTo = "now"
[[transform.investigate]]
label = "Recent activity on this host"
description = ""
providers = [
[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
]
]
relativeFrom = "now-48h/h"
relativeTo = "now"
[[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 = "T1112"
name = "Modify Registry"
reference = "https://attack.mitre.org/techniques/T1112/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Stage 1: registry
registry where host.os.type == "windows" and event.type == "change" and
registry.value : ("Common Startup", "Startup") and
registry.path : (
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Common Startup",
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Common Startup",
"HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Startup",
"HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Startup",
"HKU\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Startup",
"HKU\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Startup",
"HKCU\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Startup",
"HKCU\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Startup",
"\\REGISTRY\\MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Common Startup",
"\\REGISTRY\\MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Common Startup",
"\\REGISTRY\\USER\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Startup",
"\\REGISTRY\\USER\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Startup",
"MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Common Startup",
"MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Common Startup",
"USER\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Startup",
"USER\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Startup"
) and
registry.data.strings != null and
not registry.data.strings : (
"C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
"%ProgramData%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
"%USERPROFILE%\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
"%%USERPROFILE%%\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
"C:\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
"\\\\*"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"change" |
registry.data.strings | is_not_null | field:"Details" kind:is_not_null | |
registry.path | wildcard |
| field:"TargetObject" kind:wildcard |
registry.value | wildcard |
| field:"registry_value_name" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
registry.data.strings | wildcard | C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup, %ProgramData%\Microsoft\Windows\Start Menu\Programs\Startup, %USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup, %%USERPROFILE%%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup, C:\Users\*\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup, \\* | excludes:registry.data.strings |
Systemd Service Override Configuration File Created
#This rule detects the creation or renaming of a new Systemd override configuration file in any of the Systemd service locations for both root and regular users. Systemd override configuration files are configuration files in Linux systems used to override the default Systemd service configuration for a specific service. Malicious actors can leverage systemd override configuration files to achieve persistence by creating or modifying services to execute malicious commands or payloads during system startup or at a predefined interval by adding a systemd timer. This allows them to maintain unauthorized access, execute additional malicious activities, or evade detection.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Privilege Escalation |
Rule Body
[metadata]
creation_date = "2026/06/05"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/06/05"
[rule]
author = ["Elastic"]
description = """
This rule detects the creation or renaming of a new Systemd override configuration file in any
of the Systemd service locations for both root and regular users. Systemd override configuration
files are configuration files in Linux systems used to override the default Systemd service
configuration for a specific service. Malicious actors can leverage systemd override configuration
files to achieve persistence by creating or modifying services to execute malicious commands or
payloads during system startup or at a predefined interval by adding a systemd timer. This allows
them to maintain unauthorized access, execute additional malicious activities, or evade detection.
"""
from = "now-9m"
index = ["logs-endpoint.events.file*"]
language = "eql"
license = "Elastic License v2"
name = "Systemd Service Override Configuration File Created"
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 Systemd Service Override Configuration File Created
This alert fires when a new systemd service override file appears in standard system or user service directories, which can silently change how a service starts and make malicious behavior survive reboots or user logins. An attacker might drop an override for sshd.service or a common daemon to add an ExecStartPre or timer-triggered command that launches a backdoor every boot while leaving the original unit intact.
### Possible investigation steps
- Open the new override and compare it with the base unit and any recent approved change, focusing on directives like ExecStart, ExecStartPre, ExecStartPost, Environment, User, WorkingDirectory, OnCalendar, and WantedBy that could introduce persistence or alter privileges.
- Trace the creation back to the initiating binary, parent process chain, account, and session context to determine whether it originated from expected package management or configuration automation versus an interactive shell, script, or unknown tool.
- Review nearby host activity for `systemctl daemon-reload`, `enable`, `start`, `restart`, or timer operations, then verify whether the affected service or timer loaded the override and launched any newly referenced command.
- Examine any scripts, binaries, environment files, sockets, or network destinations referenced by the override for newly dropped or suspicious content, and hunt for similar override files on the same host and peer systems to assess spread.
### False positive analysis
- A system administrator may legitimately create `/etc/systemd/system/<service>.d/override.conf` during maintenance to change startup order, resource limits, or environment settings for a supported service, so verify a corresponding approved change and confirm the creating process and user session map to expected administrative activity.
- A user or root account may create a user-level `override.conf` under `~/.config/systemd/user/` or `~/.local/share/systemd/user/` to customize a legitimate per-user service, so confirm the file owner matches the affected account and that any `Exec*` or `Environment` entries reference the expected application path and business use.
### Response and remediation
- Isolate the affected Linux host from the network while keeping it powered on, preserve the malicious `override.conf`, the base unit file, any referenced scripts or binaries, and the output of `systemctl cat <service>` and `systemctl status <service>` for evidence and scoping.
- Remove attacker persistence by disabling and stopping the altered service or timer, deleting the malicious drop-in directory or `override.conf`, reversing any added `Exec*`, `Environment`, or `OnCalendar` directives, and running `systemctl daemon-reload` before confirming the unit now matches the approved baseline.
- Search the host and peer systems for additional drop-ins under `/etc/systemd/system`, `/usr/lib/systemd/system`, and user service paths, then quarantine any newly referenced payloads, kill related processes, and block their hashes or paths in endpoint controls.
- Restore the system to a known-good state by reinstalling or replacing any modified unit files, scripts, and binaries from trusted packages or backups, rotating credentials and secrets used by the affected service account, and rebuilding the host if integrity cannot be confidently verified.
- Escalate to incident response immediately if the override modified a high-value service such as `sshd`, a security agent, or a network-facing daemon, if root-level user service paths were abused, or if the same persistence appears on multiple hosts, because these signs indicate broader compromise.
- Harden the environment by restricting write access to systemd service directories, tightening sudo and configuration-management permissions, enforcing file integrity monitoring on `*.service.d/override.conf`, and alerting on unauthorized `systemctl enable`, `daemon-reload`, and service or timer changes.
"""
risk_score = 47
rule_id = "9e8c185c-8237-4b13-a4da-4a8d4e9bb6ef"
setup = """## Setup
This rule requires data coming in from Elastic Defend.
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Tactic: Privilege Escalation",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
file where host.os.type == "linux" and event.action in ("rename", "creation") and
file.extension == "conf" and file.path like (
"/etc/systemd/system/*.d/*.conf", "/etc/systemd/user/*.d/*.conf", "/usr/local/lib/systemd/system/*.d/*.conf",
"/lib/systemd/system/*.d/*.conf", "/usr/lib/systemd/system/*.d/*.conf", "/usr/lib/systemd/user/*.d/*.conf",
"/home/*/.config/systemd/user/*.d/*.conf", "/home/*/.local/share/systemd/user/*.d/*.conf",
"/root/.config/systemd/user/*.d/*.conf", "/root/.local/share/systemd/user/*.d/*.conf",
"/run/systemd/system/*.d/*.conf", "/var/run/systemd/system/*.d/*.conf"
) and
not process.executable in (
"/bin/dpkg", "/usr/bin/dpkg", "/bin/dockerd", "/usr/bin/dockerd", "/usr/sbin/dockerd", "/bin/microdnf",
"/usr/bin/microdnf", "/bin/rpm", "/usr/bin/rpm", "/bin/snapd", "/usr/bin/snapd", "/bin/yum", "/usr/bin/yum",
"/bin/dnf", "/usr/bin/dnf", "/bin/podman", "/usr/bin/podman", "/bin/dnf-automatic", "/usr/bin/dnf-automatic",
"/usr/bin/dpkg-divert", "/bin/dpkg-divert", "/sbin/apk", "/usr/sbin/apk", "/usr/local/sbin/apk", "/usr/bin/dnf5",
"/usr/bin/apt", "/usr/bin/puppet", "/bin/puppet", "/opt/puppetlabs/puppet/bin/puppet", "/usr/bin/pacman",
"/usr/bin/chef-client", "/bin/chef-client", "/usr/bin/pamac-daemon", "/bin/pamac-daemon", "/usr/local/bin/dockerd",
"/usr/bin/crio", "/usr/bin/podman", "/usr/bin/tdnf", "/usr/bin/apk"
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"
[[rule.threat.technique.subtechnique]]
id = "T1543.002"
name = "Systemd Service"
reference = "https://attack.mitre.org/techniques/T1543/002/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"
[[rule.threat.technique.subtechnique]]
id = "T1543.002"
name = "Systemd Service"
reference = "https://attack.mitre.org/techniques/T1543/002/"
[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
Stages and Predicates
Stage 1: file
file where host.os.type == "linux" and event.action in ("rename", "creation") and
file.extension == "conf" and file.path like (
"/etc/systemd/system/*.d/*.conf", "/etc/systemd/user/*.d/*.conf", "/usr/local/lib/systemd/system/*.d/*.conf",
"/lib/systemd/system/*.d/*.conf", "/usr/lib/systemd/system/*.d/*.conf", "/usr/lib/systemd/user/*.d/*.conf",
"/home/*/.config/systemd/user/*.d/*.conf", "/home/*/.local/share/systemd/user/*.d/*.conf",
"/root/.config/systemd/user/*.d/*.conf", "/root/.local/share/systemd/user/*.d/*.conf",
"/run/systemd/system/*.d/*.conf", "/var/run/systemd/system/*.d/*.conf"
) and
not process.executable in (
"/bin/dpkg", "/usr/bin/dpkg", "/bin/dockerd", "/usr/bin/dockerd", "/usr/sbin/dockerd", "/bin/microdnf",
"/usr/bin/microdnf", "/bin/rpm", "/usr/bin/rpm", "/bin/snapd", "/usr/bin/snapd", "/bin/yum", "/usr/bin/yum",
"/bin/dnf", "/usr/bin/dnf", "/bin/podman", "/usr/bin/podman", "/bin/dnf-automatic", "/usr/bin/dnf-automatic",
"/usr/bin/dpkg-divert", "/bin/dpkg-divert", "/sbin/apk", "/usr/sbin/apk", "/usr/local/sbin/apk", "/usr/bin/dnf5",
"/usr/bin/apt", "/usr/bin/puppet", "/bin/puppet", "/opt/puppetlabs/puppet/bin/puppet", "/usr/bin/pacman",
"/usr/bin/chef-client", "/bin/chef-client", "/usr/bin/pamac-daemon", "/bin/pamac-daemon", "/usr/local/bin/dockerd",
"/usr/bin/crio", "/usr/bin/podman", "/usr/bin/tdnf", "/usr/bin/apk"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | in |
| field:"EventType" kind:in |
file.extension | eq |
| field:"file.extension" kind:eq value:"conf" |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.executable | in | /bin/chef-client, /bin/dnf, /bin/dnf-automatic, /bin/dockerd, /bin/dpkg, /bin/dpkg-divert, /bin/microdnf, /bin/pamac-daemon, /bin/podman, /bin/puppet, /bin/rpm, /bin/snapd, /bin/yum, /opt/puppetlabs/puppet/bin/puppet, /sbin/apk, /usr/bin/apk, /usr/bin/apt, /usr/bin/chef-client, /usr/bin/crio, /usr/bin/dnf, /usr/bin/dnf-automatic, /usr/bin/dnf5, /usr/bin/dockerd, /usr/bin/dpkg, /usr/bin/dpkg-divert, /usr/bin/microdnf, /usr/bin/pacman, /usr/bin/pamac-daemon, /usr/bin/podman, /usr/bin/puppet, /usr/bin/rpm, /usr/bin/snapd, /usr/bin/tdnf, /usr/bin/yum, /usr/local/bin/dockerd, /usr/local/sbin/apk, /usr/sbin/apk, /usr/sbin/dockerd | excludes:process.executable |
Third-party Backup Files Deleted via Unexpected Process
#Identifies the deletion of backup files, saved using third-party software, by a process outside of the backup suite. Adversaries may delete Backup files to ensure that recovery from a ransomware attack is less likely.
Known False Positives
- Certain utilities that delete files for disk cleanup or Administrators manually removing backup files.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Impact |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2021/10/01"
integration = ["endpoint", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2026/05/04"
[rule]
author = ["Elastic"]
description = """
Identifies the deletion of backup files, saved using third-party software, by a process outside of the backup suite.
Adversaries may delete Backup files to ensure that recovery from a ransomware attack is less likely.
"""
false_positives = [
"Certain utilities that delete files for disk cleanup or Administrators manually removing backup files.",
]
from = "now-9m"
index = ["logs-endpoint.events.file-*", "logs-sentinel_one_cloud_funnel.*"]
language = "eql"
license = "Elastic License v2"
name = "Third-party Backup Files Deleted via Unexpected Process"
note = """## Triage and analysis
### Investigating Third-party Backup Files Deleted via Unexpected Process
Backups are a significant obstacle for any ransomware operation. They allow the victim to resume business by performing data recovery, making them a valuable target.
Attackers can delete backups from the host and gain access to backup servers to remove centralized backups for the environment, ensuring that victims have no alternatives to paying the ransom.
This rule identifies file deletions performed by a process that does not belong to the backup suite and aims to delete Veritas or Veeam backups.
#### Possible investigation steps
- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.
- Identify the user account that performed the action and whether it should perform this kind of action.
- Contact the account owner and confirm whether they are aware of this activity.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Check if any files on the host machine have been encrypted.
### False positive analysis
- This rule can be triggered by the manual removal of backup files and by removal using other third-party tools that are not from the backup suite. Exceptions can be added for specific accounts and executables, preferably tied together.
### Related rules
- Deleting Backup Catalogs with Wbadmin - 581add16-df76-42bb-af8e-c979bfb39a59
- Volume Shadow Copy Deleted or Resized via VssAdmin - b5ea4bfe-a1b2-421f-9d47-22a75a6f2921
- Volume Shadow Copy Deletion via PowerShell - d99a037b-c8e2-47a5-97b9-170d076827c4
- Volume Shadow Copy Deletion via WMIC - dc9c1f74-dac3-48e3-b47f-eb79db358f57
### Response and remediation
- Initiate the incident response process based on the outcome of the 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.
- Consider isolating the involved host to prevent destructive behavior, which is commonly associated with this activity.
- Perform data recovery locally or restore the backups from replicated copies (Cloud, other servers, etc.).
- 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)
"""
references = ["https://www.advintel.io/post/backup-removal-solutions-from-conti-ransomware-with-love"]
risk_score = 47
rule_id = "11ea6bec-ebde-4d71-a8e9-784948f8e3e9"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Impact",
"Resources: Investigation Guide",
"Data Source: Elastic Defend",
"Data Source: SentinelOne",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
file where host.os.type == "windows" and event.type == "deletion" and
(
/* Veeam Related Backup Files */
(
file.extension : ("VBK", "VIB", "VBM") and
not (
process.executable : ("?:\\Windows\\*", "?:\\Program Files\\*", "?:\\Program Files (x86)\\*") and
(process.code_signature.trusted == true and process.code_signature.subject_name : ("Veeam Software Group GmbH", "Veeam Software AG"))
)
) or
/* Veritas Backup Exec Related Backup File */
(
file.extension : "BKF" and
not process.executable : (
"?:\\Program Files\\Veritas\\Backup Exec\\*",
"?:\\Program Files (x86)\\Veritas\\Backup Exec\\*"
)
)
) and
not (
process.name : ("MSExchangeMailboxAssistants.exe", "Microsoft.PowerBI.EnterpriseGateway.exe") and
(process.code_signature.subject_name : "Microsoft Corporation" and process.code_signature.trusted == true)
) and
not file.path : (
"?:\\ProgramData\\Trend Micro\\*",
"?:\\Program Files (x86)\\Trend Micro\\*",
"?:\\$RECYCLE.BIN\\*"
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1485"
name = "Data Destruction"
reference = "https://attack.mitre.org/techniques/T1485/"
[[rule.threat.technique]]
id = "T1490"
name = "Inhibit System Recovery"
reference = "https://attack.mitre.org/techniques/T1490/"
[rule.threat.tactic]
id = "TA0040"
name = "Impact"
reference = "https://attack.mitre.org/tactics/TA0040/"
Stages and Predicates
Stage 1: file
file where host.os.type == "windows" and event.type == "deletion" and
(
(
file.extension : ("VBK", "VIB", "VBM") and
not (
process.executable : ("?:\\Windows\\*", "?:\\Program Files\\*", "?:\\Program Files (x86)\\*") and
(process.code_signature.trusted == true and process.code_signature.subject_name : ("Veeam Software Group GmbH", "Veeam Software AG"))
)
) or
(
file.extension : "BKF" and
not process.executable : (
"?:\\Program Files\\Veritas\\Backup Exec\\*",
"?:\\Program Files (x86)\\Veritas\\Backup Exec\\*"
)
)
) and
not (
process.name : ("MSExchangeMailboxAssistants.exe", "Microsoft.PowerBI.EnterpriseGateway.exe") and
(process.code_signature.subject_name : "Microsoft Corporation" and process.code_signature.trusted == true)
) and
not file.path : (
"?:\\ProgramData\\Trend Micro\\*",
"?:\\Program Files (x86)\\Trend Micro\\*",
"?:\\$RECYCLE.BIN\\*"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"deletion" |
file.extension | wildcard |
| field:"file.extension" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.code_signature.subject_name | eq | Microsoft Corporation | excludes:process.code_signature.subject_name field:"process.code_signature.subject_name" value:"Microsoft Corporation" |
process.code_signature.trusted | eq | true | excludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true" |
process.name | eq | MSExchangeMailboxAssistants.exe, Microsoft.PowerBI.EnterpriseGateway.exe | excludes:process.name field:"process.name" value:"MSExchangeMailboxAssistants.exe" field:"process.name" value:"Microsoft.PowerBI.EnterpriseGateway.exe" |
file.path | starts_with | ?:\ProgramData\Trend Micro\, ?:\Program Files (x86)\Trend Micro\, ?:\$RECYCLE.BIN\ | excludes:file.path field:"file.path" value:"?:\ProgramData\Trend Micro\" field:"file.path" value:"?:\Program Files (x86)\Trend Micro\" field:"file.path" value:"?:\$RECYCLE.BIN\" |
UAC Bypass Attempt via MMC DLL Search Order Hijacking
#Identifies attempts to bypass User Account Control (UAC) via DLL search order hijacking by setting the .NET Core profiler environment variable to force MMC loading a malicious DLL. Attackers may attempt to bypass UAC to stealthily execute code with elevated permissions.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Privilege Escalation | |
| Stealth |
Rule Body
[rule]
description = """
Identifies attempts to bypass User Account Control (UAC) via DLL search order hijacking by setting the .NET Core
profiler environment variable to force MMC loading a malicious DLL. Attackers may attempt to bypass UAC to stealthily
execute code with elevated permissions.
"""
id = "28996098-b9be-4aa8-a1f3-4923c84b2649"
license = "Elastic License v2"
name = "UAC Bypass Attempt via MMC DLL Search Order Hijacking"
os_list = ["windows"]
reference = ["https://github.com/hfiref0x/UACME"]
version = "1.0.32"
query = '''
sequence with maxspan=60s
[registry where
registry.path :
("HKEY_USERS\\S-1-5-21*\\Environment\\COR_PROFILER_PATH",
"HKEY_USERS\\S-1-12-1-*\\Environment\\COR_PROFILER_PATH") and
registry.data.strings : "*.dll"]
[process where event.action == "start" and process.name : "mmc.exe"]
[process where event.action == "start" and
process.parent.name : "mmc.exe" and process.Ext.token.integrity_level_name == "high" and
not process.executable :
("?:\\Windows\\System32\\WerFault.exe",
"?:\\Windows\\SysWOW64\\WerFault.exe")]
'''
min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 2
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 2
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1548"
name = "Abuse Elevation Control Mechanism"
reference = "https://attack.mitre.org/techniques/T1548/"
[[threat.technique.subtechnique]]
id = "T1548.002"
name = "Bypass User Account Control"
reference = "https://attack.mitre.org/techniques/T1548/002/"
[threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"
[[threat.technique.subtechnique]]
id = "T1574.001"
name = "DLL"
reference = "https://attack.mitre.org/techniques/T1574/001/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: registry
[registry where
registry.path :
("HKEY_USERS\\S-1-5-21*\\Environment\\COR_PROFILER_PATH",
"HKEY_USERS\\S-1-12-1-*\\Environment\\COR_PROFILER_PATH") and
registry.data.strings : "*.dll"]
Stage 2: process
[process where event.action == "start" and process.name : "mmc.exe"]
Stage 3: process
[process where event.action == "start" and
process.parent.name : "mmc.exe" and process.Ext.token.integrity_level_name == "high" and
not process.executable :
("?:\\Windows\\System32\\WerFault.exe",
"?:\\Windows\\SysWOW64\\WerFault.exe")]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.Ext.token.integrity_level_name | eq |
| field:"process.Ext.token.integrity_level_name" kind:eq value:"high" |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:"mmc.exe" |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard value:"mmc.exe" |
registry.data.strings | wildcard |
| field:"Details" kind:wildcard value:"*.dll" |
registry.path | wildcard |
| field:"TargetObject" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.executable | eq | ?:\Windows\System32\WerFault.exe, ?:\Windows\SysWOW64\WerFault.exe | excludes:process.executable field:"process.executable" value:"?:\Windows\System32\WerFault.exe" field:"process.executable" value:"?:\Windows\SysWOW64\WerFault.exe" |
Unusual Source IP for a User to Logon from
#A machine learning job detected a user logging in from an IP address that is unusual for the user. This can be due to credentialed access via a compromised account when the user and the threat actor are in different locations. An unusual source IP address for a username could also be due to lateral movement when a compromised account is used to pivot between hosts.
Known False Positives
- Business travelers who roam to new locations may trigger this alert.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Lateral Movement |
Rule Body
[metadata]
creation_date = "2021/06/10"
integration = ["auditd_manager", "endpoint", "system"]
maturity = "production"
min_stack_version = "9.4.0"
min_stack_comments = "Use EA (Entity Analytics) fields"
updated_date = "2026/07/27"
[rule]
anomaly_threshold = 75
author = ["Elastic"]
description = """
A machine learning job detected a user logging in from an IP address that is unusual for the user. This can be due to
credentialed access via a compromised account when the user and the threat actor are in different locations. An unusual
source IP address for a username could also be due to lateral movement when a compromised account is used to pivot
between hosts.
"""
false_positives = ["Business travelers who roam to new locations may trigger this alert."]
from = "now-30m"
interval = "15m"
license = "Elastic License v2"
machine_learning_job_id = "auth_rare_source_ip_for_a_user_ea"
name = "Unusual Source IP for a User to Logon from"
setup = """## Setup
This rule requires the installation of associated Machine Learning jobs, as well as data coming in from one of the following integrations:
- Elastic Defend
- Auditd Manager
- System
### Anomaly Detection Setup
Once the rule is enabled, the associated Machine Learning job will start automatically. You can view the Machine Learning job linked under the "Definition" panel of the detection rule. If the job does not start due to an error, the issue must be resolved for the job to commence successfully. For more details on setting up anomaly detection jobs, refer to the [helper guide](https://www.elastic.co/guide/en/kibana/current/xpack-ml-anomalies.html).
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration to your system:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/current/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
### Auditd Manager Integration Setup
The Auditd Manager Integration receives audit events from the Linux Audit Framework which is a part of the Linux kernel.
Auditd Manager provides a user-friendly interface and automation capabilities for configuring and monitoring system auditing through the auditd daemon. With `auditd_manager`, administrators can easily define audit rules, track system events, and generate comprehensive audit reports, improving overall security and compliance in the system.
#### The following steps should be executed in order to add the Elastic Agent System integration "auditd_manager" to your system:
- Go to the Kibana home page and click “Add integrations”.
- In the query bar, search for “Auditd Manager” and select the integration to see more details about it.
- Click “Add Auditd Manager”.
- Configure the integration name and optionally add a description.
- Review optional and advanced settings accordingly.
- Add the newly installed “auditd manager” to an existing or a new agent policy, and deploy the agent on a Linux system from which auditd log files are desirable.
- Click “Save and Continue”.
- For more details on the integration refer to the [helper guide](https://docs.elastic.co/integrations/auditd_manager).
#### Rule Specific Setup Note
Auditd Manager subscribes to the kernel and receives events as they occur without any additional configuration.
However, if more advanced configuration is required to detect specific behavior, audit rules can be added to the integration in either the "audit rules" configuration box or the "auditd rule files" box by specifying a file to read the audit rules from.
- For this detection rule no additional audit rules are required.
### System Integration Setup
The System integration allows you to collect system logs and metrics from your servers with Elastic Agent.
#### The following steps should be executed in order to add the Elastic Agent System integration "system" to your system:
- Go to the Kibana home page and click “Add integrations”.
- In the query bar, search for “System” and select the integration to see more details about it.
- Click “Add System”.
- Configure the integration name and optionally add a description.
- Review optional and advanced settings accordingly.
- Add the newly installed “system” to an existing or a new agent policy, and deploy the agent on your system from which system log files are desirable.
- Click “Save and Continue”.
- For more details on the integration refer to the [helper guide](https://docs.elastic.co/integrations/system).
"""
references = ["https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html"]
risk_score = 21
rule_id = "d4b73fa0-9d43-465e-b8bf-50230da6718b"
severity = "low"
tags = [
"Data Source: Elastic Defend",
"Data Source: Auditd Manager",
"Data Source: Windows Security Event Logs",
"Use Case: Identity and Access Audit",
"Use Case: Threat Detection",
"Rule Type: ML",
"Rule Type: Machine Learning",
"Tactic: Initial Access",
"Resources: Investigation Guide",
]
type = "machine_learning"
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Unusual Source IP for a User to Logon from
Machine learning models analyze login patterns to identify atypical IP addresses for users, which may indicate compromised accounts or lateral movement by threat actors. Adversaries exploit valid credentials to access systems from unexpected locations. This detection rule flags such anomalies, aiding in early identification of unauthorized access attempts, thereby enhancing security posture.
### Possible investigation steps
- Review the login details to identify the unusual source IP address and compare it with the user's typical login locations and times.
- Check the geolocation of the unusual IP address to determine if it aligns with any known travel or business activities of the user.
- Analyze the user's recent activity logs to identify any other suspicious behavior or anomalies that might indicate account compromise.
- Investigate if there are any other users or systems that have logged in from the same unusual IP address, which could suggest lateral movement.
- Contact the user to verify if they recognize the login activity and if they have recently traveled or used a VPN that might explain the unusual IP address.
- Cross-reference the unusual IP address with threat intelligence sources to determine if it is associated with known malicious activity.
### False positive analysis
- Users frequently traveling or working remotely may trigger false positives due to legitimate logins from various locations. To manage this, create exceptions for known travel patterns or remote work IP ranges.
- Employees using VPNs or proxy services can appear to log in from unusual IP addresses. Identify and whitelist IP ranges associated with company-approved VPNs or proxies.
- Shared accounts used by multiple users across different locations can generate alerts. Implement stricter access controls or assign unique credentials to each user to reduce false positives.
- Automated systems or scripts that log in from different IP addresses might be flagged. Document and exclude these systems from the rule if they are verified as non-threatening.
- Regularly review and update the list of excluded IP addresses to ensure that only legitimate exceptions are maintained, reducing the risk of overlooking genuine threats.
### Response and remediation
- Immediately isolate the affected user account by disabling it to prevent further unauthorized access.
- Conduct a password reset for the compromised account and ensure the new password adheres to strong security policies.
- Review and terminate any active sessions associated with the unusual IP address to cut off any ongoing unauthorized access.
- Analyze logs to identify any lateral movement or additional compromised accounts and isolate those accounts as necessary.
- Notify the user of the suspicious activity and verify if they recognize the unusual IP address or if they have recently traveled.
- Escalate the incident to the security operations team for further investigation and to determine if additional systems or accounts have been affected.
- Implement IP whitelisting or geofencing rules to restrict access from unexpected locations, enhancing future detection and prevention."""
[[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 = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1021"
name = "Remote Services"
reference = "https://attack.mitre.org/techniques/T1021/"
[rule.threat.tactic]
id = "TA0008"
name = "Lateral Movement"
reference = "https://attack.mitre.org/tactics/TA0008/"
Unusual SSHD Child Process
#This rule detects the creation of an unusual SSHD child process through the usage of the "new_terms" rule type. Attackers may abuse SSH to maintain persistence on a compromised system, or to establish a backdoor for remote access, potentially resulting in an unusual SSHD child process being created.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Persistence | |
| Lateral Movement |
Rule Body
[metadata]
creation_date = "2024/12/16"
integration = ["endpoint", "crowdstrike"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
This rule detects the creation of an unusual SSHD child process through the usage of the "new_terms" rule type.
Attackers may abuse SSH to maintain persistence on a compromised system, or to establish a backdoor for remote access,
potentially resulting in an unusual SSHD child process being created.
"""
from = "now-9m"
index = ["logs-endpoint.events.process*", "logs-crowdstrike.fdr*"]
language = "kuery"
license = "Elastic License v2"
name = "Unusual SSHD Child Process"
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Unusual SSHD Child Process
Secure Shell (SSH) is a protocol used to securely access remote systems. Adversaries may exploit SSH to maintain persistence or create backdoors by spawning unexpected child processes. The detection rule identifies anomalies by monitoring process creation events where SSH or SSHD is the parent, focusing on atypical command-line arguments, which may indicate malicious activity.
### Possible investigation steps
- Review the process command line arguments for the unusual SSHD child process to identify any suspicious or unexpected commands that could indicate malicious activity.
- Check the user account associated with the SSHD child process to determine if it is a legitimate user or if there are signs of compromise, such as unusual login times or locations.
- Investigate the parent process (SSH or SSHD) to understand the context of the connection, including the source IP address and any associated user activity, to assess if it aligns with expected behavior.
- Examine the process tree to identify any subsequent processes spawned by the unusual SSHD child process, which may provide further insight into the attacker's actions or objectives.
- Correlate the event with other security logs and alerts from the same host or network segment to identify any related suspicious activities or patterns that could indicate a broader attack campaign.
### False positive analysis
- Legitimate administrative scripts or automation tools may trigger this rule if they execute commands with SSH or SSHD as the parent process. To handle this, identify and document these scripts, then create exceptions for their specific command-line patterns.
- System maintenance tasks or updates that involve SSH connections might appear as unusual child processes. Regularly review and whitelist these known maintenance activities to prevent unnecessary alerts.
- Custom user environments or shell configurations that deviate from standard shells like bash, zsh, or sh could be flagged. Analyze these configurations and exclude them if they are verified as non-threatening.
- Monitoring tools or security solutions that interact with SSH sessions for logging or auditing purposes might generate alerts. Verify these tools' behavior and exclude their processes if they are part of legitimate monitoring activities.
### Response and remediation
- Immediately isolate the affected system from the network to prevent further unauthorized access or lateral movement by the adversary.
- Terminate any suspicious SSHD child processes identified by the alert to halt potential malicious activities.
- Conduct a thorough review of SSH configuration files and access logs to identify unauthorized changes or access patterns, and revert any unauthorized modifications.
- Change all SSH keys and credentials associated with the compromised system to prevent further unauthorized access.
- Implement additional monitoring on the affected system and related network segments to detect any further suspicious activities or attempts to re-establish persistence.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if other systems may be affected.
- Review and update firewall rules and access controls to restrict SSH access to only trusted IP addresses and users, reducing the attack surface for future incidents."""
references = ["https://hadess.io/the-art-of-linux-persistence/"]
risk_score = 21
rule_id = "4c3c6c47-e38f-4944-be27-5c80be973bd7"
severity = "low"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
"Data Source: Crowdstrike",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
event.category:process and host.os.type:linux and event.type:start and event.action:(exec or ProcessRollup2) and
process.parent.name:sshd and process.args_count:2 and process.parent.args:"-D" and
not (
process.command_line:(-bash or -zsh or -sh) or
process.name:(ractrans or exectask or tty or tput or ferny-askpass or id or ip) or
process.executable:/var/tmp/foreman-ssh-cmd*/script
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1133"
name = "External Remote Services"
reference = "https://attack.mitre.org/techniques/T1133/"
[[rule.threat.technique]]
id = "T1546"
name = "Event Triggered Execution"
reference = "https://attack.mitre.org/techniques/T1546/"
[[rule.threat.technique.subtechnique]]
id = "T1546.004"
name = "Unix Shell Configuration Modification"
reference = "https://attack.mitre.org/techniques/T1546/004/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1021"
name = "Remote Services"
reference = "https://attack.mitre.org/techniques/T1021/"
[[rule.threat.technique.subtechnique]]
id = "T1021.004"
name = "SSH"
reference = "https://attack.mitre.org/techniques/T1021/004/"
[[rule.threat.technique]]
id = "T1563"
name = "Remote Service Session Hijacking"
reference = "https://attack.mitre.org/techniques/T1563/"
[[rule.threat.technique.subtechnique]]
id = "T1563.001"
name = "SSH Hijacking"
reference = "https://attack.mitre.org/techniques/T1563/001/"
[rule.threat.tactic]
id = "TA0008"
name = "Lateral Movement"
reference = "https://attack.mitre.org/tactics/TA0008/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[rule.threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1133"
name = "External Remote Services"
reference = "https://attack.mitre.org/techniques/T1133/"
[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[rule.new_terms]
field = "new_terms_fields"
value = ["process.executable"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-5d"
Stages and Predicates
Stage 1: new_terms
event.category:process and host.os.type:linux and event.type:start and event.action:(exec or ProcessRollup2) and
process.parent.name:sshd and process.args_count:2 and process.parent.args:"-D" and
not (
process.command_line:(-bash or -zsh or -sh) or
process.name:(ractrans or exectask or tty or tput or ferny-askpass or id or ip) or
process.executable:/var/tmp/foreman-ssh-cmd*/script
)
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.command_line | in | -bash, -sh, -zsh | excludes:process.command_line field:"process.command_line" value:"-bash" field:"process.command_line" value:"-sh" field:"process.command_line" value:"-zsh" |
process.executable | wildcard | /var/tmp/foreman-ssh-cmd*/script | excludes:process.executable field:"process.executable" value:"/var/tmp/foreman-ssh-cmd*/script" |
process.name | in | exectask, ferny-askpass, id, ip, ractrans, tput, tty | excludes:process.name |