Detection rules › Elastic
Elastic rules: 3d
AWS Bedrock Resource-Based Policy Modified or Deleted
#Detects modification or deletion of resource-based access policies on AWS Bedrock resources via the PutResourcePolicy and DeleteResourcePolicy API calls. Resource-based policies govern which principals (including external accounts) may access Bedrock resources such as agents, knowledge bases, and custom models. An adversary may attach a resource policy granting an external or unexpected principal access to a Bedrock resource to establish persistence or enable cross-account access, or may delete an existing policy to weaken access controls. These changes should be validated for principal ownership and least-privilege intent.
Known False Positives
- Resource policy changes may be performed by administrators, infrastructure-as-code pipelines, or automation during legitimate onboarding, sharing, or access-management activities. Verify whether the user identity, user agent, and source IP are expected to manage Bedrock resource policies in your environment. Known automation can be exempted from the rule.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence |
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
Rule Body
[metadata]
creation_date = "2026/06/04"
integration = ["aws"]
maturity = "production"
updated_date = "2026/06/04"
[rule]
author = ["Elastic"]
description = """
Detects modification or deletion of resource-based access policies on AWS Bedrock resources via the PutResourcePolicy
and DeleteResourcePolicy API calls. Resource-based policies govern which principals (including external accounts) may
access Bedrock resources such as agents, knowledge bases, and custom models. An adversary may attach a resource policy
granting an external or unexpected principal access to a Bedrock resource to establish persistence or enable
cross-account access, or may delete an existing policy to weaken access controls. These changes should be validated for
principal ownership and least-privilege intent.
"""
false_positives = [
"""
Resource policy changes may be performed by administrators, infrastructure-as-code pipelines, or automation during
legitimate onboarding, sharing, or access-management activities. Verify whether the user identity, user agent, and
source IP are expected to manage Bedrock resource policies in your environment. Known automation can be exempted
from the rule.
""",
]
from = "now-6m"
index = ["logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS Bedrock Resource-Based Policy Modified or Deleted"
note = """## Triage and analysis
### Investigating AWS Bedrock Resource-Based Policy Modified or Deleted
AWS Bedrock resource-based policies control which principals can access Bedrock resources such as agents,
knowledge bases, and custom models. Adversaries can attach a policy that grants an external principal
access for persistence or cross-account access, or delete a policy to break existing access controls. This
rule detects successful `PutResourcePolicy` and `DeleteResourcePolicy` calls against the Bedrock control
plane.
#### Possible investigation steps
- **Identify the actor and context**
- Review `aws.cloudtrail.user_identity.arn`, `aws.cloudtrail.user_identity.type`,
`aws.cloudtrail.user_identity.access_key_id`, `user_agent.original`, and `source.ip`.
- Confirm the identity is expected to manage Bedrock resource policies and that a related change request
exists.
- **Validate the policy change**
- For `PutResourcePolicy`, inspect `aws.cloudtrail.request_parameters` and
`aws.cloudtrail.flattened.request_parameters` for the target resource ARN and the policy document.
Look for `Principal` values referencing external AWS account IDs, `"*"`, or unfamiliar roles.
- For `DeleteResourcePolicy`, determine which resource lost its policy and whether that resource should
have remained restricted.
- **Correlate activity**
- Look for related Bedrock actions (model invocation, agent updates, knowledge base access) from the same
identity or the newly granted principal.
- Check for prior enumeration of Bedrock resources or other recent IAM/resource-policy changes.
### False positive analysis
- **Planned access management**: Legitimate sharing or onboarding may add or remove resource policies.
Validate against change tickets and standard templates.
- **Automation**: IaC or platform pipelines may set or remove resource policies during deployment. Confirm
the actor matches known automation infrastructure.
### Response and remediation
- If the change is unauthorized, revert the resource policy to its approved state and remove any external
or overly permissive principals.
- Disable or rotate the credentials in `aws.cloudtrail.user_identity.access_key_id` if compromise is
suspected.
- Review all Bedrock and IAM activity from the same identity in the surrounding time window for further
access grants or persistence.
- Restrict `bedrock:PutResourcePolicy` and `bedrock:DeleteResourcePolicy` to administrative roles and
enforce least-privilege resource policies.
"""
references = [
"https://docs.aws.amazon.com/bedrock/latest/APIReference/API_PutResourcePolicy.html",
"https://docs.aws.amazon.com/bedrock/latest/APIReference/API_DeleteResourcePolicy.html"
]
risk_score = 47
rule_id = "de0e9ed8-b68f-4249-957a-2c2bbdbd1c1b"
severity = "medium"
tags = [
"Domain: Cloud",
"Domain: LLM",
"Data Source: AWS",
"Data Source: AWS CloudTrail",
"Data Source: Amazon Web Services",
"Data Source: Amazon Bedrock",
"Use Case: Identity and Access Audit",
"Resources: Investigation Guide",
"Tactic: Persistence",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
data_stream.dataset: "aws.cloudtrail" and
event.provider: "bedrock.amazonaws.com" and
event.action: ("PutResourcePolicy" or "DeleteResourcePolicy") and
event.outcome: "success"
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[rule.investigation_fields]
field_names = [
"@timestamp",
"user.name",
"user_agent.original",
"source.ip",
"aws.cloudtrail.user_identity.arn",
"aws.cloudtrail.user_identity.type",
"aws.cloudtrail.user_identity.access_key_id",
"event.action",
"event.provider",
"event.outcome",
"cloud.account.id",
"cloud.region",
"aws.cloudtrail.request_parameters",
"aws.cloudtrail.response_elements",
]
[rule.new_terms]
field = "new_terms_fields"
value = ["aws.cloudtrail.user_identity.arn"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-7d"
Stages and Predicates
Stage 1: new_terms
data_stream.dataset: "aws.cloudtrail" and
event.provider: "bedrock.amazonaws.com" and
event.action: ("PutResourcePolicy" or "DeleteResourcePolicy") and
event.outcome: "success"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"aws.cloudtrail" |
event.action | in |
| field:"EventType" kind:in |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"success" |
event.provider | eq |
| field:"Provider_Name" kind:eq value:"bedrock.amazonaws.com" |
AWS CloudTrail Log Evasion
#Identifies the evasion of cloudtrail logging for IAM actions involving policy creation, modification or attachment. When making certain policy-related API calls, an adversary may pad the associated policy document with whitespaces to trigger CloudTrail’s logging size constraints, resulting in incomplete logging where critical details about the policy are omitted. By exploiting this gap, threat actors can bypass monitoring performed through CloudTrail and can effectively obscure unauthorized changes. This rule looks for IAM API calls with the requestParameters property containing reason:”requestParameters too large” and omitted:true.
Known False Positives
- There is no known legitimate reason for padding policies with white spaces to the extent it would take to trigger Cloudtrail's logging constraints. Any instance of this should be investigated.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
Rule Body
[metadata]
creation_date = "2025/06/10"
integration = ["aws"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
Identifies the evasion of cloudtrail logging for IAM actions involving policy creation, modification or attachment. When making certain policy-related API calls, an adversary may pad the associated policy document with whitespaces to trigger CloudTrail’s logging size constraints, resulting in incomplete logging where critical details about the policy are omitted. By exploiting this gap, threat actors can bypass monitoring performed through CloudTrail and can effectively obscure unauthorized changes. This rule looks for IAM API calls with the requestParameters property containing reason:”requestParameters too large” and omitted:true.
"""
false_positives = [
"""
There is no known legitimate reason for padding policies with white spaces to the extent it would take to trigger Cloudtrail's logging constraints. Any instance of this should be investigated.
""",
]
from = "now-6m"
interval = "5m"
index = ["filebeat-*", "logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS CloudTrail Log Evasion"
note = """## Triage and analysis
### Investigating AWS CloudTrail Log Evasion
Amazon CloudTrail is a service that enables governance, compliance, operational auditing, and risk auditing of your Amazon Web Services account. With CloudTrail, you can log, continuously monitor, and retain account activity related to actions across your Amazon Web Services infrastructure. In the `requestParameters` field of CloudTrail logs, a policy that was created/updated is typically displayed, including details such as the policy name and the full policy document content. However, when policies padded with large amounts of insignificant whitespace (such as spaces, tabs, or line breaks), reach a size range of 102,401 to 131,072 characters they begin to be omitted from CloudTrail logs and are instead rendered as "requestParameters too large". Attackers can do this to cover their tracks and impact security monitoring that relies on this source. This rule looks for IAM API calls with the requestParameters property containing reason:”requestParameters too large” and omitted:true.
#### Possible investigation steps
- Identify the user account that performed the action and whether it should perform this kind of action.
- Investigate other alerts associated with the user account during the past 48 hours.
- Contact the account and resource owners and confirm whether they are aware of this activity.
- Check if this operation was approved and performed according to the organization's change management policy.
- Considering the source IP address and geolocation of the user who issued the command:
- Do they look normal for the user?
- If the source is an EC2 IP address, is it associated with an EC2 instance in one of your accounts or is the source IP from an EC2 instance that's not under your control?
- If it is an authorized EC2 instance, is the activity associated with normal behavior for the instance role or roles? Are there any other alerts or signs of suspicious activity involving this instance?
- Examine the newly created or modified policy.
- If no policy name is included for event.actions like `PutRolePolicy`, analyze the inline policies attached for unexpected permission changes or additions.
- If you suspect the account has been compromised, scope potentially compromised assets by tracking servers, services, and data accessed by the account in the last 24 hours.
### False positive analysis
- If this rule is noisy in your environment due to expected activity, consider adding exceptions — preferably with a combination of user and IP address conditions. However, this behavior is rarely seen in legitimate operations and should be thoroughly investigated.
### Response and remediation
- Initiate the incident response process based on the outcome of the triage.
- Disable or limit the account during the investigation and response.
- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context:
- Identify the account role in the cloud environment.
- Assess the criticality of affected services and servers.
- Work with your IT team to identify and minimize the impact on users.
- Identify if the attacker is moving laterally and compromising other accounts, servers, or services.
- Identify any regulatory or legal ramifications related to this activity.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords or delete API keys as needed to revoke the attacker's access to the environment. Work with your IT teams to minimize the impact on business operations during these actions.
- Check if unauthorized new users were created, remove unauthorized new accounts, and request password resets for other IAM users.
- Consider enabling multi-factor authentication for users.
- Review the permissions assigned to the implicated user to ensure that the least privilege principle is being followed.
- Implement security best practices [outlined](https://aws.amazon.com/premiumsupport/knowledge-center/security-best-practices/) by AWS.
- Take the actions needed to return affected systems, data, or services to their normal operational levels.
- Identify the initial vector abused by the attacker and take action to prevent reinfection via the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
## Setup
The AWS Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
references = [
"https://permiso.io/blog/cloudtrail-logging-evasion-where-policy-size-matters",
]
risk_score = 47
rule_id = "9ebd48ac-a0e2-430a-a219-fe072a50146b"
severity = "medium"
tags = [
"Domain: Cloud",
"Data Source: AWS",
"Data Source: Amazon Web Services",
"Data Source: AWS IAM",
"Use Case: Log Auditing",
"Resources: Investigation Guide",
"Tactic: Defense Evasion",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset: aws.cloudtrail and event.provider: iam.amazonaws.com and aws.cloudtrail.flattened.request_parameters.reason: "requestParameters too large" and aws.cloudtrail.flattened.request_parameters.omitted : true and event.outcome: success
'''
[rule.investigation_fields]
field_names = [
"@timestamp",
"user.name",
"user_agent.original",
"source.ip",
"aws.cloudtrail.user_identity.arn",
"aws.cloudtrail.user_identity.type",
"aws.cloudtrail.user_identity.access_key_id",
"event.action",
"event.outcome",
"cloud.account.id",
"cloud.region",
"aws.cloudtrail.request_parameters",
"aws.cloudtrail.response_elements"
]
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[[rule.threat.technique.subtechnique]]
id = "T1562.008"
name = "Disable or Modify Cloud Logs"
reference = "https://attack.mitre.org/techniques/T1562/008/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Stage 1: query
data_stream.dataset: aws.cloudtrail and event.provider: iam.amazonaws.com and aws.cloudtrail.flattened.request_parameters.reason: "requestParameters too large" and aws.cloudtrail.flattened.request_parameters.omitted : true and event.outcome: success
Indicators
These rows show field, operator, and value matches.
AWS EKS Control Plane Logging Disabled
#Detects successful Amazon EKS UpdateClusterConfig requests that disable control plane logging. Disabling EKS API server and control plane logs can reduce visibility into cluster activity and may indicate defense evasion following compromised AWS credentials or unauthorized administrative access. EKS control plane logging changes are typically rare and should align with approved maintenance or cost optimization workflows.
Known False Positives
- Legitimate changes to EKS logging configuration during cluster provisioning, troubleshooting, or cost optimization may match. Validate the caller identity and change records, and baseline expected automation roles.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2026/05/07"
integration = ["aws"]
maturity = "production"
updated_date = "2026/07/08"
[rule]
author = ["Elastic"]
description = """
Detects successful Amazon EKS UpdateClusterConfig requests that disable control plane logging. Disabling EKS API server
and control plane logs can reduce visibility into cluster activity and may indicate defense evasion following
compromised AWS credentials or unauthorized administrative access. EKS control plane logging changes are typically rare
and should align with approved maintenance or cost optimization workflows.
"""
false_positives = [
"""
Legitimate changes to EKS logging configuration during cluster provisioning, troubleshooting, or cost optimization
may match. Validate the caller identity and change records, and baseline expected automation roles.
""",
]
from = "now-6m"
index = ["logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS EKS Control Plane Logging Disabled"
note = """## Triage and analysis
### Investigating AWS EKS Control Plane Logging Disabled
Review the caller (user.name, aws.cloudtrail.user_identity.arn, type), source.ip, user_agent.original, cloud.account.id, and cloud.region. Confirm which log types were disabled and whether the change aligns with a planned change window.
### Possible investigation steps
- Inspect aws.cloudtrail.request_parameters and response elements for cluster name and logging settings.
- Correlate with adjacent EKS and IAM activity from the same principal (access entry changes, iam policy attachments, sts assume events) and with any Kubernetes audit telemetry available.
- Check whether control plane logs stopped ingesting shortly after the change and scope potential visibility gaps.
### Response and remediation
- If unauthorized, re-enable EKS control plane logging and restrict IAM permissions that allow eks:UpdateClusterConfig.
- Rotate or revoke compromised credentials and review for additional EKS or IAM persistence changes.
"""
references = [
"https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html",
"https://docs.aws.amazon.com/eks/latest/APIReference/API_UpdateClusterConfig.html",
]
risk_score = 73
rule_id = "0f189343-dac7-4c1b-aca7-be8baa6bd02b"
severity = "high"
tags = [
"Domain: Cloud",
"Domain: Kubernetes",
"Data Source: AWS",
"Data Source: Amazon Web Services",
"Data Source: AWS CloudTrail",
"Use Case: Threat Detection",
"Tactic: Defense Evasion",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:"aws.cloudtrail" and
event.provider:"eks.amazonaws.com" and
event.action:"UpdateClusterConfig" and
event.outcome:"success" and
aws.cloudtrail.request_parameters:*logging*enabled=false*
'''
[rule.investigation_fields]
field_names = [
"@timestamp",
"user.name",
"user_agent.original",
"source.ip",
"aws.cloudtrail.user_identity.arn",
"aws.cloudtrail.user_identity.type",
"event.action",
"event.outcome",
"cloud.account.id",
"cloud.region",
"aws.cloudtrail.request_parameters",
"aws.cloudtrail.response_elements",
]
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[[rule.threat.technique.subtechnique]]
id = "T1562.008"
name = "Disable or Modify Cloud Logs"
reference = "https://attack.mitre.org/techniques/T1562/008/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Stage 1: query
data_stream.dataset:"aws.cloudtrail" and
event.provider:"eks.amazonaws.com" and
event.action:"UpdateClusterConfig" and
event.outcome:"success" and
aws.cloudtrail.request_parameters:*logging*enabled=false*
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
aws.cloudtrail.request_parameters | wildcard |
| field:"aws::requestParameters" kind:wildcard value:"*logging*enabled=false*" |
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"aws.cloudtrail" |
event.action | eq |
| field:"EventType" kind:eq value:"UpdateClusterConfig" |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"success" |
event.provider | eq |
| field:"Provider_Name" kind:eq value:"eks.amazonaws.com" |
Command Obfuscation via Unicode Modifier Letters
#Identifies the presence of Unicode modifier letters in the process command_line. Adversaries sometimes replace ASCII characters with visually similar Unicode modifier letters to evade simple string-based detections.
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]
creation_date = "2025/11/13"
integration = ["endpoint", "windows", "system", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/04/30"
[rule]
author = ["Elastic"]
description = """
Identifies the presence of Unicode modifier letters in the process command_line. Adversaries sometimes replace ASCII
characters with visually similar Unicode modifier letters to evade simple string-based detections.
"""
from = "now-9m"
index = [
"endgame-*",
"logs-crowdstrike.fdr*",
"logs-endpoint.events.process-*",
"logs-m365_defender.event-*",
"logs-sentinel_one_cloud_funnel.*",
"logs-system.security*",
"logs-windows.forwarded*",
"logs-windows.sysmon_operational-*",
"winlogbeat-*",
]
language = "eql"
license = "Elastic License v2"
name = "Command Obfuscation via Unicode Modifier Letters"
references = ["https://www.wietzebeukema.nl/blog/windows-command-line-obfuscation"]
risk_score = 73
rule_id = "37148ae6-c6ec-4fe4-88b1-02f40aed93a9"
severity = "high"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Defense Evasion",
"Data Source: Elastic Endgame",
"Resources: Investigation Guide",
"Data Source: Elastic Defend",
"Data Source: Windows Security Event Logs",
"Data Source: Microsoft Defender XDR",
"Data Source: Sysmon",
"Data Source: SentinelOne",
"Data Source: Crowdstrike",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "windows" and event.type == "start" and
(
process.name : (
"reg.exe", "net.exe", "net1.exe", "certutil.exe", "MSHTA.EXE", "msiexec.exe", "bitsadmin.exe", "CertReq.exe",
"PrintBrm.exe", "MSBuild.exe", "wuauclt.exe", "curl.exe", "wget.exe", "ssh.exe", "Cmd.Exe", "PowerShell.EXE",
"CONHOST.EXE", "wscript.exe", "cscript.exe", "REGSVR32.EXE", "RUNDLL32.EXE", "procdump.exe", "ntdsutil.exe",
"diskshadow.exe", "schtasks.exe", "sc.exe", "wmic.exe", "VSSADMIN.EXE", "WBADMIN.EXE", "iCACLS.EXE",
"sftp.exe", "scp.exe", "esentutl.exe", "InstallUtil.exe", "wevtutil.exe"
) or
?process.pe.original_file_name in (
"reg.exe", "net.exe", "net1.exe", "CertUtil.exe", "MSHTA.EXE", "msiexec.exe", "bitsadmin.exe", "CertReq.exe",
"PrintBrm.exe", "MSBuild.exe", "wuauclt.exe", "curl.exe", "wget.exe", "ssh.exe", "Cmd.Exe", "PowerShell.EXE",
"CONHOST.EXE", "wscript.exe", "cscript.exe", "REGSVR32.EXE", "RUNDLL32.EXE", "procdump", "ntdsutil.exe",
"diskshadow.exe", "schtasks.exe", "sc.exe", "wmic.exe", "VSSADMIN.EXE", "WBADMIN.EXE", "iCACLS.EXE",
"sftp.exe", "scp.exe", "esentutl.exe", "InstallUtil.exe", "wevtutil.exe"
)
) and
process.command_line regex """.*[ʰ-˿ᴬ-ᶻ]+.*"""
'''
note = """## Triage and analysis
### Investigating Command Obfuscation via Unicode Modifier Letters
#### Possible investigation steps
- What did the raw modifier-letter command hide after ASCII normalization?
- Focus: raw `process.command_line` and modifier-letter code points in `U+02B0-U+02FF` or `U+1D2C-U+1D7B`.
- Hint: preserve the raw string, view code points, then compare with NFKC or ASCII-folded rendering; visual review can miss modifier letters a Windows utility may parse as ASCII.
- Implication: escalate when normalization reveals a behavior-changing verb, flag, URL, path, or target; lower suspicion when characters remain in localized names, package names, or path text and behavior is unchanged.
- What operational intent does the normalized command express?
- Focus: normalized `process.command_line`, `process.name`, and the hidden verb, option, URL, path, or target after ASCII normalization.
- Hint: map the hidden token to the utility family: "urlcache" or remote retrieval for certutil/bitsadmin/curl/wget, "encodedcommand" or script execution for PowerShell/cmd/script hosts, add/create/delete for reg/sc/schtasks, shadow/log deletion for vssadmin/wevtutil, and dump/export for procdump/ntdsutil. Treat paired quote insertion or shorthand options as adjacent obfuscation on the same decision path.
- Implication: escalate when the normalized token enables high-risk utility behavior; lower suspicion when it remains read-only status, inventory, or installer activity fitting the same process context.
- Is the utility identity consistent with the normalized behavior?
- 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 binary is renamed, user-writable, unsigned/untrusted, mismatched to its original file name, or new for the host; lower suspicion when a signed, stable utility path fits the normalized behavior. Identity alone never clears obfuscation.
- Does the launch and session context explain why this utility received obfuscated text?
- Focus: `process.parent.executable`, `process.parent.command_line`, `process.Ext.session_info.logon_type`, `process.Ext.token.elevation_level`, and the `user.id` / `host.id` cohort.
- Implication: escalate when a document, browser, archive tool, script host, unexpected interactive user, remote session, or unexplained service chain introduces the command; lower suspicion when a recognized management, installer, or testing launcher runs the same unchanged pattern under the expected account and host cohort.
- Did the obfuscated process launch follow-on process activity?
- Focus: child process starts on the same `host.id` where `process.parent.entity_id` matches alert `process.entity_id`; read child `process.name`, `process.executable`, and `process.command_line`. $investigate_0
- Hint: inspect same-process file, network, or registry activity for utility effects without child processes. $investigate_1 Missing network telemetry is unresolved, not benign. If `process.entity_id` is absent, pivot with `host.id`, alert `process.pid`, child `process.parent.pid`, and a tight alert window.
- Implication: escalate when child activity shows shells, script hosts, installers, remote clients, credential tools, service/task utilities, or cleanup commands matching normalized intent; lower suspicion when no suspicious child follows and the normalized command fits the local workflow.
- If local evidence is suspicious or unresolved, does related alert history change scope?
- Focus: related alerts for the same `host.id`, using the strongest local suspicious anchor: normalized command fragment, modifier-letter sequence, utility identity, or parent launcher. $investigate_2
- Hint: if host history does not explain the activity, compare related alerts for the same `user.id` with the same anchors. $investigate_3
- Implication: broaden containment when the same obfuscation pattern appears across unrelated hosts or users; keep local when the pattern stays confined to one confirmed workflow and process evidence has no contradiction.
- Based on command meaning, utility identity, lineage/session, follow-on processes, and scope, what disposition is supported?
- Implication: escalate when normalization changes behavior and identity, lineage, child-process, or scope evidence supports abuse; close only when normalized meaning is unchanged or clearly benign and every process-context category fits one exact workflow; preserve raw command evidence and escalate when evidence is mixed or incomplete.
### False positive analysis
- Localized product names, internationalized paths, user-supplied file names, vendor installers, deployment frameworks, or internal admin tools can introduce non-ASCII package names or paths. Confirm only when normalization leaves behavior unchanged, modifier letters sit in content rather than a verb or flag, utility identity and parent command line match one recognized workflow, and `user.id` plus `host.id` fit the same local task. If records exist, use them as corroboration; otherwise require prior alerts from this rule with the same normalized command pattern, launcher, host, and user.
- Security testing or detection-validation exercises may intentionally use obfuscated commands. Confirm by matching normalized `process.command_line`, modifier-letter sequence, `process.parent.executable`, `host.id`, and `user.id` to the test scope; outside test records can corroborate but should not override contradictory process evidence.
- Before creating an exception, build it from the minimum confirmed pattern: normalized `process.command_line`, modifier-letter sequence or code-point range, utility identity in `process.executable` or `process.pe.original_file_name`, launcher context in `process.parent.executable`, and the stable `host.id` or `user.id` cohort. Avoid exceptions on `process.name` alone or the mere presence of non-ASCII characters.
### Response and remediation
- If confirmed benign, reverse any temporary containment and record the raw and normalized `process.command_line`, recovered code points, utility identity, parent command line, and `user.id` / `host.id` evidence that validated the workflow. Create an exception only for the same recurring pattern.
- If suspicious but unconfirmed, preserve the raw command string, normalized rendering, recovered code points, alerting and child `process.entity_id` values, parent command line, and `user.id` / `host.id` scope before containment. Apply reversible containment first, such as heightened monitoring, temporary account restrictions, or host isolation only when the normalized command, lineage, or follow-on process activity suggests active compromise and the host can tolerate isolation.
- If confirmed malicious, isolate the host or restrict the affected account based on the normalized intent, launcher chain, child process activity, and related-alert scope. Record alerting and child `process.entity_id` values before suspending or terminating processes, then eradicate only the payloads, configuration changes, or destructive actions identified in the case evidence.
- Post-incident hardening: replace scripts that require modifier-letter arguments, pin administrative automation to stable signed launcher paths and expected parent command lines, and retain full process command-line, parentage, child-process, and user-host telemetry for future alerts.
"""
setup = """## Setup
This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
Setup instructions: https://ela.st/install-elastic-defend
### Additional data sources
This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
- [CrowdStrike](https://ela.st/crowdstrike-integration)
- [Microsoft Defender XDR](https://ela.st/m365-defender)
- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
- [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
- [Windows Process Creation Logs](https://ela.st/audit-process-creation)
"""
[rule.investigation_fields]
field_names = [
"@timestamp",
"host.id",
"user.id",
"process.entity_id",
"process.pid",
"process.executable",
"process.command_line",
"process.Ext.session_info.logon_type",
"process.Ext.token.elevation_level",
"process.hash.sha256",
"process.pe.original_file_name",
"process.code_signature.subject_name",
"process.code_signature.trusted",
"process.parent.executable",
"process.parent.command_line",
]
[transform]
[[transform.investigate]]
label = "Child process activity from the obfuscated process"
description = ""
providers = [
[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
{ excluded = false, field = "event.type", queryType = "phrase", value = "start", valueType = "string" }
]
]
relativeFrom = "now-1h"
relativeTo = "now"
[[transform.investigate]]
label = "File, network, or registry activity by the obfuscated process"
description = ""
providers = [
[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
{ excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" }
],
[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
{ excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" }
],
[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
{ excluded = false, field = "event.category", queryType = "phrase", value = "registry", valueType = "string" }
]
]
relativeFrom = "now-1h"
relativeTo = "now"
[[transform.investigate]]
label = "Alerts associated with the host"
description = ""
providers = [
[
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
]
]
relativeFrom = "now-48h/h"
relativeTo = "now"
[[transform.investigate]]
label = "Alerts associated with the user"
description = ""
providers = [
[
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
{ excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
]
]
relativeFrom = "now-48h/h"
relativeTo = "now"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1027"
name = "Obfuscated Files or Information"
reference = "https://attack.mitre.org/techniques/T1027/"
[[rule.threat.technique.subtechnique]]
id = "T1027.010"
name = "Command Obfuscation"
reference = "https://attack.mitre.org/techniques/T1027/010/"
[rule.threat.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 : (
"reg.exe", "net.exe", "net1.exe", "certutil.exe", "MSHTA.EXE", "msiexec.exe", "bitsadmin.exe", "CertReq.exe",
"PrintBrm.exe", "MSBuild.exe", "wuauclt.exe", "curl.exe", "wget.exe", "ssh.exe", "Cmd.Exe", "PowerShell.EXE",
"CONHOST.EXE", "wscript.exe", "cscript.exe", "REGSVR32.EXE", "RUNDLL32.EXE", "procdump.exe", "ntdsutil.exe",
"diskshadow.exe", "schtasks.exe", "sc.exe", "wmic.exe", "VSSADMIN.EXE", "WBADMIN.EXE", "iCACLS.EXE",
"sftp.exe", "scp.exe", "esentutl.exe", "InstallUtil.exe", "wevtutil.exe"
) or
?process.pe.original_file_name in (
"reg.exe", "net.exe", "net1.exe", "CertUtil.exe", "MSHTA.EXE", "msiexec.exe", "bitsadmin.exe", "CertReq.exe",
"PrintBrm.exe", "MSBuild.exe", "wuauclt.exe", "curl.exe", "wget.exe", "ssh.exe", "Cmd.Exe", "PowerShell.EXE",
"CONHOST.EXE", "wscript.exe", "cscript.exe", "REGSVR32.EXE", "RUNDLL32.EXE", "procdump", "ntdsutil.exe",
"diskshadow.exe", "schtasks.exe", "sc.exe", "wmic.exe", "VSSADMIN.EXE", "WBADMIN.EXE", "iCACLS.EXE",
"sftp.exe", "scp.exe", "esentutl.exe", "InstallUtil.exe", "wevtutil.exe"
)
) and
process.command_line regex """.*[ʰ-˿ᴬ-ᶻ]+.*"""
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.command_line | regex_match |
| field:"CommandLine" kind:regex_match value:".*[ʰ-˿ᴬ-ᶻ]+.*" |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
process.pe.original_file_name | in |
| field:"OriginalFileName" kind:in |
Credential Dumping - Prevented - Elastic Endgame
#Elastic Endgame prevented Credential Dumping. Click the Elastic Endgame icon in the event.module column or the link in the rule.reference column for additional information.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Rule Body
[metadata]
creation_date = "2020/02/18"
maturity = "production"
promotion = true
updated_date = "2025/03/21"
[rule]
author = ["Elastic"]
description = """
Elastic Endgame prevented Credential Dumping. Click the Elastic Endgame icon in the event.module column or the link in
the rule.reference column for additional information.
"""
from = "now-2m"
index = ["endgame-*"]
interval = "1m"
language = "kuery"
license = "Elastic License v2"
max_signals = 1000
name = "Credential Dumping - Prevented - Elastic Endgame"
risk_score = 47
rule_id = "db8c33a8-03cd-4988-9e2c-d0a4863adb13"
setup = """## Setup
### Additional notes
For information on troubleshooting the maximum alerts warning please refer to this [guide](https://www.elastic.co/guide/en/security/current/alerts-ui-monitor.html#troubleshoot-max-alerts).
"""
severity = "medium"
tags = ["Data Source: Elastic Endgame", "Use Case: Threat Detection", "Tactic: Credential Access", "Resources: Investigation Guide"]
timestamp_override = "event.ingested"
type = "query"
query = '''
event.kind:alert and event.module:endgame and endgame.metadata.type:prevention and (event.action:cred_theft_event or endgame.event_subtype_full:cred_theft_event)
'''
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Credential Dumping - Prevented - Elastic Endgame
Elastic Endgame is a security solution that proactively prevents credential dumping, a technique where attackers extract sensitive authentication data from systems. Adversaries exploit this to gain unauthorized access to networks. The detection rule identifies prevention alerts by monitoring specific event actions and metadata, signaling attempts to steal credentials, thus enabling timely threat mitigation.
### Possible investigation steps
- Review the alert details to confirm the presence of event.kind:alert and event.module:endgame, ensuring the alert is related to Elastic Endgame's prevention of credential dumping.
- Examine the event.action and endgame.event_subtype_full fields for the value cred_theft_event to understand the specific credential theft attempt that was prevented.
- Investigate the source and destination systems involved in the alert to identify potential points of compromise or targeted systems.
- Check for any related alerts or events in the same timeframe that might indicate a coordinated attack or further attempts at credential access.
- Assess the user accounts involved in the alert to determine if they have been compromised or if there are any unauthorized access attempts.
- Review the risk score and severity to prioritize the investigation and response actions based on the potential impact on the organization.
### False positive analysis
- Routine administrative tools or scripts that access credential stores may trigger alerts. Review and whitelist these tools if they are verified as non-threatening.
- Security software performing legitimate credential checks can be mistaken for credential dumping. Identify and exclude these processes from alert generation.
- Automated backup systems accessing credential data for legitimate purposes might be flagged. Ensure these systems are recognized and excluded from the rule.
- Regular system maintenance activities that involve credential verification could cause false positives. Document and exclude these activities if they are part of standard operations.
- User behavior analytics might misinterpret legitimate user actions as credential theft. Implement user behavior baselines to reduce such false positives.
### Response and remediation
- Isolate the affected system immediately to prevent further unauthorized access or lateral movement within the network.
- Terminate any suspicious processes identified as part of the credential dumping attempt to halt ongoing malicious activities.
- Change all potentially compromised credentials, especially those with elevated privileges, to prevent unauthorized access using stolen credentials.
- Conduct a thorough review of access logs and event data to identify any additional systems that may have been targeted or compromised.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to ensure comprehensive remediation.
- Implement additional monitoring on the affected system and related network segments to detect any further suspicious activities or attempts at credential theft.
- Review and update endpoint protection configurations to ensure that similar threats are detected and prevented in the future, leveraging insights from the MITRE ATT&CK framework."""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1003"
name = "OS Credential Dumping"
reference = "https://attack.mitre.org/techniques/T1003/"
[[rule.threat.technique.subtechnique]]
id = "T1003.001"
name = "LSASS Memory"
reference = "https://attack.mitre.org/techniques/T1003/001/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
Stages and Predicates
Stage 1: query
event.kind:alert and event.module:endgame and endgame.metadata.type:prevention and (event.action:cred_theft_event or endgame.event_subtype_full:cred_theft_event)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
endgame.event_subtype_full | eq |
| field:"endgame.event_subtype_full" kind:eq value:"cred_theft_event" |
endgame.metadata.type | eq |
| field:"endgame.metadata.type" kind:eq value:"prevention" |
event.action | eq |
| field:"EventType" kind:eq value:"cred_theft_event" |
event.kind | eq |
| field:"event.kind" kind:eq value:"alert" |
event.module | eq |
| field:"event.module" kind:eq value:"endgame" |
Decoded Payload Piped to Interpreter Detected via Defend for Containers
#This rule detects the execution of a base64 decoded payload to an interpreter inside a container. Attackers may use this technique to execute malicious code, while attempting to evade detection.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Stealth |
Rule Body
[metadata]
creation_date = "2026/03/05"
integration = ["cloud_defend"]
maturity = "production"
min_stack_comments = "Defend for Containers integration was re-introduced in 9.3.0"
min_stack_version = "9.3.0"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
This rule detects the execution of a base64 decoded payload to an interpreter inside a container. Attackers
may use this technique to execute malicious code, while attempting to evade detection.
"""
from = "now-6m"
index = ["logs-cloud_defend.process*"]
interval = "5m"
language = "eql"
license = "Elastic License v2"
name = "Decoded Payload Piped to Interpreter Detected via Defend for Containers"
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Decoded Payload Piped to Interpreter Detected via Defend for Containers
This detection flags a container process that decodes an obfuscated payload (commonly base64 or similar) and immediately feeds the output into an interpreter, a high-signal pattern for fileless execution and defense evasion. Attackers use it to deliver short-lived scripts without writing them to disk, reducing forensic artifacts and bypassing simple content controls. A common pattern is echoing an encoded blob, decoding it, and piping it into `sh`/`bash` or `python` to run a downloader or backdoor inline.
### Possible investigation steps
- Correlate the paired exec events to reconstruct the full pipeline and determine whether it originated from an interactive exec session, the container entrypoint, or an orchestrated task.
- Extract the encoded blob from the command invocation or captured stdin, decode it in an isolated environment, and assess the decoded script for downloader/backdoor logic, persistence attempts, or secret access.
- Pivot from the interpreter execution to spawned children and concurrent outbound connections to identify second-stage payload retrieval, command-and-control, or lateral movement activity.
- Validate workload legitimacy by reviewing the container’s image tag/digest and the owning pod/deployment, namespace, and service account, and compare against recent changes or redeploys for compromise indicators.
- Look for post-execution artifacts in writable layers and mounted volumes (new scripts/binaries, modified init files, scheduled tasks), and if suspicious preserve evidence and rotate potentially exposed credentials.
### False positive analysis
- Containerized init/entrypoint or CI job logic decodes embedded base64 configuration or a small helper script at runtime (e.g., `base64 -d | sh` or `python -c ...b64decode...`) to avoid shipping plaintext in the image and to support templating across environments.
- An operator troubleshooting a container uses an interactive exec session to paste an encoded one-liner that decodes and pipes into a shell or interpreter to quickly run diagnostics or apply a transient fix without creating files in the container filesystem.
### Response and remediation
- Immediately isolate or stop the affected container/pod and block further `kubectl exec`/interactive sessions into the workload while preserving the full command line, container image digest, and recent stdout/stderr logs for evidence.
- Decode the observed base64/openssl/python/perl/ruby payload in a sandbox to identify its actions, then terminate any spawned interpreter children and remove any dropped binaries/scripts from writable layers and mounted volumes.
- If the decoded script performs outbound retrieval or C2, quarantine the node or restrict egress for the namespace and rotate any secrets, tokens, or cloud credentials accessible to the container’s service account.
- Rebuild and redeploy the workload from a known-good image (pin by digest), revoke the compromised image/tag from the registry, and validate the deployment manifests for unauthorized entrypoint/command changes.
- Escalate to incident response if the payload includes credential access, lateral movement tooling, or creates persistence on the node (e.g., cron/systemd changes, modified kubelet paths), or if multiple containers show similar decode-to-interpreter pipelines.
- Harden by enforcing admission controls to deny privileged containers and runtime `exec`, require read-only root filesystems and least-privilege service accounts, and add detections/blocks for decode-to-interpreter patterns and unexpected interpreters in production images.
"""
references = [
"https://flare.io/learn/resources/blog/teampcp-cloud-native-ransomware",
]
risk_score = 73
rule_id = "0fb83aa0-3d17-41e9-b09c-56397bf7a7d9"
severity = "high"
tags = [
"Data Source: Elastic Defend for Containers",
"Domain: Container",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Defense Evasion",
"Tactic: Execution",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
sequence by process.parent.entity_id, container.id with maxspan=3s
[process where event.type == "start" and event.action == "exec" and container.id like "?*" and (
(
(
process.name in ("base64", "basez", "base64plain", "base64url", "base64mime", "base64pem", "basenc", "base32", "base16") or
(
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox") and
process.args in ("base64", "basez", "base64plain", "base64url", "base64mime", "base64pem", "basenc", "base32", "base16")
)
) and
process.args like~ "*-*d*"
) or
(
process.name == "openssl" and
process.args == "enc" and process.args in ("-d", "-base64", "-a", "-A")
) or
(
process.name like "python*" and (
(process.args == "base64" and process.args in ("-d", "-u", "-t")) or
(process.args == "-c" and process.args like "*base64*" and process.args like~ "*b64decode*")
)
) or
(
process.name like "perl*" and
process.args like~ "*decode_base64*"
) or
(
process.name like "ruby*" and
process.args == "-e" and
process.args like~ "*Base64.decode64*"
)
)]
[process where event.type == "start" and event.action == "exec" and process.name like (
"bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox",
"python*", "perl*", "ruby*", "lua*", "php*"
) and
process.args like (
"-bash", "-dash", "-sh", "-tcsh", "-csh", "-zsh", "-ksh", "-fish", "-busybox",
"bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox",
"/bin/bash", "/bin/dash", "/bin/sh", "/bin/tcsh", "/bin/csh",
"/bin/zsh", "/bin/ksh", "/bin/fish", "/bin/busybox",
"/usr/bin/bash", "/usr/bin/dash", "/usr/bin/sh", "/usr/bin/tcsh",
"/usr/bin/csh", "/usr/bin/zsh", "/usr/bin/ksh", "/usr/bin/fish",
"/usr/bin/busybox",
"*python*", "*perl*", "*ruby*", "*lua*", "*php*", "/dev/fd/*"
) and
not (
process.working_directory like (
"/usr/local/zeek", "/opt/zeek", "/var/lib/docker/overlay2/*/opt/zeek", "/usr/local/zeek_old_install",
"/var/lib/docker/overlay2/*/usr/local/zeek", "/proc/self/fd/*/usr/local/zeek"
) or
process.args in (
"which", "/bin/which", "/usr/bin/which", "/usr/local/bin/which",
"man", "/bin/man", "/usr/bin/man", "/usr/local/bin/man",
"chmod", "/bin/chmod", "/usr/bin/chmod", "/usr/local/bin/chmod",
"chown", "/bin/chown", "/usr/bin/chown", "/usr/local/bin/chown"
)
)]
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1027"
name = "Obfuscated Files or Information"
reference = "https://attack.mitre.org/techniques/T1027/"
[[rule.threat.technique.subtechnique]]
id = "T1027.010"
name = "Command Obfuscation"
reference = "https://attack.mitre.org/techniques/T1027/010/"
[[rule.threat.technique]]
id = "T1140"
name = "Deobfuscate/Decode Files or Information"
reference = "https://attack.mitre.org/techniques/T1140/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"
[[rule.threat.technique.subtechnique]]
id = "T1059.006"
name = "Python"
reference = "https://attack.mitre.org/techniques/T1059/006/"
[[rule.threat.technique.subtechnique]]
id = "T1059.011"
name = "Lua"
reference = "https://attack.mitre.org/techniques/T1059/011/"
[[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/"
Stages and Predicates
Ordered sequence: each step below must occur in order within 3s, correlated by container.id, process.parent.entity_id.
Stage 1: process
[process where event.type == "start" and event.action == "exec" and container.id like "?*" and (
(
(
process.name in ("base64", "basez", "base64plain", "base64url", "base64mime", "base64pem", "basenc", "base32", "base16") or
(
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox") and
process.args in ("base64", "basez", "base64plain", "base64url", "base64mime", "base64pem", "basenc", "base32", "base16")
)
) and
process.args like~ "*-*d*"
) or
(
process.name == "openssl" and
process.args == "enc" and process.args in ("-d", "-base64", "-a", "-A")
) or
(
process.name like "python*" and (
(process.args == "base64" and process.args in ("-d", "-u", "-t")) or
(process.args == "-c" and process.args like "*base64*" and process.args like~ "*b64decode*")
)
) or
(
process.name like "perl*" and
process.args like~ "*decode_base64*"
) or
(
process.name like "ruby*" and
process.args == "-e" and
process.args like~ "*Base64.decode64*"
)
)]
Stage 2: process
[process where event.type == "start" and event.action == "exec" and process.name like (
"bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox",
"python*", "perl*", "ruby*", "lua*", "php*"
) and
process.args like (
"-bash", "-dash", "-sh", "-tcsh", "-csh", "-zsh", "-ksh", "-fish", "-busybox",
"bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox",
"/bin/bash", "/bin/dash", "/bin/sh", "/bin/tcsh", "/bin/csh",
"/bin/zsh", "/bin/ksh", "/bin/fish", "/bin/busybox",
"/usr/bin/bash", "/usr/bin/dash", "/usr/bin/sh", "/usr/bin/tcsh",
"/usr/bin/csh", "/usr/bin/zsh", "/usr/bin/ksh", "/usr/bin/fish",
"/usr/bin/busybox",
"*python*", "*perl*", "*ruby*", "*lua*", "*php*", "/dev/fd/*"
) and
not (
process.working_directory like (
"/usr/local/zeek", "/opt/zeek", "/var/lib/docker/overlay2/*/opt/zeek", "/usr/local/zeek_old_install",
"/var/lib/docker/overlay2/*/usr/local/zeek", "/proc/self/fd/*/usr/local/zeek"
) or
process.args in (
"which", "/bin/which", "/usr/bin/which", "/usr/local/bin/which",
"man", "/bin/man", "/usr/bin/man", "/usr/local/bin/man",
"chmod", "/bin/chmod", "/usr/bin/chmod", "/usr/local/bin/chmod",
"chown", "/bin/chown", "/usr/bin/chown", "/usr/local/bin/chown"
)
)]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
container.id | wildcard |
| field:"container.id" kind:wildcard value:"?*" |
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | eq |
| field:"process.args" kind:eq |
process.args | in |
| field:"process.args" kind:in |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.name | eq |
| field:"process_basename" kind:eq value:"openssl" |
process.name | in |
| field:"process_basename" kind:in |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | in | /bin/chmod, /bin/chown, /bin/man, /bin/which, /usr/bin/chmod, /usr/bin/chown, /usr/bin/man, /usr/bin/which, /usr/local/bin/chmod, /usr/local/bin/chown, /usr/local/bin/man, /usr/local/bin/which, chmod, chown, man, which | excludes:process.args |
process.working_directory | wildcard | /usr/local/zeek, /opt/zeek, /var/lib/docker/overlay2/*/opt/zeek, /usr/local/zeek_old_install, /var/lib/docker/overlay2/*/usr/local/zeek, /proc/self/fd/*/usr/local/zeek | excludes:process.working_directory |
DNS Request by Suspicious Process Executable
#This rule detects DNS requests initiated by suspicious process executables. Malware authors may use these requests to communicate with command and control infrastructure, exfiltrate data from the target system, or to download payloads for later execution.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Command & Control |
Rule Body
[rule]
description = """
This rule detects DNS requests initiated by suspicious process executables. Malware authors may use these requests to
communicate with command and control infrastructure, exfiltrate data from the target system, or to download payloads for
later execution.
"""
id = "503823dd-722f-4f23-84fc-8a6024f505f2"
license = "Elastic License v2"
name = "DNS Request by Suspicious Process Executable"
os_list = ["linux"]
version = "1.0.7"
query = '''
sequence by process.entity_id with maxspan=10s
[process where event.type == "start" and event.action == "exec" and (
process.executable like (
"./*", "/var/tmp/*", "/dev/shm/*", "/run/*", "/var/run/*", "/boot/*", "/sys/*",
"/lost+found/*", "/var/mail/*"
) or
process.name like ".*"
) and
not (
process.executable like (
"./usr/bin/podman", "./", "/dev/.buildkit_qemu_emulator", "/u01/*/webtier/ohs/bin/.apachectl",
"/usr/local/share/npm-global/lib/node_modules/opencode-ai/bin/.opencode",
"./usr/bin/qemu-aarch64-static", "/nix/store/*/bin/.opencode-wrapped", "/home/agent/.local/share/coursier/bin/.bloop.aux",
"/var/tmp/pamac-build-richard/*/bin/node", "/nix/store/*/bin/.rclone-wrapped", "/nix/store/*/bin/.glab-wrapped"
) or
(
process.executable like "/nix/store/*/bin/.gh-wrapped" and
process.command_line like "/home/*/.nix-profile/bin/gh *"
) or
(
process.executable == "./usr/bin/qemu-x86_64-static" and
process.command_line like "/usr/libexec/qemu-binfmt/x86_64-binfmt-P *"
) or
process.parent.executable in ("/usr/bin/skopeo", "/usr/bin/buildah") or
process.args == "datadog-ipc-helper" or
process.executable like (
"/nix/store/*claude-code-*/bin/.claude-wrapped",
"*/node_modules/@kilocode/cli/bin/.kilo"
)
)]
[dns where event.action == "lookup_result" and dns.question.name != "localhost" and
not (
dns.question.name == "pypi.org" or
(process.executable like "/home/*/.elastic-ramen" and dns.question.name in ("registry.npmjs.org", "models.dev"))
)
]
'''
min_endpoint_version = "9.3.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 1
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1204"
name = "User Execution"
reference = "https://attack.mitre.org/techniques/T1204/"
[[threat.technique.subtechnique]]
id = "T1204.002"
name = "Malicious File"
reference = "https://attack.mitre.org/techniques/T1204/002/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"
[[threat.technique.subtechnique]]
id = "T1071.004"
name = "DNS"
reference = "https://attack.mitre.org/techniques/T1071/004/"
[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[internal]
min_endpoint_version = "9.3.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 10s, correlated by process.entity_id.
Stage 1: process
[process where event.type == "start" and event.action == "exec" and (
process.executable like (
"./*", "/var/tmp/*", "/dev/shm/*", "/run/*", "/var/run/*", "/boot/*", "/sys/*",
"/lost+found/*", "/var/mail/*"
) or
process.name like ".*"
) and
not (
process.executable like (
"./usr/bin/podman", "./", "/dev/.buildkit_qemu_emulator", "/u01/*/webtier/ohs/bin/.apachectl",
"/usr/local/share/npm-global/lib/node_modules/opencode-ai/bin/.opencode",
"./usr/bin/qemu-aarch64-static", "/nix/store/*/bin/.opencode-wrapped", "/home/agent/.local/share/coursier/bin/.bloop.aux",
"/var/tmp/pamac-build-richard/*/bin/node", "/nix/store/*/bin/.rclone-wrapped", "/nix/store/*/bin/.glab-wrapped"
) or
(
process.executable like "/nix/store/*/bin/.gh-wrapped" and
process.command_line like "/home/*/.nix-profile/bin/gh *"
) or
(
process.executable == "./usr/bin/qemu-x86_64-static" and
process.command_line like "/usr/libexec/qemu-binfmt/x86_64-binfmt-P *"
) or
process.parent.executable in ("/usr/bin/skopeo", "/usr/bin/buildah") or
process.args == "datadog-ipc-helper" or
process.executable like (
"/nix/store/*claude-code-*/bin/.claude-wrapped",
"*/node_modules/@kilocode/cli/bin/.kilo"
)
)]
Stage 2: dns
[dns where event.action == "lookup_result" and dns.question.name != "localhost" and
not (
dns.question.name == "pypi.org" or
(process.executable like "/home/*/.elastic-ramen" and dns.question.name in ("registry.npmjs.org", "models.dev"))
)
]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
dns.question.name | ne |
| field:"QueryName" kind:ne value:"localhost" |
event.action | eq |
| field:"EventType" kind:eq |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.executable | wildcard |
| field:"Image" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:".*" |
Exclusions
The rule actively suppresses these predicates.
Entra ID Custom Domain Added or Verified
#Detects when a custom domain is added or verified in an Entra ID tenant. Adding and verifying a custom domain are precursor steps to configuring domain federation, which can be abused by adversaries to route authentication through an attacker-controlled identity provider (Golden SAML). In most organizations, custom domains are added infrequently and these events should be investigated to ensure they are part of a legitimate administrative workflow.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Resource Development |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Azure | Add unverified domain |
| Azure | Verify domain |
Rules Detecting the Same Action
These rules filter on the same operation.
- [Entra ID] Domain Federation Trust Settings Modified (Kusto)
- Azure AD New Custom Domain Added (Splunk)
- Azure AD New Federated Domain Added (Splunk)
- Azure Domain Federation Settings Modified (Sigma)
- Entra ID Domain Federation Configuration Change (Elastic)
- Modified domain federation trust settings (Kusto)
- New onmicrosoft domain added to tenant (Kusto)
- New Root Certificate Authority Added (Sigma)
Rule Body
[metadata]
creation_date = "2026/03/03"
integration = ["azure"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
Detects when a custom domain is added or verified in an Entra ID tenant. Adding and verifying a custom domain are
precursor steps to configuring domain federation, which can be abused by adversaries to route authentication through an
attacker-controlled identity provider (Golden SAML). In most organizations, custom domains are added infrequently and
these events should be investigated to ensure they are part of a legitimate administrative workflow.
"""
from = "now-9m"
index = ["filebeat-*", "logs-azure.auditlogs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Entra ID Custom Domain Added or Verified"
note = """## Triage and analysis
### Investigating Entra ID Custom Domain Added or Verified
This rule detects when a custom domain is added or verified in an Entra ID tenant. These are precursor steps required before an adversary can configure domain federation. While adding and verifying domains are legitimate administrative activities, they are infrequent in most organizations. When observed without a corresponding change request or IT workflow, they may indicate the early stages of a Golden SAML or BYOIDP (Bring Your Own Identity Provider) attack.
While adding and verifying domains are legitimate administrative activities, they are infrequent in most organizations. When observed without a corresponding change request or IT workflow, they may indicate the early stages of a Golden SAML or BYOIDP (Bring Your Own Identity Provider) attack.
### Possible investigation steps
- Review `azure.auditlogs.properties.initiated_by.user.userPrincipalName` and `ipAddress` to identify who performed the action and from where.
- For `"Add unverified domain"` events, check `azure.auditlogs.properties.target_resources.0.display_name` for the domain name that was added.
- Determine whether the domain is known to the organization or is potentially adversary-controlled.
- Check if a corresponding `"Verify domain"` event follows shortly after and from the same actor.
- Look for subsequent `"Set domain authentication"` or `"Set federation settings on domain"` events that would indicate the domain was federated — this escalates the severity significantly.
- Verify with the Global Administrator or IT team whether a domain addition was planned.
- Check DNS records for the domain to understand who owns it and when the verification TXT record was added.
- Review the `user_agent.original` field for the actor to determine if the change was made via the Azure Portal, Microsoft Graph API, or PowerShell, which may provide additional context on whether this was a manual or scripted action.
### False positive analysis
- Legitimate domain additions during initial tenant setup, organizational expansion, or mergers and acquisitions.
- IT administrators adding domains for new email routing, SharePoint vanity URLs, or multi-domain configurations.
- Automated provisioning systems that manage domain lifecycle.
- Validate with the identity or IT team before dismissing these events.
### Response and remediation
- If the domain addition is unauthorized, immediately remove the unverified or verified domain: `Remove-MgDomain -DomainId "<domain>"`.
- Investigate how the actor obtained privileges to add domains (requires Global Administrator or Domain Administrator role).
- Review the tenant for any other unauthorized changes made by the same actor using the `azure.correlation_id` or actor identity.
- If the domain was already federated, escalate to the response steps in the companion rule `Entra ID Domain Federation Configuration Change`.
- Restrict domain management operations by implementing PIM (Privileged Identity Management) for Global Administrator roles.
"""
references = [
"https://cloud.google.com/blog/topics/threat-intelligence/unc2452-merged-into-apt29",
"https://learn.microsoft.com/en-us/graph/api/domain-post-domains",
"https://learn.microsoft.com/en-us/graph/api/domain-verify",
"https://medium.com/tenable-techblog/roles-allowing-to-abuse-entra-id-federation-for-persistence-and-privilege-escalation-df9ca6e58360",
"https://securitylabs.datadoghq.com/articles/i-spy-escalating-to-entra-id-global-admin/",
]
risk_score = 21
rule_id = "7dc921db-4cd3-48ef-88bf-2bfa91f29f5c"
setup = """### Microsoft Entra ID Audit Logs
This rule requires the Azure integration with Microsoft Entra ID Audit Logs data stream ingesting in your Elastic Stack deployment. For more information, refer to the [Microsoft Entra ID Audit Logs integration documentation](https://www.elastic.co/docs/reference/integrations/azure/adlogs).
"""
severity = "low"
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",
"Tactic: Discovery",
"Tactic: Resource Development",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset: azure.auditlogs
and azure.auditlogs.properties.category: DirectoryManagement
and event.action: ("Add unverified domain" or "Verify domain")
and event.outcome: success
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1584"
name = "Compromise Infrastructure"
reference = "https://attack.mitre.org/techniques/T1584/"
[[rule.threat.technique.subtechnique]]
id = "T1584.001"
name = "Domains"
reference = "https://attack.mitre.org/techniques/T1584/001/"
[rule.threat.tactic]
id = "TA0042"
name = "Resource Development"
reference = "https://attack.mitre.org/tactics/TA0042/"
Stages and Predicates
Stage 1: query
data_stream.dataset: azure.auditlogs
and azure.auditlogs.properties.category: DirectoryManagement
and event.action: ("Add unverified domain" or "Verify domain")
and event.outcome: success
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
azure.auditlogs.properties.category | eq |
| field:"azure.auditlogs.properties.category" kind:eq value:"DirectoryManagement" |
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"azure.auditlogs" |
event.action | in |
| field:"EventType" kind:in |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"success" |
Entra ID Windows Hello for Business Credential Registered
#Identifies the first-seen registration of a Windows Hello for Business (WHfB) credential for a Microsoft Entra ID user from a given source ASN in a tenant, based on a prefixed historic window. Enrollment is commonly part of legitimate onboarding or passwordless rollout and is not inherently malicious. Adversaries who have obtained a token that satisfies fresh (NGC) multi-factor authentication, for example by borrowing an existing WHfB key or passkey, can also enroll their own WHfB credential to establish durable, phishing-resistant persistence that survives password resets and standard session revocation. Correlate first-seen enrollments with the sign-in and device state that preceded them.
Known False Positives
- Legitimate WHfB and passwordless onboarding commonly generate this event, especially for new users or users enrolling from a new network ASN. This rule fires only on first-seen combinations of tenant, user, and source ASN over 14 days. Investigate unexpected ASNs, users outside the enrollment population, or enrollments preceded by anomalous sign-ins.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Azure | Add Windows Hello for Business credential |
Rules Detecting the Same Action
These rules filter on the same operation.
- [Entra ID] Authentication Method Changed for Privileged Account (Kusto)
- Account Created and Deleted in Short Timeframe (Kusto)
- Account Created And Deleted Within A Close Time Frame (Sigma)
- Account created from non-approved sources (Kusto)
- Account created or deleted by non-approved user (Kusto)
- Addition of a Temporary Access Pass to a Privileged Account (Kusto)
- Authentication Method Changed for Privileged Account (Kusto)
- Authentication Methods Changed for Privileged Account (Kusto)
Rule Body
[metadata]
creation_date = "2026/08/07"
integration = ["azure"]
maturity = "production"
updated_date = "2026/08/07"
[rule]
author = ["Elastic"]
description = """
Identifies the first-seen registration of a Windows Hello for Business (WHfB) credential for a Microsoft Entra ID user
from a given source ASN in a tenant, based on a prefixed historic window. Enrollment is commonly part of legitimate
onboarding or passwordless rollout and is not inherently malicious. Adversaries who have obtained a token that satisfies
fresh (NGC) multi-factor authentication, for example by borrowing an existing WHfB key or passkey, can also enroll their
own WHfB credential to establish durable, phishing-resistant persistence that survives password resets and standard
session revocation. Correlate first-seen enrollments with the sign-in and device state that preceded them.
"""
false_positives = [
"""
Legitimate WHfB and passwordless onboarding commonly generate this event, especially for new users or users
enrolling from a new network ASN. This rule fires only on first-seen combinations of tenant, user, and source ASN
over 14 days. Investigate unexpected ASNs, users outside the enrollment population, or enrollments preceded by
anomalous sign-ins.
""",
]
from = "now-9m"
index = ["logs-azure.auditlogs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Entra ID Windows Hello for Business Credential Registered"
note = """## Triage and analysis
### Investigating Entra ID Windows Hello for Business Credential Registered
This is a first-seen (new_terms) signal: a WHfB credential was registered for a tenant/user/source-ASN combination not observed in the prior 14 days. Enrollment is often legitimate onboarding, but adversaries abuse the same action as persistence - after borrowing an existing WHfB key or passkey to satisfy fresh MFA, they enroll their own credential, which survives password resets and ordinary session revocation.
### Possible investigation steps
- Identify the target (`target_resources.0.user_principal_name`) and initiator (`initiated_by.user.userPrincipalName`), confirm whether WHfB enrollment was expected, and check whether the source ASN is new for that user.
- Correlate with `azure.signinlogs` shortly before for a deviceless WHfB/passkey sign-in, device-code flow, or attacker device registration/PRT issuance; an additional credential from a new ASN on an established account is more suspicious. Examine the preceding sign-in's source IP/geo and user agent for automation or hosting/VPS origins.
### False positive analysis
- First-time WHfB enrollment during onboarding/passwordless rollout is expected; repeat enrollments from the same tenant/user/ASN within 14 days don't fire.
- Users traveling or switching ISP/VPN may appear as a new ASN - validate against known networks before treating as suspicious.
### Response and remediation
- If unauthorized, delete the WHfB credential and any attacker-registered device via Graph or the Entra portal, revoke sessions and refresh tokens (delete devices first, to break device-bound PRT persistence), reset credentials, and re-enroll from a trusted device.
- Review the sign-in that authorized the enrollment to determine the initial access vector.
"""
references = ["https://dirkjanm.io/borrowing-windows-hello-keys/"]
risk_score = 21
rule_id = "8c6f8cca-f730-4cdd-93a7-d65f087a4116"
setup = """#### Required Microsoft Entra ID Audit Logs
This rule requires the Azure integration with Microsoft Entra ID Audit logs enabled and collected via Azure Event Hub.
"""
severity = "low"
tags = [
"Domain: Cloud",
"Domain: Identity",
"Platform: Entra ID",
"Use Case: Identity and Access Audit",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Rule Type: New Terms",
"Data Source: Azure",
"Data Source: Microsoft Entra ID",
"Data Source: Microsoft Entra ID Audit Logs",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
data_stream.dataset: "azure.auditlogs" and
azure.auditlogs.operation_name: "Add Windows Hello for Business credential" and
event.outcome: ("Success" or "success") and
azure.tenant_id: * and
azure.auditlogs.properties.initiated_by.user.userPrincipalName: * and
source.as.number: *
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[[rule.threat.technique.subtechnique]]
id = "T1098.001"
name = "Additional Cloud Credentials"
reference = "https://attack.mitre.org/techniques/T1098/001/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[rule.new_terms]
field = "new_terms_fields"
value = [
"azure.tenant_id",
"azure.auditlogs.properties.initiated_by.user.userPrincipalName",
"source.as.number",
]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-14d"
Stages and Predicates
Stage 1: new_terms
data_stream.dataset: "azure.auditlogs" and
azure.auditlogs.operation_name: "Add Windows Hello for Business credential" and
event.outcome: ("Success" or "success") and
azure.tenant_id: * and
azure.auditlogs.properties.initiated_by.user.userPrincipalName: * and
source.as.number: *
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
azure.auditlogs.operation_name | eq |
| field:"azure_ad::activity_display_name" kind:eq value:"Add Windows Hello for Business credential" |
azure.auditlogs.properties.initiated_by.user.userPrincipalName | is_not_null | field:"azure.auditlogs.properties.initiated_by.user.userPrincipalName" kind:is_not_null | |
azure.tenant_id | is_not_null | field:"azure.tenant_id" kind:is_not_null | |
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"azure.auditlogs" |
event.outcome | in |
| field:"event.outcome" kind:in |
source.as.number | is_not_null | field:"source.as.number" kind:is_not_null |
External IP Address Discovery via Curl
#Detects applications making a curl request to a known public IP address lookup web service. Malware commonly performs this action during reconnaissance to assess potential targets and identify the victim's external IP address.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Discovery |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2026/01/30"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/07/30"
[rule]
author = ["Elastic", "Massimo Bertocchi"]
description = """
Detects applications making a curl request to a known public IP address lookup web service. Malware commonly
performs this action during reconnaissance to assess potential targets and identify the victim's external
IP address.
"""
from = "now-9m"
index = ["logs-endpoint.events.process-*"]
language = "eql"
license = "Elastic License v2"
name = "External IP Address Discovery via Curl"
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 External IP Address Discovery via Curl
This rule detects macOS processes launching curl (or nscurl) to query common public “what is my IP” and geolocation services, often from unusual parent applications or untrusted/unsigned code. Attackers use this to learn the victim’s outward-facing address and network context to guide follow-on targeting, routing, or staging decisions. A typical pattern is a script or dropped binary spawning curl with a short command that hits ipify/ipinfo/ifconfig-style endpoints immediately after execution.
### Possible investigation steps
- Review the full process tree and timeline around the curl execution to identify the initiating app/script, preceding download or execution activity, and any rapid follow-on discovery or persistence commands.
- Examine the curl/nscurl command line and stdout/stderr capture (if available) to confirm the external-IP lookup intent and whether results were written to disk, environment variables, or passed to subsequent processes.
- Correlate with network telemetry for the same host and time window to verify the outbound connection, destination IP/ASN, DNS resolution, TLS/SNI details, and any additional unexpected egress to non-lookup infrastructure.
- Validate the provenance of the parent executable by checking its path, quarantine/notarization status, signature trust, and recent file creation/modification events to assess whether it was dropped or launched from a user-writable location.
- Hunt for repeat occurrences across the endpoint (and fleet) that share the same parent, script content, or destination services, then check for associated indicators like new launch agents/daemons, cron jobs, or suspicious login items.
### False positive analysis
- A user or admin runs a short shell one-liner (bash/zsh with an http-containing command line) that uses curl to quickly confirm the Mac’s external IP during routine troubleshooting, VPN verification, or connectivity checks.
- A legitimate but unsigned/not-yet-trusted macOS app launched from /Applications, a mounted /Volumes installer/dmg, or a temporary /private/var/folders path performs an external IP lookup via curl as part of initialization, telemetry, or network diagnostics.
### Response and remediation
- Isolate the affected Mac from the network if the curl/nscurl external-IP lookup is spawned by an unsigned/untrusted parent or from user-writable paths (e.g., /private/var/folders, mounted /Volumes) to prevent follow-on command-and-control.
- Quarantine and remove the initiating artifact (app/script/binary) and any associated installers or DMGs, then block its hash and the specific lookup domains contacted (e.g., ipinfo.io, api.ipify.org, ifconfig.me) at egress/DNS to stop repeat discovery.
- Hunt for and delete persistence created around the event (LaunchAgents/LaunchDaemons, login items, cron entries) and terminate any remaining suspicious processes that inherit environment/output from the curl call.
- Reset exposed credentials and invalidate active sessions if the same parent process also accessed browsers, keychain, SSH keys, or configuration files shortly before/after the lookup, and rotate VPN/API tokens used on the host.
- Reimage or restore the endpoint from a known-good snapshot if additional unknown binaries, repeated external-IP lookups, or unexpected outbound connections are observed after cleanup, then validate with a follow-up scan and a clean process baseline.
- Escalate to IR leadership immediately if the external-IP lookup is followed by downloads/execution, persistence creation, or connections to newly registered/rare domains, and harden by restricting curl execution for non-admin contexts and tightening macOS app execution controls (Gatekeeper/notarization).
"""
risk_score = 21
rule_id = "3ad362a9-40cb-4536-8f8b-6a8b5cc24d3c"
severity = "low"
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 = '''
process where host.os.type == "macos" and event.type == "start" and event.action == "exec" and
((process.parent.executable like ("/Applications/*", "/Volumes/*", "/private/var/folders/*")) or
(process.parent.name in ("bash", "sh", "zsh") and process.parent.command_line like "*http*") or
(process.parent.code_signature.trusted == false or process.parent.code_signature.exists == false or process.code_signature.exists == false)) and
process.name in ("curl", "nscurl") and
process.args_count <= 5 and
process.command_line like ("*ip-api.com*", "*ipwho.is*", "*checkip.dyndns.org*", "*api.ipify.org*",
"*whatismyip.akamai.com*", "*ifcfg.me*", "*ifconfig.me*", "*ident.me*",
"*icanhazip.com*", "*ipecho.net*", "*api.myip.com*", "*checkip.amazonaws.com*",
"*wtfismyip.com*", "*iplogger.*", "*freegeoip.net*", "*ipinfo.io*",
"*geoplugin.net*", "*httpbin.org*", "*myip.opendns.com*")
'''
[[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: process
process where host.os.type == "macos" and event.type == "start" and event.action == "exec" and
((process.parent.executable like ("/Applications/*", "/Volumes/*", "/private/var/folders/*")) or
(process.parent.name in ("bash", "sh", "zsh") and process.parent.command_line like "*http*") or
(process.parent.code_signature.trusted == false or process.parent.code_signature.exists == false or process.code_signature.exists == false)) and
process.name in ("curl", "nscurl") and
process.args_count <= 5 and
process.command_line like ("*ip-api.com*", "*ipwho.is*", "*checkip.dyndns.org*", "*api.ipify.org*",
"*whatismyip.akamai.com*", "*ifcfg.me*", "*ifconfig.me*", "*ident.me*",
"*icanhazip.com*", "*ipecho.net*", "*api.myip.com*", "*checkip.amazonaws.com*",
"*wtfismyip.com*", "*iplogger.*", "*freegeoip.net*", "*ipinfo.io*",
"*geoplugin.net*", "*httpbin.org*", "*myip.opendns.com*")
Indicators
These rows show field, operator, and value matches.
GCP Firewall Rule Creation
#Identifies when a firewall rule is created 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 create a new firewall rule in order to weaken their target's security controls and allow more permissive ingress or egress traffic flows for their benefit.
Known False Positives
- Firewall rules may be created 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 created 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 create a new firewall rule in order to weaken their target's security controls
and allow more permissive ingress or egress traffic flows for their benefit.
"""
false_positives = [
"""
Firewall rules may be created 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 Creation"
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 Creation
In GCP, firewall rules manage network traffic to and from VPCs and App Engine applications, crucial for maintaining security. Adversaries may exploit this by creating rules that permit unauthorized access, bypassing security measures. The detection rule monitors audit logs for specific actions indicating new rule creation, flagging potential defense evasion attempts to ensure timely investigation and response.
### Possible investigation steps
- Review the audit logs for the specific event.dataset:gcp.audit entries to identify the source of the firewall rule creation, focusing on the event.action fields: *.compute.firewalls.insert or google.appengine.*.Firewall.Create*Rule.
- Identify the user or service account responsible for the action by examining the actor information in the audit logs, such as the principalEmail field.
- Determine the network or application affected by the new firewall rule by analyzing the target resources, such as the VPC or App Engine application, to understand the potential impact.
- Assess the rule's configuration details, including the allowed or denied IP ranges, protocols, and ports, to evaluate if it introduces any security risks or deviates from established security policies.
- Check for any recent changes in permissions or roles assigned to the user or service account involved, which might indicate privilege escalation or misuse.
- Correlate the firewall rule creation event with other security events or alerts in the same timeframe to identify any suspicious patterns or activities that might suggest a coordinated attack.
- Consult with relevant stakeholders or teams to verify if the firewall rule creation was authorized and aligns with current operational requirements or projects.
### False positive analysis
- Routine administrative actions by authorized personnel can trigger alerts when they create or update firewall rules for legitimate purposes. To manage this, establish a list of known IP addresses or user accounts that frequently perform these actions and create exceptions for them in the detection rule.
- Automated processes or scripts that regularly update firewall configurations as part of normal operations may also cause false positives. Identify these processes and adjust the rule to exclude their specific actions or service accounts.
- Changes made during scheduled maintenance windows might be flagged as suspicious. Implement time-based exceptions to ignore rule creation events during these predefined periods.
- Integration with third-party security tools or services that modify firewall rules for enhanced protection can be mistaken for unauthorized activity. Verify these integrations and whitelist their actions to prevent unnecessary alerts.
- Development and testing environments often require frequent firewall rule changes, which can lead to false positives. Differentiate these environments from production by tagging them appropriately and excluding their events from the detection rule.
### Response and remediation
- Immediately review the newly created firewall rule to determine its source and intent. Verify if the rule aligns with organizational security policies and intended network configurations.
- Temporarily disable or delete the suspicious firewall rule to prevent unauthorized access while further investigation is conducted.
- Conduct a thorough audit of recent firewall rule changes in the affected GCP project to identify any other unauthorized modifications.
- Isolate affected systems or applications that may have been exposed due to the unauthorized firewall rule to prevent further exploitation.
- Notify the security operations team and relevant stakeholders about the incident for awareness and further action.
- Implement additional monitoring on the affected VPC or App Engine environment to detect any further unauthorized changes or suspicious activities.
- Review and update access controls and permissions for creating and modifying firewall rules to ensure only authorized personnel have the necessary privileges.
## 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 = 21
rule_id = "30562697-9859-4ae0-a8c5-dab45d664170"
severity = "low"
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.insert or google.appengine.*.Firewall.Create*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.insert or google.appengine.*.Firewall.Create*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 |
GCP Secret Manager ListSecrets Across Multiple Projects
#Detects a single identity listing Google Cloud Secret Manager secrets across many distinct projects in a short window. ListSecrets does not return secret values, but sweeping many projects is a common reconnaissance step before targeted AccessSecretVersion calls. Legitimate workloads typically list secrets within one project or a small set of projects; cross-project bursts from one user and source IP are uncommon outside security tooling or compromise.
Known False Positives
- Organization-wide security scanners, CSPM products, inventory jobs, or approved red-team exercises may list secrets across many projects. Validate the principal, source IP, user agent, and schedule against known tooling before treating the activity as malicious, and exclude documented automation identities when baselined.
- Platform or IAM administrators troubleshooting Secret Manager access across environments may briefly exceed the project cardinality threshold. Correlate with change tickets and expected administrative clients.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Discovery |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| GCP | google.cloud.secretmanager.SecretManagerService.ListSecrets: ListSecrets |
Rule Body
[metadata]
creation_date = "2026/08/12"
integration = ["gcp"]
maturity = "production"
updated_date = "2026/08/12"
[rule]
author = ["Elastic"]
description = """
Detects a single identity listing Google Cloud Secret Manager secrets across many distinct projects in a short window.
ListSecrets does not return secret values, but sweeping many projects is a common reconnaissance step before targeted
AccessSecretVersion calls. Legitimate workloads typically list secrets within one project or a small set of projects;
cross-project bursts from one user and source IP are uncommon outside security tooling or compromise.
"""
false_positives = [
"""
Organization-wide security scanners, CSPM products, inventory jobs, or approved red-team exercises may list secrets
across many projects. Validate the principal, source IP, user agent, and schedule against known tooling before
treating the activity as malicious, and exclude documented automation identities when baselined.
""",
"""
Platform or IAM administrators troubleshooting Secret Manager access across environments may briefly exceed the
project cardinality threshold. Correlate with change tickets and expected administrative clients.
""",
]
from = "now-6m"
interval = "5m"
language = "esql"
license = "Elastic License v2"
name = "GCP Secret Manager ListSecrets Across Multiple Projects"
note = """## Triage and analysis
### Investigating GCP Secret Manager ListSecrets Across Multiple Projects
This rule aggregates Secret Manager `ListSecrets` audit events per `client.user.email` and `source.ip` over the rule
lookback. It alerts when the same actor lists secrets in 10 or more distinct `cloud.project.id` values. Listing does
not retrieve secret payloads, but multi-project enumeration is a strong discovery signal ahead of credential access.
### Possible investigation steps
- Review `Esql.cloud_project_id_values` to identify which projects were
enumerated and whether they include high-value or production workloads.
- Confirm whether `client.user.email`, `source.ip`, and
`Esql.user_agent_original_values` match expected administrators, CI/CD, or approved security scanners.
- Check `Esql.event_outcome_values` for mixed success and failure, which can indicate permission probing across projects
the identity cannot fully access.
- Hunt for follow-on Secret Manager activity from the same identity or IP, especially
`AccessSecretVersion`, `GetSecret`, and IAM policy changes on secrets or projects.
- Bound the burst with `Esql.earliest_timestamp` and `Esql.latest_timestamp`, then pivot in Discover on the same
`client.user.email` / `source.ip` for related GCP audit activity.
### False positive analysis
- Documented CSPM, secret inventory, or compliance scanners that walk many projects will match; exclude those
principals after validation.
- Break-glass or org-admin troubleshooting can look similar; require change-management correlation before raising
severity.
### Response and remediation
- If unauthorized, revoke or rotate the implicated credentials, review IAM bindings that grant
`secretmanager.secrets.list` across projects, and inspect for subsequent secret access or exfiltration.
- Restrict Secret Manager list permissions to least privilege and prefer per-project roles over org-wide grants for
human users.
"""
setup = """The GCP Fleet integration (or Filebeat module) with audit logs for Secret Manager is required. `ListSecrets` is a
data-access method; enable DATA_READ audit logging for the Secret Manager API so these events are ingested into
`logs-gcp.audit-*`.
See [Secret Manager audit logging](https://cloud.google.com/secret-manager/docs/audit-logging) and
[Configure Data Access audit logs](https://cloud.google.com/logging/docs/audit/configure-data-access).
"""
references = [
"https://cloud.google.com/secret-manager/docs/reference/rest/v1/projects.secrets/list",
]
risk_score = 73
rule_id = "642ac343-e7d6-4cf2-bb0b-7db412e614ad"
severity = "high"
tags = [
"Domain: Cloud",
"Data Source: GCP",
"Data Source: Google Cloud Platform",
"Data Source: GCP Audit Logs",
"Use Case: Threat Detection",
"Tactic: Discovery",
"Resources: Investigation Guide",
"Rule Type: ESQL",
"Platform: GCP",
"Service: GCP Secret Manager",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-gcp.audit-* metadata _id, _version, _index
| where data_stream.dataset == "gcp.audit"
and event.action == "google.cloud.secretmanager.v1.SecretManagerService.ListSecrets"
and cloud.project.id is not null
and client.user.email is not null
and source.ip is not null
| stats
Esql.cloud_project_id_count_distinct = count_distinct(cloud.project.id),
Esql.cloud_project_id_values = values(cloud.project.id),
Esql.event_count = count(*),
Esql.event_outcome_values = values(event.outcome),
Esql.client_user_id_values = values(client.user.id),
Esql.user_agent_original_values = values(user_agent.original),
Esql.earliest_timestamp = min(@timestamp),
Esql.latest_timestamp = max(@timestamp)
by client.user.email, source.ip, data_stream.namespace
| where Esql.cloud_project_id_count_distinct >= 10
| keep
client.user.email,
source.ip,
Esql.cloud_project_id_count_distinct,
Esql.cloud_project_id_values,
Esql.event_count,
Esql.event_outcome_values,
Esql.client_user_id_values,
Esql.user_agent_original_values,
Esql.earliest_timestamp,
Esql.latest_timestamp,
data_stream.namespace
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1526"
name = "Cloud Service Discovery"
reference = "https://attack.mitre.org/techniques/T1526/"
[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
Stages and Predicates
Stage 1: from
from logs-gcp.audit-* metadata _id, _version, _index
Stage 2: where
| where data_stream.dataset == "gcp.audit"
and event.action == "google.cloud.secretmanager.v1.SecretManagerService.ListSecrets"
and cloud.project.id is not null
and client.user.email is not null
and source.ip is not null
Stage 3: stats
| stats
Esql.cloud_project_id_count_distinct = count_distinct(cloud.project.id),
Esql.cloud_project_id_values = values(cloud.project.id),
Esql.event_count = count(*),
Esql.event_outcome_values = values(event.outcome),
Esql.client_user_id_values = values(client.user.id),
Esql.user_agent_original_values = values(user_agent.original),
Esql.earliest_timestamp = min(@timestamp),
Esql.latest_timestamp = max(@timestamp)
by client.user.email, source.ip, data_stream.namespace
Stage 4: where
| where Esql.cloud_project_id_count_distinct >= 10
Stage 5: keep
| keep
client.user.email,
source.ip,
Esql.cloud_project_id_count_distinct,
Esql.cloud_project_id_values,
Esql.event_count,
Esql.event_outcome_values,
Esql.client_user_id_values,
Esql.user_agent_original_values,
Esql.earliest_timestamp,
Esql.latest_timestamp,
data_stream.namespace
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Esql.cloud_project_id_count_distinct | ge |
| field:"Esql.cloud_project_id_count_distinct" kind:ge value:"10" |
client.user.email | is_not_null | field:"client.user.email" kind:is_not_null | |
cloud.project.id | is_not_null | field:"cloud.project.id" kind:is_not_null | |
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"gcp.audit" |
event.action | eq |
| field:"EventType" kind:eq value:"google.cloud.secretmanager.v1.SecretManagerService.ListSecrets" |
source.ip | is_not_null | field:"src_ip" kind:is_not_null |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
client.user.email | KEEP client.user.email |
source.ip | KEEP source.ip |
Esql.cloud_project_id_count_distinct | KEEP Esql.cloud_project_id_count_distinct |
Esql.cloud_project_id_values | KEEP Esql.cloud_project_id_values |
Esql.event_count | KEEP Esql.event_count |
Esql.event_outcome_values | KEEP Esql.event_outcome_values |
Esql.client_user_id_values | KEEP Esql.client_user_id_values |
Esql.user_agent_original_values | KEEP Esql.user_agent_original_values |
Esql.earliest_timestamp | KEEP Esql.earliest_timestamp |
Esql.latest_timestamp | KEEP Esql.latest_timestamp |
data_stream.namespace | KEEP data_stream.namespace |
GitHub Repo Created
#A new GitHub repository was created.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Resource Development | |
| Execution |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| GitHub | Audit log action repo.create: Repository created |
Rules Detecting the Same Action
These rules filter on the same operation.
- GitHub - Repository was created (Kusto)
- Github Public Repository Created (Panther)
- GitHub Repository Created (Panther)
- NX Supply Chain - S1ngularity Repository Detection (Panther)
Rule Body
[metadata]
bypass_bbr_timing = true
creation_date = "2023/10/11"
integration = ["github"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
building_block_type = "default"
description = "A new GitHub repository was created.\n"
from = "now-9m"
index = ["logs-github.audit-*"]
language = "eql"
license = "Elastic License v2"
name = "GitHub Repo Created"
risk_score = 21
rule_id = "6cea88e4-6ce2-4238-9981-a54c140d6336"
severity = "low"
tags = [
"Domain: Cloud",
"Use Case: Threat Detection",
"Use Case: UEBA",
"Tactic: Execution",
"Rule Type: BBR",
"Data Source: Github",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
configuration where event.dataset == "github.audit" and event.action == "repo.create"
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1648"
name = "Serverless Execution"
reference = "https://attack.mitre.org/techniques/T1648/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1583"
name = "Acquire Infrastructure"
reference = "https://attack.mitre.org/techniques/T1583/"
[[rule.threat.technique.subtechnique]]
id = "T1583.006"
name = "Web Services"
reference = "https://attack.mitre.org/techniques/T1583/006/"
[rule.threat.tactic]
id = "TA0042"
name = "Resource Development"
reference = "https://attack.mitre.org/tactics/TA0042/"
Stages and Predicates
Stage 1: configuration
configuration where event.dataset == "github.audit" and event.action == "repo.create"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"repo.create" |
event.dataset | eq |
| field:"event.dataset" kind:eq value:"github.audit" |
Google Workspace API Access Granted via Domain-Wide Delegation
#Detects when a super administrator authorizes domain-wide delegation (DWD) API client access for a Google Cloud service account or OAuth client. DWD lets an application impersonate users and access Workspace APIs across the tenant. Adversaries with admin access may register or authorize a malicious client with broad scopes to maintain API-based persistence and access mail, drive, and directory data without relying on a single user's password alone.
Known False Positives
- Domain-wide delegation of authority may be granted to service accounts by system administrators. Verify that the configuration change was expected. Exceptions can be added to this rule to filter expected behavior.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Privilege Escalation |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Google Workspace | AUTHORIZE_API_CLIENT_ACCESS: API Client Access Authorize |
Rule Body
[metadata]
creation_date = "2020/11/12"
integration = ["google_workspace"]
maturity = "production"
updated_date = "2026/07/08"
[rule]
author = ["Elastic"]
description = """
Detects when a super administrator authorizes domain-wide delegation (DWD) API client access for a Google Cloud service
account or OAuth client. DWD lets an application impersonate users and access Workspace APIs across the tenant.
Adversaries with admin access may register or authorize a malicious client with broad scopes to maintain API-based
persistence and access mail, drive, and directory data without relying on a single user's password alone.
"""
false_positives = [
"""
Domain-wide delegation of authority may be granted to service accounts by system administrators. Verify that the
configuration change was expected. Exceptions can be added to this rule to filter expected behavior.
""",
]
from = "now-130m"
interval = "10m"
index = ["filebeat-*", "logs-google_workspace.admin-*"]
language = "kuery"
license = "Elastic License v2"
name = "Google Workspace API Access Granted via Domain-Wide Delegation"
note = """## Triage and analysis
### Investigating Google Workspace API Access Granted via Domain-Wide Delegation
Domain-wide delegation (DWD) allows a Google Cloud service account or OAuth client to access Workspace user data on
behalf of users across the domain. Only super administrators can authorize DWD, and each grant specifies API scopes
that define what the client can read or modify (for example Gmail, Drive, Directory, or Calendar APIs). Over-scoped DWD
grants create durable third-party access paths that survive individual user password resets.
This rule matches `AUTHORIZE_API_CLIENT_ACCESS` events in the `google_workspace.admin` data stream.
### Possible investigation steps
- Identify the administrator who authorized access by reviewing `user.email` or `user.name`, and note `user.domain` and
`event.ingested` if present in the alert.
- Identify the authorized client by reviewing `google_workspace.admin.api.client.name` and confirm the affected tenant
with `google_workspace.admin.domain.name`.
- Review granted API scopes in `google_workspace.admin.api.scopes` against least-privilege expectations. Broad scopes
(for example full mail or drive access) warrant higher urgency.
- Determine whether the change is expected and authorized:
- Validate there is an approved change request or vendor onboarding record for the client and scopes.
- If the actor account is unusual or the scopes exceed documented requirements, treat as higher priority until proven benign.
- Review DWD configuration in the Google Admin console:
- Sign in to [admin.google.com](https://admin.google.com) with an authorized administrator account.
- Navigate to Security > Access and data control > API controls > Domain-wide delegation.
- Confirm the client ID, client name, and scopes match the alert fields.
- Search Kibana for related admin activity:
- Find other DWD grants or revocations by the same administrator:
```
data_stream.dataset: "google_workspace.admin" and user.email: "<ACTOR_EMAIL>" and event.action: ("AUTHORIZE_API_CLIENT_ACCESS" or "REVOKE_API_CLIENT_ACCESS")
```
- Scope for all grants to the same API client:
```
data_stream.dataset: "google_workspace.admin" and event.action: "AUTHORIZE_API_CLIENT_ACCESS" and google_workspace.admin.api.client.name: "<CLIENT_NAME>"
```
- Correlate with other high-risk admin actions from the same actor in the last 48 hours:
```
data_stream.dataset: "google_workspace.admin" and user.email: "<ACTOR_EMAIL>" and event.action: ("ASSIGN_ROLE" or "ADD_APPLICATION" or "CREATE_ROLE")
```
- If GCP audit logs are ingested, pivot on the service account or client:
- Search for the client name in `gcp.audit.resource_name` and review `event.action` over the last 48 hours to determine
how the service account is being used after authorization.
### False positive analysis
- Platform or security teams may authorize DWD for approved automation, backup, or migration tooling — validate against
known service accounts and documented scope requirements.
- Vendor onboarding sometimes requires temporary broad scopes; confirm timing against change windows before closing as benign.
### Response and remediation
- Initiate the incident response process based on triage findings.
- If the grant is not clearly authorized, revoke domain-wide delegation for the client under Security > Access and data
control > API controls > Domain-wide delegation while the investigation proceeds.
- Rotate or disable the associated GCP service account keys if the client is suspected malicious.
- If the initiating admin account is suspected compromised, reset credentials, revoke active sessions, and review
delegated admin roles assigned to that account.
- Review activity performed with the authorized client based on scopes in `google_workspace.admin.api.scopes`.
- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context:
- Identify the account role in the cloud environment.
- Assess the criticality of affected services and servers.
- Work with your IT team to identify and minimize the impact on users.
- Identify if the attacker is moving laterally and compromising other accounts, servers, or services.
- Identify any regulatory or legal ramifications related to this activity.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords or delete API keys as needed to revoke the attacker's access to the environment. Work with your IT teams to minimize the impact on business operations during these actions.
- Review the permissions assigned to the implicated administrator to ensure that the least privilege principle is being followed.
- Implement security best practices [outlined](https://support.google.com/a/answer/7587183) by Google.
- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
## Setup
The Google Workspace Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.
### Important Information Regarding Google Workspace Event Lag Times
- As per Google's documentation, Google Workspace administrators may observe lag times ranging from minutes up to 3 days between the time of an event's occurrence and the event being visible in the Google Workspace admin/audit logs.
- This rule is configured to run every 10 minutes with a lookback time of 130 minutes.
- To reduce the risk of false negatives, consider reducing the interval that the Google Workspace (formerly G Suite) Filebeat module polls Google's reporting API for new events.
- By default, `var.interval` is set to 2 hours (2h). Consider changing this interval to a lower value, such as 10 minutes (10m).
- See the following references for further information:
- https://support.google.com/a/answer/7061566
- https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-module-google_workspace.html"""
references = [
"https://developers.google.com/admin-sdk/directory/v1/guides/delegation",
"https://www.elastic.co/security-labs/google-workspace-attack-surface-part-one",
"https://www.elastic.co/security-labs/google-workspace-attack-surface-part-two"
]
risk_score = 73
rule_id = "acbc8bb9-2486-49a8-8779-45fb5f9a93ee"
severity = "high"
tags = [
"Domain: Cloud",
"Data Source: Google Workspace",
"Use Case: Identity and Access Audit",
"Resources: Investigation Guide",
"Tactic: Persistence",
"Tactic: Privilege Escalation",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:google_workspace.admin
and event.action:AUTHORIZE_API_CLIENT_ACCESS
'''
[rule.investigation_fields]
field_names = [
"user.name",
"user.email",
"user.domain",
"event.action",
"google_workspace.admin.api.client.name",
"google_workspace.admin.api.scopes",
"google_workspace.admin.domain.name",
]
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
Stages and Predicates
Stage 1: query
data_stream.dataset:google_workspace.admin
and event.action:AUTHORIZE_API_CLIENT_ACCESS
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"google_workspace.admin" |
event.action | eq |
| field:"EventType" kind:eq value:"AUTHORIZE_API_CLIENT_ACCESS" |
Google Workspace Device Registration After OAuth from Suspicious ASN
#Detects when a Google Workspace account completes OAuth authorization for a specific Google OAuth client from a high-risk autonomous system number (ASN), followed within 30 seconds by a device registration event with account state REGISTERED. This sequence can indicate device enrollment or join flows initiated from attacker-controlled or residential-proxy infrastructure after a user authorizes a sensitive client.
Known False Positives
- Users on VPNs, carrier NAT, or cloud egress that map to flagged ASNs may match. Legitimate bulk enrollment or scripted onboarding that uses the same OAuth client can also produce the sequence. Baseline `source.as.organization.name` and successful registration sources before adding exclusions.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Persistence |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Google Workspace | OAuth Token audit event authorize: Application access authorized |
Rules Detecting the Same Action
These rules filter on the same operation.
- First Time Seen Google Workspace OAuth Login from Third-Party Application (Elastic)
- Google Workspace OAuth Token Requests from New IP (Panther)
- Google Workspace OAuth Token Requests from New IPs (Panther)
- Google Workspace Object Copied from External Drive with App Consent (Elastic)
- Google Workspace User Login with Unusual ASN (Elastic)
Rule Body
[metadata]
creation_date = "2026/05/15"
integration = ["google_workspace"]
maturity = "production"
updated_date = "2026/05/15"
[rule]
author = ["Elastic"]
description = """
Detects when a Google Workspace account completes OAuth authorization for a specific Google OAuth client from a
high-risk autonomous system number (ASN), followed within 30 seconds by a device registration event with account state
REGISTERED. This sequence can indicate device enrollment or join flows initiated from attacker-controlled or
residential-proxy infrastructure after a user authorizes a sensitive client.
"""
false_positives = [
"""
Users on VPNs, carrier NAT, or cloud egress that map to flagged ASNs may match. Legitimate bulk enrollment or
scripted onboarding that uses the same OAuth client can also produce the sequence. Baseline `source.as.organization.name`
and successful registration sources before adding exclusions.
""",
]
from = "now-15m"
index = ["logs-google_workspace*"]
interval = "5m"
language = "eql"
license = "Elastic License v2"
name = "Google Workspace Device Registration After OAuth from Suspicious ASN"
note = """## Triage and analysis
### Investigating Google Workspace Device Registration After OAuth from Suspicious ASN
Review `user.name`, `user.email`, `source.ip`, `source.as.organization.name`, `google_workspace.token.client.id`,
`google_workspace.token.app_name`, and device fields on the second event (for example device display name or ID if
present in your schema).
Confirm whether the user intentionally registered a device and whether the OAuth client and ASN are expected for your
mobile device management or enrollment program.
### Possible investigation steps
- Correlate both events on `user.name` and timestamps to confirm the sequence is a single enrollment story.
- Revoke or audit OAuth grants for the client if the authorization was not expected.
- Search for additional `google_workspace.device` registrations from the same ASN in the same period.
### Response and remediation
- If malicious, remove the unauthorized device from the Google Admin console, reset the user password, and revoke
active sessions and tokens per incident policy.
- Restrict device registration and review OAuth app access policies.
## Setup
The Google Workspace Fleet integration or Filebeat Google Workspace module must ingest `google_workspace.token` and
`google_workspace.device` audit streams.
### Event lag
Google Workspace audit data can lag minutes to days behind real time. If sequences are missed, increase `from` and
lower the integration poll interval per Google and Elastic documentation.
"""
references = [
"https://www.elastic.co/security-labs/google-workspace-attack-surface-part-one",
"https://support.google.com/a/answer/7061566",
]
risk_score = 73
rule_id = "012bfca7-45cb-4507-a3ba-3777167f8b81"
severity = "high"
tags = [
"Domain: Cloud",
"Data Source: Google Workspace",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Tactic: Initial Access",
"Threat: Tycoon2FA",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
sequence by user.name with maxspan=30s
[iam where data_stream.dataset == "google_workspace.token" and event.action == "authorize" and
google_workspace.token.client.id == "77185425430.apps.googleusercontent.com" and
source.as.number in (9009, 45102, 215540, 29802, 62240, 204957, 395092)]
[any where data_stream.dataset == "google_workspace.device" and google_workspace.device.account_state == "REGISTERED"]
'''
[[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 = "T1566"
name = "Phishing"
reference = "https://attack.mitre.org/techniques/T1566/"
[[rule.threat.technique.subtechnique]]
id = "T1566.002"
name = "Spearphishing Link"
reference = "https://attack.mitre.org/techniques/T1566/002/"
[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
Stages and Predicates
Ordered sequence: each step below must occur in order within 30s, correlated by user.name.
Stage 1: iam
[iam where data_stream.dataset == "google_workspace.token" and event.action == "authorize" and
google_workspace.token.client.id == "77185425430.apps.googleusercontent.com" and
source.as.number in (9009, 45102, 215540, 29802, 62240, 204957, 395092)]
Stage 2: any
[any where data_stream.dataset == "google_workspace.device" and google_workspace.device.account_state == "REGISTERED"]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq |
event.action | eq |
| field:"EventType" kind:eq value:"authorize" |
google_workspace.device.account_state | eq |
| field:"gws::device_account_state" kind:eq value:"REGISTERED" |
google_workspace.token.client.id | eq |
| field:"gws::token_client_id" kind:eq value:"77185425430.apps.googleusercontent.com" |
source.as.number | in |
| field:"source.as.number" kind:in |
LSASS Access Attempt from an Unsigned Executable
#Identifies attempt to access the Local Security Authority Subsystem Service (LSASS) by an unsigned process that was recently dropped. Adversaries may attempt to access credential material stored in the process memory of LSASS.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Rule Body
[rule]
description = """
Identifies attempt to access the Local Security Authority Subsystem Service (LSASS) by an unsigned process that was
recently dropped. Adversaries may attempt to access credential material stored in the process memory of LSASS.
"""
id = "6661d3b1-0baa-413c-9843-d83b8f9baaee"
license = "Elastic License v2"
name = "LSASS Access Attempt from an Unsigned Executable"
os_list = ["windows"]
reference = ["https://www.elastic.co/security-labs/bits-and-bytes-analyzing-bitsloth"]
version = "1.0.16"
query = '''
sequence by process.entity_id with maxspan=5m
[process where event.action == "start" and
(process.Ext.relative_file_creation_time <= 500 or process.Ext.relative_file_name_modify_time <= 500) and
not process.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*") and
not process.hash.sha256 : "1c6af94b26f369e2c10819eefb869f873e5540e2c1b7bf4c7c632fc03d67368a"]
[credential_access where
startswith~(process.thread.Ext.call_stack_final_user_module.path, process.executable)]
'''
min_endpoint_version = "8.7.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1003"
name = "OS Credential Dumping"
reference = "https://attack.mitre.org/techniques/T1003/"
[[threat.technique.subtechnique]]
id = "T1003.001"
name = "LSASS Memory"
reference = "https://attack.mitre.org/techniques/T1003/001/"
[threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[internal]
min_endpoint_version = "8.7.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 5m, correlated by process.entity_id.
Stage 1: process
[process where event.action == "start" and
(process.Ext.relative_file_creation_time <= 500 or process.Ext.relative_file_name_modify_time <= 500) and
not process.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*") and
not process.hash.sha256 : "1c6af94b26f369e2c10819eefb869f873e5540e2c1b7bf4c7c632fc03d67368a"]
Stage 2: credential_access
[credential_access where
startswith~(process.thread.Ext.call_stack_final_user_module.path, process.executable)]
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.code_signature.status | wildcard | trusted, errorExpired, errorCode_endpoint* | excludes:process.code_signature.status field:"process.code_signature.status" value:"trusted" field:"process.code_signature.status" value:"errorExpired" field:"process.code_signature.status" value:"errorCode_endpoint*" |
process.hash.sha256 | eq | 1c6af94b26f369e2c10819eefb869f873e5540e2c1b7bf4c7c632fc03d67368a | excludes:process.hash.sha256 field:"process.hash.sha256" value:"1c6af94b26f369e2c10819eefb869f873e5540e2c1b7bf4c7c632fc03d67368a" |
New Okta Authentication Behavior Detected
#Detects events where Okta behavior detection has identified a new authentication behavior.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
Rule Body
[metadata]
bypass_bbr_timing = true
creation_date = "2023/11/07"
integration = ["okta"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
building_block_type = "default"
description = "Detects events where Okta behavior detection has identified a new authentication behavior."
from = "now-9m"
index = ["logs-okta.system-*"]
language = "kuery"
license = "Elastic License v2"
name = "New Okta Authentication Behavior Detected"
note = """## Triage and analysis
### Investigating New Okta Authentication Behavior Detected
This rule detects events where Okta behavior detection has identified a new authentication behavior such as a new device or location.
#### Possible investigation steps:
- Identify the user involved in this action by examining the `okta.actor.id`, `okta.actor.type`, `okta.actor.alternate_id`, and `okta.actor.display_name` fields.
- Determine the authentication anomaly by examining the `okta.debug_context.debug_data.risk_behaviors` and `okta.debug_context.debug_data.flattened` fields.
- Determine the client used by the actor. Review the `okta.client.ip`, `okta.client.user_agent.raw_user_agent`, `okta.client.zone`, `okta.client.device`, and `okta.client.id` fields.
- If the client is a device, check the `okta.device.id`, `okta.device.name`, `okta.device.os_platform`, `okta.device.os_version`, and `okta.device.managed` fields.
- Review the past activities of the actor involved in this action by checking their previous actions.
- Examine the `okta.request.ip_chain` field to potentially determine if the actor used a proxy or VPN to perform this action.
- Evaluate the actions that happened just before and after this event in the `okta.event_type` field to help understand the full context of the activity.
### False positive analysis:
- A user may be using a new device or location to sign in.
- The Okta behavior detection may be incorrectly identifying a new authentication behavior and need adjusted.
### Response and remediation:
- If the user is legitimate and the authentication behavior is not suspicious, no action is required.
- If the user is legitimate but the authentication behavior is suspicious, consider resetting the user's password and enabling multi-factor authentication (MFA).
- If MFA is already enabled, consider resetting MFA for the user.
- If the user is not legitimate, consider deactivating the user's account.
- If this is a false positive, consider adjusting the Okta behavior detection settings.
- Block the IP address or device used in the attempts if they appear suspicious, using the data from the `okta.client.ip` and `okta.device.id` fields.
- Conduct a review of Okta policies and ensure they are in accordance with security best practices.
## Setup
The Okta Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.
"""
references = [
"https://www.elastic.co/security-labs/testing-okta-visibility-and-detection-dorothy",
"https://sec.okta.com/articles/2023/08/cross-tenant-impersonation-prevention-and-detection",
"https://unit42.paloaltonetworks.com/muddled-libra/",
"https://help.okta.com/oie/en-us/content/topics/security/behavior-detection/about-behavior-detection.htm",
"https://www.elastic.co/security-labs/monitoring-okta-threats-with-elastic-security",
"https://www.elastic.co/security-labs/starter-guide-to-understanding-okta",
]
risk_score = 21
rule_id = "260486ee-7d98-11ee-9599-f661ea17fbcd"
severity = "low"
tags = [
"Use Case: Identity and Access Audit",
"Tactic: Initial Access",
"Data Source: Okta",
"Resources: Investigation Guide",
"Rule Type: BBR",
"Domain: Identity"
]
timestamp_override = "event.ingested"
type = "query"
query = '''
event.dataset:okta.system and okta.debug_context.debug_data.risk_behaviors:*
'''
[[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: query
event.dataset:okta.system and okta.debug_context.debug_data.risk_behaviors:*
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.dataset | eq |
| field:"event.dataset" kind:eq value:"okta.system" |
okta.debug_context.debug_data.risk_behaviors | is_not_null | field:"okta.debug_context.debug_data.risk_behaviors" kind:is_not_null |
Payload Downloaded by Interpreter and Piped to Interpreter
#This rule detects when a payload is downloaded by an interpreter, and piped to an interpreter. Attackers may use this technique to download and execute payloads for various malicious purposes, such as establishing persistence or exfiltrating data.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Command & Control |
Rule Body
[metadata]
creation_date = "2026/07/02"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/07/20"
[rule]
author = ["Elastic"]
description = """
This rule detects when a payload is downloaded by an interpreter, and piped to an interpreter. Attackers may use this
technique to download and execute payloads for various malicious purposes, such as establishing persistence or
exfiltrating data.
"""
from = "now-9m"
index = ["logs-endpoint.events.network*", "logs-endpoint.events.process*"]
language = "eql"
license = "Elastic License v2"
name = "Payload Downloaded by Interpreter and Piped to Interpreter"
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 Payload Downloaded by Interpreter and Piped to Interpreter
This rule flags a Linux interpreter that reaches out to an external address and then immediately starts another interpreter with no script argument, a strong sign that downloaded content is being fed directly into code execution. Attackers use this to avoid writing files and blend into admin activity, for example by having Python fetch a remote shell script with urllib and pipe the response into `sh` or `bash` to run a stager in memory.
### Possible investigation steps
- Reconstruct the full process lineage and execution context, including the initiating user, shell history, service unit, cron job, container entrypoint, or remote session that triggered the download-and-execute chain, to distinguish sanctioned automation from attacker activity.
- Validate the remote endpoint by reviewing DNS, proxy, HTTP/TLS, and reputation data for the contacted infrastructure and compare it with known package mirrors, internal tooling, and recent maintenance activity to quickly identify likely benign installers versus suspicious staging hosts.
- Attempt to recover the downloaded payload from proxy caches, packet capture, endpoint telemetry, memory, or command history and analyze its behavior to determine whether it is a legitimate bootstrap script or a stager that enables persistence, credential theft, or additional downloads.
- Investigate post-alert activity on the host for concrete follow-on actions such as writes to temporary or startup locations, cron or systemd persistence, new accounts, SSH key changes, privilege escalation, lateral movement tooling, or security-control tampering.
- If the activity cannot be confidently tied to approved administration, isolate the system and pivot across the environment for the same parent-child lineage, remote infrastructure, script fragments, and resulting artifacts to scope impact and block recurrence.
### False positive analysis
- Legitimate provisioning or maintenance on a Linux host may use a shell or Python one-liner to download an installation or update script from an approved external repository and pipe it to `sh` or `bash`; verify the parent process aligns with a known admin action or change window and that the destination and script content match an approved baseline.
- Scheduled automation can trigger this when a service account or system task fetches a small bootstrap script from a sanctioned internet endpoint and feeds it directly to an interpreter during deployment or configuration refresh; verify it was started by the expected cron or systemd context and that the same process lineage and destination recur consistently across managed hosts.
### Response and remediation
- Isolate the affected Linux host from the network while preserving forensic access, stop the active interpreter chain, and block the contacted external IPs, domains, and download URLs at egress controls to prevent reinfection.
- Remove attacker footholds created by the downloaded script, including malicious cron entries, systemd services or timers, `/etc/rc.local` changes, shell profile modifications, unauthorized `authorized_keys` entries, and payloads dropped in `/tmp`, `/var/tmp`, `/dev/shm`, or user home directories.
- Revoke access the payload may have exposed by resetting passwords, rotating SSH keys, API tokens, and application secrets present on the host, and disabling any unauthorized local or service accounts created during the intrusion.
- Restore the host to a known-good state by rebuilding or reimaging from a trusted baseline or verified backup, applying current security patches, and validating that only approved packages, startup items, and scheduled tasks remain before reconnecting it to production.
- Escalate to incident response immediately if the script executed as root, the same download source or script fragment appears on multiple hosts, authentication material was accessed or modified, or you observe follow-on behaviors such as lateral movement, data staging, or persistent outbound beaconing.
- Harden the environment by restricting direct internet access from interpreters and automation accounts, allowlisting approved package mirrors and script repositories, enforcing least privilege for service users, and alerting on future `curl` or `wget` to shell and interpreter-to-interpreter execution patterns.
"""
risk_score = 47
rule_id = "5dc3519c-1f56-42fc-9a70-7e6b705c2781"
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: Execution",
"Tactic: Command and Control",
"Tactic: Defense Evasion",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
type = "eql"
query = '''
sequence by host.id, process.parent.entity_id, process.working_directory with maxspan=1s
[network where host.os.type == "linux" and event.type == "start" and event.action == "connection_attempted" and (
process.name like (
"bash", "dash", "sh", "tcsh", "tclsh", "wish", "csh", "zsh", "ksh", "fish",
"mksh", "busybox", "rscript", "r", "julia", "mono", "dotnet", "groovy", "kotlin",
"scala", "erlang", "escript", "ocaml", "ocamlopt", "ld.so", "ld-linux-x86-64.so.2",
"ld-musl-x86_64.so.1", "awk", "gawk", "mawk", "nawk", "node", "nodejs", "deno",
"env", "timeout", "nice", "stdbuf", "setsid", "setarch", "unshare", "nsenter", "flock",
"runuser", "sudo", "snap"
) or
process.name like ("python*", "perl*", "ruby*", "lua*", "php*", "qemu-*-static")
) and
not (destination.ip == null or destination.ip == "0.0.0.0" or cidrmatch(
destination.ip, "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24", "192.0.0.0/29",
"192.0.0.8/32", "192.0.0.9/32", "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24",
"192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", "224.0.0.0/4", "100.64.0.0/10",
"192.175.48.0/24","198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1", "FE80::/10",
"FF00::/8"
)
)]
[process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and (
process.name like (
"bash", "dash", "sh", "tcsh", "tclsh", "wish", "csh", "zsh", "ksh", "fish",
"mksh", "busybox", "rscript", "r", "julia", "mono", "dotnet", "groovy", "kotlin",
"scala", "erlang", "escript", "ocaml", "ocamlopt", "ld.so", "ld-linux-x86-64.so.2",
"ld-musl-x86_64.so.1", "awk", "gawk", "mawk", "nawk", "node", "nodejs", "deno"
) or
process.name like ("python*", "perl*", "ruby*", "lua*", "php*")
) and (
stringcontains(process.executable, process.command_line) or
stringcontains(process.name, process.command_line)
) and
process.args_count == 1]
'''
[[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]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[rule.threat.tactic]
name = "Command and Control"
id = "TA0011"
reference = "https://attack.mitre.org/tactics/TA0011/"
[[rule.threat.technique]]
name = "Application Layer Protocol"
id = "T1071"
reference = "https://attack.mitre.org/techniques/T1071/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[rule.threat.tactic]
name = "Defense Evasion"
id = "TA0005"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Ordered sequence: each step below must occur in order within 1s, correlated by host.id, process.parent.entity_id, process.working_directory.
Stage 1: network
[network where host.os.type == "linux" and event.type == "start" and event.action == "connection_attempted" and (
process.name like (
"bash", "dash", "sh", "tcsh", "tclsh", "wish", "csh", "zsh", "ksh", "fish",
"mksh", "busybox", "rscript", "r", "julia", "mono", "dotnet", "groovy", "kotlin",
"scala", "erlang", "escript", "ocaml", "ocamlopt", "ld.so", "ld-linux-x86-64.so.2",
"ld-musl-x86_64.so.1", "awk", "gawk", "mawk", "nawk", "node", "nodejs", "deno",
"env", "timeout", "nice", "stdbuf", "setsid", "setarch", "unshare", "nsenter", "flock",
"runuser", "sudo", "snap"
) or
process.name like ("python*", "perl*", "ruby*", "lua*", "php*", "qemu-*-static")
) and
not (destination.ip == null or destination.ip == "0.0.0.0" or cidrmatch(
destination.ip, "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24", "192.0.0.0/29",
"192.0.0.8/32", "192.0.0.9/32", "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24",
"192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", "224.0.0.0/4", "100.64.0.0/10",
"192.175.48.0/24","198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1", "FE80::/10",
"FF00::/8"
)
)]
Stage 2: process
[process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and (
process.name like (
"bash", "dash", "sh", "tcsh", "tclsh", "wish", "csh", "zsh", "ksh", "fish",
"mksh", "busybox", "rscript", "r", "julia", "mono", "dotnet", "groovy", "kotlin",
"scala", "erlang", "escript", "ocaml", "ocamlopt", "ld.so", "ld-linux-x86-64.so.2",
"ld-musl-x86_64.so.1", "awk", "gawk", "mawk", "nawk", "node", "nodejs", "deno"
) or
process.name like ("python*", "perl*", "ruby*", "lua*", "php*")
) and (
stringcontains(process.executable, process.command_line) or
stringcontains(process.name, process.command_line)
) and
process.args_count == 1]
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_count | eq |
| field:"process.args_count" kind:eq value:"1" |
process.executable | contains |
| field:"Image" kind:contains value:"process.command_line" |
process.name | contains |
| field:"process_basename" kind:contains value:"process.command_line" |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
destination.ip | cidr_match | 10.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.0.0.0/24, 192.0.0.0/29, 192.0.0.8/32, 192.0.0.9/32, 192.0.0.10/32, 192.0.0.170/32, 192.0.0.171/32, 192.0.2.0/24, 192.31.196.0/24, 192.52.193.0/24, 192.168.0.0/16, 192.88.99.0/24, 224.0.0.0/4, 100.64.0.0/10, 192.175.48.0/24, 198.18.0.0/15, 198.51.100.0/24, 203.0.113.0/24, 240.0.0.0/4, ::1, FE80::/10, FF00::/8 | excludes:destination.ip |
destination.ip | eq | 0.0.0.0 | excludes:destination.ip field:"destination.ip" value:"0.0.0.0" |
destination.ip | is_null | excludes:destination.ip |
Potential Data Exfiltration Activity to an Unusual Region
#A machine learning job has detected data exfiltration to a particular geo-location (by region name). Data transfers to geo-locations that are outside the normal traffic patterns of an organization could indicate exfiltration over command and control channels.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Exfiltration |
Rule Body
[metadata]
creation_date = "2023/09/22"
integration = ["ded", "endpoint", "network_traffic"]
maturity = "production"
updated_date = "2026/07/27"
min_stack_version = "9.4.0"
min_stack_comments = "Use EA (Entity Analytics) fields"
[rule]
anomaly_threshold = 75
author = ["Elastic"]
description = """
A machine learning job has detected data exfiltration to a particular geo-location (by region name). Data transfers to
geo-locations that are outside the normal traffic patterns of an organization could indicate exfiltration over command
and control channels.
"""
from = "now-6h"
interval = "15m"
license = "Elastic License v2"
machine_learning_job_id = "ded_high_sent_bytes_destination_region_name_ea"
name = "Potential Data Exfiltration Activity to an Unusual Region"
references = [
"https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html",
"https://docs.elastic.co/en/integrations/ded",
"https://www.elastic.co/blog/detect-data-exfiltration-activity-with-kibanas-new-integration",
]
risk_score = 21
rule_id = "bfba5158-1fd6-4937-a205-77d96213b341"
setup = """## Setup
The rule requires the Data Exfiltration Detection integration assets to be installed, as well as network and file events collected by integrations such as Elastic Defend and Network Packet Capture (for network events only).
### Data Exfiltration Detection Setup
The Data Exfiltration Detection integration detects data exfiltration activity by identifying abnormalities in network and file events. Anomalies are detected using Elastic's Anomaly Detection feature.
#### Prerequisite Requirements:
- Fleet is required for Data Exfiltration Detection.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
- Network events collected by the [Elastic Defend](https://docs.elastic.co/en/integrations/endpoint) or [Network Packet Capture](https://docs.elastic.co/integrations/network_traffic) integration.
- To install Elastic Defend, refer to the [documentation](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
- To add the Network Packet Capture integration to an Elastic Agent policy, refer to [this](https://www.elastic.co/guide/en/fleet/current/add-integration-to-policy.html) guide.
#### The following steps should be executed to install assets associated with the Data Exfiltration Detection integration:
- Go to the Kibana homepage. Under Management, click Integrations.
- In the query bar, search for Data Exfiltration Detection and select the integration to see more details about it.
- Follow the instructions under the **Installation** section.
- For this rule to work, complete the instructions through **Add preconfigured anomaly detection jobs**.
"""
severity = "low"
tags = [
"Data Source: Elastic Defend",
"Data Source: Network Packet Capture",
"Use Case: Data Exfiltration Detection",
"Rule Type: ML",
"Rule Type: Machine Learning",
"Tactic: Exfiltration",
"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 Potential Data Exfiltration Activity to an Unusual Region
Machine learning models analyze network traffic patterns to identify anomalies, such as data transfers to atypical regions. Adversaries exploit command and control channels to exfiltrate data to these regions, bypassing traditional security measures. This detection rule leverages ML to flag unusual geo-locations, indicating potential exfiltration activities, thus aiding in early threat identification.
### Possible investigation steps
- Review the geo-location details flagged by the alert to determine if the region is indeed unusual for the organization's typical network traffic patterns.
- Analyze the network traffic logs associated with the alert to identify the volume and type of data being transferred to the unusual region.
- Cross-reference the IP addresses involved in the data transfer with threat intelligence databases to check for any known malicious activity or associations.
- Investigate the user accounts and devices involved in the data transfer to assess if they have been compromised or are exhibiting other suspicious behaviors.
- Check for any recent changes in network configurations or security policies that might have inadvertently allowed data transfers to atypical regions.
- Collaborate with the organization's IT and security teams to verify if there are legitimate business reasons for the data transfer to the flagged region.
### False positive analysis
- Legitimate business operations involving data transfers to new or infrequent regions may trigger false positives. Users should review and whitelist these regions if they are part of regular business activities.
- Scheduled data backups or transfers to cloud services located in atypical regions can be mistaken for exfiltration. Identify and exclude these services from the rule's scope.
- Remote work scenarios where employees connect from different regions might cause alerts. Maintain an updated list of remote work locations to prevent unnecessary alerts.
- Partner or vendor data exchanges that occur outside usual geographic patterns should be documented and excluded if they are verified as non-threatening.
- Temporary projects or collaborations with international teams may result in unusual data flows. Ensure these are accounted for in the rule's configuration to avoid false positives.
### Response and remediation
- Isolate the affected systems immediately to prevent further data exfiltration. Disconnect them from the network to stop ongoing communication with the unusual geo-location.
- Conduct a thorough analysis of the network traffic logs to identify the scope of the exfiltration and determine which data was accessed or transferred.
- Revoke any compromised credentials and enforce a password reset for affected accounts to prevent unauthorized access.
- Implement geo-blocking measures to restrict data transfers to the identified unusual region, ensuring that only approved regions can communicate with the network.
- Review and update firewall and intrusion detection system (IDS) rules to detect and block similar command and control traffic patterns in the future.
- Escalate the incident to the security operations center (SOC) and relevant stakeholders, providing them with detailed findings and actions taken for further investigation and response.
- Conduct a post-incident review to assess the effectiveness of the response and identify any gaps in the security posture, implementing necessary improvements to prevent recurrence."""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1041"
name = "Exfiltration Over C2 Channel"
reference = "https://attack.mitre.org/techniques/T1041/"
[rule.threat.tactic]
id = "TA0010"
name = "Exfiltration"
reference = "https://attack.mitre.org/tactics/TA0010/"
Potential PowerShell Obfuscation via Concatenated Dynamic Command Invocation
#Detects PowerShell scripts that builds commands from concatenated string literals inside dynamic invocation constructs like &() or .(). Attackers use concatenated dynamic invocation to obscure execution intent, bypass keyword-based detections, and evade AMSI.
MITRE ATT&CK Coverage
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| PowerShell | Event ID 4104: Creating Scriptblock text (MessageNumber of MessageTotal). |
Rule Body
[metadata]
creation_date = "2025/04/15"
integration = ["windows"]
maturity = "production"
updated_date = "2026/04/30"
[rule]
author = ["Elastic"]
description = """
Detects PowerShell scripts that builds commands from concatenated string literals inside dynamic invocation constructs
like &() or .(). Attackers use concatenated dynamic invocation to obscure execution intent, bypass keyword-based
detections, and evade AMSI.
"""
from = "now-9m"
language = "esql"
license = "Elastic License v2"
name = "Potential PowerShell Obfuscation via Concatenated Dynamic Command Invocation"
risk_score = 73
rule_id = "083383af-b9a4-42b7-a463-29c40efe7797"
severity = "high"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Defense Evasion",
"Data Source: PowerShell Logs",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-windows.powershell_operational* metadata _id, _version, _index
| where event.code == "4104" and powershell.file.script_block_text like "*+*"
// replace the patterns we are looking for with the 🔥 emoji to enable counting them
// The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1
| eval Esql.script_block_tmp = replace(
powershell.file.script_block_text,
"""[.&]\(\s*(['"][A-Za-z0-9.-]+['"]\s*\+\s*)+['"][A-Za-z0-9.-]+['"]\s*\)""",
"🔥"
)
// count how many patterns were detected by calculating the number of 🔥 characters inserted
| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "🔥", ""))
// keep the fields relevant to the query, although this is not needed as the alert is populated using _id
| keep
Esql.script_block_pattern_count,
Esql.script_block_tmp,
powershell.file.*,
file.path,
process.pid,
powershell.sequence,
powershell.total,
_id,
_version,
_index,
host.name,
host.id,
agent.id,
user.id
// Filter for scripts that match the pattern at least once
| where Esql.script_block_pattern_count >= 1
'''
note = """## Triage and analysis
### Investigating Potential PowerShell Obfuscation via Concatenated Dynamic Command Invocation
#### Possible investigation steps
- What did the alert preserve about the concatenated dynamic invocation?
- Focus: `Esql.script_block_pattern_count`, `powershell.file.script_block_text`, and `powershell.file.script_block_id`.
- Hint: use full-alert `Esql.script_block_tmp` only when you need the match-local slice.
- Implication: escalate faster when multiple call-operator or dot-sourced matches sit near download, reflection, credential, persistence, or execution logic; lower suspicion only when one short match resolves to a transparent helper and source recovery supports the same recognized workflow.
- Can you reconstruct the full source 4104 script block before interpreting context?
- Why: PowerShell can split large script blocks, and this ES|QL alert keeps summary fields that do not replace source-event recovery.
- Focus: query PowerShell Operational source events with `host.id`, `powershell.file.script_block_id`, `powershell.sequence`, and `powershell.total`; order fragments and record source `process.pid` when recovered. $investigate_2
- Implication: incomplete fragments are unresolved, not benign; escalation is stronger when reconstruction exposes hidden stages, fileless delivery, or missing execution context.
- What command or script does the concatenation resolve to, and does the operator expand impact?
- Focus: reconstructed `powershell.file.script_block_text`, surrounding variable assignments, and call-operator versus dot-sourcing use.
- Implication: escalate when the resolved token hides invocation or LOLBin logic that the surrounding code then executes; lower suspicion when reconstruction leaves one readable helper inside a recognized module or compatibility wrapper.
- Does the source event show a file-backed or fileless origin that fits this user and host?
- Focus: recovered `file.path`, `user.id`, source-event `user.name`, source-event `user.domain`, and `host.id`.
- Implication: escalate when the script is fileless or sourced from temp, downloads, profiles, shares, or another user-writable path under an unexpected identity; lower suspicion when the file path and user-host pairing match the same recognized admin module or compatibility workflow.
- Hint: absent `file.path` after source recovery means interactive, pasted, or memory-only activity; require stronger corroboration before closure.
- Can you recover the PowerShell process launch chain?
- Focus: source `process.pid` plus same-host process-start telemetry for recovered `process.entity_id`, `process.command_line`, and `process.parent.executable`.
- Hint: if endpoint process telemetry is unavailable, keep later pivots bounded to `host.id` plus `user.id` or `user.name` in the alert window rather than assuming process scope. $investigate_3
- Implication: escalate when PowerShell is launched by Office, a browser, an archive extractor, a LOLBin, an unexpected service, or a remote session; lower suspicion when the launch chain matches the same recognized management tool or scheduled task already supported by source evidence.
- Does the reconstructed script show layered obfuscation or payload-delivery logic beyond concatenation?
- Focus: `powershell.file.script_block_entropy_bits`, `powershell.file.script_block_surprisal_stdev`, `powershell.file.script_block_length`, and reconstructed `powershell.file.script_block_text`; compare `powershell.file.script_block_length` against `Esql.script_block_pattern_count` to detect dead-code inflation around few match sites.
- Implication: escalate when concatenation sits beside encoding, reflection, decoder routines, download strings, hidden payload material, dead-code padding, or Get-Command wildcard resolution.
- Did the recovered process or host-window activity retrieve, stage, or execute follow-on content?
- Focus: child starts from recovered `process.entity_id`, same-PID 4104 blocks, and file, DNS, or connection side effects: `file.path`, `dns.question.name`, and `destination.ip`.
- Hint: missing file, DNS, or network telemetry is unresolved, not benign; if `process.entity_id` was not recovered, scope only by `host.id` plus `user.id` or `user.name` in the alert window. $investigate_4 $investigate_5 $investigate_6
- Implication: escalate when the same process chain spawns shells, writes scripts or binaries, or reaches rare external destinations.
- If local findings remain suspicious or unresolved, does related alert history change scope?
- Focus: related alerts for the same `user.id` in the last 48 hours, prioritizing repeated obfuscated PowerShell, the same resolved token, or script path. $investigate_0
- Hint: if the user view is sparse or shared, pivot to the same `host.id` in the last 48 hours. $investigate_1
- Implication: broaden response when repeated obfuscation, AMSI tampering, encoded commands, download, credential-access, or persistence alerts cluster on the same user or host; keep scope local when the alert is isolated and local evidence resolves to one recognized workflow.
- Escalate on intentionally hidden PowerShell execution across match details, reconstruction, origin, launch chain, layered obfuscation, or follow-on activity; close only when recovered script, resolved token, origin, user-host context, launch chain, and side-effect telemetry align with one recognized workflow; preserve artifacts and escalate when reconstruction, process recovery, or file/network visibility stays incomplete.
### False positive analysis
- Internal compatibility wrappers, module loaders, code-protected vendor scripts, or administrative scripts may concatenate or dot-source helper names. Confirm recovered `powershell.file.script_block_text`, resolved token, `file.path` or stable helper path, recovered parent executable, dot-sourced location, and `user.id` plus `host.id` all align with one recognized workflow, with child process, file, DNS, and network effects contained to it. If external records are unavailable, require the same `file.path` or helper path, resolved token, parent executable, and user-host pairing to recur across prior alerts from this rule.
- Before creating an exception, anchor it on stable `file.path`, resolved token, recovered parent executable, and relevant `host.id` or `user.id` scope. Avoid exceptions on `Esql.script_block_pattern_count`, `Esql.script_block_tmp`, `user.name`, or `powershell.file.script_block_text` alone.
### Response and remediation
- If confirmed benign, reverse any temporary containment and document the evidence that proved one recognized workflow: resolved token, recovered `file.path`, launch chain, and `user.id` plus `host.id` scope. Create an exception only after the same pattern recurs consistently.
- If suspicious but unconfirmed, preserve the alert, reconstructed script fragments, recovered process identifiers, launch chain, staged file paths, DNS names, destination IPs, and case timeline before containment or cleanup.
- Apply reversible containment first: heightened monitoring, temporary outbound restrictions, or PowerShell restrictions on the affected `host.id`. Escalate to host isolation only when launch-chain or follow-on evidence indicates likely payload execution, lateral movement, or active command-and-control.
- If confirmed malicious, isolate the endpoint or contain the account based on the identity, launch-chain, file, and network evidence. Before suspending or terminating PowerShell, record the recovered process entity ID, command line, parent chain, resolved token, reconstructed script fragments, and staged file or network indicators.
- Review related hosts and users for the same resolved token, stable file path, parent executable, and destination indicators before removing artifacts so scoping completes before evidence is destroyed.
- Remove only the unauthorized scripts, dropped payloads, and persistence artifacts identified during the investigation, then remediate the delivery path or administrative-control gap that allowed obfuscated PowerShell execution.
- Post-incident hardening: retain Script Block Logging and endpoint process/file/network telemetry, restrict PowerShell where it is not required, and document the resolved token, script path, launch chain, and side-effect pattern that distinguished benign workflow from abuse."""
setup = """## Setup
PowerShell Script Block Logging must be enabled to generate the events used by this rule (e.g., 4104).
Setup instructions: https://ela.st/powershell-logging-setup
"""
[rule.investigation_fields]
field_names = [
"@timestamp",
"host.name",
"host.id",
"user.id",
"file.path",
"process.pid",
"powershell.file.script_block_text",
"powershell.file.script_block_id",
"powershell.sequence",
"powershell.total",
"powershell.file.script_block_entropy_bits",
"powershell.file.script_block_surprisal_stdev",
"powershell.file.script_block_unique_symbols",
"powershell.file.script_block_length",
"Esql.script_block_pattern_count"
]
[transform]
[[transform.investigate]]
label = "Alerts associated with the user"
description = ""
providers = [
[
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
{ excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
]
]
relativeFrom = "now-48h/h"
relativeTo = "now"
[[transform.investigate]]
label = "Alerts associated with the host"
description = ""
providers = [
[
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
]
]
relativeFrom = "now-48h/h"
relativeTo = "now"
[[transform.investigate]]
label = "Script block fragments for the same script"
description = ""
providers = [
[
{ excluded = false, field = "powershell.file.script_block_id", queryType = "phrase", value = "{{powershell.file.script_block_id}}", valueType = "string" },
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
]
]
relativeFrom = "now-1h"
relativeTo = "now"
[[transform.investigate]]
label = "Process events for the PowerShell instance"
description = ""
providers = [
[
{ excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
]
]
relativeFrom = "now-1h"
relativeTo = "now"
[[transform.investigate]]
label = "Child process activity from the PowerShell instance"
description = ""
providers = [
[
{ excluded = false, field = "process.parent.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.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" }
]
]
relativeFrom = "now-1h"
relativeTo = "now"
[[transform.investigate]]
label = "File, network, and DNS events for the PowerShell PID"
description = ""
providers = [
[
{ excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" },
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", 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 = "dns", 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-1h"
relativeTo = "now"
[[transform.investigate]]
label = "Script block events for the PowerShell PID"
description = ""
providers = [
[
{ excluded = false, field = "event.code", queryType = "phrase", value = "4104", 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-1h"
relativeTo = "now"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1027"
name = "Obfuscated Files or Information"
reference = "https://attack.mitre.org/techniques/T1027/"
[[rule.threat.technique.subtechnique]]
id = "T1027.010"
name = "Command Obfuscation"
reference = "https://attack.mitre.org/techniques/T1027/010/"
[[rule.threat.technique]]
id = "T1140"
name = "Deobfuscate/Decode Files or Information"
reference = "https://attack.mitre.org/techniques/T1140/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
Stages and Predicates
Stage 1: from
from logs-windows.powershell_operational* metadata _id, _version, _index
Stage 2: where
| where event.code == "4104" and powershell.file.script_block_text like "*+*"
Stage 3: eval
| eval Esql.script_block_tmp = replace(
powershell.file.script_block_text,
"""[.&]\(\s*(['"][A-Za-z0-9.-]+['"]\s*\+\s*)+['"][A-Za-z0-9.-]+['"]\s*\)""",
"🔥"
)
Stage 4: eval
| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "🔥", ""))
Stage 5: keep
| keep
Esql.script_block_pattern_count,
Esql.script_block_tmp,
powershell.file.*,
file.path,
process.pid,
powershell.sequence,
powershell.total,
_id,
_version,
_index,
host.name,
host.id,
agent.id,
user.id
Stage 6: where
| where Esql.script_block_pattern_count >= 1
Indicators
These rows show field, operator, and value matches.
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Esql.script_block_pattern_count | KEEP Esql.script_block_pattern_count |
Esql.script_block_tmp | KEEP Esql.script_block_tmp |
powershell.file.* | KEEP powershell.file.* |
file.path | KEEP file.path |
process.pid | KEEP process.pid |
powershell.sequence | KEEP powershell.sequence |
powershell.total | KEEP powershell.total |
_id | KEEP _id |
_version | KEEP _version |
_index | KEEP _index |
host.name | KEEP host.name |
host.id | KEEP host.id |
agent.id | KEEP agent.id |
user.id | KEEP user.id |
Potential Privilege Escalation via a Parent Process Sequence
#Detects a potential privilege escalation sequence via a parent process relationship. This rule checks for non-root execution of a process executable in a user or world-writeable directory followed by a UID change event to 0 (root). This sequence is indicative of a potential local privilege escalation exploit.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Privilege Escalation |
Rule Body
[rule]
description = """
Detects a potential privilege escalation sequence via a parent process relationship. This rule checks for non-root
execution of a process executable in a user or world-writeable directory followed by a UID change event to 0 (root).
This sequence is indicative of a potential local privilege escalation exploit.
"""
id = "727c9703-6879-45d1-80ad-7729ff244964"
license = "Elastic License v2"
name = "Potential Privilege Escalation via a Parent Process Sequence"
os_list = ["linux"]
version = "1.0.6"
query = '''
sequence by process.parent.entity_id with maxspan=15s
[process where event.type == "start" and event.action == "exec" and
user.id != 0 and process.parent.user.id != 0 and process.parent.group.id != 0 and
process.interactive == true and
(
process.executable like (".*", "/tmp/*", "/dev/shm/*", "/var/tmp/*", "/run/user/*", "/var/run/user/*") or
(process.executable like "/home/*/*" and process.args like ".*") or
process.parent.executable like (".*", "/tmp/*", "/dev/shm/*", "/var/tmp/*", "/run/user/*", "/var/run/user/*") or
(process.parent.executable like "/home/*/*" and process.parent.args like ".*")
) and
not (
process.executable like (
"/home/*/.local/share/mise/installs/*", "/home/*/.toolbox/cache", "/home/*/.local/share/pipx/*",
"/home/*/google-cloud-sdk/platform/*", "/home/*/.cargo/bin/rustup", "/home/*/.toolbox/test-results",
"/home/*/.local/share/claude/versions/*", "/tmp/newroot/*", "/run/user/1000/.bubblewrap/newroot/*",
"/home/*/.atuin/bin/atuin", "/home/*/.toolbox/artifact", "/usr/bin/ldconfig", "/home/*/.rustup/toolchains/*",
"/home/*/r2-cli/dist/r2", "/home/*/venv/bin/pip", "/home/linuxbrew/.linuxbrew/Cellar/*",
"/usr/bin/date", "/usr/bin/docker", "/usr/bin/getconf", "/usr/bin/getent", "/usr/bin/getsubids", "/usr/bin/git",
"/usr/bin/id", "/usr/bin/lscpu", "/usr/bin/tar", "/usr/bin/tee", "/usr/bin/uname", "/usr/bin/which", "/usr/bin/apt-cache",
"/usr/bin/virsh", "/usr/libexec/vte-urlencode-cwd", "/usr/lib/postgresql/*/bin/psql", "./push.sh", "./bin/console",
"./tmp/recover-rmanyari-host.sh", "./shutdown_NorenDB.sh", "/home/*/.local/bin/oh-my-posh", "/home/*/.local/bin/uv",
"/home/*/.hermes/bin/uv", "/home/*/.hermes/bin/tirith", "/home/*/.local/bin/mise", "/home/*/.local/bin/aws",
"/home/*/.local/bin/asdf", "/home/*/bin/asdf", "/home/*/.local/bin/direnv", "/home/*/.local/bin/starship",
"/home/*/.local/bin/claude", "/home/*/.local/bin/zoxide", "/home/*/.fzf/bin/fzf", "/home/*/.cargo/bin/starship",
"/home/*/.cargo/bin/cargo", "/home/*/.cargo/bin/fnm", "/home/*/.cargo/bin/ghidra", "/home/*/.binenv/shim",
"/home/*/.pyenv/libexec/pyenv-rehash", "/home/*/.pyenv/libexec/pyenv-version-name", "/home/*/.pyenv/libexec/pyenv-exec",
"/home/*/.nvm/versions/node/v*/bin/node", "/home/*/.nvm/versions/node/v*/lib/node_modules/@anthropic-ai/claude-code/bin/claude.exe",
"/home/*/.local/share/fnm/fnm", "/home/*/.local/node-v*/bin/node", "/home/*/node_modules/.bin/nodemon",
"/home/*/.local/share/uv/python/cpython-*/bin/python*", "/home/*/anaconda3/envs/*/bin/python*", "/home/*/.conda/envs/*/bin/kinit",
"/home/*/anaconda3/bin/conda", "/home/*/repos/gocryptfs/fortanix-dsm-fseagent", "/home/*/devel/rak-ps/bas", "/home/*/bin/crc",
"/home/*/.crc/bin/crc-admin-helper-linux-amd64", "/home/*/xen-mig-storage.sh", "/home/*/bin/gem_db_status",
"/home/*/admin/simbuka-loan-application/loan-analytics-api/run.sh", "/home/*/repo/gcc-monitor/gcc-monitor", "/home/*/repo/*/build/uuu",
"/home/*/Workspace/*/target/debug/*", "/home/*/experiments/fortanix-tdx-measure/cli/target/release/tdx-measure",
"/home/*/research/tools/go/pkg/tool/linux_amd64/link", "/home/*/Downloads/nvim-linux-x86_64/bin/nvim", "/home/*/mc",
"/home/linuxbrew/.linuxbrew/bin/brew", "/home/linuxbrew/.linuxbrew/bin/getopt", "/run/user/*/.bubblewrap/snap/snapd/current/usr/bin/snap",
"/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/shims/shared/git", "/opt/cubecoders/amp/ampinstmgr", "/tmp/.mount_*/bin/bambu-studio",
"/tmp/snap.rootfs_*/snap/gnome-calculator/*/usr/bin/gnome-calculator", "/tmp/snap.rootfs_*/snap/gnome-calculator/*/snap/command-chain/desktop-launch",
"/tmp/tmp.*/ijent", "/tmp/go-build*/b001/*.test", "/tmp/usr/bin/cat", "/tmp/bin/sh", "/tmp/var/lib/awx/venv/awx/bin/python3",
"./merged/home/*/.local/share/containers/storage/overlay/*/merged/usr/bin/basename", "/home/*/.local/share/containers/storage/overlay/*/diff/usr/local/apache2/bin/suexec",
"/u01/app/oracle/*/bin/emctl", "/home/*/devel/rak-ps/*", "/run/user/*/.bubblewrap/*", "/home/*/work/check-hardware/coco-detect/target/debug/coco-detect",
"/tmp/snap.rootfs_*/snap/*", "/usr/share/clearpass-onguard/via-cli", "/home/*/elastic-agent-*/elastic-agent", "/home/*/Downloads/isaac-sim/kit/kit",
"/home/*/.conda/envs/*/bin/python", "/home/*/go/src/*/odinq"
) or
process.parent.executable like (
"/home/*/.conda/envs/fmf_server_agent/bin/python*", "/home/*/.local/share/mise/installs/node/*/bin/node",
"/tmp/go-build*/*/sso.test", "/usr/bin/make", "/usr/bin/update-notifier", "/home/*/.hermes/node/bin/node",
"/home/*/.hermes/venvs/*/lib/python*/site-packages/playwright/driver/node",
"/home/*/.local/share/fnm/node-versions/v*/installation/bin/node", "/home/*/.vscode-server/cli/servers/Stable-*/server/node",
"/home/*/.bun/bin/bun", "/home/*/.nvm/versions/node/v*/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/*/bin/codex",
"/home/*/.npm-global/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/*/bin/codex", "/home/*/anaconda3/envs/*/bin/python*",
"/home/*/.venv/lib/python*/site-packages/playwright/driver/node", "/home/*/cricket/cricket/util/cenic/*.pl", "/home/*/.local/bin/agy",
"/home/*/.local/bin/copilot", "/home/*/Programy/DCC_harris_release/dcc", "./merged/home/*/.local/share/containers/storage/overlay/*/merged/bin/bash",
"/home/*/.local/share/containers/storage/overlay/*", "/usr/sbin/httpd", "./merged/var/lib/containers/storage/overlay/*", "/cav/gtm/mumps",
"/home/*/Downloads/Antigravity-arm64/antigravity","/usr/bin/gnome-shell", "/home/oracle/bin/request-daily.sh",
"/tmp/newroot/usr/local/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex"
) or
(
process.parent.name like "python*" and
process.parent.args == "terraform.kafka_runner.run-test"
) or
process.command_line in ("/bin/sh ./catalina.sh stop", "/bin/bash --login", "bash scripts/build_nvxsw_ssh.sh", "subscription-manager identity") or
process.parent.executable like "*/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/*/bin/codex"
)]
[process where event.type == "change" and event.action == "uid_change" and
user.id == 0 and process.parent.user.id != 0 and process.parent.group.id != 0 and
process.executable != "/usr/bin/sudo"]
'''
min_endpoint_version = "8.2.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 1
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1068"
name = "Exploitation for Privilege Escalation"
reference = "https://attack.mitre.org/techniques/T1068/"
[threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
[internal]
min_endpoint_version = "8.2.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 15s, correlated by process.parent.entity_id.
Stage 1: process
[process where event.type == "start" and event.action == "exec" and
user.id != 0 and process.parent.user.id != 0 and process.parent.group.id != 0 and
process.interactive == true and
(
process.executable like (".*", "/tmp/*", "/dev/shm/*", "/var/tmp/*", "/run/user/*", "/var/run/user/*") or
(process.executable like "/home/*/*" and process.args like ".*") or
process.parent.executable like (".*", "/tmp/*", "/dev/shm/*", "/var/tmp/*", "/run/user/*", "/var/run/user/*") or
(process.parent.executable like "/home/*/*" and process.parent.args like ".*")
) and
not (
process.executable like (
"/home/*/.local/share/mise/installs/*", "/home/*/.toolbox/cache", "/home/*/.local/share/pipx/*",
"/home/*/google-cloud-sdk/platform/*", "/home/*/.cargo/bin/rustup", "/home/*/.toolbox/test-results",
"/home/*/.local/share/claude/versions/*", "/tmp/newroot/*", "/run/user/1000/.bubblewrap/newroot/*",
"/home/*/.atuin/bin/atuin", "/home/*/.toolbox/artifact", "/usr/bin/ldconfig", "/home/*/.rustup/toolchains/*",
"/home/*/r2-cli/dist/r2", "/home/*/venv/bin/pip", "/home/linuxbrew/.linuxbrew/Cellar/*",
"/usr/bin/date", "/usr/bin/docker", "/usr/bin/getconf", "/usr/bin/getent", "/usr/bin/getsubids", "/usr/bin/git",
"/usr/bin/id", "/usr/bin/lscpu", "/usr/bin/tar", "/usr/bin/tee", "/usr/bin/uname", "/usr/bin/which", "/usr/bin/apt-cache",
"/usr/bin/virsh", "/usr/libexec/vte-urlencode-cwd", "/usr/lib/postgresql/*/bin/psql", "./push.sh", "./bin/console",
"./tmp/recover-rmanyari-host.sh", "./shutdown_NorenDB.sh", "/home/*/.local/bin/oh-my-posh", "/home/*/.local/bin/uv",
"/home/*/.hermes/bin/uv", "/home/*/.hermes/bin/tirith", "/home/*/.local/bin/mise", "/home/*/.local/bin/aws",
"/home/*/.local/bin/asdf", "/home/*/bin/asdf", "/home/*/.local/bin/direnv", "/home/*/.local/bin/starship",
"/home/*/.local/bin/claude", "/home/*/.local/bin/zoxide", "/home/*/.fzf/bin/fzf", "/home/*/.cargo/bin/starship",
"/home/*/.cargo/bin/cargo", "/home/*/.cargo/bin/fnm", "/home/*/.cargo/bin/ghidra", "/home/*/.binenv/shim",
"/home/*/.pyenv/libexec/pyenv-rehash", "/home/*/.pyenv/libexec/pyenv-version-name", "/home/*/.pyenv/libexec/pyenv-exec",
"/home/*/.nvm/versions/node/v*/bin/node", "/home/*/.nvm/versions/node/v*/lib/node_modules/@anthropic-ai/claude-code/bin/claude.exe",
"/home/*/.local/share/fnm/fnm", "/home/*/.local/node-v*/bin/node", "/home/*/node_modules/.bin/nodemon",
"/home/*/.local/share/uv/python/cpython-*/bin/python*", "/home/*/anaconda3/envs/*/bin/python*", "/home/*/.conda/envs/*/bin/kinit",
"/home/*/anaconda3/bin/conda", "/home/*/repos/gocryptfs/fortanix-dsm-fseagent", "/home/*/devel/rak-ps/bas", "/home/*/bin/crc",
"/home/*/.crc/bin/crc-admin-helper-linux-amd64", "/home/*/xen-mig-storage.sh", "/home/*/bin/gem_db_status",
"/home/*/admin/simbuka-loan-application/loan-analytics-api/run.sh", "/home/*/repo/gcc-monitor/gcc-monitor", "/home/*/repo/*/build/uuu",
"/home/*/Workspace/*/target/debug/*", "/home/*/experiments/fortanix-tdx-measure/cli/target/release/tdx-measure",
"/home/*/research/tools/go/pkg/tool/linux_amd64/link", "/home/*/Downloads/nvim-linux-x86_64/bin/nvim", "/home/*/mc",
"/home/linuxbrew/.linuxbrew/bin/brew", "/home/linuxbrew/.linuxbrew/bin/getopt", "/run/user/*/.bubblewrap/snap/snapd/current/usr/bin/snap",
"/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/shims/shared/git", "/opt/cubecoders/amp/ampinstmgr", "/tmp/.mount_*/bin/bambu-studio",
"/tmp/snap.rootfs_*/snap/gnome-calculator/*/usr/bin/gnome-calculator", "/tmp/snap.rootfs_*/snap/gnome-calculator/*/snap/command-chain/desktop-launch",
"/tmp/tmp.*/ijent", "/tmp/go-build*/b001/*.test", "/tmp/usr/bin/cat", "/tmp/bin/sh", "/tmp/var/lib/awx/venv/awx/bin/python3",
"./merged/home/*/.local/share/containers/storage/overlay/*/merged/usr/bin/basename", "/home/*/.local/share/containers/storage/overlay/*/diff/usr/local/apache2/bin/suexec",
"/u01/app/oracle/*/bin/emctl", "/home/*/devel/rak-ps/*", "/run/user/*/.bubblewrap/*", "/home/*/work/check-hardware/coco-detect/target/debug/coco-detect",
"/tmp/snap.rootfs_*/snap/*", "/usr/share/clearpass-onguard/via-cli", "/home/*/elastic-agent-*/elastic-agent", "/home/*/Downloads/isaac-sim/kit/kit",
"/home/*/.conda/envs/*/bin/python", "/home/*/go/src/*/odinq"
) or
process.parent.executable like (
"/home/*/.conda/envs/fmf_server_agent/bin/python*", "/home/*/.local/share/mise/installs/node/*/bin/node",
"/tmp/go-build*/*/sso.test", "/usr/bin/make", "/usr/bin/update-notifier", "/home/*/.hermes/node/bin/node",
"/home/*/.hermes/venvs/*/lib/python*/site-packages/playwright/driver/node",
"/home/*/.local/share/fnm/node-versions/v*/installation/bin/node", "/home/*/.vscode-server/cli/servers/Stable-*/server/node",
"/home/*/.bun/bin/bun", "/home/*/.nvm/versions/node/v*/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/*/bin/codex",
"/home/*/.npm-global/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/*/bin/codex", "/home/*/anaconda3/envs/*/bin/python*",
"/home/*/.venv/lib/python*/site-packages/playwright/driver/node", "/home/*/cricket/cricket/util/cenic/*.pl", "/home/*/.local/bin/agy",
"/home/*/.local/bin/copilot", "/home/*/Programy/DCC_harris_release/dcc", "./merged/home/*/.local/share/containers/storage/overlay/*/merged/bin/bash",
"/home/*/.local/share/containers/storage/overlay/*", "/usr/sbin/httpd", "./merged/var/lib/containers/storage/overlay/*", "/cav/gtm/mumps",
"/home/*/Downloads/Antigravity-arm64/antigravity","/usr/bin/gnome-shell", "/home/oracle/bin/request-daily.sh",
"/tmp/newroot/usr/local/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex"
) or
(
process.parent.name like "python*" and
process.parent.args == "terraform.kafka_runner.run-test"
) or
process.command_line in ("/bin/sh ./catalina.sh stop", "/bin/bash --login", "bash scripts/build_nvxsw_ssh.sh", "subscription-manager identity") or
process.parent.executable like "*/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/*/bin/codex"
)]
Stage 2: process
[process where event.type == "change" and event.action == "uid_change" and
user.id == 0 and process.parent.user.id != 0 and process.parent.group.id != 0 and
process.executable != "/usr/bin/sudo"]
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 |
process.args | wildcard |
| field:"process.args" kind:wildcard value:".*" |
process.executable | ne |
| field:"Image" kind:ne value:"/usr/bin/sudo" |
process.executable | wildcard |
| field:"Image" kind:wildcard |
process.interactive | eq |
| field:"process.interactive" kind:eq value:"true" |
process.parent.args | wildcard |
| field:"process.parent.args" kind:wildcard value:".*" |
process.parent.executable | wildcard |
| field:"ParentImage" kind:wildcard |
process.parent.group.id | ne |
| field:"process.parent.group.id" kind:ne value:"0" |
process.parent.user.id | ne |
| field:"process.parent.user.id" kind:ne value:"0" |
user.id | eq |
| field:"user.id" kind:eq value:"0" |
user.id | ne |
| field:"user.id" kind:ne value:"0" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.parent.args | eq | terraform.kafka_runner.run-test | excludes:process.parent.args field:"process.parent.args" value:"terraform.kafka_runner.run-test" |
process.parent.name | starts_with | python | excludes:process.parent.name field:"process.parent.name" value:"python" |
process.command_line | in | /bin/bash --login, /bin/sh ./catalina.sh stop, bash scripts/build_nvxsw_ssh.sh, subscription-manager identity | excludes:process.command_line |
process.executable | wildcard | /home/*/.local/share/mise/installs/*, /home/*/.toolbox/cache, /home/*/.local/share/pipx/*, /home/*/google-cloud-sdk/platform/*, /home/*/.cargo/bin/rustup, /home/*/.toolbox/test-results, /home/*/.local/share/claude/versions/*, /tmp/newroot/*, /run/user/1000/.bubblewrap/newroot/*, /home/*/.atuin/bin/atuin, /home/*/.toolbox/artifact, /usr/bin/ldconfig, /home/*/.rustup/toolchains/*, /home/*/r2-cli/dist/r2, /home/*/venv/bin/pip, /home/linuxbrew/.linuxbrew/Cellar/*, /usr/bin/date, /usr/bin/docker, /usr/bin/getconf, /usr/bin/getent, /usr/bin/getsubids, /usr/bin/git, /usr/bin/id, /usr/bin/lscpu, /usr/bin/tar, /usr/bin/tee, /usr/bin/uname, /usr/bin/which, /usr/bin/apt-cache, /usr/bin/virsh, /usr/libexec/vte-urlencode-cwd, /usr/lib/postgresql/*/bin/psql, ./push.sh, ./bin/console, ./tmp/recover-rmanyari-host.sh, ./shutdown_NorenDB.sh, /home/*/.local/bin/oh-my-posh, /home/*/.local/bin/uv, /home/*/.hermes/bin/uv, /home/*/.hermes/bin/tirith, /home/*/.local/bin/mise, /home/*/.local/bin/aws, /home/*/.local/bin/asdf, /home/*/bin/asdf, /home/*/.local/bin/direnv, /home/*/.local/bin/starship, /home/*/.local/bin/claude, /home/*/.local/bin/zoxide, /home/*/.fzf/bin/fzf, /home/*/.cargo/bin/starship, /home/*/.cargo/bin/cargo, /home/*/.cargo/bin/fnm, /home/*/.cargo/bin/ghidra, /home/*/.binenv/shim, /home/*/.pyenv/libexec/pyenv-rehash, /home/*/.pyenv/libexec/pyenv-version-name, /home/*/.pyenv/libexec/pyenv-exec, /home/*/.nvm/versions/node/v*/bin/node, /home/*/.nvm/versions/node/v*/lib/node_modules/@anthropic-ai/claude-code/bin/claude.exe, /home/*/.local/share/fnm/fnm, /home/*/.local/node-v*/bin/node, /home/*/node_modules/.bin/nodemon, /home/*/.local/share/uv/python/cpython-*/bin/python*, /home/*/anaconda3/envs/*/bin/python*, /home/*/.conda/envs/*/bin/kinit, /home/*/anaconda3/bin/conda, /home/*/repos/gocryptfs/fortanix-dsm-fseagent, /home/*/devel/rak-ps/bas, /home/*/bin/crc, /home/*/.crc/bin/crc-admin-helper-linux-amd64, /home/*/xen-mig-storage.sh, /home/*/bin/gem_db_status, /home/*/admin/simbuka-loan-application/loan-analytics-api/run.sh, /home/*/repo/gcc-monitor/gcc-monitor, /home/*/repo/*/build/uuu, /home/*/Workspace/*/target/debug/*, /home/*/experiments/fortanix-tdx-measure/cli/target/release/tdx-measure, /home/*/research/tools/go/pkg/tool/linux_amd64/link, /home/*/Downloads/nvim-linux-x86_64/bin/nvim, /home/*/mc, /home/linuxbrew/.linuxbrew/bin/brew, /home/linuxbrew/.linuxbrew/bin/getopt, /run/user/*/.bubblewrap/snap/snapd/current/usr/bin/snap, /home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/shims/shared/git, /opt/cubecoders/amp/ampinstmgr, /tmp/.mount_*/bin/bambu-studio, /tmp/snap.rootfs_*/snap/gnome-calculator/*/usr/bin/gnome-calculator, /tmp/snap.rootfs_*/snap/gnome-calculator/*/snap/command-chain/desktop-launch, /tmp/tmp.*/ijent, /tmp/go-build*/b001/*.test, /tmp/usr/bin/cat, /tmp/bin/sh, /tmp/var/lib/awx/venv/awx/bin/python3, ./merged/home/*/.local/share/containers/storage/overlay/*/merged/usr/bin/basename, /home/*/.local/share/containers/storage/overlay/*/diff/usr/local/apache2/bin/suexec, /u01/app/oracle/*/bin/emctl, /home/*/devel/rak-ps/*, /run/user/*/.bubblewrap/*, /home/*/work/check-hardware/coco-detect/target/debug/coco-detect, /tmp/snap.rootfs_*/snap/*, /usr/share/clearpass-onguard/via-cli, /home/*/elastic-agent-*/elastic-agent, /home/*/Downloads/isaac-sim/kit/kit, /home/*/.conda/envs/*/bin/python, /home/*/go/src/*/odinq | excludes:process.executable |
process.parent.executable | wildcard | */node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/*/bin/codex | excludes:process.parent.executable field:"process.parent.executable" value:"*/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/*/bin/codex" |
process.parent.executable | wildcard | /home/*/.conda/envs/fmf_server_agent/bin/python*, /home/*/.local/share/mise/installs/node/*/bin/node, /tmp/go-build*/*/sso.test, /usr/bin/make, /usr/bin/update-notifier, /home/*/.hermes/node/bin/node, /home/*/.hermes/venvs/*/lib/python*/site-packages/playwright/driver/node, /home/*/.local/share/fnm/node-versions/v*/installation/bin/node, /home/*/.vscode-server/cli/servers/Stable-*/server/node, /home/*/.bun/bin/bun, /home/*/.nvm/versions/node/v*/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/*/bin/codex, /home/*/.npm-global/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/*/bin/codex, /home/*/anaconda3/envs/*/bin/python*, /home/*/.venv/lib/python*/site-packages/playwright/driver/node, /home/*/cricket/cricket/util/cenic/*.pl, /home/*/.local/bin/agy, /home/*/.local/bin/copilot, /home/*/Programy/DCC_harris_release/dcc, ./merged/home/*/.local/share/containers/storage/overlay/*/merged/bin/bash, /home/*/.local/share/containers/storage/overlay/*, /usr/sbin/httpd, ./merged/var/lib/containers/storage/overlay/*, /cav/gtm/mumps, /home/*/Downloads/Antigravity-arm64/antigravity, /usr/bin/gnome-shell, /home/oracle/bin/request-daily.sh, /tmp/newroot/usr/local/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex | excludes:process.parent.executable |
Potential Telnet Authentication Bypass (CVE-2026-24061)
#Identifies potential exploitation of a Telnet remote authentication bypass vulnerability (CVE-2026-24061) in GNU Inetutils telnetd. The vulnerability allows unauthenticated access by supplying a crafted "-f <username>" value via the "USER" environment variable, resulting in a login process spawned with elevated privileges.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Lateral Movement |
Rule Body
[rule]
description = """
Identifies potential exploitation of a Telnet remote authentication bypass vulnerability (CVE-2026-24061) in GNU
Inetutils telnetd. The vulnerability allows unauthenticated access by supplying a crafted "-f <username>" value via the
"USER" environment variable, resulting in a login process spawned with elevated privileges.
"""
id = "afb48a5f-f1d5-402c-91f8-53a8c279e1ed"
license = "Elastic License v2"
name = "Potential Telnet Authentication Bypass (CVE-2026-24061)"
os_list = ["linux"]
reference = [
"https://www.safebreach.com/blog/safebreach-labs-root-cause-analysis-and-poc-exploit-for-cve-2026-24061/",
"https://security-tracker.debian.org/tracker/CVE-2026-24061",
"https://man7.org/linux/man-pages/man1/login.1.html",
]
version = "1.0.1"
query = '''
process where event.type == "start" and event.action == "exec" and (
(process.name == "login" and process.args like~ "-*f*" and process.parent.name == "telnetd") or
descendant of [
process where event.type == "start" and event.action == "exec" and
process.name == "login" and process.args like~ "-*f*" and process.parent.name == "telnetd"
]
)
'''
min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1190"
name = "Exploit Public-Facing Application"
reference = "https://attack.mitre.org/techniques/T1190/"
[threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1210"
name = "Exploitation of Remote Services"
reference = "https://attack.mitre.org/techniques/T1210/"
[threat.tactic]
id = "TA0008"
name = "Lateral Movement"
reference = "https://attack.mitre.org/tactics/TA0008/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: process
process where event.type == "start" and event.action == "exec" and (
(process.name == "login" and process.args like~ "-*f*" and process.parent.name == "telnetd") or
descendant of [
process where event.type == "start" and event.action == "exec" and
process.name == "login" and process.args like~ "-*f*" and process.parent.name == "telnetd"
]
)
Indicators
These rows show field, operator, and value matches.
Potentially Suspicious Process Started via tmux or screen
#This rule monitors for the execution of suspicious commands via screen and tmux. When launching a command and detaching directly, the commands will be executed in the background via its parent process. Attackers may leverage screen or tmux to execute commands while attempting to evade detection.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Stealth | |
| Discovery | |
| Command & Control |
Rule Body
[metadata]
creation_date = "2023/09/04"
integration = ["endpoint", "crowdstrike", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
This rule monitors for the execution of suspicious commands via screen and tmux. When launching a command and detaching
directly, the commands will be executed in the background via its parent process. Attackers may leverage screen or tmux
to execute commands while attempting to evade detection.
"""
from = "now-9m"
index = [
"endgame-*",
"logs-crowdstrike.fdr*",
"logs-endpoint.events.process*",
"logs-sentinel_one_cloud_funnel.*",
]
language = "eql"
license = "Elastic License v2"
name = "Potentially Suspicious Process Started via tmux or screen"
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 Potentially Suspicious Process Started via tmux or screen
Tmux and screen are terminal multiplexers that allow users to manage multiple terminal sessions from a single window, facilitating multitasking and session persistence. Adversaries may exploit these tools to execute commands stealthily, detaching sessions to run processes in the background. The detection rule identifies suspicious processes initiated by tmux or screen, focusing on potentially malicious commands, to uncover attempts at evading security measures.
### Possible investigation steps
- Review the process details to identify the specific command executed by tmux or screen, focusing on the process.name field to determine if it matches any known suspicious commands like "nmap", "nc", "wget", etc.
- Examine the user account associated with the process to determine if the activity aligns with their typical behavior or if it appears anomalous.
- Check the parent process information, specifically process.parent.name, to confirm that the process was indeed initiated by tmux or screen, and assess if this behavior is expected for the user or system.
- Investigate the network activity associated with the process, especially if the command involves network utilities like "curl" or "ping", to identify any unusual or unauthorized connections.
- Correlate the event with other security alerts or logs from the same host or user to identify any patterns or additional suspicious activities that might indicate a broader attack or compromise.
### False positive analysis
- System administrators or developers may use tmux or screen to run legitimate maintenance scripts or development tools like Java, PHP, or Perl. To manage these, create exceptions for known scripts or processes that are regularly executed by trusted users.
- Automated monitoring or testing tools might utilize tmux or screen to execute network diagnostic commands such as ping or nmap. Identify and whitelist these tools if they are part of routine operations.
- Some backup or data transfer processes might use wget or curl to fetch resources. Verify the source and destination of these processes and exclude them if they are part of scheduled tasks.
- Developers might use tmux or screen to run interactive sessions with languages like Ruby or Lua for debugging purposes. Establish a list of trusted users and exclude their sessions from triggering alerts.
- In environments where remote management is common, tools like ngrok might be used for legitimate purposes. Ensure that these tools are configured securely and exclude them if they are part of authorized workflows.
### Response and remediation
- Immediately isolate the affected host from the network to prevent further malicious activity and lateral movement.
- Terminate any suspicious processes identified as being initiated by tmux or screen, especially those matching the query criteria.
- Conduct a thorough review of the affected system's process tree and logs to identify any additional malicious activity or persistence mechanisms.
- Reset credentials and review access permissions for any accounts that were active on the affected system to prevent unauthorized access.
- Escalate the incident to the security operations team for further investigation and to determine if additional systems are compromised.
- Implement network monitoring to detect any unusual outbound connections or data exfiltration attempts from the affected host.
- Update and enhance detection rules to include additional suspicious command patterns or behaviors observed during the investigation."""
risk_score = 47
rule_id = "e0cc3807-e108-483c-bf66-5a4fbe0d7e89"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Defense Evasion",
"Data Source: Elastic Defend",
"Data Source: Elastic Endgame",
"Data Source: Crowdstrike",
"Data Source: SentinelOne",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "linux" and event.type == "start" and
event.action in ("exec", "exec_event", "start", "ProcessRollup2") and
process.parent.name in ("screen", "tmux") and process.name like (
"nmap", "nc", "ncat", "netcat", "socat", "nc.openbsd", "ngrok", "ping", "java", "php*", "perl", "ruby", "lua*",
"openssl", "telnet", "wget", "curl", "id"
)
'''
[[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.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1105"
name = "Ingress Tool Transfer"
reference = "https://attack.mitre.org/techniques/T1105/"
[rule.threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1033"
name = "System Owner/User Discovery"
reference = "https://attack.mitre.org/techniques/T1033/"
[[rule.threat.technique]]
id = "T1046"
name = "Network Service Discovery"
reference = "https://attack.mitre.org/techniques/T1046/"
[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
Stages and Predicates
Stage 1: process
process where host.os.type == "linux" and event.type == "start" and
event.action in ("exec", "exec_event", "start", "ProcessRollup2") and
process.parent.name in ("screen", "tmux") and process.name like (
"nmap", "nc", "ncat", "netcat", "socat", "nc.openbsd", "ngrok", "ping", "java", "php*", "perl", "ruby", "lua*",
"openssl", "telnet", "wget", "curl", "id"
)
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 | wildcard |
| field:"process_basename" kind:wildcard |
process.parent.name | in |
| field:"parent_process_basename" kind:in |
Renamed Third Party Administrator Tools
#Identifies third party administrative tools commonly used by adversaries but running with unexpected file names.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule Body
[rule]
description = "Identifies third party administrative tools commonly used by adversaries but running with unexpected file names."
id = "b707de5c-8e4d-4d2c-be22-b09a7e82b73f"
license = "Elastic License v2"
name = "Renamed Third Party Administrator Tools"
os_list = ["windows"]
version = "1.0.33"
query = '''
process where event.action == "start" and
(
(process.pe.original_file_name : "procdump" and
process.code_signature.subject_name == "Microsoft Corporation" and not process.name : "*procdump*.exe") or
(process.pe.original_file_name : "psexec.c" and process.code_signature.subject_name == "Microsoft Corporation" and not process.name : "*psexec*.exe") or
(process.pe.original_file_name : "sdelete.exe" and process.code_signature.subject_name == "Microsoft Corporation" and not process.name : "*sdelete*")
) and
not process.executable :
("?:\\Windows\\System32\\*.exe",
"?:\\Windows\\SysWOW64\\*.exe",
"?:\\Program Files (x86)\\*.exe",
"?:\\Program Files\\*.exe")
'''
min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1036"
name = "Masquerading"
reference = "https://attack.mitre.org/techniques/T1036/"
[[threat.technique.subtechnique]]
id = "T1036.003"
name = "Rename Legitimate Utilities"
reference = "https://attack.mitre.org/techniques/T1036/003/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: process
process where event.action == "start" and
(
(process.pe.original_file_name : "procdump" and
process.code_signature.subject_name == "Microsoft Corporation" and not process.name : "*procdump*.exe") or
(process.pe.original_file_name : "psexec.c" and process.code_signature.subject_name == "Microsoft Corporation" and not process.name : "*psexec*.exe") or
(process.pe.original_file_name : "sdelete.exe" and process.code_signature.subject_name == "Microsoft Corporation" and not process.name : "*sdelete*")
) and
not process.executable :
("?:\\Windows\\System32\\*.exe",
"?:\\Windows\\SysWOW64\\*.exe",
"?:\\Program Files (x86)\\*.exe",
"?:\\Program Files\\*.exe")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.code_signature.subject_name | eq |
| field:"Signature" kind:eq value:"Microsoft Corporation" |
process.pe.original_file_name | wildcard |
| field:"OriginalFileName" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.executable | wildcard | ?:\Windows\System32\*.exe, ?:\Windows\SysWOW64\*.exe, ?:\Program Files (x86)\*.exe, ?:\Program Files\*.exe | excludes:process.executable |
Renaming of OpenSSH Binaries
#Adversaries may modify SSH related binaries for persistence or credential access by patching sensitive functions to enable unauthorized access or by logging SSH credentials for exfiltration.
Known False Positives
- Trusted OpenSSH executable updates. It's recommended to verify the integrity of OpenSSH binary changes.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Credential Access | |
| Lateral Movement |
Rule Body
[metadata]
creation_date = "2020/12/21"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"
[transform]
[[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 = """
Adversaries may modify SSH related binaries for persistence or credential access by patching sensitive functions to
enable unauthorized access or by logging SSH credentials for exfiltration.
"""
false_positives = [
"Trusted OpenSSH executable updates. It's recommended to verify the integrity of OpenSSH binary changes.",
]
from = "now-9m"
index = ["logs-endpoint.events.*", "endgame-*"]
language = "kuery"
license = "Elastic License v2"
name = "Renaming of OpenSSH Binaries"
note = """## Triage and analysis
### Investigating Renaming of OpenSSH Binaries
OpenSSH is a widely used suite of secure networking utilities based on the Secure Shell (SSH) protocol, which provides encrypted communication sessions over a computer network.
Adversaries may exploit OpenSSH by modifying its binaries, such as `/usr/bin/scp`, `/usr/bin/sftp`, `/usr/bin/ssh`, `/usr/sbin/sshd`, or `libkeyutils.so`, to gain unauthorized access or exfiltrate SSH credentials.
The detection rule 'Modification of OpenSSH Binaries' is designed to identify such abuse by monitoring file changes in the Linux environment. It triggers an alert when a process, modifies any of the specified OpenSSH binaries or libraries. This helps security analysts detect potential malicious activities and take appropriate action.
> **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 script execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence and whether they are located in expected locations.
- $osquery_0
- 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_1
- 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_2
- $osquery_3
- Identify the user account that performed the action, analyze it, and check whether it should perform this kind of action.
- $osquery_4
- Investigate whether the user is currently logged in and active.
- $osquery_5
### False positive analysis
- Regular users should not need to modify OpenSSH binaries, which makes false positives unlikely. In the case of authorized benign true positives (B-TPs), exceptions can be added.
- 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 that performed these actions 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://blog.angelalonso.es/2016/09/anatomy-of-real-linux-intrusion-part-ii.html"]
risk_score = 21
rule_id = "0415f22a-2336-45fa-ba07-618a5942e22c"
setup = """## Setup
This rule requires data coming in from one of the following integrations:
- Elastic Defend
- Auditbeat
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
### Auditbeat Setup
Auditbeat is a lightweight shipper that you can install on your servers to audit the activities of users and processes on your systems. For example, you can use Auditbeat to collect and centralize audit events from the Linux Audit Framework. You can also use Auditbeat to detect changes to critical files, like binaries and configuration files, and identify potential security policy violations.
#### The following steps should be executed in order to add the Auditbeat on a Linux System:
- Elastic provides repositories available for APT and YUM-based distributions. Note that we provide binary packages, but no source packages.
- To install the APT and YUM repositories follow the setup instructions in this [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/setup-repositories.html).
- To run Auditbeat on Docker follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/running-on-docker.html).
- To run Auditbeat on Kubernetes follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/running-on-kubernetes.html).
- For complete “Setup and Run Auditbeat” information refer to the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/setting-up-and-running.html).
"""
severity = "low"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Credential Access",
"Tactic: Persistence",
"Tactic: Lateral Movement",
"Data Source: Elastic Endgame",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
event.category:file and host.os.type:linux and event.type:change and
process.name:(* and not (
dnf or dnf-automatic or dpkg or yum or rpm or yum-cron or anacron or platform-python* or
apk or ansible-admin or systemd or python* or yum or nix-daemon or nix
)
) and
(file.path:(/usr/bin/scp or
/usr/bin/sftp or
/usr/bin/ssh or
/usr/sbin/sshd) or
file.name:libkeyutils.so) and
not (
process.executable:(
/usr/share/elasticsearch/* or "/usr/bin/microdnf" or "/usr/bin/dnf5" or "/usr/sbin/gdm" or
"/usr/libexec/packagekitd" or "/usr/libexec/zypp/zypp-rpm" or "/home/sa-ansible"
) or
file.Ext.original.name:"sshd.session-split"
)
'''
[[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]]
id = "T1554"
name = "Compromise Host Software Binary"
reference = "https://attack.mitre.org/techniques/T1554/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1556"
name = "Modify Authentication Process"
reference = "https://attack.mitre.org/techniques/T1556/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[[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/"
Stages and Predicates
Stage 1: query
event.category:file and host.os.type:linux and event.type:change and
process.name:(* and not (
dnf or dnf-automatic or dpkg or yum or rpm or yum-cron or anacron or platform-python* or
apk or ansible-admin or systemd or python* or yum or nix-daemon or nix
)
) and
(file.path:(/usr/bin/scp or
/usr/bin/sftp or
/usr/bin/ssh or
/usr/sbin/sshd) or
file.name:libkeyutils.so) and
not (
process.executable:(
/usr/share/elasticsearch/* or "/usr/bin/microdnf" or "/usr/bin/dnf5" or "/usr/sbin/gdm" or
"/usr/libexec/packagekitd" or "/usr/libexec/zypp/zypp-rpm" or "/home/sa-ansible"
) or
file.Ext.original.name:"sshd.session-split"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.category | eq |
| field:"event.category" kind:eq value:"file" |
event.type | eq |
| field:"event.type" kind:eq value:"change" |
file.name | eq |
| field:"file.name" kind:eq value:"libkeyutils.so" |
file.path | in |
| field:"TargetFilename" kind:in |
process.name | is_not_null | field:"process_basename" kind:is_not_null |
Exclusions
The rule actively suppresses these predicates.
Scheduled Task Execution at Scale via GPO
#Detects the modification of Group Policy Object attributes to execute a scheduled task in the objects controlled by the GPO.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Privilege Escalation | |
| Lateral Movement |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2021/11/08"
integration = ["system", "windows"]
maturity = "production"
updated_date = "2026/05/04"
[rule]
author = ["Elastic"]
description = """
Detects the modification of Group Policy Object attributes to execute a scheduled task in the objects controlled by the
GPO.
"""
index = ["logs-system.security*", "logs-windows.forwarded*", "winlogbeat-*"]
language = "eql"
license = "Elastic License v2"
name = "Scheduled Task Execution at Scale via GPO"
note = """## Triage and analysis
### Investigating Scheduled Task Execution at Scale via GPO
Group Policy Objects (GPOs) can be used by attackers to execute scheduled tasks at scale to compromise objects controlled by a given GPO. This is done by changing the contents of the `<GPOPath>\\Machine\\Preferences\\ScheduledTasks\\ScheduledTasks.xml` file.
#### Possible investigation steps
- This attack abuses a legitimate mechanism of Active Directory, so it is important to determine whether the activity is legitimate and the administrator is authorized to perform this operation.
- Retrieve the contents of the `ScheduledTasks.xml` file, and check the `<Command>` and `<Arguments>` XML tags for any potentially malicious commands or binaries.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Scope which objects may be compromised by retrieving information about which objects are controlled by the GPO.
### False positive analysis
- Verify if the execution is allowed and done under change management, and if the execution is legitimate.
### Related rules
- Group Policy Abuse for Privilege Addition - b9554892-5e0e-424b-83a0-5aef95aa43bf
- Startup/Logon Script added to Group Policy Object - 16fac1a1-21ee-4ca6-b720-458e3855d046
### Response and remediation
- Initiate the incident response process based on the outcome of the triage.
- The investigation and containment must be performed in every computer controlled by the GPO, where necessary.
- Remove the script from the GPO.
- Check if other GPOs have suspicious scheduled tasks attached.
- 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://github.com/atc-project/atc-data/blob/master/docs/Logging_Policies/LP_0025_windows_audit_directory_service_changes.md",
"https://github.com/atc-project/atc-data/blob/f2bbb51ecf68e2c9f488e3c70dcdd3df51d2a46b/docs/Logging_Policies/LP_0029_windows_audit_detailed_file_share.md",
"https://labs.f-secure.com/tools/sharpgpoabuse",
"https://twitter.com/menasec1/status/1106899890377052160",
"https://github.com/SigmaHQ/sigma/blob/master/rules/windows/builtin/security/win_gpo_scheduledtasks.yml",
]
risk_score = 47
rule_id = "15a8ba77-1c13-4274-88fe-6bd14133861e"
setup = """## Setup
The following Windows audit policies must be enabled to generate the events used by this rule:
- [Audit Directory Service Changes](https://ela.st/audit-directory-service-changes)
- [Audit Detailed File Share](https://ela.st/audit-detailed-file-share)
"""
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Privilege Escalation",
"Tactic: Lateral Movement",
"Data Source: Active Directory",
"Resources: Investigation Guide",
"Use Case: Active Directory Monitoring",
"Data Source: Windows Security Event Logs",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
any where host.os.type == "windows" and event.code in ("5136", "5145") and
(
(
winlog.event_data.AttributeLDAPDisplayName : (
"gPCMachineExtensionNames",
"gPCUserExtensionNames"
) and
winlog.event_data.AttributeValue : "*CAB54552-DEEA-4691-817E-ED4A4D1AFC72*" and
winlog.event_data.AttributeValue : "*AADCED64-746C-4633-A97C-D61349046527*"
) or
(
winlog.event_data.ShareName : "\\\\*\\SYSVOL" and
winlog.event_data.RelativeTargetName : "*ScheduledTasks.xml" and
winlog.event_data.AccessList:"*%%4417*"
)
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1053"
name = "Scheduled Task/Job"
reference = "https://attack.mitre.org/techniques/T1053/"
[[rule.threat.technique.subtechnique]]
id = "T1053.005"
name = "Scheduled Task"
reference = "https://attack.mitre.org/techniques/T1053/005/"
[[rule.threat.technique]]
id = "T1484"
name = "Domain or Tenant Policy Modification"
reference = "https://attack.mitre.org/techniques/T1484/"
[[rule.threat.technique.subtechnique]]
id = "T1484.001"
name = "Group Policy Modification"
reference = "https://attack.mitre.org/techniques/T1484/001/"
[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 = "T1570"
name = "Lateral Tool Transfer"
reference = "https://attack.mitre.org/techniques/T1570/"
[rule.threat.tactic]
id = "TA0008"
name = "Lateral Movement"
reference = "https://attack.mitre.org/tactics/TA0008/"
Stages and Predicates
Stage 1: any
event.code in ("5136", "5145") and host.os.type == "windows" and winlog.event_data.AttributeLDAPDisplayName in~ ("gPCMachineExtensionNames", "gPCUserExtensionNames") and wildcard~(winlog.event_data.AttributeValue, "*AADCED64-746C-4633-A97C-D61349046527*") and wildcard~(winlog.event_data.AttributeValue, "*CAB54552-DEEA-4691-817E-ED4A4D1AFC72*")
Stage 2: any
event.code in ("5136", "5145") and host.os.type == "windows" and wildcard~(winlog.event_data.AccessList, "*%%4417*") and endswith~(winlog.event_data.RelativeTargetName, "ScheduledTasks.xml") and wildcard~(winlog.event_data.ShareName, "\\\\*\\SYSVOL")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.code | in |
| field:"EventID" kind:in |
winlog.event_data.AccessList | wildcard |
| field:"AccessList" kind:wildcard value:"*%%4417*" |
winlog.event_data.AttributeLDAPDisplayName | wildcard |
| field:"AttributeLDAPDisplayName" kind:wildcard |
winlog.event_data.AttributeValue | wildcard |
| field:"AttributeValue" kind:wildcard |
winlog.event_data.RelativeTargetName | wildcard |
| field:"RelativeTargetName" kind:wildcard value:"*ScheduledTasks.xml" |
winlog.event_data.ShareName | wildcard |
| field:"ShareName" kind:wildcard value:"\\*\SYSVOL" |
Suspicious Curl to Google App Script Endpoint
#Detects the use of curl to a Google Script endpoint for the purpose of downloading a second stage payload or tool. Threat actors utilize exposed Google Script endpoints to host payloads as Google URLs are generally whitelisted and bypass security controls.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Command & Control |
Rule Body
[metadata]
creation_date = "2026/01/30"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
Detects the use of curl to a Google Script endpoint for the purpose of downloading a second stage payload
or tool. Threat actors utilize exposed Google Script endpoints to host payloads as Google URLs are
generally whitelisted and bypass security controls.
"""
from = "now-9m"
index = ["logs-endpoint.events.process-*", "logs-endpoint.events.network-*"]
language = "eql"
license = "Elastic License v2"
name = "Suspicious Curl to Google App Script Endpoint"
references = [
"https://www.google.com/script/start/",
"https://attack.mitre.org/techniques/T1105/"
]
risk_score = 73
rule_id = "6b82a0ce-10ac-4cb7-8a66-0ba4d24540cf"
severity = "high"
tags = [
"Domain: Endpoint",
"OS: macOS",
"Use Case: Threat Detection",
"Tactic: Command and Control",
"Data Source: Elastic Defend",
"Resources: Investigation Guide"
]
type = "eql"
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 Curl to Google App Script Endpoint
Google Apps Script is a cloud-based development platform that allows users to extend Google Workspace functionality with custom scripts. Threat actors abuse this legitimate service to host malicious scripts that serve as command and control endpoints, taking advantage of the trusted domain reputation and SSL certificates. This detection rule identifies curl connections to Google Apps Script endpoints from macOS systems, which may indicate C2 communication or payload retrieval from attacker-controlled scripts.
### Possible investigation steps
- Review the process.parent.executable and process.command_line fields to understand what application or script initiated the curl request to Google Apps Script.
- Extract the full URL from process.args to identify the specific Apps Script deployment being accessed and determine if it belongs to your organization.
- Analyze the process.Ext.effective_parent.executable to trace the execution chain and identify the root cause of the suspicious activity.
- Check Google Workspace admin logs if available to review the Apps Script deployment and its contents for malicious code.
- Investigate the user.name associated with the activity to determine if the behavior aligns with their normal duties.
- Review network response data if captured to identify any commands, payloads, or exfiltrated data transmitted via the Apps Script endpoint.
- Search for similar curl to Google Apps Script activity across other endpoints to assess the scope of potential compromise.
### False positive analysis
- Legitimate business automation may use Google Apps Script for workflow integrations. Verify with the script owner and confirm the Apps Script belongs to your organization.
- MDM and management tools like Kandji may interact with Google services legitimately. These are already excluded in the query but verify if additional tools should be added.
- Marketing and analytics platforms may use Apps Script for data collection. Confirm these are sanctioned business applications.
- Development and testing activities may involve Apps Script integrations. Coordinate with development teams to understand expected activities.
### Response and remediation
- Immediately block the suspicious Google Apps Script URL at the proxy or web filter to prevent ongoing C2 communication.
- Terminate the curl process and any parent processes that initiated the suspicious activity.
- Isolate the affected macOS system from the network while conducting forensic analysis.
- Report the malicious Apps Script to Google through their abuse reporting mechanisms to initiate takedown.
- Conduct a thorough scan of the affected system for additional malware, persistence mechanisms, or exfiltrated data.
- Review authentication logs for the affected user account and reset credentials if compromise is suspected.
- Search for similar activity across the environment to identify additional affected systems.
- Implement enhanced monitoring for connections to script.google.com from unexpected applications.
"""
query = '''
sequence by process.entity_id with maxspan=15s
[process where host.os.type == "macos" and event.type == "start" and process.name in ("curl", "nscurl") and
not process.Ext.effective_parent.executable like "/Library/Kandji/Kandji Agent.app/Contents/Helpers/Kandji Library Manager.app/Contents/MacOS/kandji-library-manager"]
[network where host.os.type == "macos" and event.type == "start" and process.name in ("curl", "nscurl") and
destination.domain in ("script.google.com", "script.google.com.")]
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"
[[rule.threat.technique.subtechnique]]
id = "T1071.001"
name = "Web Protocols"
reference = "https://attack.mitre.org/techniques/T1071/001/"
[[rule.threat.technique]]
id = "T1102"
name = "Web Service"
reference = "https://attack.mitre.org/techniques/T1102/"
[[rule.threat.technique.subtechnique]]
id = "T1102.002"
name = "Bidirectional Communication"
reference = "https://attack.mitre.org/techniques/T1102/002/"
[[rule.threat.technique]]
id = "T1105"
name = "Ingress Tool Transfer"
reference = "https://attack.mitre.org/techniques/T1105/"
[rule.threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
Stages and Predicates
Ordered sequence: each step below must occur in order within 15s, correlated by process.entity_id.
Stage 1: process
[process where host.os.type == "macos" and event.type == "start" and process.name in ("curl", "nscurl") and
not process.Ext.effective_parent.executable like "/Library/Kandji/Kandji Agent.app/Contents/Helpers/Kandji Library Manager.app/Contents/MacOS/kandji-library-manager"]
Stage 2: network
[network where host.os.type == "macos" and event.type == "start" and process.name in ("curl", "nscurl") and
destination.domain in ("script.google.com", "script.google.com.")]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
destination.domain | in |
| field:"DestinationHostname" kind:in |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.name | in |
| field:"process_basename" kind:in |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.Ext.effective_parent.executable | eq | /Library/Kandji/Kandji Agent.app/Contents/Helpers/Kandji Library Manager.app/Contents/MacOS/kandji-library-manager | excludes:process.Ext.effective_parent.executable field:"process.Ext.effective_parent.executable" value:"/Library/Kandji/Kandji Agent.app/Contents/Helpers/Kandji Library Manager.app/Contents/MacOS/kandji-library-manager" |
Suspicious DNS Query from Mounted Virtual Disk
#Identifies DNS queries to commonly abused legit web services by a process running from a mounted virtual disk (.iso, .vhd).
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Command & Control |
Rule Body
[rule]
description = """
Identifies DNS queries to commonly abused legit web services by a process running from a mounted virtual disk (.iso,
.vhd).
"""
id = "3bc98de7-3349-43ac-869c-58357ae2aac0"
license = "Elastic License v2"
name = "Suspicious DNS Query from Mounted Virtual Disk"
os_list = ["windows"]
reference = ["https://www.elastic.co/security-labs/globally-distributed-stealers"]
version = "1.0.36"
query = '''
sequence by process.entity_id with maxspan=5m
[process where event.action == "start" and
(process.Ext.device.product_id : ("Virtual DVD-ROM", "Virtual Disk") and not process.executable : "C:\\*") and
not process.hash.sha256 : "cf4179ffdb3eda997a26340edaa70a85f919093d0753239eb4a38d7dc3a1107d"]
[dns where
dns.question.name :
(
/* common ddns */
"*.no-ip.com",
"*.no-ip.org",
"*.no-ip.biz",
"*.no-ip.info",
"*.noip.com",
"*.afraid.org",
"*.changeip.com",
"*.ddns.net",
"*.dyndns.org",
"*.hopto.org",
"*.zapto.org",
"*.servehttp.com",
"*.sytes.net",
"*.myftp.biz",
"*.myftp.org",
"*.ddnsfree.com",
"*.duckdns.org",
"*.000webhostapp.com",
"*.myddns.me",
"*.dlinkddns.com",
"*.chickenkiller.com",
"*.thddns.net",
"*.linkpc.net",
"*.gotdns.ch",
"*.ydns.eu",
"*.dynv6.net",
"*.dns.army",
"*.dns.navy",
"*.v6.army",
"*.v6.navy",
"*.v6.rocks",
/* common websvc */
"raw.githubusercontent.*",
"github.com",
"pastebin.*",
"paste4btc.com",
"paste.ee",
"ghostbin.com",
"drive.google.com",
"?.docs.live.net",
"api.dropboxapi.*",
"content.dropboxapi.*",
"dl.dropboxusercontent.*",
"api.onedrive.com",
"*.onedrive.org",
"onedrive.live.com",
"filebin.net",
"*.ngrok.io",
"ngrok.com",
"*.ngrok-free.app",
"*.portmap.*",
"*serveo.net",
"*localtunnel.me",
"*pagekite.me",
"*localxpose.io",
"*notabug.org",
"rawcdn.githack.*",
"paste.nrecom.net",
"zerobin.net",
"controlc.com",
"requestbin.net",
"api.slack.com",
"slack-redir.net",
"slack-files.com",
"cdn.discordapp.com",
"discordapp.com",
"discord.com",
"apis.azureedge.net",
"cdn.sql.gg",
"?.top4top.io",
"top4top.io",
"www.uplooder.net",
"*.cdnmegafiles.com",
"transfer.sh",
"gofile.io",
"store?.gofile.io",
"updates.peer2profit.com",
"api.telegram.org",
"t.me",
"meacz.gq",
"rwrd.org",
"*.publicvm.com",
"*.blogspot.com",
"api.mylnikov.org",
"file.io",
"stackoverflow.com",
"*files.1drv.com",
"api.anonfile.com",
"*hosting-profi.de",
"ipbase.com",
"ipfs.io",
"*up.freeo*.space",
"mail.*",
"smtp.*",
"api.mylnikov.org",
"script.google.com",
"script.googleusercontent.com",
"api.notion.com",
"graph.microsoft.com",
"*.sharepoint.com",
"mbasic.facebook.com",
"login.live.com",
"api.gofile.io",
"api.anonfiles.com",
"api.notion.com",
"api.trello.com",
"gist.githubusercontent.com",
"files.pythonhosted.org",
"g.live.com",
"*.zulipchat.com",
/* public IP discovery */
"ip-api.com",
"checkip.dyndns.org",
"api.ipify.org",
"whatismyip.akamai.com",
"bot.whatismyipaddress.com",
"ifcfg.me",
"ident.me",
"ipof.in",
"ip.tyk.nu",
"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",
"ipinfo.io",
"geoplugin.net",
"myip.dnsomatic.com",
"www.geoplugin.net",
"api64.ipify.org",
"ip4.seeip.org",
"*.geojs.io",
"*portmap.io",
"*mediafire.com",
"filetransfer.io",
"api.gofile.io",
"api.anonfiles.com",
"api.trello.com",
"api.2ip.ua",
"api.db-ip.com",
"geolocation-db.com",
"httpbin.org",
"www.myexternalip.com",
"ipwho.is",
/* other */
"*.lencr.org",
"*.cloudfront.net",
"*azureedge.net",
"*azure.com",
"graph.microsoft.com",
"cld.pt",
"yandex.ru",
"*.yandex.ru",
"*.aternos.me",
"geo.netsupportsoftware.com",
"webhook.site")]
'''
min_endpoint_version = "8.4.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1204"
name = "User Execution"
reference = "https://attack.mitre.org/techniques/T1204/"
[[threat.technique.subtechnique]]
id = "T1204.002"
name = "Malicious File"
reference = "https://attack.mitre.org/techniques/T1204/002/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"
[[threat.technique.subtechnique]]
id = "T1071.004"
name = "DNS"
reference = "https://attack.mitre.org/techniques/T1071/004/"
[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[internal]
min_endpoint_version = "8.4.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 5m, correlated by process.entity_id.
Stage 1: process
[process where event.action == "start" and
(process.Ext.device.product_id : ("Virtual DVD-ROM", "Virtual Disk") and not process.executable : "C:\\*") and
not process.hash.sha256 : "cf4179ffdb3eda997a26340edaa70a85f919093d0753239eb4a38d7dc3a1107d"]
Stage 2: dns
[dns where
dns.question.name :
(
"*.no-ip.com",
"*.no-ip.org",
"*.no-ip.biz",
"*.no-ip.info",
"*.noip.com",
"*.afraid.org",
"*.changeip.com",
"*.ddns.net",
"*.dyndns.org",
"*.hopto.org",
"*.zapto.org",
"*.servehttp.com",
"*.sytes.net",
"*.myftp.biz",
"*.myftp.org",
"*.ddnsfree.com",
"*.duckdns.org",
"*.000webhostapp.com",
"*.myddns.me",
"*.dlinkddns.com",
"*.chickenkiller.com",
"*.thddns.net",
"*.linkpc.net",
"*.gotdns.ch",
"*.ydns.eu",
"*.dynv6.net",
"*.dns.army",
"*.dns.navy",
"*.v6.army",
"*.v6.navy",
"*.v6.rocks",
"raw.githubusercontent.*",
"github.com",
"pastebin.*",
"paste4btc.com",
"paste.ee",
"ghostbin.com",
"drive.google.com",
"?.docs.live.net",
"api.dropboxapi.*",
"content.dropboxapi.*",
"dl.dropboxusercontent.*",
"api.onedrive.com",
"*.onedrive.org",
"onedrive.live.com",
"filebin.net",
"*.ngrok.io",
"ngrok.com",
"*.ngrok-free.app",
"*.portmap.*",
"*serveo.net",
"*localtunnel.me",
"*pagekite.me",
"*localxpose.io",
"*notabug.org",
"rawcdn.githack.*",
"paste.nrecom.net",
"zerobin.net",
"controlc.com",
"requestbin.net",
"api.slack.com",
"slack-redir.net",
"slack-files.com",
"cdn.discordapp.com",
"discordapp.com",
"discord.com",
"apis.azureedge.net",
"cdn.sql.gg",
"?.top4top.io",
"top4top.io",
"www.uplooder.net",
"*.cdnmegafiles.com",
"transfer.sh",
"gofile.io",
"store?.gofile.io",
"updates.peer2profit.com",
"api.telegram.org",
"t.me",
"meacz.gq",
"rwrd.org",
"*.publicvm.com",
"*.blogspot.com",
"api.mylnikov.org",
"file.io",
"stackoverflow.com",
"*files.1drv.com",
"api.anonfile.com",
"*hosting-profi.de",
"ipbase.com",
"ipfs.io",
"*up.freeo*.space",
"mail.*",
"smtp.*",
"api.mylnikov.org",
"script.google.com",
"script.googleusercontent.com",
"api.notion.com",
"graph.microsoft.com",
"*.sharepoint.com",
"mbasic.facebook.com",
"login.live.com",
"api.gofile.io",
"api.anonfiles.com",
"api.notion.com",
"api.trello.com",
"gist.githubusercontent.com",
"files.pythonhosted.org",
"g.live.com",
"*.zulipchat.com",
"ip-api.com",
"checkip.dyndns.org",
"api.ipify.org",
"whatismyip.akamai.com",
"bot.whatismyipaddress.com",
"ifcfg.me",
"ident.me",
"ipof.in",
"ip.tyk.nu",
"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",
"ipinfo.io",
"geoplugin.net",
"myip.dnsomatic.com",
"www.geoplugin.net",
"api64.ipify.org",
"ip4.seeip.org",
"*.geojs.io",
"*portmap.io",
"*mediafire.com",
"filetransfer.io",
"api.gofile.io",
"api.anonfiles.com",
"api.trello.com",
"api.2ip.ua",
"api.db-ip.com",
"geolocation-db.com",
"httpbin.org",
"www.myexternalip.com",
"ipwho.is",
"*.lencr.org",
"*.cloudfront.net",
"*azureedge.net",
"*azure.com",
"graph.microsoft.com",
"cld.pt",
"yandex.ru",
"*.yandex.ru",
"*.aternos.me",
"geo.netsupportsoftware.com",
"webhook.site")]
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:"start" |
process.Ext.device.product_id | wildcard |
| field:"process.Ext.device.product_id" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.executable | starts_with | C:\ | excludes:process.executable field:"process.executable" value:"C:\" |
process.hash.sha256 | eq | cf4179ffdb3eda997a26340edaa70a85f919093d0753239eb4a38d7dc3a1107d | excludes:process.hash.sha256 field:"process.hash.sha256" value:"cf4179ffdb3eda997a26340edaa70a85f919093d0753239eb4a38d7dc3a1107d" |
Suspicious MsiExec Child Process
#Identifies the execution of a suspicious MsiExec child process. Adversaries may abuse Windows Installers for initial access and delivery of malware.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule Body
[rule]
description = """
Identifies the execution of a suspicious MsiExec child process. Adversaries may abuse Windows Installers for initial
access and delivery of malware.
"""
id = "877c6bd9-8df1-4a15-aa97-2a091731b15d"
license = "Elastic License v2"
name = "Suspicious MsiExec Child Process"
os_list = ["windows"]
reference = ["https://www.elastic.co/security-labs/spring-cleaning-with-latrodectus"]
version = "1.0.33"
query = '''
process where event.action == "start" and
not user.id : "S-1-5-18" and
(process.parent.name : "msiexec.exe" or
process.parent.executable : "?:\\WINDOWS\\Installer\\MSI*.tmp") and
(
(process.name : "rundll32.exe" and process.args : ("?:\\Users\\*\\AppData\\*", "?:\\ProgramData\\*", "?:\\Users\\Public\\*", "-e")) or
(process.parent.args : "/DontWait" and process.parent.args : "/HideWindow") or
(process.name : "cmd.exe" and
process.command_line : ("*start*microsoft-edge:*", "*reg add*", "*fodhelper.exe*", "*CurrentVersion\\Run*", "*set *&set*")) or
process.executable : ("?:\\Users\\*\\Documents\\*", "?:\\Users\\Public\\*", "?:\\ProgramData\\*", "?:\\Users\\*\\AppData\\Roaming\\*") or
process.name : ("wscript.exe", "cscript.exe") or
(process.name : "powershell.exe" and
process.command_line :
("*Software\\Classes\\CLSID*", "*Reflection.Assembly*", "*::Load*",
"?:\\Users\\*\\AppData\\Local\\Temp\\pss*.tmp.ps1", "* -enc *", "* -ec *", "*Add-MpPreference*",
"*WebClient*", "*DownloadFile*", "*DownloadString*", "*iex)*", "*-encodedCommand*", "*HwAaQBlAHgA*")) or
(process.name : "powershell.exe" and process.parent.name : "msiexec.exe" and process.parent.args : "/v") or
/* AteraAgent RMM abused by threat actors - */
(process.pe.original_file_name == "AteraAgent.exe" and process.args : "/IntegratorLogin=*@*" and process.args : "/AccountId=??*") or
(process.pe.original_file_name : "WMIC.exe" and process.args : "MSFT_MpPreference")
) and
/* noisy FP patterns */
not (process.name : "rundll32.exe" and process.command_line : ("*zzzzInvokeManagedCustomActionOutOfProc*", "*MSI*.tmp,WiseElevateRun*")) and
not (process.name : ("wscript.exe", "cscript.exe") and
process.args : ("?:\\Program Files\\*", "?:\\Program Files (x86)\\*", "IsHTTPSListenerPresent.vbs")) and
not (process.executable : "?:\\ProgramData\\*" and (process.Ext.token.integrity_level_name : "high" or process.args : "*uninstall*")) and
not (process.executable : "?:\\Users\\*\\AppData\\Roaming\\*" and (process.code_signature.exists == true or process.Ext.token.integrity_level_name : "high")) and
not (process.name : "powershell.exe" and
process.parent.command_line :
("*\\AppData\\Roaming\\Browser Extension\\*",
"*\\AppData\\Roaming\\Browser Assistant\\*",
"*\\AppData\\Roaming\\BBWC\\*",
"*$env:APPDATA*/Browser Extension/*")) and
not (process.name : "regsvr32.exe" and process.args : "/i:user" and process.args : "/n") and
not (process.executable : "?:\\ProgramData\\*\\*\\*" and process.code_signature.trusted == true) and
not (process.name : "cscript.exe" and process.command_line : "cscript IsHTTPSListenerPresent.vbs") and
not process.pe.imphash in ("693eeec0e40605ff41c9cee4be66760e", "ccb9e4bcad9dd001d25d6220ffcab2dc") and
not process.hash.sha256 :
("d09e299150f4a9904cfbedff7a2478ce16b9c1ea6a5bc2fba0bcb2b1f7a845d0",
"73634c154e121ea172dce96da629f50aa8eb69f72922f5ff14d1331ea281f105",
"7f7635389553b7441a27a2b44988a56155f79320445923e73e59c91ea521f8d2",
"2fd626d4ade59166e3db27ee6f24b24040498928840d88e293edd92c503aca8d",
"530e754c40d38fab5e3f802380f202ca7e1c675ea25b32dfe6d419403d7b0e5b",
"dd1854024eb375e23c42745b1a5848734a262aa5c31571112a0b824c3729a638",
"525b993f89500abc33cab311e453beb2841d2335eb787a3753f7ff092cca195a",
"ba8c1a434b2cc355fc2f005639af36729f32fc91ff1f278bcded65428cad0126",
"7c33270e54646ba7cbda98157a052586812d004670b02f920b285e4eb42507b5",
"3f59a2799dc6aa6cdddbc62e169fad7e7dd282bffba3538ed2594e3a8d6c1a05",
"54b1f519d64469ffcb2c9f417dc9b46e16f44a19522236122741a9df7a877f0a",
"ec4a6b16df94b1c78b48796d7f624fc19253140569ccb51dfb7f6771d2b0e53d",
"0f727129cd58c2291dbccac8930ad80c28b6d19ebfa4c5f91deb4c00b7c75774",
"2aee9f92793ccd46579951e44dc8793045b50e1c23824681a64f653bdae58973",
"801670c7b9d17bd3967c38ad74b5caf0d577fe21819462f54529bf3898c58c94") and
not (process.name : "rundll32.exe" and
process.args : ("printui.dll,PrintUIEntry",
"C:\\ProgramData\\FastTrack Software\\Admin By Request\\ShellHelper??.dll,#1",
"C:\\Users\\*\\AppData\\Local\\Temp\\MSI*.tmp,GetOsVersion")) and
not (process.name : "regsvr32.exe" and process.args : "?:\\ProgramData\\LEAP Office\\Cloud\\Extras\\Automation Extras\\LEAPRedemption64.dll") and
not (process.name : "cmd.exe" and process.args : "del" and process.args : "/f") and
not (process.name : "cmd.exe" and process.args : "C:\\Program") and
not (process.name : "powershell.exe" and
process.command_line : ("*Web Client\\Modules\\NAVWebClientManagement\\NAVWebClientManagement.psm1*", "*https://go.microsoft.com/fwlink/p/?LinkId=*")) and
not (process.name : ("powershell.exe", "cmd.exe") and process.args : ("?:\\Program Files\\*", "?:\\Program Files (x86)\\*")) and
not (process.code_signature.subject_name in ("Dassault Systemes SolidWorks Corp.", "Turning Technologies, LLC") and process.code_signature.trusted == true) and
not (process.name : "powershell.exe" and process.args : "Get-ChildItem -Path . -Exclude *")
'''
min_endpoint_version = "8.6.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 = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"
[[threat.technique.subtechnique]]
id = "T1218.007"
name = "Msiexec"
reference = "https://attack.mitre.org/techniques/T1218/007/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "8.6.0"
Stages and Predicates
Stage 1: process
process where event.action == "start" and
not user.id : "S-1-5-18" and
(process.parent.name : "msiexec.exe" or
process.parent.executable : "?:\\WINDOWS\\Installer\\MSI*.tmp") and
(
(process.name : "rundll32.exe" and process.args : ("?:\\Users\\*\\AppData\\*", "?:\\ProgramData\\*", "?:\\Users\\Public\\*", "-e")) or
(process.parent.args : "/DontWait" and process.parent.args : "/HideWindow") or
(process.name : "cmd.exe" and
process.command_line : ("*start*microsoft-edge:*", "*reg add*", "*fodhelper.exe*", "*CurrentVersion\\Run*", "*set *&set*")) or
process.executable : ("?:\\Users\\*\\Documents\\*", "?:\\Users\\Public\\*", "?:\\ProgramData\\*", "?:\\Users\\*\\AppData\\Roaming\\*") or
process.name : ("wscript.exe", "cscript.exe") or
(process.name : "powershell.exe" and
process.command_line :
("*Software\\Classes\\CLSID*", "*Reflection.Assembly*", "*::Load*",
"?:\\Users\\*\\AppData\\Local\\Temp\\pss*.tmp.ps1", "* -enc *", "* -ec *", "*Add-MpPreference*",
"*WebClient*", "*DownloadFile*", "*DownloadString*", "*iex)*", "*-encodedCommand*", "*HwAaQBlAHgA*")) or
(process.name : "powershell.exe" and process.parent.name : "msiexec.exe" and process.parent.args : "/v") or
(process.pe.original_file_name == "AteraAgent.exe" and process.args : "/IntegratorLogin=*@*" and process.args : "/AccountId=??*") or
(process.pe.original_file_name : "WMIC.exe" and process.args : "MSFT_MpPreference")
) and
not (process.name : "rundll32.exe" and process.command_line : ("*zzzzInvokeManagedCustomActionOutOfProc*", "*MSI*.tmp,WiseElevateRun*")) and
not (process.name : ("wscript.exe", "cscript.exe") and
process.args : ("?:\\Program Files\\*", "?:\\Program Files (x86)\\*", "IsHTTPSListenerPresent.vbs")) and
not (process.executable : "?:\\ProgramData\\*" and (process.Ext.token.integrity_level_name : "high" or process.args : "*uninstall*")) and
not (process.executable : "?:\\Users\\*\\AppData\\Roaming\\*" and (process.code_signature.exists == true or process.Ext.token.integrity_level_name : "high")) and
not (process.name : "powershell.exe" and
process.parent.command_line :
("*\\AppData\\Roaming\\Browser Extension\\*",
"*\\AppData\\Roaming\\Browser Assistant\\*",
"*\\AppData\\Roaming\\BBWC\\*",
"*$env:APPDATA*/Browser Extension/*")) and
not (process.name : "regsvr32.exe" and process.args : "/i:user" and process.args : "/n") and
not (process.executable : "?:\\ProgramData\\*\\*\\*" and process.code_signature.trusted == true) and
not (process.name : "cscript.exe" and process.command_line : "cscript IsHTTPSListenerPresent.vbs") and
not process.pe.imphash in ("693eeec0e40605ff41c9cee4be66760e", "ccb9e4bcad9dd001d25d6220ffcab2dc") and
not process.hash.sha256 :
("d09e299150f4a9904cfbedff7a2478ce16b9c1ea6a5bc2fba0bcb2b1f7a845d0",
"73634c154e121ea172dce96da629f50aa8eb69f72922f5ff14d1331ea281f105",
"7f7635389553b7441a27a2b44988a56155f79320445923e73e59c91ea521f8d2",
"2fd626d4ade59166e3db27ee6f24b24040498928840d88e293edd92c503aca8d",
"530e754c40d38fab5e3f802380f202ca7e1c675ea25b32dfe6d419403d7b0e5b",
"dd1854024eb375e23c42745b1a5848734a262aa5c31571112a0b824c3729a638",
"525b993f89500abc33cab311e453beb2841d2335eb787a3753f7ff092cca195a",
"ba8c1a434b2cc355fc2f005639af36729f32fc91ff1f278bcded65428cad0126",
"7c33270e54646ba7cbda98157a052586812d004670b02f920b285e4eb42507b5",
"3f59a2799dc6aa6cdddbc62e169fad7e7dd282bffba3538ed2594e3a8d6c1a05",
"54b1f519d64469ffcb2c9f417dc9b46e16f44a19522236122741a9df7a877f0a",
"ec4a6b16df94b1c78b48796d7f624fc19253140569ccb51dfb7f6771d2b0e53d",
"0f727129cd58c2291dbccac8930ad80c28b6d19ebfa4c5f91deb4c00b7c75774",
"2aee9f92793ccd46579951e44dc8793045b50e1c23824681a64f653bdae58973",
"801670c7b9d17bd3967c38ad74b5caf0d577fe21819462f54529bf3898c58c94") and
not (process.name : "rundll32.exe" and
process.args : ("printui.dll,PrintUIEntry",
"C:\\ProgramData\\FastTrack Software\\Admin By Request\\ShellHelper??.dll,#1",
"C:\\Users\\*\\AppData\\Local\\Temp\\MSI*.tmp,GetOsVersion")) and
not (process.name : "regsvr32.exe" and process.args : "?:\\ProgramData\\LEAP Office\\Cloud\\Extras\\Automation Extras\\LEAPRedemption64.dll") and
not (process.name : "cmd.exe" and process.args : "del" and process.args : "/f") and
not (process.name : "cmd.exe" and process.args : "C:\\Program") and
not (process.name : "powershell.exe" and
process.command_line : ("*Web Client\\Modules\\NAVWebClientManagement\\NAVWebClientManagement.psm1*", "*https://go.microsoft.com/fwlink/p/?LinkId=*")) and
not (process.name : ("powershell.exe", "cmd.exe") and process.args : ("?:\\Program Files\\*", "?:\\Program Files (x86)\\*")) and
not (process.code_signature.subject_name in ("Dassault Systemes SolidWorks Corp.", "Turning Technologies, LLC") and process.code_signature.trusted == true) and
not (process.name : "powershell.exe" and process.args : "Get-ChildItem -Path . -Exclude *")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard |
process.executable | wildcard |
| field:"Image" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
process.parent.args | wildcard |
| field:"process.parent.args" kind:wildcard |
process.parent.executable | wildcard |
| field:"ParentImage" kind:wildcard value:"?:\WINDOWS\Installer\MSI*.tmp" |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard value:"msiexec.exe" |
process.pe.original_file_name | eq |
| field:"OriginalFileName" kind:eq value:"AteraAgent.exe" |
process.pe.original_file_name | wildcard |
| field:"OriginalFileName" kind:wildcard value:"WMIC.exe" |
Exclusions
The rule actively suppresses these predicates.
Suspicious Scheduled Task Creation via Masqueraded XML File
#Identifies the creation of a scheduled task using an XML file that does not have a .xml file extension. This behavior is consistent with an adversary attempting to establish persistence in a stealthy manner to evade detection.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Stealth |
Rule Body
[rule]
description = """
Identifies the creation of a scheduled task using an XML file that does not have a .xml file extension. This behavior is
consistent with an adversary attempting to establish persistence in a stealthy manner to evade detection.
"""
id = "1efc0496-106b-4c09-b99b-91cdd17ba7b3"
license = "Elastic License v2"
name = "Suspicious Scheduled Task Creation via Masqueraded XML File"
os_list = ["windows"]
reference = ["https://docs.microsoft.com/en-us/windows/win32/taskschd/daily-trigger-example--xml-"]
version = "1.0.34"
query = '''
process where event.action == "start" and
process.pe.original_file_name : "schtasks.exe" and
process.args : ("/create", "-create") and
process.args : ("/xml", "-xml") and
not process.command_line : "*.xml*" and
not process.Ext.token.integrity_level_name == "system" and
not process.parent.executable :
("?:\\ProgramData\\OEM\\UpgradeTool\\CareCenter_*\\BUnzip\\Setup_msi.exe",
"?:\\Program Files\\Axis Communications\\AXIS Camera Station\\SetupActions.exe",
"?:\\Program Files\\Axis Communications\\AXIS Device Manager\\AdmSetupActions.exe",
"?:\\Program Files (x86)\\Zemana\\AntiMalware\\AntiMalware.exe",
"?:\\Program Files\\Dell\\SupportAssist\\pcdrcui.exe",
"?:\\Program Files\\Axis Communications\\AXIS Camera Station\\Installer*\\SetupActions.exe",
"?:\\Program Files (x86)\\Axis Communications\\AXIS Camera Station\\Installer*\\SetupActions.exe",
"?:\\Program Files\\WinCompose\\wincompose.exe") and
not (process.parent.name : "rundll32.exe" and process.parent.args : "?:\\WINDOWS\\Installer\\MSI*.tmp,zzzzInvokeManagedCustomActionOutOfProc")
'''
min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1053"
name = "Scheduled Task/Job"
reference = "https://attack.mitre.org/techniques/T1053/"
[[threat.technique.subtechnique]]
id = "T1053.005"
name = "Scheduled Task"
reference = "https://attack.mitre.org/techniques/T1053/005/"
[threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1036"
name = "Masquerading"
reference = "https://attack.mitre.org/techniques/T1036/"
[[threat.technique.subtechnique]]
id = "T1036.005"
name = "Match Legitimate Resource Name or Location"
reference = "https://attack.mitre.org/techniques/T1036/005/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: process
process where event.action == "start" and
process.pe.original_file_name : "schtasks.exe" and
process.args : ("/create", "-create") and
process.args : ("/xml", "-xml") and
not process.command_line : "*.xml*" and
not process.Ext.token.integrity_level_name == "system" and
not process.parent.executable :
("?:\\ProgramData\\OEM\\UpgradeTool\\CareCenter_*\\BUnzip\\Setup_msi.exe",
"?:\\Program Files\\Axis Communications\\AXIS Camera Station\\SetupActions.exe",
"?:\\Program Files\\Axis Communications\\AXIS Device Manager\\AdmSetupActions.exe",
"?:\\Program Files (x86)\\Zemana\\AntiMalware\\AntiMalware.exe",
"?:\\Program Files\\Dell\\SupportAssist\\pcdrcui.exe",
"?:\\Program Files\\Axis Communications\\AXIS Camera Station\\Installer*\\SetupActions.exe",
"?:\\Program Files (x86)\\Axis Communications\\AXIS Camera Station\\Installer*\\SetupActions.exe",
"?:\\Program Files\\WinCompose\\wincompose.exe") and
not (process.parent.name : "rundll32.exe" and process.parent.args : "?:\\WINDOWS\\Installer\\MSI*.tmp,zzzzInvokeManagedCustomActionOutOfProc")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.pe.original_file_name | wildcard |
| field:"OriginalFileName" kind:wildcard value:"schtasks.exe" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.parent.args | wildcard | ?:\WINDOWS\Installer\MSI*.tmp,zzzzInvokeManagedCustomActionOutOfProc | excludes:process.parent.args field:"process.parent.args" value:"?:\WINDOWS\Installer\MSI*.tmp,zzzzInvokeManagedCustomActionOutOfProc" |
process.parent.name | eq | rundll32.exe | excludes:process.parent.name field:"process.parent.name" value:"rundll32.exe" |
process.Ext.token.integrity_level_name | eq | system | excludes:process.Ext.token.integrity_level_name field:"process.Ext.token.integrity_level_name" value:"system" |
process.command_line | match | .xml | excludes:process.command_line field:"process.command_line" value:".xml" |
process.parent.executable | wildcard | ?:\ProgramData\OEM\UpgradeTool\CareCenter_*\BUnzip\Setup_msi.exe, ?:\Program Files\Axis Communications\AXIS Camera Station\SetupActions.exe, ?:\Program Files\Axis Communications\AXIS Device Manager\AdmSetupActions.exe, ?:\Program Files (x86)\Zemana\AntiMalware\AntiMalware.exe, ?:\Program Files\Dell\SupportAssist\pcdrcui.exe, ?:\Program Files\Axis Communications\AXIS Camera Station\Installer*\SetupActions.exe, ?:\Program Files (x86)\Axis Communications\AXIS Camera Station\Installer*\SetupActions.exe, ?:\Program Files\WinCompose\wincompose.exe | excludes:process.parent.executable |
Suspicious Windows Script Interpreter Child Process
#Identifies unusual windows script interpreter child process which could indicate code injection or other form of malicious code execution via Windows scripts.
MITRE ATT&CK Coverage
Rule Body
[rule]
description = """
Identifies unusual windows script interpreter child process which could indicate code injection or other form of
malicious code execution via Windows scripts.
"""
id = "83da4fac-563a-4af8-8f32-5a3797a9068e"
license = "Elastic License v2"
name = "Suspicious Windows Script Interpreter Child Process"
os_list = ["windows"]
reference = ["https://www.elastic.co/security-labs/thawing-the-permafrost-of-icedid-summary"]
version = "1.0.41"
query = '''
process where event.type == "start" and
process.parent.name : ("wscript.exe", "mshta.exe") and
process.parent.args_count >= 2 and
not process.Ext.token.integrity_level_name == "system" and
(
process.name : ("rundll32.exe", "odbcconf.exe") or
(process.name : ("cmd.exe", "powershell.exe", "curl.exe") and process.parent.name : "mshta.exe") or
/* suspicious or unusual paths */
process.executable : ("?:\\Windows\\Microsoft.NET\\*",
"?:\\Users\\Public\\*",
"?:\\Windows\\Tasks\\*",
"?:\\Windows\\System32\\Tasks\\*") or
/* potential hollowed trusted system process with no arguments */
(process.args_count == 1 and
process.executable : ("?:\\Windows\\System32\\*.exe", "?:\\Windows\\SysWOW64\\*.exe") and
process.code_signature.trusted == true and process.code_signature.subject_name : "Microsoft *" and
not process.name : ("conhost.exe", "gpupdate.exe", "logoff.exe", "HOSTNAME.EXE"))
) and
not (process.parent.name : "mshta.exe" and process.parent.args : "?:\\Program Files\\HP\\*\\HPSolutionsPortal.hta") and
not (process.name : "regsvr32.exe" and process.parent.name : "wscript.exe" and process.parent.command_line : ("*LiteTouch.wsf*", "*LTICleanup.wsf*")) and
not (process.pe.original_file_name == "acslaunch" and process.executable : "?:\\Users\\Public\\IBM\\*.exe") and
not (process.name : ("rundll32.exe", "regsvr32.exe") and
process.args : ("?:\\Program Files\\*", "?:\\Program Files (x86)\\*", "ndfapi.dll,NdfRunDllDiagnoseWithAnswerFile", "?:\\Windows\\sysWOW64\\*.ocx")) and
not process.executable : ("?:\\WINDOWS\\Microsoft.NET\\Framework\\*\\caspol.exe", "?:\\Windows\\System32\\Vmw.exe") and
not (process.name : "rundll32.exe" and process.args : "UpdatePerUserSystemParameters" and process.args : "user32.dll,") and
not (process.executable : "?:\\Windows\\System32\\Vmw.exe" and process.parent.args : "kms_host.vbs") and
not (process.name : "regsvr32.exe" and process.args : "C:\\nondefault\\System\\*.exe" and process.args : "/u") and
not (process.name : ("rundll32.exe", "regsvr32.exe", "regasm.exe") and process.args : ("?:\\Program Files\\*", "?:\\Program Files (x86)\\*")) and
not process.executable : ("?:\\WINDOWS\\Microsoft.NET\\Framework\\*\\caspol.exe", "?:\\Windows\\System32\\Vmw.exe") and
not (process.name : "rundll32.exe" and
process.args : ("printui.dll,PrintUIEntry", "user32.dll,UpdatePerUserSystemParameters", "dfshim.dll,ShArpMaintain")) and
not (process.name : "regsvr32.exe" and process.args : ("?:\\Windows\\sysWOW64\\*.ocx", "?:\\EQ\\System\\QXLAddInDialogs.exe")) and
not (process.code_signature.subject_name : "Dassault Systemes SolidWorks Corp." and process.code_signature.trusted == true) and
not (process.parent.name : "cscript.exe" and
process.parent.args : "?:\\Windows\\Options\\SWD\\MapHomeDrive_*.vbs" and process.name : "mshta.exe") and
not (process.name : "rundll32.exe" and process.parent.args : "?:\\Program Files (x86)\\PCMatic\\PC Matic\\registerActiveX.wsf") and
not process.command_line : "mshta.exe" and
not (process.name : "wscript.exe" and process.args : "\\\\*\\netlogon\\*.vbe") and
not (process.name : "rundll32.exe" and process.args: "C:\\ProgramData\\FastTrack Software\\Admin By Request\\ShellHelper32.dll,#1") and
not (process.name: ("cmd.exe", "regsvr32.exe") and process.parent.executable : "C:\\Windows\\SysWOW64\\mshta.exe") and
not (process.executable : "?:\\Windows\\System32\\odbcconf.exe" and process.args : "configdsn") and
not process.hash.sha256 in ("13eacb4b57ac207f7f5c118915359a6e66a7f52f7154f8bb577f54b48b0d5e68", "6e0cb7d79cfc0b51468904701ff5227270180b9c8ff79d181000049ce991fc5a") and
not (process.parent.name : "mshta.exe" and
process.executable : ("C:\\Windows\\SysWOW64\\cmd.exe", "C:\\Windows\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe") and
process.working_directory : ("C:\\Users\\*\\AppData\\Roaming\\DriverPack Notifier\\bin\\", "\\\\*")) and
not (process.parent.executable : "C:\\Windows\\SysWOW64\\mshta.exe" and process.name : "rundll32.exe" and process.args == "dsquery.dll,OpenQueryWindow") and
not (process.name : "cmd.exe" and process.command_line : "\"C:\\Windows\\System32\\cmd.exe /C mklink /D *")
'''
min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "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.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: process
process where event.type == "start" and
process.parent.name : ("wscript.exe", "mshta.exe") and
process.parent.args_count >= 2 and
not process.Ext.token.integrity_level_name == "system" and
(
process.name : ("rundll32.exe", "odbcconf.exe") or
(process.name : ("cmd.exe", "powershell.exe", "curl.exe") and process.parent.name : "mshta.exe") or
process.executable : ("?:\\Windows\\Microsoft.NET\\*",
"?:\\Users\\Public\\*",
"?:\\Windows\\Tasks\\*",
"?:\\Windows\\System32\\Tasks\\*") or
(process.args_count == 1 and
process.executable : ("?:\\Windows\\System32\\*.exe", "?:\\Windows\\SysWOW64\\*.exe") and
process.code_signature.trusted == true and process.code_signature.subject_name : "Microsoft *" and
not process.name : ("conhost.exe", "gpupdate.exe", "logoff.exe", "HOSTNAME.EXE"))
) and
not (process.parent.name : "mshta.exe" and process.parent.args : "?:\\Program Files\\HP\\*\\HPSolutionsPortal.hta") and
not (process.name : "regsvr32.exe" and process.parent.name : "wscript.exe" and process.parent.command_line : ("*LiteTouch.wsf*", "*LTICleanup.wsf*")) and
not (process.pe.original_file_name == "acslaunch" and process.executable : "?:\\Users\\Public\\IBM\\*.exe") and
not (process.name : ("rundll32.exe", "regsvr32.exe") and
process.args : ("?:\\Program Files\\*", "?:\\Program Files (x86)\\*", "ndfapi.dll,NdfRunDllDiagnoseWithAnswerFile", "?:\\Windows\\sysWOW64\\*.ocx")) and
not process.executable : ("?:\\WINDOWS\\Microsoft.NET\\Framework\\*\\caspol.exe", "?:\\Windows\\System32\\Vmw.exe") and
not (process.name : "rundll32.exe" and process.args : "UpdatePerUserSystemParameters" and process.args : "user32.dll,") and
not (process.executable : "?:\\Windows\\System32\\Vmw.exe" and process.parent.args : "kms_host.vbs") and
not (process.name : "regsvr32.exe" and process.args : "C:\\nondefault\\System\\*.exe" and process.args : "/u") and
not (process.name : ("rundll32.exe", "regsvr32.exe", "regasm.exe") and process.args : ("?:\\Program Files\\*", "?:\\Program Files (x86)\\*")) and
not process.executable : ("?:\\WINDOWS\\Microsoft.NET\\Framework\\*\\caspol.exe", "?:\\Windows\\System32\\Vmw.exe") and
not (process.name : "rundll32.exe" and
process.args : ("printui.dll,PrintUIEntry", "user32.dll,UpdatePerUserSystemParameters", "dfshim.dll,ShArpMaintain")) and
not (process.name : "regsvr32.exe" and process.args : ("?:\\Windows\\sysWOW64\\*.ocx", "?:\\EQ\\System\\QXLAddInDialogs.exe")) and
not (process.code_signature.subject_name : "Dassault Systemes SolidWorks Corp." and process.code_signature.trusted == true) and
not (process.parent.name : "cscript.exe" and
process.parent.args : "?:\\Windows\\Options\\SWD\\MapHomeDrive_*.vbs" and process.name : "mshta.exe") and
not (process.name : "rundll32.exe" and process.parent.args : "?:\\Program Files (x86)\\PCMatic\\PC Matic\\registerActiveX.wsf") and
not process.command_line : "mshta.exe" and
not (process.name : "wscript.exe" and process.args : "\\\\*\\netlogon\\*.vbe") and
not (process.name : "rundll32.exe" and process.args: "C:\\ProgramData\\FastTrack Software\\Admin By Request\\ShellHelper32.dll,#1") and
not (process.name: ("cmd.exe", "regsvr32.exe") and process.parent.executable : "C:\\Windows\\SysWOW64\\mshta.exe") and
not (process.executable : "?:\\Windows\\System32\\odbcconf.exe" and process.args : "configdsn") and
not process.hash.sha256 in ("13eacb4b57ac207f7f5c118915359a6e66a7f52f7154f8bb577f54b48b0d5e68", "6e0cb7d79cfc0b51468904701ff5227270180b9c8ff79d181000049ce991fc5a") and
not (process.parent.name : "mshta.exe" and
process.executable : ("C:\\Windows\\SysWOW64\\cmd.exe", "C:\\Windows\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe") and
process.working_directory : ("C:\\Users\\*\\AppData\\Roaming\\DriverPack Notifier\\bin\\", "\\\\*")) and
not (process.parent.executable : "C:\\Windows\\SysWOW64\\mshta.exe" and process.name : "rundll32.exe" and process.args == "dsquery.dll,OpenQueryWindow") and
not (process.name : "cmd.exe" and process.command_line : "\"C:\\Windows\\System32\\cmd.exe /C mklink /D *")
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_count | eq |
| field:"process.args_count" kind:eq value:"1" |
process.code_signature.subject_name | wildcard |
| field:"Signature" kind:wildcard value:"Microsoft *" |
process.code_signature.trusted | eq |
| field:"process.code_signature.trusted" kind:eq value:"true" |
process.executable | wildcard |
| field:"Image" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
process.parent.args_count | ge |
| field:"process.parent.args_count" kind:ge value:"2" |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
Temporarily Scheduled Task Creation
#Indicates the creation and deletion of a scheduled task within a short time interval. Adversaries can use these to proxy malicious execution via the schedule service and perform clean up.
Known False Positives
- Legitimate scheduled tasks may be created during installation of new software.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Persistence |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2022/08/29"
integration = ["system", "windows"]
maturity = "production"
updated_date = "2026/05/04"
[rule]
author = ["Elastic"]
description = """
Indicates the creation and deletion of a scheduled task within a short time interval. Adversaries can use these to proxy
malicious execution via the schedule service and perform clean up.
"""
false_positives = ["Legitimate scheduled tasks may be created during installation of new software."]
from = "now-9m"
index = ["logs-system.security*", "logs-windows.forwarded*", "winlogbeat-*"]
language = "eql"
license = "Elastic License v2"
name = "Temporarily Scheduled Task Creation"
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 Temporarily Scheduled Task Creation
Scheduled tasks in Windows environments automate routine tasks, but adversaries exploit them for persistence and execution by creating and quickly deleting tasks to mask malicious activity. The detection rule identifies such behavior by tracking task creation and deletion within a short timeframe, flagging potential misuse when these actions occur in rapid succession without typical user patterns.
### Possible investigation steps
- Review the winlog.computer_name field to identify the affected system and determine if it is a critical asset or part of a sensitive network segment.
- Examine the winlog.event_data.TaskName to understand the nature of the task created and deleted, and assess if it aligns with known legitimate tasks or appears suspicious.
- Investigate the user.name associated with the task creation and deletion events to determine if the activity was performed by a legitimate user or potentially compromised account.
- Check for any related events or logs around the same timeframe on the affected system to identify any additional suspicious activities or anomalies.
- Correlate the task creation and deletion events with other security alerts or incidents to determine if this activity is part of a broader attack campaign or isolated incident.
### False positive analysis
- Routine administrative tasks may trigger the rule if system administrators frequently create and delete scheduled tasks for maintenance purposes. To manage this, create exceptions for known administrative accounts or specific task names that are part of regular operations.
- Automated scripts or software updates that temporarily create scheduled tasks can also cause false positives. Identify these scripts or update processes and exclude their associated user accounts or task names from the detection rule.
- Some legitimate applications may use scheduled tasks for temporary operations. Review application documentation to confirm such behavior and exclude these applications by their task names or associated user accounts.
- In environments with frequent testing or development activities, developers might create and delete tasks as part of their workflow. Consider excluding developer accounts or specific task names used in testing environments to reduce noise.
- Scheduled tasks created by monitoring or security tools for short-lived operations can be mistaken for malicious activity. Verify these tools' behavior and exclude their task names or user accounts if they are known to be safe.
### Response and remediation
- Immediately isolate the affected system from the network to prevent further malicious activity and lateral movement.
- Review the scheduled task details, including the task name and associated scripts or executables, to identify any malicious payloads or commands.
- Terminate any malicious processes or executables identified from the scheduled task analysis to stop ongoing threats.
- Restore any altered or deleted system files from a known good backup to ensure system integrity.
- Conduct a thorough scan of the affected system using updated antivirus or endpoint detection and response (EDR) tools to identify and remove any additional malware.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if other systems are affected.
- Implement additional monitoring and alerting for similar scheduled task activities to enhance detection and prevent recurrence of this threat."""
references = ["https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4698"]
risk_score = 47
rule_id = "81ff45f8-f8c2-4e28-992e-5a0e8d98e0fe"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Tactic: Execution",
"Data Source: Windows Security Event Logs",
"Resources: Investigation Guide",
]
type = "eql"
query = '''
sequence by winlog.computer_name, winlog.event_data.TaskName with maxspan=5m
[iam where host.os.type == "windows" and event.action == "scheduled-task-created" and not user.name : "*$"]
[iam where host.os.type == "windows" and event.action == "scheduled-task-deleted" and not user.name : "*$"]
'''
setup = """## Setup
Audit Other Object Access Events must be enabled to generate the events used by this rule.
Setup instructions: https://ela.st/audit-other-object-access-events
"""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1053"
name = "Scheduled Task/Job"
reference = "https://attack.mitre.org/techniques/T1053/"
[[rule.threat.technique.subtechnique]]
id = "T1053.005"
name = "Scheduled Task"
reference = "https://attack.mitre.org/techniques/T1053/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 = "T1053"
name = "Scheduled Task/Job"
reference = "https://attack.mitre.org/techniques/T1053/"
[[rule.threat.technique.subtechnique]]
id = "T1053.005"
name = "Scheduled Task"
reference = "https://attack.mitre.org/techniques/T1053/005/"
[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 5m, correlated by winlog.computer_name, winlog.event_data.TaskName.
Stage 1: iam
[iam where host.os.type == "windows" and event.action == "scheduled-task-created" and not user.name : "*$"]
Stage 2: iam
[iam where host.os.type == "windows" and event.action == "scheduled-task-deleted" and not user.name : "*$"]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
user.name | ends_with | $ | excludes:user.name field:"user.name" value:"$" |
UAC Bypass Attempt via DLL Side-Loading from Windows Media Player Folder
#Identifies attempts to bypass User Account Control (UAC) via DLL side-loading from the trusted Windows Media Player folder. 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 side-loading from the trusted Windows Media Player
folder. Attackers may attempt to bypass UAC to stealthily execute code with elevated permissions.
"""
id = "2aac12a2-23e7-4557-950e-a7b9ab96a26d"
license = "Elastic License v2"
name = "UAC Bypass Attempt via DLL Side-Loading from Windows Media Player Folder"
os_list = ["windows"]
reference = ["https://github.com/hfiref0x/UACME"]
version = "1.0.32"
query = '''
sequence with maxspan=60s
[file where event.action == "rename" and
process.name : "dllhost.exe" and
file.path : ("?:\\Program Files\\Windows Media Player\\*.dll", "?:\\Program Files (x86)\\Windows Media Player\\*.dll")]
[process where event.action == "start" and
process.Ext.token.integrity_level_name : ("high", "system") and
process.executable : ("?:\\Program Files\\Windows Media Player\\*.exe", "?:\\Program Files (x86)\\Windows Media Player\\*.dll")]
'''
min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 1
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "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: file
[file where event.action == "rename" and
process.name : "dllhost.exe" and
file.path : ("?:\\Program Files\\Windows Media Player\\*.dll", "?:\\Program Files (x86)\\Windows Media Player\\*.dll")]
Stage 2: process
[process where event.action == "start" and
process.Ext.token.integrity_level_name : ("high", "system") and
process.executable : ("?:\\Program Files\\Windows Media Player\\*.exe", "?:\\Program Files (x86)\\Windows Media Player\\*.dll")]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard |
process.Ext.token.integrity_level_name | wildcard |
| field:"process.Ext.token.integrity_level_name" kind:wildcard |
process.executable | wildcard |
| field:"Image" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:"dllhost.exe" |
User Discovery Command Execution from Volume Mount
#Detects the execution of a user discovery command from a mounted volume. This is highly abnormal behavior and can be an indication of malicious activity.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Discovery |
Telemetry Coverage
Rule Body
[rule]
description = """
Detects the execution of a user discovery command from a mounted volume. This is highly abnormal behavior and can be an
indication of malicious activity.
"""
id = "a9b01a60-0d26-4b53-b043-1e995ba5c6d1"
license = "Elastic License v2"
name = "User Discovery Command Execution from Volume Mount"
os_list = ["macos"]
version = "1.0.7"
query = '''
sequence with maxspan=1m
[process where event.type == "start" and event.action == "exec" and
process.executable like "/Volumes/*" and
not process.executable like "/Volumes/Docker/Docker.app/Contents/MacOS/com.docker.backend" and
not process.Ext.effective_parent.executable like "/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon"] by process.entity_id
[process where event.type == "start" and event.action == "exec" and
process.parent.executable like "/Volumes/*" and process.name in ("whoami", "dscl", "uname")] by process.parent.entity_id
'''
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 = 1
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1033"
name = "System Owner/User Discovery"
reference = "https://attack.mitre.org/techniques/T1033/"
[threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
[internal]
min_endpoint_version = "8.7.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 1m, correlated by process.entity_id, process.parent.entity_id.
Stage 1: process
[process where event.type == "start" and event.action == "exec" and
process.executable like "/Volumes/*" and
not process.executable like "/Volumes/Docker/Docker.app/Contents/MacOS/com.docker.backend" and
not process.Ext.effective_parent.executable like "/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon"] by process.entity_id
Stage 2: process
[process where event.type == "start" and event.action == "exec" and
process.parent.executable like "/Volumes/*" and process.name in ("whoami", "dscl", "uname")] by process.parent.entity_id
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.executable | wildcard |
| field:"Image" kind:wildcard value:"/Volumes/*" |
process.name | in |
| field:"process_basename" kind:in |
process.parent.executable | wildcard |
| field:"ParentImage" kind:wildcard value:"/Volumes/*" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.Ext.effective_parent.executable | eq | /Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon | excludes:process.Ext.effective_parent.executable field:"process.Ext.effective_parent.executable" value:"/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon" |
process.executable | eq | /Volumes/Docker/Docker.app/Contents/MacOS/com.docker.backend | excludes:process.executable field:"process.executable" value:"/Volumes/Docker/Docker.app/Contents/MacOS/com.docker.backend" |
Volume Shadow Copy Deletion via PowerShell
#Identifies the use of the Win32_ShadowCopy class and related cmdlets to achieve shadow copy deletion. This commonly occurs in tandem with ransomware or other destructive attacks.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Impact |
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 = "2021/07/19"
integration = ["endpoint", "windows", "system", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/05/03"
[rule]
author = ["Elastic", "Austin Songer"]
description = """
Identifies the use of the Win32_ShadowCopy class and related cmdlets to achieve shadow copy deletion. This commonly
occurs in tandem with ransomware or other destructive attacks.
"""
from = "now-9m"
index = [
"endgame-*",
"logs-crowdstrike.fdr*",
"logs-endpoint.events.process-*",
"logs-m365_defender.event-*",
"logs-sentinel_one_cloud_funnel.*",
"logs-system.security*",
"logs-windows.forwarded*",
"logs-windows.sysmon_operational-*",
"winlogbeat-*",
]
language = "eql"
license = "Elastic License v2"
name = "Volume Shadow Copy Deletion via PowerShell"
references = [
"https://docs.microsoft.com/en-us/previous-versions/windows/desktop/vsswmi/win32-shadowcopy",
"https://powershell.one/wmi/root/cimv2/win32_shadowcopy",
"https://www.fortinet.com/blog/threat-research/stomping-shadow-copies-a-second-look-into-deletion-methods",
]
risk_score = 73
rule_id = "d99a037b-c8e2-47a5-97b9-170d076827c4"
severity = "high"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Impact",
"Resources: Investigation Guide",
"Data Source: Elastic Endgame",
"Data Source: Elastic Defend",
"Data Source: Windows Security Event Logs",
"Data Source: Microsoft Defender XDR",
"Data Source: Sysmon",
"Data Source: SentinelOne",
"Data Source: Crowdstrike",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "windows" and event.type == "start" and
process.name : ("powershell.exe", "pwsh.exe", "powershell_ise.exe") and
process.args : ("*Get-WmiObject*", "*gwmi*", "*Get-CimInstance*", "*gcim*") and
process.args : ("*Win32_ShadowCopy*") and
process.args : ("*.Delete()*", "*Remove-WmiObject*", "*rwmi*", "*Remove-CimInstance*", "*rcim*")
'''
note = """## Triage and analysis
### Investigating Volume Shadow Copy Deletion via PowerShell
#### Possible investigation steps
- Does the alert-local PowerShell command show broad shadow-copy deletion, remote targeting, or obscured execution?
- Focus: `process.command_line`, checking whether "Win32_ShadowCopy" is paired with WMI or CIM enumeration and deletion.
- Hint: treat `Get-WmiObject`, `gwmi`, `Get-CimInstance`, `gcim`, `Remove-WmiObject`, `rwmi`, `Remove-CimInstance`, `rcim`, "$_.Delete()", `-ComputerName`, and `-CimSession` as high-signal command cues. This rule requires plaintext cmdlet tokens in `process.args`; fully encoded commands or script-file invocations that hide the deletion logic will not fire this rule.
- Implication: escalate when the command deletes all returned shadow-copy instances, targets remote systems, or hides WMI or CIM deletion behind aliases; lower suspicion only when narrowly scoped to one recognized backup-retention, image-reset, or lab-test workflow on the expected host.
- Is the PowerShell host binary expected rather than renamed or tampered?
- Focus: `process.executable`, `process.name`, `process.pe.original_file_name`, `process.code_signature.subject_name`, and `process.code_signature.trusted`.
- Implication: escalate when path, signer, trust state, or original file name does not match the expected PowerShell host; lower suspicion when identity matches a trusted system PowerShell installation, but continue because legitimate PowerShell can still delete recovery points.
- Does the parent process and user context explain why this host removed shadow copies?
- Focus: `process.parent.executable`, `process.parent.command_line`, `user.id`, `user.name`, and `user.domain`.
- Implication: escalate when Office, a browser, a script host, an unexpected remote-management chain, or a standard user launches deletion; lower suspicion when parent, account, and host match a recognized backup, imaging, disaster-recovery, or lab-reset workflow.
- Do surrounding process events show recovery inhibition or ransomware preparation from the same host or lineage?
- Why: ransomware commonly pairs shadow-copy deletion with other recovery removal or encryption preparation before impact.
- Focus: process starts on `host.id` and, when present, the same `process.entity_id` or lineage, using `process.name`, `process.command_line`, and `process.parent.executable`. $investigate_0
- Range: start with the alert window and following 15 minutes; expand only when the same lineage shows recovery tampering or encryption behavior.
- Implication: escalate when the same window shows `vssadmin`, `wmic`, `diskshadow`, `wbadmin`, backup service stops, recovery-setting changes, or likely encryptor launchers; lower suspicion when activity stays bounded to the same parent-launched cleanup or reset sequence and no other recovery-inhibition utilities appear.
- If command or lineage remains suspicious and endpoint file telemetry is available, does file activity show encryption or destructive cleanup?
- Focus: recover file events with `host.id` + `process.entity_id`; if absent, use `host.id` + `process.pid` plus a tight alert window as a weaker fallback, then review `file.path`, `file.extension`, and `file.Ext.original.extension`. $investigate_1
- Implication: escalate when recovered file events show mass renames, unfamiliar extensions, replaced user files, or ransom-note paths after deletion; lower suspicion only when changes stay inside the recovered backup or reset target. Missing endpoint file telemetry leaves file impact unanswered; do not treat absence of file evidence as benign.
- If local evidence remains suspicious or unresolved, does related alerting show the same VSS deletion or backup-tampering pattern?
- Focus: related impact or execution alerts for the same `user.id` involving VSS deletion, backup tampering, credential access, or the same parent tool. $investigate_2
- Hint: check the same `host.id` for shadow-copy deletion by other binaries, encryption, ransom-note creation, backup tampering, or service tampering. $investigate_3
- Implication: expand scope when the same user touches multiple hosts or the same host shows a broader ransomware chain; keep the case local only when related alerts are absent and local telemetry already fits one recognized workflow.
- Escalate broad or remote shadow-copy deletion that lacks a recognized workflow, has suspicious lineage, destructive process or file evidence, or related spread; close only when narrow command scope, identity, lineage, and supported surrounding telemetry fit one workflow; preserve and escalate mixed or visibility-limited evidence.
### False positive analysis
- PowerShell WMI or CIM shadow-copy deletion is suspicious by default outside controlled backup-retention cleanup, disaster-recovery testing, gold-image preparation, lab reset, or ransomware simulation. Close as benign only when `process.command_line` is narrowly scoped, `process.parent.executable` matches the backup, orchestration, reset, or test tool, `user.id` or `user.name` matches the expected admin or service account, `host.id` plus `host.name` fit the target, and surrounding telemetry shows no destructive process or file impact. Use change records or lab schedules only as corroboration; generic storage maintenance is not enough.
- Before creating an exception, validate historical stability for the same `process.executable`, `process.parent.executable`, stable `process.command_line` scope, `user.id` or `user.name`, and `host.id`. Build the exception from that minimum confirmed workflow pattern. Avoid exceptions on "powershell.exe", `process.name`, or "Win32_ShadowCopy" alone.
### Response and remediation
- If confirmed benign, reverse any temporary containment and record the `process.command_line`, `process.parent.executable`, `user.id` or `user.name`, `host.id`, and maintenance evidence that proved the workflow. Create an exception only if the same command scope, lineage, account, and host recur consistently across prior alerts from this rule.
- If suspicious but unconfirmed, preserve the alert, `process.entity_id`, full `process.command_line`, `process.args`, parent chain, `user.id`, `user.name`, `host.id`, surrounding process commands, and any recovered file-impact examples before containment. Apply reversible containment first: isolate the host only when destructive process or file evidence suggests ongoing impact and the host can tolerate isolation; otherwise restrict the implicated admin channel or account while scope is confirmed. Expand containment to related hosts or accounts only if the same-user or same-host pivots show spread.
- If confirmed malicious, preserve the same process, command, lineage, and recovered file-impact artifacts before destructive action. Prefer endpoint isolation to stop further impact while keeping telemetry available; if direct response is unavailable, escalate with the preserved `host.id`, `user.id`, `user.name`, `process.entity_id`, `process.command_line`, and suspected ransom-note or renamed-extension indicators to the team that can isolate the host and suspend related accounts or services. If the malicious process chain is still active, record `process.entity_id` and `process.command_line` before suspending or terminating it.
- After scope review, remove only the malicious scripts, scheduled tasks, services, payloads, or dropped notes identified during the investigation, then restore affected backup or recovery settings and validate that snapshots or backup jobs are functioning before closure.
- Post-incident hardening: restrict VSS-management workflows and remote CIM deletion patterns to controlled administrative channels, retain the process and file telemetry that proved the case, and review whether adjacent VSS methods such as "vssadmin", "wmic", `diskshadow`, `wbadmin`, COM-based deletion, or diff-area resizing need the same controls.
"""
setup = """## Setup
This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
Setup instructions: https://ela.st/install-elastic-defend
### Additional data sources
This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
- [CrowdStrike](https://ela.st/crowdstrike-integration)
- [Microsoft Defender XDR](https://ela.st/m365-defender)
- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
- [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
- [Windows Process Creation Logs](https://ela.st/audit-process-creation)
"""
[rule.investigation_fields]
field_names = [
"@timestamp",
"host.id",
"user.id",
"process.entity_id",
"process.pid",
"process.executable",
"process.pe.original_file_name",
"process.command_line",
"process.args",
"process.parent.entity_id",
"process.parent.pid",
"process.parent.executable",
"process.parent.command_line",
"process.code_signature.subject_name",
"process.code_signature.trusted",
]
[transform]
[[transform.investigate]]
label = "Process starts on the same host"
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 = "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" }
]
]
relativeFrom = "now-1h"
relativeTo = "now"
[[transform.investigate]]
label = "File events from the PowerShell process"
description = ""
providers = [
[
{ excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" },
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
],
[
{ 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" }
]
]
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 = "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/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1047"
name = "Windows Management Instrumentation"
reference = "https://attack.mitre.org/techniques/T1047/"
[[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
Stage 1: process
process where host.os.type == "windows" and event.type == "start" and
process.name : ("powershell.exe", "pwsh.exe", "powershell_ise.exe") and
process.args : ("*Get-WmiObject*", "*gwmi*", "*Get-CimInstance*", "*gcim*") and
process.args : ("*Win32_ShadowCopy*") and
process.args : ("*.Delete()*", "*Remove-WmiObject*", "*rwmi*", "*Remove-CimInstance*", "*rcim*")
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 | wildcard |
| field:"process.args" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard |