Detection rules › Elastic
Elastic rules: 2l
Active Directory Group Modification by SYSTEM
#Identifies a user being added to an active directory group by the SYSTEM (S-1-5-18) user. This behavior can indicate that the attacker has achieved SYSTEM privileges in a domain controller, which attackers can obtain by exploiting vulnerabilities or abusing default group privileges (e.g., Server Operators), and is attempting to pivot to a domain account.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Privilege Escalation |
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Security-Auditing | Event ID 4728: A member was added to a security-enabled global group. |
Rule Body
[metadata]
creation_date = "2024/06/26"
integration = ["system", "windows"]
maturity = "production"
updated_date = "2026/05/04"
[rule]
author = ["Elastic"]
description = """
Identifies a user being added to an active directory group by the SYSTEM (S-1-5-18) user. This behavior can indicate
that the attacker has achieved SYSTEM privileges in a domain controller, which attackers can obtain by exploiting
vulnerabilities or abusing default group privileges (e.g., Server Operators), and is attempting to pivot to a domain
account.
"""
from = "now-9m"
index = ["logs-system.security*", "logs-windows.forwarded*", "winlogbeat-*"]
language = "eql"
license = "Elastic License v2"
name = "Active Directory Group Modification by SYSTEM"
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 Active Directory Group Modification by SYSTEM
Active Directory (AD) is a critical component in Windows environments, managing user and group permissions. SYSTEM, a high-privilege account, can modify AD groups, which attackers exploit to gain unauthorized access. By monitoring specific event logs for SYSTEM-initiated group changes, the detection rule identifies potential privilege escalation, signaling an attacker may have compromised a domain controller.
### Possible investigation steps
- Review the event log entry with event code 4728 to confirm the SYSTEM account (S-1-5-18) initiated the group modification.
- Identify the specific Active Directory group that was modified and determine if it is a sensitive or high-privilege group.
- Check for any recent changes or anomalies in the domain controller's security logs that might indicate SYSTEM privilege escalation.
- Investigate the timeline of events leading up to the group modification to identify any suspicious activities or patterns.
- Correlate this event with other security alerts or logs to assess if there is a broader attack pattern or campaign.
- Verify if there are any known vulnerabilities or misconfigurations in the domain controller that could have been exploited to gain SYSTEM privileges.
### False positive analysis
- Routine administrative tasks performed by automated scripts or scheduled tasks may trigger this rule. Review and document these tasks, then create exceptions for known benign scripts to prevent unnecessary alerts.
- System maintenance activities, such as software updates or system reconfigurations, might involve legitimate group modifications by SYSTEM. Coordinate with IT teams to identify and whitelist these activities.
- Certain security tools or monitoring solutions may perform group modifications as part of their normal operation. Verify these tools' actions and exclude them from triggering alerts if they are confirmed to be safe.
- In environments with custom applications that require SYSTEM-level access for group management, ensure these applications are documented and their actions are excluded from detection to avoid false positives.
- Regularly review and update the list of exceptions to ensure they remain relevant and do not inadvertently allow malicious activities to go undetected.
### Response and remediation
- Immediately isolate the affected domain controller from the network to prevent further unauthorized access or lateral movement by the attacker.
- Revoke any unauthorized group memberships added by the SYSTEM account to prevent privilege escalation and unauthorized access.
- Conduct a thorough review of recent changes in Active Directory, focusing on group modifications and user account activities, to identify any other potential unauthorized changes.
- Reset passwords for all accounts that were added to groups by the SYSTEM account to mitigate the risk of compromised credentials being used.
- Apply security patches and updates to the domain controller to address any vulnerabilities that may have been exploited to gain SYSTEM privileges.
- Monitor for any further suspicious activities or attempts to modify Active Directory groups, using enhanced logging and alerting mechanisms.
- Escalate the incident to the security operations center (SOC) or incident response team for a comprehensive investigation and to determine the full scope of the breach."""
risk_score = 47
rule_id = "6f024bde-7085-489b-8250-5957efdf1caf"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Use Case: Active Directory Monitoring",
"Data Source: Active Directory",
"Data Source: Windows Security Event Logs",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
iam where host.os.type == "windows" and event.code == "4728" and
winlog.event_data.SubjectUserSid : "S-1-5-18" and
/* DOMAIN_USERS and local groups */
not group.id : "S-1-5-21-*-513"
'''
setup = """## Setup
Audit Security Group Management must be enabled to generate the events used by this rule.
Setup instructions: https://ela.st/audit-security-group-management
"""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
Stages and Predicates
Stage 1: iam
iam where host.os.type == "windows" and event.code == "4728" and
winlog.event_data.SubjectUserSid : "S-1-5-18" and
not group.id : "S-1-5-21-*-513"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.code | eq |
| field:"EventID" kind:eq value:"4728" |
winlog.event_data.SubjectUserSid | wildcard |
| field:"SubjectUserSid" kind:wildcard value:"S-1-5-18" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
group.id | wildcard | S-1-5-21-*-513 | excludes:group.id field:"group.id" value:"S-1-5-21-*-513" |
AD Certificate Services Enumeration via LDAP
#Identifies a list of LDAP queries used to enumerate Active Directory Certificate Services as a preparation step to identify potential AD Certificate Service attack paths.
MITRE ATT&CK Coverage
Rule Body
[rule]
description = """
Identifies a list of LDAP queries used to enumerate Active Directory Certificate Services as a preparation step to
identify potential AD Certificate Service attack paths.
"""
id = "d5c1ecae-c25a-4ad5-b9e8-3d4fa8ffa25f"
license = "Elastic License v2"
name = "AD Certificate Services Enumeration via LDAP"
os_list = ["windows"]
reference = ["https://posts.specterops.io/bofhound-ad-cs-integration-91b706bc7958"]
version = "1.0.3"
query = '''
api where process.Ext.api.name == "ldap_search" and
process.Ext.api.parameters.attribute_list == "ntsecuritydescriptor" and
process.Ext.api.parameters.distinguished_name like "*cn=configuration*" and
process.Ext.api.parameters.search_filter : (
"(objectclass=pKIEnrollmentService)",
"(objectclass=certificationAuthority)",
"(objectclass=pKICertificateTemplate)",
"(objectclass=msPKI-Enterprise-Oid)"
) and
not (process.code_signature.subject_name == "Netwrix Corporation" and process.code_signature.trusted == true) and
not process.executable :
("?:\\Program Files\\Azure Advanced Threat Protection Sensor\\*\\Microsoft.Tri.Sensor.exe",
"?:\\Windows\\System32\\lsass.exe",
"?:\\Windows\\ADFS\\Microsoft.IdentityServer.ServiceHost.exe",
"?:\\Windows\\ADWS\\Microsoft.ActiveDirectory.WebServices.exe",
"?:\\Program Files\\Semperis\\Management Server\\Semperis.TaskServerSvcHost.exe")
'''
min_endpoint_version = "9.1.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1069"
name = "Permission Groups Discovery"
reference = "https://attack.mitre.org/techniques/T1069/"
[[threat.technique.subtechnique]]
id = "T1069.002"
name = "Domain Groups"
reference = "https://attack.mitre.org/techniques/T1069/002/"
[[threat.technique]]
id = "T1087"
name = "Account Discovery"
reference = "https://attack.mitre.org/techniques/T1087/"
[[threat.technique.subtechnique]]
id = "T1087.002"
name = "Domain Account"
reference = "https://attack.mitre.org/techniques/T1087/002/"
[[threat.technique]]
id = "T1482"
name = "Domain Trust Discovery"
reference = "https://attack.mitre.org/techniques/T1482/"
[threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
[internal]
min_endpoint_version = "9.1.0"
Stages and Predicates
Stage 1: api
api where process.Ext.api.name == "ldap_search" and
process.Ext.api.parameters.attribute_list == "ntsecuritydescriptor" and
process.Ext.api.parameters.distinguished_name like "*cn=configuration*" and
process.Ext.api.parameters.search_filter : (
"(objectclass=pKIEnrollmentService)",
"(objectclass=certificationAuthority)",
"(objectclass=pKICertificateTemplate)",
"(objectclass=msPKI-Enterprise-Oid)"
) and
not (process.code_signature.subject_name == "Netwrix Corporation" and process.code_signature.trusted == true) and
not process.executable :
("?:\\Program Files\\Azure Advanced Threat Protection Sensor\\*\\Microsoft.Tri.Sensor.exe",
"?:\\Windows\\System32\\lsass.exe",
"?:\\Windows\\ADFS\\Microsoft.IdentityServer.ServiceHost.exe",
"?:\\Windows\\ADWS\\Microsoft.ActiveDirectory.WebServices.exe",
"?:\\Program Files\\Semperis\\Management Server\\Semperis.TaskServerSvcHost.exe")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
process.Ext.api.name | eq |
| field:"process.Ext.api.name" kind:eq value:"ldap_search" |
process.Ext.api.parameters.attribute_list | eq |
| field:"process.Ext.api.parameters.attribute_list" kind:eq value:"ntsecuritydescriptor" |
process.Ext.api.parameters.distinguished_name | wildcard |
| field:"process.Ext.api.parameters.distinguished_name" kind:wildcard value:"*cn=configuration*" |
process.Ext.api.parameters.search_filter | wildcard |
| field:"process.Ext.api.parameters.search_filter" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.code_signature.subject_name | eq | Netwrix Corporation | excludes:process.code_signature.subject_name field:"process.code_signature.subject_name" value:"Netwrix Corporation" |
process.code_signature.trusted | eq | true | excludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true" |
process.executable | wildcard | ?:\Program Files\Azure Advanced Threat Protection Sensor\*\Microsoft.Tri.Sensor.exe, ?:\Windows\System32\lsass.exe, ?:\Windows\ADFS\Microsoft.IdentityServer.ServiceHost.exe, ?:\Windows\ADWS\Microsoft.ActiveDirectory.WebServices.exe, ?:\Program Files\Semperis\Management Server\Semperis.TaskServerSvcHost.exe | excludes:process.executable |
AWS CloudTrail Log Updated
#Detects updates to an existing CloudTrail trail via UpdateTrail API which may reduce visibility, change destinations, or weaken integrity (e.g., removing global events, moving the S3 destination, or disabling validation). Adversaries can modify trails to evade detection while maintaining a semblance of logging. Validate any configuration change against approved baselines.
Known False Positives
- Trail updates may be made by a system or network administrator. Verify whether the user identity, user agent, and/or hostname should be making changes in your environment. Trail updates 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 | |
| Collection | |
| Impact |
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/08/05"
[rule]
author = ["Elastic"]
description = """
Detects updates to an existing CloudTrail trail via UpdateTrail API which may reduce visibility, change destinations, or
weaken integrity (e.g., removing global events, moving the S3 destination, or disabling validation). Adversaries can
modify trails to evade detection while maintaining a semblance of logging. Validate any configuration change against
approved baselines.
"""
false_positives = [
"""
Trail updates may be made by a system or network administrator. Verify whether the user identity, user agent, and/or
hostname should be making changes in your environment. Trail updates 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 Updated"
note = """## Triage and analysis
### Investigating AWS CloudTrail Log Updated
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. Trail modifications can be used by attackers to redirect logs to non-approved buckets, drop regions, or disable valuable selectors. This rule identifies a modification on CloudTrail settings using the `UpdateTrail` API.
#### Possible investigation steps
- **Actor and context**
- Check `aws.cloudtrail.user_identity.arn`, `user_agent.original`, `source.ip`; verify approved change.
- **Assess the modification**
- In `aws.cloudtrail.request_parameters`, note changes to:
- `S3BucketName`, `CloudWatchLogsLogGroupArn`, `KmsKeyId`
- `IsMultiRegionTrail`, `IncludeGlobalServiceEvents`
- Event or insight selectors (management vs data events)
- **Correlate**
- Look for preceding `StopLogging` or following `DeleteTrail`.
- Review concurrent IAM policy edits or role changes by the same actor.
### False positive analysis
- **Planned changes**: Baseline drift during region onboarding or encryption rotation.
- **Automation**: IaC pipelines updating trails as templates evolve.
### Response and remediation
- **If unauthorized**
- Revert to baseline; validate destination ownership and KMS policy.
- Investigate time ranges where visibility may have been reduced.
- **Hardening**
- Constrain `cloudtrail:UpdateTrail`, require approvals, and monitor with AWS Config rules.
### 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_UpdateTrail.html",
"https://awscli.amazonaws.com/v2/documentation/api/latest/reference/cloudtrail/update-trail.html",
]
risk_score = 73
rule_id = "3e002465-876f-4f04-b016-84ef48ce7e5d"
severity = "high"
tags = [
"Domain: Cloud",
"Platform: AWS",
"Data Source: AWS CloudTrail",
"Tactic: Impact",
"Rule Type: Custom Query (KQL)",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset: "aws.cloudtrail"
and event.provider: "cloudtrail.amazonaws.com"
and event.action: "UpdateTrail"
and event.outcome: "success"
and not user_agent.original: (*Pulumi* or *Terraform*)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1565"
name = "Data Manipulation"
reference = "https://attack.mitre.org/techniques/T1565/"
[[rule.threat.technique.subtechnique]]
id = "T1565.001"
name = "Stored Data Manipulation"
reference = "https://attack.mitre.org/techniques/T1565/001/"
[rule.threat.tactic]
id = "TA0040"
name = "Impact"
reference = "https://attack.mitre.org/tactics/TA0040/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1530"
name = "Data from Cloud Storage"
reference = "https://attack.mitre.org/techniques/T1530/"
[rule.threat.tactic]
id = "TA0009"
name = "Collection"
reference = "https://attack.mitre.org/tactics/TA0009/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[[rule.threat.technique.subtechnique]]
id = "T1562.008"
name = "Disable or Modify Cloud Logs"
reference = "https://attack.mitre.org/techniques/T1562/008/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[rule.investigation_fields]
field_names = [
"@timestamp",
"user.name",
"user_agent.original",
"source.ip",
"aws.cloudtrail.user_identity.arn",
"aws.cloudtrail.user_identity.type",
"aws.cloudtrail.user_identity.access_key_id",
"event.action",
"event.outcome",
"cloud.account.id",
"cloud.region",
"aws.cloudtrail.request_parameters",
"aws.cloudtrail.response_elements",
]
Stages and Predicates
Stage 1: query
data_stream.dataset: "aws.cloudtrail"
and event.provider: "cloudtrail.amazonaws.com"
and event.action: "UpdateTrail"
and event.outcome: "success"
and not user_agent.original: (*Pulumi* or *Terraform*)
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:"UpdateTrail" |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"success" |
event.provider | eq |
| field:"Provider_Name" kind:eq value:"cloudtrail.amazonaws.com" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
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" |
AWS IAM Assume Role Policy Update
#Identifies AWS CloudTrail events where an IAM role's trust policy has been updated by an IAM user or Assumed Role identity. The trust policy is a JSON document that defines which principals are allowed to assume the role. An attacker may attempt to modify this policy to gain the privileges of the role. This is a New Terms rule, which means it will only trigger once for each unique combination of the "cloud.account.id", "user.name" and "entity.target.id" fields, that have not been seen making this API request.
Known False Positives
- Verify whether the user identity should be making changes in your environment. Policy updates from unfamiliar users should be investigated. If known behavior is causing false positives, it can be exempted from the rule.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Privilege Escalation |
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
Rule Body
[metadata]
creation_date = "2020/07/06"
integration = ["aws"]
maturity = "production"
updated_date = "2026/08/05"
min_stack_comments = "Changing min stack to 9.3.0, the latest minimum supported version for 9.X releases."
min_stack_version = "9.3.0"
[rule]
author = ["Elastic"]
description = """
Identifies AWS CloudTrail events where an IAM role's trust policy has been updated by an IAM user or Assumed Role
identity. The trust policy is a JSON document that defines which principals are allowed to assume the role. An attacker
may attempt to modify this policy to gain the privileges of the role. This is a New Terms rule, which means it will only
trigger once for each unique combination of the "cloud.account.id", "user.name" and "entity.target.id" fields, that have
not been seen making this API request.
"""
false_positives = [
"""
Verify whether the user identity should be making changes in your environment. Policy updates from unfamiliar users
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 IAM Assume Role Policy Update"
note = """## Triage and analysis
### Investigating AWS IAM Assume Role Policy Update
An IAM role is an IAM identity that you can create in your account that has specific permissions. An IAM role is similar to an IAM user, in that it is an AWS identity with permission policies that determine what the identity can and cannot do in AWS. However, instead of being uniquely associated with one person, a role is intended to be assumable by anyone who needs it. Also, a role does not have standard long-term credentials such as a password or access keys associated with it. Instead, when you assume a role, it provides you with temporary security credentials for your role session.
The role trust policy is a JSON document in which you define the principals you trust to assume the role. This policy is a required resource-based policy that is attached to a role in IAM. An attacker may attempt to modify this policy by using the `UpdateAssumeRolePolicy` API action to gain the privileges of that role.
#### Possible investigation steps
- Review the `aws.cloudtrail.user_identity.arn` to determine the IAM User that performed the action.
- If an AssumedRole identity type performed the action review the `aws.cloudtrail.user_identity.session_context.session_issuer.arn` field to determine which role was used.
- Review the `entity.target.id` field to confirm the role that was updated.
- Within the `aws.cloudtrail.request_parameters` field, review the `policyDocument` to understand the changes made to the trust policy.
- If `aws.cloudtrail.user_identity.access_key_id` is present, investigate the access key used to perform the action as it may be compromised.
- Identify the user account that performed the action and whether it should perform this kind of action.
- Investigate other alerts associated with the user account during the past 48 hours.
- Contact the account and resource owners and confirm whether they are aware of this activity.
- Check if this operation was approved and performed according to the organization's change management policy.
- If you suspect the account has been compromised, scope potentially compromised assets by tracking servers, services, and data accessed by the account in the last 24 hours.
### False positive analysis
- False positives may occur due to the intended usage of the service. Tuning is needed in order to have higher confidence. Consider adding exceptions — preferably with a combination of the user agent and user ID conditions — to cover administrator activities and infrastructure as code tooling.
### Response and remediation
- Initiate the incident response process based on the outcome of the triage.
- Disable or limit the account during the investigation and response.
- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context:
- Identify the account role in the cloud environment.
- Assess the criticality of affected services and servers.
- Work with your IT team to identify and minimize the impact on users.
- Identify if the attacker is moving laterally and compromising other accounts, servers, or services.
- Identify any regulatory or legal ramifications related to this activity.
- Use AWS [policy versioning](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-versioning.html) to restore the trust policy to the desired state.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords or delete API keys as needed to revoke the attacker's access to the environment. Work with your IT teams to minimize the impact on business operations during these actions.
- Check if unauthorized new users were created, remove unauthorized new accounts, and request password resets for other IAM users.
- Consider enabling multi-factor authentication for users.
- Review the permissions assigned to the implicated user to ensure that the least privilege principle is being followed.
- Implement security best practices [outlined](https://aws.amazon.com/premiumsupport/knowledge-center/security-best-practices/) by AWS.
- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
references = ["https://labs.bishopfox.com/tech-blog/5-privesc-attack-vectors-in-aws"]
risk_score = 21
rule_id = "a60326d7-dca7-4fb7-93eb-1ca03a1febbd"
severity = "low"
tags = [
"Domain: Cloud",
"Platform: AWS",
"Data Source: AWS CloudTrail",
"Service: AWS IAM",
"Tactic: Privilege Escalation",
"Rule Type: New Terms",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
data_stream.dataset: "aws.cloudtrail"
and event.provider: "iam.amazonaws.com"
and event.action: "UpdateAssumeRolePolicy"
and event.outcome: "success"
and not user_agent.original: (*Terraform* or *Pulumi*)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"
[[rule.threat.technique.subtechnique]]
id = "T1078.004"
name = "Cloud Accounts"
reference = "https://attack.mitre.org/techniques/T1078/004/"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[[rule.threat.technique.subtechnique]]
id = "T1098.003"
name = "Additional Cloud Roles"
reference = "https://attack.mitre.org/techniques/T1098/003/"
[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[[rule.threat.technique.subtechnique]]
id = "T1098.003"
name = "Additional Cloud Roles"
reference = "https://attack.mitre.org/techniques/T1098/003/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[rule.investigation_fields]
field_names = [
"@timestamp",
"user.name",
"user_agent.original",
"source.ip",
"aws.cloudtrail.user_identity.type",
"aws.cloudtrail.user_identity.arn",
"aws.cloudtrail.user_identity.access_key_id",
"entity.target.id",
"event.action",
"event.outcome",
"cloud.account.id",
"cloud.region",
"aws.cloudtrail.request_parameters",
]
[rule.new_terms]
field = "new_terms_fields"
value = ["cloud.account.id", "user.name", "entity.target.id"]
[[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: "iam.amazonaws.com"
and event.action: "UpdateAssumeRolePolicy"
and event.outcome: "success"
and not user_agent.original: (*Terraform* or *Pulumi*)
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:"UpdateAssumeRolePolicy" |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"success" |
event.provider | eq |
| field:"Provider_Name" kind:eq value:"iam.amazonaws.com" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
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 Diagnostic Settings Alert Suppression Rule Created or Modified
#Identifies the creation of suppression rules in Azure. Suppression rules are a mechanism used to suppress alerts previously identified as false positives or too noisy to be in production. This mechanism can be abused or mistakenly configured, resulting in defense evasions and loss of security visibility.
Known False Positives
- Suppression Rules can be created legitimately by a system administrator. Verify whether the user identity, user agent, and/or hostname should be making changes in your environment. Suppression Rules created by unfamiliar users 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
Rule Body
[metadata]
creation_date = "2021/08/27"
integration = ["azure"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Austin Songer"]
description = """
Identifies the creation of suppression rules in Azure. Suppression rules are a mechanism used to suppress alerts
previously identified as false positives or too noisy to be in production. This mechanism can be abused or mistakenly
configured, resulting in defense evasions and loss of security visibility.
"""
false_positives = [
"""
Suppression Rules can be created legitimately by a system administrator. Verify whether the user identity, user
agent, and/or hostname should be making changes in your environment. Suppression Rules created by unfamiliar users
should be investigated. If known behavior is causing false positives, it can be exempted from the rule.
""",
]
from = "now-9m"
index = ["logs-azure.activitylogs-*", "filebeat-*"]
language = "kuery"
license = "Elastic License v2"
name = "Azure Diagnostic Settings Alert Suppression Rule Created or Modified"
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Azure Diagnostic Settings Alert Suppression Rule Created or Modified
Azure Alert Suppression Rules are used to manage alert noise by filtering out known false positives. However, adversaries can exploit these rules to hide malicious activities by suppressing legitimate security alerts. The detection rule monitors Azure activity logs for successful operations related to suppression rule changes, helping identify potential misuse that could lead to defense evasion and reduced security visibility.
### Possible investigation steps
- Review the Azure activity logs to identify the specific suppression rule that was created or modified by filtering logs with the operation name "MICROSOFT.SECURITY/ALERTSSUPPRESSIONRULES/WRITE" and ensuring the event outcome is "success".
- Determine the identity of the user or service principal that performed the operation by examining the associated user or service account details in the activity logs.
- Investigate the context and justification for the creation or modification of the suppression rule by checking any related change management records or communications.
- Assess the impact of the suppression rule on security visibility by identifying which alerts are being suppressed and evaluating whether these alerts are critical for detecting potential threats.
- Cross-reference the suppression rule changes with recent security incidents or alerts to determine if there is any correlation or if the rule could have been used to hide malicious activity.
- Verify the legitimacy of the suppression rule by consulting with relevant stakeholders, such as security operations or cloud management teams, to confirm if the change was authorized and aligns with security policies.
### False positive analysis
- Routine maintenance activities by IT staff may trigger alerts when legitimate suppression rules are created or modified. To manage this, establish a baseline of expected changes and create exceptions for known maintenance periods or personnel.
- Automated processes or scripts that regularly update suppression rules for operational efficiency can generate false positives. Identify these processes and exclude their activity from alerting by using specific identifiers or tags associated with the automation.
- Changes made by trusted third-party security services that integrate with Azure might be flagged. Verify the legitimacy of these services and whitelist their operations to prevent unnecessary alerts.
- Frequent updates to suppression rules due to evolving security policies can lead to false positives. Document these policy changes and adjust the alerting criteria to accommodate expected modifications.
- Temporary suppression rules created during incident response to manage alert noise can be mistaken for malicious activity. Ensure these rules are documented and time-bound, and exclude them from alerting during the response period.
### Response and remediation
- Immediately review the Azure activity logs to confirm the creation or modification of the suppression rule and identify the user or service account responsible for the change.
- Temporarily disable the suspicious suppression rule to restore visibility into potential security alerts that may have been suppressed.
- Conduct a thorough investigation of recent alerts that were suppressed by the rule to determine if any malicious activities were overlooked.
- If malicious activity is confirmed, initiate incident response procedures to contain and remediate the threat, including isolating affected resources and accounts.
- Escalate the incident to the security operations team for further analysis and to assess the potential impact on the organization's security posture.
- Implement additional monitoring and alerting for changes to suppression rules to ensure any future modifications are promptly detected and reviewed.
- Review and update access controls and permissions for creating or modifying suppression rules to ensure only authorized personnel can make such changes.
## Setup
The Azure Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
references = [
"https://docs.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations",
"https://docs.microsoft.com/en-us/rest/api/securitycenter/alerts-suppression-rules/update",
]
risk_score = 21
rule_id = "f0bc081a-2346-4744-a6a4-81514817e888"
severity = "low"
tags = ["Domain: Cloud", "Data Source: Azure", "Use Case: Configuration Audit", "Tactic: Defense Evasion", "Resources: Investigation Guide"]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:azure.activitylogs and azure.activitylogs.operation_name:"MICROSOFT.SECURITY/ALERTSSUPPRESSIONRULES/WRITE" and
event.outcome: "success"
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[[rule.threat.technique.subtechnique]]
id = "T1562.001"
name = "Disable or Modify Tools"
reference = "https://attack.mitre.org/techniques/T1562/001/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Stage 1: query
data_stream.dataset:azure.activitylogs and azure.activitylogs.operation_name:"MICROSOFT.SECURITY/ALERTSSUPPRESSIONRULES/WRITE" and
event.outcome: "success"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
azure.activitylogs.operation_name | eq |
| field:"azure.activitylogs.operation_name" kind:eq value:"MICROSOFT.SECURITY/ALERTSSUPPRESSIONRULES/WRITE" |
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"azure.activitylogs" |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"success" |
Azure VNet Firewall Policy Deleted
#Identifies the deletion of a firewall policy in Azure. An adversary may delete a firewall policy in an attempt to evade defenses and/or to eliminate barriers to their objective.
Known False Positives
- Firewall policy deletions may be done by a system or network administrator. Verify whether the username, hostname, and/or resource name should be making changes in your environment. Firewall policy deletions by unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Azure | Activity Log event Microsoft.Network/firewallPolicies/delete: Deletes a Firewall Policy |
Rule Body
[metadata]
creation_date = "2020/08/18"
integration = ["azure"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
Identifies the deletion of a firewall policy in Azure. An adversary may delete a firewall policy in an attempt to evade
defenses and/or to eliminate barriers to their objective.
"""
false_positives = [
"""
Firewall policy deletions may be done by a system or network administrator. Verify whether the username, hostname,
and/or resource name should be making changes in your environment. Firewall policy deletions by unfamiliar users or
hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule.
""",
]
from = "now-9m"
index = ["logs-azure.activitylogs-*", "filebeat-*"]
language = "kuery"
license = "Elastic License v2"
name = "Azure VNet Firewall Policy Deleted"
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Azure VNet Firewall Policy Deleted
Azure Firewall policies are crucial for managing and enforcing network security rules across Azure environments. Adversaries may target these policies to disable security measures, facilitating unauthorized access or data exfiltration. The detection rule monitors Azure activity logs for successful deletion operations of firewall policies, signaling potential defense evasion attempts by identifying specific operation names and outcomes.
### Possible investigation steps
- Review the Azure activity logs to confirm the deletion event by filtering for the operation name "MICROSOFT.NETWORK/FIREWALLPOLICIES/DELETE" and ensuring the event outcome is "Success".
- Identify the user or service principal responsible for the deletion by examining the 'caller' field in the activity logs.
- Check the timestamp of the deletion event to determine when the policy was deleted and correlate it with other security events or alerts around the same time.
- Investigate the context of the deletion by reviewing any related activities performed by the same user or service principal, such as modifications to other security settings or unusual login patterns.
- Assess the impact of the deletion by identifying which resources or networks were protected by the deleted firewall policy and evaluating the potential exposure or risk introduced by its removal.
- Contact the responsible user or team to verify if the deletion was authorized and part of a planned change or if it was unexpected and potentially malicious.
### False positive analysis
- Routine maintenance or updates by authorized personnel can trigger the deletion event. Ensure that such activities are logged and verified by cross-referencing with change management records.
- Automated scripts or tools used for infrastructure management might delete and recreate firewall policies as part of their operation. Identify these scripts and exclude their activity from alerts by using specific identifiers or tags.
- Test environments often undergo frequent changes, including policy deletions. Consider excluding activity from known test environments by filtering based on resource group or subscription IDs.
- Scheduled policy updates or rotations might involve temporary deletions. Document these schedules and adjust monitoring rules to account for these expected changes.
- Ensure that any third-party integrations or services with permissions to modify firewall policies are accounted for, and their actions are reviewed and whitelisted if necessary.
### Response and remediation
- Immediately isolate the affected Azure resources to prevent further unauthorized access or data exfiltration. This can be done by applying restrictive network security group (NSG) rules or using Azure Security Center to quarantine resources.
- Review Azure activity logs to identify the user or service principal responsible for the deletion. Verify if the action was authorized and investigate any suspicious accounts or credentials.
- Restore the deleted firewall policy from backups or recreate it using predefined templates to ensure that network security rules are reinstated promptly.
- Implement conditional access policies to enforce multi-factor authentication (MFA) for all users with permissions to modify or delete firewall policies, reducing the risk of unauthorized changes.
- Escalate the incident to the security operations team for further investigation and to determine if additional resources or systems have been compromised.
- Conduct a post-incident review to identify gaps in security controls and update incident response plans to address similar threats in the future.
- Enhance monitoring by configuring alerts for any future attempts to delete or modify critical security policies, ensuring rapid detection and response to potential threats.
## Setup
The Azure Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
references = ["https://docs.microsoft.com/en-us/azure/firewall-manager/policy-overview"]
risk_score = 21
rule_id = "e02bd3ea-72c6-4181-ac2b-0f83d17ad969"
severity = "low"
tags = [
"Domain: Cloud",
"Data Source: Azure",
"Use Case: Network Security Monitoring",
"Tactic: Defense Evasion",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:azure.activitylogs and azure.activitylogs.operation_name:"MICROSOFT.NETWORK/FIREWALLPOLICIES/DELETE" and event.outcome:(Success or success)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[[rule.threat.technique.subtechnique]]
id = "T1562.007"
name = "Disable or Modify Cloud Firewall"
reference = "https://attack.mitre.org/techniques/T1562/007/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Stage 1: query
data_stream.dataset:azure.activitylogs and azure.activitylogs.operation_name:"MICROSOFT.NETWORK/FIREWALLPOLICIES/DELETE" and event.outcome:(Success or success)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
azure.activitylogs.operation_name | eq |
| field:"azure.activitylogs.operation_name" kind:eq value:"MICROSOFT.NETWORK/FIREWALLPOLICIES/DELETE" |
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"azure.activitylogs" |
event.outcome | in |
| field:"event.outcome" kind:in |
Creation of SettingContent-ms Files
#Identifies the suspicious creation of SettingContents-ms files, which have been used in attacks to achieve code execution while evading defenses.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Execution | |
| Stealth |
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 11: FileCreate |
Rule Body
[metadata]
bypass_bbr_timing = true
creation_date = "2023/08/24"
integration = ["endpoint", "windows"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
building_block_type = "default"
description = """
Identifies the suspicious creation of SettingContents-ms files, which have been used in attacks to achieve code
execution while evading defenses.
"""
from = "now-9m"
index = ["logs-endpoint.events.file-*", "logs-windows.sysmon_operational-*", "endgame-*", "winlogbeat-*"]
language = "eql"
license = "Elastic License v2"
name = "Creation of SettingContent-ms Files"
references = ["https://posts.specterops.io/the-tale-of-settingcontent-ms-files-f1ea253e4d39"]
risk_score = 21
rule_id = "1e6363a6-3af5-41d4-b7ea-d475389c0ceb"
severity = "low"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Execution",
"Data Source: Elastic Defend",
"Rule Type: BBR",
"Data Source: Sysmon",
"Data Source: Elastic Endgame",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
file where host.os.type == "windows" and event.type == "creation" and
file.extension : "settingcontent-ms" and
not file.path : (
"?:\\*\\AppData\\Local\\Packages\\windows.immersivecontrolpanel_*\\LocalState\\Indexed\\Settings\\*",
"\\Device\\HarddiskVolume*\\Windows\\WinSxS\\amd64_microsoft-windows-s..*\\*.settingcontent-ms"
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1203"
name = "Exploitation for Client Execution"
reference = "https://attack.mitre.org/techniques/T1203/"
[[rule.threat.technique]]
id = "T1204"
name = "User Execution"
reference = "https://attack.mitre.org/techniques/T1204/"
[[rule.threat.technique.subtechnique]]
id = "T1204.002"
name = "Malicious File"
reference = "https://attack.mitre.org/techniques/T1204/002/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1566"
name = "Phishing"
reference = "https://attack.mitre.org/techniques/T1566/"
[[rule.threat.technique.subtechnique]]
id = "T1566.001"
name = "Spearphishing Attachment"
reference = "https://attack.mitre.org/techniques/T1566/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 = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Stage 1: file
file where host.os.type == "windows" and event.type == "creation" and
file.extension : "settingcontent-ms" and
not file.path : (
"?:\\*\\AppData\\Local\\Packages\\windows.immersivecontrolpanel_*\\LocalState\\Indexed\\Settings\\*",
"\\Device\\HarddiskVolume*\\Windows\\WinSxS\\amd64_microsoft-windows-s..*\\*.settingcontent-ms"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"creation" |
file.extension | wildcard |
| field:"file.extension" kind:wildcard value:"settingcontent-ms" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
file.path | wildcard | ?:\*\AppData\Local\Packages\windows.immersivecontrolpanel_*\LocalState\Indexed\Settings\*, \Device\HarddiskVolume*\Windows\WinSxS\amd64_microsoft-windows-s..*\*.settingcontent-ms | excludes:file.path field:"file.path" value:"?:\*\AppData\Local\Packages\windows.immersivecontrolpanel_*\LocalState\Indexed\Settings\*" field:"file.path" value:"\Device\HarddiskVolume*\Windows\WinSxS\amd64_microsoft-windows-s..*\*.settingcontent-ms" |
Defense Evasion via Bind Mount
#Identifies the use of the "mount" command to bind mount a directory to "/proc" in order to hide files or processes from detection. This technique is used in the wild by malware samples to evade detection by hiding files or processes from security tools that rely on "/proc" to gather information about running processes.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Stealth |
Rule Body
[rule]
description = """
Identifies the use of the "mount" command to bind mount a directory to "/proc" in order to hide files or processes from
detection. This technique is used in the wild by malware samples to evade detection by hiding files or processes from
security tools that rely on "/proc" to gather information about running processes.
"""
id = "69b41dec-033a-4629-9b1d-dd2c54b507b9"
license = "Elastic License v2"
name = "Defense Evasion via Bind Mount"
os_list = ["linux"]
reference = ["https://dfir.ch/posts/slash-proc/"]
version = "1.0.6"
query = '''
process where event.type == "start" and event.action == "exec" and process.name == "mount" and
process.args in ("-B", "--bind", "-R", "--rbind", "-M", "--move") and
process.args like "/proc/*" and process.args_count >= 5 and not process.args like "/proc/*/*"
'''
min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
tree = true
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1564"
name = "Hide Artifacts"
reference = "https://attack.mitre.org/techniques/T1564/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: process
process where event.type == "start" and event.action == "exec" and process.name == "mount" and
process.args in ("-B", "--bind", "-R", "--rbind", "-M", "--move") and
process.args like "/proc/*" and process.args_count >= 5 and not process.args like "/proc/*/*"
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.args | in |
| field:"process.args" kind:in |
process.args | wildcard |
| field:"process.args" kind:wildcard value:"/proc/*" |
process.args_count | ge |
| field:"process.args_count" kind:ge value:"5" |
process.name | eq |
| field:"process_basename" kind:eq value:"mount" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | wildcard | /proc/*/* | excludes:process.args field:"process.args" value:"/proc/*/*" |
Execution of a File Dropped by OpenSSL
#Identifies when the OpenSSL utility creates a file followed by its execution. Malware authors may attempt to evade detection and trick users into executing malicious code by encoding and encrypting their payload and placing it in a disk image file. This behavior is consistent with adware or malware families such as Bundlore and Shlayer.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Stealth |
Telemetry Coverage
Rule Body
[rule]
description = """
Identifies when the OpenSSL utility creates a file followed by its execution. Malware authors may attempt to evade
detection and trick users into executing malicious code by encoding and encrypting their payload and placing it in a
disk image file. This behavior is consistent with adware or malware families such as Bundlore and Shlayer.
"""
id = "d2017990-b448-4617-8d4a-55aa45abe354"
license = "Elastic License v2"
name = "Execution of a File Dropped by OpenSSL"
os_list = ["macos"]
reference = ["https://attack.mitre.org/software/S0482/", "https://attack.mitre.org/software/S0402/"]
version = "1.0.25"
query = '''
sequence with maxspan=1m
[file where event.action != "deletion" and process.name == "openssl"] by file.path
[process where event.action == "exec"] by process.executable
'''
min_endpoint_version = "8.10.2"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1204"
name = "User Execution"
reference = "https://attack.mitre.org/techniques/T1204/"
[[threat.technique.subtechnique]]
id = "T1204.002"
name = "Malicious File"
reference = "https://attack.mitre.org/techniques/T1204/002/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1027"
name = "Obfuscated Files or Information"
reference = "https://attack.mitre.org/techniques/T1027/"
[[threat.technique]]
id = "T1140"
name = "Deobfuscate/Decode Files or Information"
reference = "https://attack.mitre.org/techniques/T1140/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "8.10.2"
Stages and Predicates
Ordered sequence: each step below must occur in order within 1m, correlated by file.path, process.executable.
Stage 1: file
[file where event.action != "deletion" and process.name == "openssl"] by file.path
Stage 2: process
[process where event.action == "exec"] by process.executable
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.action | ne |
| field:"EventType" kind:ne value:"deletion" |
process.name | eq |
| field:"process_basename" kind:eq value:"openssl" |
Execution via Electron Child Process Node.js Module
#Identifies attempts to execute a child process from within the context of an Electron application using the child_process Node.js module. Adversaries may abuse this technique to inherit permissions from parent processes.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Privilege Escalation |
Rule Body
[metadata]
creation_date = "2020/01/07"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
Identifies attempts to execute a child process from within the context of an Electron application using the
child_process Node.js module. Adversaries may abuse this technique to inherit permissions from parent processes.
"""
from = "now-9m"
index = ["logs-endpoint.events.*"]
language = "eql"
license = "Elastic License v2"
name = "Execution via Electron Child Process Node.js Module"
references = [
"https://www.matthewslipper.com/2019/09/22/everything-you-wanted-electron-child-process.html",
"https://www.trustedsec.com/blog/macos-injection-via-third-party-frameworks/",
"https://nodejs.org/api/child_process.html",
]
risk_score = 47
rule_id = "35330ba2-c859-4c98-8b7f-c19159ea0e58"
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: Defense Evasion",
"Tactic: Execution",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "macos" and event.type in ("start", "process_started") and
process.args == "-e" and process.args : "const*require*child_process*"
'''
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Execution via Electron Child Process Node.js Module
Electron applications, built on Node.js, can execute child processes using the `child_process` module, inheriting parent process permissions. Adversaries exploit this to execute unauthorized commands, bypassing security controls. The detection rule identifies suspicious process starts on macOS, focusing on command-line arguments indicative of such abuse, aiding in threat detection and mitigation.
### Possible investigation steps
- Review the process arguments captured in the alert to confirm the presence of suspicious patterns, such as the use of "-e" and the inclusion of "require('child_process')".
- Identify the parent Electron application process to determine if it is a legitimate application or potentially malicious.
- Check the user account associated with the process to assess if it has elevated privileges that could be exploited.
- Investigate the command executed by the child process to understand its purpose and potential impact on the system.
- Correlate the alert with other security events or logs from the same host to identify any related suspicious activities or patterns.
- Examine the network activity of the host around the time of the alert to detect any unauthorized data exfiltration or communication with known malicious IPs.
### False positive analysis
- Legitimate Electron applications may use the child_process module for valid operations, such as launching helper scripts or tools. Users should identify and whitelist these known applications to prevent unnecessary alerts.
- Development environments often execute scripts using child_process during testing or debugging. Exclude processes originating from development directories or environments to reduce false positives.
- Automated build or deployment tools running on macOS might invoke child processes as part of their workflow. Recognize and exclude these tools by their process names or paths.
- Some Electron-based applications might use command-line arguments that match the detection pattern for legitimate reasons. Review and adjust the detection rule to exclude these specific argument patterns when associated with trusted applications.
- Regularly review and update the exclusion list to accommodate new legitimate use cases as they arise, ensuring that the detection rule remains effective without generating excessive false positives.
### Response and remediation
- Immediately isolate the affected macOS system from the network to prevent further unauthorized command execution and potential lateral movement.
- Terminate any suspicious child processes identified as being spawned by the Electron application to halt any ongoing malicious activity.
- Conduct a thorough review of the Electron application's code and configuration to identify and remove any unauthorized or malicious scripts or modules, particularly those involving the `child_process` module.
- Revoke and reset any credentials or tokens that may have been exposed or compromised due to the unauthorized execution, ensuring that new credentials are distributed securely.
- Apply security patches and updates to the Electron application and underlying Node.js environment to mitigate any known vulnerabilities that could be exploited in a similar manner.
- Enhance monitoring and logging on the affected system and similar environments to detect any future attempts to exploit the `child_process` module, focusing on command-line arguments and process creation events.
- Escalate the incident to the security operations team for further investigation and to determine if additional systems or data have been impacted, ensuring a comprehensive response to the threat."""
[[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.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1548"
name = "Abuse Elevation Control Mechanism"
reference = "https://attack.mitre.org/techniques/T1548/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Stage 1: process
process where host.os.type == "macos" and event.type in ("start", "process_started") and
process.args == "-e" and process.args : "const*require*child_process*"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | in |
| field:"event.type" kind:in |
process.args | eq |
| field:"process.args" kind:eq value:"-e" |
process.args | wildcard |
| field:"process.args" kind:wildcard value:"const*require*child_process*" |
Exploit - Prevented - Elastic Endgame
#Elastic Endgame prevented an Exploit. Click the Elastic Endgame icon in the event.module column or the link in the rule.reference column for additional information.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Privilege Escalation |
Rule Body
[metadata]
creation_date = "2020/02/18"
maturity = "production"
promotion = true
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
Elastic Endgame prevented an Exploit. Click the Elastic Endgame icon in the event.module column or the link in the
rule.reference column for additional information.
"""
from = "now-2m"
index = ["endgame-*"]
interval = "1m"
language = "kuery"
license = "Elastic License v2"
max_signals = 1000
name = "Exploit - Prevented - Elastic Endgame"
risk_score = 47
rule_id = "2863ffeb-bf77-44dd-b7a5-93ef94b72036"
setup = """## Setup
### Additional notes
For information on troubleshooting the maximum alerts warning please refer to this [guide](https://www.elastic.co/guide/en/security/current/alerts-ui-monitor.html#troubleshoot-max-alerts).
"""
severity = "medium"
tags = [
"Data Source: Elastic Endgame",
"Use Case: Threat Detection",
"Tactic: Execution",
"Tactic: Privilege Escalation",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
event.kind:alert and event.module:endgame and endgame.metadata.type:prevention and (event.action:exploit_event or endgame.event_subtype_full:exploit_event)
'''
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Exploit - Prevented - Elastic Endgame
Elastic Endgame is a security solution designed to prevent exploits by monitoring and analyzing system behaviors. Adversaries often exploit vulnerabilities to execute unauthorized code or escalate privileges. This detection rule identifies prevention events where an exploit attempt was blocked, focusing on alerts from the Endgame module. By analyzing specific event actions and metadata, it helps security analysts quickly identify and respond to potential threats, ensuring system integrity and security.
### Possible investigation steps
- Review the alert details to confirm the event.kind is 'alert' and event.module is 'endgame', ensuring the alert is relevant to the Elastic Endgame module.
- Examine the endgame.metadata.type field to verify it is marked as 'prevention', indicating that the exploit attempt was successfully blocked.
- Analyze the event.action and endgame.event_subtype_full fields to determine the specific type of exploit event that was attempted, such as 'exploit_event'.
- Investigate the source and destination IP addresses, user accounts, and hostnames involved in the alert to identify potential points of compromise or targets.
- Check for any related alerts or logs within the same timeframe to identify patterns or additional indicators of compromise that may suggest a broader attack campaign.
- Assess the risk score and severity level to prioritize the investigation and determine if immediate action is required to mitigate potential threats.
- Document findings and any actions taken in response to the alert to maintain a comprehensive record for future reference and analysis.
### False positive analysis
- Routine software updates or patches may trigger prevention alerts as they modify system files or configurations. Review the update schedule and correlate alerts with known maintenance windows to verify legitimacy.
- Legitimate administrative tools or scripts that perform actions similar to exploit techniques can be flagged. Identify these tools and create exceptions for their known behaviors to reduce noise.
- Security testing or vulnerability scanning activities might mimic exploit attempts. Coordinate with IT and security teams to whitelist these activities during scheduled assessments.
- Custom applications with unique behaviors may be misidentified as threats. Work with development teams to understand these behaviors and adjust detection rules or create exceptions accordingly.
- Frequent alerts from specific systems or users could indicate a misconfiguration. Investigate these patterns and adjust system settings or user permissions to align with security policies.
### Response and remediation
- Immediately isolate the affected system from the network to prevent further exploitation or lateral movement by the adversary.
- Verify the integrity of critical system files and applications on the affected system to ensure no unauthorized changes have been made.
- Apply the latest security patches and updates to the affected system to address any known vulnerabilities that may have been targeted.
- Conduct a thorough review of user accounts and privileges on the affected system to identify and revoke any unauthorized access or privilege escalation.
- Restore the affected system from a known good backup if any unauthorized changes or exploit attempts have compromised system integrity.
- Monitor the network and system logs for any signs of similar exploit attempts or related suspicious activities to ensure no further threats are present.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if additional systems may be at risk."""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1203"
name = "Exploitation for Client Execution"
reference = "https://attack.mitre.org/techniques/T1203/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[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.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
Stages and Predicates
Stage 1: query
event.kind:alert and event.module:endgame and endgame.metadata.type:prevention and (event.action:exploit_event or endgame.event_subtype_full:exploit_event)
Indicators
These rows show field, operator, and value matches.
File Creation and Execution Detected via Defend for Containers
#This rule detects when a process creates a file inside of a running container, followed by its execution. This could indicate a potential container breakout attempt, an attacker's attempt to gain unauthorized access to the underlying host, or to evade detection by security controls.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Command & Control |
Rule Body
[metadata]
creation_date = "2026/02/06"
integration = ["cloud_defend"]
maturity = "production"
min_stack_comments = "Defend for Containers integration was re-introduced in 9.3.0"
min_stack_version = "9.3.0"
updated_date = "2026/07/29"
[rule]
author = ["Elastic"]
description = """
This rule detects when a process creates a file inside of a running container, followed by its execution.
This could indicate a potential container breakout attempt, an attacker's attempt to gain unauthorized access to the
underlying host, or to evade detection by security controls.
"""
from = "now-6m"
index = ["logs-cloud_defend.process*", "logs-cloud_defend.file*"]
interval = "5m"
language = "eql"
license = "Elastic License v2"
name = "File Creation and Execution Detected via Defend for Containers"
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating File Creation and Execution Detected via Defend for Containers
This detects activity inside a running Linux container creating a new file and then executing it moments later, a pattern that often signals hands-on intrusion rather than routine automation. Attackers commonly use an `exec` shell into a pod/container to drop a small script or ELF payload (for reverse shell, credential theft, or host discovery) and run it immediately to establish control or stage a breakout attempt.
### Possible investigation steps
- Correlate the alert time with container runtime and Kubernetes audit logs to identify who started the interactive session (user/service account), from where (source IP), and via what mechanism (kubectl exec/attach, docker exec).
- Acquire the newly created file from the container filesystem, record hash/size/permissions, and analyze its contents to determine whether it is a script, ELF payload, or staged dropper.
- Reconstruct the execution chain by reviewing the process tree and interactive shell artifacts (TTY, environment, shell history) to understand the operator’s commands before and after running the file.
- Inspect the container’s network activity immediately following execution (DNS lookups, new outbound connections, unusual ports/destinations) to confirm or rule out command-and-control or payload download behavior.
- Validate whether the activity indicates privilege escalation or breakout by checking the node and container for access to sensitive host interfaces (e.g., docker.sock, hostPath mounts, /proc probing) and contain the workload if present.
### False positive analysis
- A developer or SRE uses an interactive shell in the container to create or modify a script/binary for debugging (e.g., `cat`/heredoc/vim writing to `/tmp` or the app directory) and then immediately runs it to reproduce an issue or validate a fix.
- An operator performs interactive break-glass maintenance by manually writing a short helper script (log collection, configuration validation, one-off remediation) inside the container and executing it right after creation to restore service during an incident.
### Response and remediation
- Immediately isolate the affected workload by cordoning and draining the node or applying a deny-all network policy to the pod/namespace, then terminate the interactive session and stop the container to prevent further execution.
- Preserve evidence by snapshotting the container filesystem and collecting the created file and any adjacent artifacts (shell history, temp directories, downloaded tools), then compute hashes and submit the file for malware analysis.
- Eradicate by deleting the compromised pod/container and redeploying from a known-good image, rotating any credentials that may have been exposed in the container environment, and blocking the observed outbound destinations if C2 behavior is present.
- Escalate to incident response immediately if the executed file attempts host interaction (e.g., accesses docker.sock, /proc, hostPath mounts) or if you observe new privileged containers, node-level processes, or lateral movement to other pods/namespaces.
- Harden by restricting interactive exec/attach to a small admin group with MFA, enforcing Pod Security/Admission policies to disallow privileged/host mounts, and enabling runtime controls to block execution from writable paths like /tmp and /dev/shm."""
risk_score = 47
rule_id = "b799720e-40d0-4dd6-9c9c-4f193a6ed643"
severity = "medium"
tags = [
"Data Source: Elastic Defend for Containers",
"Domain: Container",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Execution",
"Tactic: Command and Control",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
sequence by container.id, user.id with maxspan=3s
[file where host.os.type == "linux" and event.type == "creation" and container.id like "?*" and
file.path like ("/tmp/*", "/var/tmp/*", "/dev/shm/*", "/root/*", "/home/*") and
not process.name in ("apt", "apt-get", "dnf", "microdnf", "yum", "zypper", "tdnf", "apk", "pacman", "rpm", "dpkg")] by file.path
[process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and
container.id like "?*"] by process.executable
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[rule.threat.tactic]
name = "Execution"
id = "TA0002"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[rule.threat.tactic]
name = "Command and Control"
id = "TA0011"
reference = "https://attack.mitre.org/tactics/TA0011/"
[[rule.threat.technique]]
name = "Application Layer Protocol"
id = "T1071"
reference = "https://attack.mitre.org/techniques/T1071/"
Stages and Predicates
Ordered sequence: each step below must occur in order within 3s, correlated by container.id, file.path, process.executable, user.id.
Stage 1: file
[file where host.os.type == "linux" and event.type == "creation" and container.id like "?*" and
file.path like ("/tmp/*", "/var/tmp/*", "/dev/shm/*", "/root/*", "/home/*") and
not process.name in ("apt", "apt-get", "dnf", "microdnf", "yum", "zypper", "tdnf", "apk", "pacman", "rpm", "dpkg")] by file.path
Stage 2: process
[process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and
container.id like "?*"] by process.executable
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
container.id | wildcard |
| field:"container.id" kind:wildcard value:"?*" |
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.type | eq |
| field:"event.type" kind:eq |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.name | in | apk, apt, apt-get, dnf, dpkg, microdnf, pacman, rpm, tdnf, yum, zypper | excludes:process.name |
M365 Exchange DKIM Signing Configuration Disabled
#Identifies when a DomainKeys Identified Mail (DKIM) signing configuration is disabled in Microsoft 365. With DKIM in Microsoft 365, messages that are sent from Exchange Online will be cryptographically signed. This will allow the receiving email system to validate that the messages were generated by a server that the organization authorized and were not spoofed.
Known False Positives
- Disabling a DKIM configuration may be done by a system or network administrator. Verify that the configuration change was expected. Exceptions can be added to this rule to filter expected behavior.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Privilege Escalation | |
| Defense Impairment |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Microsoft 365 | Exchange audit operation Set-DkimSigningConfig: Federated domain added |
Rule Body
[metadata]
creation_date = "2020/11/18"
integration = ["o365"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
Identifies when a DomainKeys Identified Mail (DKIM) signing configuration is disabled in Microsoft 365. With DKIM in
Microsoft 365, messages that are sent from Exchange Online will be cryptographically signed. This will allow the
receiving email system to validate that the messages were generated by a server that the organization authorized and
were not spoofed.
"""
false_positives = [
"""
Disabling a DKIM configuration may be done by a system or network administrator. Verify that the configuration
change was expected. Exceptions can be added to this rule to filter expected behavior.
""",
]
from = "now-9m"
index = ["logs-o365.audit-*", "filebeat-*"]
language = "kuery"
license = "Elastic License v2"
name = "M365 Exchange DKIM Signing Configuration Disabled"
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 M365 Exchange DKIM Signing Configuration Disabled
DomainKeys Identified Mail (DKIM) is a security protocol that ensures email authenticity by allowing recipients to verify that messages are sent from authorized servers. Disabling DKIM can expose organizations to email spoofing, where attackers impersonate legitimate domains to conduct phishing attacks. The detection rule identifies when DKIM is disabled in Microsoft 365, signaling potential unauthorized changes that could facilitate persistent threats.
### Possible investigation steps
- Review the audit logs in Microsoft 365 to identify the user or service account associated with the event.action "Set-DkimSigningConfig" where o365.audit.Parameters.Enabled is False. This will help determine who or what initiated the change.
- Check the event.timestamp to establish when the DKIM signing configuration was disabled and correlate this with any other suspicious activities or changes in the environment around the same time.
- Investigate the event.outcome field to confirm that the action was successful and not a failed attempt, which could indicate a misconfiguration or unauthorized access attempt.
- Examine the event.provider and event.category fields to ensure that the event is specifically related to Exchange and web actions, confirming the context of the alert.
- Assess the risk score and severity level to prioritize the investigation and determine if immediate action is required to mitigate potential threats.
- Look into any recent changes in administrative roles or permissions that could have allowed unauthorized users to disable DKIM signing, focusing on persistence tactics as indicated by the MITRE ATT&CK framework reference.
### False positive analysis
- Routine administrative changes: Sometimes, DKIM signing configurations may be disabled temporarily during routine maintenance or updates by authorized IT personnel. To manage this, establish a process to document and approve such changes, and create exceptions in the monitoring system for these documented events.
- Testing and troubleshooting: IT teams may disable DKIM as part of testing or troubleshooting email configurations. Ensure that these activities are logged and approved, and consider setting up alerts that differentiate between test environments and production environments to reduce noise.
- Configuration migrations: During migrations to new email systems or configurations, DKIM may be disabled as part of the transition process. Implement a change management protocol that includes notifying the security team of planned migrations, allowing them to temporarily adjust monitoring rules.
- Third-party integrations: Some third-party email services may require DKIM to be disabled temporarily for integration purposes. Maintain a list of approved third-party services and create exceptions for these specific cases, ensuring that the security team is aware of and has approved the integration.
### Response and remediation
- Immediately re-enable DKIM signing for the affected domain in Microsoft 365 to restore email authenticity and prevent potential spoofing attacks.
- Conduct a review of recent administrative activities in Microsoft 365 to identify any unauthorized changes or suspicious behavior that may have led to the DKIM configuration being disabled.
- Notify the security team and relevant stakeholders about the incident, providing details of the unauthorized change and potential risks associated with it.
- Implement additional monitoring on the affected domain and related accounts to detect any further unauthorized changes or suspicious activities.
- Review and update access controls and permissions for administrative accounts in Microsoft 365 to ensure that only authorized personnel can modify DKIM settings.
- Escalate the incident to the organization's incident response team for further investigation and to determine if any additional security measures are necessary.
- Consider implementing additional email security measures, such as SPF and DMARC, to complement DKIM and enhance overall email security posture.
## Setup
The Office 365 Logs Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
references = [
"https://docs.microsoft.com/en-us/powershell/module/exchange/set-dkimsigningconfig?view=exchange-ps",
]
risk_score = 47
rule_id = "514121ce-c7b6-474a-8237-68ff71672379"
severity = "medium"
tags = ["Domain: Cloud", "Data Source: Microsoft 365", "Tactic: Defense Evasion", "Resources: Investigation Guide"]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:o365.audit and event.provider:Exchange and event.category:web and event.action:"Set-DkimSigningConfig" and o365.audit.Parameters.Enabled:False and event.outcome:success
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1484"
name = "Domain or Tenant Policy Modification"
reference = "https://attack.mitre.org/techniques/T1484/"
[[rule.threat.technique]]
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: query
data_stream.dataset:o365.audit and event.provider:Exchange and event.category:web and event.action:"Set-DkimSigningConfig" and o365.audit.Parameters.Enabled:False and event.outcome:success
Indicators
These rows show field, operator, and value matches.
Modification of Persistence Relevant Files Detected via Defend for Containers
#This rule detects attempts from within a Linux container to create or modify files commonly used for persistence on native Linux systems, including cron jobs, systemd units, sudoers files, and shell profile configurations. While many of these mechanisms do not provide reliable persistence in typical containerized workloads, such modifications are unusual and may indicate persistence attempts, privilege abuse, or preparation for container escape, especially when performed outside normal image build or package management processes.
MITRE ATT&CK Coverage
Rule Body
[metadata]
creation_date = "2026/02/10"
integration = ["cloud_defend"]
maturity = "production"
min_stack_comments = "Defend for Containers integration was re-introduced in 9.3.0"
min_stack_version = "9.3.0"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
This rule detects attempts from within a Linux container to create or modify files commonly used for
persistence on native Linux systems, including cron jobs, systemd units, sudoers files, and shell
profile configurations. While many of these mechanisms do not provide reliable persistence in typical
containerized workloads, such modifications are unusual and may indicate persistence attempts, privilege
abuse, or preparation for container escape, especially when performed outside normal image build or
package management processes.
"""
from = "now-6m"
index = ["logs-cloud_defend.file*"]
interval = "5m"
language = "eql"
license = "Elastic License v2"
name = "Modification of Persistence Relevant Files Detected via Defend for Containers"
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Modification of Persistence Relevant Files Detected via Defend for Containers
This detection flags a process inside a Linux container creating or modifying files tied to host-style persistence and privilege control, such as cron schedules, systemd units, sudoers, or shell startup profiles. These changes rarely belong in normal container runtime behavior, so they often signal an attacker staging long-lived execution, escalating privileges, or preparing an escape path. A common pattern is dropping a new `/etc/cron.d/*` entry that periodically launches a payload or backconnects.
### Possible investigation steps
- Review the modifying process’s full command line, parent/ancestor chain, effective UID, and container entrypoint to determine whether it aligns with expected runtime behavior or indicates an interactive shell/exploit.
- Pull the before/after contents of the changed file and look for execution hooks (cron command, systemd ExecStart, sudoers NOPASSWD, or shell profile stagers), then extract any referenced binaries, users, paths, or URLs for follow-on hunting.
- Determine whether the container is privileged or has elevated capabilities and sensitive host mounts (e.g., `/etc`, `/var/run/docker.sock`, `/proc`, `/sys`) that would make the change meaningful for host persistence or escape attempts.
- Correlate the modification time with nearby activity from the same container (process spawns, tool downloads, outbound connections, and interactive access such as `kubectl exec`) to reconstruct the sequence and probable entry vector.
- Check for the same change across replicas/nodes and in the image/build pipeline, and if the modification is unapproved, isolate and redeploy from a known-good image while preserving artifacts for analysis.
### False positive analysis
- An application container running as root updates shell startup files (e.g., `/root/.bashrc`, `/etc/profile.d/*`) at runtime to enforce environment variables, PATH changes, or interactive defaults for troubleshooting, triggering a write/open event without any persistence intent.
- A container startup/entrypoint script generates or adjusts cron/systemd-related files (e.g., `/etc/cron.d/*`, `/etc/systemd/system/*.service`) to schedule internal maintenance tasks or align configuration on first boot, causing file creations/renames outside package-manager processes.
### Response and remediation
- Quarantine the affected workload by scaling the deployment to zero or applying a deny-all egress policy, and isolate the node if the container was privileged or had host filesystem mounts that could make the persistence change impact the host.
- Preserve evidence by exporting the modified persistence-related file(s) (e.g., `/etc/cron.d/*`, `/etc/sudoers*`, systemd unit/timer, shell profile) and collecting the writing process binary, command line, environment, and a short window of process and network activity from the container.
- Eradicate by deleting or reverting the unauthorized cron/systemd/sudoers/profile changes, removing any referenced payload binaries/scripts, revoking any newly added users/keys/tokens, and rotating credentials used by the container or mounted into it.
- Recover by redeploying the service from a known-good image and clean configuration (ConfigMaps/Secrets), validating that no persistence files are modified at runtime and that outbound connections and scheduled executions return to expected behavior.
- Escalate to incident response immediately if the change grants passwordless sudo, drops a new systemd unit/timer or cron job that executes a network-capable command, or if the container is privileged/has `/var/run/docker.sock` or host `/etc` mounted, as this may indicate attempted host persistence or escape.
- Harden by enforcing read-only root filesystem and non-root execution, restricting capabilities/privileged mode and sensitive host mounts, and adding policy controls to block writes to `/etc/cron*`, `/etc/sudoers*`, systemd paths, and shell profiles outside the image build pipeline."""
references = [
"https://flare.io/learn/resources/blog/teampcp-cloud-native-ransomware",
]
risk_score = 21
rule_id = "f246e70e-5e20-4006-8460-d72b023d6adf"
severity = "low"
tags = [
"Data Source: Elastic Defend for Containers",
"Domain: Container",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Tactic: Execution",
"Tactic: Privilege Escalation",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
file where event.type != "deletion" and
/* open events currently only log file opens with write intent */
event.action in ("creation", "rename", "open") and (
file.path like (
// Cron & Anacron Jobs
"/etc/cron.allow", "/etc/cron.deny", "/etc/cron.d/*", "/etc/cron.hourly/*", "/etc/cron.daily/*",
"/etc/cron.weekly/*", "/etc/cron.monthly/*", "/etc/crontab", "/var/spool/cron/crontabs/*",
"/var/spool/anacron/*",
// At Job
"/var/spool/cron/atjobs/*", "/var/spool/atjobs/*",
// Sudoers
"/etc/sudoers*"
) or
(
// Systemd Service/Timer
file.path like (
"/etc/systemd/system/*", "/etc/systemd/user/*", "/usr/local/lib/systemd/system/*",
"/lib/systemd/system/*", "/usr/lib/systemd/system/*", "/usr/lib/systemd/user/*",
"/home/*/.config/systemd/user/*", "/home/*/.local/share/systemd/user/*",
"/root/.config/systemd/user/*", "/root/.local/share/systemd/user/*"
) and
file.extension in ("service", "timer")
) or
(
// Shell Profile Configuration
file.path like ("/etc/profile.d/*", "/etc/zsh/*") or (
file.path like ("/home/*/*", "/etc/*", "/root/*") and
file.name in (
"profile", "bash.bashrc", "bash.bash_logout", "csh.cshrc", "csh.login", "config.fish", "ksh.kshrc",
".bashrc", ".bash_login", ".bash_logout", ".bash_profile", ".bash_aliases", ".zprofile", ".zshrc",
".cshrc", ".login", ".logout", ".kshrc"
)
)
)
) and container.id like "?*" and
not process.name in ("apt", "apt-get", "dnf", "microdnf", "yum", "zypper", "tdnf", "apk", "pacman", "rpm", "dpkg")
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1037"
name = "Boot or Logon Initialization Scripts"
reference = "https://attack.mitre.org/techniques/T1037/"
[[rule.threat.technique]]
id = "T1053"
name = "Scheduled Task/Job"
reference = "https://attack.mitre.org/techniques/T1053/"
[[rule.threat.technique.subtechnique]]
id = "T1053.002"
name = "At"
reference = "https://attack.mitre.org/techniques/T1053/002/"
[[rule.threat.technique.subtechnique]]
id = "T1053.003"
name = "Cron"
reference = "https://attack.mitre.org/techniques/T1053/003/"
[[rule.threat.technique.subtechnique]]
id = "T1053.006"
name = "Systemd Timers"
reference = "https://attack.mitre.org/techniques/T1053/006/"
[[rule.threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"
[[rule.threat.technique.subtechnique]]
id = "T1543.002"
name = "Systemd Service"
reference = "https://attack.mitre.org/techniques/T1543/002/"
[[rule.threat.technique]]
id = "T1546"
name = "Event Triggered Execution"
reference = "https://attack.mitre.org/techniques/T1546/"
[[rule.threat.technique.subtechnique]]
id = "T1546.004"
name = "Unix Shell Configuration Modification"
reference = "https://attack.mitre.org/techniques/T1546/004/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1053"
name = "Scheduled Task/Job"
reference = "https://attack.mitre.org/techniques/T1053/"
[[rule.threat.technique.subtechnique]]
id = "T1053.002"
name = "At"
reference = "https://attack.mitre.org/techniques/T1053/002/"
[[rule.threat.technique.subtechnique]]
id = "T1053.003"
name = "Cron"
reference = "https://attack.mitre.org/techniques/T1053/003/"
[[rule.threat.technique.subtechnique]]
id = "T1053.006"
name = "Systemd Timers"
reference = "https://attack.mitre.org/techniques/T1053/006/"
[[rule.threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"
[[rule.threat.technique.subtechnique]]
id = "T1543.002"
name = "Systemd Service"
reference = "https://attack.mitre.org/techniques/T1543/002/"
[[rule.threat.technique]]
id = "T1548"
name = "Abuse Elevation Control Mechanism"
reference = "https://attack.mitre.org/techniques/T1548/"
[[rule.threat.technique.subtechnique]]
id = "T1548.003"
name = "Sudo and Sudo Caching"
reference = "https://attack.mitre.org/techniques/T1548/003/"
[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 = "T1053"
name = "Scheduled Task/Job"
reference = "https://attack.mitre.org/techniques/T1053/"
[[rule.threat.technique.subtechnique]]
id = "T1053.002"
name = "At"
reference = "https://attack.mitre.org/techniques/T1053/002/"
[[rule.threat.technique.subtechnique]]
id = "T1053.003"
name = "Cron"
reference = "https://attack.mitre.org/techniques/T1053/003/"
[[rule.threat.technique.subtechnique]]
id = "T1053.006"
name = "Systemd Timers"
reference = "https://attack.mitre.org/techniques/T1053/006/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
Stages and Predicates
Stage 1: file
file where event.type != "deletion" and
event.action in ("creation", "rename", "open") and (
file.path like (
"/etc/cron.allow", "/etc/cron.deny", "/etc/cron.d/*", "/etc/cron.hourly/*", "/etc/cron.daily/*",
"/etc/cron.weekly/*", "/etc/cron.monthly/*", "/etc/crontab", "/var/spool/cron/crontabs/*",
"/var/spool/anacron/*",
"/var/spool/cron/atjobs/*", "/var/spool/atjobs/*",
"/etc/sudoers*"
) or
(
file.path like (
"/etc/systemd/system/*", "/etc/systemd/user/*", "/usr/local/lib/systemd/system/*",
"/lib/systemd/system/*", "/usr/lib/systemd/system/*", "/usr/lib/systemd/user/*",
"/home/*/.config/systemd/user/*", "/home/*/.local/share/systemd/user/*",
"/root/.config/systemd/user/*", "/root/.local/share/systemd/user/*"
) and
file.extension in ("service", "timer")
) or
(
file.path like ("/etc/profile.d/*", "/etc/zsh/*") or (
file.path like ("/home/*/*", "/etc/*", "/root/*") and
file.name in (
"profile", "bash.bashrc", "bash.bash_logout", "csh.cshrc", "csh.login", "config.fish", "ksh.kshrc",
".bashrc", ".bash_login", ".bash_logout", ".bash_profile", ".bash_aliases", ".zprofile", ".zshrc",
".cshrc", ".login", ".logout", ".kshrc"
)
)
)
) and container.id like "?*" and
not process.name in ("apt", "apt-get", "dnf", "microdnf", "yum", "zypper", "tdnf", "apk", "pacman", "rpm", "dpkg")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
container.id | wildcard |
| field:"container.id" kind:wildcard value:"?*" |
event.action | in |
| field:"EventType" kind:in |
event.type | ne |
| field:"event.type" kind:ne value:"deletion" |
file.extension | in |
| field:"file.extension" kind:in |
file.name | in |
| field:"file.name" kind:in |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.name | in | apk, apt, apt-get, dnf, dpkg, microdnf, pacman, rpm, tdnf, yum, zypper | excludes:process.name |
Network Connection via Certutil
#Identifies certutil.exe making a network connection. Adversaries could abuse certutil.exe to download a certificate, or malware, from a remote URL.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth | |
| Command & Control |
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 3: Network connection |
Rule Body
[metadata]
bypass_bbr_timing = true
creation_date = "2020/03/19"
integration = ["endpoint", "windows"]
maturity = "production"
updated_date = "2026/03/24"
[transform]
[[transform.investigate]]
label = "Alerts associated with the user in the last 48h"
providers = [
[
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
{ excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
]
]
relativeFrom = "now-48h/h"
relativeTo = "now"
[[transform.investigate]]
label = "Alerts associated with the host in the last 48h"
providers = [
[
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
{ excluded = false, field = "host.name", queryType = "phrase", value = "{{host.name}}", valueType = "string" }
]
]
relativeFrom = "now-48h/h"
relativeTo = "now"
[[transform.investigate]]
label = "Investigate the Subject Process Network Events"
providers = [
[
{ excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" },
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
]
]
[[transform.osquery]]
label = "Osquery - Retrieve DNS Cache"
query = "SELECT * FROM dns_cache"
[[transform.osquery]]
label = "Osquery - Retrieve All Services"
query = "SELECT description, display_name, name, path, pid, service_type, start_type, status, user_account FROM services"
[[transform.osquery]]
label = "Osquery - Retrieve Services Running on User Accounts"
query = """
SELECT description, display_name, name, path, pid, service_type, start_type, status, user_account FROM services WHERE
NOT (user_account LIKE '%LocalSystem' OR user_account LIKE '%LocalService' OR user_account LIKE '%NetworkService' OR
user_account == null)
"""
[[transform.osquery]]
label = "Osquery - Retrieve Service Unsigned Executables with Virustotal Link"
query = """
SELECT concat('https://www.virustotal.com/gui/file/', sha1) AS VtLink, name, description, start_type, status, pid,
services.path FROM services JOIN authenticode ON services.path = authenticode.path OR services.module_path =
authenticode.path JOIN hash ON services.path = hash.path WHERE authenticode.result != 'trusted'
"""
[rule]
author = ["Elastic"]
building_block_type = "default"
description = """
Identifies certutil.exe making a network connection. Adversaries could abuse certutil.exe to download a certificate, or
malware, from a remote URL.
"""
from = "now-9m"
index = ["winlogbeat-*", "logs-endpoint.events.network-*", "logs-windows.sysmon_operational-*", "endgame-*"]
language = "eql"
license = "Elastic License v2"
name = "Network Connection via Certutil"
note = """## Triage and analysis
### Investigating Network Connection via Certutil
Attackers can abuse `certutil.exe` to download malware, offensive security tools, and certificates from external sources in order to take the next steps in a compromised environment.
This rule looks for network events where `certutil.exe` contacts IP ranges other than the ones specified in [IANA IPv4 Special-Purpose Address Registry](https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml)
> **Note**:
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/current/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.
> This investigation guide uses the [Investigate Markdown Plugin](https://www.elastic.co/guide/en/security/current/interactive-investigation-guides.html) introduced in Elastic Stack version 8.8.0. Older Elastic Stack versions will display unrendered Markdown in this guide.
#### Possible investigation steps
- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.
- Investigate other alerts associated with the user/host during the past 48 hours.
- $investigate_0
- $investigate_1
- Investigate if the downloaded file was executed.
- Determine the context in which `certutil.exe` and the file were run.
- Examine the host for derived artifacts that indicate suspicious activities:
- Analyze the downloaded file using a private sandboxed analysis system.
- Observe and collect information about the following activities in both the sandbox and the alert subject host:
- Attempts to contact external domains and addresses.
- Use the Elastic Defend network events to determine domains and addresses contacted by the subject process by filtering by the process' `process.entity_id`.
- $investigate_2
- Examine the DNS cache for suspicious or anomalous entries.
- $osquery_0
- Use the Elastic Defend registry events to examine registry keys accessed, modified, or created by the related processes in the process tree.
- Examine the host services for suspicious or anomalous entries.
- $osquery_1
- $osquery_2
- $osquery_3
- Retrieve the files' SHA-256 hash values using the PowerShell `Get-FileHash` cmdlet and search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.
### False positive analysis
- This mechanism can be used legitimately. If trusted software uses this command and the triage has not identified anything suspicious, this alert can be closed as a false positive.
- If this rule is noisy in your environment due to expected activity, consider adding exceptions — preferably with a combination of user and command line conditions.
### Response and remediation
- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- If the triage identified malware, search the environment for additional compromised hosts.
- Implement temporary network rules, procedures, and segmentation to contain the malware.
- Stop suspicious processes.
- Immediately block the identified indicators of compromise (IoCs).
- Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that attackers could use to reinfect the system.
- Remove and block malicious artifacts identified during triage.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
references = [
"https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml",
"https://frsecure.com/malware-incident-response-playbook/",
]
risk_score = 21
rule_id = "3838e0e3-1850-4850-a411-2e8c5ba40ba8"
severity = "low"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Command and Control",
"Resources: Investigation Guide",
"Data Source: Elastic Defend",
"Data Source: Sysmon",
"Data Source: Elastic Endgame",
"Rule Type: BBR",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
network where host.os.type == "windows" and process.name : "certutil.exe" 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.168.0.0/16", "192.88.99.0/24", "224.0.0.0/4", "100.64.0.0/10", "192.175.48.0/24",
"198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1",
"FE80::/10", "FF00::/8") and
not dns.question.name in ("localhost", "*.digicert.com", "ctldl.windowsupdate.com")
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1105"
name = "Ingress Tool Transfer"
reference = "https://attack.mitre.org/techniques/T1105/"
[rule.threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Stage 1: network
network where host.os.type == "windows" and process.name : "certutil.exe" 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.168.0.0/16", "192.88.99.0/24", "224.0.0.0/4", "100.64.0.0/10", "192.175.48.0/24",
"198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1",
"FE80::/10", "FF00::/8") and
not dns.question.name in ("localhost", "*.digicert.com", "ctldl.windowsupdate.com")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
process.name | wildcard |
| field:"process_basename" kind:wildcard value:"certutil.exe" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
destination.ip | cidr_match | 10.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.0.0.0/24, 192.0.0.0/29, 192.0.0.8/32, 192.0.0.9/32, 192.0.0.10/32, 192.0.0.170/32, 192.0.0.171/32, 192.0.2.0/24, 192.31.196.0/24, 192.52.193.0/24, 192.168.0.0/16, 192.88.99.0/24, 224.0.0.0/4, 100.64.0.0/10, 192.175.48.0/24, 198.18.0.0/15, 198.51.100.0/24, 203.0.113.0/24, 240.0.0.0/4, ::1, FE80::/10, FF00::/8 | excludes:destination.ip |
dns.question.name | in | *.digicert.com, ctldl.windowsupdate.com, localhost | excludes:dns.question.name field:"dns.question.name" value:"*.digicert.com" field:"dns.question.name" value:"ctldl.windowsupdate.com" field:"dns.question.name" value:"localhost" |
Nsenter to PID Namespace via Auditd
#Detects nsenter executions that target PID with a namespace target flag, a pattern commonly used to attach to the host init namespace from a container or session and run with host context.
Known False Positives
- Platform engineers may nsenter into PID 1 namespaces during deep node debugging; correlate with tickets and bastion sessions before escalating.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Privilege Escalation |
Rule Body
[metadata]
creation_date = "2026/04/27"
integration = ["auditd_manager"]
maturity = "production"
updated_date = "2026/07/17"
[rule]
author = ["Elastic"]
description = """
Detects nsenter executions that target PID with a namespace target flag, a pattern commonly used to attach to the
host init namespace from a container or session and run with host context.
"""
false_positives = [
"""
Platform engineers may nsenter into PID 1 namespaces during deep node debugging; correlate with tickets and bastion
sessions before escalating.
""",
]
from = "now-9m"
index = ["auditbeat-*", "logs-auditd_manager.auditd-*"]
language = "kuery"
license = "Elastic License v2"
name = "Nsenter to PID Namespace via Auditd"
note = """## Triage and analysis
### Investigating Nsenter to PID Namespace via Auditd
Review process.args for the full nsenter invocation (target PID, mount, UTS, IPC, net, user namespaces), parent process,
user identity, and host. PID targeting is a strong escape or host-administration signal when unexpected for the actor.
### Possible investigation steps
- Confirm whether the session originated from a container, SSH session, or automation agent.
- Pivot on the same host for subsequent writes under /etc, docker.sock access, or new systemd units.
### False positive analysis
- Some CNI or snap workflows can resemble nsenter; rely on the built-in exclusions first, then tune by parent command
or service account.
### Response and remediation
- If malicious, isolate the host, revoke credentials, inspect for persistence, and re-image if integrity cannot be proven.
"""
references = [
"https://attack.mitre.org/techniques/T1611/",
"https://man7.org/linux/man-pages/man1/nsenter.1.html",
]
risk_score = 73
rule_id = "75f9b95f-370b-4ff3-a84c-66d9ec0b84eb"
setup = """## Setup
Deploy the Auditd Manager integration on Linux hosts that should emit process execution telemetry (Fleet, Integrations,
Auditd Manager, attach to an agent policy).
Ensure syscall rules capture execve for utilities such as nsenter so event.category process and event.action executed
populate with process.name and process.args.
See https://docs.elastic.co/integrations/auditd_manager for integration details.
"""
severity = "high"
tags = [
"Domain: Endpoint",
"Domain: Container",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Privilege Escalation",
"Data Source: Auditd Manager",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
host.os.type:linux and event.category:process and event.action:(exec or executed) and
(process.name:nsenter or process.args:nsenter) and
process.args:(
(-t or --target*) and
not --net=/run/netns/* and
not (--assertion and snap) and
not (is-active and snap.*) and
not (-anp and netstat)
)
'''
[[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/"
Stages and Predicates
Stage 1: query
host.os.type:linux and event.category:process and event.action:(exec or executed) and
(process.name:nsenter or process.args:nsenter) and
process.args:(
(-t or --target*) and
not --net=/run/netns/* and
not (--assertion and snap) and
not (is-active and snap.*) and
not (-anp and netstat)
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | in |
| field:"EventType" kind:in |
event.category | eq |
| field:"event.category" kind:eq value:"process" |
process.args | eq |
| field:"process.args" kind:eq |
process.args | wildcard |
| field:"process.args" kind:wildcard value:"--target*" |
process.name | eq |
| field:"process_basename" kind:eq value:"nsenter" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | eq | --assertion | excludes:process.args field:"process.args" value:"--assertion" |
process.args | eq | snap | excludes:process.args field:"process.args" value:"snap" |
process.args | eq | -anp | excludes:process.args field:"process.args" value:"-anp" |
process.args | eq | netstat | excludes:process.args field:"process.args" value:"netstat" |
process.args | eq | is-active | excludes:process.args field:"process.args" value:"is-active" |
process.args | starts_with | snap. | excludes:process.args field:"process.args" value:"snap." |
process.args | starts_with | --net=/run/netns/ | excludes:process.args field:"process.args" value:"--net=/run/netns/" |
Potential Execution of rc.local Script
#This rule detects the potential execution of the "/etc/rc.local" script through the "already_running" event action created by the "rc-local.service" systemd service. The "/etc/rc.local" script is a legacy initialization script that is executed at the end of the boot process. The "/etc/rc.local" script is not enabled by default on most Linux distributions. The "/etc/rc.local" script can be used by attackers to persistently execute malicious commands or scripts on a compromised system at reboot. As the rc.local file is executed prior to the initialization of Elastic Defend, the execution event is not ingested, and therefore the "already_running" event is leveraged to provide insight into the potential execution of "rc.local".
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Privilege Escalation |
Rule Body
[metadata]
creation_date = "2024/06/21"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
This rule detects the potential execution of the "/etc/rc.local" script through the "already_running" event action
created by the "rc-local.service" systemd service. The "/etc/rc.local" script is a legacy initialization script that is
executed at the end of the boot process. The "/etc/rc.local" script is not enabled by default on most Linux
distributions. The "/etc/rc.local" script can be used by attackers to persistently execute malicious commands or scripts
on a compromised system at reboot. As the rc.local file is executed prior to the initialization of Elastic Defend, the
execution event is not ingested, and therefore the "already_running" event is leveraged to provide insight into the
potential execution of "rc.local".
"""
from = "now-9m"
index = ["logs-endpoint.events.process*"]
language = "eql"
license = "Elastic License v2"
name = "Potential Execution of rc.local Script"
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 Execution of rc.local Script
The `/etc/rc.local` script is a legacy Linux initialization script executed at the end of the boot process. While not enabled by default, attackers can exploit it to persistently run malicious commands upon system reboot. The detection rule identifies potential misuse by monitoring for the `already_running` event action linked to `rc-local.service`, indicating the script's execution, thus alerting to possible persistence tactics.
### Possible investigation steps
- Review the system logs to identify any recent changes or modifications to the /etc/rc.local file, focusing on timestamps and user accounts involved in the changes.
- Examine the contents of the /etc/rc.local file to identify any suspicious or unauthorized commands or scripts that may have been added.
- Investigate the process tree and parent processes associated with the rc-local.service to determine if there are any unusual or unexpected parent processes that could indicate compromise.
- Check for any other persistence mechanisms or indicators of compromise on the system, such as unauthorized user accounts or scheduled tasks, to assess the broader impact of the potential threat.
- Correlate the event with other security alerts or logs from the same host to identify any patterns or related activities that could provide additional context or evidence of malicious behavior.
### False positive analysis
- System maintenance scripts: Some Linux distributions or administrators may use the rc.local script for legitimate system maintenance tasks. Review the script's content to verify its purpose and consider excluding these known benign scripts from triggering alerts.
- Custom startup configurations: Organizations might have custom startup configurations that utilize rc.local for non-malicious purposes. Document these configurations and create exceptions in the detection rule to prevent unnecessary alerts.
- Legacy applications: Certain legacy applications might rely on rc.local for initialization. Identify these applications and assess their necessity. If deemed safe, exclude their execution from the rule to reduce false positives.
- Testing environments: In testing or development environments, rc.local might be used for various non-threatening experiments. Clearly label these environments and adjust the rule to ignore alerts originating from them.
### Response and remediation
- Immediately isolate the affected system from the network to prevent further execution of potentially malicious scripts and limit the attacker's access.
- Review the contents of the `/etc/rc.local` file on the affected system to identify any unauthorized or suspicious commands or scripts. Remove any malicious entries found.
- Conduct a thorough scan of the system using updated antivirus or endpoint detection tools to identify and remove any additional malware or persistence mechanisms.
- Restore the system from a known good backup if the integrity of the system is in question and if malicious activity is confirmed.
- Implement monitoring for changes to the `/etc/rc.local` file and other critical system files to detect unauthorized modifications in the future.
- Escalate the incident to the security operations team for further investigation and to determine if other systems may be affected.
- Review and update security policies and configurations to disable the execution of the `/etc/rc.local` script by default on all systems, unless explicitly required for legitimate purposes."""
references = [
"https://www.intezer.com/blog/malware-analysis/hiddenwasp-malware-targeting-linux-systems/",
"https://pberba.github.io/security/2022/02/06/linux-threat-hunting-for-persistence-initialization-scripts-and-shell-configuration/#8-boot-or-logon-initialization-scripts-rc-scripts",
"https://www.cyberciti.biz/faq/how-to-enable-rc-local-shell-script-on-systemd-while-booting-linux-system/",
"https://www.elastic.co/security-labs/sequel-on-persistence-mechanisms",
]
risk_score = 47
rule_id = "7318affb-bfe8-4d50-a425-f617833be160"
setup = """## Setup
This rule requires data coming in from Elastic Defend.
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "linux" and event.type == "info" and event.action == "already_running" and
process.parent.args == "/etc/rc.local" and process.parent.args == "start"
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1037"
name = "Boot or Logon Initialization Scripts"
reference = "https://attack.mitre.org/techniques/T1037/"
[[rule.threat.technique.subtechnique]]
id = "T1037.004"
name = "RC Scripts"
reference = "https://attack.mitre.org/techniques/T1037/004/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1037"
name = "Boot or Logon Initialization Scripts"
reference = "https://attack.mitre.org/techniques/T1037/"
[[rule.threat.technique.subtechnique]]
id = "T1037.004"
name = "RC Scripts"
reference = "https://attack.mitre.org/techniques/T1037/004/"
[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
Stages and Predicates
Stage 1: process
process where host.os.type == "linux" and event.type == "info" and event.action == "already_running" and
process.parent.args == "/etc/rc.local" and process.parent.args == "start"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"already_running" |
event.type | eq |
| field:"event.type" kind:eq value:"info" |
process.parent.args | eq |
| field:"process.parent.args" kind:eq |
Potential Okta Credential Stuffing (Single Source)
#Detects potential credential stuffing attacks where a single source IP attempts authentication against many Okta user accounts with minimal attempts per user, indicating the use of breached credential lists.
Known False Positives
- Corporate proxy or VPN exit nodes may aggregate traffic from multiple legitimate users.
- Shared systems such as kiosks or conference room computers may have multiple users authenticating.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
- Failed Logins from Unknown or Invalid User (Kusto)
- First Occurrence of Okta User Session Started via Proxy (Elastic)
- High-Risk Admin Activity (Kusto)
- Multiple Okta Sessions Detected for a Single User (Elastic)
- Multiple Okta User Authentication Events with Same Device Token Hash (Elastic)
- New Device/Location sign-in along with critical operation (Kusto)
- Okta AiTM Session Cookie Replay (Elastic)
- Okta Login From CrowdStrike Unmanaged Device (Panther)
Rule Body
[metadata]
creation_date = "2024/06/17"
integration = ["okta"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
Detects potential credential stuffing attacks where a single source IP attempts authentication against many Okta
user accounts with minimal attempts per user, indicating the use of breached credential lists.
"""
false_positives = [
"Corporate proxy or VPN exit nodes may aggregate traffic from multiple legitimate users.",
"Shared systems such as kiosks or conference room computers may have multiple users authenticating.",
]
from = "now-15m"
language = "esql"
license = "Elastic License v2"
name = "Potential Okta Credential Stuffing (Single Source)"
note = """## Triage and analysis
### Investigating Potential Okta Credential Stuffing (Single Source)
This rule identifies a single source IP attempting authentication against many user accounts with minimal attempts per user. This pattern indicates credential stuffing where attackers rapidly test breached username and password pairs.
#### Possible investigation steps
- Identify the source IP and determine if it belongs to known proxy, VPN, or cloud infrastructure.
- Review the list of targeted user accounts and check if any authentications succeeded.
- Examine the user agent strings for signs of automation or scripting tools.
- Check if Okta flagged the source as a known threat or proxy.
- Determine if any targeted accounts have elevated privileges or access to sensitive systems.
- Review the geographic location and ASN of the source IP for anomalies.
### False positive analysis
- Corporate proxies or VPN exit nodes may aggregate traffic from multiple legitimate users.
- Shared systems such as kiosks or conference room computers may have multiple users authenticating.
- Legitimate SSO integrations may generate multiple authentication attempts from a single source.
### Response and remediation
- If attack is confirmed, block the source IP at the network perimeter.
- Reset passwords for any accounts that may have been compromised.
- Enable or strengthen MFA for targeted accounts.
- Review Okta sign-on policies to add additional friction for suspicious authentication patterns.
- If this is a known legitimate source, consider adding an exception for the IP or ASN.
"""
references = [
"https://support.okta.com/help/s/article/Troubleshooting-Distributed-Brute-Force-andor-Password-Spray-attacks-in-Okta",
"https://www.okta.com/identity-101/brute-force/",
"https://support.okta.com/help/s/article/How-does-the-Device-Token-work?language=en_US",
"https://developer.okta.com/docs/reference/api/event-types/",
"https://www.elastic.co/security-labs/testing-okta-visibility-and-detection-dorothy",
"https://sec.okta.com/articles/2023/08/cross-tenant-impersonation-prevention-and-detection",
"https://www.okta.com/resources/whitepaper-how-adaptive-mfa-can-help-in-mitigating-brute-force-attacks/",
"https://www.elastic.co/security-labs/monitoring-okta-threats-with-elastic-security",
"https://www.elastic.co/security-labs/starter-guide-to-understanding-okta",
]
risk_score = 47
rule_id = "94e734c0-2cda-11ef-84e1-f661ea17fbce"
setup = "The Okta Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."
severity = "medium"
tags = [
"Domain: Identity",
"Use Case: Identity and Access Audit",
"Data Source: Okta",
"Data Source: Okta System Logs",
"Tactic: Credential Access",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
FROM logs-okta.system-* METADATA _id, _version, _index
| WHERE
data_stream.dataset == "okta.system"
AND (event.action LIKE "user.authentication.*" OR event.action == "user.session.start")
AND okta.outcome.reason IN ("INVALID_CREDENTIALS", "LOCKED_OUT")
AND okta.actor.alternate_id IS NOT NULL
// Build user-source context as JSON for enrichment
| EVAL Esql.user_source_info = CONCAT(
"{\"user\":\"", okta.actor.alternate_id,
"\",\"ip\":\"", COALESCE(okta.client.ip::STRING, "unknown"),
"\",\"user_agent\":\"", COALESCE(okta.client.user_agent.raw_user_agent, "unknown"), "\"}"
)
// FIRST STATS: Aggregate by (IP, user) to get per-user attempt counts
// This prevents skew from outlier users with many attempts
| STATS
Esql.user_attempts = COUNT(*),
Esql.user_dt_hashes = COUNT_DISTINCT(okta.debug_context.debug_data.dt_hash),
Esql.user_source_info = VALUES(Esql.user_source_info),
Esql.user_agents_per_user = VALUES(okta.client.user_agent.raw_user_agent),
Esql.devices_per_user = VALUES(okta.client.device),
Esql.is_proxy = VALUES(okta.security_context.is_proxy),
Esql.geo_country = VALUES(client.geo.country_name),
Esql.geo_city = VALUES(client.geo.city_name),
Esql.asn_number = VALUES(source.as.number),
Esql.asn_org = VALUES(source.as.organization.name),
Esql.threat_suspected = VALUES(okta.debug_context.debug_data.threat_suspected),
Esql.risk_level = VALUES(okta.debug_context.debug_data.risk_level),
Esql.risk_reasons = VALUES(okta.debug_context.debug_data.risk_reasons),
Esql.event_actions = VALUES(event.action),
Esql.first_seen_user = MIN(@timestamp),
Esql.last_seen_user = MAX(@timestamp)
BY okta.client.ip, okta.actor.alternate_id
// SECOND STATS: Aggregate by IP to detect credential stuffing pattern
// Now we can accurately measure the distribution of attempts across users
| STATS
Esql.unique_users = COUNT(*),
Esql.total_attempts = SUM(Esql.user_attempts),
Esql.max_attempts_per_user = MAX(Esql.user_attempts),
Esql.min_attempts_per_user = MIN(Esql.user_attempts),
Esql.avg_attempts_per_user = AVG(Esql.user_attempts),
Esql.users_with_single_attempt = SUM(CASE(Esql.user_attempts == 1, 1, 0)),
Esql.users_with_few_attempts = SUM(CASE(Esql.user_attempts <= 2, 1, 0)),
Esql.first_seen = MIN(Esql.first_seen_user),
Esql.last_seen = MAX(Esql.last_seen_user),
Esql.target_users = VALUES(okta.actor.alternate_id),
Esql.user_source_mapping = VALUES(Esql.user_source_info),
Esql.event_action_values = VALUES(Esql.event_actions),
Esql.user_agent_values = VALUES(Esql.user_agents_per_user),
Esql.device_values = VALUES(Esql.devices_per_user),
Esql.is_proxy_values = VALUES(Esql.is_proxy),
Esql.geo_country_values = VALUES(Esql.geo_country),
Esql.geo_city_values = VALUES(Esql.geo_city),
Esql.source_asn_values = VALUES(Esql.asn_number),
Esql.source_asn_org_values = VALUES(Esql.asn_org),
Esql.threat_suspected_values = VALUES(Esql.threat_suspected),
Esql.risk_level_values = VALUES(Esql.risk_level),
Esql.risk_reasons_values = VALUES(Esql.risk_reasons)
BY okta.client.ip
// Calculate stuffing signature: most users should have very few attempts
| EVAL Esql.pct_users_few_attempts = Esql.users_with_few_attempts * 100.0 / Esql.unique_users
// Credential stuffing: many users, most with 1-2 attempts each, low max per user
// Stacked stats gives us accurate per-user distribution instead of skewed averages
| WHERE
Esql.total_attempts >= 25
AND Esql.unique_users >= 15
AND Esql.max_attempts_per_user <= 2
AND Esql.pct_users_few_attempts >= 80.0
| SORT Esql.unique_users DESC
| KEEP Esql.*, okta.client.ip
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1110"
name = "Brute Force"
reference = "https://attack.mitre.org/techniques/T1110/"
[[rule.threat.technique.subtechnique]]
id = "T1110.004"
name = "Credential Stuffing"
reference = "https://attack.mitre.org/techniques/T1110/004/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
Stages and Predicates
Stage 1: from
FROM logs-okta.system-* METADATA _id, _version, _index
Stage 2: where
| WHERE
data_stream.dataset == "okta.system"
AND (event.action LIKE "user.authentication.*" OR event.action == "user.session.start")
AND okta.outcome.reason IN ("INVALID_CREDENTIALS", "LOCKED_OUT")
AND okta.actor.alternate_id IS NOT NULL
Stage 3: eval
| EVAL Esql.user_source_info = CONCAT(
"{\"user\":\"", okta.actor.alternate_id,
"\",\"ip\":\"", COALESCE(okta.client.ip::STRING, "unknown"),
"\",\"user_agent\":\"", COALESCE(okta.client.user_agent.raw_user_agent, "unknown"), "\"}"
)
Stage 4: stats
| STATS
Esql.user_attempts = COUNT(*),
Esql.user_dt_hashes = COUNT_DISTINCT(okta.debug_context.debug_data.dt_hash),
Esql.user_source_info = VALUES(Esql.user_source_info),
Esql.user_agents_per_user = VALUES(okta.client.user_agent.raw_user_agent),
Esql.devices_per_user = VALUES(okta.client.device),
Esql.is_proxy = VALUES(okta.security_context.is_proxy),
Esql.geo_country = VALUES(client.geo.country_name),
Esql.geo_city = VALUES(client.geo.city_name),
Esql.asn_number = VALUES(source.as.number),
Esql.asn_org = VALUES(source.as.organization.name),
Esql.threat_suspected = VALUES(okta.debug_context.debug_data.threat_suspected),
Esql.risk_level = VALUES(okta.debug_context.debug_data.risk_level),
Esql.risk_reasons = VALUES(okta.debug_context.debug_data.risk_reasons),
Esql.event_actions = VALUES(event.action),
Esql.first_seen_user = MIN(@timestamp),
Esql.last_seen_user = MAX(@timestamp)
BY okta.client.ip, okta.actor.alternate_id
Stage 5: stats
| STATS
Esql.unique_users = COUNT(*),
Esql.total_attempts = SUM(Esql.user_attempts),
Esql.max_attempts_per_user = MAX(Esql.user_attempts),
Esql.min_attempts_per_user = MIN(Esql.user_attempts),
Esql.avg_attempts_per_user = AVG(Esql.user_attempts),
Esql.users_with_single_attempt = SUM(CASE(Esql.user_attempts == 1, 1, 0)),
Esql.users_with_few_attempts = SUM(CASE(Esql.user_attempts <= 2, 1, 0)),
Esql.first_seen = MIN(Esql.first_seen_user),
Esql.last_seen = MAX(Esql.last_seen_user),
Esql.target_users = VALUES(okta.actor.alternate_id),
Esql.user_source_mapping = VALUES(Esql.user_source_info),
Esql.event_action_values = VALUES(Esql.event_actions),
Esql.user_agent_values = VALUES(Esql.user_agents_per_user),
Esql.device_values = VALUES(Esql.devices_per_user),
Esql.is_proxy_values = VALUES(Esql.is_proxy),
Esql.geo_country_values = VALUES(Esql.geo_country),
Esql.geo_city_values = VALUES(Esql.geo_city),
Esql.source_asn_values = VALUES(Esql.asn_number),
Esql.source_asn_org_values = VALUES(Esql.asn_org),
Esql.threat_suspected_values = VALUES(Esql.threat_suspected),
Esql.risk_level_values = VALUES(Esql.risk_level),
Esql.risk_reasons_values = VALUES(Esql.risk_reasons)
BY okta.client.ip
Stage 6: eval
| EVAL Esql.pct_users_few_attempts = Esql.users_with_few_attempts * 100.0 / Esql.unique_users
Stage 7: where
| WHERE
Esql.total_attempts >= 25
AND Esql.unique_users >= 15
AND Esql.max_attempts_per_user <= 2
AND Esql.pct_users_few_attempts >= 80.0
Stage 8: sort
| SORT Esql.unique_users DESC
Stage 9: keep
| KEEP Esql.*, okta.client.ip
Indicators
These rows show field, operator, and value matches.
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Esql.* | KEEP Esql.* |
okta.client.ip | KEEP okta.client.ip |
Potential PowerShell Obfuscation via Invalid Escape Sequences
#Detects PowerShell scripts with repeated invalid backtick escapes between word characters (letters, digits, underscore, or dash), splitting tokens while preserving execution. Attackers use this obfuscation to fragment keywords and evade pattern-based detection and AMSI.
MITRE ATT&CK Coverage
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| PowerShell | Event ID 4104: Creating Scriptblock text (MessageNumber of MessageTotal). |
Rule Body
[metadata]
creation_date = "2025/04/15"
integration = ["windows"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
Detects PowerShell scripts with repeated invalid backtick escapes between word characters (letters, digits, underscore,
or dash), splitting tokens while preserving execution. Attackers use this obfuscation to fragment keywords and evade
pattern-based detection and AMSI.
"""
from = "now-9m"
language = "esql"
license = "Elastic License v2"
name = "Potential PowerShell Obfuscation via Invalid Escape Sequences"
note = """## Triage and analysis
> **Disclaimer**:
> This guide was created by humans with the assistance of generative AI. While its contents have been manually curated to include the most valuable information, always validate assumptions and adjust procedures to match your internal runbooks and incident triage and response policies.
### Investigating Potential PowerShell Obfuscation via Invalid Escape Sequences
This rule flags PowerShell script block content that repeatedly inserts invalid backtick escape sequences within otherwise contiguous word characters. This can fragment tokens (cmdlets, parameters, variable names, strings) while preserving execution and readability to the interpreter, which can hinder content inspection and pattern-based detections.
Analyst goals:
- Reconstruct complete script block content when split across multiple events.
- Normalize the content (remove or correct invalid escapes) to reveal the underlying logic.
- Determine execution context (host, user, script origin) and correlate with adjacent activity to assess intent and impact.
#### Key alert fields to review
- `user.name`, `user.domain`, `user.id`: Account execution context for correlation, prioritization, and scoping.
- `host.name`, `host.id`: Host execution context for correlation, prioritization, and scoping.
- `file.path`, `file.directory`, `file.name`: File-origin context when the script block is sourced from an on-disk file.
- `powershell.file.script_block_text`: Script block content that matched the detection logic.
- `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`: Script block metadata to pivot to other fragments or reconstruct full script content when split across multiple events.
- `Esql.script_block_tmp`: Transformed script block where detection patterns replace original content with a marker to support scoring/counting and quickly spot match locations.
- `Esql.script_block_pattern_count`: Count of matches for the detection pattern(s) observed in the script block content.
- `powershell.file.script_block_entropy_bits`: Shannon entropy of the script block. Higher values may indicate obfuscation.
- `powershell.file.script_block_surprisal_stdev`: Standard deviation of surprisal across the script block. Low values indicate uniform randomness. High values indicate mixed patterns and variability.
- `powershell.file.script_block_unique_symbols`: Count of distinct characters present in the script block.
- `powershell.file.script_block_length`: Script block length (size) context.
#### Possible investigation steps
- Establish timeline and ownership:
- Anchor the activity using `@timestamp`, then record `host.name`, `host.id`, and `agent.id`.
- Identify the execution context with `user.name`, `user.domain`, and `user.id`. Note whether the account is expected to run PowerShell on this host and whether the host is commonly used for scripting.
- Assess the likelihood of intentional obfuscation:
- Review `Esql.script_block_pattern_count` to understand how heavily the content is fragmented. Higher counts generally increase confidence that this is deliberate obfuscation rather than incidental escaping.
- Use `powershell.file.script_block_length` as size context and review `powershell.file.script_block_entropy_bits`, `powershell.file.script_block_unique_symbols`, and `powershell.file.script_block_surprisal_stdev` to characterize the content (simple text vs. mixed/randomized payloads).
- Compare `Esql.script_block_tmp` to `powershell.file.script_block_text` to understand where obfuscation is concentrated (localized string vs. widespread token fragmentation).
- Reconstruct complete content when split across events:
- If `powershell.total` is greater than 1, pivot on `powershell.file.script_block_id` and rebuild the script by ordering segments on `powershell.sequence`.
- Validate the reconstructed set is complete (sequence 1 through `powershell.total`). Missing segments should be treated as an investigative gap and may require additional scoping.
- Determine script origin and delivery:
- If `file.path`, `file.directory`, and `file.name` are present, treat the script block as file-associated. Evaluate whether the location and naming are consistent with approved scripts or expected tooling for the endpoint.
- If file fields are absent, treat the script as inline or dynamically generated content and prioritize correlation by `host.id`, `user.id`, and time.
- Normalize and interpret the script content safely:
- In a controlled analysis workflow, normalize the script by removing or correcting invalid backtick insertions so that split tokens become readable. Keep both the original and normalized versions for reporting.
- Review the normalized text for behaviors that indicate malicious intent (secondary payload retrieval, dynamic execution, decoding/decompression, data collection, persistence logic, or remote interaction).
- Extract and document indicators present in the content (network destinations, file paths/names, unique strings, or embedded encoded blobs) for scoping.
- Correlate within PowerShell telemetry:
- Pivot on `host.id` and `user.id` to identify additional `powershell.file.script_block_text` events shortly before and after the alert time to capture staging, follow-on commands, and potential cleanup.
- Check for the same `powershell.file.script_block_id` appearing across hosts, or for repeated normalized strings, to identify automation reuse or broader activity.
- Correlate with adjacent endpoint activity (if available in your environment):
- Review process execution around `@timestamp` on `host.name` to identify the PowerShell host process and its parent, then assess whether the launch chain aligns with expected activity for the user and endpoint.
- Review network activity around the alert time for connections that align with indicators extracted from the script content.
- Review file and registry activity around the same time window for artifacts consistent with the script (new or modified scripts, dropped files, or persistence-related changes).
- Review authentication activity associated with `user.id` around the alert time for suspicious logons or remote access that may align with script execution.
- Scope impact:
- Search for other alerts/events with similar obfuscation characteristics on the same host and for the same user to determine whether this is a one-off execution or a repeated pattern.
- If multiple hosts are involved, prioritize investigation for critical assets and accounts with elevated privileges.
### False positive analysis
- Legitimate scripts can contain backticks for formatting, string construction, or content generation; however, repeated invalid escape sequences embedded inside alphanumeric tokens are uncommon. Validate whether the execution context (`host.id`, `user.id`) aligns with known administrative or developer activity.
- Some commercial or internal tools intentionally obfuscate PowerShell to protect intellectual property. Confirm whether the script origin (`file.path` when present), account context, and prevalence across the environment match an approved application or workflow.
- Copy/paste artifacts and encoding transformations can introduce unexpected characters. When suspected, compare the normalized content to known-good scripts and assess whether the obfuscation is systematic (repeating across many tokens) versus localized.
### Response and remediation
- If the activity is confirmed or strongly suspected malicious:
- Contain affected host(s) to prevent further execution and lateral movement.
- Preserve evidence: reconstructed `powershell.file.script_block_text`, `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`, and alert-derived fields (`Esql.script_block_tmp`, `Esql.script_block_pattern_count`, and the script block metrics).
- If `file.path` is present, collect and quarantine the referenced script and review the surrounding directory for related artifacts.
- Use indicators extracted from normalized content to scope related activity across endpoints (pivot on `host.id`, `user.id`, `file.path`, and unique strings from the script).
- Coordinate credential remediation for affected accounts when remote execution, credential material, or post-exploitation behavior is suspected.
- If the activity is benign but requires reduction:
- Document the legitimate source (expected hosts/users and `file.path` when applicable).
- Apply narrowly scoped tuning using stable attributes available in the alert (such as `host.id`, `user.id`, and `file.path`) and continue monitoring for deviations in script content and execution context.
"""
risk_score = 47
rule_id = "64f17c52-6c6e-479e-ba72-236f3df18f3d"
setup = """## Setup
PowerShell Script Block Logging must be enabled to generate the events used by this rule (e.g., 4104).
Setup instructions: https://ela.st/powershell-logging-setup
"""
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Defense Evasion",
"Data Source: PowerShell Logs",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-windows.powershell_operational* metadata _id, _version, _index
| where event.code == "4104" and powershell.file.script_block_text like "*`*"
// replace the patterns we are looking for with the 🔥 emoji to enable counting them
// The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1
| eval Esql.script_block_tmp = replace(powershell.file.script_block_text, """[A-Za-z0-9_-]`(?![rntb]|\r|\n|\d)[A-Za-z0-9_-]""", "🔥")
// count how many patterns were detected by calculating the number of 🔥 characters inserted
| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "🔥", ""))
// keep the fields relevant to the query, although this is not needed as the alert is populated using _id
| keep
Esql.script_block_pattern_count,
Esql.script_block_tmp,
powershell.file.*,
file.name,
file.directory,
file.path,
powershell.sequence,
powershell.total,
_id,
_version,
_index,
host.name,
host.id,
agent.id,
user.id
// Filter for scripts that match the pattern at least 20 times
| where Esql.script_block_pattern_count >= 20
| where file.name not like "TSS_*.psm1"
// ESQL requires this condition, otherwise it only returns matches where file.name exists.
or file.name is null
// VSCode Shell integration
| where not powershell.file.script_block_text like "*$([char]0x1b)]633*"
| where not file.directory == "C:\\Program Files\\MVPSI\\JAMS\\Agent\\Temp"
// ESQL requires this condition, otherwise it only returns matches where file.directory exists.
or file.directory is null
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1027"
name = "Obfuscated Files or Information"
reference = "https://attack.mitre.org/techniques/T1027/"
[[rule.threat.technique.subtechnique]]
id = "T1027.010"
name = "Command Obfuscation"
reference = "https://attack.mitre.org/techniques/T1027/010/"
[[rule.threat.technique]]
id = "T1140"
name = "Deobfuscate/Decode Files or Information"
reference = "https://attack.mitre.org/techniques/T1140/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[rule.investigation_fields]
field_names = [
"@timestamp",
"user.name",
"user.id",
"user.domain",
"powershell.file.script_block_text",
"powershell.file.script_block_id",
"powershell.sequence",
"powershell.total",
"file.path",
"file.directory",
"file.name",
"process.pid",
"host.name",
"host.id",
"powershell.file.script_block_length"
]
Stages and Predicates
Stage 1: from
from logs-windows.powershell_operational* metadata _id, _version, _index
Stage 2: where
| where event.code == "4104" and powershell.file.script_block_text like "*`*"
Stage 3: eval
| eval Esql.script_block_tmp = replace(powershell.file.script_block_text, """[A-Za-z0-9_-]`(?![rntb]|\r|\n|\d)[A-Za-z0-9_-]""", "🔥")
Stage 4: eval
| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "🔥", ""))
Stage 5: keep
| keep
Esql.script_block_pattern_count,
Esql.script_block_tmp,
powershell.file.*,
file.name,
file.directory,
file.path,
powershell.sequence,
powershell.total,
_id,
_version,
_index,
host.name,
host.id,
agent.id,
user.id
Stage 6: where
| where Esql.script_block_pattern_count >= 20
Stage 7: where
| where file.name not like "TSS_*.psm1"
or file.name is null
Stage 8: where
| where not powershell.file.script_block_text like "*$([char]0x1b)]633*"
Stage 9: where
| where not file.directory == "C:\\Program Files\\MVPSI\\JAMS\\Agent\\Temp"
or file.directory is null
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
powershell.file.script_block_text | match | $([char]0x1b)]633 | excludes:powershell.file.script_block_text field:"powershell.file.script_block_text" value:"$([char]0x1b)]633" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Esql.script_block_pattern_count | KEEP Esql.script_block_pattern_count |
Esql.script_block_tmp | KEEP Esql.script_block_tmp |
powershell.file.* | KEEP powershell.file.* |
file.name | KEEP file.name |
file.directory | KEEP file.directory |
file.path | KEEP file.path |
powershell.sequence | KEEP powershell.sequence |
powershell.total | KEEP powershell.total |
_id | KEEP _id |
_version | KEEP _version |
_index | KEEP _index |
host.name | KEEP host.name |
host.id | KEEP host.id |
agent.id | KEEP agent.id |
user.id | KEEP user.id |
PowerShell Kerberos Ticket Request
#Detects PowerShell script content that references KerberosRequestorSecurityToken, which can request Kerberos service tickets. Attackers request service tickets to perform Kerberoasting for offline password cracking of service accounts.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Credential Access |
Rule Body
[metadata]
creation_date = "2022/01/24"
integration = ["windows"]
maturity = "production"
updated_date = "2026/04/27"
[rule]
author = ["Elastic"]
description = """
Detects PowerShell script content that references KerberosRequestorSecurityToken, which can request Kerberos service
tickets. Attackers request service tickets to perform Kerberoasting for offline password cracking of service accounts.
"""
from = "now-9m"
index = ["logs-windows.powershell*", "winlogbeat-*"]
language = "kuery"
license = "Elastic License v2"
name = "PowerShell Kerberos Ticket Request"
references = [
"https://www.cobalt.io/blog/kerberoast-attack-techniques",
"https://github.com/EmpireProject/Empire/blob/master/data/module_source/credentials/Invoke-Kerberoast.ps1",
]
risk_score = 73
rule_id = "eb610e70-f9e6-4949-82b9-f1c5bcd37c39"
severity = "high"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Credential Access",
"Resources: Investigation Guide",
"Data Source: PowerShell Logs",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
event.category:process and host.os.type:windows and
powershell.file.script_block_text : "KerberosRequestorSecurityToken" and
not powershell.file.script_block_text : (
("sentinelbreakpoints" and ("Set-PSBreakpoint" or "Set-HookFunctionTabs")) or
("function global" and "\\windows\\sentinel\\4")
)
'''
note = """## Triage and analysis
### Investigating PowerShell Kerberos Ticket Request
#### Possible investigation steps
- What does the reconstructed script actually do with KerberosRequestorSecurityToken?
- Focus: Reconstruct full 4104 content on `host.id` with `powershell.file.script_block_id`, `powershell.sequence`, and `powershell.total`; interpret `powershell.file.script_block_text`.
- Hint: pull fragments with matching `host.id` and `powershell.file.script_block_id`, order by `powershell.sequence`, and note gaps before judging intent. $investigate_2
- Implication: escalate when the script requests SPN TGS tickets, loops across "Get-DomainUser -SPN" results, or emits John/Hashcat, "TicketByteHexStream", "$krb5tgs$", or ".kirbi" material; lower suspicion only when reconstruction proves incidental text, comments, or a bounded fixed-SPN test with no output logic.
- Do the user, host, and script source fit a bounded recognized Kerberos test?
- Focus: `user.id`, `user.name`, `user.domain`, `host.id`, and `file.path`.
- Hint: absent `file.path` means the script block may be interactive, pasted, or generated in memory, so require stronger corroboration before closure.
- Implication: escalate when a standard user, shared workstation, production server, user-writable `file.path`, or absent `file.path` pairs with broad SPN targeting; lower suspicion only for a recognized identity test or Kerberos diagnostic on the expected host and user with a fixed SPN set.
- If endpoint process telemetry is available for this host, how did the PowerShell session start?
- Focus: `process.command_line`, `process.parent.executable`, `process.parent.command_line`, and `process.Ext.session_info.logon_type`.
- Hint: recover the process via `host.id + process.pid` before interpreting `process.*` or `process.parent.*`; if absent after a wider lookup, keep launch context unresolved and scope later pivots with `host.id`, `user.id`, and alert time. $investigate_3
- Implication: escalate when launch context shows encoded commands, pasted or remote delivery, Office or browser parents, unexpected service or network logon, or alternate-credential use; lower suspicion when command line and parent chain match the exact recognized test workflow.
- Did the activity create ticket, hash, or target-list artifacts?
- Focus: If endpoint file telemetry exists, scope writes to `host.id`, `user.id`, and the alert window; use the recovered process only after process recovery succeeds, and review `file.path` and `file.Ext.header_bytes`. $investigate_4
- Implication: escalate when writes show SPN lists, ".kirbi" tickets, "$krb5tgs$" or John/Hashcat text, "TicketByteHexStream", base64 blobs, archives, or temp/share/user-writable staging; no file output does not clear direct hash output or memory-only ticket export, and missing file telemetry is unresolved, not benign.
- Do domain-controller ticket events confirm active Kerberoasting behavior?
- Focus: DC-side Windows Security `event.code` 4769 near alert time, starting with `winlog.event_data.TargetUserName` = alert `user.name` for domain requesters; review `winlog.event_data.TargetDomainName`, `source.ip`, `winlog.event_data.ServiceName`, `winlog.event_data.TicketEncryptionType`, and target SPN volume. $investigate_5
- Hint: if the alert user is local, SYSTEM, or the transform is quiet, retry DC 4769 with UPN/domain variants from `user.name` + `user.domain`, then pivot by source host/address and candidate requester from reconstruction or launch context.
- Implication: escalate when 4769 events show broad SPN enumeration, RC4 or weak encryption, service-account-heavy targeting, or client addresses inconsistent with the expected workflow. Missing authentication telemetry is unresolved, not benign.
- Is this ticket-request activity isolated or part of broader suspicious behavior?
- Focus: same-scope events or alerts for `user.id` in the last 48 hours for credential access, execution, discovery, or lateral movement. $investigate_0
- Hint: use the host pivot separately when user scope is noisy or service-account-heavy. $investigate_1
- Implication: broaden response when either pivot shows adjacent credential access, execution, discovery, or lateral movement; keep the case local only when related alerts stay quiet or match the same bounded recognized workflow.
- Escalate active service-ticket collection without a recognized owner or with suspicious scope, output, launch, artifact, DC 4769, or same-scope evidence; close only when alert-local evidence and supported recovery bind one exact bounded workflow and outside confirmation resolves gaps; preserve evidence and escalate when findings are mixed or incomplete.
### False positive analysis
- Recognized Kerberos diagnostics, identity validation, or red-team tests can trigger this rule when reconstructed `powershell.file.script_block_text` stays limited to a fixed SPN set, creates no ticket or hash output, and the script source fits. If process telemetry was recovered via `host.id + process.pid`, require `process.command_line` and `process.parent.executable` to match. Require test-record alignment when present; otherwise close only when current telemetry proves the same fixed-SPN, no-output, user-host, source, and launch-chain pattern.
- Build exceptions from the minimum confirmed workflow: `user.id`, `host.id`, exact source pattern, recovered launch chain, and fixed SPN set. If prior alerts exist, verify they do not add expanded targets, crackable output, or a different launch path; for a first verified case, prefer a narrow candidate or time-bounded exception over broad suppression. Avoid exceptions on "KerberosRequestorSecurityToken" alone, `user.name` alone, or host alone.
### Response and remediation
- If confirmed benign, reverse any temporary containment and record the evidence that proved the recognized diagnostics, lab, or identity-test workflow: stable user-host pairing, fixed SPN scope, script source, recovered launch chain when available, and no contradictory artifact or same-scope evidence. Create only a narrow exception from that confirmed evidence; use prior alerts to tighten scope when they exist, not as the primary proof.
- If suspicious but unconfirmed, preserve the reconstructed `powershell.file.script_block_text`, `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`, `process.pid`, any recovered process details, named SPNs, output paths, and available identity records before containment. Apply reversible containment first, such as temporary host isolation or account restriction matched to host criticality, and avoid destructive cleanup until service-account exposure is scoped.
- If confirmed malicious, contain the host and affected account when script intent, recovered launch context, named SPNs, output artifacts, or same-scope events support unauthorized ticket collection. Record the recovered PowerShell command line, parent chain, named SPNs, output locations, and available identity evidence before terminating processes, deleting files, or purging sessions.
- If targeted or bulk service-ticket requests are confirmed, prioritize the named service accounts for password rotation, privilege review, and downstream logon analysis, then review affected services for anomalous authentication or access tied to the same period.
- Eradicate only the unauthorized scripts, SPN lists, ticket or hash output, scheduled tasks, and persistence mechanisms uncovered during the investigation, then remediate the delivery path or administrative-control gap that allowed the script to run.
- After containment, hunt for the same reconstructed script fragments, SPN patterns, and ticket-request evidence across other hosts, and retain PowerShell Script Block Logging plus supporting endpoint or identity telemetry where gaps limited the investigation.
"""
setup = """## Setup
PowerShell Script Block Logging must be enabled to generate the events used by this rule (e.g., 4104).
Setup instructions: https://ela.st/powershell-logging-setup
"""
[rule.investigation_fields]
field_names = [
"@timestamp",
"user.name",
"user.id",
"user.domain",
"powershell.file.script_block_text",
"powershell.file.script_block_id",
"powershell.sequence",
"powershell.total",
"file.path",
"file.directory",
"file.name",
"process.pid",
"host.name",
"host.id",
"powershell.file.script_block_length"
]
[transform]
[[transform.investigate]]
label = "Alerts associated with the user"
description = ""
providers = [
[
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
{ excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
]
]
relativeFrom = "now-48h/h"
relativeTo = "now"
[[transform.investigate]]
label = "Alerts associated with the host"
description = ""
providers = [
[
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
]
]
relativeFrom = "now-48h/h"
relativeTo = "now"
[[transform.investigate]]
label = "All PowerShell 4104 fragments for this script on this host"
description = ""
providers = [
[
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "powershell.file.script_block_id", queryType = "phrase", value = "{{powershell.file.script_block_id}}", valueType = "string" },
{ excluded = false, field = "event.code", queryType = "phrase", value = "4104", valueType = "string" }
]
]
relativeFrom = "now-1h"
relativeTo = "now"
[[transform.investigate]]
label = "Process events for the PowerShell instance"
description = ""
providers = [
[
{ excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
]
]
relativeFrom = "now-1h"
relativeTo = "now"
[[transform.investigate]]
label = "File events for the PowerShell process"
description = ""
providers = [
[
{ excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" }
]
]
relativeFrom = "now-1h"
relativeTo = "now"
[[transform.investigate]]
label = "Kerberos service ticket events for the alert user name"
description = ""
providers = [
[
{ excluded = false, field = "winlog.event_data.TargetUserName", queryType = "phrase", value = "{{user.name}}", valueType = "string" },
{ excluded = false, field = "event.code", queryType = "phrase", value = "4769", valueType = "string" }
]
]
relativeFrom = "now-24h"
relativeTo = "now"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1558"
name = "Steal or Forge Kerberos Tickets"
reference = "https://attack.mitre.org/techniques/T1558/"
[[rule.threat.technique.subtechnique]]
id = "T1558.003"
name = "Kerberoasting"
reference = "https://attack.mitre.org/techniques/T1558/003/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
Stages and Predicates
Stage 1: query
event.category:process and host.os.type:windows and
powershell.file.script_block_text : "KerberosRequestorSecurityToken" and
not powershell.file.script_block_text : (
("sentinelbreakpoints" and ("Set-PSBreakpoint" or "Set-HookFunctionTabs")) or
("function global" and "\\windows\\sentinel\\4")
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.category | eq |
| field:"event.category" kind:eq value:"process" |
powershell.file.script_block_text | eq |
| field:"ScriptBlockText" kind:eq value:"KerberosRequestorSecurityToken" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
powershell.file.script_block_text | eq | \windows\sentinel\4 | excludes:powershell.file.script_block_text field:"powershell.file.script_block_text" value:"\windows\sentinel\4" |
powershell.file.script_block_text | eq | function global | excludes:powershell.file.script_block_text field:"powershell.file.script_block_text" value:"function global" |
powershell.file.script_block_text | eq | sentinelbreakpoints | excludes:powershell.file.script_block_text field:"powershell.file.script_block_text" value:"sentinelbreakpoints" |
powershell.file.script_block_text | in | Set-HookFunctionTabs, Set-PSBreakpoint | excludes:powershell.file.script_block_text field:"powershell.file.script_block_text" value:"Set-HookFunctionTabs" field:"powershell.file.script_block_text" value:"Set-PSBreakpoint" |
PowerShell Script Block Logging Disabled
#Detects registry changes that disable PowerShell Script Block Logging. Attackers may disable this logging to conceal their activities in the host and evade detection.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Defense Impairment |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2022/01/31"
integration = ["endpoint", "windows", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/05/04"
[rule]
author = ["Elastic"]
description = """
Detects registry changes that disable PowerShell Script Block Logging. Attackers may disable this logging to conceal
their activities in the host and evade detection.
"""
from = "now-9m"
index = [
"winlogbeat-*",
"logs-endpoint.events.registry-*",
"logs-windows.sysmon_operational-*",
"endgame-*",
"logs-m365_defender.event-*",
"logs-sentinel_one_cloud_funnel.*",
"logs-crowdstrike.fdr*",
]
language = "eql"
license = "Elastic License v2"
name = "PowerShell Script Block Logging Disabled"
note = """## Triage and analysis
> **Disclaimer**:
> This guide was created by humans with the assistance of generative AI. While its contents have been manually curated to include the most valuable information, always validate assumptions and adjust procedures to match your internal runbooks and incident triage and response policies.
### Investigating PowerShell Script Block Logging Disabled
This alert indicates a registry modification that set `EnableScriptBlockLogging` to a disabled value (`registry.data.strings` of `0` or `0x00000000`). Disabling Script Block Logging reduces visibility into PowerShell execution and is commonly used to evade detection, especially when followed by script-driven activity.
#### Key alert fields to review
- `process.executable`: The process responsible for modifying the registry value.
- `registry.value`: The registry value name that was changed (`EnableScriptBlockLogging`).
- `registry.data.strings`: The new data indicating the setting was disabled.
- `registry.path`: The full registry path of the modified value.
- `user.name`, `user.domain`, `user.id`: Account execution context for correlation, prioritization, and scoping.
- `host.name`, `host.id`: Host execution context for correlation, prioritization, and scoping.
#### Possible investigation steps
- Establish the affected endpoint and time window:
- Use `host.name`, `host.id`, and `@timestamp` to identify the impacted endpoint and define a review window (include activity immediately before and after the change).
- Prioritize based on endpoint role and criticality (for example, servers and admin workstations).
- Validate the registry change and its scope:
- Review `registry.path`, `registry.value`, and `registry.data.strings` to confirm the setting was disabled and to understand where it was applied.
- Compare `registry.path` to common policy locations for Script Block Logging (for example, `HKEY_LOCAL_MACHINE\\Software\\Policies\\Microsoft\\Windows\\PowerShell\\ScriptBlockLogging\\EnableScriptBlockLogging`).
- Determine whether the change is likely machine-wide or user-scoped based on the hive reflected in `registry.path`, and assess the blast radius accordingly.
- Check for repeated changes (toggling) to the same `registry.path` and `registry.value` around the alert time, which can indicate attempted evasion or policy enforcement conflicts.
- Identify the modifying process and execution context:
- Review `process.executable` for legitimacy (expected binary name, expected install path) and whether it typically performs configuration changes.
- Pivoting using `process.entity_id`, review `process.command_line` to understand how the value was set and whether the command line suggests interactive administration, scripts, or automation.
- Using nearby endpoint process telemetry on the same host, reconstruct the process tree to identify the initiating process (parent) and any immediate follow-on execution that may have benefited from reduced PowerShell logging.
- Assess the user context and authorization:
- Review `user.name`, `user.domain`, and `user.id` to determine whether the account is expected to manage logging or policy settings on this endpoint.
- If the change is attributed to a service or system context, identify the associated service, scheduled activity, or management workflow that could have performed the modification.
- Scope the user across other hosts for similar activity during the same window to identify potential credential misuse.
- Hunt for related activity that may be masked by reduced logging:
- Review host activity immediately before the change for suspicious behavior that could explain the need to disable Script Block Logging (initial access, privilege escalation, or tool staging).
- Review host activity after the change for suspicious process launches, script interpreter activity, persistence attempts, credential access behavior, or lateral movement indicators.
- Review network activity from the host around the change for connections consistent with payload retrieval, remote access, or command and control.
- Review other registry changes around the same time that may further impair visibility or weaken defenses.
- Scope and impact assessment across the environment:
- Search for other instances where `registry.value` is `EnableScriptBlockLogging` and `registry.data.strings` indicates a disabled state to determine whether this is isolated or widespread.
- Pivot on `process.executable` and `user.id` to identify other endpoints where the same process or account modified this setting.
- Identify whether the setting was later restored on the same host by looking for subsequent changes to the same `registry.path` and `registry.value`.
### False positive analysis
- Authorized policy, baseline, or hardening changes that intentionally modify PowerShell logging settings, supported by change records and consistent execution by expected accounts and tooling.
- Provisioning or imaging workflows where configuration changes occur during early host lifecycle stages and are consistent across a known deployment batch.
- Short-lived administrative troubleshooting where the setting is temporarily changed and promptly restored, with supporting documentation.
### Response and remediation
- If the change is unexpected or suspicious:
- Treat as potential defense evasion and escalate according to incident response procedures.
- Contain the endpoint if there are indicators of follow-on malicious activity in the surrounding timeframe.
- Preserve evidence related to the change, including `process.executable`, `process.command_line`, user context, and any correlated endpoint telemetry.
- Restore and enforce PowerShell visibility:
- Re-enable Script Block Logging using approved administrative processes and verify the setting persists through policy enforcement.
- Monitor for repeated attempts to disable Script Block Logging, especially from the same user or originating process.
- Remediate root cause and reduce recurrence:
- Identify and remove unauthorized tooling or persistence associated with the modifying process.
- Investigate potential account compromise for the associated user and take appropriate actions (credential reset and access review), prioritizing privileged accounts.
- Hunt for additional endpoints impacted by the same user or process and remediate as needed.
- Apply least-privilege controls to limit who can modify logging-related registry settings and improve alerting for additional defense impairment behaviors observed during the investigation window.
"""
setup = """## Setup
This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
Setup instructions: https://ela.st/install-elastic-defend
### Additional data sources
This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
- [CrowdStrike](https://ela.st/crowdstrike-integration)
- [Microsoft Defender XDR](https://ela.st/m365-defender)
- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
- [Sysmon Registry Events](https://ela.st/sysmon-event-reg-setup)
"""
references = [
"https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.PowerShell::EnableScriptBlockLogging",
]
risk_score = 47
rule_id = "818e23e6-2094-4f0e-8c01-22d30f3506c6"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Defense Evasion",
"Resources: Investigation Guide",
"Data Source: Elastic Endgame",
"Data Source: Elastic Defend",
"Data Source: Sysmon",
"Data Source: Microsoft Defender XDR",
"Data Source: SentinelOne",
"Data Source: Crowdstrike",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
registry where host.os.type == "windows" and event.type == "change" and
registry.value : "EnableScriptBlockLogging" and
registry.data.strings : ("0", "0x00000000") and
not process.executable : (
"?:\\Windows\\System32\\svchost.exe",
"?:\\Windows\\System32\\DeviceEnroller.exe",
"?:\\Windows\\system32\\omadmclient.exe",
"?:\\Program Files\\Trend Micro\\Cloud Endpoint\\CloudEndpointService.exe",
"?:\\Program Files (x86)\\N-able Technologies\\AutomationManagerAgent\\AutomationManager.AgentService.exe",
/* Crowdstrike specific exclusion as it uses NT Object paths */
"\\Device\\HarddiskVolume*\\Windows\\System32\\svchost.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\DeviceEnroller.exe",
"\\Device\\HarddiskVolume*\\Windows\\system32\\omadmclient.exe",
"\\Device\\HarddiskVolume*\\Program Files\\Trend Micro\\Cloud Endpoint\\CloudEndpointService.exe",
"\\Device\\HarddiskVolume*\\Program Files (x86)\\N-able Technologies\\AutomationManagerAgent\\AutomationManager.AgentService.exe"
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1112"
name = "Modify Registry"
reference = "https://attack.mitre.org/techniques/T1112/"
[[rule.threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[[rule.threat.technique.subtechnique]]
id = "T1562.002"
name = "Disable Windows Event Logging"
reference = "https://attack.mitre.org/techniques/T1562/002/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[rule.investigation_fields]
field_names = [
"@timestamp",
"registry.path",
"registry.value",
"registry.data.strings",
"process.executable",
"process.entity_id",
"host.name",
"host.id",
"user.name",
"user.id",
"user.domain"
]
Stages and Predicates
Stage 1: registry
registry where host.os.type == "windows" and event.type == "change" and
registry.value : "EnableScriptBlockLogging" and
registry.data.strings : ("0", "0x00000000") and
not process.executable : (
"?:\\Windows\\System32\\svchost.exe",
"?:\\Windows\\System32\\DeviceEnroller.exe",
"?:\\Windows\\system32\\omadmclient.exe",
"?:\\Program Files\\Trend Micro\\Cloud Endpoint\\CloudEndpointService.exe",
"?:\\Program Files (x86)\\N-able Technologies\\AutomationManagerAgent\\AutomationManager.AgentService.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\svchost.exe",
"\\Device\\HarddiskVolume*\\Windows\\System32\\DeviceEnroller.exe",
"\\Device\\HarddiskVolume*\\Windows\\system32\\omadmclient.exe",
"\\Device\\HarddiskVolume*\\Program Files\\Trend Micro\\Cloud Endpoint\\CloudEndpointService.exe",
"\\Device\\HarddiskVolume*\\Program Files (x86)\\N-able Technologies\\AutomationManagerAgent\\AutomationManager.AgentService.exe"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"change" |
registry.data.strings | wildcard |
| field:"Details" kind:wildcard |
registry.value | wildcard |
| field:"registry_value_name" kind:wildcard value:"EnableScriptBlockLogging" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.executable | wildcard | ?:\Windows\System32\svchost.exe, ?:\Windows\System32\DeviceEnroller.exe, ?:\Windows\system32\omadmclient.exe, ?:\Program Files\Trend Micro\Cloud Endpoint\CloudEndpointService.exe, ?:\Program Files (x86)\N-able Technologies\AutomationManagerAgent\AutomationManager.AgentService.exe, \Device\HarddiskVolume*\Windows\System32\svchost.exe, \Device\HarddiskVolume*\Windows\System32\DeviceEnroller.exe, \Device\HarddiskVolume*\Windows\system32\omadmclient.exe, \Device\HarddiskVolume*\Program Files\Trend Micro\Cloud Endpoint\CloudEndpointService.exe, \Device\HarddiskVolume*\Program Files (x86)\N-able Technologies\AutomationManagerAgent\AutomationManager.AgentService.exe | excludes:process.executable |
Shell Command-Line History Deletion Detected via Defend for Containers
#This rule detects the deletion of shell command-line history files inside a container. The shell command-line history files are used to store the command-line history for the shell. Adversaries may delete these files to cover their tracks or evade detection.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule Body
[metadata]
creation_date = "2026/02/06"
integration = ["cloud_defend"]
maturity = "production"
min_stack_comments = "Defend for Containers integration was re-introduced in 9.3.0"
min_stack_version = "9.3.0"
updated_date = "2026/07/29"
[rule]
author = ["Elastic"]
description = """
This rule detects the deletion of shell command-line history files inside a container. The shell command-line history
files are used to store the command-line history for the shell. Adversaries may delete these files to cover their tracks
or evade detection.
"""
from = "now-6m"
index = ["logs-cloud_defend.file*", "logs-cloud_defend.process*"]
interval = "5m"
language = "eql"
license = "Elastic License v2"
name = "Shell Command-Line History Deletion Detected via Defend for Containers"
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Shell Command-Line History Deletion Detected via Defend for Containers
This rule detects attempts to delete, truncate, or disable shell command history files inside containers, a common tactic to erase evidence and impede investigations. An attacker uses kubectl exec to open an interactive bash shell in a running pod, then symlinks /root/.bash_history to /dev/null to prevent future commands from being recorded while performing reconnaissance or credential access.
### Possible investigation steps
- Correlate the container to its pod, namespace, and owning workload, and pull Kubernetes audit logs for exec/attach around the alert time to identify the caller identity, source IP, and user-agent and validate business justification.
- Reconstruct the interactive session timeline by reviewing adjacent process telemetry before and after the history suppression to surface reconnaissance, credential access, data staging, or tooling downloads the actor may be hiding.
- Examine shell configs and filesystem state for persistent history suppression (e.g., HISTFILE/HISTSIZE/HISTCONTROL in /etc/profile.d or .bashrc/.zshrc, or history files symlinked to /dev/null) and compare timestamps/owners to distinguish image defaults from live tampering.
- Assess runtime context for impact by confirming the session’s user/UID, effective capabilities, mounted secrets or tokens, and writable volumes, and checking for privilege escalation or access to sensitive data.
- If unauthorized, isolate the pod and capture volatile evidence (filesystem tarball, /proc, environment variables, shell rc files), rotate any exposed credentials, and hunt for similar events across pods/namespaces and the same source IP or identity.
### False positive analysis
- An authorized operator opens an interactive shell in a container for troubleshooting and intentionally clears or disables history (e.g., history -c, rm/truncate ~/.bash_history, or export HISTFILE=/dev/null) to avoid recording sensitive commands.
- The container image’s interactive shell startup configuration automatically disables history (e.g., HISTFILESIZE=0, unset HISTFILE, or linking ~/.bash_history to /dev/null), so a normal debug login triggers the alert.
### Response and remediation
- Isolate the affected pod by applying a temporary NetworkPolicy to block egress, remove pods/exec and pods/attach permissions from the caller, and terminate any interactive shells that executed rm, history -c, or truncate on ~/.bash_history or linked it to /dev/null.
- Eradicate changes by removing any ~/.bash_history symlink to /dev/null, recreating /root/.bash_history and /home/*/.bash_history with correct ownership and 600 permissions, and restoring HISTFILE/HISTFILESIZE/HISTCONTROL in /etc/profile.d, .bashrc, and .zshrc to expected values.
- Recover by rebuilding and redeploying the workload from a trusted image, rotating any secrets or tokens accessed during the session (service account token, cloud provider credentials, SSH keys), and validating that new shells now persist command history.
- Escalate to incident response if the exec caller identity is unknown or unauthorized, if privileged actions (kubectl with cluster-admin, sudo, or reading /var/run/secrets/kubernetes.io/serviceaccount) occurred after history deletion, or if multiple pods/namespaces show coordinated history suppression.
- Harden by restricting kubectl exec/attach to break-glass roles via RBAC, enforcing admission controls to block images or init scripts that unset HISTFILE or link ~/.bash_history to /dev/null, and adding runtime policy to deny rm/truncate of history files and alert on history -c."""
risk_score = 73
rule_id = "cebabc1e-1145-4e39-b04b-34d621ee1e2c"
severity = "high"
tags = [
"Data Source: Elastic Defend for Containers",
"Domain: Container",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Defense Evasion",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
any where host.os.type == "linux" and event.category in ("file", "process") and container.id like "?*" and (
(event.category == "file" and event.type == "deletion" and file.name in (".bash_history", ".sh_history", ".zsh_history")) or
(event.category == "process" and event.type == "start" and event.action == "exec" and (
(
(
process.args in (
"rm", "/bin/rm", "/usr/bin/rm", "/usr/local/bin/rm",
"echo", "/bin/echo", "/usr/bin/echo", "/usr/local/bin/echo"
) or
(process.args in ("ln", "/bin/ln", "/usr/bin/ln", "/usr/local/bin/ln") and process.args == "-sf" and process.args == "/dev/null") or
(process.args in ("truncate", "/bin/truncate", "/usr/bin/truncate", "/usr/local/bin/truncate") and process.args == "-s0")
) and process.args like ("*.bash_history*", "*.sh_history*", "*.zsh_history*")
) or
(process.name == "history" and process.args == "-c") or
(process.args == "export" and process.args in ("HISTFILE=/dev/null", "HISTFILESIZE=0")) or
(process.args == "unset" and process.args == "HISTFILE") or
(process.args == "set" and process.args == "history" and process.args == "+o")
)
)
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[rule.threat.tactic]
name = "Defense Evasion"
id = "TA0005"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[rule.threat.technique]]
name = "Indicator Removal"
id = "T1070"
reference = "https://attack.mitre.org/techniques/T1070/"
[[rule.threat.technique.subtechnique]]
name = "Clear Command History"
id = "T1070.003"
reference = "https://attack.mitre.org/techniques/T1070/003/"
Stages and Predicates
Stage 1: any
any where host.os.type == "linux" and event.category in ("file", "process") and container.id like "?*" and (
(event.category == "file" and event.type == "deletion" and file.name in (".bash_history", ".sh_history", ".zsh_history")) or
(event.category == "process" and event.type == "start" and event.action == "exec" and (
(
(
process.args in (
"rm", "/bin/rm", "/usr/bin/rm", "/usr/local/bin/rm",
"echo", "/bin/echo", "/usr/bin/echo", "/usr/local/bin/echo"
) or
(process.args in ("ln", "/bin/ln", "/usr/bin/ln", "/usr/local/bin/ln") and process.args == "-sf" and process.args == "/dev/null") or
(process.args in ("truncate", "/bin/truncate", "/usr/bin/truncate", "/usr/local/bin/truncate") and process.args == "-s0")
) and process.args like ("*.bash_history*", "*.sh_history*", "*.zsh_history*")
) or
(process.name == "history" and process.args == "-c") or
(process.args == "export" and process.args in ("HISTFILE=/dev/null", "HISTFILESIZE=0")) or
(process.args == "unset" and process.args == "HISTFILE") or
(process.args == "set" and process.args == "history" and process.args == "+o")
)
)
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
container.id | wildcard |
| field:"container.id" kind:wildcard value:"?*" |
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.category | eq |
| field:"event.category" kind:eq |
event.category | in |
| field:"event.category" kind:in |
event.type | eq |
| field:"event.type" kind:eq |
file.name | in |
| field:"file.name" kind:in |
process.args | eq |
| field:"process.args" kind:eq |
process.args | in |
| field:"process.args" kind:in |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.name | eq |
| field:"process_basename" kind:eq value:"history" |
Spike in Failed Logon Events
#A machine learning job found an unusually large spike in authentication failure events. This can be due to password spraying, user enumeration or brute force activity and may be a precursor to account takeover or credentialed access.
Known False Positives
- A misconfigured service account can trigger this alert. A password change on an account used by an email client can trigger this alert. Security test cycles that include brute force or password spraying activities may trigger this alert.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Rule Body
[metadata]
creation_date = "2021/06/10"
integration = ["auditd_manager", "endpoint", "system"]
maturity = "production"
min_stack_version = "9.4.0"
min_stack_comments = "Use EA (Entity Analytics) fields"
updated_date = "2026/07/27"
[rule]
anomaly_threshold = 75
author = ["Elastic"]
description = """
A machine learning job found an unusually large spike in authentication failure events. This can be due to password
spraying, user enumeration or brute force activity and may be a precursor to account takeover or credentialed access.
"""
false_positives = [
"""
A misconfigured service account can trigger this alert. A password change on an account used by an email client can
trigger this alert. Security test cycles that include brute force or password spraying activities may trigger this
alert.
""",
]
from = "now-30m"
interval = "15m"
license = "Elastic License v2"
machine_learning_job_id = "auth_high_count_logon_fails_ea"
name = "Spike in Failed Logon Events"
setup = """## Setup
This rule requires the installation of associated Machine Learning jobs, as well as data coming in from one of the following integrations:
- Elastic Defend
- Auditd Manager
- System
### Anomaly Detection Setup
Once the rule is enabled, the associated Machine Learning job will start automatically. You can view the Machine Learning job linked under the "Definition" panel of the detection rule. If the job does not start due to an error, the issue must be resolved for the job to commence successfully. For more details on setting up anomaly detection jobs, refer to the [helper guide](https://www.elastic.co/guide/en/kibana/current/xpack-ml-anomalies.html).
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration to your system:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/current/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
### Auditd Manager Integration Setup
The Auditd Manager Integration receives audit events from the Linux Audit Framework which is a part of the Linux kernel.
Auditd Manager provides a user-friendly interface and automation capabilities for configuring and monitoring system auditing through the auditd daemon. With `auditd_manager`, administrators can easily define audit rules, track system events, and generate comprehensive audit reports, improving overall security and compliance in the system.
#### The following steps should be executed in order to add the Elastic Agent System integration "auditd_manager" to your system:
- Go to the Kibana home page and click “Add integrations”.
- In the query bar, search for “Auditd Manager” and select the integration to see more details about it.
- Click “Add Auditd Manager”.
- Configure the integration name and optionally add a description.
- Review optional and advanced settings accordingly.
- Add the newly installed “auditd manager” to an existing or a new agent policy, and deploy the agent on a Linux system from which auditd log files are desirable.
- Click “Save and Continue”.
- For more details on the integration refer to the [helper guide](https://docs.elastic.co/integrations/auditd_manager).
#### Rule Specific Setup Note
Auditd Manager subscribes to the kernel and receives events as they occur without any additional configuration.
However, if more advanced configuration is required to detect specific behavior, audit rules can be added to the integration in either the "audit rules" configuration box or the "auditd rule files" box by specifying a file to read the audit rules from.
- For this detection rule no additional audit rules are required.
### System Integration Setup
The System integration allows you to collect system logs and metrics from your servers with Elastic Agent.
#### The following steps should be executed in order to add the Elastic Agent System integration "system" to your system:
- Go to the Kibana home page and click “Add integrations”.
- In the query bar, search for “System” and select the integration to see more details about it.
- Click “Add System”.
- Configure the integration name and optionally add a description.
- Review optional and advanced settings accordingly.
- Add the newly installed “system” to an existing or a new agent policy, and deploy the agent on your system from which system log files are desirable.
- Click “Save and Continue”.
- For more details on the integration refer to the [helper guide](https://docs.elastic.co/integrations/system).
"""
note = """## Triage and analysis
### Investigating Spike in Failed Logon Events
This rule uses a machine learning job to detect a substantial spike in failed authentication events. This could indicate attempts to enumerate users, password spraying, brute force, etc.
#### Possible investigation steps
- Identify the users involved and if the activity targets a specific user or a set of users.
- Check if the authentication comes from different sources.
- Investigate if the host where the failed authentication events occur is exposed to the internet.
- If the host is exposed to the internet, and the source of these attempts is external, the activity can be related to bot activity and possibly not directed at your organization.
- If the host is not exposed to the internet, investigate the hosts where the authentication attempts are coming from, as this can indicate that they are compromised and the attacker is trying to move laterally.
- Investigate other alerts associated with the involved users and hosts during the past 48 hours.
- Check whether the involved credentials are used in automation or scheduled tasks.
- If this activity is suspicious, contact the account owner and confirm whether they are aware of it.
- Investigate whether there are successful authentication events from the involved sources. This could indicate a successful brute force or password spraying attack.
### False positive analysis
- If the account is used in automation tasks, it is possible that they are using expired credentials, causing a spike in authentication failures.
- Authentication failures can be related to permission issues.
### Response and remediation
- Initiate the incident response process based on the outcome of the triage.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Assess whether the asset should be exposed to the internet, and take action to reduce your attack surface.
- If the asset needs to be exposed to the internet, restrict access to remote login services to specific IPs.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
references = ["https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html"]
risk_score = 21
rule_id = "99dcf974-6587-4f65-9252-d866a3fdfd9c"
severity = "low"
tags = [
"Data Source: Elastic Defend",
"Data Source: Auditd Manager",
"Data Source: Windows Security Event Logs",
"Use Case: Identity and Access Audit",
"Use Case: Threat Detection",
"Rule Type: ML",
"Rule Type: Machine Learning",
"Tactic: Credential Access",
"Resources: Investigation Guide",
]
type = "machine_learning"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1110"
name = "Brute Force"
reference = "https://attack.mitre.org/techniques/T1110/"
[[rule.threat.technique.subtechnique]]
id = "T1110.001"
name = "Password Guessing"
reference = "https://attack.mitre.org/techniques/T1110/001/"
[[rule.threat.technique.subtechnique]]
id = "T1110.003"
name = "Password Spraying"
reference = "https://attack.mitre.org/techniques/T1110/003/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
Stolen Credentials Used to Login to Okta Account After MFA Reset
#Detects a sequence of suspicious activities on Windows hosts indicative of credential compromise, followed by efforts to undermine multi-factor authentication (MFA) and single sign-on (SSO) mechanisms for an Okta user account.
Known False Positives
- A Windows administrator may have triggered a low-fidelity credential access alert during a legitimate administrative action. Following this, the administrator may have reset the MFA credentials for themselves and then logged into the Okta console for AD directory services integration management.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence |
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
- Okta Investigate MFA and Password resets (Panther)
- Okta Support Reset Credential (Panther)
Rule Body
[metadata]
creation_date = "2023/11/09"
integration = ["endpoint", "okta"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
Detects a sequence of suspicious activities on Windows hosts indicative of credential compromise, followed by efforts to
undermine multi-factor authentication (MFA) and single sign-on (SSO) mechanisms for an Okta user account.
"""
false_positives = [
"""
A Windows administrator may have triggered a low-fidelity credential access alert during a legitimate administrative
action. Following this, the administrator may have reset the MFA credentials for themselves and then logged into the
Okta console for AD directory services integration management.
""",
]
from = "now-12h"
index = ["filebeat-*", "logs-okta*", ".alerts-security.*", "logs-endpoint.events.*"]
interval = "6h"
language = "eql"
license = "Elastic License v2"
name = "Stolen Credentials Used to Login to Okta Account After MFA Reset"
note = """## Triage and analysis
### Investigating Stolen Credentials Used to Login to Okta Account After MFA Reset
This rule detects a sequence of suspicious activities on Windows hosts indicative of credential compromise, followed by efforts to undermine multi-factor authentication (MFA) and single sign-on (SSO) mechanisms for an Okta user account.
Typically, adversaries initially extract credentials from targeted endpoints through various means. Subsequently, leveraging social engineering, they may seek to reset the MFA credentials associated with an Okta account, especially in scenarios where Active Directory (AD) services are integrated with Okta. Successfully resetting MFA allows the unauthorized use of stolen credentials to gain access to the compromised Okta account. The attacker can then register their own device for MFA, paving the way for unfettered access to the user's Okta account and any associated SaaS applications. This is particularly alarming if the compromised account has administrative rights, as it could lead to widespread access to organizational resources and configurations.
#### Possible investigation steps:
- Identify the user account associated with the Okta login attempt by examining the `user.name` field.
- Identify the endpoint for the Credential Access alert for this user by examining the `host.name` and `host.id` fields from the alert document.
- Cross-examine the Okta user and endpoint user to confirm that they are the same person.
- Reach out to the user to confirm if they have intentionally reset their MFA credentials recently or asked for help in doing so.
- If the user is unaware of the MFA reset, incident response may be required immediately to prevent further compromise.
### False positive analysis:
- A Windows administrator may have triggered a low-fidelity credential access alert during a legitimate administrative action. Following this, the administrator may have reset the MFA credentials for themselves and then logged into the Okta console for AD directory services integration management.
### Response and remediation:
- If confirmed that the user did not intentionally have their MFA factor reset, deactivate the user account.
- After deactivation, reset the user's password and MFA factor to regain control of the account.
- Ensure that all user sessions are stopped during this process.
- Immediately reset the user's AD password as well if Okta does not sync back to AD.
- Forensic analysis on the user's endpoint may be required to determine the root cause of the compromise and identify the scope of the compromise.
- Review Okta system logs to identify any other suspicious activity associated with the user account, such as creation of a backup account.
- With the device ID captured from the MFA factor reset, search across all Okta logs for any other activity associated with the device ID.
## Setup
The Okta and Elastic Defend fleet integration structured data is required to be compatible with this rule. Directory services integration in Okta with AD synced is also required for this rule to be effective as it relies on triaging `user.name` from Okta and Elastic Defend events.
"""
references = [
"https://developer.okta.com/docs/reference/api/system-log/",
"https://developer.okta.com/docs/reference/api/event-types/",
"https://www.elastic.co/security-labs/testing-okta-visibility-and-detection-dorothy",
"https://sec.okta.com/articles/2023/08/cross-tenant-impersonation-prevention-and-detection",
"https://www.elastic.co/security-labs/monitoring-okta-threats-with-elastic-security",
"https://www.elastic.co/security-labs/starter-guide-to-understanding-okta",
]
risk_score = 73
rule_id = "5610b192-7f18-11ee-825b-f661ea17fbcd"
severity = "high"
tags = [
"Tactic: Persistence",
"Use Case: Identity and Access Audit",
"Data Source: Okta",
"Data Source: Elastic Defend",
"Rule Type: Higher-Order Rule",
"Domain: Endpoint",
"Domain: Cloud",
"Resources: Investigation Guide",
]
type = "eql"
query = '''
sequence by user.name with maxspan=12h
[any where host.os.type == "windows" and signal.rule.threat.tactic.name == "Credential Access"]
[any where data_stream.dataset == "okta.system" and okta.event_type == "user.mfa.factor.update"]
[any where data_stream.dataset == "okta.system" and okta.event_type: ("user.session.start", "user.authentication*")]
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1556"
name = "Modify Authentication Process"
reference = "https://attack.mitre.org/techniques/T1556/"
[[rule.threat.technique.subtechnique]]
id = "T1556.006"
name = "Multi-Factor Authentication"
reference = "https://attack.mitre.org/techniques/T1556/006/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
Stages and Predicates
Ordered sequence: each step below must occur in order within 12h, correlated by user.name.
Stage 1: any
[any where host.os.type == "windows" and signal.rule.threat.tactic.name == "Credential Access"]
Stage 2: any
[any where data_stream.dataset == "okta.system" and okta.event_type == "user.mfa.factor.update"]
Stage 3: any
[any where data_stream.dataset == "okta.system" and okta.event_type: ("user.session.start", "user.authentication*")]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"okta.system" |
okta.event_type | eq |
| field:"okta::eventType" kind:eq value:"user.mfa.factor.update" |
okta.event_type | wildcard |
| field:"okta::eventType" kind:wildcard |
signal.rule.threat.tactic.name | eq |
| field:"signal.rule.threat.tactic.name" kind:eq value:"Credential Access" |
Suspicious Curl Execution via NodeJS
#Identifies the execution of the CURL utility from a NodeJS script interpreter. This may indicate an attempt to transfer tools via a malicious JavaScript file.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Command & Control |
Telemetry Coverage
Rule Body
[rule]
description = """
Identifies the execution of the CURL utility from a NodeJS script interpreter. This may indicate an attempt to transfer
tools via a malicious JavaScript file.
"""
id = "04dc5f8a-8c12-412a-86ca-ef4f2b024531"
license = "Elastic License v2"
name = "Suspicious Curl Execution via NodeJS"
os_list = ["macos", "windows"]
reference = [
"https://www.elastic.co/blog/shai-hulud-worm-npm-supply-chain-compromise",
"https://socket.dev/blog/shai-hulud-strikes-again-v2",
]
version = "1.0.2"
query = '''
process where event.action in ("start", "exec") and
process.parent.name in ("node.exe", "node", "bun", "bun.exe") and
process.name in ("curl", "curl.exe") and process.args in ("-o", "--output") and process.args like "http*" and
process.parent.command_line : "*node_modules*.js*" and not process.command_line : ("*://localhost*", "*://127.0.0.1*")
'''
min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.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 = "T1105"
name = "Ingress Tool Transfer"
reference = "https://attack.mitre.org/techniques/T1105/"
[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: process
process where event.action in ("start", "exec") and
process.parent.name in ("node.exe", "node", "bun", "bun.exe") and
process.name in ("curl", "curl.exe") and process.args in ("-o", "--output") and process.args like "http*" and
process.parent.command_line : "*node_modules*.js*" and not process.command_line : ("*://localhost*", "*://127.0.0.1*")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | in |
| field:"EventType" kind:in |
process.args | in |
| field:"process.args" kind:in |
process.args | wildcard |
| field:"process.args" kind:wildcard value:"http*" |
process.name | in |
| field:"process_basename" kind:in |
process.parent.command_line | wildcard |
| field:"ParentCommandLine" kind:wildcard value:"*node_modules*.js*" |
process.parent.name | in |
| field:"parent_process_basename" kind:in |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.command_line | match | ://localhost, ://127.0.0.1 | excludes:process.command_line field:"process.command_line" value:"://localhost" field:"process.command_line" value:"://127.0.0.1" |
Suspicious File Rename by an Unusual Process
#Identifies the execution of commonly abused signed proxy execution utilities such as rundll32, regsvr32 and powershell followed by a suspicious file rename operation. This may indicate Ransomware behavior leveraging legit Windows utilities.
MITRE ATT&CK Coverage
Rule Body
[rule]
description = """
Identifies the execution of commonly abused signed proxy execution utilities such as rundll32, regsvr32 and powershell
followed by a suspicious file rename operation. This may indicate Ransomware behavior leveraging legit Windows
utilities.
"""
id = "df874d7e-6639-44ce-b47d-96254022ccd5"
license = "Elastic License v2"
name = "Suspicious File Rename by an Unusual Process"
os_list = ["windows"]
version = "1.0.28"
query = '''
sequence by process.entity_id with maxspan=5m
[process where event.action == "start" and process.name : ("rundll32.exe", "regsvr32.exe")]
[file where event.action : "rename" and
file.extension != null and file.Ext.entropy >= 7 and
file.Ext.original.name : ("*.jpg", "*.bmp", "*.png", "*.pdf", "*.doc", "*.docx", "*.xls", "*.xlsx", "*.ppt", "*.pptx") and
not file.extension : ("tmp", "~tmp", "diff", "gz", "download", "bak", "bck", "lnk", "part", "save", "url", "jpg", "bmp",
"png", "pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx")]
'''
min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 1
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "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.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.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/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1486"
name = "Data Encrypted for Impact"
reference = "https://attack.mitre.org/techniques/T1486/"
[[threat.technique]]
id = "T1490"
name = "Inhibit System Recovery"
reference = "https://attack.mitre.org/techniques/T1490/"
[threat.tactic]
id = "TA0040"
name = "Impact"
reference = "https://attack.mitre.org/tactics/TA0040/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 5m, correlated by process.entity_id.
Stage 1: process
[process where event.action == "start" and process.name : ("rundll32.exe", "regsvr32.exe")]
Stage 2: file
[file where event.action : "rename" and
file.extension != null and file.Ext.entropy >= 7 and
file.Ext.original.name : ("*.jpg", "*.bmp", "*.png", "*.pdf", "*.doc", "*.docx", "*.xls", "*.xlsx", "*.ppt", "*.pptx") and
not file.extension : ("tmp", "~tmp", "diff", "gz", "download", "bak", "bck", "lnk", "part", "save", "url", "jpg", "bmp",
"png", "pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx")]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
event.action | wildcard |
| field:"EventType" kind:wildcard value:"rename" |
file.Ext.entropy | ge |
| field:"file.Ext.entropy" kind:ge value:"7" |
file.Ext.original.name | wildcard |
| field:"file.Ext.original.name" kind:wildcard |
file.extension | is_not_null | field:"file.extension" kind:is_not_null | |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
file.extension | eq | tmp, ~tmp, diff, gz, download, bak, bck, lnk, part, save, url, jpg, bmp, png, pdf, doc, docx, xls, xlsx, ppt, pptx | excludes:file.extension |
Suspicious Reading of procfs Maps File
#This rule detects suspicious reading of the /proc/[pid]/maps file which contains the memory mappings for a process. Adversaries may read this file to gather information about the memory layout of a process, which can be useful for exploiting memory corruption vulnerabilities or for performing process injection techniques. Legitimate use cases include debugging and performance monitoring.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Discovery |
Rule Body
[rule]
description = """
This rule detects suspicious reading of the /proc/[pid]/maps file which contains the memory mappings for a process.
Adversaries may read this file to gather information about the memory layout of a process, which can be useful for
exploiting memory corruption vulnerabilities or for performing process injection techniques. Legitimate use cases
include debugging and performance monitoring.
"""
id = "7a9c2b27-7693-4cc8-882e-eb4f0f9bfc4f"
license = "Elastic License v2"
name = "Suspicious Reading of procfs Maps File"
os_list = ["linux"]
version = "1.0.10"
query = '''
process where event.type == "start" and event.action == "exec" and process.name in ("cat", "grep", "tail", "less", "more", "egrep", "fgrep") and
process.args like ("/proc/*/maps", "[stack]", "[vdso]", "[heap]") and not (
process.parent.executable like (
"/var/lib/dpkg/tmp.ci/preinst", "/var/lib/docker/overlay2/*/bin/sqlservr", "/proc/*/bin/sqlservr", "/opt/data/db2inst1/sqllib/bin/db2cos",
"/run/containerd/io.containerd.runtime.v2.task/k8s.io/*/bin/sqlservr", "/opt/mssql/bin/sqlservr", "/usr/lib/ocf/resource.d/heartbeat/Filesystem"
) or
process.parent.args in (
"/sbin/chkrootkit", "/usr/sbin/chkrootkit", "/opt/mssql/bin/handle-crash.sh", "/var/lib/dpkg/tmp.ci/preinst", "/usr/bin/checkservices",
"/usr/lib/ocf/resource.d/heartbeat/Filesystem"
) or
process.parent.args like "/psoft/*/bin/psprocinfo" or
process.working_directory like (
"/opt/secl/linux-ir-scripts-v3", "/etc/audit/rules.d", "/opt/Tanium/TaniumClient/*", "/var/opt/mssql/log", "/opt/oracle.ahf/*",
"/opt/sentinelone/addons/data/SentinelRSO/uac.zip-*", "/run/containerd/io.containerd.runtime.v2.task/k8s.io/*/mssql/log",
"/opt/traps/download/upgrades", "/var/lib/3cxpbx", "/opt/xdragent/traps/rpm-installer", "/opt/traps/rpm-installer"
) or
process.args like "EXT$HRLINK_CEN_CURRENT_MEGA" or
process.parent.command_line in (
"/usr/bin/bash --init-file /usr/share/code/resources/app/out/vs/workbench/contrib/terminal/common/scripts/shellIntegration-bash.sh",
"""xargs -I{} grep -l libcrypto\.so /proc/{}/maps"""
) or
(process.parent.args == "--deb" and process.args == "--upgrade") or
(process.parent.args == "ir_triage" and process.parent.args == "./uac") or
(process.parent.args == "./setup.sh" and process.parent.args == "--deb") or
(process.parent.executable == "/opt/traps/rpm-installer/setup.sh" and process.command_line == "cat /proc/self/maps") or
((process.parent.name == "thieves.sh" or process.parent.args == "./thieves.sh") and process.command_line like "grep r--p 00000000 /proc/*/maps") or
(process.working_directory like "/tmp/selfgz*" and process.command_line == "cat /proc/self/maps") or
(process.name == "grep" and process.args == "-qiE" and process.args like "libsdmp*libserviceDiscovery*so") or
(process.parent.executable == "/usr/lib/systemd/systemd" and process.parent.command_line == "/sbin/init") or
process.parent.command_line like "*/.claude/shell-snapshots*" or
(process.parent.executable like "/tmp/*/rasoat_new.sh" and process.parent.command_line like "/bin/bash ./rasoat_new.sh*") or
(process.parent.command_line in ("/bin/bash --norc --noprofile -m -i", "rasoat_new.sh") and process.args == "-H" and process.args == "memfd") or
process.command_line == "grep -Eow /.*ld-.*.so /proc/self/maps" or
process.group_leader.executable in ("/usr/local/qualys/cloud-agent/bin/qualys-cloud-agent", "/opt/traps/bin/cytool") or
(
process.parent.executable == "/bin/sh" and
process.parent.command_line == "/bin/sh -s unix:cmd" and
process.working_directory == "/ebsmnt/erlang/usercode"
)
)
'''
min_endpoint_version = "8.6.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 = "T1057"
name = "Process Discovery"
reference = "https://attack.mitre.org/techniques/T1057/"
[threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
[internal]
min_endpoint_version = "8.6.0"
Stages and Predicates
Stage 1: process
process where event.type == "start" and event.action == "exec" and process.name in ("cat", "grep", "tail", "less", "more", "egrep", "fgrep") and
process.args like ("/proc/*/maps", "[stack]", "[vdso]", "[heap]") and not (
process.parent.executable like (
"/var/lib/dpkg/tmp.ci/preinst", "/var/lib/docker/overlay2/*/bin/sqlservr", "/proc/*/bin/sqlservr", "/opt/data/db2inst1/sqllib/bin/db2cos",
"/run/containerd/io.containerd.runtime.v2.task/k8s.io/*/bin/sqlservr", "/opt/mssql/bin/sqlservr", "/usr/lib/ocf/resource.d/heartbeat/Filesystem"
) or
process.parent.args in (
"/sbin/chkrootkit", "/usr/sbin/chkrootkit", "/opt/mssql/bin/handle-crash.sh", "/var/lib/dpkg/tmp.ci/preinst", "/usr/bin/checkservices",
"/usr/lib/ocf/resource.d/heartbeat/Filesystem"
) or
process.parent.args like "/psoft/*/bin/psprocinfo" or
process.working_directory like (
"/opt/secl/linux-ir-scripts-v3", "/etc/audit/rules.d", "/opt/Tanium/TaniumClient/*", "/var/opt/mssql/log", "/opt/oracle.ahf/*",
"/opt/sentinelone/addons/data/SentinelRSO/uac.zip-*", "/run/containerd/io.containerd.runtime.v2.task/k8s.io/*/mssql/log",
"/opt/traps/download/upgrades", "/var/lib/3cxpbx", "/opt/xdragent/traps/rpm-installer", "/opt/traps/rpm-installer"
) or
process.args like "EXT$HRLINK_CEN_CURRENT_MEGA" or
process.parent.command_line in (
"/usr/bin/bash --init-file /usr/share/code/resources/app/out/vs/workbench/contrib/terminal/common/scripts/shellIntegration-bash.sh",
"""xargs -I{} grep -l libcrypto\.so /proc/{}/maps"""
) or
(process.parent.args == "--deb" and process.args == "--upgrade") or
(process.parent.args == "ir_triage" and process.parent.args == "./uac") or
(process.parent.args == "./setup.sh" and process.parent.args == "--deb") or
(process.parent.executable == "/opt/traps/rpm-installer/setup.sh" and process.command_line == "cat /proc/self/maps") or
((process.parent.name == "thieves.sh" or process.parent.args == "./thieves.sh") and process.command_line like "grep r--p 00000000 /proc/*/maps") or
(process.working_directory like "/tmp/selfgz*" and process.command_line == "cat /proc/self/maps") or
(process.name == "grep" and process.args == "-qiE" and process.args like "libsdmp*libserviceDiscovery*so") or
(process.parent.executable == "/usr/lib/systemd/systemd" and process.parent.command_line == "/sbin/init") or
process.parent.command_line like "*/.claude/shell-snapshots*" or
(process.parent.executable like "/tmp/*/rasoat_new.sh" and process.parent.command_line like "/bin/bash ./rasoat_new.sh*") or
(process.parent.command_line in ("/bin/bash --norc --noprofile -m -i", "rasoat_new.sh") and process.args == "-H" and process.args == "memfd") or
process.command_line == "grep -Eow /.*ld-.*.so /proc/self/maps" or
process.group_leader.executable in ("/usr/local/qualys/cloud-agent/bin/qualys-cloud-agent", "/opt/traps/bin/cytool") or
(
process.parent.executable == "/bin/sh" and
process.parent.command_line == "/bin/sh -s unix:cmd" and
process.working_directory == "/ebsmnt/erlang/usercode"
)
)
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.args | wildcard |
| field:"process.args" kind:wildcard |
process.name | in |
| field:"process_basename" kind:in |
Exclusions
The rule actively suppresses these predicates.
UAC Bypass via Control Panel Execution Hijack
#Identifies attempts to bypass User Account Control (UAC) via hijacking the default handler of the Backup and Restore control panel. Attackers bypass UAC to stealthily execute code with elevated permissions.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Privilege Escalation |
Rule Body
[rule]
description = """
Identifies attempts to bypass User Account Control (UAC) via hijacking the default handler of the Backup and Restore
control panel. Attackers bypass UAC to stealthily execute code with elevated permissions.
"""
id = "0545f127-b1ae-478a-a68a-84f477f765e2"
license = "Elastic License v2"
name = "UAC Bypass via Control Panel Execution Hijack"
os_list = ["windows"]
reference = ["https://github.com/hfiref0x/UACME"]
version = "1.0.33"
query = '''
sequence with maxspan=1m
[registry where
registry.hive == "HKEY_USERS" and
registry.key : "S-1-5-21*_Classes\\Folder\\Shell\\Open\\Command*"]
[process where event.action == "start" and process.pe.original_file_name : "sdclt.exe"]
[process where event.action == "start" and
process.Ext.token.integrity_level_name == "high" and
process.parent.name : "control.exe" and process.parent.command_line : "*Microsoft.BackupAndRestoreCenter*"]
'''
min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 2
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 2
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1548"
name = "Abuse Elevation Control Mechanism"
reference = "https://attack.mitre.org/techniques/T1548/"
[[threat.technique.subtechnique]]
id = "T1548.002"
name = "Bypass User Account Control"
reference = "https://attack.mitre.org/techniques/T1548/002/"
[threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: registry
[registry where
registry.hive == "HKEY_USERS" and
registry.key : "S-1-5-21*_Classes\\Folder\\Shell\\Open\\Command*"]
Stage 2: process
[process where event.action == "start" and process.pe.original_file_name : "sdclt.exe"]
Stage 3: process
[process where event.action == "start" and
process.Ext.token.integrity_level_name == "high" and
process.parent.name : "control.exe" and process.parent.command_line : "*Microsoft.BackupAndRestoreCenter*"]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.Ext.token.integrity_level_name | eq |
| field:"process.Ext.token.integrity_level_name" kind:eq value:"high" |
process.parent.command_line | wildcard |
| field:"ParentCommandLine" kind:wildcard value:"*Microsoft.BackupAndRestoreCenter*" |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard value:"control.exe" |
process.pe.original_file_name | wildcard |
| field:"OriginalFileName" kind:wildcard value:"sdclt.exe" |
registry.hive | eq |
| field:"registry.hive" kind:eq value:"HKEY_USERS" |
registry.key | wildcard |
| field:"TargetObject" kind:wildcard value:"S-1-5-21*_Classes\Folder\Shell\Open\Command*" |
Unusual Startup Shell Folder Modification
#Identifies suspicious startup shell folder modifications. An adversary may attempt to change the default startup directory in order to bypass detections that monitor for suspicious file creation events in the default Windows Startup folder.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence |
Rule Body
[rule]
description = """
Identifies suspicious startup shell folder modifications. An adversary may attempt to change the default startup
directory in order to bypass detections that monitor for suspicious file creation events in the default Windows Startup
folder.
"""
id = "377aad38-24e0-4dd7-93c2-bd231cb749e3"
license = "Elastic License v2"
name = "Unusual Startup Shell Folder Modification"
os_list = ["windows"]
version = "1.0.36"
query = '''
registry where
user.id like ("S-1-5-21*", "S-1-12-*") and process.executable != null and
registry.path : (
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Common Startup",
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Common Startup",
"HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Startup",
"HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Startup"
) and
registry.data.strings != null and
// Normal Startup Folder Paths
not registry.data.strings : (
"?:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
"%ProgramData%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
"%USERPROFILE%\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
"?:\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
"\\\\*"
) and
not process.executable :
("?:\\Windows\\explorer.exe",
"?:\\Windows\\System32\\regsvr32.exe",
"?:\\Windows\\System32\\runonce.exe",
"?:\\Windows\\System32\\svchost.exe")
'''
min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1547"
name = "Boot or Logon Autostart Execution"
reference = "https://attack.mitre.org/techniques/T1547/"
[[threat.technique.subtechnique]]
id = "T1547.001"
name = "Registry Run Keys / Startup Folder"
reference = "https://attack.mitre.org/techniques/T1547/001/"
[threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[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
user.id like ("S-1-5-21*", "S-1-12-*") and process.executable != null and
registry.path : (
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Common Startup",
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Common Startup",
"HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\Startup",
"HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Startup"
) and
registry.data.strings != null and
not registry.data.strings : (
"?:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
"%ProgramData%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
"%USERPROFILE%\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
"?:\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
"\\\\*"
) and
not process.executable :
("?:\\Windows\\explorer.exe",
"?:\\Windows\\System32\\regsvr32.exe",
"?:\\Windows\\System32\\runonce.exe",
"?:\\Windows\\System32\\svchost.exe")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
process.executable | is_not_null | field:"Image" kind:is_not_null | |
registry.data.strings | is_not_null | field:"Details" kind:is_not_null | |
registry.path | wildcard |
| field:"TargetObject" kind:wildcard |
user.id | wildcard |
| field:"user.id" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.executable | eq | ?:\Windows\explorer.exe, ?:\Windows\System32\regsvr32.exe, ?:\Windows\System32\runonce.exe, ?:\Windows\System32\svchost.exe | excludes:process.executable |
registry.data.strings | wildcard | ?:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup, %ProgramData%\Microsoft\Windows\Start Menu\Programs\Startup, %USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup, ?:\Users\*\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup, \\* | excludes:registry.data.strings |
Unusual Sudo Activity
#Looks for sudo activity from an unusual user context. An unusual sudo user could be due to troubleshooting activity or it could be a sign of credentialed access via compromised accounts.
Known False Positives
- Uncommon sudo 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 |
|---|---|
| Privilege Escalation |
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 = 75
author = ["Elastic"]
description = """
Looks for sudo activity from an unusual user context. An unusual sudo user could be due to troubleshooting activity or
it could be a sign of credentialed access via compromised accounts.
"""
false_positives = [
"""
Uncommon sudo 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_rare_sudo_user_ea"]
name = "Unusual Sudo Activity"
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 = "1e9fc667-9ff1-4b33-9f40-fefca8537eb0"
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: Privilege Escalation",
"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 Sudo Activity
Sudo is a command in Unix-like systems that allows permitted users to execute commands as a superuser, providing necessary privileges for administrative tasks. Adversaries may exploit this by using compromised credentials to gain elevated access, potentially bypassing security controls. The 'Unusual Sudo Activity' detection rule leverages machine learning to identify deviations from normal sudo usage patterns, flagging potential privilege escalation attempts for further investigation.
### Possible investigation steps
- Review the user account associated with the unusual sudo activity to determine if it aligns with known administrative roles or if it is typically associated with non-privileged tasks.
- Check the timestamp of the sudo activity to see if it coincides with any known maintenance windows or reported troubleshooting activities.
- Analyze the command executed with sudo to assess whether it is a common administrative command or if it appears suspicious or unnecessary for the user's role.
- Investigate the source IP address or hostname from which the sudo command was executed to verify if it is a recognized and authorized device.
- Look into recent login activity for the user account to identify any unusual access patterns or locations that could indicate compromised credentials.
- Cross-reference the alert with any other security events or logs around the same time to identify potential indicators of compromise or related malicious activity.
### False positive analysis
- Administrative troubleshooting activities can trigger false positives. Regularly review and document legitimate administrative tasks that require sudo access to differentiate them from potential threats.
- Developers or IT staff performing routine maintenance may cause alerts. Create exceptions for known maintenance windows or specific user accounts that frequently require elevated privileges.
- Automated scripts or scheduled tasks using sudo might be flagged. Identify and whitelist these scripts or tasks if they are verified as safe and necessary for operations.
- New employees or role changes can lead to unusual sudo activity. Update user roles and permissions promptly to reflect their current responsibilities and reduce unnecessary alerts.
- Temporary access granted for specific projects can appear suspicious. Ensure that temporary access is well-documented and set to expire automatically to prevent lingering false positives.
### Response and remediation
- Immediately isolate the affected system from the network to prevent further unauthorized access or lateral movement by the adversary.
- Revoke or reset the compromised credentials to prevent further misuse and ensure that the affected user account is secured.
- Conduct a thorough review of recent sudo logs and system activity to identify any unauthorized changes or actions taken by the adversary.
- Restore any altered or deleted files from backups, ensuring that the system is returned to its last known good state.
- Apply any necessary security patches or updates to the affected system to close vulnerabilities that may have been exploited.
- Enhance monitoring and logging for sudo activities across all systems to detect similar anomalies in the future.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if additional systems are affected."""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1548"
name = "Abuse Elevation Control Mechanism"
reference = "https://attack.mitre.org/techniques/T1548/"
[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 = "T1548"
name = "Abuse Elevation Control Mechanism"
reference = "https://attack.mitre.org/techniques/T1548/"
[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
Windows Subsystem for Linux Distribution Installed
#Detects changes to the registry that indicates the install of a new Windows Subsystem for Linux distribution by name. Adversaries may enable and use WSL for Linux to avoid detection.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Persistence | |
| Stealth | |
| Defense Impairment |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2023/01/12"
integration = ["endpoint", "windows", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/05/04"
[rule]
author = ["Elastic"]
description = """
Detects changes to the registry that indicates the install of a new Windows Subsystem for Linux distribution by name.
Adversaries may enable and use WSL for Linux to avoid detection.
"""
from = "now-9m"
index = [
"winlogbeat-*",
"logs-endpoint.events.registry-*",
"logs-windows.sysmon_operational-*",
"endgame-*",
"logs-m365_defender.event-*",
"logs-sentinel_one_cloud_funnel.*",
"logs-crowdstrike.fdr*",
]
language = "eql"
license = "Elastic License v2"
name = "Windows Subsystem for Linux Distribution Installed"
note = """## Triage and analysis
### Investigating Windows Subsystem for Linux Distribution Installed
The Windows Subsystem for Linux (WSL) lets developers install a Linux distribution (such as Ubuntu, OpenSUSE, Kali, Debian, Arch Linux, etc) and use Linux applications, utilities, and Bash command-line tools directly on Windows, unmodified, without the overhead of a traditional virtual machine or dualboot setup. Attackers may abuse WSL to avoid security protections on a Windows host and perform a wide range of attacks.
This rule identifies the installation of a new Windows Subsystem for Linux distribution via registry events.
### Possible investigation steps
- Identify the user account that performed the action and whether it should perform this kind of action.
- Examine which distribution was installed. Some distributions such as Kali Linux can facilitate the compromise of the environment.
- Contact the account owner and confirm whether they are aware of this activity.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Validate that the activity is not related to planned patches, updates, network administrator activity, or legitimate software installations.
- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.
### False positive analysis
- This is a dual-use tool, meaning its usage is not inherently malicious. Analysts can dismiss the alert if the administrator is aware of the activity, no other suspicious activity was identified, and the WSL distribution is homologated and approved in the environment.
### Related Rules
- Host Files System Changes via Windows Subsystem for Linux - e88d1fe9-b2f4-48d4-bace-a026dc745d4b
- Execution via Windows Subsystem for Linux - db7dbad5-08d2-4d25-b9b1-d3a1e4a15efd
- Suspicious Execution via Windows Subsystem for Linux - 3e0eeb75-16e8-4f2f-9826-62461ca128b7
- Windows Subsystem for Linux Enabled via Dism Utility - e2e0537d-7d8f-4910-a11d-559bcf61295a
### 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.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- 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.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
setup = """## Setup
This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
Setup instructions: https://ela.st/install-elastic-defend
### Additional data sources
This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
- [CrowdStrike](https://ela.st/crowdstrike-integration)
- [Microsoft Defender XDR](https://ela.st/m365-defender)
- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
- [Sysmon Registry Events](https://ela.st/sysmon-event-reg-setup)
"""
references = ["https://learn.microsoft.com/en-us/windows/wsl/wsl-config"]
risk_score = 47
rule_id = "a1699af0-8e1e-4ed0-8ec1-89783538a061"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Defense Evasion",
"Data Source: Elastic Endgame",
"Data Source: Elastic Defend",
"Data Source: Sysmon",
"Data Source: Microsoft Defender XDR",
"Data Source: SentinelOne",
"Data Source: Crowdstrike",
"Resources: Investigation Guide",
]
timeline_id = "3e47ef71-ebfc-4520-975c-cb27fc090799"
timeline_title = "Comprehensive Registry Timeline"
timestamp_override = "event.ingested"
type = "eql"
query = '''
registry where host.os.type == "windows" and event.type == "change" and registry.value : "PackageFamilyName" and
registry.path : "*\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Lxss\\*\\PackageFamilyName"
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1112"
name = "Modify Registry"
reference = "https://attack.mitre.org/techniques/T1112/"
[[rule.threat.technique]]
id = "T1202"
name = "Indirect Command Execution"
reference = "https://attack.mitre.org/techniques/T1202/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
Stages and Predicates
Stage 1: registry
registry where host.os.type == "windows" and event.type == "change" and registry.value : "PackageFamilyName" and
registry.path : "*\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Lxss\\*\\PackageFamilyName"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"change" |
registry.path | wildcard |
| field:"TargetObject" kind:wildcard value:"*\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss\*\PackageFamilyName" |
registry.value | wildcard |
| field:"registry_value_name" kind:wildcard value:"PackageFamilyName" |