Detection rules › Elastic
Elastic rules: 2i
AWS Discovery API Calls from VPN ASN for the First Time by Identity
#Flags the first time a given IAM principal invokes a narrow set of high-signal discovery APIs (credential check, account and IAM enumeration, bucket and compute inventory, logging introspection) from a source IP whose autonomous system number (ASN) matches a curated set commonly associated with consumer VPN brands, VPN-heavy hosting, and provider networks referenced in public reporting on TeamPCP activity (for example 31173 Services AB AS39351 and Oy Crea Nova Hosting Solution Ltd). Broad List*/Describe* patterns are intentionally omitted to reduce noise. Hosting ASNs are heavily dual-use; validate source.as.number in your data and extend event.action only when your baseline allows it.
Known False Positives
- Administrators, developers, CI runners, and SaaS egress often exit through Datacamp, M247, Vultr, Linode, or brand-name VPN ASNs. Expect more noise on hosting ASNs than on VPN-only registrations. Exclude approved principals, accounts, CIDRs, or ASNs after review. GeoIP and ASN enrichment gaps (`source.as.number` unset) will skip events entirely. Maintain the ASN list with local intelligence (for example RIPE, BGPView, or peeringdb).
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Discovery |
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
- AWS Account Discovery By Rare User (Elastic)
- AWS Bedrock Foundation Model Enumeration Followed by Invocation via Long-Term Key (Elastic)
- AWS Bedrock High Number List Foundation Model Failures (Splunk)
- AWS EC2 Multi-Region DescribeInstances API Calls (Elastic)
- AWS EC2 Role GetCallerIdentity from New Source AS Organization (Elastic)
- AWS IAM Group Read Only Events (Panther)
- AWS RDS Snapshot Enumeration with Public or Shared Flag (Panther)
- AWS STS GetCallerIdentity API Called for the First Time (Elastic)
Rule Body
[metadata]
creation_date = "2026/04/03"
integration = ["aws"]
maturity = "production"
updated_date = "2026/07/15"
[rule]
author = ["Elastic"]
description = """
Flags the first time a given IAM principal invokes a narrow set of high-signal discovery APIs (credential check,
account and IAM enumeration, bucket and compute inventory, logging introspection) from a source IP whose autonomous
system number (ASN) matches a curated set commonly associated with consumer VPN brands, VPN-heavy hosting, and provider
networks referenced in public reporting on TeamPCP activity (for example 31173 Services AB AS39351 and Oy Crea Nova
Hosting Solution Ltd). Broad `List*`/`Describe*` patterns are intentionally omitted to reduce noise. Hosting ASNs are
heavily dual-use; validate `source.as.number` in your data and extend `event.action` only when your baseline allows it.
"""
false_positives = [
"""
Administrators, developers, CI runners, and SaaS egress often exit through Datacamp, M247, Vultr, Linode, or
brand-name VPN ASNs. Expect more noise on hosting ASNs than on VPN-only registrations. Exclude approved principals,
accounts, CIDRs, or ASNs after review. GeoIP and ASN enrichment gaps (`source.as.number` unset) will skip events
entirely. Maintain the ASN list with local intelligence (for example RIPE, BGPView, or peeringdb).
""",
]
from = "now-6m"
index = ["filebeat-*", "logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS Discovery API Calls from VPN ASN for the First Time by Identity"
note = """## Triage and analysis
### Investigating AWS Discovery API Calls from VPN ASN for the First Time by Identity
This rule applies a [New Terms](https://www.elastic.co/guide/en/security/current/rules-ui-create.html#create-new-terms-rule) condition on **`source.as.number`** and **`aws.cloudtrail.user_identity.arn`**. It fires the first time a specific principal is observed calling discovery-like APIs from an IP geolocated to one of the ASNs in the rule query (within the 10-day history window).
**High-signal `event.action` values** (explicit allowlist in the rule query): `GetCallerIdentity`; IAM `ListUsers`,
`ListRoles`, `ListAccessKeys`, `GetAccountSummary`, `ListAccountAliases`, `ListGroups`, `ListMFADevices`; S3 `ListBuckets`;
EC2 `DescribeInstances`, `DescribeRegions`, `DescribeVpcs`, `DescribeSecurityGroups`; Lambda `ListFunctions`; RDS
`DescribeDBInstances`, `DescribeDBSnapshots`; DynamoDB `ListTables`; KMS `ListKeys`, `ListAliases`; CloudTrail
`DescribeTrails`, `LookupEvents`; Bedrock `ListFoundationModels`. Clone the rule to add actions (for example ELB or Secrets Manager) if needed.
**Curated VPN-oriented ASNs (verify locally)** — examples this rule matches (subject to registry and enrichment updates):
| ASN | Commonly associated operator (reference only) |
|-----|-----------------------------------------------|
| 216025 | Mullvad VPN AB |
| 57138 | Mullvad supporting infrastructure |
| 207137 | Tefincom S.A. (NordVPN-related) |
| 212238 | Nord / Nord Security class VPN egress in many datasets |
| 199218 | ProtonVPN |
| 209103 | Proton AG (VPN; confirm in your enrichment source) |
| 209854 | Surfshark Ltd. |
| 141039, 147049 | Packet-style VPN/colocation pools often tied to large VPN footprints |
| 53314 | ExpressVPN-related registration in some registries (often small; validate) |
| 60068 | Datacamp Limited — CDN/hosting; used by several VPN brands and many legitimate workloads (**high dual-use**) |
| 9009 | M247 Ltd — colocation and connectivity; common VPN/proxy exit (**high dual-use**) |
| 20473 | Choopa / Vultr (The Constant Company) — VPS; frequent VPN exit and automation (**high dual-use**) |
| 63949 | Linode LLC (Akamai cloud) — VPS; VPN exits and dev workloads (**dual-use**) |
| 39351 | 31173 Services AB (Sweden) — colocation/hosting; cited in TeamPCP-related reporting (**dual-use**). Not the same as **AS31173** (unrelated Ukrainian ISP). |
| 51765 | Oy Crea Nova Hosting Solution Ltd (Finland) — hosting; cited in TeamPCP-related reporting (**dual-use**) |
| 204187 | Oy Crea Nova Hosting Solution Ltd — related network under the same operator (**dual-use**) |
| 208172 | Proton AG — additional VPN egress network (same Proton operator as 209103 / ProtonVPN) |
| 9002 | RETN Limited — pan-European/global transit backbone; carries VPN/proxy egress plus heavy legitimate traffic (**high dual-use**) |
| 49981 | WorldStream B.V. (Netherlands) — dedicated-server/hosting; VPN exits and many legitimate workloads (**dual-use**) |
Other ASNs sometimes seen for VPN or reseller egress (not in this rule by default) include **16276** (OVH), **14061**
(DigitalOcean), **24940** (Hetzner), **51167** (Contabo), and **49453** (Global Layer). Add them only if your baseline
shows manageable false-positive volume.
#### Possible investigation steps
- Confirm `aws.cloudtrail.user_identity.arn`, `aws.cloudtrail.user_identity.type`, and `aws.cloudtrail.user_identity.access_key_id`.
- Review `event.action` and `event.provider` in the alert; several distinct allowlisted actions from the same session suggest broader enumeration.
- Compare `source.ip`, `source.as.organization.name`, and `source.as.number` against your asset inventory and approved remote-access patterns.
- Hunt ±30 minutes for privilege changes, data access (`GetObject`, snapshot sharing), or credential operations.
### False positive analysis
- First-time legitimate VPN or hosting egress per identity produces a single alert per ASN until the term ages out of the window.
- **Datacamp (60068), M247 (9009), and Vultr (20473)** are especially noisy; consider dropping them locally if alerts exceed capacity.
- **31173 Services AB (39351)** and **Crea Nova (51765, 204187)** are legitimate hosting providers; only escalation-worthy when paired with unexpected identities or follow-on impact.
### Response and remediation
- If unexpected, rotate keys, revoke sessions, and tighten IAM; add exceptions only after documented approval.
### Additional information
- [CloudTrail userIdentity](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-user-identity.html)
- [BGP / ASN lookup](https://bgp.tools/) (third-party) for validating AS registrations
"""
references = [
"https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference.html",
"https://attack.mitre.org/techniques/T1526/",
"https://github.com/bountyyfi/bad-asn-list/blob/main/all.txt"
]
risk_score = 73
rule_id = "e3c7a891-4b2d-4e8c-a1f0-9d8e7c6b5a4d"
severity = "high"
tags = [
"Domain: Cloud",
"Domain: Identity",
"Data Source: AWS",
"Data Source: Amazon Web Services",
"Data Source: AWS CloudTrail",
"Use Case: Threat Detection",
"Tactic: Discovery",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
event.dataset: "aws.cloudtrail"
and aws.cloudtrail.user_identity.arn:(* and not *AWSServiceRoleForConfig*)
and not aws.cloudtrail.user_identity.type: "AWSService"
and event.provider: (
"sts.amazonaws.com" or
"iam.amazonaws.com" or
"s3.amazonaws.com" or
"ec2.amazonaws.com" or
"lambda.amazonaws.com" or
"rds.amazonaws.com" or
"dynamodb.amazonaws.com" or
"kms.amazonaws.com" or
"cloudtrail.amazonaws.com" or
"bedrock.amazonaws.com"
)
and event.action: (
"GetCallerIdentity" or
"ListUsers" or
"ListRoles" or
"ListAccessKeys" or
"GetAccountSummary" or
"ListAccountAliases" or
"ListGroups" or
"ListMFADevices" or
"ListBuckets" or
"DescribeInstances" or
"DescribeRegions" or
"DescribeVpcs" or
"DescribeSecurityGroups" or
"ListFunctions" or
"DescribeDBInstances" or
"DescribeDBSnapshots" or
"ListTables" or
"ListKeys" or
"ListAliases" or
"DescribeTrails" or
"LookupEvents" or
"ListFoundationModels"
)
and source.as.number: (
216025 or
57138 or
207137 or
212238 or
199218 or
209103 or
209854 or
141039 or
147049 or
53314 or
60068 or
9009 or
20473 or
63949 or
39351 or
51765 or
204187 or
29066 or
206092 or
208172 or
9002 or
49981
)
'''
[rule.investigation_fields]
field_names = [
"@timestamp",
"user.name",
"user_agent.original",
"source.ip",
"source.as.number",
"source.as.organization.name",
"aws.cloudtrail.user_identity.arn",
"aws.cloudtrail.user_identity.type",
"aws.cloudtrail.user_identity.access_key_id",
"event.provider",
"event.action",
"event.outcome",
"cloud.account.id",
"cloud.region",
]
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1526"
name = "Cloud Service Discovery"
reference = "https://attack.mitre.org/techniques/T1526/"
[[rule.threat.technique]]
id = "T1580"
name = "Cloud Infrastructure Discovery"
reference = "https://attack.mitre.org/techniques/T1580/"
[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
[rule.new_terms]
field = "new_terms_fields"
value = ["source.as.number", "user.name", "cloud.account.id"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-10d"
Stages and Predicates
Stage 1: new_terms
event.dataset: "aws.cloudtrail"
and aws.cloudtrail.user_identity.arn:(* and not *AWSServiceRoleForConfig*)
and not aws.cloudtrail.user_identity.type: "AWSService"
and event.provider: (
"sts.amazonaws.com" or
"iam.amazonaws.com" or
"s3.amazonaws.com" or
"ec2.amazonaws.com" or
"lambda.amazonaws.com" or
"rds.amazonaws.com" or
"dynamodb.amazonaws.com" or
"kms.amazonaws.com" or
"cloudtrail.amazonaws.com" or
"bedrock.amazonaws.com"
)
and event.action: (
"GetCallerIdentity" or
"ListUsers" or
"ListRoles" or
"ListAccessKeys" or
"GetAccountSummary" or
"ListAccountAliases" or
"ListGroups" or
"ListMFADevices" or
"ListBuckets" or
"DescribeInstances" or
"DescribeRegions" or
"DescribeVpcs" or
"DescribeSecurityGroups" or
"ListFunctions" or
"DescribeDBInstances" or
"DescribeDBSnapshots" or
"ListTables" or
"ListKeys" or
"ListAliases" or
"DescribeTrails" or
"LookupEvents" or
"ListFoundationModels"
)
and source.as.number: (
216025 or
57138 or
207137 or
212238 or
199218 or
209103 or
209854 or
141039 or
147049 or
53314 or
60068 or
9009 or
20473 or
63949 or
39351 or
51765 or
204187 or
29066 or
206092 or
208172 or
9002 or
49981
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
aws.cloudtrail.user_identity.arn | is_not_null | field:"aws::userIdentity.arn" kind:is_not_null | |
event.action | in |
| field:"EventType" kind:in |
event.dataset | eq |
| field:"event.dataset" kind:eq value:"aws.cloudtrail" |
event.provider | in |
| field:"Provider_Name" kind:in |
source.as.number | in |
| field:"source.as.number" kind:in |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
aws.cloudtrail.user_identity.arn | match | AWSServiceRoleForConfig | excludes:aws.cloudtrail.user_identity.arn field:"aws.cloudtrail.user_identity.arn" value:"AWSServiceRoleForConfig" |
aws.cloudtrail.user_identity.type | eq | AWSService | excludes:aws.cloudtrail.user_identity.type field:"aws.cloudtrail.user_identity.type" value:"AWSService" |
AWS RDS DB Instance Made Public
#Identifies the creation or modification of an Amazon RDS DB instance or cluster where the "publiclyAccessible" attribute is set to "true". Publicly accessible RDS instances expose a network endpoint on the public internet, which may allow unauthorized access if combined with overly permissive security groups, weak authentication, or misconfigured IAM policies. Adversaries may enable public access on an existing instance, or create a new publicly accessible instance, to establish persistence, move data outside of controlled network boundaries, or bypass internal access controls.
Known False Positives
- Public access is a common configuration used to enable access from outside a private VPC. Ensure that the instance should not be modified in this way before taking action.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence |
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
- AWS Credential Access RDS Password reset (Splunk)
- AWS RDS DB Instance or Cluster Deletion Protection Disabled (Elastic)
- AWS RDS DB Instance or Cluster Password Modified (Elastic)
- AWS RDS Deletion Protection Disabled (Panther)
- AWS RDS Instance Modified to be Publicly Accessible (Panther)
- AWS RDS Master Password Change (Sigma)
- AWS RDS Master Password Updated (Panther)
- AWS RDS Snapshot Deleted (Elastic)
Rule Body
[metadata]
creation_date = "2024/06/29"
integration = ["aws"]
maturity = "production"
updated_date = "2026/08/05"
[rule]
author = ["Elastic"]
description = """
Identifies the creation or modification of an Amazon RDS DB instance or cluster where the "publiclyAccessible" attribute
is set to "true". Publicly accessible RDS instances expose a network endpoint on the public internet, which may allow
unauthorized access if combined with overly permissive security groups, weak authentication, or misconfigured IAM
policies. Adversaries may enable public access on an existing instance, or create a new publicly accessible instance, to
establish persistence, move data outside of controlled network boundaries, or bypass internal access controls.
"""
false_positives = [
"""
Public access is a common configuration used to enable access from outside a private VPC. Ensure that the instance
should not be modified in this way before taking action.
""",
]
from = "now-6m"
index = ["filebeat-*", "logs-aws.cloudtrail-*"]
language = "eql"
license = "Elastic License v2"
name = "AWS RDS DB Instance Made Public"
note = """## Triage and analysis
### Investigating AWS RDS DB Instance Made Public
This rule detects when an Amazon RDS DB instance or cluster is created or modified with
`publiclyAccessible=true`. While some environments operate publicly accessible RDS instances,
unexpected exposure of a database to the internet is a meaningful security risk. Adversaries who
gain access to AWS credentials may modify a DB instance’s public accessibility to exfiltrate data,
establish persistence, or bypass internal network restrictions.
#### Possible Investigation Steps
- **Identify the actor**
- Review `aws.cloudtrail.user_identity.arn`, `aws.cloudtrail.user_identity.type`, and `access_key_id` to determine which IAM principal made the change.
- Determine whether the user, role, or automation service typically manages RDS configurations.
- **Examine the request parameters**
- Review `aws.cloudtrail.request_parameters` for:
- `publiclyAccessible=true`
- DBInstanceIdentifier / DBClusterIdentifier
- Additional changes included in the same modification request (e.g., master user changes, security group updates)
- **Validate the target resource**
- Determine the sensitivity of the instance:
- What data does it store?
- Is it production, staging, dev, or ephemeral?
- Confirm whether the instance was previously private.
- **Assess network exposure**
- Check associated security groups for:
- `0.0.0.0/0` (unrestricted ingress)
- Unexpected IP ranges
- Review VPC/subnet placement to determine if the instance is reachable externally.
- **Correlate with other recent CloudTrail activity**
- Look for related events performed by the same actor:
- `AuthorizeSecurityGroupIngress`
- `ModifyDBInstance`
- IAM policy modifications enabling broader DB access
- Look for indicators of credential misuse:
- unusual `source.ip`
- unusual `user_agent.original`
- MFA not used (`session_context.mfa_authenticated=false`)
- **Validate intent with owners**
- Contact the service or database owner to confirm whether the change was an approved part of a deployment or migration.
### False Positive Analysis
- **Expected public-access configuration**
- Some workloads intentionally require public access (e.g., internet-facing reporting tools).
- Validate against change management tickets, deployment pipelines, or Terraform/IaC automation logs.
### Response and Remediation
- **Containment**
- If exposure is unauthorized:
- Modify the instance to disable public access (`publiclyAccessible=false`).
- Restrict the security group inbound rules immediately.
- Snapshot the instance to preserve state if compromise is suspected.
- **Investigation**
- Review all recent actions from the same IAM principal.
- Check for data access patterns (CloudWatch, RDS Enhanced Monitoring, VPC Flow Logs).
- Identify whether this exposure correlates with suspicious outbound network activity.
- **Hardening**
- Require private-only RDS instances unless explicitly documented.
- Enforce security group least privilege and block public DB access via:
- AWS Config rules (`rds-instance-public-access-check`)
- Service Control Policies (SCPs) preventing public RDS settings
- Implement continuous monitoring for network or configuration drift.
- **Recovery**
- Restore the database to a private subnet if necessary.
- Rotate credentials used by the DB instance and associated applications.
- Document the incident and update policies or IaC templates to prevent recurrence.
### Additional Information:
- **[AWS IR Playbooks](https://github.com/aws-samples/aws-incident-response-playbooks/blob/c151b0dc091755fffd4d662a8f29e2f6794da52c/playbooks/)**
- **[AWS Customer Playbook Framework](https://github.com/aws-samples/aws-customer-playbook-framework/tree/a8c7b313636b406a375952ac00b2d68e89a991f2/docs)**
- **Security Best Practices:** [AWS Knowledge Center – Security Best Practices](https://aws.amazon.com/premiumsupport/knowledge-center/security-best-practices/).
"""
references = [
"https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_ModifyDBInstance.html",
"https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.DBInstance.Modifying.html",
"https://cloud.hacktricks.xyz/pentesting-cloud/aws-security/aws-persistence/aws-rds-persistence#make-instance-publicly-accessible-rds-modifydbinstance",
"https://cloud.hacktricks.xyz/pentesting-cloud/aws-security/aws-privilege-escalation/aws-rds-privesc#rds-createdbinstance",
]
risk_score = 47
rule_id = "9efb3f79-b77b-466a-9fa0-3645d22d1e7f"
severity = "medium"
tags = [
"Domain: Cloud",
"Platform: AWS",
"Data Source: AWS CloudTrail",
"Service: AWS RDS",
"Tactic: Defense Evasion",
"Tactic: Persistence",
"Rule Type: Event Correlation (EQL)",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
any where data_stream.dataset == "aws.cloudtrail"
and event.provider == "rds.amazonaws.com"
and event.outcome == "success"
and (
(event.action == "ModifyDBInstance" and stringContains(aws.cloudtrail.request_parameters, "publiclyAccessible=true"))
or
(event.action in ("CreateDBInstance", "CreateDBCluster") and stringContains(aws.cloudtrail.request_parameters, "publiclyAccessible=true"))
)
and not user_agent.original like~ ("*Terraform*", "*Pulumi*")
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1133"
name = "External Remote Services"
reference = "https://attack.mitre.org/techniques/T1133/"
[[rule.threat.technique]]
id = "T1556"
name = "Modify Authentication Process"
reference = "https://attack.mitre.org/techniques/T1556/"
[[rule.threat.technique.subtechnique]]
id = "T1556.009"
name = "Conditional Access Policies"
reference = "https://attack.mitre.org/techniques/T1556/009/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[rule.investigation_fields]
field_names = [
"@timestamp",
"user.name",
"user_agent.original",
"source.ip",
"aws.cloudtrail.user_identity.arn",
"aws.cloudtrail.user_identity.type",
"aws.cloudtrail.user_identity.access_key_id",
"event.action",
"event.outcome",
"cloud.account.id",
"cloud.region",
"aws.cloudtrail.request_parameters",
"aws.cloudtrail.response_elements",
]
Stages and Predicates
Stage 1: any
any where data_stream.dataset == "aws.cloudtrail"
and event.provider == "rds.amazonaws.com"
and event.outcome == "success"
and (
(event.action == "ModifyDBInstance" and stringContains(aws.cloudtrail.request_parameters, "publiclyAccessible=true"))
or
(event.action in ("CreateDBInstance", "CreateDBCluster") and stringContains(aws.cloudtrail.request_parameters, "publiclyAccessible=true"))
)
and not user_agent.original like~ ("*Terraform*", "*Pulumi*")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
aws.cloudtrail.request_parameters | contains |
| field:"aws::requestParameters" kind:contains value:"publiclyAccessible=true" |
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"aws.cloudtrail" |
event.action | eq |
| field:"EventType" kind:eq value:"ModifyDBInstance" |
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:"rds.amazonaws.com" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
user_agent.original | match | Terraform, Pulumi | excludes:user_agent.original field:"user_agent.original" value:"Terraform" field:"user_agent.original" value:"Pulumi" |
Azure Kubernetes Services (AKS) Kubernetes Events Deleted
#Identifies when events are deleted in Azure Kubernetes. Kubernetes events are objects that log any state changes. Example events are a container creation, an image pull, or a pod scheduling on a node. An adversary may delete events in Azure Kubernetes in an attempt to evade detection.
Known False Positives
- Events deletions may be done by a system or network administrator. Verify whether the username, hostname, and/or resource name should be making changes in your environment. Events deletions by unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Rule Body
[metadata]
creation_date = "2021/06/24"
integration = ["azure"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Austin Songer"]
description = """
Identifies when events are deleted in Azure Kubernetes. Kubernetes events are objects that log any state changes.
Example events are a container creation, an image pull, or a pod scheduling on a node. An adversary may delete events in
Azure Kubernetes in an attempt to evade detection.
"""
false_positives = [
"""
Events deletions may be done by a system or network administrator. Verify whether the username, hostname, and/or
resource name should be making changes in your environment. Events deletions by unfamiliar users or hosts should be
investigated. If known behavior is causing false positives, it can be exempted from the rule.
""",
]
from = "now-9m"
index = ["logs-azure.activitylogs-*", "filebeat-*"]
language = "kuery"
license = "Elastic License v2"
name = "Azure Kubernetes Services (AKS) Kubernetes Events Deleted"
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Azure Kubernetes Services (AKS) Kubernetes Events Deleted
Azure Kubernetes Service (AKS) manages containerized applications using Kubernetes, which logs events like state changes. These logs are crucial for monitoring and troubleshooting. Adversaries may delete these logs to hide their tracks, impairing defenses. The detection rule identifies such deletions by monitoring specific Azure activity logs, flagging successful deletion operations to alert security teams of potential evasion tactics.
### Possible investigation steps
- Review the Azure activity logs to confirm the deletion event by checking for the operation name "MICROSOFT.KUBERNETES/CONNECTEDCLUSTERS/EVENTS.K8S.IO/EVENTS/DELETE" and ensure the event outcome is marked as "Success".
- Identify the user or service principal responsible for the deletion by examining the associated identity information in the activity logs.
- Investigate the timeline of events leading up to and following the deletion to identify any suspicious activities or patterns, such as unauthorized access attempts or configuration changes.
- Check for any other related alerts or anomalies in the Azure environment that might indicate a broader attack or compromise.
- Assess the impact of the deleted events by determining which Kubernetes resources or operations were affected and if any critical logs were lost.
- Review access controls and permissions for the user or service principal involved to ensure they align with the principle of least privilege and adjust if necessary.
- Consider implementing additional monitoring or alerting for similar deletion activities to enhance detection and response capabilities.
### False positive analysis
- Routine maintenance activities by authorized personnel may trigger deletion events. To manage this, create exceptions for known maintenance windows or specific user accounts responsible for these tasks.
- Automated scripts or tools used for log rotation or cleanup might delete events as part of their normal operation. Identify these scripts and exclude their activity from triggering alerts by whitelisting their associated service accounts or IP addresses.
- Misconfigured applications or services that inadvertently delete logs can cause false positives. Review application configurations and adjust them to prevent unnecessary deletions, and exclude these applications from alerts if they are verified as non-threatening.
- Test environments often generate log deletions during setup or teardown processes. Exclude these environments from monitoring or create specific rules that differentiate between production and test environments to avoid unnecessary alerts.
### Response and remediation
- Immediately isolate the affected Azure Kubernetes cluster to prevent further unauthorized access or tampering with logs.
- Conduct a thorough review of recent activity logs and access permissions for the affected cluster to identify any unauthorized access or privilege escalation.
- Restore deleted Kubernetes events from backups or snapshots if available, to ensure continuity in monitoring and auditing.
- Implement stricter access controls and audit logging for Kubernetes event deletion operations to prevent unauthorized deletions in the future.
- Notify the security operations team and relevant stakeholders about the incident for awareness and further investigation.
- Escalate the incident to the incident response team if there is evidence of broader compromise or if the deletion is part of a larger attack campaign.
- Review and update incident response plans to incorporate lessons learned from this event, ensuring quicker detection and response to similar threats in the future.
## Setup
The Azure Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
references = [
"https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftkubernetes",
]
risk_score = 47
rule_id = "8b64d36a-1307-4b2e-a77b-a0027e4d27c8"
severity = "medium"
tags = ["Domain: Cloud", "Data Source: Azure", "Use Case: Log Auditing", "Tactic: Defense Evasion", "Resources: Investigation Guide"]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:azure.activitylogs and azure.activitylogs.operation_name:"MICROSOFT.KUBERNETES/CONNECTEDCLUSTERS/EVENTS.K8S.IO/EVENTS/DELETE" and
event.outcome:(Success or success)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[[rule.threat.technique.subtechnique]]
id = "T1562.001"
name = "Disable or Modify Tools"
reference = "https://attack.mitre.org/techniques/T1562/001/"
[[rule.threat.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:azure.activitylogs and azure.activitylogs.operation_name:"MICROSOFT.KUBERNETES/CONNECTEDCLUSTERS/EVENTS.K8S.IO/EVENTS/DELETE" and
event.outcome:(Success or success)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
azure.activitylogs.operation_name | eq |
| field:"azure.activitylogs.operation_name" kind:eq value:"MICROSOFT.KUBERNETES/CONNECTEDCLUSTERS/EVENTS.K8S.IO/EVENTS/DELETE" |
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"azure.activitylogs" |
event.outcome | in |
| field:"event.outcome" kind:in |
Command Shell Activity Started via RunDLL32
#Identifies command shell activity started via RunDLL32, which is commonly abused by attackers to host malicious code.
MITRE ATT&CK Coverage
Rule Body
[rule]
description = "Identifies command shell activity started via RunDLL32, which is commonly abused by attackers to host malicious code."
id = "b8a0a3aa-0345-4035-b41d-f758a6c59a78"
license = "Elastic License v2"
name = "Command Shell Activity Started via RunDLL32"
os_list = ["windows"]
reference = ["https://www.elastic.co/security-labs/spring-cleaning-with-latrodectus"]
version = "1.0.34"
query = '''
process where event.type == "start" and
process.name : ("cmd.exe", "powershell.exe") and
process.parent.name : "rundll32.exe" and process.parent.command_line != null and
not process.parent.command_line :
("*:\\Windows\\System32\\SHELL32.dll,RunAsNewUser_RunDLL*",
"*zzzzInvokeManagedCustomActionOutOfProc*",
"\"C:\\WINDOWS\\system32\\rundll32.exe\" C:\\WINDOWS\\system32\\PcaSvc.dll,PcaPatchSdbTask") and
not (process.parent.args : "aepdu.dll,AePduRunUpdate" and process.args : "osloader" and process.args : "%windir%\\system32\\bcdedit") and
not (process.parent.args : ("?:\\Windows\\System32\\LogiLDA.dll,LogiFetch", "?:\\WINDOWS\\system32\\PcaSvc.dll,PcaPatchSdbTask") and
process.name : "powershell.exe" and process.command_line : "*install*") and
not process.parent.args : "C:\\Program Files\\NVIDIA Corporation\\*\\NVI2.DLL,ResumeAsync" and
not (process.args : "dellpointstick://Mainpage/*" and process.parent.args : "Vxd_launch_UI") and
not (process.parent.args : "?:\\Windows\\system32\\davclnt.dll,DavSetCookie" and process.name : "powershell.exe") and
not process.parent.args : "AppXDeploymentExtensions.OneCore.dll,ShellRefresh" and
not (process.args : ("launchalpsdelltouchpad://Mainpage/path2?param=start", "alpsdelltouchpadsettings://Mainpage/path2?param=start") and
process.parent.args : "?:\\WINDOWS\\System32\\main.cpl") and
not (process.command_line : "*REG QUERY HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography*" and
process.parent.args : "?:\\WINDOWS\\system32\\PcaSvc.dll,PcaPatchSdbTask") and
not (process.args : "launchalpsdelltouchpad://Mainpage/path2?param=start" and process.parent.args : "Vxd_launch_UI") and
not (process.working_directory : "C:\\Program Files (x86)\\Windows Kits\\*\\Assessment and Deployment Kit\\Windows Assessment Toolkit\\Energy\\" and
process.args : "axecore.dll,RunJob_RunDll") and
not process.parent.command_line : "rundll32.exe \"C:\\Program Files (x86)\\Windows Shell\\fx_ws_main.dll\",ProcessDll s=hidedialog" and
not (process.parent.command_line : "C:\\Windows\\system32\\rundll32.exe iernonce.dll,RunOnceExProcess" and
process.working_directory : "C:\\Windows\\system32\\") and
not (process.parent.command_line : "\"C:\\WINDOWS\\System32\\rundll32.exe\" C:\\WINDOWS\\Lvgic10u.dll,Execute" and
process.command_line : "cmd /c C:\\WINDOWS\\System32\\rundll32.exe C:\\WINDOWS\\Lvgic10u.dll,ExecuteQuick")
'''
min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"
[[threat.technique.subtechnique]]
id = "T1059.003"
name = "Windows Command Shell"
reference = "https://attack.mitre.org/techniques/T1059/003/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[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.011"
name = "Rundll32"
reference = "https://attack.mitre.org/techniques/T1218/011/"
[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.name : ("cmd.exe", "powershell.exe") and
process.parent.name : "rundll32.exe" and process.parent.command_line != null and
not process.parent.command_line :
("*:\\Windows\\System32\\SHELL32.dll,RunAsNewUser_RunDLL*",
"*zzzzInvokeManagedCustomActionOutOfProc*",
"\"C:\\WINDOWS\\system32\\rundll32.exe\" C:\\WINDOWS\\system32\\PcaSvc.dll,PcaPatchSdbTask") and
not (process.parent.args : "aepdu.dll,AePduRunUpdate" and process.args : "osloader" and process.args : "%windir%\\system32\\bcdedit") and
not (process.parent.args : ("?:\\Windows\\System32\\LogiLDA.dll,LogiFetch", "?:\\WINDOWS\\system32\\PcaSvc.dll,PcaPatchSdbTask") and
process.name : "powershell.exe" and process.command_line : "*install*") and
not process.parent.args : "C:\\Program Files\\NVIDIA Corporation\\*\\NVI2.DLL,ResumeAsync" and
not (process.args : "dellpointstick://Mainpage/*" and process.parent.args : "Vxd_launch_UI") and
not (process.parent.args : "?:\\Windows\\system32\\davclnt.dll,DavSetCookie" and process.name : "powershell.exe") and
not process.parent.args : "AppXDeploymentExtensions.OneCore.dll,ShellRefresh" and
not (process.args : ("launchalpsdelltouchpad://Mainpage/path2?param=start", "alpsdelltouchpadsettings://Mainpage/path2?param=start") and
process.parent.args : "?:\\WINDOWS\\System32\\main.cpl") and
not (process.command_line : "*REG QUERY HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography*" and
process.parent.args : "?:\\WINDOWS\\system32\\PcaSvc.dll,PcaPatchSdbTask") and
not (process.args : "launchalpsdelltouchpad://Mainpage/path2?param=start" and process.parent.args : "Vxd_launch_UI") and
not (process.working_directory : "C:\\Program Files (x86)\\Windows Kits\\*\\Assessment and Deployment Kit\\Windows Assessment Toolkit\\Energy\\" and
process.args : "axecore.dll,RunJob_RunDll") and
not process.parent.command_line : "rundll32.exe \"C:\\Program Files (x86)\\Windows Shell\\fx_ws_main.dll\",ProcessDll s=hidedialog" and
not (process.parent.command_line : "C:\\Windows\\system32\\rundll32.exe iernonce.dll,RunOnceExProcess" and
process.working_directory : "C:\\Windows\\system32\\") and
not (process.parent.command_line : "\"C:\\WINDOWS\\System32\\rundll32.exe\" C:\\WINDOWS\\Lvgic10u.dll,Execute" and
process.command_line : "cmd /c C:\\WINDOWS\\System32\\rundll32.exe C:\\WINDOWS\\Lvgic10u.dll,ExecuteQuick")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
process.parent.command_line | is_not_null | field:"ParentCommandLine" kind:is_not_null | |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard value:"rundll32.exe" |
Exclusions
The rule actively suppresses these predicates.
Cron Tab Creation or Modification via Shell Command
#Detects the creation or modification of cron tabs by a suspicious or malicious process. Cron is one of the most well known persistence mechanisms for macOS. It is a scheduler that allows a user to create a scheduled execution. Threat actors have abused this tool to persist their malware on macOS systems.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Persistence |
Rule Body
[rule]
description = """
Detects the creation or modification of cron tabs by a suspicious or malicious process. Cron is one of the most well
known persistence mechanisms for macOS. It is a scheduler that allows a user to create a scheduled execution. Threat
actors have abused this tool to persist their malware on macOS systems.
"""
id = "e5fc1285-d312-4b45-9e6b-e6c037276c17"
license = "Elastic License v2"
name = "Cron Tab Creation or Modification via Shell Command"
os_list = ["macos"]
reference = ["https://theevilbit.github.io/beyond/beyond_0004/"]
version = "1.0.24"
query = '''
sequence by process.entity_id with maxspan=5s
[process where event.type == "start" and (process.name in ("bash", "sh", "zsh", "dash", "csh", "tcsh", "ksh", "tclsh", "fish") or process.name like "tclsh*") and process.args == "-c" and
not process.command_line : ("*/.claude/shell-snapshots/*", "*/.codex/shell_snapshots/*", "*/.cursor/shell-snapshots/*")]
[file where event.action != "deletion" and
file.path like "/private/var/at/tabs/*" and
process.executable == "/usr/bin/crontab" and not
file.path == "/private/var/at/tabs/root"]
'''
min_endpoint_version = "8.11.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.003"
name = "Cron"
reference = "https://attack.mitre.org/techniques/T1053/003/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[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.003"
name = "Cron"
reference = "https://attack.mitre.org/techniques/T1053/003/"
[threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[internal]
min_endpoint_version = "8.11.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 5s, correlated by process.entity_id.
Stage 1: process
[process where event.type == "start" and (process.name in ("bash", "sh", "zsh", "dash", "csh", "tcsh", "ksh", "tclsh", "fish") or process.name like "tclsh*") and process.args == "-c" and
not process.command_line : ("*/.claude/shell-snapshots/*", "*/.codex/shell_snapshots/*", "*/.cursor/shell-snapshots/*")]
Stage 2: file
[file where event.action != "deletion" and
file.path like "/private/var/at/tabs/*" and
process.executable == "/usr/bin/crontab" and not
file.path == "/private/var/at/tabs/root"]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | ne |
| field:"EventType" kind:ne value:"deletion" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard value:"/private/var/at/tabs/*" |
process.args | eq |
| field:"process.args" kind:eq value:"-c" |
process.executable | eq |
| field:"Image" kind:eq value:"/usr/bin/crontab" |
process.name | in |
| field:"process_basename" kind:in |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:"tclsh*" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.command_line | match | /.claude/shell-snapshots/, /.codex/shell_snapshots/, /.cursor/shell-snapshots/ | excludes:process.command_line field:"process.command_line" value:"/.claude/shell-snapshots/" field:"process.command_line" value:"/.codex/shell_snapshots/" field:"process.command_line" value:"/.cursor/shell-snapshots/" |
file.path | eq | /private/var/at/tabs/root | excludes:file.path field:"file.path" value:"/private/var/at/tabs/root" |
DNS-over-HTTPS Enabled via Registry
#Identifies when a user enables DNS-over-HTTPS. This can be used to hide internet activity or the process of exfiltrating data. With this enabled, an organization will lose visibility into data such as query type, response, and originating IP, which are used to determine bad actors.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Defense Impairment |
Rule Body
[metadata]
creation_date = "2021/07/22"
integration = ["endpoint", "windows", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/05/04"
[rule]
author = ["Austin Songer"]
description = """
Identifies when a user enables DNS-over-HTTPS. This can be used to hide internet activity or the process of exfiltrating
data. With this enabled, an organization will lose visibility into data such as query type, response, and originating
IP, which are used to determine bad actors.
"""
from = "now-9m"
index = [
"winlogbeat-*",
"logs-endpoint.events.registry-*",
"logs-windows.sysmon_operational-*",
"endgame-*",
"logs-m365_defender.event-*",
"logs-sentinel_one_cloud_funnel.*",
"logs-crowdstrike.fdr*",
]
language = "eql"
license = "Elastic License v2"
name = "DNS-over-HTTPS Enabled via Registry"
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating DNS-over-HTTPS Enabled via Registry
DNS-over-HTTPS (DoH) encrypts DNS queries to enhance privacy and security, preventing eavesdropping and manipulation. However, adversaries can exploit DoH to conceal malicious activities, such as data exfiltration, by bypassing traditional DNS monitoring. The detection rule identifies registry changes enabling DoH in browsers like Edge, Chrome, and Firefox, signaling potential misuse for defense evasion.
### Possible investigation steps
- Review the registry path and data values from the alert to determine which browser and setting were modified. Check if the change aligns with known user activity or policy.
- Investigate the user account associated with the registry change to assess if the activity is expected or if the account has a history of suspicious behavior.
- Examine recent network traffic from the host to identify any unusual or unauthorized DNS queries that could indicate data exfiltration or other malicious activities.
- Check for any other recent registry changes or system modifications on the host that might suggest further attempts at defense evasion or persistence.
- Correlate the alert with other security events or logs from the same host or user to identify patterns or additional indicators of compromise.
### False positive analysis
- Legitimate software updates or installations may enable DNS-over-HTTPS settings in browsers. Monitor software update schedules and correlate registry changes with known update events to identify benign changes.
- Organizational policies might require DNS-over-HTTPS for privacy compliance. Document these policies and create exceptions in the detection rule for systems where this is a known requirement.
- User-initiated privacy settings changes can trigger the rule. Educate users on the implications of enabling DNS-over-HTTPS and establish a process for them to report intentional changes, allowing for exclusion of these events.
- Security tools or privacy-focused applications may enable DNS-over-HTTPS as part of their functionality. Identify these tools within the organization and adjust the detection rule to exclude registry changes associated with their operation.
### Response and remediation
- Immediately isolate the affected system from the network to prevent potential data exfiltration or further malicious activity.
- Review and revert any unauthorized registry changes related to DNS-over-HTTPS settings in Edge, Chrome, and Firefox to restore standard DNS monitoring capabilities.
- Conduct a thorough scan of the affected system using updated antivirus and endpoint detection tools to identify and remove any malicious software or scripts.
- Analyze network traffic logs to identify any unusual or unauthorized DNS queries or data transfers that may have occurred during the period of DoH activation.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if additional systems are affected.
- Implement enhanced monitoring for registry changes related to DNS settings across the organization to detect similar threats in the future.
- Review and update security policies to ensure that DNS-over-HTTPS is only enabled through approved channels and for legitimate purposes, reducing the risk of misuse."""
references = [
"https://www.tenforums.com/tutorials/151318-how-enable-disable-dns-over-https-doh-microsoft-edge.html",
"https://chromeenterprise.google/policies/?policy=DnsOverHttpsMode",
]
risk_score = 21
rule_id = "a22a09c2-2162-4df0-a356-9aacbeb56a04"
severity = "low"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Defense Evasion",
"Data Source: Elastic Endgame",
"Data Source: Elastic Defend",
"Data Source: Sysmon",
"Data Source: Microsoft Defender XDR",
"Data Source: SentinelOne",
"Resources: Investigation Guide",
"Data Source: Crowdstrike",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
registry where host.os.type == "windows" and event.type == "change" and
(registry.path : "*\\SOFTWARE\\Policies\\Microsoft\\Edge\\BuiltInDnsClientEnabled" and
registry.data.strings : ("1", "0x00000001")) or
(registry.path : "*\\SOFTWARE\\Google\\Chrome\\DnsOverHttpsMode" and
registry.data.strings : "secure") or
(registry.path : "*\\SOFTWARE\\Policies\\Mozilla\\Firefox\\DNSOverHTTPS" and
registry.data.strings : ("1", "0x00000001"))
'''
setup = """## Setup
This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
Setup instructions: https://ela.st/install-elastic-defend
### Additional data sources
This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
- [CrowdStrike](https://ela.st/crowdstrike-integration)
- [Microsoft Defender XDR](https://ela.st/m365-defender)
- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
- [Sysmon Registry Events](https://ela.st/sysmon-event-reg-setup)
"""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1112"
name = "Modify Registry"
reference = "https://attack.mitre.org/techniques/T1112/"
[[rule.threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Stage 1: registry
registry where host.os.type == "windows" and event.type == "change" and
(registry.path : "*\\SOFTWARE\\Policies\\Microsoft\\Edge\\BuiltInDnsClientEnabled" and
registry.data.strings : ("1", "0x00000001")) or
(registry.path : "*\\SOFTWARE\\Google\\Chrome\\DnsOverHttpsMode" and
registry.data.strings : "secure") or
(registry.path : "*\\SOFTWARE\\Policies\\Mozilla\\Firefox\\DNSOverHTTPS" and
registry.data.strings : ("1", "0x00000001"))
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"change" |
registry.data.strings | wildcard |
| field:"Details" kind:wildcard |
registry.path | wildcard |
| field:"TargetObject" kind:wildcard |
Execution of File Written or Modified by Microsoft Office
#Identifies when a Microsoft Office process creates a portable executable (PE) file and the file is subsequently executed. An adversary may deliver a weaponized Office document to their target that writes and executes a malicious PE file.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
Rule Body
[rule]
description = """
Identifies when a Microsoft Office process creates a portable executable (PE) file and the file is subsequently
executed. An adversary may deliver a weaponized Office document to their target that writes and executes a malicious PE
file.
"""
id = "901f0c30-a7c5-40c5-80e3-a50c6744632f"
license = "Elastic License v2"
name = "Execution of File Written or Modified by Microsoft Office"
os_list = ["windows"]
version = "1.0.31"
query = '''
sequence with maxspan=2m
[ file where event.action != "deletion" and
process.name : ("WINWORD.EXE", "EXCEL.EXE", "POWERPNT.EXE", "MSACCESS.EXE") and
// Match Windows PE files by header data (MZ)
file.Ext.header_bytes : "4d5a*" and
not file.extension : ("exe", "com") ] by file.path
[ process where event.action == "start" ] by process.executable
'''
min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 1
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1566"
name = "Phishing"
reference = "https://attack.mitre.org/techniques/T1566/"
[[threat.technique.subtechnique]]
id = "T1566.001"
name = "Spearphishing Attachment"
reference = "https://attack.mitre.org/techniques/T1566/001/"
[[threat.technique.subtechnique]]
id = "T1566.002"
name = "Spearphishing Link"
reference = "https://attack.mitre.org/techniques/T1566/002/"
[threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 2m, correlated by file.path, process.executable.
Stage 1: file
[ file where event.action != "deletion" and
process.name : ("WINWORD.EXE", "EXCEL.EXE", "POWERPNT.EXE", "MSACCESS.EXE") and
file.Ext.header_bytes : "4d5a*" and
not file.extension : ("exe", "com") ] by file.path
Stage 2: process
[ process where event.action == "start" ] by process.executable
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
event.action | ne |
| field:"EventType" kind:ne value:"deletion" |
file.Ext.header_bytes | wildcard |
| field:"file.Ext.header_bytes" kind:wildcard value:"4d5a*" |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
file.extension | eq | exe, com | excludes:file.extension field:"file.extension" value:"exe" field:"file.extension" value:"com" |
Execution via Microsoft Excel XLL Add-In
#Identifies attempt to execute and load an unsigned Microsoft Excel XLL Addin. This may indicate an attempt to get initial access via a malicious phishing Microsoft Office Excel Add-In.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Persistence |
Rule Body
[rule]
description = """
Identifies attempt to execute and load an unsigned Microsoft Excel XLL Addin. This may indicate an attempt to get
initial access via a malicious phishing Microsoft Office Excel Add-In.
"""
id = "9efd977a-6d4a-4cc8-8ab3-355587b0ef69"
license = "Elastic License v2"
name = "Execution via Microsoft Excel XLL Add-In"
os_list = ["windows"]
reference = [
"https://github.com/Octoberfest7/XLL_Phishing",
"https://labs.f-secure.com/archive/add-in-opportunities-for-office-persistence/",
]
version = "1.0.25"
query = '''
sequence by process.entity_id with maxspan=2m
[process where event.action == "start" and
process.name : "EXCEL.EXE" and process.args : "-xlls"]
[library where
process.name : "EXCEL.EXE" and dll.name : "*.xll" and
not dll.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*")]
'''
min_endpoint_version = "8.4.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1566"
name = "Phishing"
reference = "https://attack.mitre.org/techniques/T1566/"
[[threat.technique.subtechnique]]
id = "T1566.001"
name = "Spearphishing Attachment"
reference = "https://attack.mitre.org/techniques/T1566/001/"
[threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1137"
name = "Office Application Startup"
reference = "https://attack.mitre.org/techniques/T1137/"
[[threat.technique.subtechnique]]
id = "T1137.006"
name = "Add-ins"
reference = "https://attack.mitre.org/techniques/T1137/006/"
[threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[internal]
min_endpoint_version = "8.4.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 2m, correlated by process.entity_id.
Stage 1: process
[process where event.action == "start" and
process.name : "EXCEL.EXE" and process.args : "-xlls"]
Stage 2: library
[library where
process.name : "EXCEL.EXE" and dll.name : "*.xll" and
not dll.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*")]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
dll.name | wildcard |
| field:"dll.name" kind:wildcard value:"*.xll" |
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.args | wildcard |
| field:"process.args" kind:wildcard value:"-xlls" |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:"EXCEL.EXE" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
dll.code_signature.status | wildcard | trusted, errorExpired, errorCode_endpoint* | excludes:dll.code_signature.status field:"dll.code_signature.status" value:"trusted" field:"dll.code_signature.status" value:"errorExpired" field:"dll.code_signature.status" value:"errorCode_endpoint*" |
General Privilege Escalation Sequence Detected
#This rule detects the execution of a binary, followed by a UID change event to 0 (root), and then the execution of a command that is used to check the current user's privileges. This sequence is often used by exploits to escalate privileges to root, and check if the escalation was successful.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Privilege Escalation |
Rule Body
[rule]
description = """
This rule detects the execution of a binary, followed by a UID change event to 0 (root), and then the execution of a
command that is used to check the current user's privileges. This sequence is often used by exploits to escalate
privileges to root, and check if the escalation was successful.
"""
id = "d8194360-9d84-43fb-bd8a-51db153d6632"
license = "Elastic License v2"
name = "General Privilege Escalation Sequence Detected"
os_list = ["linux"]
version = "1.0.6"
query = '''
sequence with maxspan=10s
[process where event.type == "start" and event.action == "exec" and user.id != 0 and
process.executable like ("/tmp/*", "/dev/shm/*", "/var/tmp/*", "/home/*", "/run/user/*", "/var/run/user/*") and
not process.parent.executable in ("/usr/bin/sw-engine", "/usr/sbin/sshd", "/usr/sbin/sw-engine-fpm", "/usr/lib/systemd/systemd")] by process.entity_id
[process where event.type == "change" and event.action == "uid_change" and user.id == 0] by process.entity_id
[process where event.type == "start" and event.action == "exec" and process.name in ("whoami", "id", "logname") and user.id == 0] by process.parent.entity_id
'''
min_endpoint_version = "7.15.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.entity_id"
state = 2
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 1
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 2
[[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 = "7.15.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 10s, correlated by process.entity_id, process.parent.entity_id.
Stage 1: process
[process where event.type == "start" and event.action == "exec" and user.id != 0 and
process.executable like ("/tmp/*", "/dev/shm/*", "/var/tmp/*", "/home/*", "/run/user/*", "/var/run/user/*") and
not process.parent.executable in ("/usr/bin/sw-engine", "/usr/sbin/sshd", "/usr/sbin/sw-engine-fpm", "/usr/lib/systemd/systemd")] by process.entity_id
Stage 2: process
[process where event.type == "change" and event.action == "uid_change" and user.id == 0] by process.entity_id
Stage 3: process
[process where event.type == "start" and event.action == "exec" and process.name in ("whoami", "id", "logname") and user.id == 0] 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 |
event.type | eq |
| field:"event.type" kind:eq |
process.executable | wildcard |
| field:"Image" kind:wildcard |
process.name | in |
| field:"process_basename" kind:in |
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.executable | in | /usr/bin/sw-engine, /usr/lib/systemd/systemd, /usr/sbin/sshd, /usr/sbin/sw-engine-fpm | excludes:process.parent.executable |
GKE Anonymous Endpoint Permission Enumeration
#Detects bursts of GKE API requests from an anonymous identity that probe many distinct actions and resources with mostly failed outcomes. This pattern is consistent with unauthenticated permission enumeration against an exposed API server. On GKE GCP audit logs, unauthenticated probes often omit "client.user.email" (null principal) with Unauthorized failures; those events are included alongside "system:anonymous" / "system:unauthenticated".
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Reconnaissance | |
| Discovery |
Rule Body
[metadata]
creation_date = "2026/07/16"
integration = ["gcp"]
maturity = "production"
updated_date = "2026/07/16"
[rule]
author = ["Elastic"]
description = """
Detects bursts of GKE API requests from an anonymous identity that probe many distinct actions and resources with
mostly failed outcomes. This pattern is consistent with unauthenticated permission enumeration against an exposed API
server. On GKE GCP audit logs, unauthenticated probes often omit "client.user.email" (null principal) with
Unauthorized failures; those events are included alongside "system:anonymous" / "system:unauthenticated".
"""
from = "now-6m"
interval = "5m"
language = "esql"
license = "Elastic License v2"
name = "GKE Anonymous Endpoint Permission Enumeration"
note = """## Triage and analysis
### Investigating GKE Anonymous Endpoint Permission Enumeration
Anonymous multi-endpoint failure bursts map which APIs are reachable before credential theft or exploitation.
Treat missing `client.user.email` with Unauthorized/failure bursts as anonymous on GKE.
### Investigation steps
- Review `Esql.event_action_values` and `Esql.resource_name_values` for targeted APIs (secrets, RBAC, CRDs).
- Confirm whether `source.ip` is Internet-routable and whether the API endpoint is publicly exposed.
- Hunt for later successful anonymous or authenticated activity from the same source or user agent.
### False positives
- Misconfigured auth proxies that strip credentials can make legitimate clients appear anonymous during outages.
"""
references = [
"https://heilancoos.github.io/research/2025/12/16/kubernetes.html#unauthenticated-api-access",
"https://cloud.google.com/kubernetes-engine/docs/how-to/audit-logging",
]
risk_score = 47
rule_id = "bd7345e5-c822-41de-a393-7573fec07ef4"
severity = "medium"
tags = [
"Domain: Cloud",
"Domain: Kubernetes",
"Data Source: GCP",
"Data Source: Google Cloud Platform",
"Use Case: Threat Detection",
"Tactic: Discovery",
"Tactic: Reconnaissance",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
setup = "The GCP Fleet integration with GKE audit logs enabled is required to be compatible with this rule."
query = '''
from logs-gcp.audit-* metadata _id, _index, _version
| where data_stream.dataset == "gcp.audit"
and service.name == "k8s.io"
and (
client.user.email in ("system:anonymous", "system:unauthenticated")
or client.user.email is null
)
and not gcp.audit.resource_name in ("readyz", "livez", "healthz", "version")
| stats
Esql.document_count = count(),
Esql.failure_count = sum(case(event.outcome == "failure", 1, 0)),
Esql.event_action_count_distinct = count_distinct(event.action),
Esql.resource_name_count_distinct = count_distinct(gcp.audit.resource_name),
Esql.event_action_values = values(event.action),
Esql.resource_name_values = values(gcp.audit.resource_name),
Esql.event_outcome_values = values(event.outcome),
Esql.client_user_email_values = values(client.user.email),
Esql.timestamp = VALUES(@timestamp),
Esql.data_stream_namespace = VALUES(data_stream.namespace),
Esql.user_agent_original_values = VALUES(user_agent.original)
by source.ip
| where Esql.event_action_count_distinct > 5
and Esql.resource_name_count_distinct > 3
and Esql.document_count < 50
and Esql.failure_count >= 1
| keep Esql.*, source.ip
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1613"
name = "Container and Resource Discovery"
reference = "https://attack.mitre.org/techniques/T1613/"
[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1595"
name = "Active Scanning"
reference = "https://attack.mitre.org/techniques/T1595/"
[[rule.threat.technique.subtechnique]]
id = "T1595.003"
name = "Wordlist Scanning"
reference = "https://attack.mitre.org/techniques/T1595/003/"
[rule.threat.tactic]
id = "TA0043"
name = "Reconnaissance"
reference = "https://attack.mitre.org/tactics/TA0043/"
Stages and Predicates
Stage 1: from
from logs-gcp.audit-* metadata _id, _index, _version
Stage 2: where
| where data_stream.dataset == "gcp.audit"
and service.name == "k8s.io"
and (
client.user.email in ("system:anonymous", "system:unauthenticated")
or client.user.email is null
)
and not gcp.audit.resource_name in ("readyz", "livez", "healthz", "version")
Stage 3: stats
| stats
Esql.document_count = count(),
Esql.failure_count = sum(case(event.outcome == "failure", 1, 0)),
Esql.event_action_count_distinct = count_distinct(event.action),
Esql.resource_name_count_distinct = count_distinct(gcp.audit.resource_name),
Esql.event_action_values = values(event.action),
Esql.resource_name_values = values(gcp.audit.resource_name),
Esql.event_outcome_values = values(event.outcome),
Esql.client_user_email_values = values(client.user.email),
Esql.timestamp = VALUES(@timestamp),
Esql.data_stream_namespace = VALUES(data_stream.namespace),
Esql.user_agent_original_values = VALUES(user_agent.original)
by source.ip
Stage 4: where
| where Esql.event_action_count_distinct > 5
and Esql.resource_name_count_distinct > 3
and Esql.document_count < 50
and Esql.failure_count >= 1
Stage 5: keep
| keep Esql.*, source.ip
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
gcp.audit.resource_name | in | healthz, livez, readyz, version | excludes:gcp.audit.resource_name |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Esql.* | KEEP Esql.* |
source.ip | KEEP source.ip |
Network Activity from Memory File Descriptor
#Detects when a file descriptor in the proc (temporary) file system is executed and immediately makes an outbound network connection. This activity can occur when the memfd syscall is utilized to create a memory resident file, like a payload, and then execute it after which is establishes outbound network connections (C2).
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Stealth |
Rule Body
[rule]
description = """
Detects when a file descriptor in the proc (temporary) file system is executed and immediately makes an outbound network
connection. This activity can occur when the memfd syscall is utilized to create a memory resident file, like a payload,
and then execute it after which is establishes outbound network connections (C2).
"""
id = "4c8b9c6f-4d85-4fa9-9104-16f7a99aded6"
license = "Elastic License v2"
name = "Network Activity from Memory File Descriptor"
os_list = ["linux"]
reference = [
"https://github.com/MythicAgents/merlin/blob/main/Payload_Type/merlin/container/commands/memfd.go",
"https://x-c3ll.github.io/posts/fileless-memfd_create/",
]
version = "1.0.18"
query = '''
sequence by process.entity_id with maxspan=10s
[process where event.type == "start" and event.action == "exec" and
process.executable regex """/proc/(self|[0-9]{1,7})/fd/[0-9]{1,7}""" and
not (
process.args like ("/usr/lib/systemd/systemd-executor", "/nix/store/*/systemd-executor*") or
process.parent.executable like (
"/usr/sbin/runc", "/usr/bin/dockerd", "/lib/systemd/systemd", "/usr/lib/systemd/systemd", "/nix/store/*/systemd",
"/opt/sentinelone/bin/addon-host", "/opt/gitlab/embedded/bin/gitlab-kas", "/usr/sbin/nordlayerd", "/sbin/init",
"/proc/self/fd/*/*"
) or
process.command_line == "runc init"
)]
[network where event.type == "start" and event.action == "connection_attempted" and
not (
cidrmatch(destination.ip, "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24",
"192.0.0.0/29", "192.0.0.8/32", "192.0.0.9/32", "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32",
"192.0.2.0/24", "192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", "224.0.0.0/4",
"100.64.0.0/10", "192.175.48.0/24","198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1",
"FE80::/10", "FF00::/8"
) or
process.name == "check-new-release-gtk"
)]
'''
min_endpoint_version = "8.3.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
tree = true
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1106"
name = "Native API"
reference = "https://attack.mitre.org/techniques/T1106/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1620"
name = "Reflective Code Loading"
reference = "https://attack.mitre.org/techniques/T1620/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "8.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 regex """/proc/(self|[0-9]{1,7})/fd/[0-9]{1,7}""" and
not (
process.args like ("/usr/lib/systemd/systemd-executor", "/nix/store/*/systemd-executor*") or
process.parent.executable like (
"/usr/sbin/runc", "/usr/bin/dockerd", "/lib/systemd/systemd", "/usr/lib/systemd/systemd", "/nix/store/*/systemd",
"/opt/sentinelone/bin/addon-host", "/opt/gitlab/embedded/bin/gitlab-kas", "/usr/sbin/nordlayerd", "/sbin/init",
"/proc/self/fd/*/*"
) or
process.command_line == "runc init"
)]
Stage 2: network
[network where event.type == "start" and event.action == "connection_attempted" and
not (
cidrmatch(destination.ip, "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24",
"192.0.0.0/29", "192.0.0.8/32", "192.0.0.9/32", "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32",
"192.0.2.0/24", "192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", "224.0.0.0/4",
"100.64.0.0/10", "192.175.48.0/24","198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1",
"FE80::/10", "FF00::/8"
) or
process.name == "check-new-release-gtk"
)]
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.executable | regex_match |
| field:"Image" kind:regex_match value:"/proc/(self|[0-9]{1,7})/fd/[0-9]{1,7}" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | wildcard | /usr/lib/systemd/systemd-executor, /nix/store/*/systemd-executor* | excludes:process.args field:"process.args" value:"/usr/lib/systemd/systemd-executor" field:"process.args" value:"/nix/store/*/systemd-executor*" |
process.command_line | eq | runc init | excludes:process.command_line field:"process.command_line" value:"runc init" |
process.parent.executable | wildcard | /usr/sbin/runc, /usr/bin/dockerd, /lib/systemd/systemd, /usr/lib/systemd/systemd, /nix/store/*/systemd, /opt/sentinelone/bin/addon-host, /opt/gitlab/embedded/bin/gitlab-kas, /usr/sbin/nordlayerd, /sbin/init, /proc/self/fd/*/* | excludes:process.parent.executable |
destination.ip | cidr_match | 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 |
process.name | eq | check-new-release-gtk | excludes:process.name field:"process.name" value:"check-new-release-gtk" |
PKINIT Followed by Same-Principal U2U Service Ticket
#Identifies a successful PKINIT ticket-granting ticket request followed within five seconds on the same domain controller and source address by a successful user-to-user service-ticket request whose service SID matches the PKINIT principal SID. This sequence is consistent with the KDC-visible ticket requests used in an UnPAC-the-Hash attack, before client-side PAC credential decryption and NT hash recovery. The certificate used for PKINIT may have been obtained through CertiGhost or another certificate-abuse path.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2026/08/13"
integration = ["system", "windows"]
maturity = "production"
updated_date = "2026/08/13"
[rule]
author = ["Elastic"]
description = """
Identifies a successful PKINIT ticket-granting ticket request followed within five seconds on the same domain controller
and source address by a successful user-to-user service-ticket request whose service SID matches the PKINIT principal
SID. This sequence is consistent with the KDC-visible ticket requests used in an UnPAC-the-Hash attack, before
client-side PAC credential decryption and NT hash recovery. The certificate used for PKINIT may have been obtained
through CertiGhost or another certificate-abuse path.
"""
from = "now-9m"
index = ["logs-system.security*", "logs-windows.forwarded*", "winlogbeat-*"]
language = "eql"
license = "Elastic License v2"
name = "PKINIT Followed by Same-Principal U2U Service Ticket"
references = [
"https://specterops.io/blog/2026/06/09/user-to-user-authentication-down-the-rabbit-hole-part-1/",
"https://dirkjanm.io/ntlm-relaying-to-ad-certificate-services/#obtaining-the-nt-hash-of-the-impersonated-computer-account",
"https://github.com/FalconForceTeam/FalconFriday/blob/c662a6a0dc5d973beb3abb673d4e8cdc193bf469/0xFF-0299-UnPAC_the_hash-Win.md",
"https://gist.github.com/H0j3n/a5ef2609b5f2944ac2390a191a534c26",
"https://github.com/dirkjanm/PKINITtools/blob/0f0cfa542b0348609ad494713e84744234b2d3b0/getnthash.py",
]
risk_score = 47
rule_id = "04443c0e-9f23-4b61-996b-d8d6b0263bd2"
setup = """## Setup
Audit Kerberos Authentication Service and Audit Kerberos Service Ticket Operations must be enabled to generate the
events used by this rule.
Setup instructions:
- [Audit Kerberos Authentication Service](https://ela.st/audit-kerberos-authentication-service)
- [Audit Kerberos Service Ticket Operations](https://ela.st/audit-kerberos-service-ticket-operations)
"""
severity = "medium"
tags = [
"Domain: Identity",
"Platform: Windows",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Credential Access",
"Rule Type: Event Correlation (EQL)",
"Use Case: Active Directory Monitoring",
"Data Source: Active Directory",
"Data Source: Windows Security Event Logs",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
sequence by winlog.computer_name, source.ip with maxspan=5s
[authentication where host.os.type == "windows" and
event.code == "4768" and winlog.event_data.PreAuthType == "16" and
winlog.event_data.Status == "0x0"
] by winlog.event_data.TargetSid
[authentication where host.os.type == "windows" and
event.code == "4769" and winlog.event_data.Status == "0x0" and
winlog.event_data.TicketOptions in ("0x40810008", "0x40810018")
] by winlog.event_data.ServiceSid
'''
note = """## Triage and analysis
### Investigating PKINIT Followed by Same-Principal U2U Service Ticket
The query uses `winlog.event_data.PreAuthType` value `16` for `PA-PK-AS-REQ`, the PKINIT pre-authentication request
type. Both accepted `winlog.event_data.TicketOptions` masks include `FORWARDABLE`, `RENEWABLE`, `CANONICALIZE`, and
`ENC-TKT-IN-SKEY`; `ENC-TKT-IN-SKEY` is the option that identifies a user-to-user service-ticket request.
`0x40810018` also includes `RENEWABLE-OK`, while `0x40810008` does not.
Controlled request profiles produced both masks, so `RENEWABLE-OK` is not required. Neither mask is suspicious by
itself; the signal is the five-second same-domain-controller and source sequence with the 4768 `TargetSid` matching
the 4769 `ServiceSid`.
#### Possible investigation steps
- Did the 4769 requester match the PKINIT principal?
- Focus: `event.code`, `winlog.event_data.TargetUserName`, `winlog.event_data.TargetDomainName`, `winlog.event_data.TargetSid`, `winlog.event_data.ServiceSid`.
- Hint: Use Investigate in Timeline to review the matched 4768 and 4769 source events. Compare their `winlog.event_data.TargetUserName` values case-insensitively after removing any `@REALM` suffix, and compare `winlog.event_data.TargetDomainName`. Event 4769 exposes the requester name and domain, but not its SID; resolve ambiguous names through the directory before disposition.
- Implication: A resolved requester matching the 4768 principal supports the same-principal interpretation. Confirmed authorized UnPAC-the-Hash or PKINIT/U2U testing is a benign true positive. Keep a raw-name mismatch unresolved; if identity resolution and client or application evidence establish a different requester and unrelated events, close the alert as a false correlation.
- Does the rule-shaped pattern recur for the same domain controller and source address?
- Focus: `winlog.computer_name`, `source.ip`, `@timestamp`, `winlog.event_data.TargetSid`, `winlog.event_data.ServiceSid`.
- Hint: Reconstruct each sequence manually by checking order, the five-second interval, and the stage-local SID values. The following Timeline investigation returns 24 hours of matching PKINIT and U2U candidates for the shared domain controller and source address, not principal-specific history. $investigate_0
- Implication: Repeated valid pairs or different principals from the same source increase confidence in credential-recovery tooling. Recurrence does not prove client-side PAC decryption or NT hash recovery.
- What related activity corroborates or expands the scope?
- Focus: `winlog.computer_name`, `source.ip`, `winlog.event_data.TargetUserName`, `winlog.event_data.TargetSid`, `winlog.event_data.ServiceSid`.
- Hint: After reviewing the matched source events, search available identity, endpoint, certificate, and alert telemetry for the source address, principal, and domain controller. Look for upstream certificate abuse, client tooling, repeated PKINIT/U2U activity, or follow-on authentication. Missing telemetry is unresolved, not benign.
- Implication: Upstream certificate abuse, relevant client execution, or follow-on credential use supports escalation and broader scoping. Their absence does not clear the matched sequence.
Escalate unexplained or corroborated sequences with the matched source events and source/principal scope. Close as a benign true positive only for confirmed authorized UnPAC-the-Hash or PKINIT/U2U testing, or as a false positive when identity resolution and client or application evidence prove an unrelated cross-principal correlation. Preserve available evidence and escalate mixed or incomplete cases.
### False positive analysis
No known false positives have been identified. Validate the 4769 requester against the matched 4768 principal because event 4769 does not expose the requester SID.
Avoid exceptions based only on a domain controller or source address. EQL exceptions evaluate each sequence member independently and cannot express the cross-stage SID relationship.
### Response and remediation
- Preserve the alert, matched 4768/4769 source events, timestamps, identities, domain controller, and source address before disruptive action.
- If the client endpoint is identified, collect relevant volatile process or memory evidence before isolation or process termination.
- For confirmed malicious activity, contain the identified client and affected account with reversible controls where possible. Revoke a certificate only when evidence binds it to the activity, and rotate affected credentials when recovery or subsequent use is confirmed or the exposure assessment warrants it.
- Document confirmed indicators, matched source-event values, and any logging gaps for the responsible detection or logging owners after scoping and containment.
"""
[rule.investigation_fields]
field_names = [
"winlog.computer_name",
"source.ip",
]
[[transform.investigate]]
label = "Kerberos history for the same DC and source"
providers = [
[
{ excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" },
{ excluded = false, field = "source.ip", queryType = "phrase", value = "{{source.ip}}", valueType = "string" },
{ excluded = false, field = "event.code", queryType = "phrase", value = "4768", valueType = "string" },
{ excluded = false, field = "winlog.event_data.PreAuthType", queryType = "phrase", value = "16", valueType = "string" },
{ excluded = false, field = "winlog.event_data.Status", queryType = "phrase", value = "0x0", valueType = "string" },
],
[
{ excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" },
{ excluded = false, field = "source.ip", queryType = "phrase", value = "{{source.ip}}", valueType = "string" },
{ excluded = false, field = "event.code", queryType = "phrase", value = "4769", valueType = "string" },
{ excluded = false, field = "winlog.event_data.Status", queryType = "phrase", value = "0x0", valueType = "string" },
{ excluded = false, field = "winlog.event_data.TicketOptions", queryType = "phrase", value = "0x40810008", valueType = "string" },
],
[
{ excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" },
{ excluded = false, field = "source.ip", queryType = "phrase", value = "{{source.ip}}", valueType = "string" },
{ excluded = false, field = "event.code", queryType = "phrase", value = "4769", valueType = "string" },
{ excluded = false, field = "winlog.event_data.Status", queryType = "phrase", value = "0x0", valueType = "string" },
{ excluded = false, field = "winlog.event_data.TicketOptions", queryType = "phrase", value = "0x40810018", valueType = "string" },
],
]
relativeFrom = "now-24h/h"
relativeTo = "now"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1558"
name = "Steal or Forge Kerberos Tickets"
reference = "https://attack.mitre.org/techniques/T1558/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
Stages and Predicates
Ordered sequence: each step below must occur in order within 5s, correlated by source.ip, winlog.computer_name, winlog.event_data.ServiceSid, winlog.event_data.TargetSid.
Stage 1: authentication
[authentication where host.os.type == "windows" and
event.code == "4768" and winlog.event_data.PreAuthType == "16" and
winlog.event_data.Status == "0x0"
] by winlog.event_data.TargetSid
Stage 2: authentication
[authentication where host.os.type == "windows" and
event.code == "4769" and winlog.event_data.Status == "0x0" and
winlog.event_data.TicketOptions in ("0x40810008", "0x40810018")
] by winlog.event_data.ServiceSid
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.code | eq |
| field:"EventID" kind:eq |
winlog.event_data.PreAuthType | eq |
| field:"PreAuthType" kind:eq value:"16" |
winlog.event_data.Status | eq |
| field:"Status" kind:eq value:"0x0" |
winlog.event_data.TicketOptions | in |
| field:"TicketOptions" kind:in |
Potential Evasion via Oversized Image Load
#Adversaries may use binary padding to add junk data and change the on-disk representation of malware. This can be done without affecting the functionality or behavior of a binary, but can increase the size of the binary beyond what some security tools are capable of handling due to file size limitations
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule Body
[rule]
description = """
Adversaries may use binary padding to add junk data and change the on-disk representation of malware. This can be done
without affecting the functionality or behavior of a binary, but can increase the size of the binary beyond what some
security tools are capable of handling due to file size limitations
"""
id = "65a402ff-904b-4d14-b7aa-fa0c5ae575f8"
license = "Elastic License v2"
name = "Potential Evasion via Oversized Image Load"
os_list = ["windows"]
reference = [
"https://attack.mitre.org/techniques/T1027/001/",
"https://www.elastic.co/security-labs/Hunting-for-Suspicious-Windows-Libraries-for-Execution-and-Evasion",
]
version = "1.0.27"
query = '''
sequence with maxspan=1m
[file where event.action != "deletion" and
/* over 100MB in size */
file.size >= 100000000 and file.Ext.header_bytes : "4d5a*" and not file.extension : "exe" and
not user.id : "S-1-5-18" and
not (process.code_signature.subject_name in ("Trend Micro, Inc.", "Azul Systems, Inc.", "Wargaming Group Limited",
"Avigilon Corporation", "Duck Duck Go, Inc.", "Wargaming Group Limited", "Griff Gate Pte. Ltd.", "Corsair Memory, Inc.",
"Anaconda, Inc.") and
process.code_signature.status == "trusted") and
not process.executable : ("C:\\ProgramData\\slicer.org\\Slicer *\\bin\\python-real.exe", "C:\\Program Files\\burpsuite_enterprise\\jres\\*\\bin\\java.exe") and
not file.path : "C:\\ProgramData\\*\\PyQt5\\Qt5\\bin\\Qt5WebEngineCore.dll"
] by file.path
[library where
(
process.name : ("rundll32.exe", "regsvr32.exe", "svchost.exe") or
process.executable :
("?:\\Users\\Public\\*",
"?:\\ProgramData\\*",
"?:\\Windows\\Temp\\*",
"?:\\Users\\*\\AppData\\Local\\Temp\\Temp?_*",
"?:\\Users\\*\\AppData\\Local\\Temp\\7z*",
"?:\\Users\\*\\AppData\\Local\\Temp\\Rar*",
"?:\\Users\\*\\AppData\\Local\\Temp\\BNZ.*")
)
and not dll.code_signature.trusted == true and
not dll.code_signature.status : "errorExpired" and
not user.id : "S-1-5-18" and
not (process.name : "regsvr32.exe" and dll.path : "C:\\Oracle\\*.dll") and
not (dll.name : "Qt5WebEngineCore.dll" and process.code_signature.subject_name == "Pitney Bowes Inc.")] by dll.path
'''
min_endpoint_version = "8.4.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1027"
name = "Obfuscated Files or Information"
reference = "https://attack.mitre.org/techniques/T1027/"
[[threat.technique.subtechnique]]
id = "T1027.001"
name = "Binary Padding"
reference = "https://attack.mitre.org/techniques/T1027/001/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "8.4.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 1m, correlated by dll.path, file.path.
Stage 1: file
[file where event.action != "deletion" and
file.size >= 100000000 and file.Ext.header_bytes : "4d5a*" and not file.extension : "exe" and
not user.id : "S-1-5-18" and
not (process.code_signature.subject_name in ("Trend Micro, Inc.", "Azul Systems, Inc.", "Wargaming Group Limited",
"Avigilon Corporation", "Duck Duck Go, Inc.", "Wargaming Group Limited", "Griff Gate Pte. Ltd.", "Corsair Memory, Inc.",
"Anaconda, Inc.") and
process.code_signature.status == "trusted") and
not process.executable : ("C:\\ProgramData\\slicer.org\\Slicer *\\bin\\python-real.exe", "C:\\Program Files\\burpsuite_enterprise\\jres\\*\\bin\\java.exe") and
not file.path : "C:\\ProgramData\\*\\PyQt5\\Qt5\\bin\\Qt5WebEngineCore.dll"
] by file.path
Stage 2: library
[library where
(
process.name : ("rundll32.exe", "regsvr32.exe", "svchost.exe") or
process.executable :
("?:\\Users\\Public\\*",
"?:\\ProgramData\\*",
"?:\\Windows\\Temp\\*",
"?:\\Users\\*\\AppData\\Local\\Temp\\Temp?_*",
"?:\\Users\\*\\AppData\\Local\\Temp\\7z*",
"?:\\Users\\*\\AppData\\Local\\Temp\\Rar*",
"?:\\Users\\*\\AppData\\Local\\Temp\\BNZ.*")
)
and not dll.code_signature.trusted == true and
not dll.code_signature.status : "errorExpired" and
not user.id : "S-1-5-18" and
not (process.name : "regsvr32.exe" and dll.path : "C:\\Oracle\\*.dll") and
not (dll.name : "Qt5WebEngineCore.dll" and process.code_signature.subject_name == "Pitney Bowes Inc.")] by dll.path
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | ne |
| field:"EventType" kind:ne value:"deletion" |
file.Ext.header_bytes | wildcard |
| field:"file.Ext.header_bytes" kind:wildcard value:"4d5a*" |
file.size | ge |
| field:"file.size" kind:ge value:"100000000" |
process.executable | wildcard |
| field:"Image" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
Potential Injection via PyInstaller Executable
#Identifies attempt to perform code injection using shellcode and from an unsigned PyInstaller executable.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule Body
[rule]
description = "Identifies attempt to perform code injection using shellcode and from an unsigned PyInstaller executable."
id = "deb48ee3-8ce0-4ff7-a30b-041c5db024bb"
license = "Elastic License v2"
name = "Potential Injection via PyInstaller Executable"
os_list = ["windows"]
version = "1.0.5"
query = '''
api where not process.code_signature.status : "trusted" and
(
(process.Ext.api.behaviors : ("shellcode", "allocate_shellcode", "execute_shellcode") and
process.thread.Ext.call_stack_summary :
("ntdll.dll|kernelbase.dll|Unbacked",
"ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|Unbacked",
"ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|Unbacked|kernel32.dll|ntdll.dll",
"ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|Unbacked|libffi-?.dll|_ctypes.pyd|*") and
process.thread.Ext.call_stack_final_user_module.protection_provenance : "libffi*.dll" and
process.thread.Ext.call_stack_final_user_module.name : "Unbacked" and
_arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info : "Unbacked*" and $entry.callsite_trailing_bytes : "?*")) or
(process.Ext.api.name : ("VirtualAlloc*", "MapViewOfFile*") and process.Ext.api.parameters.protection : "RWX" and
process.thread.Ext.call_stack_final_user_module.name : "libffi*.dll" and
process.thread.Ext.call_stack_summary : ("ntdll.dll|kernelbase.dll|libffi-?.dll|_ctypes.pyd|*",
"ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|libffi-?.dll|_ctypes.pyd|*"))
) and
not process.Ext.api.summary == "VirtualAlloc( NULL, 0x1c, COMMIT|RESERVE, RWX )"
'''
min_endpoint_version = "8.10.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "8.10.0"
Stages and Predicates
Stage 1: api
api where not process.code_signature.status : "trusted" and
(
(process.Ext.api.behaviors : ("shellcode", "allocate_shellcode", "execute_shellcode") and
process.thread.Ext.call_stack_summary :
("ntdll.dll|kernelbase.dll|Unbacked",
"ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|Unbacked",
"ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|Unbacked|kernel32.dll|ntdll.dll",
"ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|Unbacked|libffi-?.dll|_ctypes.pyd|*") and
process.thread.Ext.call_stack_final_user_module.protection_provenance : "libffi*.dll" and
process.thread.Ext.call_stack_final_user_module.name : "Unbacked" and
_arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info : "Unbacked*" and $entry.callsite_trailing_bytes : "?*")) or
(process.Ext.api.name : ("VirtualAlloc*", "MapViewOfFile*") and process.Ext.api.parameters.protection : "RWX" and
process.thread.Ext.call_stack_final_user_module.name : "libffi*.dll" and
process.thread.Ext.call_stack_summary : ("ntdll.dll|kernelbase.dll|libffi-?.dll|_ctypes.pyd|*",
"ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|libffi-?.dll|_ctypes.pyd|*"))
) and
not process.Ext.api.summary == "VirtualAlloc( NULL, 0x1c, COMMIT|RESERVE, RWX )"
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.Ext.api.summary | eq | VirtualAlloc( NULL, 0x1c, COMMIT|RESERVE, RWX ) | excludes:process.Ext.api.summary field:"process.Ext.api.summary" value:"VirtualAlloc( NULL, 0x1c, COMMIT|RESERVE, RWX )" |
process.code_signature.status | eq | trusted | excludes:process.code_signature.status field:"process.code_signature.status" value:"trusted" |
Potential Malware-Driven SSH Brute Force Attempt
#This detection identifies a Linux host that has potentially been infected with malware and is being used to conduct brute-force attacks against external systems over SSH (port 22 and common alternative SSH ports). The detection looks for a high volume of outbound connection attempts to non-private IP addresses from a single process. A compromised host may be part of a botnet or controlled by an attacker, attempting to gain unauthorized access to remote systems. This behavior is commonly observed in SSH brute-force campaigns where malware hijacks vulnerable machines to expand its attack surface. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Credential Access | |
| Command & Control | |
| Impact |
Rule Body
[metadata]
creation_date = "2025/02/20"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
This detection identifies a Linux host that has potentially been infected with malware and is being used to conduct
brute-force attacks against external systems over SSH (port 22 and common alternative SSH ports). The detection looks
for a high volume of outbound connection attempts to non-private IP addresses from a single process. A compromised host
may be part of a botnet or controlled by an attacker, attempting to gain unauthorized access to remote systems. This
behavior is commonly observed in SSH brute-force campaigns where malware hijacks vulnerable machines to expand its
attack surface. ESQL rules have limited fields available in its alert documents. Make sure to review the original
documents to aid in the investigation of this alert.
"""
from = "now-61m"
interval = "1h"
language = "esql"
license = "Elastic License v2"
name = "Potential Malware-Driven SSH Brute Force Attempt"
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 Malware-Driven SSH Brute Force Attempt
SSH is a protocol used to securely access remote systems. Adversaries exploit it by deploying malware on compromised Linux hosts to perform brute-force attacks, attempting unauthorized access to other systems. The detection rule identifies such abuse by monitoring high volumes of outbound SSH connection attempts from a single process to external IPs, indicating potential malware activity.
### Possible investigation steps
- Review the process executable identified in the alert to determine if it is a legitimate application or potentially malicious. Check for known malware signatures or unusual file paths.
- Analyze the destination IP addresses involved in the connection attempts to identify if they are known malicious hosts or part of a larger attack infrastructure. Use threat intelligence sources to gather more information.
- Examine the host's recent activity logs to identify any unusual behavior or signs of compromise, such as unexpected process executions or changes in system configurations.
- Investigate the specific agent.id associated with the alert to determine if other alerts or suspicious activities have been reported from the same host, indicating a broader compromise.
- Check for any recent changes or updates to the host's software or configurations that could have introduced vulnerabilities exploited by the malware.
- Assess the network traffic patterns from the host to identify any other unusual outbound connections that may indicate additional malicious activity or data exfiltration attempts.
### False positive analysis
- High-volume legitimate SSH operations from a single process can trigger alerts. Exclude known safe processes or scripts that perform frequent SSH operations by adding them to an exception list.
- Automated backup or synchronization tools using SSH to connect to external servers may be misidentified. Identify these tools and exclude their process names or IP addresses from the detection rule.
- Development or testing environments where SSH connections are frequently initiated to external systems for legitimate purposes can cause false positives. Document these environments and adjust the rule to exclude their specific IP ranges or process identifiers.
- Security scanning tools that perform SSH checks on external systems might be flagged. Ensure these tools are recognized and their activities are excluded by specifying their process names or IP addresses in the rule exceptions.
### Response and remediation
- Isolate the affected Linux host from the network immediately to prevent further unauthorized access attempts and potential spread of malware to other systems.
- Terminate the suspicious process identified by the detection rule to stop ongoing brute-force attempts and reduce the risk of further compromise.
- Conduct a thorough malware scan on the isolated host using updated antivirus or endpoint detection and response (EDR) tools to identify and remove any malicious software.
- Review and reset credentials for any accounts that may have been targeted or compromised during the brute-force attempts to ensure account security.
- Apply security patches and updates to the affected host and any other vulnerable systems to mitigate known vulnerabilities that could be exploited by similar threats.
- Monitor network traffic for any signs of continued or new suspicious activity, particularly focusing on outbound SSH connections, to detect and respond to any further attempts promptly.
- Escalate the incident to the security operations center (SOC) or relevant security team for further investigation and to assess the potential impact on the broader network infrastructure.
"""
risk_score = 47
rule_id = "77122db4-5876-4127-b91b-6c179eb21f88"
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: Impact",
"Tactic: Execution",
"Tactic: Command and Control",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-endpoint.events.network-* metadata _id, _index, _version
| mv_expand event.action
| where
host.os.type == "linux" and
event.type == "start" and
event.action == "connection_attempted" and
destination.port in (22, 222, 2222, 10022, 2022, 2200, 62612, 8022) and
not (
cidr_match(
destination.ip,
"10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12",
"192.0.0.0/24", "192.0.0.0/29", "192.0.0.8/32", "192.0.0.9/32",
"192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24",
"192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24",
"224.0.0.0/4", "100.64.0.0/10", "192.175.48.0/24", "198.18.0.0/15",
"198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1", "FE80::/10", "FF00::/8"
) or
process.executable in (
"/usr/bin/rclone", "/usr/bin/sss_ssh_knownhostsproxy", "/usr/sbin/sshd", "/usr/bin/ssh",
"/usr/local/bin/php", "/usr/sbin/apache2", "/usr/sbin/nginx", "/usr/local/bin/argocd-repo-server",
"/opt/nessus/sbin/nessusd", "/usr/local/bin/source-controller"
) or
process.executable like "/usr/local/efax/*"
)
| keep
@timestamp,
_id,
_index,
_version,
host.os.type,
event.type,
event.action,
destination.port,
destination.ip,
process.executable,
agent.id,
host.name,
data_stream.dataset,
data_stream.namespace
| stats
Esql.event_count = count(),
Esql.agent_id_count_distinct = count_distinct(agent.id),
Esql.host_name_values = values(host.name),
Esql.agent_id_values = values(agent.id),
Esql.data_stream_dataset_values = values(data_stream.dataset),
Esql.data_stream_namespace_values = values(data_stream.namespace)
by process.executable, destination.port
| where
Esql.agent_id_count_distinct == 1 and
Esql.event_count >= 100
// Extract unique values to ECS fields for alerts exclusion
| eval agent.id = mv_min(Esql.agent_id_values),
host.name = mv_min(Esql.host_name_values)
| sort Esql.event_count asc
| keep Esql.*, agent.id, host.name, process.executable, destination.port
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1496"
name = "Resource Hijacking"
reference = "https://attack.mitre.org/techniques/T1496/"
[rule.threat.tactic]
id = "TA0040"
name = "Impact"
reference = "https://attack.mitre.org/tactics/TA0040/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"
[rule.threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1110"
name = "Brute Force"
reference = "https://attack.mitre.org/techniques/T1110/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
Stages and Predicates
Stage 1: from
from logs-endpoint.events.network-* metadata _id, _index, _version
Stage 2: mv_expand
| mv_expand event.action
Stage 3: where
| where
host.os.type == "linux" and
event.type == "start" and
event.action == "connection_attempted" and
destination.port in (22, 222, 2222, 10022, 2022, 2200, 62612, 8022) and
not (
cidr_match(
destination.ip,
"10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12",
"192.0.0.0/24", "192.0.0.0/29", "192.0.0.8/32", "192.0.0.9/32",
"192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24",
"192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24",
"224.0.0.0/4", "100.64.0.0/10", "192.175.48.0/24", "198.18.0.0/15",
"198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1", "FE80::/10", "FF00::/8"
) or
process.executable in (
"/usr/bin/rclone", "/usr/bin/sss_ssh_knownhostsproxy", "/usr/sbin/sshd", "/usr/bin/ssh",
"/usr/local/bin/php", "/usr/sbin/apache2", "/usr/sbin/nginx", "/usr/local/bin/argocd-repo-server",
"/opt/nessus/sbin/nessusd", "/usr/local/bin/source-controller"
) or
process.executable like "/usr/local/efax/*"
)
Stage 4: keep
| keep
@timestamp,
_id,
_index,
_version,
host.os.type,
event.type,
event.action,
destination.port,
destination.ip,
process.executable,
agent.id,
host.name,
data_stream.dataset,
data_stream.namespace
Stage 5: stats
| stats
Esql.event_count = count(),
Esql.agent_id_count_distinct = count_distinct(agent.id),
Esql.host_name_values = values(host.name),
Esql.agent_id_values = values(agent.id),
Esql.data_stream_dataset_values = values(data_stream.dataset),
Esql.data_stream_namespace_values = values(data_stream.namespace)
by process.executable, destination.port
Stage 6: where
| where
Esql.agent_id_count_distinct == 1 and
Esql.event_count >= 100
Stage 7: eval
| eval agent.id = mv_min(Esql.agent_id_values),
host.name = mv_min(Esql.host_name_values)
Stage 8: sort
| sort Esql.event_count asc
Stage 9: keep
| keep Esql.*, agent.id, host.name, process.executable, destination.port
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Esql.agent_id_count_distinct | eq |
| field:"Esql.agent_id_count_distinct" kind:eq value:"1" |
Esql.event_count | ge |
| field:"Esql.event_count" kind:ge value:"100" |
destination.port | in |
| field:"DestinationPort" kind:in |
event.action | eq |
| field:"EventType" kind:eq value:"connection_attempted" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
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 |
process.executable | in | /opt/nessus/sbin/nessusd, /usr/bin/rclone, /usr/bin/ssh, /usr/bin/sss_ssh_knownhostsproxy, /usr/local/bin/argocd-repo-server, /usr/local/bin/php, /usr/local/bin/source-controller, /usr/sbin/apache2, /usr/sbin/nginx, /usr/sbin/sshd | excludes:process.executable |
process.executable | starts_with | /usr/local/efax/ | excludes:process.executable field:"process.executable" value:"/usr/local/efax/" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Esql.* | KEEP Esql.* |
agent.id | KEEP agent.id |
host.name | KEEP host.name |
process.executable | KEEP process.executable |
destination.port | KEEP destination.port |
Potential Privilege Escalation via a Parent/Child Process Sequence
#Detects a potential privilege escalation sequence via a parent/child process relationship. This rule checks for non-root execution of a parent process executable in a user or world-writeable directory by a non-root user followed by a UID change event to 0 (root) by the child process. 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/child process relationship. This rule checks for non-root
execution of a parent process executable in a user or world-writeable directory by a non-root user followed by a UID
change event to 0 (root) by the child process. This sequence is indicative of a potential local privilege escalation
exploit.
"""
id = "ee4a9893-2c55-4268-9292-d4efb15e8195"
license = "Elastic License v2"
name = "Potential Privilege Escalation via a Parent/Child Process Sequence"
os_list = ["linux"]
version = "1.0.5"
query = '''
sequence with maxspan=30s
[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.parent.executable like (
"/home/*/.conda/envs/fmf_server_agent/bin/python*", "/home/*/.local/share/uv/python/cpython-*-linux-x86_64-gnu/bin/python*",
"/home/*/.local/share/mise/installs/node/*/bin/node", "/tmp/newroot/*", "/home/*/.local/share/claude/versions/*",
"/home/*/.npm-global/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex",
"/home/*/.vscode-server/bin/*/node", "/home/*/.local/bin/claude", "/run/user/*/.bubblewrap/newroot/*",
"/tmp/go-build*/*/sso.test", "./bd.sh", "/usr/bin/node", "/usr/bin/terminator", "/usr/bin/yakuake", "/usr/libexec/gnome-terminal-server",
"/usr/libexec/ptyxis-agent", "/home/*/Desktop/actions-runner/bin.*/Runner.Worker",
"/home/*/.nvm/versions/node/v*/lib/node_modules/@anthropic-ai/claude-code/bin/claude.exe",
"/home/*/.nvm/versions/node/v*/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/*/bin/codex",
"/home/*/.local/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/*/codex/codex",
"/home/*/.codex/packages/standalone/releases/*/bin/codex", "/home/*/.npm-global/bin/claude", "/home/*/.local/bin/copilot",
"/home/*/.local/bin/agy", "/home/*/.local/bin/kiro-cli-chat", "/home/*/.local/bin/kiro-cli-term", "/home/*/.local/bin/zellij",
"/home/*/.pixi/bin/pixi", "/home/*/.bun/bin/bun", "/home/*/.vnc/xstartup", "/home/*/bin/tmux", "/home/*/.local/share/cursor-agent/versions/*/node",
"/home/*/.cache/yay/llmfit/src/llmfit/target/release/deps/llmfit-*", "/home/*/.sideload/nvim/nvim-linux-x86_64/bin/nvim",
"/home/*/repos/gocryptfs/fortanix-dsm-fseagent", "/home/*/devel/rak-ps/base/test.runner/tts.interpreter", "/home/*/cricket/cricket/util/cenic/*.pl",
"/home/*/.local/share/containers/storage/overlay/*/merged/usr/libexec/openssh/sshd-session",
"./merged/home/*/.local/share/containers/storage/overlay/*/merged/usr/libexec/openssh/sshd-session",
"./merged/var/lib/containers/storage/overlay/*/merged/usr/libexec/openssh/sshd-session",
"/var/lib/containers/storage/overlay/*/merged/usr/libexec/openssh/sshd-session", "/tmp/*/.vscode-server/bin/*/node",
"/tmp/*/easybuild/LLVM/*/llvm.obj.*/bin/clang-*", "/sw/eb/sw/*", "/home/*/.vscode-server/cli/servers/Stable-*/server/node",
"/home/*/.npm-global/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex/codex",
"/home/*/.nvm/versions/node/*/bin/node", "/home/*/cricket/util/cenic/decomDevice.pl", "/home/*/.cursor-server/bin/linux-x64/*/node",
"/home/*/h/*/anaconda3/envs/gd/bin/python3.*", "/tmp/.tmp*/.vscode-server/cli/servers/Stable-*/server/node",
"/home/*/my-tools/kitty.app/bin/kitty", "/home/*/bin/ext/gocryptfs*", "/home/*/.local/bin/micromamba",
"/tmp/.mount_Cursor*/usr/share/cursor/cursor", "/home/*/sp/bin/goofys", "/usr/bin/cmake", "/tmp/vscode-komo/*/server/node",
"/home/*/sysadmin/linuxCommands/OnGuard/clearpass-onguard-installer*", "/home/*/Downloads/Antigravity-arm64/antigravity"
) or
process.executable like (
"./sh/relaunch.sh", "./install-components.sh", "./clean-docker.sh", "./docker-deploy.sh", "./bin/deploy-nautilus", "./get_helm.sh",
"/home/*/scripts/odoo.sh", "/home/*/Scripts/.clear_etc_hosts.sh", "/home/*/Scripts/simplified_add_private_ips_to_etc_hosts.sh",
"/home/*/.local/bin/sshuttle", "/home/*/.linuxbrew/bin/brew", "/home/*/repos/gocryptfs/fortanix-dsm-fseagent", "/home/*/bin/rootlesskit",
"/home/grads/*/miniconda3/envs/*/bin/python*", "/home/grads/*/anaconda3/envs/*/bin/python*", "/home/staff/*/.local/share/uv/python/cpython-*/bin/python*",
"/home/*/ntl/venv/bin/python", "/home/*/.venv/lib/python*/site-packages/playwright/driver/node", "/home/*/cricket/cricket/util/cenic/*.pl",
"/home/*/run_metering_for_all_times.sh", "/home/*/bin/crc", "/home/*/crc-linux-*/crc", "/home/*/.local/bin/k8t", "/home/*/bin/minikube",
"/home/*/.local/share/fnm/node-versions/v*/installation/bin/node", "/home/*/.nvm/versions/node/v*/bin/node", "/home/*/.hermes/node/bin/node",
"/home/*/updateThingsBoard/*.sh", "/home/*/.ampdata/instances/*/AMP_Linux_x86_64", "/home/*/utils/vpn/vpn.sh", "/home/*/local/bin/pvbatch",
"/tmp/newroot/usr/bin/flatpak", "/tmp/newroot/usr/bin/sh", "/cav/gtm/lke", "/home/*/cricket/util/cenic/*.pl", "/home/*/restart_starman.sh",
"/home/*/Programy/DCC_harris_release/dcc", "/tmp/newroot/var/lib/awx/venv/awx/bin/python3", "/tmp/var/lib/awx/venv/awx/bin/python3",
"/home/oracle/bin/request-daily.sh", "./merged/var/lib/containers/storage/overlay/*", "/usr/bin/podman", "/home/*/.conda/envs/*/bin/python",
"/home/*/go/src/*/odinq", "/tmp/newroot/usr/bin/sudo", "/usr/bin/consolehelper", "/home/*/llama.cpp/build/bin/llama-server"
) or
process.command_line in ("/usr/bin/env bash ./run_docker.sh", "/usr/bin/env bash ./run_docker_prod.sh") or
(process.parent.executable == "/tmp/newroot/var/lib/awx/venv/awx/bin/python3" and process.executable == "/tmp/newroot/var/lib/awx/venv/awx/bin/python3") or
(process.parent.executable == "/tmp/newroot/etc/profiles/per-user/tilupe/bin/starship" and process.executable == "/tmp/newroot/etc/profiles/per-user/tilupe/bin/starship")
)] by process.entity_id
[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"] by process.parent.entity_id
'''
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 30s, correlated by process.entity_id, 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.parent.executable like (
"/home/*/.conda/envs/fmf_server_agent/bin/python*", "/home/*/.local/share/uv/python/cpython-*-linux-x86_64-gnu/bin/python*",
"/home/*/.local/share/mise/installs/node/*/bin/node", "/tmp/newroot/*", "/home/*/.local/share/claude/versions/*",
"/home/*/.npm-global/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex",
"/home/*/.vscode-server/bin/*/node", "/home/*/.local/bin/claude", "/run/user/*/.bubblewrap/newroot/*",
"/tmp/go-build*/*/sso.test", "./bd.sh", "/usr/bin/node", "/usr/bin/terminator", "/usr/bin/yakuake", "/usr/libexec/gnome-terminal-server",
"/usr/libexec/ptyxis-agent", "/home/*/Desktop/actions-runner/bin.*/Runner.Worker",
"/home/*/.nvm/versions/node/v*/lib/node_modules/@anthropic-ai/claude-code/bin/claude.exe",
"/home/*/.nvm/versions/node/v*/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/*/bin/codex",
"/home/*/.local/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/*/codex/codex",
"/home/*/.codex/packages/standalone/releases/*/bin/codex", "/home/*/.npm-global/bin/claude", "/home/*/.local/bin/copilot",
"/home/*/.local/bin/agy", "/home/*/.local/bin/kiro-cli-chat", "/home/*/.local/bin/kiro-cli-term", "/home/*/.local/bin/zellij",
"/home/*/.pixi/bin/pixi", "/home/*/.bun/bin/bun", "/home/*/.vnc/xstartup", "/home/*/bin/tmux", "/home/*/.local/share/cursor-agent/versions/*/node",
"/home/*/.cache/yay/llmfit/src/llmfit/target/release/deps/llmfit-*", "/home/*/.sideload/nvim/nvim-linux-x86_64/bin/nvim",
"/home/*/repos/gocryptfs/fortanix-dsm-fseagent", "/home/*/devel/rak-ps/base/test.runner/tts.interpreter", "/home/*/cricket/cricket/util/cenic/*.pl",
"/home/*/.local/share/containers/storage/overlay/*/merged/usr/libexec/openssh/sshd-session",
"./merged/home/*/.local/share/containers/storage/overlay/*/merged/usr/libexec/openssh/sshd-session",
"./merged/var/lib/containers/storage/overlay/*/merged/usr/libexec/openssh/sshd-session",
"/var/lib/containers/storage/overlay/*/merged/usr/libexec/openssh/sshd-session", "/tmp/*/.vscode-server/bin/*/node",
"/tmp/*/easybuild/LLVM/*/llvm.obj.*/bin/clang-*", "/sw/eb/sw/*", "/home/*/.vscode-server/cli/servers/Stable-*/server/node",
"/home/*/.npm-global/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex/codex",
"/home/*/.nvm/versions/node/*/bin/node", "/home/*/cricket/util/cenic/decomDevice.pl", "/home/*/.cursor-server/bin/linux-x64/*/node",
"/home/*/h/*/anaconda3/envs/gd/bin/python3.*", "/tmp/.tmp*/.vscode-server/cli/servers/Stable-*/server/node",
"/home/*/my-tools/kitty.app/bin/kitty", "/home/*/bin/ext/gocryptfs*", "/home/*/.local/bin/micromamba",
"/tmp/.mount_Cursor*/usr/share/cursor/cursor", "/home/*/sp/bin/goofys", "/usr/bin/cmake", "/tmp/vscode-komo/*/server/node",
"/home/*/sysadmin/linuxCommands/OnGuard/clearpass-onguard-installer*", "/home/*/Downloads/Antigravity-arm64/antigravity"
) or
process.executable like (
"./sh/relaunch.sh", "./install-components.sh", "./clean-docker.sh", "./docker-deploy.sh", "./bin/deploy-nautilus", "./get_helm.sh",
"/home/*/scripts/odoo.sh", "/home/*/Scripts/.clear_etc_hosts.sh", "/home/*/Scripts/simplified_add_private_ips_to_etc_hosts.sh",
"/home/*/.local/bin/sshuttle", "/home/*/.linuxbrew/bin/brew", "/home/*/repos/gocryptfs/fortanix-dsm-fseagent", "/home/*/bin/rootlesskit",
"/home/grads/*/miniconda3/envs/*/bin/python*", "/home/grads/*/anaconda3/envs/*/bin/python*", "/home/staff/*/.local/share/uv/python/cpython-*/bin/python*",
"/home/*/ntl/venv/bin/python", "/home/*/.venv/lib/python*/site-packages/playwright/driver/node", "/home/*/cricket/cricket/util/cenic/*.pl",
"/home/*/run_metering_for_all_times.sh", "/home/*/bin/crc", "/home/*/crc-linux-*/crc", "/home/*/.local/bin/k8t", "/home/*/bin/minikube",
"/home/*/.local/share/fnm/node-versions/v*/installation/bin/node", "/home/*/.nvm/versions/node/v*/bin/node", "/home/*/.hermes/node/bin/node",
"/home/*/updateThingsBoard/*.sh", "/home/*/.ampdata/instances/*/AMP_Linux_x86_64", "/home/*/utils/vpn/vpn.sh", "/home/*/local/bin/pvbatch",
"/tmp/newroot/usr/bin/flatpak", "/tmp/newroot/usr/bin/sh", "/cav/gtm/lke", "/home/*/cricket/util/cenic/*.pl", "/home/*/restart_starman.sh",
"/home/*/Programy/DCC_harris_release/dcc", "/tmp/newroot/var/lib/awx/venv/awx/bin/python3", "/tmp/var/lib/awx/venv/awx/bin/python3",
"/home/oracle/bin/request-daily.sh", "./merged/var/lib/containers/storage/overlay/*", "/usr/bin/podman", "/home/*/.conda/envs/*/bin/python",
"/home/*/go/src/*/odinq", "/tmp/newroot/usr/bin/sudo", "/usr/bin/consolehelper", "/home/*/llama.cpp/build/bin/llama-server"
) or
process.command_line in ("/usr/bin/env bash ./run_docker.sh", "/usr/bin/env bash ./run_docker_prod.sh") or
(process.parent.executable == "/tmp/newroot/var/lib/awx/venv/awx/bin/python3" and process.executable == "/tmp/newroot/var/lib/awx/venv/awx/bin/python3") or
(process.parent.executable == "/tmp/newroot/etc/profiles/per-user/tilupe/bin/starship" and process.executable == "/tmp/newroot/etc/profiles/per-user/tilupe/bin/starship")
)] by process.entity_id
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"] 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 |
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.executable | eq | /tmp/newroot/etc/profiles/per-user/tilupe/bin/starship | excludes:process.executable field:"process.executable" value:"/tmp/newroot/etc/profiles/per-user/tilupe/bin/starship" |
process.parent.executable | eq | /tmp/newroot/etc/profiles/per-user/tilupe/bin/starship | excludes:process.parent.executable field:"process.parent.executable" value:"/tmp/newroot/etc/profiles/per-user/tilupe/bin/starship" |
process.executable | eq | /tmp/newroot/var/lib/awx/venv/awx/bin/python3 | excludes:process.executable field:"process.executable" value:"/tmp/newroot/var/lib/awx/venv/awx/bin/python3" |
process.parent.executable | eq | /tmp/newroot/var/lib/awx/venv/awx/bin/python3 | excludes:process.parent.executable field:"process.parent.executable" value:"/tmp/newroot/var/lib/awx/venv/awx/bin/python3" |
process.command_line | in | /usr/bin/env bash ./run_docker.sh, /usr/bin/env bash ./run_docker_prod.sh | excludes:process.command_line field:"process.command_line" value:"/usr/bin/env bash ./run_docker.sh" field:"process.command_line" value:"/usr/bin/env bash ./run_docker_prod.sh" |
process.executable | wildcard | ./sh/relaunch.sh, ./install-components.sh, ./clean-docker.sh, ./docker-deploy.sh, ./bin/deploy-nautilus, ./get_helm.sh, /home/*/scripts/odoo.sh, /home/*/Scripts/.clear_etc_hosts.sh, /home/*/Scripts/simplified_add_private_ips_to_etc_hosts.sh, /home/*/.local/bin/sshuttle, /home/*/.linuxbrew/bin/brew, /home/*/repos/gocryptfs/fortanix-dsm-fseagent, /home/*/bin/rootlesskit, /home/grads/*/miniconda3/envs/*/bin/python*, /home/grads/*/anaconda3/envs/*/bin/python*, /home/staff/*/.local/share/uv/python/cpython-*/bin/python*, /home/*/ntl/venv/bin/python, /home/*/.venv/lib/python*/site-packages/playwright/driver/node, /home/*/cricket/cricket/util/cenic/*.pl, /home/*/run_metering_for_all_times.sh, /home/*/bin/crc, /home/*/crc-linux-*/crc, /home/*/.local/bin/k8t, /home/*/bin/minikube, /home/*/.local/share/fnm/node-versions/v*/installation/bin/node, /home/*/.nvm/versions/node/v*/bin/node, /home/*/.hermes/node/bin/node, /home/*/updateThingsBoard/*.sh, /home/*/.ampdata/instances/*/AMP_Linux_x86_64, /home/*/utils/vpn/vpn.sh, /home/*/local/bin/pvbatch, /tmp/newroot/usr/bin/flatpak, /tmp/newroot/usr/bin/sh, /cav/gtm/lke, /home/*/cricket/util/cenic/*.pl, /home/*/restart_starman.sh, /home/*/Programy/DCC_harris_release/dcc, /tmp/newroot/var/lib/awx/venv/awx/bin/python3, /tmp/var/lib/awx/venv/awx/bin/python3, /home/oracle/bin/request-daily.sh, ./merged/var/lib/containers/storage/overlay/*, /usr/bin/podman, /home/*/.conda/envs/*/bin/python, /home/*/go/src/*/odinq, /tmp/newroot/usr/bin/sudo, /usr/bin/consolehelper, /home/*/llama.cpp/build/bin/llama-server | excludes:process.executable |
process.parent.executable | wildcard | /home/*/.conda/envs/fmf_server_agent/bin/python*, /home/*/.local/share/uv/python/cpython-*-linux-x86_64-gnu/bin/python*, /home/*/.local/share/mise/installs/node/*/bin/node, /tmp/newroot/*, /home/*/.local/share/claude/versions/*, /home/*/.npm-global/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/bin/codex, /home/*/.vscode-server/bin/*/node, /home/*/.local/bin/claude, /run/user/*/.bubblewrap/newroot/*, /tmp/go-build*/*/sso.test, ./bd.sh, /usr/bin/node, /usr/bin/terminator, /usr/bin/yakuake, /usr/libexec/gnome-terminal-server, /usr/libexec/ptyxis-agent, /home/*/Desktop/actions-runner/bin.*/Runner.Worker, /home/*/.nvm/versions/node/v*/lib/node_modules/@anthropic-ai/claude-code/bin/claude.exe, /home/*/.nvm/versions/node/v*/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/*/bin/codex, /home/*/.local/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/*/codex/codex, /home/*/.codex/packages/standalone/releases/*/bin/codex, /home/*/.npm-global/bin/claude, /home/*/.local/bin/copilot, /home/*/.local/bin/agy, /home/*/.local/bin/kiro-cli-chat, /home/*/.local/bin/kiro-cli-term, /home/*/.local/bin/zellij, /home/*/.pixi/bin/pixi, /home/*/.bun/bin/bun, /home/*/.vnc/xstartup, /home/*/bin/tmux, /home/*/.local/share/cursor-agent/versions/*/node, /home/*/.cache/yay/llmfit/src/llmfit/target/release/deps/llmfit-*, /home/*/.sideload/nvim/nvim-linux-x86_64/bin/nvim, /home/*/repos/gocryptfs/fortanix-dsm-fseagent, /home/*/devel/rak-ps/base/test.runner/tts.interpreter, /home/*/cricket/cricket/util/cenic/*.pl, /home/*/.local/share/containers/storage/overlay/*/merged/usr/libexec/openssh/sshd-session, ./merged/home/*/.local/share/containers/storage/overlay/*/merged/usr/libexec/openssh/sshd-session, ./merged/var/lib/containers/storage/overlay/*/merged/usr/libexec/openssh/sshd-session, /var/lib/containers/storage/overlay/*/merged/usr/libexec/openssh/sshd-session, /tmp/*/.vscode-server/bin/*/node, /tmp/*/easybuild/LLVM/*/llvm.obj.*/bin/clang-*, /sw/eb/sw/*, /home/*/.vscode-server/cli/servers/Stable-*/server/node, /home/*/.npm-global/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/codex/codex, /home/*/.nvm/versions/node/*/bin/node, /home/*/cricket/util/cenic/decomDevice.pl, /home/*/.cursor-server/bin/linux-x64/*/node, /home/*/h/*/anaconda3/envs/gd/bin/python3.*, /tmp/.tmp*/.vscode-server/cli/servers/Stable-*/server/node, /home/*/my-tools/kitty.app/bin/kitty, /home/*/bin/ext/gocryptfs*, /home/*/.local/bin/micromamba, /tmp/.mount_Cursor*/usr/share/cursor/cursor, /home/*/sp/bin/goofys, /usr/bin/cmake, /tmp/vscode-komo/*/server/node, /home/*/sysadmin/linuxCommands/OnGuard/clearpass-onguard-installer*, /home/*/Downloads/Antigravity-arm64/antigravity | excludes:process.parent.executable |
Process Creation from Unbacked Memory via Unsigned Parent
#Identifies the creation of a process where the creating thread's stack contains frames pointing outside any known executable image and the parent process is unsigned and was recently dropped. This may be indicative of the creation of a process as a result of a code injection.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule Body
[rule]
description = """
Identifies the creation of a process where the creating thread's stack contains frames pointing outside any known
executable image and the parent process is unsigned and was recently dropped. This may be indicative of the creation of
a process as a result of a code injection.
"""
id = "5eb295bd-38d5-48b0-9753-47e1651cef1b"
license = "Elastic License v2"
name = "Process Creation from Unbacked Memory via Unsigned Parent"
os_list = ["windows"]
reference = [
"https://www.elastic.co/security-labs/upping-the-ante-detecting-in-memory-threats-with-kernel-call-stacks",
]
version = "1.0.17"
query = '''
sequence by user.id with maxspan=3m
[process where event.action == "start" and not user.id : "S-1-5-18" and
(process.Ext.relative_file_creation_time <= 500 or process.Ext.relative_file_name_modify_time <= 500) and
not process.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*") and
not process.executable : ("C:\\Program Files\\Cognex\\ALI\\Cognex.VisionSolutions.ServiceHost.exe",
"C:\\Program Files (x86)\\PatientWorks\\Bin\\PWPatientXpress.exe",
"C:\\Program Files (x86)\\Enrollment\\WebEnrollment\\Server\\bin\\JobEngineService.exe") and
process.pe.imphash != "f34d5f2d4577ed6d9ceec516c1f5a744" and
not process.parent.executable : "C:\\Program Files\\Microsoft Visual Studio\\*\\Common?\\IDE\\devenv.exe"
] by process.entity_id as event0
[process where event.action == "start" and
process.parent.thread.Ext.call_stack_contains_unbacked == true and
process.parent.thread.Ext.call_stack_summary :
("ntdll.dll|kernelbase.dll|kernel32.dll|Unbacked",
"ntdll.dll|kernelbase.dll|Unbacked",
"ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|Unbacked",
"ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|windows.storage.dll|shell32.dll|Unbacked",
"ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|Unbacked|kernel32.dll|ntdll.dll",
"*mscorlib.ni.dll|microsoft.visualbasic.ni.dll|Unbacked*") and
(
process.executable : "?:\\Windows\\Microsoft.NET\\Framework*" or
(process.executable regex~ """(c:\\windows\\system32\\[a-z0-9\-\_\.]+\.exe|c:\\windows\\syswow64\\[a-z0-9\-\_\.]+\.exe|c:\\windows\\[a-z0-9\-\_\.]+\.exe)""" and process.args_count <= 1) or
event0.process.hash.sha256 == process.hash.sha256
)
] by process.parent.entity_id
'''
min_endpoint_version = "8.8.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "8.8.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 3m, correlated by process.entity_id, process.parent.entity_id, user.id.
Stage 1: process
[process where event.action == "start" and not user.id : "S-1-5-18" and
(process.Ext.relative_file_creation_time <= 500 or process.Ext.relative_file_name_modify_time <= 500) and
not process.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*") and
not process.executable : ("C:\\Program Files\\Cognex\\ALI\\Cognex.VisionSolutions.ServiceHost.exe",
"C:\\Program Files (x86)\\PatientWorks\\Bin\\PWPatientXpress.exe",
"C:\\Program Files (x86)\\Enrollment\\WebEnrollment\\Server\\bin\\JobEngineService.exe") and
process.pe.imphash != "f34d5f2d4577ed6d9ceec516c1f5a744" and
not process.parent.executable : "C:\\Program Files\\Microsoft Visual Studio\\*\\Common?\\IDE\\devenv.exe"
] by process.entity_id as event0
Stage 2: process
[process where event.action == "start" and
process.parent.thread.Ext.call_stack_contains_unbacked == true and
process.parent.thread.Ext.call_stack_summary :
("ntdll.dll|kernelbase.dll|kernel32.dll|Unbacked",
"ntdll.dll|kernelbase.dll|Unbacked",
"ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|Unbacked",
"ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|windows.storage.dll|shell32.dll|Unbacked",
"ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|Unbacked|kernel32.dll|ntdll.dll",
"*mscorlib.ni.dll|microsoft.visualbasic.ni.dll|Unbacked*") and
(
process.executable : "?:\\Windows\\Microsoft.NET\\Framework*" or
(process.executable regex~ """(c:\\windows\\system32\\[a-z0-9\-\_\.]+\.exe|c:\\windows\\syswow64\\[a-z0-9\-\_\.]+\.exe|c:\\windows\\[a-z0-9\-\_\.]+\.exe)""" and process.args_count <= 1) or
event0.process.hash.sha256 == process.hash.sha256
)
] by process.parent.entity_id
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
Process Masquerading as Kernel Process
#This rule detects potential process masquerading as a kernel process. Attackers may leverage the exec -a command to change the name of a process to mimic a kernel process, such as kworker, ksoftirqd, or kthreadd. When exec is spawned directly, it will kill the currently running shell, and continue to run as the masqueraded process. This leads to spawning a process with only one process argument, which is the name of a kernel thread (hence the brackets). This technique is used by malware to hide the true identity of a process from security tools and analysts.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Stealth |
Rule Body
[rule]
description = """
This rule detects potential process masquerading as a kernel process. Attackers may leverage the `exec -a` command to
change the name of a process to mimic a kernel process, such as `kworker`, `ksoftirqd`, or `kthreadd`. When `exec` is
spawned directly, it will kill the currently running shell, and continue to run as the masqueraded process. This leads
to spawning a process with only one process argument, which is the name of a kernel thread (hence the brackets). This
technique is used by malware to hide the true identity of a process from security tools and analysts.
"""
id = "fb2c3240-4cbe-413e-be78-5427807b618b"
license = "Elastic License v2"
name = "Process Masquerading as Kernel Process"
os_list = ["linux"]
version = "1.0.5"
query = '''
process where event.type == "start" and event.action == "exec" and process.args_count == 1 and
process.command_line like "[*]" and not (
process.executable like "/opt/splunk*" or
process.parent.executable like "/opt/splunk*" or
process.executable in ("/usr/local/ahnlab/v3net/bin/v3containerd", "/usr/local/ahnlab/v3net/bin/v3brokerd")
)
'''
min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
tree = true
[[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 = "T1564"
name = "Hide Artifacts"
reference = "https://attack.mitre.org/techniques/T1564/"
[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 event.action == "exec" and process.args_count == 1 and
process.command_line like "[*]" and not (
process.executable like "/opt/splunk*" or
process.parent.executable like "/opt/splunk*" or
process.executable in ("/usr/local/ahnlab/v3net/bin/v3containerd", "/usr/local/ahnlab/v3net/bin/v3brokerd")
)
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.executable | in | /usr/local/ahnlab/v3net/bin/v3brokerd, /usr/local/ahnlab/v3net/bin/v3containerd | excludes:process.executable field:"process.executable" value:"/usr/local/ahnlab/v3net/bin/v3brokerd" field:"process.executable" value:"/usr/local/ahnlab/v3net/bin/v3containerd" |
process.executable | starts_with | /opt/splunk | excludes:process.executable field:"process.executable" value:"/opt/splunk" |
process.parent.executable | starts_with | /opt/splunk | excludes:process.parent.executable field:"process.parent.executable" value:"/opt/splunk" |
Suspicious Base64 String Command-line
#This rule identifies suspicious base64 strings in a command execution. Malware authors may attempt to evade detection and trick users into executing malicious code by encoding and obfuscating their payloads. Several payloads relate to interpreter executions, reverse shells and ELF binaries.
MITRE ATT&CK Coverage
Rule Body
[rule]
description = """
This rule identifies suspicious base64 strings in a command execution. Malware authors may attempt to evade detection
and trick users into executing malicious code by encoding and obfuscating their payloads. Several payloads relate to
interpreter executions, reverse shells and ELF binaries.
"""
id = "18cdd8c1-4dc8-4ac1-8f7c-830be4c493cc"
license = "Elastic License v2"
name = "Suspicious Base64 String Command-line"
os_list = ["linux"]
reference = ["https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1140/T1140.yaml"]
version = "1.0.5"
query = '''
process where event.type == "start" and event.action == "exec" and
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and
process.parent.executable != null and process.command_line like (
// python and python3
"*cHl0aG9uIC1jICdpbXBvcnQgc29ja2V0*", "*ZXhwb3J0IFJIT1NUPQ*", "*cHl0aG9uMyAtYyAnaW1wb3J0IHNvY2tldA*",
"*cHl0aG9uMyAtYyAnaW1wb3J0IG9zLHB0eSxzb2NrZXQ7*", "*cHl0aG9uIC1jICdpbXBvcnQgb3MscHR5LHNvY2tldDs*",
"*cHl0aG9uIC1jICdpbXBvcnQgb3MscHR5LHNvY2tldDs*",
// perl
"*cGVybCAtTUlPIC1l*", "*cGVybCAtZQ*",
// ruby -r, -e
"cnVieSAtcg*", "*cnVie*tZQ*",
// php -r & cmd shells
"*cGhwIC1y*", "*PD9waHAgaWY*", "*PD89YCRfR0VUWzBdYD8*",
// lua -e + versioning wildcard
"*bHVh*IC1l*",
// sh reverse shells
"*c2ggLWkgPiYgL2Rldi90Y3Av*", "*MDwmMTk2O2V4ZWMgMTk2PD4vZGV2L3RjcC8*", "*ZXhlYyA1PD4vZGV2L3RjcC8*",
"*c2ggLWkgNTw+IC9kZXYvdGNwLw*", "*c2ggLWkgPiYgL2Rldi91ZHAv*",
// nc
"*cm0gL3RtcC9mO21rZmlmbyAvdG1wL2Y7Y2F0IC90bXAvZnxzaCAtaSAyPiYxfG5j*", "*YnVzeWJveCBuYw*",
// bash reverse shells
"*YmFzaCAtaSA+JiAvZGV2L3RjcC8*", "*L2Jpbi9iYXNoIC1sID4gL2Rldi90Y3Av*",
// node -e
"*bm9kZSAtZQ*",
// socat
"*c29jYXQ*",
// ELF
"*f0VMRg*"
) and not (
process.parent.name in ("fzf", "nvim") or
process.command_line like~ "sh -c *data *" or
process.parent.executable like ("/home/*/.cursor-server/bin/linux-x64/*/node", "/tmp/.mount_*/usr/share/cursor/cursor")
)
'''
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 = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"
[[threat.technique]]
id = "T1204"
name = "User Execution"
reference = "https://attack.mitre.org/techniques/T1204/"
[[threat.technique.subtechnique]]
id = "T1204.002"
name = "Malicious File"
reference = "https://attack.mitre.org/techniques/T1204/002/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1027"
name = "Obfuscated Files or Information"
reference = "https://attack.mitre.org/techniques/T1027/"
[[threat.technique]]
id = "T1140"
name = "Deobfuscate/Decode Files or Information"
reference = "https://attack.mitre.org/techniques/T1140/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: process
process where event.type == "start" and event.action == "exec" and
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and
process.parent.executable != null and process.command_line like (
"*cHl0aG9uIC1jICdpbXBvcnQgc29ja2V0*", "*ZXhwb3J0IFJIT1NUPQ*", "*cHl0aG9uMyAtYyAnaW1wb3J0IHNvY2tldA*",
"*cHl0aG9uMyAtYyAnaW1wb3J0IG9zLHB0eSxzb2NrZXQ7*", "*cHl0aG9uIC1jICdpbXBvcnQgb3MscHR5LHNvY2tldDs*",
"*cHl0aG9uIC1jICdpbXBvcnQgb3MscHR5LHNvY2tldDs*",
"*cGVybCAtTUlPIC1l*", "*cGVybCAtZQ*",
"cnVieSAtcg*", "*cnVie*tZQ*",
"*cGhwIC1y*", "*PD9waHAgaWY*", "*PD89YCRfR0VUWzBdYD8*",
"*bHVh*IC1l*",
"*c2ggLWkgPiYgL2Rldi90Y3Av*", "*MDwmMTk2O2V4ZWMgMTk2PD4vZGV2L3RjcC8*", "*ZXhlYyA1PD4vZGV2L3RjcC8*",
"*c2ggLWkgNTw+IC9kZXYvdGNwLw*", "*c2ggLWkgPiYgL2Rldi91ZHAv*",
"*cm0gL3RtcC9mO21rZmlmbyAvdG1wL2Y7Y2F0IC90bXAvZnxzaCAtaSAyPiYxfG5j*", "*YnVzeWJveCBuYw*",
"*YmFzaCAtaSA+JiAvZGV2L3RjcC8*", "*L2Jpbi9iYXNoIC1sID4gL2Rldi90Y3Av*",
"*bm9kZSAtZQ*",
"*c29jYXQ*",
"*f0VMRg*"
) and not (
process.parent.name in ("fzf", "nvim") or
process.command_line like~ "sh -c *data *" or
process.parent.executable like ("/home/*/.cursor-server/bin/linux-x64/*/node", "/tmp/.mount_*/usr/share/cursor/cursor")
)
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.command_line | wildcard |
| field:"CommandLine" kind:wildcard |
process.name | in |
| field:"process_basename" kind:in |
process.parent.executable | is_not_null | field:"ParentImage" kind:is_not_null |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.command_line | wildcard | sh -c *data * | excludes:process.command_line field:"process.command_line" value:"sh -c *data *" |
process.parent.executable | wildcard | /home/*/.cursor-server/bin/linux-x64/*/node, /tmp/.mount_*/usr/share/cursor/cursor | excludes:process.parent.executable field:"process.parent.executable" value:"/home/*/.cursor-server/bin/linux-x64/*/node" field:"process.parent.executable" value:"/tmp/.mount_*/usr/share/cursor/cursor" |
process.parent.name | in | fzf, nvim | excludes:process.parent.name field:"process.parent.name" value:"fzf" field:"process.parent.name" value:"nvim" |
Suspicious Communication App Child Process
#Identifies suspicious child processes of communications apps, which can indicate a potential masquerading as the communication app or the exploitation of a vulnerability on the application causing it to execute code.
MITRE ATT&CK Coverage
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 1: Process creation |
| Security-Auditing | Event ID 4688: A new process has been created. |
Rule Body
[metadata]
creation_date = "2023/08/04"
integration = ["endpoint", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2026/05/04"
[rule]
author = ["Elastic"]
description = """
Identifies suspicious child processes of communications apps, which can indicate a potential masquerading as the
communication app or the exploitation of a vulnerability on the application causing it to execute code.
"""
from = "now-9m"
index = ["logs-endpoint.events.process-*", "logs-sentinel_one_cloud_funnel.*", "endgame-*"]
language = "eql"
license = "Elastic License v2"
name = "Suspicious Communication App Child Process"
risk_score = 47
rule_id = "adbfa3ee-777e-4747-b6b0-7bd645f30880"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Defense Evasion",
"Tactic: Persistence",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
"Data Source: SentinelOne",
"Data Source: Elastic Endgame",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "windows" and event.type == "start" and
process.parent.name : (
"slack.exe", "CiscoCollabHost.exe", "WebexHost.exe", "Teams.exe",
"Discord.exe", "Whatsapp.exe", "Zoom.exe", "thunderbird.exe"
) and
not process.executable : (
"?:\\Program Files\\*.exe",
"?:\\Program Files (x86)\\*.exe",
"?:\\Windows\\System32\\WerFault.exe",
"?:\\Windows\\SysWOW64\\WerFault.exe"
) and
/* Common Signed Browser Processes */
not (
process.executable : (
"?:\\Users\\*\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe",
"?:\\Users\\*\\AppData\\Local\\Island\\Island\\Application\\Island.exe",
"?:\\Users\\*\\AppData\\Local\\Mozilla Firefox\\firefox.exe",
"?:\\Users\\*\\AppData\\Local\\Programs\\Opera\\opera.exe"
) and process.code_signature.trusted == true
) and
(
/* Slack */
(process.parent.name : "slack.exe" and not
(
(
process.executable : (
"?:\\Users\\*\\AppData\\Roaming\\Zoom\\bin*\\Zoom.exe",
"?:\\Windows\\System32\\rundll32.exe",
"?:\\Windows\\System32\\notepad.exe"
) and process.code_signature.trusted == true
) or
(
process.code_signature.subject_name : (
"Slack Technologies, Inc.",
"Slack Technologies, LLC"
) and process.code_signature.trusted == true
) or
(
(process.name : "powershell.exe" and process.command_line : "powershell.exe -c Invoke-WebRequest -Uri https://slackb.com/*") or
(process.name : "cmd.exe" and process.command_line : "C:\\WINDOWS\\system32\\cmd.exe /d /s /c \"%windir%\\System32\\rundll32.exe User32.dll,SetFocus 0\"")
)
)
) or
/* WebEx */
(process.parent.name : ("CiscoCollabHost.exe", "WebexHost.exe") and not
(
process.code_signature.subject_name : (
"Cisco Systems, Inc.",
"Cisco WebEx LLC",
"Cisco Systems Inc."
) and process.code_signature.trusted == true
)
) or
/* Teams */
(process.parent.name : "Teams.exe" and not
(
(
process.executable : (
"?:\\Windows\\BrowserCore\\BrowserCore.exe",
"?:\\Users\\*\\AppData\\Local\\Microsoft\\Teams\\current\\Teams.exe"
) and process.code_signature.trusted == true
) or
(
process.code_signature.subject_name : (
"Microsoft Corporation",
"Microsoft 3rd Party Application Component"
) and process.code_signature.trusted == true
) or
(
(process.name : "taskkill.exe" and process.args : "Teams.exe")
)
)
) or
/* Discord */
(process.parent.name : "Discord.exe" and not
(
(
process.executable : (
"?:\\Windows\\System32\\reg.exe",
"?:\\Windows\\SysWOW64\\reg.exe"
) and process.code_signature.trusted == true
) or
(
process.code_signature.subject_name : (
"Discord Inc."
) and process.code_signature.trusted == true
) or
(
process.name : "cmd.exe" and
(
process.command_line : (
"C:\\WINDOWS\\system32\\cmd.exe /d /s /c \"chcp\"",
"C:\\WINDOWS\\system32\\cmd.exe /q /d /s /c \"C:\\Program^ Files\\NVIDIA^ Corporation\\NVSMI\\nvidia-smi.exe\""
) or
process.args : (
"C:\\WINDOWS/System32/nvidia-smi.exe",
"C:\\WINDOWS\\System32\\nvidia-smi.exe",
"C:\\Windows\\System32\\DriverStore\\FileRepository/*/nvidia-smi.exe*"
)
)
)
)
) or
/* WhatsApp */
(process.parent.name : "Whatsapp.exe" and not
(
(
process.executable : (
"?:\\Windows\\System32\\reg.exe",
"?:\\Windows\\SysWOW64\\reg.exe"
) and process.code_signature.trusted == true
) or
(
process.code_signature.subject_name : (
"WhatsApp LLC",
"WhatsApp, Inc",
"24803D75-212C-471A-BC57-9EF86AB91435"
) and process.code_signature.trusted == true
) or
(
(process.name : "cmd.exe" and process.command_line : "C:\\Windows\\system32\\cmd.exe /d /s /c \"C:\\Windows\\system32\\wbem\\wmic.exe*")
)
)
) or
/* Zoom */
(process.parent.name : "Zoom.exe" and not
(
(
process.executable : (
"?:\\Users\\*\\AppData\\Local\\BraveSoftware\\Brave-Browser\\Application\\brave.exe"
) and process.code_signature.trusted == true
) or
(
process.code_signature.subject_name : (
"Zoom Video Communications, Inc.",
"Zoom Communications, Inc."
) and process.code_signature.trusted == true
)
)
) or
/* Thunderbird */
(process.parent.name : "thunderbird.exe" and not
(
(
process.executable : (
"?:\\Windows\\splwow64.exe",
"?:\\Windows\\System32\\spool\\drivers\\x64\\3\\*.EXE"
) and process.code_signature.trusted == true
) or
(
process.code_signature.subject_name : (
"Mozilla Corporation"
) and process.code_signature.trusted == true
)
)
)
)
'''
setup = """## Setup
This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
Setup instructions: https://ela.st/install-elastic-defend
### Additional data sources
This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
"""
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 Communication App Child Process
Communication apps like Slack, WebEx, and Teams are integral to modern workflows, facilitating collaboration. However, adversaries can exploit these apps by spawning unauthorized child processes, potentially masquerading as legitimate ones or exploiting vulnerabilities to execute malicious code. The detection rule identifies such anomalies by monitoring child processes of these apps, ensuring they are trusted and signed by recognized entities. This helps in identifying potential threats that deviate from expected behavior, thus safeguarding against unauthorized access and execution.
### Possible investigation steps
- Review the process details, including the parent process name and executable path, to confirm if the child process is expected or unusual for the communication app in question.
- Check the code signature of the suspicious child process to determine if it is trusted and signed by a recognized entity, as specified in the query.
- Investigate the command line arguments of the child process to identify any potentially malicious or unexpected commands being executed.
- Correlate the event with other logs or alerts to identify any related suspicious activities or patterns, such as repeated unauthorized child process executions.
- Assess the user account associated with the process to determine if it has been compromised or is exhibiting unusual behavior.
- Examine the network activity of the affected system to identify any suspicious outbound connections that may indicate data exfiltration or communication with a command and control server.
### False positive analysis
- Legitimate software updates or installations may trigger the rule if they spawn child processes from communication apps. Users can create exceptions for known update processes by verifying their code signatures and paths.
- Custom scripts or automation tools that interact with communication apps might be flagged. Users should ensure these scripts are signed and located in trusted directories, then add them to the exception list.
- Certain administrative tasks, such as using command-line tools like cmd.exe or powershell.exe, may be mistakenly identified as suspicious. Users can whitelist specific command lines or arguments that are regularly used in their environment.
- Some third-party integrations with communication apps may generate child processes that are not inherently malicious. Users should verify the legitimacy of these integrations and add them to the trusted list if they are deemed safe.
- Regularly review and update the list of trusted code signatures and executable paths to ensure that legitimate processes are not inadvertently flagged as suspicious.
### Response and remediation
- Immediately isolate the affected system from the network to prevent further unauthorized access or execution of malicious code.
- Terminate any suspicious child processes identified by the detection rule that are not signed by recognized entities or are executing from unexpected locations.
- Conduct a thorough review of the affected communication app's logs and configurations to identify any unauthorized changes or access patterns.
- Restore the affected system from a known good backup if malicious activity is confirmed, ensuring that the backup is free from compromise.
- Update the communication app and all related software to the latest versions to patch any known vulnerabilities that may have been exploited.
- Implement application whitelisting to ensure only trusted and signed applications can execute, reducing the risk of similar threats.
- Escalate the incident to the security operations center (SOC) or relevant security team for further investigation and to assess the potential impact on other systems."""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1036"
name = "Masquerading"
reference = "https://attack.mitre.org/techniques/T1036/"
[[rule.threat.technique.subtechnique]]
id = "T1036.001"
name = "Invalid Code Signature"
reference = "https://attack.mitre.org/techniques/T1036/001/"
[[rule.threat.technique.subtechnique]]
id = "T1036.005"
name = "Match Legitimate Resource Name or Location"
reference = "https://attack.mitre.org/techniques/T1036/005/"
[[rule.threat.technique]]
id = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"
[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 = "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 = "T1203"
name = "Exploitation for Client Execution"
reference = "https://attack.mitre.org/techniques/T1203/"
[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.parent.name : (
"slack.exe", "CiscoCollabHost.exe", "WebexHost.exe", "Teams.exe",
"Discord.exe", "Whatsapp.exe", "Zoom.exe", "thunderbird.exe"
) and
not process.executable : (
"?:\\Program Files\\*.exe",
"?:\\Program Files (x86)\\*.exe",
"?:\\Windows\\System32\\WerFault.exe",
"?:\\Windows\\SysWOW64\\WerFault.exe"
) and
not (
process.executable : (
"?:\\Users\\*\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe",
"?:\\Users\\*\\AppData\\Local\\Island\\Island\\Application\\Island.exe",
"?:\\Users\\*\\AppData\\Local\\Mozilla Firefox\\firefox.exe",
"?:\\Users\\*\\AppData\\Local\\Programs\\Opera\\opera.exe"
) and process.code_signature.trusted == true
) and
(
(process.parent.name : "slack.exe" and not
(
(
process.executable : (
"?:\\Users\\*\\AppData\\Roaming\\Zoom\\bin*\\Zoom.exe",
"?:\\Windows\\System32\\rundll32.exe",
"?:\\Windows\\System32\\notepad.exe"
) and process.code_signature.trusted == true
) or
(
process.code_signature.subject_name : (
"Slack Technologies, Inc.",
"Slack Technologies, LLC"
) and process.code_signature.trusted == true
) or
(
(process.name : "powershell.exe" and process.command_line : "powershell.exe -c Invoke-WebRequest -Uri https://slackb.com/*") or
(process.name : "cmd.exe" and process.command_line : "C:\\WINDOWS\\system32\\cmd.exe /d /s /c \"%windir%\\System32\\rundll32.exe User32.dll,SetFocus 0\"")
)
)
) or
(process.parent.name : ("CiscoCollabHost.exe", "WebexHost.exe") and not
(
process.code_signature.subject_name : (
"Cisco Systems, Inc.",
"Cisco WebEx LLC",
"Cisco Systems Inc."
) and process.code_signature.trusted == true
)
) or
(process.parent.name : "Teams.exe" and not
(
(
process.executable : (
"?:\\Windows\\BrowserCore\\BrowserCore.exe",
"?:\\Users\\*\\AppData\\Local\\Microsoft\\Teams\\current\\Teams.exe"
) and process.code_signature.trusted == true
) or
(
process.code_signature.subject_name : (
"Microsoft Corporation",
"Microsoft 3rd Party Application Component"
) and process.code_signature.trusted == true
) or
(
(process.name : "taskkill.exe" and process.args : "Teams.exe")
)
)
) or
(process.parent.name : "Discord.exe" and not
(
(
process.executable : (
"?:\\Windows\\System32\\reg.exe",
"?:\\Windows\\SysWOW64\\reg.exe"
) and process.code_signature.trusted == true
) or
(
process.code_signature.subject_name : (
"Discord Inc."
) and process.code_signature.trusted == true
) or
(
process.name : "cmd.exe" and
(
process.command_line : (
"C:\\WINDOWS\\system32\\cmd.exe /d /s /c \"chcp\"",
"C:\\WINDOWS\\system32\\cmd.exe /q /d /s /c \"C:\\Program^ Files\\NVIDIA^ Corporation\\NVSMI\\nvidia-smi.exe\""
) or
process.args : (
"C:\\WINDOWS/System32/nvidia-smi.exe",
"C:\\WINDOWS\\System32\\nvidia-smi.exe",
"C:\\Windows\\System32\\DriverStore\\FileRepository/*/nvidia-smi.exe*"
)
)
)
)
) or
(process.parent.name : "Whatsapp.exe" and not
(
(
process.executable : (
"?:\\Windows\\System32\\reg.exe",
"?:\\Windows\\SysWOW64\\reg.exe"
) and process.code_signature.trusted == true
) or
(
process.code_signature.subject_name : (
"WhatsApp LLC",
"WhatsApp, Inc",
"24803D75-212C-471A-BC57-9EF86AB91435"
) and process.code_signature.trusted == true
) or
(
(process.name : "cmd.exe" and process.command_line : "C:\\Windows\\system32\\cmd.exe /d /s /c \"C:\\Windows\\system32\\wbem\\wmic.exe*")
)
)
) or
(process.parent.name : "Zoom.exe" and not
(
(
process.executable : (
"?:\\Users\\*\\AppData\\Local\\BraveSoftware\\Brave-Browser\\Application\\brave.exe"
) and process.code_signature.trusted == true
) or
(
process.code_signature.subject_name : (
"Zoom Video Communications, Inc.",
"Zoom Communications, Inc."
) and process.code_signature.trusted == true
)
)
) or
(process.parent.name : "thunderbird.exe" and not
(
(
process.executable : (
"?:\\Windows\\splwow64.exe",
"?:\\Windows\\System32\\spool\\drivers\\x64\\3\\*.EXE"
) and process.code_signature.trusted == true
) or
(
process.code_signature.subject_name : (
"Mozilla Corporation"
) and process.code_signature.trusted == true
)
)
)
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.code_signature.trusted | eq | true | excludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true" |
process.executable | wildcard | ?:\Users\*\AppData\Local\Google\Chrome\Application\chrome.exe, ?:\Users\*\AppData\Local\Island\Island\Application\Island.exe, ?:\Users\*\AppData\Local\Mozilla Firefox\firefox.exe, ?:\Users\*\AppData\Local\Programs\Opera\opera.exe | excludes:process.executable |
process.executable | wildcard | ?:\Program Files\*.exe, ?:\Program Files (x86)\*.exe, ?:\Windows\System32\WerFault.exe, ?:\Windows\SysWOW64\WerFault.exe | excludes:process.executable |
Suspicious Desktop Window Manager API Call
#Identifies suspicious memory API calls by the Window Desktop Manager process. This may indicate a successful vulnerability exploitation for privilege escalation.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Privilege Escalation |
Rule Body
[rule]
description = """
Identifies suspicious memory API calls by the Window Desktop Manager process. This may indicate a successful
vulnerability exploitation for privilege escalation.
"""
id = "1ddca85b-866b-4bee-96cd-ac5466f36e0a"
license = "Elastic License v2"
name = "Suspicious Desktop Window Manager API Call"
os_list = ["windows"]
reference = [
"https://googleprojectzero.github.io/0days-in-the-wild/0day-RCAs/2023/CVE-2023-36033.html",
"https://www.elastic.co/security-labs/itw-windows-lpe-0days-insights-and-detection-strategies",
"https://nvd.nist.gov/vuln/detail/cve-2024-30051",
]
version = "1.0.1"
query = '''
api where process.Ext.api.name in ("VirtualAlloc", "VirtualProtect", "ResumeThread", "WinExec", "SetThreadContext") and
process.executable : "?:\\Windows\\system32\\dwm.exe" and
(
process.thread.Ext.call_stack_summary like "*|combase.dll|user32.dll|dwmcore.dll|*" or
process.thread.Ext.call_stack_final_user_module.name == "combase.dll" or
(process.thread.Ext.call_stack_final_user_module.name == "Unbacked" and process.thread.Ext.call_stack_final_user_module.protection_provenance == "combase.dll")
) and
not (process.Ext.api.name == "VirtualProtect" and
_arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info like ("c:\\windows\\sys?????\\ntdll.dll!LdrLoadDll*", "c:\\windows\\sys?????\\kernelbase.dll!LoadLibrary*")))
'''
min_endpoint_version = "8.10.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true
[[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.10.0"
Stages and Predicates
Stage 1: api
api where process.Ext.api.name in ("VirtualAlloc", "VirtualProtect", "ResumeThread", "WinExec", "SetThreadContext") and
process.executable : "?:\\Windows\\system32\\dwm.exe" and
(
process.thread.Ext.call_stack_summary like "*|combase.dll|user32.dll|dwmcore.dll|*" or
process.thread.Ext.call_stack_final_user_module.name == "combase.dll" or
(process.thread.Ext.call_stack_final_user_module.name == "Unbacked" and process.thread.Ext.call_stack_final_user_module.protection_provenance == "combase.dll")
) and
not (process.Ext.api.name == "VirtualProtect" and
_arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info like ("c:\\windows\\sys?????\\ntdll.dll!LdrLoadDll*", "c:\\windows\\sys?????\\kernelbase.dll!LoadLibrary*")))
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
process.Ext.api.name | in |
| field:"process.Ext.api.name" kind:in |
process.executable | wildcard |
| field:"Image" kind:wildcard value:"?:\Windows\system32\dwm.exe" |
process.thread.Ext.call_stack_final_user_module.name | eq |
| field:"process.thread.Ext.call_stack_final_user_module.name" kind:eq |
process.thread.Ext.call_stack_final_user_module.protection_provenance | eq |
| field:"process.thread.Ext.call_stack_final_user_module.protection_provenance" kind:eq value:"combase.dll" |
process.thread.Ext.call_stack_summary | wildcard |
| field:"process.thread.Ext.call_stack_summary" kind:wildcard value:"*|combase.dll|user32.dll|dwmcore.dll|*" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.thread.Ext.call_stack | array_any | excludes:process.thread.Ext.call_stack | |
process.Ext.api.name | eq | VirtualProtect | excludes:process.Ext.api.name field:"process.Ext.api.name" value:"VirtualProtect" |
Suspicious Process Execution Detected via Defend for Containers
#This rule detects the execution of a process from a suspicious directory inside a container. The suspicious directories are /tmp, /dev/shm, /var/tmp, /run, /var/run, /mnt, /media, and /boot. Adversaries may use these directories to execute malicious code or exfiltrate data.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Stealth | |
| Command & Control |
Rule Body
[metadata]
creation_date = "2026/02/06"
integration = ["cloud_defend"]
maturity = "production"
min_stack_comments = "Defend for Containers integration was re-introduced in 9.3.0"
min_stack_version = "9.3.0"
updated_date = "2026/07/29"
[rule]
author = ["Elastic"]
description = """
This rule detects the execution of a process from a suspicious directory inside a container.
The suspicious directories are /tmp, /dev/shm, /var/tmp, /run, /var/run, /mnt, /media, and /boot.
Adversaries may use these directories to execute malicious code or exfiltrate data.
"""
from = "now-6m"
index = ["logs-cloud_defend.process*"]
interval = "5m"
language = "eql"
license = "Elastic License v2"
name = "Suspicious Process Execution 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 Suspicious Process Execution Detected via Defend for Containers
This alert flags a program launched inside a container from transient or low-trust locations such as tmpfs-backed or runtime directories, common staging points for hands-on misuse, data theft, or persistence that avoids the image filesystem. A frequent pattern is an attacker gaining a shell via kubectl exec, fetching a static reverse shell or tunneling tool into /dev/shm or /tmp, and running it interactively to pivot or siphon data. Such behavior signals live operator control and attempts to evade forensics and policy controls.
### Possible investigation steps
- Pivot to Kubernetes API server audit logs to find pod/exec or attach events around the alert and map them to the initiating user, source IP, and service account.
- Determine if the binary or script was introduced post-deploy by listing transient directories in the container and comparing artifacts against the image layers or build manifest.
- Review process lineage and TTY/PTY session details to confirm an interactive shell and identify the parent or invocation method, such as a shell or reverse-shell stager.
- Capture live network activity from the container to spot external callbacks, tunnels, or exfil destinations, and isolate the pod if suspicious connections are present.
- Assess the pod’s service account, RBAC permissions, and security context for elevated privileges or host namespace access to gauge impact and prioritize containment.
### False positive analysis
- An engineer performing authorized troubleshooting opens an interactive shell and runs a known diagnostic binary staged in /tmp or /dev/shm to avoid altering the image, leading to an interactive exec from a transient path.
- A mounted volume under /mnt or /media holds legitimate utilities, and an authorized user starts one interactively for maintenance or configuration, triggering the rule despite expected operations.
### Response and remediation
- Immediately contain by applying a deny-all egress NetworkPolicy to the affected pod, killing the interactive process whose executable resides under /tmp, /dev/shm, /var/tmp, /run, /var/run, /mnt, /media, or /boot, and blocking further kubectl exec/attach to it.
- Eradicate by terminating and redeploying the pod from a trusted image, scanning and cleaning any mounted volumes under /mnt or /media, and removing staged binaries or scripts found in transient paths like /tmp, /var/tmp, /run, and /var/run.
- Recover by rotating credentials the pod could access (service account token, mounted secrets, API keys), validating application behavior post-redeploy, and restoring network access only to approved destinations.
- Escalate to incident response immediately if you observe a shell or tunneling tool launched from /tmp or /dev/shm, evidence of exfiltration via outbound connections, privileged or hostPID/hostNetwork settings, or writes touching /boot.
- Harden by disabling kubectl exec for production workloads, enforcing readOnlyRootFilesystem with seccomp and AppArmor, mounting /tmp and /dev/shm with noexec,nodev,nosuid, and using admission policy to allowlist executable paths and deny interactive TTYs."""
risk_score = 73
rule_id = "279e272a-91d9-4780-878c-bfcac76e6e31"
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 = '''
process where event.type == "start" and event.action == "exec" and (
process.executable like (
"/tmp/*", "/dev/shm/*", "/var/tmp/*", "/run/*", "/var/run/*", "/mnt/*", "/media/*", "/boot/*"
) or
// Hidden process execution
process.name like ".*"
) and container.id like "?*"
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1564"
name = "Hide Artifacts"
reference = "https://attack.mitre.org/techniques/T1564/"
[[rule.threat.technique.subtechnique]]
id = "T1564.001"
name = "Hidden Files and Directories"
reference = "https://attack.mitre.org/techniques/T1564/001/"
[[rule.threat.technique]]
id = "T1620"
name = "Reflective Code Loading"
reference = "https://attack.mitre.org/techniques/T1620/"
[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.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"
[rule.threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
Stages and Predicates
Stage 1: process
process where event.type == "start" and event.action == "exec" and (
process.executable like (
"/tmp/*", "/dev/shm/*", "/var/tmp/*", "/run/*", "/var/run/*", "/mnt/*", "/media/*", "/boot/*"
) or
process.name like ".*"
) and container.id like "?*"
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.executable | wildcard |
| field:"Image" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:".*" |
Systemd Service Started by Unusual Parent Process
#Systemctl is a process used in Linux systems to manage systemd processes through service configuration files. Malicious actors can leverage systemd services to achieve persistence by creating or modifying service files to execute malicious commands or payloads during system startup. This allows them to maintain unauthorized access, execute additional malicious activities, or evade detection.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Persistence | |
| Privilege Escalation |
Rule Body
[metadata]
creation_date = "2024/05/17"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"
[transform]
[[transform.osquery]]
label = "Osquery - Retrieve File Listing Information"
query = """
SELECT * FROM file WHERE ( path LIKE '/etc/systemd/system/%' OR path LIKE '/usr/local/lib/systemd/system/%' OR path LIKE
'/lib/systemd/system/%' OR path LIKE '/usr/lib/systemd/system/%' OR path LIKE '/home/user/.config/systemd/user/%' )
"""
[[transform.osquery]]
label = "Osquery - Retrieve Additional File Listing Information"
query = """
SELECT f.path, u.username AS file_owner, g.groupname AS group_owner, datetime(f.atime, 'unixepoch') AS
file_last_access_time, datetime(f.mtime, 'unixepoch') AS file_last_modified_time, datetime(f.ctime, 'unixepoch') AS
file_last_status_change_time, datetime(f.btime, 'unixepoch') AS file_created_time, f.size AS size_bytes FROM file f LEFT
JOIN users u ON f.uid = u.uid LEFT JOIN groups g ON f.gid = g.gid WHERE ( path LIKE '/etc/systemd/system/%' OR path LIKE
'/usr/local/lib/systemd/system/%' OR path LIKE '/lib/systemd/system/%' OR path LIKE '/usr/lib/systemd/system/%' OR path
LIKE '/home/{{user.name}}/.config/systemd/user/%' )
"""
[[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 = """
Systemctl is a process used in Linux systems to manage systemd processes through service configuration files. Malicious
actors can leverage systemd services to achieve persistence by creating or modifying service files to execute malicious
commands or payloads during system startup. This allows them to maintain unauthorized access, execute additional
malicious activities, or evade detection.
"""
from = "now-9m"
index = ["logs-endpoint.events.*"]
language = "kuery"
license = "Elastic License v2"
name = "Systemd Service Started by Unusual Parent Process"
note = """## Triage and analysis
### Investigating Systemd Service Started by Unusual Parent Process
Systemd service files are configuration files in Linux systems used to define and manage systemd services.
Malicious actors can leverage systemd service files to achieve persistence by creating or modifying service files to execute malicious commands or payloads during system startup. This allows them to maintain unauthorized access, execute additional malicious activities, or evade detection.
This rule monitors the execution of the systemctl binary to start, enable or reenable a systemd service, potentially indicating the creation of a persistence mechanism.
> **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 currently enabled systemd services through the following command `sudo systemctl list-unit-files`.
- Investigate whether any other files in any of the available systemd directories have been altered through OSQuery.
- $osquery_0
- $osquery_1
- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence and whether they are located in expected locations.
- $osquery_2
- Investigate other alerts associated with the user/host during the past 48 hours.
- Validate the activity is not related to planned patches, updates, network administrator activity, or legitimate software installations.
- Investigate whether the altered scripts call other malicious scripts elsewhere on the file system.
- If scripts or executables were dropped, retrieve the files and determine if they are malicious:
- Use a private sandboxed malware analysis system to perform analysis.
- Observe and collect information about the following activities:
- Attempts to contact external domains and addresses.
- Check if the domain is newly registered or unexpected.
- Check the reputation of the domain or IP address.
- File access, modification, and creation activities.
- Cron jobs, services and other persistence mechanisms.
- $osquery_3
- Investigate abnormal behaviors by the subject process/user such as network connections, file modifications, and any other spawned child processes.
- Investigate listening ports and open sockets to look for potential command and control traffic or data exfiltration.
- $osquery_4
- $osquery_5
- Identify the user account that performed the action, analyze it, and check whether it should perform this kind of action.
- $osquery_6
- Investigate whether the user is currently logged in and active.
- $osquery_7
### False Positive Analysis
- If this activity is related to new benign software installation activity, consider adding exceptions — preferably with a combination of user and command line conditions.
- If this activity is related to a system administrator who uses systemd services 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.
### Related Rules
- New Systemd Service Created by Previously Unknown Process - 17b0a495-4d9f-414c-8ad0-92f018b8e001
- Potential Persistence Through Run Control Detected - 0f4d35e4-925e-4959-ab24-911be207ee6f
- Potential Persistence Through init.d Detected - 474fd20e-14cc-49c5-8160-d9ab4ba16c8b
- New Systemd Timer Created - 7fb500fa-8e24-4bd1-9480-2a819352602c
### 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.
- Delete the service/timer or restore its original configuration.
- 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://symantec-enterprise-blogs.security.com/blogs/threat-intelligence/springtail-kimsuky-backdoor-espionage",
"https://pberba.github.io/security/2022/01/30/linux-threat-hunting-for-persistence-systemd-timers-cron/",
"https://www.elastic.co/security-labs/primer-on-persistence-mechanisms",
]
risk_score = 21
rule_id = "b605f262-f7dc-41b5-9ebc-06bafe7a83b6"
setup = """## Setup
This rule requires data coming in from Elastic Defend.
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "low"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Tactic: Privilege Escalation",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
host.os.type:linux and event.category:process and event.type:start and event.action:exec and
process.executable:/usr/bin/systemctl and process.args:(enable or reenable or start) and
process.entry_leader.entry_meta.type:* and
not (
process.entry_leader.entry_meta.type:(container or init or unknown) or
process.parent.pid:1 or
process.parent.executable:(
/bin/adduser or /bin/dnf or /bin/dnf-automatic or /bin/dockerd or /bin/dpkg or /bin/microdnf or /bin/pacman or
/bin/podman or /bin/rpm or /bin/snapd or /bin/sudo or /bin/useradd or /bin/yum or /usr/bin/dnf or
/usr/bin/dnf-automatic or /usr/bin/dockerd or /usr/bin/dpkg or /usr/bin/microdnf or /usr/bin/pacman or
/usr/bin/podman or /usr/bin/rpm or /usr/bin/snapd or /usr/bin/sudo or /usr/bin/yum or /usr/sbin/adduser or
/usr/sbin/invoke-rc.d or /usr/sbin/useradd or /var/lib/dpkg/* or /opt/datadog-agent/embedded/bin/installer or
/opt/saltstack/salt/bin/python* or /opt/puppetlabs/puppet/bin/puppet or /opt/splunkforwarder/bin/splunk or
/opt/puppetlabs/puppet/bin/ruby or /opt/kaspersky/kesl/shared/kesl or /usr/local/bin/cloudflared or
/usr/bin/puppet or /opt/sentinelone/bin/sentinelctl
) or
process.args_count >= 5 or
process.parent.command_line:*ansible*
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"
[[rule.threat.technique.subtechnique]]
id = "T1543.002"
name = "Systemd Service"
reference = "https://attack.mitre.org/techniques/T1543/002/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"
[[rule.threat.technique.subtechnique]]
id = "T1543.002"
name = "Systemd Service"
reference = "https://attack.mitre.org/techniques/T1543/002/"
[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1569"
name = "System Services"
reference = "https://attack.mitre.org/techniques/T1569/"
[[rule.threat.technique.subtechnique]]
id = "T1569.002"
name = "Service Execution"
reference = "https://attack.mitre.org/techniques/T1569/002/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[rule.new_terms]
field = "new_terms_fields"
value = ["process.parent.executable"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-5d"
Stages and Predicates
Stage 1: new_terms
host.os.type:linux and event.category:process and event.type:start and event.action:exec and
process.executable:/usr/bin/systemctl and process.args:(enable or reenable or start) and
process.entry_leader.entry_meta.type:* and
not (
process.entry_leader.entry_meta.type:(container or init or unknown) or
process.parent.pid:1 or
process.parent.executable:(
/bin/adduser or /bin/dnf or /bin/dnf-automatic or /bin/dockerd or /bin/dpkg or /bin/microdnf or /bin/pacman or
/bin/podman or /bin/rpm or /bin/snapd or /bin/sudo or /bin/useradd or /bin/yum or /usr/bin/dnf or
/usr/bin/dnf-automatic or /usr/bin/dockerd or /usr/bin/dpkg or /usr/bin/microdnf or /usr/bin/pacman or
/usr/bin/podman or /usr/bin/rpm or /usr/bin/snapd or /usr/bin/sudo or /usr/bin/yum or /usr/sbin/adduser or
/usr/sbin/invoke-rc.d or /usr/sbin/useradd or /var/lib/dpkg/* or /opt/datadog-agent/embedded/bin/installer or
/opt/saltstack/salt/bin/python* or /opt/puppetlabs/puppet/bin/puppet or /opt/splunkforwarder/bin/splunk or
/opt/puppetlabs/puppet/bin/ruby or /opt/kaspersky/kesl/shared/kesl or /usr/local/bin/cloudflared or
/usr/bin/puppet or /opt/sentinelone/bin/sentinelctl
) or
process.args_count >= 5 or
process.parent.command_line:*ansible*
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.category | eq |
| field:"event.category" kind:eq value:"process" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | in |
| field:"process.args" kind:in |
process.entry_leader.entry_meta.type | is_not_null | field:"process.entry_leader.entry_meta.type" kind:is_not_null | |
process.executable | eq |
| field:"Image" kind:eq value:"/usr/bin/systemctl" |
Exclusions
The rule actively suppresses these predicates.