Detection rules › Elastic
Elastic rules: 0n
AWS CloudTrail Log Suspended
#Detects Cloudtrail logging suspension via StopLogging API. Stopping CloudTrail eliminates forward audit visibility and is a classic defense evasion step before sensitive changes or data theft. Investigate immediately and determine what occurred during the logging gap.
Known False Positives
- Suspending the recording of a trail may be done by a system or network administrator. Verify whether the user identity, user agent, and/or hostname should be making changes in your environment. Trail suspensions from 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 |
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
Rule Body
[metadata]
creation_date = "2020/06/10"
integration = ["aws"]
maturity = "production"
updated_date = "2026/07/08"
[rule]
author = ["Elastic"]
description = """
Detects Cloudtrail logging suspension via StopLogging API. Stopping CloudTrail eliminates forward audit visibility and
is a classic defense evasion step before sensitive changes or data theft. Investigate immediately and determine what
occurred during the logging gap.
"""
false_positives = [
"""
Suspending the recording of a trail may be done by a system or network administrator. Verify whether the user
identity, user agent, and/or hostname should be making changes in your environment. Trail suspensions from
unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted
from the rule.
""",
]
from = "now-6m"
index = ["filebeat-*", "logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS CloudTrail Log Suspended"
note = """## Triage and analysis
### Investigating AWS CloudTrail Log Suspended
AWS CloudTrail is a service that enables governance, compliance, and operational and risk auditing of your AWS account. It logs API calls and related events, providing visibility into user activity. This rule identifies the suspension of an AWS log trail using the `StopLogging` API. Attackers can do this to cover their tracks and impact security monitoring that relies on this source.
#### Possible investigation steps
- **Actor & scope**
- Identify `aws.cloudtrail.user_identity.arn`, `user_agent.original`, `source.ip`.
- Determine which trail stopped and whether it’s multi-region or organization-wide.
- **Timing and impact**
- When did logging stop and resume (if at all)? Are there overlapping detections indicating activity during the gap?
- **Correlate activity**
- Search for sensitive API activity around the stop event (IAM changes, S3 policy changes, EC2 exports, KMS changes).
- Check for preceding `UpdateTrail` (e.g., destination change) and subsequent `DeleteTrail`.
### False positive analysis
- **Planned suspensions**: Rare; verify maintenance tickets and ensure post-change validation.
### Response and remediation
- Restart logging (`StartLogging`) immediately.
- Investigate actor’s recent activity; rotate credentials if suspicious.
- Validate trail configuration, destination bucket/CMK, and event selectors.
- Hardening: Limit `cloudtrail:StopLogging` to break-glass roles; alert on any future stops; enforce via AWS Config/SCPs.
### 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/awscloudtrail/latest/APIReference/API_StopLogging.html",
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/cloudtrail/stop-logging.html",
]
risk_score = 73
rule_id = "1aa8fa52-44a7-4dae-b058-f3333b91c8d7"
severity = "high"
tags = [
"Domain: Cloud",
"Data Source: AWS",
"Data Source: Amazon Web Services",
"Data Source: AWS Cloudtrail",
"Use Case: Log Auditing",
"Resources: Investigation Guide",
"Tactic: Defense Evasion",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset: "aws.cloudtrail"
and event.provider: "cloudtrail.amazonaws.com"
and event.action: "StopLogging"
and event.outcome: "success"
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[[rule.threat.technique.subtechnique]]
id = "T1562.001"
name = "Disable or Modify Tools"
reference = "https://attack.mitre.org/techniques/T1562/001/"
[[rule.threat.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/"
[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",
]
Stages and Predicates
Stage 1: query
data_stream.dataset: "aws.cloudtrail"
and event.provider: "cloudtrail.amazonaws.com"
and event.action: "StopLogging"
and event.outcome: "success"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"aws.cloudtrail" |
event.action | eq |
| field:"EventType" kind:eq value:"StopLogging" |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"success" |
event.provider | eq |
| field:"Provider_Name" kind:eq value:"cloudtrail.amazonaws.com" |
AWS IAM Credentials Added to a Bedrock API Key Phantom User
#Identifies standard IAM credentials being added to an Amazon Bedrock API key phantom user, whose user name starts with "BedrockAPIKey-": either a long-term access key (CreateAccessKey) or a console password / login profile (CreateLoginProfile, UpdateLoginProfile). When a long-term Bedrock API key is generated through the AWS Console, AWS silently provisions a "BedrockAPIKey-<id>" IAM user with the AmazonBedrockLimitedAccess managed policy. That user is intended only to back a Bedrock bearer token and should never hold standard programmatic keys or interactive console access. Adding either converts a Bedrock-scoped identity into general-purpose IAM credentials that inherit the policy's Bedrock control-plane and IAM, VPC, and KMS reconnaissance permissions and that persist after the Bedrock API key is revoked. This is the privilege-escalation and persistence pivot documented for Bedrock API key phantom users, and there is no legitimate workflow that produces it.
Known False Positives
- There is no known legitimate workflow that adds IAM access keys or console login profiles to a Bedrock API key phantom user. Any match should be investigated. Confirm the actor in "aws.cloudtrail.user_identity.arn" and the target user in "aws.cloudtrail.request_parameters", and remove the credential if it was not expected.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Privilege Escalation |
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
- AWS IAM Backdoor Users Keys (Sigma)
- AWS IAM Login Profile Added for Root (Elastic)
- AWS IAM Login Profile Added to User (Elastic)
- AWS IAM Login Profile Created or Modified for an IAM User (Elastic)
- AWS IAM S3Browser LoginProfile Creation (Sigma)
- AWS IAM S3Browser User or AccessKey Creation (Sigma)
- AWS IAM Sensitive Operations via Lambda Execution Role (Elastic)
- AWS IAM User Created Access Keys For Another User (Elastic)
Rule Body
[metadata]
creation_date = "2026/07/06"
integration = ["aws"]
maturity = "production"
updated_date = "2026/07/06"
[rule]
author = ["Elastic"]
description = """
Identifies standard IAM credentials being added to an Amazon Bedrock API key phantom user, whose user name starts with
"BedrockAPIKey-": either a long-term access key (CreateAccessKey) or a console password / login profile
(CreateLoginProfile, UpdateLoginProfile). When a long-term Bedrock API key is generated through the AWS Console, AWS
silently provisions a "BedrockAPIKey-<id>" IAM user with the AmazonBedrockLimitedAccess managed policy. That user is
intended only to back a Bedrock bearer token and should never hold standard programmatic keys or interactive console
access. Adding either converts a Bedrock-scoped identity into general-purpose IAM credentials that inherit the policy's
Bedrock control-plane and IAM, VPC, and KMS reconnaissance permissions and that persist after the Bedrock API key is
revoked. This is the privilege-escalation and persistence pivot documented for Bedrock API key phantom users, and there
is no legitimate workflow that produces it.
"""
false_positives = [
"""
There is no known legitimate workflow that adds IAM access keys or console login profiles to a Bedrock API key phantom
user. Any match should be investigated. Confirm the actor in "aws.cloudtrail.user_identity.arn" and the target user in
"aws.cloudtrail.request_parameters", and remove the credential if it was not expected.
""",
]
from = "now-30m"
language = "esql"
license = "Elastic License v2"
name = "AWS IAM Credentials Added to a Bedrock API Key Phantom User"
note = """## Triage and analysis
### Investigating AWS IAM Credentials Added to a Bedrock API Key Phantom User
Amazon Bedrock API keys authenticate with a bearer token. When a long-term key is created through the AWS Console, AWS provisions an IAM user named "BedrockAPIKey-<id>" and attaches the AmazonBedrockLimitedAccess managed policy. That policy is broader than its name suggests: it grants Bedrock control-plane actions (including deletion of guardrails, custom models, and provisioned throughput) as well as IAM, VPC, and KMS reconnaissance. The phantom user is meant only to back the bearer token and should never hold standard access keys or an interactive console login.
Adding an IAM access key (CreateAccessKey) or a console password (CreateLoginProfile/UpdateLoginProfile) to the phantom user escalates a Bedrock-scoped identity into general-purpose IAM credentials or interactive access that inherit the full policy scope and continue to work after the originating Bedrock API key is revoked. This is a deliberate privilege-escalation and persistence step.
### Possible investigation steps
- Identify the actor in "aws.cloudtrail.user_identity.arn" and "aws.cloudtrail.user_identity.type", and review "source.ip" and "user_agent.original" for whether this is an expected administrator.
- Confirm the target phantom user and the credential type in "event.action" and "aws.cloudtrail.request_parameters", and enumerate the user's remaining credentials (service-specific credentials, access keys, login profile).
- Review the phantom user's subsequent activity for use of the new credential outside Bedrock (IAM, VPC, KMS, STS calls, or console logins).
- Correlate with the key-creation events (CreateUser and CreateServiceSpecificCredential for the same user) to reconstruct the timeline.
### False positive analysis
- This should be near-zero. There is no standard workflow that adds access keys or login profiles to a "BedrockAPIKey-*" user. Treat any hit as suspicious until proven otherwise.
### Response and remediation
- Remove the access key or login profile on the phantom user and, if compromise is suspected, deactivate or delete the associated Bedrock service-specific credential.
- Review the actor's recent activity and rotate or restrict its credentials.
- Deploy a Service Control Policy that denies "iam:CreateAccessKey" and "iam:CreateLoginProfile" on "arn:aws:iam::*:user/BedrockAPIKey-*" to block this pivot organization-wide.
"""
references = [
"https://www.beyondtrust.com/blog/entry/aws-bedrock-security-guide-api-keys-detection-response",
"https://www.beyondtrust.com/blog/entry/aws-bedrock-security-api-keys",
"https://docs.aws.amazon.com/bedrock/latest/userguide/api-keys.html",
]
risk_score = 73
rule_id = "71159cad-f8b3-4b3c-ac6e-9cab05594670"
setup = "This rule requires AWS CloudTrail logs ingested via the Elastic AWS integration. See https://docs.elastic.co/integrations/aws/cloudtrail for setup details."
severity = "high"
tags = [
"Domain: Cloud",
"Data Source: AWS",
"Data Source: Amazon Web Services",
"Data Source: AWS IAM",
"Data Source: Amazon Bedrock",
"Use Case: Threat Detection",
"Tactic: Privilege Escalation",
"Tactic: Persistence",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
FROM logs-aws.cloudtrail-* METADATA _id, _version, _index
| WHERE event.provider == "iam.amazonaws.com"
AND event.action IN ("CreateAccessKey", "CreateLoginProfile", "UpdateLoginProfile")
AND event.outcome == "success"
AND user.target.name LIKE "BedrockAPIKey-*"
| KEEP _id, _version, _index, @timestamp, aws.*, cloud.*, event.*, source.*, user.*, user_agent.*
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[[rule.threat.technique.subtechnique]]
id = "T1098.001"
name = "Additional Cloud Credentials"
reference = "https://attack.mitre.org/techniques/T1098/001/"
[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[[rule.threat.technique.subtechnique]]
id = "T1098.001"
name = "Additional Cloud Credentials"
reference = "https://attack.mitre.org/techniques/T1098/001/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
Stages and Predicates
Stage 1: from
FROM logs-aws.cloudtrail-* METADATA _id, _version, _index
Stage 2: where
| WHERE event.provider == "iam.amazonaws.com"
AND event.action IN ("CreateAccessKey", "CreateLoginProfile", "UpdateLoginProfile")
AND event.outcome == "success"
AND user.target.name LIKE "BedrockAPIKey-*"
Stage 3: keep
| KEEP _id, _version, _index, @timestamp, aws.*, cloud.*, event.*, source.*, user.*, user_agent.*
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | in |
| field:"EventType" kind:in |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"success" |
event.provider | eq |
| field:"Provider_Name" kind:eq value:"iam.amazonaws.com" |
user.target.name | wildcard |
| field:"TargetUserName" kind:wildcard value:"BedrockAPIKey-*" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
_id | KEEP _id |
_version | KEEP _version |
_index | KEEP _index |
@timestamp | KEEP @timestamp |
aws.* | KEEP aws.* |
cloud.* | KEEP cloud.* |
event.* | KEEP event.* |
source.* | KEEP source.* |
user.* | KEEP user.* |
user_agent.* | KEEP user_agent.* |
AWS Service Quota Increase Requested by Rare Identity
#Detects the first time an AWS identity requests a service quota increase via the AWS Service Quotas API within a 7-day history window. Service quota increases are submitted to AWS Support and, when approved, raise the limits on EC2 instances, Lambda concurrency, VPC resources, and other services. An adversary who obtains AWS credentials may request quota increases as infrastructure preparation for large-scale cryptomining, DDoS amplification, phishing campaigns, or data exfiltration operations that require compute or network resources beyond the account's current limits.
Known False Positives
- Cloud infrastructure teams requesting quota increases for planned capacity expansions, new region deployments, or scaling events will trigger this rule. Validate the requested service and limit against your infrastructure roadmap before closing.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Resource Development |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2026/08/24"
integration = ["aws"]
maturity = "production"
updated_date = "2026/08/24"
[rule]
author = ["Elastic"]
description = """
Detects the first time an AWS identity requests a service quota increase via the AWS Service
Quotas API within a 7-day history window. Service quota increases are submitted to AWS Support
and, when approved, raise the limits on EC2 instances, Lambda concurrency, VPC resources, and
other services. An adversary who obtains AWS credentials may request quota increases as
infrastructure preparation for large-scale cryptomining, DDoS amplification, phishing
campaigns, or data exfiltration operations that require compute or network resources beyond
the account's current limits.
"""
false_positives = [
"""
Cloud infrastructure teams requesting quota increases for planned capacity expansions,
new region deployments, or scaling events will trigger this rule. Validate the requested
service and limit against your infrastructure roadmap before closing.
""",
]
from = "now-6m"
index = ["logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS Service Quota Increase Requested by Rare Identity"
note = """## Triage and analysis
### Investigating AWS Service Quota Increase Requested by Rare Identity
AWS Service Quotas (formerly Service Limits) cap how many resources of each type an account can create. Default limits exist to prevent accidental runaway provisioning, but an adversary who requests an increase can scale operations far beyond what the default limits allow: requesting 1000 EC2 On-Demand vCPUs enables cryptomining at industrial scale; requesting higher SES sending limits enables large-scale phishing campaigns; requesting higher Lambda concurrency enables large-scale credential-stuffing operations.
### Possible investigation steps
- Identify the caller from aws.cloudtrail.user_identity.arn and user.name.
- Review aws.cloudtrail.request_parameters for the serviceCode (which AWS service), the quotaCode (which specific limit), and the requested value.
- Determine whether the requested quota increase aligns with a known infrastructure project.
- Check whether the same identity has recently created resources in the service being scaled (EC2 RunInstances, Lambda CreateFunction, SES SendEmail).
- Review whether this is the first quota increase request for this service from this identity or a continuation of a known capacity planning effort.
### Response and remediation
- If unauthorized, submit a cancellation request to AWS Support for the quota increase.
- Revoke active sessions for the requesting identity.
- Apply an SCP restricting servicequotas:RequestServiceQuotaIncrease to approved cloud-operations roles that require prior approval.
"""
references = [
"https://docs.aws.amazon.com/servicequotas/2019-06-24/apireference/API_RequestServiceQuotaIncrease.html",
"https://www.rapid7.com/blog/post/dr-threat-actors-aws-workmail-phishing-campaigns/",
]
risk_score = 47
rule_id = "7e1b0654-b6c0-4b1b-ab47-75588533083c"
setup = "The AWS integration must be ingesting management events into `logs-aws.cloudtrail-*`. Service Quotas management events are logged by default."
severity = "medium"
tags = [
"Domain: Cloud",
"Platform: AWS",
"Data Source: AWS CloudTrail",
"Service: AWS Service Quotas",
"Rule Type: New Terms",
"Tactic: Resource Development",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
data_stream.dataset: "aws.cloudtrail"
and event.provider: "servicequotas.amazonaws.com"
and event.action: "RequestServiceQuotaIncrease"
and event.outcome: "success"
and not user_agent.original: (*Terraform* or *Pulumi* or *Ansible* or "cloudformation.amazonaws.com")
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1583"
name = "Acquire Infrastructure"
reference = "https://attack.mitre.org/techniques/T1583/"
[rule.threat.tactic]
id = "TA0042"
name = "Resource Development"
reference = "https://attack.mitre.org/tactics/TA0042/"
[rule.investigation_fields]
field_names = [
"@timestamp",
"aws.cloudtrail.user_identity.arn",
"aws.cloudtrail.user_identity.type",
"aws.cloudtrail.user_identity.access_key_id",
"user.name",
"event.action",
"event.outcome",
"aws.cloudtrail.request_parameters",
"source.ip",
"cloud.region",
"cloud.account.id",
]
[rule.new_terms]
field = "new_terms_fields"
value = ["cloud.account.id", "user.name"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-7d"
Stages and Predicates
Stage 1: new_terms
data_stream.dataset: "aws.cloudtrail"
and event.provider: "servicequotas.amazonaws.com"
and event.action: "RequestServiceQuotaIncrease"
and event.outcome: "success"
and not user_agent.original: (*Terraform* or *Pulumi* or *Ansible* or "cloudformation.amazonaws.com")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"aws.cloudtrail" |
event.action | eq |
| field:"EventType" kind:eq value:"RequestServiceQuotaIncrease" |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"success" |
event.provider | eq |
| field:"Provider_Name" kind:eq value:"servicequotas.amazonaws.com" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
user_agent.original | eq | cloudformation.amazonaws.com | excludes:user_agent.original field:"user_agent.original" value:"cloudformation.amazonaws.com" |
user_agent.original | match | Ansible | excludes:user_agent.original field:"user_agent.original" value:"Ansible" |
user_agent.original | match | Pulumi | excludes:user_agent.original field:"user_agent.original" value:"Pulumi" |
user_agent.original | match | Terraform | excludes:user_agent.original field:"user_agent.original" value:"Terraform" |
Azure WireServer OpenSSL Certificate Decrypt or LinuxTransport Generation
#Identifies OpenSSL generating a CN=LinuxTransport certificate or decrypting CMS/PKCS7 payloads with a key that is not the Azure Linux Agent certificate under /var/lib/waagent. Adversaries can scrape WireServer certificates, mint a LinuxTransport identity, and decrypt extension protectedSettings with openssl cms -decrypt or smime -decrypt.
Known False Positives
- Custom configuration-management that decrypts CMS blobs with an organization key outside /var/lib/waagent. Confirm the key path and exclude the specific command line after review.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth | |
| Credential Access |
Rule Body
[metadata]
creation_date = "2026/08/17"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/09/10"
[rule]
author = ["Elastic"]
description = """
Identifies OpenSSL generating a CN=LinuxTransport certificate or decrypting CMS/PKCS7 payloads with a key that is not
the Azure Linux Agent certificate under /var/lib/waagent. Adversaries can scrape WireServer certificates, mint a
LinuxTransport identity, and decrypt extension protectedSettings with openssl cms -decrypt or smime -decrypt.
"""
false_positives = [
"""
Custom configuration-management that decrypts CMS blobs with an organization key outside /var/lib/waagent. Confirm
the key path and exclude the specific command line after review.
""",
]
from = "now-9m"
index = ["logs-endpoint.events.process-*"]
language = "eql"
license = "Elastic License v2"
name = "Azure WireServer OpenSSL Certificate Decrypt or LinuxTransport Generation"
note = """## Triage and analysis
### Investigating Azure WireServer OpenSSL Certificate Decrypt or LinuxTransport Generation
CyberCX-style WireServer abuse on Linux generates `openssl req -x509 -subj /CN=LinuxTransport`, posts the public
certificate to WireServer `comp=certificates`, then runs `openssl cms -decrypt` or `openssl smime -decrypt` with
`temp.key`, `wireserver.key`, or another non-waagent key to unwrap protectedSettings.
Benign Azure Linux Agent activity looks like:
`openssl cms -inform DER -decrypt -recip /var/lib/waagent/<thumbprint>.crt -inkey /var/lib/waagent/<thumbprint>.prv`
The Azure Linux Agent is excluded by certificate path in process arguments (`/var/lib/waagent/*`) and by
parent executables `/usr/sbin/waagent` and `/usr/bin/waagent`. This does not exclude Python or
`run-command-extension` as parents because attacker scripts invoked via Run Command use those parents
with a non-waagent key. The agent itself also runs `openssl req ... /CN=LinuxTransport` with output
under `/var/lib/waagent/`; that argument path exclusion covers it.
### Possible investigation steps
- Review `process.command_line` and `process.args` for `LinuxTransport`, `wireserver.key`, `temp.key`, `payload.p7m`,
or `payload.pfx`.
- Inspect parent and grandparent: Run Command (`/var/lib/waagent/run-command/`) or an interactive shell is higher
risk than a one-off admin session with a ticket.
- Correlate with network events from curl to `168.63.129.16` ports 80 and 32526 on the same host.
- Search StorageRead logs for anonymous or SAS GetBlob of the same storage account after the decrypt.
- Hunt for the generated key files (`temp.key`, `wireserver.key`) on disk and in `/tmp`.
### False positive analysis
- The Azure Linux Agent decrypt path under `/var/lib/waagent/` and waagent parent executables
(`/usr/sbin/waagent`, `/usr/bin/waagent`) are excluded.
- Legitimate certificate tooling that uses `-subj /CN=LinuxTransport` is unexpected; treat as suspicious until proven
otherwise.
### Response and remediation
- Isolate the VM, delete attacker-generated keys and decrypted payloads, and rotate secrets that were in
protectedSettings (SAS, connection strings, CSE script contents).
- Rotate the VM managed identity and review extension configuration.
- Revoke any SAS that was replayed from the decrypted settings.
"""
references = [
"https://cybercx.com.au/blog/azure-ssrf-metadata/",
"https://www.netspi.com/blog/technical-blog/cloud-pentesting/decrypting-vm-extension-settings-with-azure-wireserver/",
"https://cloud.google.com/blog/topics/threat-intelligence/escalating-privileges-azure-kubernetes-services",
"https://gtfobins.github.io/gtfobins/openssl/",
]
risk_score = 47
rule_id = "5bb27863-2da6-4d0d-879a-1efb10479c39"
severity = "medium"
tags = [
"Domain: Endpoint",
"Domain: Cloud",
"OS: Linux",
"Use Case: Threat Detection",
"Platform: Azure",
"Platform: Linux",
"Tactic: Credential Access",
"Tactic: Defense Evasion",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "linux" and event.type == "start" and
event.action in ("exec", "exec_event", "start") and process.name == "openssl" and
(
(
process.args in ("cms", "smime") and process.args == "-decrypt"
) or
(
process.args == "req" and process.args : "*LinuxTransport*"
)
) and
not process.args like "/var/lib/waagent/*" and
not process.parent.executable like (
"/usr/sbin/waagent",
"/usr/bin/waagent"
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1552"
name = "Unsecured Credentials"
reference = "https://attack.mitre.org/techniques/T1552/"
[[rule.threat.technique.subtechnique]]
id = "T1552.005"
name = "Cloud Instance Metadata API"
reference = "https://attack.mitre.org/techniques/T1552/005/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1140"
name = "Deobfuscate/Decode Files or Information"
reference = "https://attack.mitre.org/techniques/T1140/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Stage 1: process
process where host.os.type == "linux" and event.type == "start" and
event.action in ("exec", "exec_event", "start") and process.name == "openssl" and
(
(
process.args in ("cms", "smime") and process.args == "-decrypt"
) or
(
process.args == "req" and process.args : "*LinuxTransport*"
)
) and
not process.args like "/var/lib/waagent/*" and
not process.parent.executable like (
"/usr/sbin/waagent",
"/usr/bin/waagent"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | in |
| field:"EventType" kind:in |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | eq |
| field:"process.args" kind:eq |
process.args | in |
| field:"process.args" kind:in |
process.args | wildcard |
| field:"process.args" kind:wildcard value:"*LinuxTransport*" |
process.name | eq |
| field:"process_basename" kind:eq value:"openssl" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | starts_with | /var/lib/waagent/ | excludes:process.args field:"process.args" value:"/var/lib/waagent/" |
process.parent.executable | eq | /usr/sbin/waagent, /usr/bin/waagent | excludes:process.parent.executable field:"process.parent.executable" value:"/usr/sbin/waagent" field:"process.parent.executable" value:"/usr/bin/waagent" |
Delayed Common Language Runtime Load
#Identifies a delayed load of the Microsoft Common Language Runtime DLL CLR.dll associated with egress network connections.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule Body
[rule]
description = """
Identifies a delayed load of the Microsoft Common Language Runtime DLL CLR.dll associated with egress network
connections.
"""
id = "44fa18bd-c484-48f0-84ea-b8fd7d0586aa"
license = "Elastic License v2"
name = "Delayed Common Language Runtime Load"
os_list = ["windows"]
version = "1.0.6"
query = '''
sequence by process.entity_id with maxspan=5s
[network where process.pid != 4 and
event.action in ("disconnect_received", "connection_attempted") and
not cidrmatch(destination.ip, "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24",
"192.0.0.0/29", "192.0.0.8/32", "192.0.0.9/32", "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32",
"192.0.2.0/24", "192.31.196.0/24", "192.52.193.0/24", "192.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") and
not process.executable : ("?:\\Program Files (x86)\\*.exe", "?:\\Program Files\\*.exe", "\\Device\\Mup\\*") and
not (process.code_signature.trusted == true and
process.code_signature.subject_name :
("Flexera Software LLC", "Dassault Systemes SolidWorks Corp.", "Adaptive Protocols, Inc.", "SAP SE", "HP Inc.",
"TechSmith Corporation", "FactSet Research Systems Inc.", "Corel Corporation", "Amazon.com Services LLC", "Commvault Systems, Inc.",
"ONELAUNCH TECHNOLOGIES INC.", "REFINITIV US LLC", "Corel Corporation", "Environmental Systems Research Institute, Inc.",
"Nox Limited", "Therefore Corporation GmbH", "Autodesk, Inc.", "National Instruments Corporation", "Siemens AG",
"The Reynolds and Reynolds Company"))
]
[library where dll.name : ("clr.dll", "mscorwks.dll") and process.uptime >= 1 and
process.thread.Ext.call_stack_summary : "ntdll.dll|*mscoreei.dll*" and
not process.thread.Ext.call_stack_summary :
("*mscoreei.dll|msi*.tmp|msi.dll*",
"*|mscoreei.dll|mscoree.dll*",
"*mscoreei.dll|combase.dll*",
"*pghook.dll|mscoreei.dll|previewview.dll*",
"*mscoreei.dll|microsoft.teams.addinloader.dll*",
"*mscoreei.dll|vstoloader.dll*",
"*mscoreei.dll|onelaunch*.tmp|*",
"*mscoreei.dll|utils.dll|gencls.dll*",
"*mscoreei.dll|revupreviewhandler.dll*",
"*mscoreei.dll|previewview.dll*",
"*mscoreei.dll|twuniclitsprintx64.dll|rdclientax.dll*")]
'''
min_endpoint_version = "8.8.0"
optional_actions = []
reputation = true
[[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.8.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 5s, correlated by process.entity_id.
Stage 1: network
[network where process.pid != 4 and
event.action in ("disconnect_received", "connection_attempted") and
not cidrmatch(destination.ip, "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24",
"192.0.0.0/29", "192.0.0.8/32", "192.0.0.9/32", "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32",
"192.0.2.0/24", "192.31.196.0/24", "192.52.193.0/24", "192.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") and
not process.executable : ("?:\\Program Files (x86)\\*.exe", "?:\\Program Files\\*.exe", "\\Device\\Mup\\*") and
not (process.code_signature.trusted == true and
process.code_signature.subject_name :
("Flexera Software LLC", "Dassault Systemes SolidWorks Corp.", "Adaptive Protocols, Inc.", "SAP SE", "HP Inc.",
"TechSmith Corporation", "FactSet Research Systems Inc.", "Corel Corporation", "Amazon.com Services LLC", "Commvault Systems, Inc.",
"ONELAUNCH TECHNOLOGIES INC.", "REFINITIV US LLC", "Corel Corporation", "Environmental Systems Research Institute, Inc.",
"Nox Limited", "Therefore Corporation GmbH", "Autodesk, Inc.", "National Instruments Corporation", "Siemens AG",
"The Reynolds and Reynolds Company"))
]
Stage 2: library
[library where dll.name : ("clr.dll", "mscorwks.dll") and process.uptime >= 1 and
process.thread.Ext.call_stack_summary : "ntdll.dll|*mscoreei.dll*" and
not process.thread.Ext.call_stack_summary :
("*mscoreei.dll|msi*.tmp|msi.dll*",
"*|mscoreei.dll|mscoree.dll*",
"*mscoreei.dll|combase.dll*",
"*pghook.dll|mscoreei.dll|previewview.dll*",
"*mscoreei.dll|microsoft.teams.addinloader.dll*",
"*mscoreei.dll|vstoloader.dll*",
"*mscoreei.dll|onelaunch*.tmp|*",
"*mscoreei.dll|utils.dll|gencls.dll*",
"*mscoreei.dll|revupreviewhandler.dll*",
"*mscoreei.dll|previewview.dll*",
"*mscoreei.dll|twuniclitsprintx64.dll|rdclientax.dll*")]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
dll.name | wildcard |
| field:"dll.name" kind:wildcard |
event.action | in |
| field:"EventType" kind:in |
process.pid | ne |
| field:"process_id" kind:ne value:"4" |
process.thread.Ext.call_stack_summary | wildcard |
| field:"process.thread.Ext.call_stack_summary" kind:wildcard value:"ntdll.dll|*mscoreei.dll*" |
process.uptime | ge |
| field:"process.uptime" kind:ge value:"1" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.code_signature.subject_name | eq | Flexera Software LLC, Dassault Systemes SolidWorks Corp., Adaptive Protocols, Inc., SAP SE, HP Inc., TechSmith Corporation, FactSet Research Systems Inc., Corel Corporation, Amazon.com Services LLC, Commvault Systems, Inc., ONELAUNCH TECHNOLOGIES INC., REFINITIV US LLC, Corel Corporation, Environmental Systems Research Institute, Inc., Nox Limited, Therefore Corporation GmbH, Autodesk, Inc., National Instruments Corporation, Siemens AG, The Reynolds and Reynolds Company | excludes:process.code_signature.subject_name |
process.code_signature.trusted | eq | true | excludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true" |
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.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 | wildcard | ?:\Program Files (x86)\*.exe, ?:\Program Files\*.exe, \Device\Mup\* | excludes:process.executable field:"process.executable" value:"?:\Program Files (x86)\*.exe" field:"process.executable" value:"?:\Program Files\*.exe" field:"process.executable" value:"\Device\Mup\*" |
process.thread.Ext.call_stack_summary | wildcard | *mscoreei.dll|msi*.tmp|msi.dll*, *|mscoreei.dll|mscoree.dll*, *mscoreei.dll|combase.dll*, *pghook.dll|mscoreei.dll|previewview.dll*, *mscoreei.dll|microsoft.teams.addinloader.dll*, *mscoreei.dll|vstoloader.dll*, *mscoreei.dll|onelaunch*.tmp|*, *mscoreei.dll|utils.dll|gencls.dll*, *mscoreei.dll|revupreviewhandler.dll*, *mscoreei.dll|previewview.dll*, *mscoreei.dll|twuniclitsprintx64.dll|rdclientax.dll* | excludes:process.thread.Ext.call_stack_summary |
Executable File Download via Wget
#Detects executable file downloads via wget to suspicious locations such as /tmp or /Users/Shared. Threat actors commonly use wget to download malicious payloads and additional tools for post-exploitation.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Command & Control |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| macOS | ESF event write (NOTIFY): Fires after a process writes data to a file. |
Rule Body
[metadata]
creation_date = "2026/01/30"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/02/09"
[rule]
author = ["Elastic"]
description = """
Detects executable file downloads via wget to suspicious locations such as /tmp or /Users/Shared. Threat
actors commonly use wget to download malicious payloads and additional tools for post-exploitation.
"""
from = "now-9m"
index = ["logs-endpoint.events.network-*", "logs-endpoint.events.file-*"]
language = "eql"
license = "Elastic License v2"
name = "Executable File Download via Wget"
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 Executable File Download via Wget
This rule detects wget pulling down a Mach-O executable and writing it into commonly abused transient or shared directories on macOS, which often signals payload staging during ingress tool transfer. Attackers frequently run wget from a shell or scripted installer to fetch a second-stage binary into /tmp or /Users/Shared, then immediately execute it to establish command and control or deploy additional tooling.
### Possible investigation steps
- Pivot from the detected wget process to identify its parent process, user context, and full command line to determine whether it was launched by an interactive shell, script, or installer package.
- Review the network connection details from the wget execution (remote IP/domain, URL path, TLS certificate/SNI if available) and assess reputation plus whether it aligns with known internal software distribution.
- Inspect the downloaded Mach-O at the destination path by collecting its hash, signature/notarization status, and basic static traits (strings, embedded URLs, ad-hoc signing) to quickly judge legitimacy.
- Check for immediate follow-on activity from the same host such as execution of the new file, creation of persistence (LaunchAgents/Daemons, cron, login items), or additional tool downloads within the next few minutes.
- Scope for reuse by searching across endpoints for the same downloaded hash, filename, URL, or destination directory pattern to determine blast radius and whether this is a recurring delivery mechanism.
### False positive analysis
- An administrator or developer uses wget in a script to fetch an internal build or test Mach-O binary and stages it in /tmp or /Users/Shared for immediate execution during troubleshooting or CI-style workflows.
- A legitimate installation or update routine invokes wget to download a helper executable to a transient directory (for unpacking or preflight checks) before moving it into an application bundle, causing a short-lived write to /tmp-like paths.
### Response and remediation
- Isolate the affected macOS host from the network and terminate the active `wget` process to stop additional payload transfers or execution.
- Quarantine the downloaded Mach-O from `/tmp`, `/private/tmp`, `/var/tmp`, or `/Users/Shared` and preserve a copy plus the originating `wget` command/URL for analysis before removal.
- Hunt on the host for immediate follow-on execution of the downloaded file and remove any persistence artifacts created around the same time, such as new LaunchAgents/LaunchDaemons, login items, or cron entries pointing to the staged path.
- Block the observed download URL/domain/IP at egress controls and add allowlisting controls for approved internal distribution sources to reduce future misuse of `wget` for tool transfer.
- Escalate to incident response if the staged Mach-O is executed, unsigned/ad-hoc signed, establishes outbound connections to unapproved infrastructure, or the same hash/URL is found on multiple endpoints.
- Harden endpoints by restricting `wget` usage where possible, enforcing Gatekeeper/notarization and least-privilege execution, and adding monitoring/controls for executable writes and executions from world-writable directories.
"""
references = [
"https://attack.mitre.org/techniques/T1105/"
]
risk_score = 47
rule_id = "36755b43-a1f9-4f2c-9b61-6b240dd0e164"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: macOS",
"Use Case: Threat Detection",
"Tactic: Command and Control",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
type = "eql"
query = '''
sequence by process.entity_id with maxspan=30s
[network where host.os.type == "macos" and event.type == "start" and process.name == "wget"]
[file where host.os.type == "macos" and event.action == "modification" and
process.name == "wget" and
file.path like ("/tmp/*", "/private/tmp/*", "/private/var/tmp/*", "/var/tmp/*", "/Users/Shared/*") and
file.Ext.header_bytes like~ ("cffaedfe*", "cafebabe*")]
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[rule.threat.tactic]
name = "Command and Control"
id = "TA0011"
reference = "https://attack.mitre.org/tactics/TA0011/"
[[rule.threat.technique]]
name = "Ingress Tool Transfer"
id = "T1105"
reference = "https://attack.mitre.org/techniques/T1105/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[rule.threat.tactic]
name = "Execution"
id = "TA0002"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat.technique]]
name = "User Execution"
id = "T1204"
reference = "https://attack.mitre.org/techniques/T1204/"
[[rule.threat.technique.subtechnique]]
name = "Malicious File"
id = "T1204.002"
reference = "https://attack.mitre.org/techniques/T1204/002/"
Stages and Predicates
Ordered sequence: each step below must occur in order within 30s, correlated by process.entity_id.
Stage 1: network
[network where host.os.type == "macos" and event.type == "start" and process.name == "wget"]
Stage 2: file
[file where host.os.type == "macos" and event.action == "modification" and
process.name == "wget" and
file.path like ("/tmp/*", "/private/tmp/*", "/private/var/tmp/*", "/var/tmp/*", "/Users/Shared/*") and
file.Ext.header_bytes like~ ("cffaedfe*", "cafebabe*")]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"modification" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
file.Ext.header_bytes | wildcard |
| field:"file.Ext.header_bytes" kind:wildcard |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard |
process.name | eq |
| field:"process_basename" kind:eq value:"wget" |
Execution via WMI ActiveScript Event Consumer
#Identifies the creation or execution of a Windows script via a Windows Management Instrumentation Script consumer. The ActiveScriptEventConsumer class runs a predefined script in an arbitrary scripting language when an event is delivered to it. This is a legit feature but rarely used and can be a sign of execution or persistence via a malicious WMI Script consumer.
MITRE ATT&CK Coverage
Rule Body
[rule]
description = """
Identifies the creation or execution of a Windows script via a Windows Management Instrumentation Script consumer. The
ActiveScriptEventConsumer class runs a predefined script in an arbitrary scripting language when an event is delivered
to it. This is a legit feature but rarely used and can be a sign of execution or persistence via a malicious WMI Script
consumer.
"""
id = "396f3062-05ba-4594-b83e-9bd6597f0e5e"
license = "Elastic License v2"
name = "Execution via WMI ActiveScript Event Consumer"
os_list = ["windows"]
reference = [
"https://threathunterplaybook.com/hunts/windows/200902-RemoteWMIActiveScriptEventConsumers/notebook.html",
"https://learn.microsoft.com/en-us/windows/win32/wmisdk/activescripteventconsumer",
]
version = "1.0.12"
query = '''
process where event.action == "start" and
(
process.parent.executable : "?:\\Windows\\Sys*\\wbem\\scrcons.exe" or
descendant of [process where event.action == "start" and process.executable : "?:\\Windows\\Sys*\\wbem\\scrcons.exe"] or
(process.pe.original_file_name : "wmic.exe" and process.command_line : "*create*" and process.command_line : "*ActiveScriptEventConsumer*")
) and
not (process.executable : "?:\\Windows\\System32\\wscript.exe" and
user.id : "S-1-5-18" and process.args : "?:\\Windows\\System32\\sleeper.vbs") and
not process.executable :
("?:\\Program Files\\*.exe",
"?:\\Program Files (x86)\\*.exe",
"?:\\Windows\\System32\\gpupdate.exe",
"?:\\Windows\\Microsoft.NET\\Framework64\\v*\\ngen.exe",
"?:\\Windows\\Microsoft.NET\\Framework64\\v*\\ngentask.exe") and
not (process.executable : "?:\\Windows\\System32\\schtasks.exe" and
process.args : "\"C:\\Program Files\\Adobe\\Adobe Creative Cloud Experience\\CCXProcess.exe\"") and
not (process.executable : "?:\\Windows\\System32\\omadmprc.exe" and user.id : "S-1-5-18") and process.parent.executable != null and
not (process.executable : "?:\\Windows\\system32\\conhost.exe" and process.args : "0xffffffff" and process.args : "-ForceV1") and
not process.hash.sha256 :
("4620eaed30bea5f44b2655df1592f2d3cfc45042f513876090c30153a3e23815",
"0e9a6b9d0481a0f9aa49e6f53bc87414ecb84a6d45ef301f6abfde07a8e894a4",
"0f635ffad292ec796dec18cafe896f09168ad2cdefec4fc8530a6a538db21e54",
"d13f5e3d679ffb5787eb0227741cf3e3e3b476a831742e086c1aebea15acf735",
"ac3e1f40ce7bb7e31f9f2804fdc495ac566c5c072d850c66525926ca18fa7a27",
"5c9382277658a46d9918c81b760b0e7caea3639266bcdda68413ac63f9ad6f68") and
not process.parent.executable :
("?:\\Program Files\\Adobe\\Adobe Creative Cloud Experience\\libs\\node.exe",
"?:\\Program Files (x86)\\Google\\GoogleUpdater\\*\\updater.exe")
'''
min_endpoint_version = "7.16.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1047"
name = "Windows Management Instrumentation"
reference = "https://attack.mitre.org/techniques/T1047/"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.005"
name = "Visual Basic"
reference = "https://attack.mitre.org/techniques/T1059/005/"
[[threat.technique.subtechnique]]
id = "T1059.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[internal]
min_endpoint_version = "7.16.0"
Stages and Predicates
Stage 1: process
process where event.action == "start" and
(
process.parent.executable : "?:\\Windows\\Sys*\\wbem\\scrcons.exe" or
descendant of [process where event.action == "start" and process.executable : "?:\\Windows\\Sys*\\wbem\\scrcons.exe"] or
(process.pe.original_file_name : "wmic.exe" and process.command_line : "*create*" and process.command_line : "*ActiveScriptEventConsumer*")
) and
not (process.executable : "?:\\Windows\\System32\\wscript.exe" and
user.id : "S-1-5-18" and process.args : "?:\\Windows\\System32\\sleeper.vbs") and
not process.executable :
("?:\\Program Files\\*.exe",
"?:\\Program Files (x86)\\*.exe",
"?:\\Windows\\System32\\gpupdate.exe",
"?:\\Windows\\Microsoft.NET\\Framework64\\v*\\ngen.exe",
"?:\\Windows\\Microsoft.NET\\Framework64\\v*\\ngentask.exe") and
not (process.executable : "?:\\Windows\\System32\\schtasks.exe" and
process.args : "\"C:\\Program Files\\Adobe\\Adobe Creative Cloud Experience\\CCXProcess.exe\"") and
not (process.executable : "?:\\Windows\\System32\\omadmprc.exe" and user.id : "S-1-5-18") and process.parent.executable != null and
not (process.executable : "?:\\Windows\\system32\\conhost.exe" and process.args : "0xffffffff" and process.args : "-ForceV1") and
not process.hash.sha256 :
("4620eaed30bea5f44b2655df1592f2d3cfc45042f513876090c30153a3e23815",
"0e9a6b9d0481a0f9aa49e6f53bc87414ecb84a6d45ef301f6abfde07a8e894a4",
"0f635ffad292ec796dec18cafe896f09168ad2cdefec4fc8530a6a538db21e54",
"d13f5e3d679ffb5787eb0227741cf3e3e3b476a831742e086c1aebea15acf735",
"ac3e1f40ce7bb7e31f9f2804fdc495ac566c5c072d850c66525926ca18fa7a27",
"5c9382277658a46d9918c81b760b0e7caea3639266bcdda68413ac63f9ad6f68") and
not process.parent.executable :
("?:\\Program Files\\Adobe\\Adobe Creative Cloud Experience\\libs\\node.exe",
"?:\\Program Files (x86)\\Google\\GoogleUpdater\\*\\updater.exe")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard |
process.parent.executable | is_not_null | field:"ParentImage" kind:is_not_null | |
process.parent.executable | wildcard |
| field:"ParentImage" kind:wildcard value:"?:\Windows\Sys*\wbem\scrcons.exe" |
process.pe.original_file_name | wildcard |
| field:"OriginalFileName" kind:wildcard value:"wmic.exe" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | eq | -ForceV1 | excludes:process.args field:"process.args" value:"-ForceV1" |
process.args | eq | 0xffffffff | excludes:process.args field:"process.args" value:"0xffffffff" |
process.executable | eq | ?:\Windows\system32\conhost.exe | excludes:process.executable field:"process.executable" value:"?:\Windows\system32\conhost.exe" |
process.args | eq | ?:\Windows\System32\sleeper.vbs | excludes:process.args field:"process.args" value:"?:\Windows\System32\sleeper.vbs" |
process.executable | eq | ?:\Windows\System32\wscript.exe | excludes:process.executable field:"process.executable" value:"?:\Windows\System32\wscript.exe" |
user.id | eq | S-1-5-18 | excludes:user.id field:"user.id" value:"S-1-5-18" |
process.args | eq | "C:\Program Files\Adobe\Adobe Creative Cloud Experience\CCXProcess.exe" | excludes:process.args |
process.executable | eq | ?:\Windows\System32\schtasks.exe | excludes:process.executable field:"process.executable" value:"?:\Windows\System32\schtasks.exe" |
process.executable | eq | ?:\Windows\System32\omadmprc.exe | excludes:process.executable field:"process.executable" value:"?:\Windows\System32\omadmprc.exe" |
process.executable | wildcard | ?:\Program Files\*.exe, ?:\Program Files (x86)\*.exe, ?:\Windows\System32\gpupdate.exe, ?:\Windows\Microsoft.NET\Framework64\v*\ngen.exe, ?:\Windows\Microsoft.NET\Framework64\v*\ngentask.exe | excludes:process.executable |
process.hash.sha256 | eq | 4620eaed30bea5f44b2655df1592f2d3cfc45042f513876090c30153a3e23815, 0e9a6b9d0481a0f9aa49e6f53bc87414ecb84a6d45ef301f6abfde07a8e894a4, 0f635ffad292ec796dec18cafe896f09168ad2cdefec4fc8530a6a538db21e54, d13f5e3d679ffb5787eb0227741cf3e3e3b476a831742e086c1aebea15acf735, ac3e1f40ce7bb7e31f9f2804fdc495ac566c5c072d850c66525926ca18fa7a27, 5c9382277658a46d9918c81b760b0e7caea3639266bcdda68413ac63f9ad6f68 | excludes:process.hash.sha256 |
process.parent.executable | wildcard | ?:\Program Files\Adobe\Adobe Creative Cloud Experience\libs\node.exe, ?:\Program Files (x86)\Google\GoogleUpdater\*\updater.exe | excludes:process.parent.executable field:"process.parent.executable" value:"?:\Program Files\Adobe\Adobe Creative Cloud Experience\libs\node.exe" field:"process.parent.executable" value:"?:\Program Files (x86)\Google\GoogleUpdater\*\updater.exe" |
File Transfer or Listener Established via Netcat
#A netcat process is engaging in network activity on a Linux host. Netcat is often used as a persistence mechanism by exporting a reverse shell or by serving a shell on a listening port. Netcat is also sometimes used for data exfiltration.
Known False Positives
- Netcat is a dual-use tool that can be used for benign or malicious activity. Netcat is included in some Linux distributions so its presence is not necessarily suspicious. Some normal use of this program, while uncommon, may originate from scripts, automation tools, and frameworks.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Command & Control | |
| Exfiltration |
Rule Body
[metadata]
creation_date = "2020/02/18"
integration = ["endpoint", "auditd_manager", "crowdstrike", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
A netcat process is engaging in network activity on a Linux host. Netcat is often used as a persistence mechanism by
exporting a reverse shell or by serving a shell on a listening port. Netcat is also sometimes used for data
exfiltration.
"""
false_positives = [
"""
Netcat is a dual-use tool that can be used for benign or malicious activity. Netcat is included in some Linux
distributions so its presence is not necessarily suspicious. Some normal use of this program, while uncommon, may
originate from scripts, automation tools, and frameworks.
""",
]
from = "now-9m"
index = [
"auditbeat-*",
"endgame-*",
"logs-auditd_manager.auditd-*",
"logs-crowdstrike.fdr*",
"logs-endpoint.events.process*",
"logs-sentinel_one_cloud_funnel.*",
]
language = "eql"
license = "Elastic License v2"
name = "File Transfer or Listener Established via Netcat"
note = """## Triage and analysis
### Investigating File Transfer or Listener Established via Netcat
Netcat is a dual-use command line tool that can be used for various purposes, such as port scanning, file transfers, and connection tests. Attackers can abuse its functionality for malicious purposes such creating bind shells or reverse shells to gain access to the target system.
A reverse shell is a mechanism that's abused to connect back to an attacker-controlled system. It effectively redirects the system's input and output and delivers a fully functional remote shell to the attacker. Even private systems are vulnerable since the connection is outgoing.
A bind shell is a type of backdoor that attackers set up on the target host and binds to a specific port to listen for an incoming connection from the attacker.
This rule identifies potential reverse shell or bind shell activity using Netcat by checking for the execution of Netcat followed by a network connection.
#### Possible investigation steps
- Examine the command line to identify if the command is suspicious.
- Extract and examine the target domain or IP address.
- Check if the domain is newly registered or unexpected.
- Check the reputation of the domain or IP address.
- Scope other potentially compromised hosts in your environment by mapping hosts that also communicated with the domain or IP address.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Investigate any abnormal account behavior, such as command executions, file creations or modifications, and network connections.
- Investigate any abnormal behavior by the subject process such as network connections, file modifications, and any spawned child processes.
### False positive analysis
- Netcat is a dual-use tool that can be used for benign or malicious activity. It is included in some Linux distributions, so its presence is not necessarily suspicious. Some normal use of this program, while uncommon, may originate from scripts, automation tools, and frameworks.
### Response and remediation
- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Block the identified indicators of compromise (IoCs).
- Take actions to terminate processes and connections used by the attacker.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
references = [
"http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet",
"https://www.sans.org/security-resources/sec560/netcat_cheat_sheet_v1.pdf",
"https://en.wikipedia.org/wiki/Netcat",
"https://www.hackers-arise.com/hacking-fundamentals",
"https://null-byte.wonderhowto.com/how-to/hack-like-pro-use-netcat-swiss-army-knife-hacking-tools-0148657/",
"https://levelup.gitconnected.com/ethical-hacking-part-15-netcat-nc-and-netcat-f6a8f7df43fd",
]
risk_score = 47
rule_id = "adb961e0-cb74-42a0-af9e-29fc41f88f5f"
setup = """## Setup
This rule requires data coming in from one of the following integrations:
- Elastic Defend
- Auditbeat
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
### Auditbeat Setup
Auditbeat is a lightweight shipper that you can install on your servers to audit the activities of users and processes on your systems. For example, you can use Auditbeat to collect and centralize audit events from the Linux Audit Framework. You can also use Auditbeat to detect changes to critical files, like binaries and configuration files, and identify potential security policy violations.
#### The following steps should be executed in order to add the Auditbeat on a Linux System:
- Elastic provides repositories available for APT and YUM-based distributions. Note that we provide binary packages, but no source packages.
- To install the APT and YUM repositories follow the setup instructions in this [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/setup-repositories.html).
- To run Auditbeat on Docker follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/running-on-docker.html).
- To run Auditbeat on Kubernetes follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/running-on-kubernetes.html).
- For complete “Setup and Run Auditbeat” information refer to the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/setting-up-and-running.html).
"""
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Execution",
"Resources: Investigation Guide",
"Data Source: Elastic Defend",
"Data Source: Elastic Endgame",
"Data Source: Auditd Manager",
"Data Source: Crowdstrike",
"Data Source: SentinelOne",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "linux" and event.type == "start" and
event.action in ("exec", "exec_event", "start", "ProcessRollup2", "executed", "process_started") and
process.name in ("nc","ncat","netcat","netcat.openbsd","netcat.traditional") and
process.args like~ (
/* bind shell to specific port or listener */
"-*l*","-*p*",
/* reverse shell to command-line interpreter used for command execution */
"-*e*",
/* file transfer via stdout/pipe */
">","<", "|"
)
'''
[[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 = "T1095"
name = "Non-Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1095/"
[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 = "T1048"
name = "Exfiltration Over Alternative Protocol"
reference = "https://attack.mitre.org/techniques/T1048/"
[[rule.threat.technique.subtechnique]]
id = "T1048.003"
name = "Exfiltration Over Unencrypted Non-C2 Protocol"
reference = "https://attack.mitre.org/techniques/T1048/003/"
[rule.threat.tactic]
id = "TA0010"
name = "Exfiltration"
reference = "https://attack.mitre.org/tactics/TA0010/"
Stages and Predicates
Stage 1: process
process where host.os.type == "linux" and event.type == "start" and
event.action in ("exec", "exec_event", "start", "ProcessRollup2", "executed", "process_started") and
process.name in ("nc","ncat","netcat","netcat.openbsd","netcat.traditional") and
process.args like~ (
"-*l*","-*p*",
"-*e*",
">","<", "|"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | in |
| field:"EventType" kind:in |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.name | in |
| field:"process_basename" kind:in |
First Time Python Created a LaunchAgent or LaunchDaemon
#Detects the first time a Python process creates or modifies a LaunchAgent or LaunchDaemon plist file on a given host. Malicious Python scripts, compromised dependencies, or model file deserialization can establish persistence on macOS by writing plist files to LaunchAgent or LaunchDaemon directories. Legitimate Python processes do not typically create persistence mechanisms, so a first occurrence is a strong indicator of compromise.
MITRE ATT&CK Coverage
Rule Body
[metadata]
creation_date = "2026/02/23"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/04/08"
[rule]
author = ["Elastic"]
description = """
Detects the first time a Python process creates or modifies a LaunchAgent or LaunchDaemon plist file on a given host.
Malicious Python scripts, compromised dependencies, or model file deserialization can establish persistence on macOS by
writing plist files to LaunchAgent or LaunchDaemon directories. Legitimate Python processes do not typically create
persistence mechanisms, so a first occurrence is a strong indicator of compromise.
"""
from = "now-9m"
index = ["logs-endpoint.events.file-*"]
language = "kuery"
license = "Elastic License v2"
name = "First Time Python Created a LaunchAgent or LaunchDaemon"
note = """## Triage and analysis
### Investigating First Time Python Created a LaunchAgent or LaunchDaemon
macOS LaunchAgents and LaunchDaemons are plist files that configure programs to run automatically at login or boot. Attackers who achieve Python code execution — whether through malicious scripts, compromised dependencies, or model file deserialization (e.g., pickle/PyTorch `__reduce__`) — can drop plist files to establish persistence on the compromised host. This ensures their payload survives reboots and user logouts.
This rule uses the Elastic Defend persistence event type (`event.action:"launch_daemon"`), which captures plist metadata including the program arguments, run-at-load configuration, and keep-alive settings. The New Terms rule type alerts on the first time a Python process creates a LaunchAgent or LaunchDaemon on a given host within a 7-day window.
### Possible investigation steps
- Review the persistence event fields (`Persistence.runatload`, `Persistence.keepalive`, `Persistence.args`, `Persistence.path`) to understand the plist configuration.
- Examine the program path and arguments specified in the plist to determine if they reference a known legitimate application or a suspicious binary.
- Determine if the Python process was loading a model file (look for `torch.load`, `pickle.load`), running a standalone script, or executing via a compromised dependency.
- Verify if the target binary referenced in the plist exists on disk and whether it is signed or trusted.
- Investigate the origin of any recently downloaded scripts, packages, or model files on the host.
- Check for other persistence mechanisms that may have been established around the same time.
### False positive analysis
- Some Python-based system management tools (e.g., Ansible, SaltStack) may legitimately create LaunchAgent or LaunchDaemon plist files. Evaluate whether the activity matches a known automation workflow.
- Python-based application installers may create plist files during setup. Check if the activity correlates with a known software installation.
### Response and remediation
- Immediately unload the suspicious LaunchAgent or LaunchDaemon using `launchctl unload` with the plist path.
- Remove the suspicious plist file and any associated binary it references.
- Kill any processes launched by the plist file.
- Investigate and quarantine the Python script, package, or model file that created the persistence mechanism.
- Scan the host for additional indicators of compromise.
- If a malicious file is confirmed, identify all hosts where it may have been distributed.
"""
references = [
"https://blog.trailofbits.com/2024/06/11/exploiting-ml-models-with-pickle-file-attacks-part-1/",
"https://github.com/trailofbits/fickling",
]
risk_score = 47
rule_id = "25368123-b7b8-4344-9fd4-df28051b4c6e"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: macOS",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
"Domain: LLM",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
host.os.type:macos and event.action:"launch_daemon" and
process.name:python*
'''
[[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.001"
name = "Launch Agent"
reference = "https://attack.mitre.org/techniques/T1543/001/"
[[rule.threat.technique.subtechnique]]
id = "T1543.004"
name = "Launch Daemon"
reference = "https://attack.mitre.org/techniques/T1543/004/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[rule.new_terms]
field = "new_terms_fields"
value = ["host.id", "file.path"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-7d"
Stages and Predicates
Stage 1: new_terms
host.os.type:macos and event.action:"launch_daemon" and
process.name:python*
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"launch_daemon" |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:"python*" |
GCP Virtual Private Cloud Network Deletion
#Identifies when a Virtual Private Cloud (VPC) network is deleted in Google Cloud Platform (GCP). A VPC network is a virtual version of a physical network within a GCP project. Each VPC network has its own subnets, routes, and firewall, as well as other elements. An adversary may delete a VPC network in order to disrupt their target's network and business operations.
Known False Positives
- Virtual Private Cloud networks may be deleted by system administrators. Verify that the configuration change was expected. Exceptions can be added to this rule to filter expected behavior.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment | |
| Impact |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| GCP | compute.networks.delete: Delete network |
Rule Body
[metadata]
creation_date = "2020/09/22"
integration = ["gcp"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
Identifies when a Virtual Private Cloud (VPC) network is deleted in Google Cloud Platform (GCP). A VPC network is a
virtual version of a physical network within a GCP project. Each VPC network has its own subnets, routes, and firewall,
as well as other elements. An adversary may delete a VPC network in order to disrupt their target's network and business
operations.
"""
false_positives = [
"""
Virtual Private Cloud networks may be deleted by system administrators. Verify that the configuration change was
expected. Exceptions can be added to this rule to filter expected behavior.
""",
]
index = ["filebeat-*", "logs-gcp*"]
language = "kuery"
license = "Elastic License v2"
name = "GCP Virtual Private Cloud Network Deletion"
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating GCP Virtual Private Cloud Network Deletion
Google Cloud Platform's Virtual Private Cloud (VPC) networks are essential for managing isolated network environments within a project, encompassing subnets, routes, and firewalls. Adversaries may target VPC deletions to disrupt operations and evade defenses. The detection rule monitors audit logs for successful VPC deletions, flagging potential malicious activity by correlating specific event actions and outcomes.
### Possible investigation steps
- Review the audit logs for the specific event.action value "v*.compute.networks.delete" to identify the exact time and user account associated with the VPC network deletion.
- Check the event.outcome field to confirm the success of the deletion and correlate it with any other suspicious activities around the same timeframe.
- Investigate the user account or service account that performed the deletion to determine if it was authorized and if there are any signs of compromise or misuse.
- Examine the project and network configurations to assess the impact of the VPC deletion on the organization's operations and identify any critical resources that were affected.
- Look for any recent changes in IAM roles or permissions that might have allowed unauthorized users to delete the VPC network.
- Cross-reference the deletion event with other security alerts or incidents to identify potential patterns or coordinated attacks.
### False positive analysis
- Routine maintenance activities may involve the deletion of VPC networks as part of infrastructure updates or reconfigurations. To manage this, create exceptions for known maintenance windows or specific user accounts responsible for these tasks.
- Automated scripts or tools used for environment cleanup might trigger false positives if they delete VPC networks as part of their operation. Identify these scripts and exclude their actions from triggering alerts by using specific service accounts or tags associated with these tools.
- Development and testing environments often undergo frequent changes, including VPC deletions. Consider excluding these environments from alerts by filtering based on project IDs or environment tags to reduce noise.
- Organizational policy changes might lead to the intentional deletion of VPC networks. Ensure that such policy-driven actions are documented and that the responsible teams are excluded from triggering alerts by using role-based access controls or specific user identifiers.
### Response and remediation
- Immediately isolate the affected project by restricting network access to prevent further unauthorized deletions or modifications.
- Review the audit logs to identify the source of the deletion request, including the user account and IP address, and verify if it was authorized.
- Recreate the deleted VPC network using the latest backup or configuration snapshot to restore network operations and minimize downtime.
- Implement additional access controls, such as multi-factor authentication and least privilege principles, to prevent unauthorized access to VPC management.
- Notify the security team and relevant stakeholders about the incident for awareness and further investigation.
- Escalate the incident to Google Cloud Platform support if necessary, especially if there are indications of a broader compromise or if assistance is needed in recovery.
- Enhance monitoring and alerting for VPC-related activities to detect and respond to similar threats more effectively in the future.
## Setup
The GCP Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
references = ["https://cloud.google.com/vpc/docs/vpc"]
risk_score = 47
rule_id = "c58c3081-2e1d-4497-8491-e73a45d1a6d6"
severity = "medium"
tags = [
"Domain: Cloud",
"Data Source: GCP",
"Data Source: Google Cloud Platform",
"Use Case: Configuration Audit",
"Tactic: Defense Evasion",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:gcp.audit and event.action:v*.compute.networks.delete and event.outcome:success
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[[rule.threat.technique.subtechnique]]
id = "T1562.007"
name = "Disable or Modify Cloud Firewall"
reference = "https://attack.mitre.org/techniques/T1562/007/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1485"
name = "Data Destruction"
reference = "https://attack.mitre.org/techniques/T1485/"
[rule.threat.tactic]
id = "TA0040"
name = "Impact"
reference = "https://attack.mitre.org/tactics/TA0040/"
Stages and Predicates
Stage 1: query
data_stream.dataset:gcp.audit and event.action:v*.compute.networks.delete and event.outcome:success
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"gcp.audit" |
event.action | wildcard |
| field:"EventType" kind:wildcard value:"v*.compute.networks.delete" |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"success" |
GKE Pod Created With HostIPC
#Detects GKE pod create, update, or patch events that enable host IPC namespace sharing. This exposes host inter-process communication mechanisms and can support privilege escalation. Controller-owned workloads are excluded.
Known False Positives
- Administrators may enable hostIPC for legitimate debugging. Exclude trusted users or namespaces after baselining.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Privilege Escalation |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Kubernetes | create-pods: create pods |
| Kubernetes | update-pods: update pods |
| Kubernetes | patch-pods: patch pods |
Rules Detecting the Same Action
These rules filter on the same operation.
- Azure AKS Attempted User Exec into Pod (Elastic)
- Azure AKS Ephemeral Container Added to Pod (Elastic)
- Container With A hostPath Mount Created (Sigma)
- Creation Of Pod In System Namespace (Sigma)
- Direct Interactive Kubernetes API Request by Unusual Utilities (Elastic)
- Exec into Pod (Panther)
- GCP Break-glass Container Workload Deployed (Sigma)
- GCP K8s Pod Attached To Node Host Network (Panther)
Rule Body
[metadata]
creation_date = "2026/06/30"
integration = ["gcp"]
maturity = "production"
updated_date = "2026/06/30"
[rule]
author = ["Elastic"]
description = """
Detects GKE pod create, update, or patch events that enable host IPC namespace sharing. This exposes host inter-process
communication mechanisms and can support privilege escalation. Controller-owned workloads are excluded.
"""
false_positives = [
"""
Administrators may enable hostIPC for legitimate debugging. Exclude trusted users or namespaces after baselining.
""",
]
index = ["logs-gcp.audit-*"]
language = "kuery"
license = "Elastic License v2"
name = "GKE Pod Created With HostIPC"
note = """## Triage and analysis
### Investigating GKE Pod Created With HostIPC
Host IPC lets a pod interact with host IPC facilities. Review the pod spec, actor, and whether the change was expected.
### Investigation steps
- Confirm `gcp.audit.request.spec.hostIPC` and targeted namespace or pod.
- Review `user.email` and correlate with other risky pod modifications.
### False positives
- Break-glass debugging on nodes; allowlist known admin identities.
## Setup
The GCP Fleet integration with GKE audit logs enabled is required to be compatible with this rule."""
references = [
"https://kubernetes.io/docs/concepts/security/pod-security-standards/",
"https://bishopfox.com/blog/kubernetes-pod-privilege-escalation",
]
risk_score = 47
rule_id = "fde4efad-9cd0-4fa4-84c8-0e3b6fc957b4"
severity = "medium"
tags = [
"Domain: Cloud",
"Domain: Kubernetes",
"Data Source: GCP",
"Data Source: Google Cloud Platform",
"Use Case: Threat Detection",
"Tactic: Privilege Escalation",
"Tactic: Execution",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:gcp.audit and event.outcome:success and
event.action:("io.k8s.core.v1.pods.create" or "io.k8s.core.v1.pods.update" or "io.k8s.core.v1.pods.patch") and
gcp.audit.request.spec.hostIPC:true and
not gcp.audit.request.metadata.ownerReferences.kind:("ReplicaSet" or "DaemonSet" or "StatefulSet")
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1611"
name = "Escape to Host"
reference = "https://attack.mitre.org/techniques/T1611/"
[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1610"
name = "Deploy Container"
reference = "https://attack.mitre.org/techniques/T1610/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
Stages and Predicates
Stage 1: query
data_stream.dataset:gcp.audit and event.outcome:success and
event.action:("io.k8s.core.v1.pods.create" or "io.k8s.core.v1.pods.update" or "io.k8s.core.v1.pods.patch") and
gcp.audit.request.spec.hostIPC:true and
not gcp.audit.request.metadata.ownerReferences.kind:("ReplicaSet" or "DaemonSet" or "StatefulSet")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"gcp.audit" |
event.action | in |
| field:"EventType" kind:in |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"success" |
gcp.audit.request.spec.hostIPC | eq |
| field:"gcp.audit.request.spec.hostIPC" kind:eq value:"true" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
gcp.audit.request.metadata.ownerReferences.kind | in | DaemonSet, ReplicaSet, StatefulSet | excludes:gcp.audit.request.metadata.ownerReferences.kind field:"gcp.audit.request.metadata.ownerReferences.kind" value:"DaemonSet" field:"gcp.audit.request.metadata.ownerReferences.kind" value:"ReplicaSet" field:"gcp.audit.request.metadata.ownerReferences.kind" value:"StatefulSet" |
Linux Process Hooking via GDB
#This rule monitors for potential memory dumping through gdb. Attackers may leverage memory dumping techniques to attempt secret extraction from privileged processes. Tools that display this behavior include "truffleproc" and "bash-memory-dump". This behavior should not happen by default, and should be investigated thoroughly.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth | |
| Credential Access |
Rule Body
[metadata]
creation_date = "2023/08/30"
integration = ["endpoint", "auditd_manager", "crowdstrike", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
This rule monitors for potential memory dumping through gdb. Attackers may leverage memory dumping techniques to attempt
secret extraction from privileged processes. Tools that display this behavior include "truffleproc" and
"bash-memory-dump". This behavior should not happen by default, and should be investigated thoroughly.
"""
from = "now-9m"
index = [
"auditbeat-*",
"endgame-*",
"logs-auditd_manager.auditd-*",
"logs-crowdstrike.fdr*",
"logs-endpoint.events.process*",
"logs-sentinel_one_cloud_funnel.*",
]
language = "eql"
license = "Elastic License v2"
name = "Linux Process Hooking via GDB"
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 Linux Process Hooking via GDB
GDB, the GNU Debugger, is a powerful tool used for debugging applications by inspecting their memory and execution flow. Adversaries can exploit GDB to attach to running processes, potentially extracting sensitive information like credentials. The detection rule identifies suspicious use of GDB by monitoring process initiation with specific arguments, flagging potential unauthorized memory access attempts for further investigation.
### Possible investigation steps
- Review the process details to confirm the presence of GDB by checking if the process name is "gdb" and the arguments include "--pid" or "-p".
- Identify the target process that GDB is attempting to attach to by examining the process arguments and cross-referencing the process ID.
- Investigate the user account under which the GDB process is running to determine if it is authorized to perform debugging tasks on the target process.
- Check the system logs and audit logs for any unusual activity or prior attempts to access sensitive processes or data around the time the GDB process was initiated.
- Correlate the event with other security alerts or anomalies in the environment to assess if this is part of a broader attack pattern or isolated incident.
- Evaluate the necessity and legitimacy of the GDB usage in the context of the system's normal operations and the user's role.
- If unauthorized access is suspected, consider isolating the affected system and conducting a deeper forensic analysis to prevent potential data exfiltration.
### False positive analysis
- Development and debugging activities may trigger the rule when developers use GDB for legitimate purposes. To manage this, create exceptions for specific user accounts or development environments where GDB usage is expected.
- Automated scripts or maintenance tasks that utilize GDB for process inspection can also cause false positives. Identify these scripts and exclude their execution paths or associated user accounts from the rule.
- Security tools or monitoring solutions that use GDB for legitimate process analysis might be flagged. Verify these tools and whitelist their processes or execution contexts to prevent unnecessary alerts.
- Training or educational environments where GDB is used for learning purposes can lead to false positives. Consider excluding these environments or specific user groups from the rule to avoid interference with educational activities.
### Response and remediation
- Immediately isolate the affected system from the network to prevent further unauthorized access or data exfiltration.
- Terminate the GDB process if it is confirmed to be unauthorized, using process management tools to stop the process safely.
- Conduct a memory dump analysis of the affected system to identify any potential data leakage or extraction of sensitive information.
- Review system logs and audit trails to identify any additional unauthorized access attempts or related suspicious activities.
- Change credentials for any accounts that may have been exposed or accessed during the incident to prevent unauthorized use.
- Implement stricter access controls and monitoring for systems that handle sensitive information to prevent similar incidents.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if additional systems are affected."""
references = ["https://github.com/controlplaneio/truffleproc", "https://github.com/hajzer/bash-memory-dump"]
risk_score = 21
rule_id = "66c058f3-99f4-4d18-952b-43348f2577a0"
severity = "low"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Credential Access",
"Data Source: Elastic Defend",
"Data Source: Elastic Endgame",
"Data Source: Auditd Manager",
"Data Source: Crowdstrike",
"Data Source: SentinelOne",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "exec_event", "start", "ProcessRollup2", "executed", "process_started")
and process.name == "gdb" and process.args in ("--pid", "-p") and
/* Covered by d4ff2f53-c802-4d2e-9fb9-9ecc08356c3f */
process.args != "1"
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1003"
name = "OS Credential Dumping"
reference = "https://attack.mitre.org/techniques/T1003/"
[[rule.threat.technique.subtechnique]]
id = "T1003.007"
name = "Proc Filesystem"
reference = "https://attack.mitre.org/techniques/T1003/007/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"
[[rule.threat.technique.subtechnique]]
id = "T1055.008"
name = "Ptrace System Calls"
reference = "https://attack.mitre.org/techniques/T1055/008/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Stage 1: process
process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "exec_event", "start", "ProcessRollup2", "executed", "process_started")
and process.name == "gdb" and process.args in ("--pid", "-p") and
process.args != "1"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | in |
| field:"EventType" kind:in |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | in |
| field:"process.args" kind:in |
process.args | ne |
| field:"process.args" kind:ne value:"1" |
process.name | eq |
| field:"process_basename" kind:eq value:"gdb" |
Newly Observed High Severity Suricata Alert
#This rule detects Suricata high severity alerts that are observed for the first time in the previous 5 days of alert history. Analysts can use this to prioritize triage and response.
Rule Body
[metadata]
creation_date = "2026/01/20"
integration = ["suricata"]
maturity = "production"
updated_date = "2026/02/17"
[rule]
author = ["Elastic"]
description = """
This rule detects Suricata high severity alerts that are observed for the first time in the previous 5 days of alert history.
Analysts can use this to prioritize triage and response.
"""
from = "now-7205m"
interval = "5m"
language = "esql"
license = "Elastic License v2"
name = "Newly Observed High Severity Suricata Alert"
risk_score = 99
rule_id = "d591d7af-399b-4888-b705-ae612690c48d"
severity = "critical"
tags = ["Use Case: Threat Detection", "Rule Type: Higher-Order Rule", "Resources: Investigation Guide", "Domain: Network", "Data Source: Suricata"]
timestamp_override = "event.ingested"
type = "esql"
query = '''
FROM logs-suricata.*
// high severity alerts
| where event.module == "suricata" and event.kind == "signal" and event.severity == 1 and
rule.name is not null and
not rule.name like "SURICATA STREAM*"
| STATS Esql.alerts_count = count(*),
Esql.first_time_seen = MIN(@timestamp),
Esql.distinct_count_src_ip = COUNT_DISTINCT(source.ip),
Esql.distinct_count_dst_ip = COUNT_DISTINCT(destination.ip),
src_ip_values = VALUES(source.ip),
dst_ip_values = VALUES(destination.ip),
url_dom = VALUES(url.domain),
url_path = VALUES(url.path) by rule.name, event.type
| eval Esql.recent = DATE_DIFF("minute", Esql.first_time_seen, now())
// first time seen is within 10m of the rule execution time
| where Esql.recent <= 10 and
// exclude high volume alerts such as vuln-scanners
Esql.alerts_count <= 5 and Esql.distinct_count_src_ip <= 2 and Esql.distinct_count_dst_ip <= 2
// move dynamic fields to ECS quivalent for rule exceptions
| eval source.ip = MV_FIRST(src_ip_values),
destination.ip = MV_FIRST(dst_ip_values),
url.domain = MV_FIRST(url_dom),
url.path = MV_FIRST(url_path)
| keep rule.name, event.type, Esql.*, source.ip, destination.ip, url.domain, url.path
'''
note = """## Triage and analysis
### Investigating Newly Observed High Severity Suricata Alert
This rule surfaces newly observed, low-frequency high severity suricata alerts within the last 5 days.
Because the alert has not been seen previously for this rule and host, it should be prioritized for validation to determine
whether it represents a true compromise or rare benign activity.
### Investigation Steps
- Identify the source address, affected host and review the associated rule name to understand the behavior that triggered the alert.
- Validate the source address under which the activity occurred and assess whether it aligns with normal behavior.
- Refer to the specific alert details like event.original to get more context.
### False Positive Considerations
- Vulnerability scanners and pentesting.
- Administrative scripts or automation tools can trigger detections when first introduced.
- Development or testing environments may produce one-off behaviors that resemble malicious techniques.
### Response and Remediation
- If the activity is confirmed malicious, isolate the affected host to prevent further execution or lateral movement.
- Terminate malicious processes and remove any dropped files or persistence mechanisms.
- Collect forensic artifacts to understand initial access and execution flow.
- Patch or remediate any vulnerabilities or misconfigurations that enabled the behavior.
- If benign, document the finding and consider tuning or exception handling to reduce future noise.
- Continue monitoring the host and environment for recurrence of the behavior or related alerts."""
references = ["https://www.elastic.co/docs/reference/integrations/suricata"]
Stages and Predicates
Stage 1: from
FROM logs-suricata.*
Stage 2: where
| where event.module == "suricata" and event.kind == "signal" and event.severity == 1 and
rule.name is not null and
not rule.name like "SURICATA STREAM*"
Stage 3: stats
| STATS Esql.alerts_count = count(*),
Esql.first_time_seen = MIN(@timestamp),
Esql.distinct_count_src_ip = COUNT_DISTINCT(source.ip),
Esql.distinct_count_dst_ip = COUNT_DISTINCT(destination.ip),
src_ip_values = VALUES(source.ip),
dst_ip_values = VALUES(destination.ip),
url_dom = VALUES(url.domain),
url_path = VALUES(url.path) by rule.name, event.type
Stage 4: eval
| eval Esql.recent = DATE_DIFF("minute", Esql.first_time_seen, now())
Stage 5: where
| where Esql.recent <= 10 and
Esql.alerts_count <= 5 and Esql.distinct_count_src_ip <= 2 and Esql.distinct_count_dst_ip <= 2
Stage 6: eval
| eval source.ip = MV_FIRST(src_ip_values),
destination.ip = MV_FIRST(dst_ip_values),
url.domain = MV_FIRST(url_dom),
url.path = MV_FIRST(url_path)
Stage 7: keep
| keep rule.name, event.type, Esql.*, source.ip, destination.ip, url.domain, url.path
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
rule.name | starts_with | SURICATA STREAM | excludes:rule.name field:"rule.name" value:"SURICATA STREAM" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
rule.name | KEEP rule.name |
event.type | KEEP event.type |
Esql.* | KEEP Esql.* |
source.ip | KEEP source.ip |
destination.ip | KEEP destination.ip |
url.domain | KEEP url.domain |
url.path | KEEP url.path |
Persistence via DirectoryService Plugin Modification
#Identifies the creation or modification of a DirectoryService PlugIns (dsplug) file. The DirectoryService daemon launches on each system boot and automatically reloads after crash. It scans and executes bundles that are located in the DirectoryServices PlugIns folder and can be abused by adversaries to maintain persistence.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Persistence | |
| Stealth |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| macOS | ESF event write (NOTIFY): Fires after a process writes data to a file. |
Rule Body
[metadata]
creation_date = "2021/01/13"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
Identifies the creation or modification of a DirectoryService PlugIns (dsplug) file. The DirectoryService daemon
launches on each system boot and automatically reloads after crash. It scans and executes bundles that are located in
the DirectoryServices PlugIns folder and can be abused by adversaries to maintain persistence.
"""
from = "now-9m"
index = ["logs-endpoint.events.*"]
language = "eql"
license = "Elastic License v2"
name = "Persistence via DirectoryService Plugin Modification"
references = ["https://blog.chichou.me/2019/11/21/two-macos-persistence-tricks-abusing-plugins/"]
risk_score = 47
rule_id = "89fa6cb7-6b53-4de2-b604-648488841ab8"
setup = """## Setup
This rule requires data coming in from Elastic Defend.
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration on a macOS System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, for MacOS it is recommended to select "Traditional Endpoints".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/current/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: macOS",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
file where host.os.type == "macos" and event.action == "modification" and
file.path like "/Library/DirectoryServices/PlugIns/*.dsplug"
'''
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 Persistence via DirectoryService Plugin Modification
DirectoryService PlugIns on macOS are integral for managing directory-based services, automatically executing on system boot. Adversaries exploit this by modifying or creating malicious plugins to ensure persistent access. The detection rule identifies suspicious activity by monitoring non-deletion events involving dsplug files in the PlugIns directory, flagging potential unauthorized modifications indicative of persistence tactics.
### Possible investigation steps
- Review the alert details to confirm the file path matches /Library/DirectoryServices/PlugIns/*.dsplug, indicating a potential unauthorized modification or creation of a DirectoryService plugin.
- Check the file creation or modification timestamp to determine when the suspicious activity occurred and correlate it with other system events or user activities around that time.
- Investigate the file's origin by examining the file's metadata, such as the creator or modifying user, and cross-reference with known user accounts and their typical behavior.
- Analyze the contents of the modified or newly created dsplug file to identify any malicious code or unusual configurations that could indicate adversarial activity.
- Review system logs and other security alerts around the time of the event to identify any related suspicious activities or patterns that could suggest a broader compromise.
- Assess the risk and impact of the modification by determining if the plugin is actively being used for persistence or if it has been executed by the DirectoryService daemon.
### False positive analysis
- Routine system updates or legitimate software installations may modify dsplug files, triggering alerts. Users can create exceptions for known update processes or trusted software installations to reduce noise.
- Administrative tasks performed by IT personnel, such as configuring directory services, might involve legitimate modifications to dsplug files. Implementing a whitelist for actions performed by verified IT accounts can help minimize false positives.
- Security software or system management tools that interact with directory services might cause benign modifications. Identifying and excluding these tools from monitoring can prevent unnecessary alerts.
- Automated scripts or maintenance tasks that regularly check or update directory service configurations could be flagged. Documenting and excluding these scripts from detection can help maintain focus on genuine threats.
### Response and remediation
- Immediately isolate the affected macOS system from the network to prevent further unauthorized access or lateral movement by the adversary.
- Conduct a thorough review of the identified dsplug file(s) in the /Library/DirectoryServices/PlugIns/ directory to confirm unauthorized modifications or creations. Compare against known good configurations or backups.
- Remove any unauthorized or malicious dsplug files and restore legitimate versions from a trusted backup if available.
- Restart the DirectoryService daemon to ensure it is running only legitimate plugins. This can be done by executing `sudo launchctl stop com.apple.DirectoryServices` followed by `sudo launchctl start com.apple.DirectoryServices`.
- Perform a comprehensive scan of the system using updated security tools to identify any additional malicious files or indicators of compromise.
- Escalate the incident to the security operations team for further investigation and to determine if additional systems are affected.
- Implement enhanced monitoring on the DirectoryServices PlugIns directory to detect future unauthorized changes promptly, ensuring alerts are configured to notify the security team immediately."""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1547"
name = "Boot or Logon Autostart Execution"
reference = "https://attack.mitre.org/techniques/T1547/"
[[rule.threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
Stages and Predicates
Stage 1: file
file where host.os.type == "macos" and event.action == "modification" and
file.path like "/Library/DirectoryServices/PlugIns/*.dsplug"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"modification" |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard value:"/Library/DirectoryServices/PlugIns/*.dsplug" |
Potential CVE-2025-32463 Nsswitch File Creation
#Detects suspicious creation of the nsswitch.conf file, outside of the regular /etc/nsswitch.conf path, consistent with attempts to exploit CVE-2025-32463 (the "sudo chroot" privilege escalation), where an attacker tricks sudo into using attacker-controlled NSS files or libraries to gain root.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Privilege Escalation | |
| Stealth |
Rule Body
[metadata]
creation_date = "2025/10/01"
integration = ["endpoint", "auditd_manager", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/07/17"
[rule]
author = ["Elastic"]
description = """
Detects suspicious creation of the nsswitch.conf file, outside of the regular /etc/nsswitch.conf path,
consistent with attempts to exploit CVE-2025-32463 (the "sudo chroot" privilege escalation), where an
attacker tricks sudo into using attacker-controlled NSS files or libraries to gain root.
"""
from = "now-9m"
index = [
"logs-endpoint.events.file*",
"logs-sentinel_one_cloud_funnel.*",
"endgame-*",
"auditbeat-*",
"logs-auditd_manager.auditd-*",
"logs-crowdstrike.fdr*",
]
language = "eql"
license = "Elastic License v2"
name = "Potential CVE-2025-32463 Nsswitch File Creation"
note = """
## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Potential CVE-2025-32463 Nsswitch File Creation
This rule flags creation of an nsswitch.conf file outside the standard /etc location by a shell, an early sign of staging a fake root to coerce sudo's chroot path and hijack NSS resolution (CVE-2025-32463). A common pattern is writing /tmp/chroot/etc/nsswitch.conf, placing or pointing to a malicious NSS module, then running sudo chroot into that directory so name lookups load attacker-controlled code and escalate to root.
### Possible investigation steps
- Correlate the event with any sudo or chroot executions within ±10 minutes that reference the same directory prefix (e.g., /tmp/chroot), capturing full command line, user, TTY, working directory, and exit codes.
- Inspect the created nsswitch.conf for nonstandard services or module names and enumerate any libnss_*.so* under lib*/ or usr/lib*/ within that prefix, recording owner, hashes, and timestamps.
- List all contemporaneous file writes under the same prefix (etc, lib*, bin, sbin) to determine whether a chroot rootfs is being assembled and attribute it to a toolchain such as tar, rsync, debootstrap, or custom scripts via process ancestry.
- Search file access telemetry to see whether privileged processes subsequently read that specific nsswitch.conf or loaded libnss_* from the same path, which would indicate the chroot was exercised.
- Verify sudo and glibc versions and patch status for CVE-2025-32463 and collect the initiating user’s session context (SSH source, TTY, shell history) to assess exploitability and scope.
### False positive analysis
- An administrator legitimately staging a temporary chroot or test root filesystem may use a shell to create /tmp/*/etc/nsswitch.conf while populating configs, matching the rule even though no privilege escalation is intended.
- OS installation, recovery, or backup-restore workflows run from a shell can populate a mounted target like /mnt/newroot/etc/nsswitch.conf, creating the file outside /etc as part of maintenance and triggering the alert.
### Response and remediation
- Terminate any sudo or chroot processes referencing the created path (e.g., /tmp/chroot/etc/nsswitch.conf), lock the initiating user’s sudo access, and quarantine the parent directory with root-only permissions.
- Remove the staged nsswitch.conf and any libnss_*.so* or ld.so.* artifacts under lib*/ or usr/lib*/ within that prefix after collecting copies, hashes, and timestamps for evidence.
- Restore and verify /etc/nsswitch.conf on the host with correct content and root:root 0644, purge temporary chroot roots under /tmp, /var/tmp, or /mnt, and restart nscd or systemd-resolved to flush cached name-service data.
- Escalate to incident response if sudo chroot was executed against the same directory, if root processes loaded libnss_* from that path, or if nsswitch.conf appears outside /etc on multiple hosts within a short window.
- Apply vendor fixes for CVE-2025-32463 to sudo and glibc, disallow chroot in sudoers and enforce env_reset, noexec, and secure_path, and mount /tmp and /var/tmp with noexec,nosuid,nodev to prevent libraries being sourced from user-writable paths.
- Add controls to block execution from user-created chroot trees by policy (AppArmor or SELinux) and create alerts on creation of */etc/nsswitch.conf or libnss_* writes under non-system paths, with auto-isolation for directories under /tmp or a user’s home.
"""
references = [
"https://www.stratascale.com/vulnerability-alert-CVE-2025-32463-sudo-chroot",
"https://github.com/kh4sh3i/CVE-2025-32463",
]
risk_score = 73
rule_id = "163a8f2f-c8a0-4b7e-9c4a-1184310eb7f3"
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 = "high"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Privilege Escalation",
"Data Source: Elastic Defend",
"Data Source: SentinelOne",
"Data Source: Crowdstrike",
"Data Source: Elastic Endgame",
"Data Source: Auditd Manager",
"Use Case: Vulnerability",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
file where host.os.type == "linux" and event.type == "creation" and file.path like "/*/etc/nsswitch.conf" and
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and not
(
process.name in ("bash", "dash") and file.path like (
"/var/tmp/mkinitramfs_*", "/tmp/tmp.*/mkinitramfs_*", "/tmp/petalinux*/etc/nsswitch.conf",
"/tmp/selfextract.*/mkinitramfs_*/etc/nsswitch.conf", "/var/tmp/dracut.*/initramfs/etc/nsswitch.conf",
"/tmp/user/0/mkinitramfs_*/etc/nsswitch.conf", "/opt/mkinitramfs_*/etc/nsswitch.conf",
"/opt/dumpling-nxp/*/etc/nsswitch.conf", "/tmp/store/vfs/dir/*", "/opt/tmp/mkinitramfs_*",
"/opt/nvidia_tmpfs/mkinitramfs*"
)
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1068"
name = "Exploitation for Privilege Escalation"
reference = "https://attack.mitre.org/techniques/T1068/"
[[rule.threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"
[[rule.threat.technique.subtechnique]]
id = "T1574.006"
name = "Dynamic Linker Hijacking"
reference = "https://attack.mitre.org/techniques/T1574/006/"
[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
Stages and Predicates
Stage 1: file
file where host.os.type == "linux" and event.type == "creation" and file.path like "/*/etc/nsswitch.conf" and
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and not
(
process.name in ("bash", "dash") and file.path like (
"/var/tmp/mkinitramfs_*", "/tmp/tmp.*/mkinitramfs_*", "/tmp/petalinux*/etc/nsswitch.conf",
"/tmp/selfextract.*/mkinitramfs_*/etc/nsswitch.conf", "/var/tmp/dracut.*/initramfs/etc/nsswitch.conf",
"/tmp/user/0/mkinitramfs_*/etc/nsswitch.conf", "/opt/mkinitramfs_*/etc/nsswitch.conf",
"/opt/dumpling-nxp/*/etc/nsswitch.conf", "/tmp/store/vfs/dir/*", "/opt/tmp/mkinitramfs_*",
"/opt/nvidia_tmpfs/mkinitramfs*"
)
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"creation" |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard value:"/*/etc/nsswitch.conf" |
process.name | in |
| field:"process_basename" kind:in |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
file.path | wildcard | /var/tmp/mkinitramfs_*, /tmp/tmp.*/mkinitramfs_*, /tmp/petalinux*/etc/nsswitch.conf, /tmp/selfextract.*/mkinitramfs_*/etc/nsswitch.conf, /var/tmp/dracut.*/initramfs/etc/nsswitch.conf, /tmp/user/0/mkinitramfs_*/etc/nsswitch.conf, /opt/mkinitramfs_*/etc/nsswitch.conf, /opt/dumpling-nxp/*/etc/nsswitch.conf, /tmp/store/vfs/dir/*, /opt/tmp/mkinitramfs_*, /opt/nvidia_tmpfs/mkinitramfs* | excludes:file.path |
process.name | in | bash, dash | excludes:process.name field:"process.name" value:"bash" field:"process.name" value:"dash" |
Potential NetNTLMv1 Downgrade Attack
#Identifies registry modification to force the system to fall back to NTLMv1 for authentication. This modification is possible with local administrator privileges and is commonly referred to as a NetNTLMv1 downgrade attack.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Defense Impairment |
Rule Body
[rule]
description = """
Identifies registry modification to force the system to fall back to NTLMv1 for authentication. This modification is
possible with local administrator privileges and is commonly referred to as a NetNTLMv1 downgrade attack.
"""
id = "6179bd21-a2ca-40c0-bfef-77aab4e99432"
license = "Elastic License v2"
name = "Potential NetNTLMv1 Downgrade Attack"
os_list = ["windows"]
reference = [
"https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/security-policy-settings/network-security-lan-manager-authentication-level",
]
version = "1.0.4"
query = '''
registry where event.action == "modification" and registry.value == "LmCompatibilityLevel" and registry.data.strings in ("2", "1", "0") and
/* noisy FP - need to be compensated by a detection rule */
not (user.id == "S-1-5-18" and process.name == "powershell.exe" and registry.data.strings in ("1", "0"))
'''
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 = "T1112"
name = "Modify Registry"
reference = "https://attack.mitre.org/techniques/T1112/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: registry
registry where event.action == "modification" and registry.value == "LmCompatibilityLevel" and registry.data.strings in ("2", "1", "0") and
not (user.id == "S-1-5-18" and process.name == "powershell.exe" and registry.data.strings in ("1", "0"))
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"modification" |
registry.data.strings | in |
| field:"Details" kind:in |
registry.value | eq |
| field:"registry_value_name" kind:eq value:"LmCompatibilityLevel" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.name | eq | powershell.exe | excludes:process.name field:"process.name" value:"powershell.exe" |
registry.data.strings | in | 0, 1 | excludes:registry.data.strings field:"registry.data.strings" value:"0" field:"registry.data.strings" value:"1" |
user.id | eq | S-1-5-18 | excludes:user.id field:"user.id" value:"S-1-5-18" |
Potential Protocol Tunneling via Legit Utilities
#Identifies the use of known legit utilities to potentially tunnel network traffic. This can be used by attackers to enable routing of network packets that would otherwise not reach their intended destination.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Command & Control |
Rule Body
[rule]
description = """
Identifies the use of known legit utilities to potentially tunnel network traffic. This can be used by attackers to
enable routing of network packets that would otherwise not reach their intended destination.
"""
id = "87aa3f52-3f7b-4d6e-aecc-101bb1275020"
license = "Elastic License v2"
name = "Potential Protocol Tunneling via Legit Utilities"
os_list = ["windows"]
reference = ["https://blog.netspi.com/how-to-access-rdp-over-a-reverse-ssh-tunnel/"]
version = "1.0.12"
query = '''
process where event.action == "start" and
(
/* RDP port and usual SSH tunneling related switches in command line */
(process.command_line : "*:3389*" and process.args : ("-L", "-P", "-R", "-pw", "-ssh")) or
(process.code_signature.subject_name : "ngrok, Inc." and process.args : ("http", "tcp", "tunnel", "tls", "start", "3389")) or
(process.executable : "?:\\Windows\\System32\\OpenSSH\\ssh.exe" and process.command_line : ("*127.0.0.*", "*:localhost:*") and process.args : "-L") or
(process.args : "client" and process.command_line : "* R*:socks*") or
((process.name : "curl.exe" or process.pe.original_file_name == "curl.exe") and process.command_line : ("*socks5h://127.0.0.*", "*socks5h:\\127.0.0.*"))
)
and not (process.code_signature.subject_name : "ninjaRMM LLC" and process.code_signature.status : "trusted") and
not (process.name:"ssh.exe" and process.args in ("22000:127.0.0.1:1466", "localhost:8897:localhost:8897", "22000:127.0.0.1:1466",
"10005:localhost:5050", "localhost:8897:localhost:8897", "59000:localhost:5901",
"-L30000:localhost:30000", "7779:localhost:7779", "5000:localhost:5000",
"8888:localhost:8888")) and
not process.parent.command_line : ("C:\\windows\\system32\\cmd.exe /c \"\"C:\\Users\\*\\Desktop\\*.bat\" \"",
"\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" ",
"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe")
'''
min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1572"
name = "Protocol Tunneling"
reference = "https://attack.mitre.org/techniques/T1572/"
[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: process
process where event.action == "start" and
(
(process.command_line : "*:3389*" and process.args : ("-L", "-P", "-R", "-pw", "-ssh")) or
(process.code_signature.subject_name : "ngrok, Inc." and process.args : ("http", "tcp", "tunnel", "tls", "start", "3389")) or
(process.executable : "?:\\Windows\\System32\\OpenSSH\\ssh.exe" and process.command_line : ("*127.0.0.*", "*:localhost:*") and process.args : "-L") or
(process.args : "client" and process.command_line : "* R*:socks*") or
((process.name : "curl.exe" or process.pe.original_file_name == "curl.exe") and process.command_line : ("*socks5h://127.0.0.*", "*socks5h:\\127.0.0.*"))
)
and not (process.code_signature.subject_name : "ninjaRMM LLC" and process.code_signature.status : "trusted") and
not (process.name:"ssh.exe" and process.args in ("22000:127.0.0.1:1466", "localhost:8897:localhost:8897", "22000:127.0.0.1:1466",
"10005:localhost:5050", "localhost:8897:localhost:8897", "59000:localhost:5901",
"-L30000:localhost:30000", "7779:localhost:7779", "5000:localhost:5000",
"8888:localhost:8888")) and
not process.parent.command_line : ("C:\\windows\\system32\\cmd.exe /c \"\"C:\\Users\\*\\Desktop\\*.bat\" \"",
"\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" ",
"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.code_signature.subject_name | wildcard |
| field:"Signature" kind:wildcard value:"ngrok, Inc." |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard |
process.executable | wildcard |
| field:"Image" kind:wildcard value:"?:\Windows\System32\OpenSSH\ssh.exe" |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:"curl.exe" |
process.pe.original_file_name | eq |
| field:"OriginalFileName" kind:eq value:"curl.exe" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | in | -L30000:localhost:30000, 10005:localhost:5050, 22000:127.0.0.1:1466, 5000:localhost:5000, 59000:localhost:5901, 7779:localhost:7779, 8888:localhost:8888, localhost:8897:localhost:8897 | excludes:process.args |
process.name | eq | ssh.exe | excludes:process.name field:"process.name" value:"ssh.exe" |
process.code_signature.status | eq | trusted | excludes:process.code_signature.status field:"process.code_signature.status" value:"trusted" |
process.code_signature.subject_name | eq | ninjaRMM LLC | excludes:process.code_signature.subject_name field:"process.code_signature.subject_name" value:"ninjaRMM LLC" |
process.parent.command_line | wildcard | C:\windows\system32\cmd.exe /c ""C:\Users\*\Desktop\*.bat" ", "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" , C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe | excludes:process.parent.command_line |
Potential Reverse Shell Activity via Terminal
#Identifies the execution of a shell process with suspicious arguments which may be indicative of reverse shell activity.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Command & Control |
Rule Body
[metadata]
creation_date = "2020/01/07"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = "Identifies the execution of a shell process with suspicious arguments which may be indicative of reverse shell activity."
from = "now-9m"
index = ["auditbeat-*", "logs-endpoint.events.*"]
language = "eql"
license = "Elastic License v2"
name = "Potential Reverse Shell Activity via Terminal"
note = """## Triage and analysis
### Investigating Potential Reverse Shell Activity via Terminal
A reverse shell is a mechanism that's abused to connect back to an attacker-controlled system. It effectively redirects the system's input and output and delivers a fully functional remote shell to the attacker. Even private systems are vulnerable since the connection is outgoing. This activity is typically the result of vulnerability exploitation, malware infection, or penetration testing.
This rule identifies commands that are potentially related to reverse shell activities using shell applications.
#### Possible investigation steps
- Examine the command line and extract the target domain or IP address information.
- Check if the domain is newly registered or unexpected.
- Check the reputation of the domain or IP address.
- Scope other potentially compromised hosts in your environment by mapping hosts that also communicated with the domain or IP address.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Investigate any abnormal account behavior, such as command executions, file creations or modifications, and network connections.
- Investigate any abnormal behavior by the subject process such as network connections, file modifications, and any spawned child processes.
### False positive analysis
- This activity is unlikely to happen legitimately. Any activity that triggered the alert and is not inherently malicious must be monitored by the security team.
### Response and remediation
- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Take actions to terminate processes and connections used by the attacker.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
references = [
"https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md",
"https://github.com/WangYihang/Reverse-Shell-Manager",
"https://www.netsparker.com/blog/web-security/understanding-reverse-shells/",
"https://www.elastic.co/security-labs/detecting-log4j2-with-elastic-security",
]
risk_score = 73
rule_id = "a1a0375f-22c2-48c0-81a4-7c2d11cc6856"
setup = """## Setup
If enabling an EQL rule on a non-elastic-agent index (such as beats) for versions <8.2,
events will not define `event.ingested` and default fallback for EQL rules was not added until version 8.2.
Hence for this rule to work effectively, users will need to add a custom ingest pipeline to populate
`event.ingested` to @timestamp.
For more details on adding a custom ingest pipeline refer - https://www.elastic.co/guide/en/fleet/current/data-streams-pipeline-tutorial.html
"""
severity = "high"
tags = [
"Domain: Endpoint",
"OS: Linux",
"OS: macOS",
"Use Case: Threat Detection",
"Tactic: Execution",
"Resources: Investigation Guide",
"Data Source: Elastic Defend",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where event.type in ("start", "process_started") and
process.name in ("sh", "bash", "zsh", "dash", "zmodload") and
process.args : ("*/dev/tcp/*", "*/dev/udp/*", "*zsh/net/tcp*", "*zsh/net/udp*") and
/* noisy FPs */
not (process.parent.name : "timeout" and process.executable : "/var/lib/docker/overlay*") and
not process.command_line : (
"*/dev/tcp/sirh_db/*", "*/dev/tcp/remoteiot.com/*", "*dev/tcp/elk.stag.one/*", "*dev/tcp/kafka/*",
"*/dev/tcp/$0/$1*", "*/dev/tcp/127.*", "*/dev/udp/127.*", "*/dev/tcp/localhost/*", "*/dev/tcp/itom-vault/*") and
not process.parent.command_line : "runc init"
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1095"
name = "Non-Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1095/"
[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 in ("start", "process_started") and
process.name in ("sh", "bash", "zsh", "dash", "zmodload") and
process.args : ("*/dev/tcp/*", "*/dev/udp/*", "*zsh/net/tcp*", "*zsh/net/udp*") and
not (process.parent.name : "timeout" and process.executable : "/var/lib/docker/overlay*") and
not process.command_line : (
"*/dev/tcp/sirh_db/*", "*/dev/tcp/remoteiot.com/*", "*dev/tcp/elk.stag.one/*", "*dev/tcp/kafka/*",
"*/dev/tcp/$0/$1*", "*/dev/tcp/127.*", "*/dev/udp/127.*", "*/dev/tcp/localhost/*", "*/dev/tcp/itom-vault/*") and
not process.parent.command_line : "runc init"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | in |
| field:"event.type" kind:in |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.name | in |
| field:"process_basename" kind:in |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.executable | starts_with | /var/lib/docker/overlay | excludes:process.executable field:"process.executable" value:"/var/lib/docker/overlay" |
process.parent.name | eq | timeout | excludes:process.parent.name field:"process.parent.name" value:"timeout" |
process.command_line | match | /dev/tcp/sirh_db/, /dev/tcp/remoteiot.com/, dev/tcp/elk.stag.one/, dev/tcp/kafka/, /dev/tcp/$0/$1, /dev/tcp/127., /dev/udp/127., /dev/tcp/localhost/, /dev/tcp/itom-vault/ | excludes:process.command_line |
process.parent.command_line | eq | runc init | excludes:process.parent.command_line field:"process.parent.command_line" value:"runc init" |
Privilege Escalation via Polkit System Service
#A vulnerability exists within the polkit system service that a local, unprivileged attacker can leverage to perform privileged operations. In order to leverage the exposure, the attacker invokes a method over D-Bus and kills the client process. This will occasionally cause the operation to complete without being subjected to all necessary authentications. The exploit can then be used to add a new user with sudo access and a known password. The new account is then leveraged to execute a payload with root privileges.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Privilege Escalation |
Rule Body
[rule]
description = """
A vulnerability exists within the polkit system service that a local, unprivileged attacker can leverage to perform
privileged operations. In order to leverage the exposure, the attacker invokes a method over D-Bus and kills the client
process. This will occasionally cause the operation to complete without being subjected to all necessary
authentications. The exploit can then be used to add a new user with sudo access and a known password. The new account
is then leveraged to execute a payload with root privileges.
"""
id = "3144cab7-cc28-46c3-a3ac-8fefe8db22d6"
license = "Elastic License v2"
name = "Privilege Escalation via Polkit System Service"
os_list = ["linux"]
reference = [
"https://packetstormsecurity.com/files/163452/Polkit-D-Bus-Authentication-Bypass.html",
"https://github.com/oxagast/oxasploits/blob/JoshuaJohnWard/exploits/CVE-2021-3560/polkit_godmode_0day.sh",
"https://access.redhat.com/security/cve/cve-2021-3560",
]
version = "1.0.17"
query = '''
process where event.type == "start" and process.name == "dbus-send" and
process.args in ("--dest=org.freedesktop.Accounts", "org.freedesktop.Accounts.CreateUser",
"org.freedesktop.Accounts.User.SetPassword", "org.freedesktop.Accounts.DeleteUser")
'''
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 = "T1548"
name = "Abuse Elevation Control Mechanism"
reference = "https://attack.mitre.org/techniques/T1548/"
[[threat.technique.subtechnique]]
id = "T1548.002"
name = "Bypass User Account Control"
reference = "https://attack.mitre.org/techniques/T1548/002/"
[threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: process
process where event.type == "start" and process.name == "dbus-send" and
process.args in ("--dest=org.freedesktop.Accounts", "org.freedesktop.Accounts.CreateUser",
"org.freedesktop.Accounts.User.SetPassword", "org.freedesktop.Accounts.DeleteUser")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | in |
| field:"process.args" kind:in |
process.name | eq |
| field:"process_basename" kind:eq value:"dbus-send" |
Shell via NetworkManager Dispatcher Script
#This rule detects a shell being spawned by a NetworkManager dispatcher script. Attackers may use this method to establish persistence on a target system whenever a network action is triggered.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Command & Control |
Rule Body
[rule]
description = """
This rule detects a shell being spawned by a NetworkManager dispatcher script. Attackers may use this method to
establish persistence on a target system whenever a network action is triggered.
"""
id = "e8d8eb78-d6aa-456f-a24e-c073026f7809"
license = "Elastic License v2"
name = "Shell via NetworkManager Dispatcher Script"
os_list = ["linux"]
version = "1.0.3"
query = '''
process where event.type == "start" and event.action == "exec" and
process.parent.executable like "/etc/NetworkManager/dispatcher.d/*" and
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish")
'''
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.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"
[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: process
process where event.type == "start" and event.action == "exec" and
process.parent.executable like "/etc/NetworkManager/dispatcher.d/*" and
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish")
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.name | in |
| field:"process_basename" kind:in |
process.parent.executable | wildcard |
| field:"ParentImage" kind:wildcard value:"/etc/NetworkManager/dispatcher.d/*" |
Suspicious Execution from a Mounted Device
#Identifies when a script interpreter or signed binary is launched via a non-standard working directory. An attacker may use this technique to evade defenses.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Stealth |
Rule Body
[rule]
description = """
Identifies when a script interpreter or signed binary is launched via a non-standard working directory. An attacker may
use this technique to evade defenses.
"""
id = "42d2bbfb-a2fb-4327-b701-89ead6044ca1"
license = "Elastic License v2"
name = "Suspicious Execution from a Mounted Device"
os_list = ["windows"]
version = "1.0.32"
query = '''
sequence with maxspan=1m
[file where event.action == "creation" and file.extension : "lnk" and
process.name : "explorer.exe" and
file.path : ("?:\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\Recent\\*.vhd.lnk",
"?:\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\Recent\\*.iso.lnk")] by process.entity_id
[process where event.action == "start" and process.executable : "C:\\*" and
(process.working_directory : "?:\\" and not process.working_directory : "C:\\") and process.parent.name : "explorer.exe" and
process.name : ("rundll32.exe", "mshta.exe", "powershell.exe", "pwsh.exe", "cmd.exe", "regsvr32.exe", "cscript.exe",
"wscript.exe", "wmic.exe", "msbuild.exe", "regsvcs.exe", "installutil.exe", "cmstp.exe", "msxsl.exe",
"Microsoft.Workflow.Compiler.exe", "wuauclt.exe") and
/* Issue #316 */
process.args_count >= 2] by process.parent.entity_id
'''
min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.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.technique.subtechnique]]
id = "T1059.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"
[[threat.technique.subtechnique]]
id = "T1218.005"
name = "Mshta"
reference = "https://attack.mitre.org/techniques/T1218/005/"
[[threat.technique.subtechnique]]
id = "T1218.010"
name = "Regsvr32"
reference = "https://attack.mitre.org/techniques/T1218/010/"
[[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
Ordered sequence: each step below must occur in order within 1m, correlated by process.entity_id, process.parent.entity_id.
Stage 1: file
[file where event.action == "creation" and file.extension : "lnk" and
process.name : "explorer.exe" and
file.path : ("?:\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\Recent\\*.vhd.lnk",
"?:\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\Recent\\*.iso.lnk")] by process.entity_id
Stage 2: process
[process where event.action == "start" and process.executable : "C:\\*" and
(process.working_directory : "?:\\" and not process.working_directory : "C:\\") and process.parent.name : "explorer.exe" and
process.name : ("rundll32.exe", "mshta.exe", "powershell.exe", "pwsh.exe", "cmd.exe", "regsvr32.exe", "cscript.exe",
"wscript.exe", "wmic.exe", "msbuild.exe", "regsvcs.exe", "installutil.exe", "cmstp.exe", "msxsl.exe",
"Microsoft.Workflow.Compiler.exe", "wuauclt.exe") and
process.args_count >= 2] 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 |
file.extension | wildcard |
| field:"file.extension" kind:wildcard value:"lnk" |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard |
process.args_count | ge |
| field:"process.args_count" kind:ge value:"2" |
process.executable | wildcard |
| field:"Image" kind:wildcard value:"C:\*" |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard value:"explorer.exe" |
process.working_directory | wildcard |
| field:"CurrentDirectory" kind:wildcard value:"?:\" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.working_directory | eq | C:\ | excludes:process.working_directory field:"process.working_directory" value:"C:\" |
Tampering with RUNNER_TRACKING_ID in GitHub Actions Runners
#This rule detects processes spawned by GitHub Actions runners where "RUNNER_TRACKING_ID" is overridden from its default "github_*" value. Such tampering has been associated with attempts to evade runner tracking/cleanup on self-hosted runners, including behavior observed in the Shai-Hulud 2.0 npm worm campaign.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Execution | |
| Stealth | |
| Defense Impairment |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2025/11/27"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
This rule detects processes spawned by GitHub Actions runners where "RUNNER_TRACKING_ID" is overridden from its
default "github_*" value. Such tampering has been associated with attempts to evade runner tracking/cleanup on
self-hosted runners, including behavior observed in the Shai-Hulud 2.0 npm worm campaign.
"""
from = "now-9m"
index = ["logs-endpoint.events.process*"]
language = "eql"
license = "Elastic License v2"
name = "Tampering with RUNNER_TRACKING_ID in GitHub Actions Runners"
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 Tampering with RUNNER_TRACKING_ID in GitHub Actions Runners
This rule surfaces processes launched by GitHub Actions runners where RUNNER_TRACKING_ID is deliberately set to a non-default value. Attackers do this to break runner job tracking and cleanup on self-hosted runners, enabling long‑lived or hidden workloads. A common pattern is a workflow step that exports a custom RUNNER_TRACKING_ID and then spawns bash or node to fetch and execute a script via curl|bash or npm install scripts, keeping the process alive after the job finishes to run mining or exfil tasks.
### Possible investigation steps
- Correlate the event to its GitHub Actions run/job and workflow YAML, identify the repository and actor (commit/PR), and verify whether RUNNER_TRACKING_ID was explicitly set in the workflow or injected by a step script.
- On the runner host, determine if the spawned process persisted beyond job completion by checking for orphaning or reparenting to PID 1, sustained CPU/memory usage, and timestamps relative to the runner process exit.
- Review nearby telemetry for fetch-and-execute patterns (curl|bash, wget, node/npm lifecycle scripts), unexpected file writes under /tmp or actions-runner/_work, and outbound connections to non-GitHub endpoints.
- Enumerate persistence artifacts created during the run, including crontab entries, systemd unit files, pm2 or nohup sessions, and changes to authorized_keys or rc.local, and tie them back to the suspicious process.
- Assess blast radius by listing secrets and tokens available to the job, checking audit logs for their subsequent use from the runner IP or unusual repositories, and decide whether to revoke or rotate credentials.
### False positive analysis
- A self-hosted runner bootstrap script or base image intentionally sets a fixed RUNNER_TRACKING_ID for internal log correlation or debugging, causing all runner-spawned processes to inherit a non-github_* value.
- A composite action or reusable workflow accidentally overrides RUNNER_TRACKING_ID through env mapping or variable expansion (for example templating it from the run ID), resulting in benign non-default values during standard jobs.
### Response and remediation
- Quarantine the self-hosted runner by stopping Runner.Listener, removing the runner from the repository/organization, and terminating any Runner.Worker children or orphaned processes (PID 1) that carry a non-default RUNNER_TRACKING_ID.
- Purge persistence by removing artifacts created during the run, including systemd unit files under /etc/systemd/system, crontab entries in /var/spool/cron, pm2/nohup sessions, edits to ~/.ssh/authorized_keys or /etc/rc.local, and files under /tmp and actions-runner/_work linked to the tampered process.
- Revoke and rotate credentials exposed to the job (GITHUB_TOKEN, personal access tokens, cloud keys), delete leftover containers and caches in actions-runner/_work, invalidate the runner registration, and redeploy the runner from a clean, patched image.
- Escalate to incident response if you observe outbound connections to non-GitHub endpoints, processes persisting after job completion, modifications to ~/.ssh/authorized_keys or /etc/systemd/system, or repeated RUNNER_TRACKING_ID tampering across runners or repositories.
- Harden by restricting self-hosted runners to trusted repositories and actors, enforcing ephemeral per-job runners with egress allowlisting to github.com, setting strict job timeouts, and adding a workflow guard step that exits if RUNNER_TRACKING_ID does not start with github_."""
references = [
"https://www.elastic.co/blog/shai-hulud-worm-npm-supply-chain-compromise",
"https://socket.dev/blog/shai-hulud-strikes-again-v2",
"https://www.wiz.io/blog/shai-hulud-2-0-ongoing-supply-chain-attack",
"https://www.praetorian.com/blog/self-hosted-github-runners-are-backdoors/",
]
risk_score = 47
rule_id = "df0553c8-2296-45ef-b4dc-3b88c4c130a7"
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).
Elastic Defend integration does not collect environment variable logging by default.
In order to capture this behavior, this rule requires a specific configuration option set within the advanced settings of the Elastic Defend integration.
#### To set up environment variable capture for an Elastic Agent policy:
- Go to “Security → Manage → Policies”.
- Select an “Elastic Agent policy”.
- Click “Show advanced settings”.
- Scroll down or search for “linux.advanced.capture_env_vars”.
- Enter the names of environment variables you want to capture, separated by commas.
- For Linux, this rule requires the linux.advanced.capture_env_vars variable to be set to "RUNNER_TRACKING_ID".
- For macOS, this rule requires the macos.advanced.capture_env_vars variable to be set to "RUNNER_TRACKING_ID".
- Click “Save”.
After saving the integration change, the Elastic Agents running this policy will be updated and the rule will function properly.
For more information on capturing environment variables refer to the [helper guide](https://www.elastic.co/guide/en/security/current/environment-variable-capture.html).
"""
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Linux",
"OS: macOS",
"Use Case: Threat Detection",
"Tactic: Execution",
"Tactic: Initial Access",
"Tactic: Defense Evasion",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type in ("linux", "macos") and event.type == "start" and event.action == "exec" and
process.parent.name in ("Runner.Worker", "Runner.Listener") and process.env_vars like~ "RUNNER_TRACKING_ID*" and
not process.env_vars like~ "RUNNER_TRACKING_ID=github_*"
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1195"
name = "Supply Chain Compromise"
reference = "https://attack.mitre.org/techniques/T1195/"
[[rule.threat.technique.subtechnique]]
id = "T1195.001"
name = "Compromise Software Dependencies and Development Tools"
reference = "https://attack.mitre.org/techniques/T1195/001/"
[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1036"
name = "Masquerading"
reference = "https://attack.mitre.org/techniques/T1036/"
[[rule.threat.technique.subtechnique]]
id = "T1036.009"
name = "Break Process Trees"
reference = "https://attack.mitre.org/techniques/T1036/009/"
[[rule.threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[[rule.threat.technique.subtechnique]]
id = "T1562.001"
name = "Disable or Modify Tools"
reference = "https://attack.mitre.org/techniques/T1562/001/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Stage 1: process
process where host.os.type in ("linux", "macos") and event.type == "start" and event.action == "exec" and
process.parent.name in ("Runner.Worker", "Runner.Listener") and process.env_vars like~ "RUNNER_TRACKING_ID*" and
not process.env_vars like~ "RUNNER_TRACKING_ID=github_*"
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.env_vars | wildcard |
| field:"process.env_vars" kind:wildcard value:"RUNNER_TRACKING_ID*" |
process.parent.name | in |
| field:"parent_process_basename" kind:in |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.env_vars | starts_with | RUNNER_TRACKING_ID=github_ | excludes:process.env_vars field:"process.env_vars" value:"RUNNER_TRACKING_ID=github_" |
Unsigned or Untrusted Binary Execution via XPC call
#Detects the execution of an unsigned or untrusted binary by a shell interpreter via an XPC call. This activity can be carried out in several ways but the most common is when a Login Item gets created that is specified to execute a specific binary (in this instance an unsigned or untrusted binary). Threat actors will often utilize Login Items as a persistence mechanism to launch their payloads on system boot.
MITRE ATT&CK Coverage
Telemetry Coverage
Rule Body
[rule]
description = """
Detects the execution of an unsigned or untrusted binary by a shell interpreter via an XPC call. This activity can be
carried out in several ways but the most common is when a Login Item gets created that is specified to execute a
specific binary (in this instance an unsigned or untrusted binary). Threat actors will often utilize Login Items as a
persistence mechanism to launch their payloads on system boot.
"""
id = "ecd7fb9b-4a70-4a8f-8035-2df7fc90cfd5"
license = "Elastic License v2"
name = "Unsigned or Untrusted Binary Execution via XPC call"
os_list = ["macos"]
version = "1.0.6"
query = '''
process where event.type == "start" and event.action == "exec" and
process.Ext.effective_parent.name == "xpcproxy" and
process.parent.name in ("sh", "zsh", "bash") and
(process.code_signature.trusted == false or process.code_signature.exists == false) and
process.args_count <= 2 and
process.executable like~ ("/Volumes/*", "/Applications/*", "/Users/Shared/*", "/Library/Application Support/*", "/Users/*/Library/*", "/tmp/*", "/private/tmp/*", "/var/tmp/*") and
not process.name like~ "python*"
'''
min_endpoint_version = "8.7.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.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"
[[threat.technique]]
id = "T1559"
name = "Inter-Process Communication"
reference = "https://attack.mitre.org/techniques/T1559/"
[[threat.technique.subtechnique]]
id = "T1559.003"
name = "XPC Services"
reference = "https://attack.mitre.org/techniques/T1559/003/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[internal]
min_endpoint_version = "8.7.0"
Stages and Predicates
Stage 1: process
process where event.type == "start" and event.action == "exec" and
process.Ext.effective_parent.name == "xpcproxy" and
process.parent.name in ("sh", "zsh", "bash") and
(process.code_signature.trusted == false or process.code_signature.exists == false) and
process.args_count <= 2 and
process.executable like~ ("/Volumes/*", "/Applications/*", "/Users/Shared/*", "/Library/Application Support/*", "/Users/*/Library/*", "/tmp/*", "/private/tmp/*", "/var/tmp/*") and
not process.name like~ "python*"
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.Ext.effective_parent.name | eq |
| field:"process.Ext.effective_parent.name" kind:eq value:"xpcproxy" |
process.args_count | le |
| field:"process.args_count" kind:le value:"2" |
process.code_signature.exists | eq |
| field:"process.code_signature.exists" kind:eq value:"false" |
process.code_signature.trusted | eq |
| field:"process.code_signature.trusted" kind:eq value:"false" |
process.executable | wildcard |
| field:"Image" kind:wildcard |
process.parent.name | in |
| field:"parent_process_basename" kind:in |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.name | starts_with | python | excludes:process.name field:"process.name" value:"python" |
Unusual Linux Network Configuration Discovery
#Looks for commands related to system network configuration discovery from an unusual user context. This can be due to uncommon troubleshooting activity or due to a compromised account. A compromised account may be used by a threat actor to engage in system network configuration discovery in order to increase their understanding of connected networks and hosts. This information may be used to shape follow-up behaviors such as lateral movement or additional discovery.
Known False Positives
- Uncommon user command activity can be due to an engineer logging onto a server instance in order to perform manual troubleshooting or reconfiguration.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Discovery |
Rule Body
[metadata]
creation_date = "2020/09/03"
integration = ["auditd_manager", "endpoint"]
maturity = "production"
updated_date = "2026/07/27"
min_stack_version = "9.4.0"
min_stack_comments = "Use EA (Entity Analytics) fields"
[rule]
anomaly_threshold = 25
author = ["Elastic"]
description = """
Looks for commands related to system network configuration discovery from an unusual user context. This can be due to
uncommon troubleshooting activity or due to a compromised account. A compromised account may be used by a threat actor
to engage in system network configuration discovery in order to increase their understanding of connected networks and
hosts. This information may be used to shape follow-up behaviors such as lateral movement or additional discovery.
"""
false_positives = [
"""
Uncommon user command activity can be due to an engineer logging onto a server instance in order to perform manual
troubleshooting or reconfiguration.
""",
]
from = "now-45m"
interval = "15m"
license = "Elastic License v2"
machine_learning_job_id = ["v3_linux_network_configuration_discovery_ea"]
name = "Unusual Linux Network Configuration Discovery"
setup = """## Setup
This rule requires the installation of associated Machine Learning jobs, as well as data coming in from one of the following integrations:
- Elastic Defend
- Auditd Manager
### Anomaly Detection Setup
Once the rule is enabled, the associated Machine Learning job will start automatically. You can view the Machine Learning job linked under the "Definition" panel of the detection rule. If the job does not start due to an error, the issue must be resolved for the job to commence successfully. For more details on setting up anomaly detection jobs, refer to the [helper guide](https://www.elastic.co/guide/en/kibana/current/xpack-ml-anomalies.html).
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration to your system:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/current/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
### Auditd Manager Integration Setup
The Auditd Manager Integration receives audit events from the Linux Audit Framework which is a part of the Linux kernel.
Auditd Manager provides a user-friendly interface and automation capabilities for configuring and monitoring system auditing through the auditd daemon. With `auditd_manager`, administrators can easily define audit rules, track system events, and generate comprehensive audit reports, improving overall security and compliance in the system.
#### The following steps should be executed in order to add the Elastic Agent System integration "auditd_manager" to your system:
- Go to the Kibana home page and click “Add integrations”.
- In the query bar, search for “Auditd Manager” and select the integration to see more details about it.
- Click “Add Auditd Manager”.
- Configure the integration name and optionally add a description.
- Review optional and advanced settings accordingly.
- Add the newly installed “auditd manager” to an existing or a new agent policy, and deploy the agent on a Linux system from which auditd log files are desirable.
- Click “Save and Continue”.
- For more details on the integration refer to the [helper guide](https://docs.elastic.co/integrations/auditd_manager).
#### Rule Specific Setup Note
Auditd Manager subscribes to the kernel and receives events as they occur without any additional configuration.
However, if more advanced configuration is required to detect specific behavior, audit rules can be added to the integration in either the "audit rules" configuration box or the "auditd rule files" box by specifying a file to read the audit rules from.
- For this detection rule no additional audit rules are required.
"""
risk_score = 21
rule_id = "f9590f47-6bd5-4a49-bd49-a2f886476fb9"
severity = "low"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Data Source: Elastic Defend",
"Data Source: Auditd Manager",
"Use Case: Threat Detection",
"Rule Type: ML",
"Rule Type: Machine Learning",
"Tactic: Discovery",
"Resources: Investigation Guide",
]
type = "machine_learning"
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Unusual Linux Network Configuration Discovery
In Linux environments, network configuration tools are essential for managing and troubleshooting network settings. Adversaries may exploit these tools to gather network details, aiding in lateral movement or further reconnaissance. The detection rule leverages machine learning to identify atypical usage patterns of network commands by unexpected users, signaling potential account compromise or unauthorized network probing.
### Possible investigation steps
- Review the alert details to identify the specific network configuration commands executed and the user account involved. Focus on commands that are typically used for network discovery, such as `ifconfig`, `ip`, `netstat`, or `route`.
- Check the user's login history and session details to determine if the account activity aligns with the user's normal behavior or if there are signs of unauthorized access, such as logins from unusual IP addresses or at odd times.
- Investigate the user's role and responsibilities to assess whether they have a legitimate reason to perform network configuration discovery. This can help determine if the activity is expected or suspicious.
- Examine recent changes in user permissions or group memberships that might have allowed the execution of network configuration commands by an unexpected user.
- Correlate the alert with other security events or logs, such as authentication logs, to identify any related suspicious activities, such as failed login attempts or privilege escalation attempts.
- If the account is suspected to be compromised, initiate a password reset and review the system for any signs of further compromise or malicious activity, such as unauthorized software installations or data exfiltration attempts.
### False positive analysis
- Routine administrative tasks by system administrators may trigger the rule. To manage this, create exceptions for known admin accounts performing regular network configuration checks.
- Automated scripts or cron jobs that perform network diagnostics can be mistaken for unusual activity. Identify and whitelist these scripts to prevent false alerts.
- Network monitoring tools running under specific service accounts might be flagged. Ensure these service accounts are documented and excluded from the rule.
- Developers or IT staff conducting legitimate troubleshooting in non-production environments may cause alerts. Establish a process to temporarily exclude these users during known maintenance windows.
- New employees or contractors performing onboarding tasks might trigger the rule. Implement a review process to quickly assess and exclude these cases if they are verified as non-threatening.
### Response and remediation
- Isolate the affected system from the network to prevent further unauthorized access or lateral movement by the adversary.
- Terminate any suspicious processes or sessions initiated by the unusual user to halt ongoing reconnaissance activities.
- Conduct a thorough review of the affected user's account for signs of compromise, such as unauthorized access attempts or changes in user privileges.
- Reset the credentials of the compromised account and enforce multi-factor authentication to prevent future unauthorized access.
- Analyze network logs and system activity to identify any additional systems that may have been accessed or probed by the adversary.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if additional containment measures are necessary.
- Update detection mechanisms to include newly identified indicators of compromise (IOCs) and enhance monitoring for similar unusual network configuration discovery activities."""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1016"
name = "System Network Configuration Discovery"
reference = "https://attack.mitre.org/techniques/T1016/"
[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
Web Browser Credential Data Accessed by Unsigned or Untrusted Process
#Identifies an unsigned process accessing the password store of commonly used web browsers. Adversaries may steal credentials from web browsers by reading files specific to the target browser.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| macOS | ESF event open (NOTIFY): Fires after the kernel grants a process access to open a file. |
Rule Body
[rule]
description = """
Identifies an unsigned process accessing the password store of commonly used web browsers. Adversaries may steal
credentials from web browsers by reading files specific to the target browser.
"""
id = "ca46963e-c632-44cb-bb3c-a5f17a2b2c56"
license = "Elastic License v2"
name = "Web Browser Credential Data Accessed by Unsigned or Untrusted Process"
os_list = ["macos"]
reference = ["https://www.elastic.co/security-labs/beyond-the-wail"]
version = "1.0.16"
query = '''
file where event.action == "open" and process.executable != null and
file.name like~ ("cookies.sqlite",
"key?.db",
"logins.json",
"Cookies",
"Cookies.binarycookies",
"Login Data") and
(process.code_signature.trusted == false or process.code_signature.exists == false) and
not file.path like~ "/Users/*/Library/Application Support/Slack/Cookies" and
not process.code_signature.signing_id like "org.mozilla.firefox" and
not Effective_process.executable like "/Applications/Vorta.app/Contents/MacOS/vorta-darwin" and
not (process.executable like ("/opt/homebrew/*", "/Users/*/.cursor/extensions/openai.chatgpt-*-universal/bin/macos-aarch64/*", "/Users/*/.nvm/versions/node/v*/lib/node_modules/@anthropic-ai/claude-code/vendor/ripgrep/arm64-darwin/*", "/usr/local/lib/node_modules/@openai/codex/node_modules/@openai/codex-darwin-*/vendor/*/rg") and process.name == "rg") and
not process.executable like ("/opt/homebrew/Cellar/nss/*/bin/*", "/Library/Tanium/TaniumClient/*", "/Users/*/Library/Caches/ms-playwright/*/firefox/*") and
not process.code_signature.signing_id : ("rg-*", "rg")
'''
min_endpoint_version = "8.10.2"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1539"
name = "Steal Web Session Cookie"
reference = "https://attack.mitre.org/techniques/T1539/"
[[threat.technique]]
id = "T1555"
name = "Credentials from Password Stores"
reference = "https://attack.mitre.org/techniques/T1555/"
[[threat.technique.subtechnique]]
id = "T1555.003"
name = "Credentials from Web Browsers"
reference = "https://attack.mitre.org/techniques/T1555/003/"
[threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[internal]
min_endpoint_version = "8.10.2"
Stages and Predicates
Stage 1: file
file where event.action == "open" and process.executable != null and
file.name like~ ("cookies.sqlite",
"key?.db",
"logins.json",
"Cookies",
"Cookies.binarycookies",
"Login Data") and
(process.code_signature.trusted == false or process.code_signature.exists == false) and
not file.path like~ "/Users/*/Library/Application Support/Slack/Cookies" and
not process.code_signature.signing_id like "org.mozilla.firefox" and
not Effective_process.executable like "/Applications/Vorta.app/Contents/MacOS/vorta-darwin" and
not (process.executable like ("/opt/homebrew/*", "/Users/*/.cursor/extensions/openai.chatgpt-*-universal/bin/macos-aarch64/*", "/Users/*/.nvm/versions/node/v*/lib/node_modules/@anthropic-ai/claude-code/vendor/ripgrep/arm64-darwin/*", "/usr/local/lib/node_modules/@openai/codex/node_modules/@openai/codex-darwin-*/vendor/*/rg") and process.name == "rg") and
not process.executable like ("/opt/homebrew/Cellar/nss/*/bin/*", "/Library/Tanium/TaniumClient/*", "/Users/*/Library/Caches/ms-playwright/*/firefox/*") and
not process.code_signature.signing_id : ("rg-*", "rg")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"open" |
file.name | wildcard |
| field:"file.name" kind:wildcard |
process.code_signature.exists | eq |
| field:"process.code_signature.exists" kind:eq value:"false" |
process.code_signature.trusted | eq |
| field:"process.code_signature.trusted" kind:eq value:"false" |
process.executable | is_not_null | field:"Image" kind:is_not_null |
Exclusions
The rule actively suppresses these predicates.