Detection rules › Elastic

Elastic rules: 05

Application Javascript Injection via Nodejs

#
Source
github.com/elastic/protections-artifacts

Detects when a JavaScript file within an application's directory structure gets modified via Node.js. Malicious npm packages have been observed hijacking legitimate applications like Cursor editor by injecting malicious JavaScript code into application files to enable persistent code execution.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[rule]
description = """
Detects when a JavaScript file within an application's directory structure gets modified via Node.js. Malicious npm
packages have been observed hijacking legitimate applications like Cursor editor by injecting malicious JavaScript code
into application files to enable persistent code execution.
"""
id = "9c20c94b-aad6-4052-b5b4-70d968e70971"
license = "Elastic License v2"
name = "Application Javascript Injection via Nodejs"
os_list = ["macos"]
reference = ["https://socket.dev/blog/malicious-npm-packages-hijack-cursor-editor-on-macos"]
version = "1.0.2"

query = '''
file where event.action == "modification" and file.extension == "js" and
 file.path like "/Applications/*" and (process.name == "node" or Effective_process.name == "node") and 
 Effective_process.executable != "/Applications/Visual Studio Code 2.app/Contents/MacOS/Electron"
'''

min_endpoint_version = "8.11.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "Effective_process.entity_id"
state = 0

[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1195"
name = "Supply Chain Compromise"
reference = "https://attack.mitre.org/techniques/T1195/"
[[threat.technique.subtechnique]]
id = "T1195.001"
name = "Compromise Software Dependencies and Development Tools"
reference = "https://attack.mitre.org/techniques/T1195/001/"



[threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1554"
name = "Compromise Host Software Binary"
reference = "https://attack.mitre.org/techniques/T1554/"


[threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"


[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

[internal]
min_endpoint_version = "8.11.0"

Stages and Predicates

Stage 1: file

file where event.action == "modification" and file.extension == "js" and
 file.path like "/Applications/*" and (process.name == "node" or Effective_process.name == "node") and 
 Effective_process.executable != "/Applications/Visual Studio Code 2.app/Contents/MacOS/Electron"

Indicators

These rows show field, operator, and value matches.

AWS CloudWatch Log Stream Deletion

#
Status
production
Severity
medium
Time window
6m
Author
Elastic
Source
github.com/elastic/detection-rules

Detects the deletion of an Amazon CloudWatch log stream using the "DeleteLogStream" API. Deleting a log stream permanently removes its associated log events and may disrupt security visibility, break audit trails, or suppress forensic evidence. Adversaries may delete log streams to conceal malicious actions, impair monitoring pipelines, or remove artifacts generated during post-exploitation activity.

Known False Positives

  • CloudWatch log streams may be deleted legitimately during log rotation processes, test environment resets, or infrastructure deployments that recreate log groups and streams. Validate the identity, automation pipeline, and IP address associated with the deletion. If deletions are expected from specific CI/CD systems or administrative roles, consider adding targeted exceptions.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2020/05/20"
integration = ["aws"]
maturity = "production"
updated_date = "2026/08/05"

[rule]
author = ["Elastic"]
description = """
Detects the deletion of an Amazon CloudWatch log stream using the "DeleteLogStream" API. Deleting a log stream
permanently removes its associated log events and may disrupt security visibility, break audit trails, or suppress
forensic evidence. Adversaries may delete log streams to conceal malicious actions, impair monitoring pipelines, or
remove artifacts generated during post-exploitation activity.
"""
false_positives = [
    """
    CloudWatch log streams may be deleted legitimately during log rotation processes, test environment resets, or
    infrastructure deployments that recreate log groups and streams. Validate the identity, automation pipeline, and IP
    address associated with the deletion. If deletions are expected from specific CI/CD systems or administrative roles,
    consider adding targeted exceptions.
    """,
]
from = "now-6m"
index = ["filebeat-*", "logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS CloudWatch Log Stream Deletion"
note = """## Triage and analysis

### Investigating AWS CloudWatch Log Stream Deletion

CloudWatch log streams contain sequential log events from a single application, service, or AWS resource.  
Deleting a log stream permanently removes its archived log events, which may disable monitoring workflows, eliminate 
critical telemetry, or disrupt forensic visibility.

Adversaries may delete log streams to cover their tracks after unauthorized actions, break ingestion pipelines feeding SIEM, alerting, or anomaly detection or to remove evidence before escalating privileges or moving laterally. This rule detects successful invocations of the `DeleteLogStream` API from CloudTrail.

#### Possible investigation steps

- **Identify the actor**
  - Review `aws.cloudtrail.user_identity.arn` and `aws.cloudtrail.user_identity.access_key_id`.  
  - Confirm whether the user or role normally manages CloudWatch Logs resources.

- **Review request details**
  - Inspect `aws.cloudtrail.request_parameters` to determine which log stream and parent log group were deleted.  
  - Assess the importance of the deleted stream:
    - Was it used for VPC Flow Logs, CloudTrail, Lambda functions, ECS tasks, or application logs?  
    - Did it contain logs used for security detection or compliance auditing?

- **Examine request origin and context**
  - Review `source.ip` and `user_agent.original` for anomalies (e.g., unfamiliar CLI tools, suspicious automation, 
    unknown IP ranges, or external geolocations).
  - Validate whether the request originated from a legitimate automation host or jump box.  
  - Check activity around the same timestamp for related operations such as:
    - `DeleteLogGroup`
    - `StopLogging`, `UpdateTrail`, or `DeleteTrail`
    - GuardDuty detector or CloudWatch alarm deletions
    - IAM policy or role modifications

- **Determine operational justification**
  - Consult change management systems or deployment pipelines to confirm whether the deletion was planned.  
  - Contact application owners or platform teams to determine whether the log stream was part of normal rotation or cleanup.

- **Investigate broader compromise indicators**
  - Look for suspicious activity by the same identity in the past 24–48 hours, such as:
    - Failed authentication attempts  
    - IAM privilege escalations  
    - Unusual STS AssumeRole usage  
    - Access from new geolocations  

### False positive analysis

- **Log rotation and automation**
  - Some systems delete log streams automatically when rolling new deployments or recycling compute resources.
  - CI/CD pipelines managing immutable infrastructure may delete and recreate streams during each deploy.

- **Test and development accounts**
  - Dev/test environments may frequently create and delete log streams as part of iterative work.

- **Bulk cleanup operations**
  - Platform engineering teams may delete obsolete log streams during cost-optimization or log-retention management.

If the rule triggers frequently from known infrastructure accounts or automation hosts, consider adding narrow exceptions using a combination of IAM role, IP range, or user agent.

### Response and remediation

- **Containment**
  - If the deletion is unauthorized, review other CloudWatch resources for additional tampering (alarms, log groups, metric filters).
  - Temporarily restrict permissions for the implicated IAM user or role.

- **Investigation**
  - Reconstruct any missing telemetry from alternative sources (e.g., S3 buckets, application logs, third-party logging systems).
  - Review CloudTrail and Config timelines for preceding suspicious events.
  - Validate whether the deleted log stream contained evidence of prior compromise.

- **Recovery and hardening**
  - Implement IAM least-privilege for `logs:DeleteLogStream`.
  - Enable AWS Config rules to monitor CloudWatch Logs configuration changes.  
  - Ensure that business-critical log groups enforce minimum retention periods and prevent accidental deletion.
  - Integrate log stream lifecycle management into CI/CD to avoid manual deletions.
  - Establish guardrails using Service Control Policies (SCPs) to block log deletions outside designated automation roles.

### 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://awscli.amazonaws.com/v2/documentation/api/latest/reference/logs/delete-log-stream.html",
    "https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DeleteLogStream.html",
]
risk_score = 47
rule_id = "d624f0ae-3dd1-4856-9aad-ccfe4d4bfa17"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Platform: AWS",
    "Data Source: AWS CloudTrail",
    "Service: AWS CloudWatch",
    "Tactic: Defense Evasion",
    "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: "logs.amazonaws.com" 
  and event.action: "DeleteLogStream" 
  and event.outcome: "success"
  and source.ip: * 
  and not user_agent.original: ("AWS Internal" or *Terraform* or *Pulumi*)
'''


[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1485"
name = "Data Destruction"
reference = "https://attack.mitre.org/techniques/T1485/"

[rule.threat.tactic]
id = "TA0040"
name = "Impact"
reference = "https://attack.mitre.org/tactics/TA0040/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"

[[rule.threat.technique.subtechnique]]
id = "T1562.001"
name = "Disable or Modify Tools"
reference = "https://attack.mitre.org/techniques/T1562/001/"

[[rule.threat.technique.subtechnique]]
id = "T1562.008"
name = "Disable or Modify Cloud Logs"
reference = "https://attack.mitre.org/techniques/T1562/008/"

[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[rule.investigation_fields]
field_names = [
    "@timestamp",
    "user.name",
    "user_agent.original",
    "source.ip",
    "aws.cloudtrail.user_identity.arn",
    "aws.cloudtrail.user_identity.type",
    "aws.cloudtrail.user_identity.access_key_id",
    "event.action",
    "event.outcome",
    "cloud.account.id",
    "cloud.region",
    "aws.cloudtrail.request_parameters",
]

Stages and Predicates

Stage 1: query

data_stream.dataset: "aws.cloudtrail" 
  and event.provider: "logs.amazonaws.com" 
  and event.action: "DeleteLogStream" 
  and event.outcome: "success"
  and source.ip: * 
  and not user_agent.original: ("AWS Internal" or *Terraform* or *Pulumi*)

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

AWS SSM Inventory Reconnaissance by Rare User

#
Status
production
Severity
medium
Time window
6m
Group by
cloud.account.id, user.name
Author
Elastic
Source
github.com/elastic/detection-rules

Detects the rare occurrence of a user or role accessing AWS Systems Manager (SSM) inventory APIs or running the AWS-GatherSoftwareInventory job. These APIs reveal detailed information about managed EC2 instances including installed software, patch compliance status, and command execution history. Adversaries may use these calls to collect software inventory while blending in with legitimate AWS operations. This is a New Terms rule that detects when a user accesses these reconnaissance APIs for the first time.

Known False Positives

  • Legitimate administrators or automation tools may access SSM inventory APIs for asset management or compliance purposes. Verify whether the user identity should be using these APIs. If known behavior is causing false positives, add exceptions.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2026/02/11"
integration = ["aws"]
maturity = "production"
updated_date = "2026/08/05"

[rule]
author = ["Elastic"]
description = """
Detects the rare occurrence of a user or role accessing AWS Systems Manager (SSM) inventory APIs or running the 
AWS-GatherSoftwareInventory job. These APIs reveal detailed information about managed EC2 instances 
including installed software, patch compliance status, and command execution history. Adversaries may use these calls to collect software inventory while blending in with legitimate AWS 
operations. This is a New Terms rule that detects when a user accesses these reconnaissance APIs for the first time.
"""
false_positives = [
    """
    Legitimate administrators or automation tools may access SSM inventory APIs for asset management or compliance purposes.
    Verify whether the user identity should be using these APIs. If known behavior is causing false positives, add exceptions.
    """,
]
from = "now-6m"
index = ["filebeat-*", "logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS SSM Inventory Reconnaissance by Rare User"
note = """## Triage and analysis

### Investigating AWS SSM Inventory Reconnaissance by Rare User

AWS Systems Manager (SSM) Inventory provides detailed information about managed EC2 instances, including installed 
applications, network configurations, OS details, and patch compliance status. Threat actors, including Scattered 
Spider (LUCR-3), leverage these APIs to discover targets for lateral movement.

This rule detects the first time a specific user (identified by `cloud.account.id` and `user.name`) accesses SSM 
inventory reconnaissance APIs or runs inventory collection commands. These APIs are typically used by automation 
systems, not interactively by humans.

### Possible investigation steps

- **Verify User Identity**: Check `aws.cloudtrail.user_identity.arn` or `user.name` to determine who performed the action.
    - Is this a service account, automation role, or human user?
    - Does this user typically interact with SSM or EC2 infrastructure?
- **Review Source Context**: Examine `source.ip` and `source.geo` to determine where the request originated.
    - Does the source IP match expected locations for this user?
    - Is the source IP from an EC2 instance (potentially compromised) or an external location?
- **Analyze User Agent**: Check `user_agent.original` for suspicious values.
    - AWS CLI, SDK, or CloudShell usage from unexpected users is suspicious.
    - Custom or unusual user agents may indicate attacker tooling.
- **Correlate with Other Events**: Look for other reconnaissance or lateral movement activity from the same user.
    - Check for `StartSession`, `SendCommand`, or other SSM execution APIs.
    - Look for `GetCallerIdentity` calls which often precede reconnaissance.
- **Review Timeline**: Investigate activity 30 minutes before and after this event.
    - Was there an initial access event (e.g., console login, `AssumeRole`)?
    - Did the user proceed to access secrets or attempt lateral movement?

### False positive analysis

- Automation and Monitoring: Legitimate monitoring tools, asset management systems, or compliance scanners may query SSM inventory regularly. These should use dedicated service accounts.
- Administrator Activity: Cloud administrators may occasionally query inventory for troubleshooting. Verify with the user whether this was intentional.
- CI/CD Pipelines: Deployment pipelines may check patch compliance before deployments.
- SSM Associations: The `AWS-GatherSoftwareInventory` document is normally deployed via IaC tools (Terraform, CloudFormation) or the AWS Console during initial setup. Interactive `CreateAssociation` calls outside of these contexts warrant investigation.

### Response and remediation

- Immediate Verification: Contact the user to verify whether they performed this action intentionally.
- Review Permissions: If unauthorized, review and restrict the user's IAM permissions following least privilege.
- Investigate Credential Compromise: If the user did not perform this action, treat their credentials as compromised.
    - Rotate access keys and session tokens.
    - Review recent activity for data exfiltration or privilege escalation.
- Enhanced Monitoring: Add the user or role to enhanced monitoring if suspicious activity is confirmed.

### 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)** 
- **[AWS Knowledge Center – Security Best Practices](https://aws.amazon.com/premiumsupport/knowledge-center/security-best-practices/)**
"""
references = [
    "https://permiso.io/blog/lucr-3-scattered-spider-getting-saas-y-in-the-cloud",
    "https://www.cisa.gov/sites/default/files/2023-11/aa23-320a_scattered_spider_0.pdf",
    "https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-inventory.html",
]
risk_score = 47
rule_id = "1004ad5b-6900-4d28-ab5b-472f02e1fdfb"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Platform: AWS",
    "Data Source: AWS CloudTrail",
    "Service: AWS SSM",
    "Tactic: Discovery",
    "Rule Type: New Terms",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"

query = '''
data_stream.dataset: "aws.cloudtrail"
    and event.provider: "ssm.amazonaws.com"
    and (
        event.action: ("GetInventory" or "GetInventorySchema" or "ListInventoryEntries" or "DescribeInstancePatches" or "ListCommands")
        or (event.action: "CreateAssociation"
            and aws.cloudtrail.request_parameters: *AWS-GatherSoftwareInventory*)
    )
    and not aws.cloudtrail.user_identity.type : "AWSService" 
    and event.outcome: "success"
'''

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "user.name",
    "user_agent.original",
    "source.ip",
    "aws.cloudtrail.user_identity.arn",
    "aws.cloudtrail.user_identity.type",
    "aws.cloudtrail.user_identity.access_key_id",
    "event.action",
    "event.outcome",
    "cloud.account.id",
    "cloud.region",
    "aws.cloudtrail.request_parameters"
]

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1518"
name = "Software Discovery"
reference = "https://attack.mitre.org/techniques/T1518/"

[[rule.threat.technique]]
id = "T1538"
name = "Cloud Service Dashboard"
reference = "https://attack.mitre.org/techniques/T1538/"

[[rule.threat.technique]]
id = "T1580"
name = "Cloud Infrastructure Discovery"
reference = "https://attack.mitre.org/techniques/T1580/"

[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
[rule.new_terms]
field = "new_terms_fields"
value = ["cloud.account.id", "user.name"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-10d"

Stages and Predicates

Stage 1: new_terms

data_stream.dataset: "aws.cloudtrail"
    and event.provider: "ssm.amazonaws.com"
    and (
        event.action: ("GetInventory" or "GetInventorySchema" or "ListInventoryEntries" or "DescribeInstancePatches" or "ListCommands")
        or (event.action: "CreateAssociation"
            and aws.cloudtrail.request_parameters: *AWS-GatherSoftwareInventory*)
    )
    and not aws.cloudtrail.user_identity.type : "AWSService" 
    and event.outcome: "success"

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
aws.cloudtrail.user_identity.typeeqAWSServiceexcludes:aws.cloudtrail.user_identity.type field:"aws.cloudtrail.user_identity.type" value:"AWSService"

Azure Virtual Machine Configuration Modified

#
Status
production
Kind
building block (feeds higher-level correlation rules; not a standalone alert)
Severity
low
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies a successful write to an Azure virtual machine resource ("MICROSOFT.COMPUTE/VIRTUALMACHINES/WRITE"). This operation is the parent action behind VM userData injection, where an adversary with VM contributor rights writes a base64 startup payload into the VM "userData" field that executes on the next reboot (a control-plane persistence technique requiring no guest access). The Azure activity log does not record the "userData" value or which property changed, so this behavior is indistinguishable from any other VM write at detection time. This is a building block rule and does not generate alerts on its own; it captures the VM write population so it can be correlated with other signals and baselined over time to tune a higher-fidelity userData-injection detection. To investigate a candidate, retrieve the live "userData" from the VM with an Azure Resource Manager GET using "$expand=userData".

Known False Positives

  • The vast majority of VM writes are benign: provisioning, resizing, tagging, extension/identity changes, autoscale, and configuration management by users, service principals, and managed identities. This rule is informational only and is intended for correlation and baselining, not standalone alerting.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
bypass_bbr_timing = true
creation_date = "2026/06/15"
integration = ["azure"]
maturity = "production"
updated_date = "2026/06/15"

[rule]
author = ["Elastic"]
building_block_type = "default"
description = """
Identifies a successful write to an Azure virtual machine resource
("MICROSOFT.COMPUTE/VIRTUALMACHINES/WRITE"). This operation is the parent action behind VM userData injection, where an
adversary with VM contributor rights writes a base64 startup payload into the VM "userData" field that executes on the
next reboot (a control-plane persistence technique requiring no guest access). The Azure activity log does not record the
"userData" value or which property changed, so this behavior is indistinguishable from any other VM write at detection
time. This is a building block rule and does not generate alerts on its own; it captures the VM write population so it
can be correlated with other signals and baselined over time to tune a higher-fidelity userData-injection detection.
To investigate a candidate, retrieve the live "userData" from the VM with an Azure Resource Manager GET using "$expand=userData".
"""
false_positives = [
    """
    The vast majority of VM writes are benign: provisioning, resizing, tagging, extension/identity changes, autoscale,
    and configuration management by users, service principals, and managed identities. This rule is informational only
    and is intended for correlation and baselining, not standalone alerting.
    """,
]
from = "now-9m"
index = ["logs-azure.activitylogs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Azure Virtual Machine Configuration Modified"
references = [
    "https://blog.pwnedlabs.io/diving-deep-into-azure-vm-attack-vectors",
    "https://learn.microsoft.com/en-us/azure/virtual-machines/user-data",
]
risk_score = 21
rule_id = "56fa718c-a0de-4492-97ff-bbc444b015b8"
severity = "low"
tags = [
    "Domain: Cloud",
    "Domain: Endpoint",
    "Data Source: Azure",
    "Data Source: Azure Activity Logs",
    "Use Case: Asset Visibility",
    "Tactic: Persistence",
    "Rule Type: BBR",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset:azure.activitylogs and
    event.action:"MICROSOFT.COMPUTE/VIRTUALMACHINES/WRITE" and
    event.outcome:(success or Success)
'''

[[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.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1651"
name = "Cloud Administration Command"
reference = "https://attack.mitre.org/techniques/T1651/"

[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"

Stages and Predicates

Stage 1: query

data_stream.dataset:azure.activitylogs and
    event.action:"MICROSOFT.COMPUTE/VIRTUALMACHINES/WRITE" and
    event.outcome:(success or Success)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
data_stream.dataseteq
  • azure.activitylogs corpus 38 (elastic 38)
field:"data_stream.dataset" kind:eq value:"azure.activitylogs"
event.actioneq
  • MICROSOFT.COMPUTE/VIRTUALMACHINES/WRITE
field:"EventType" kind:eq value:"MICROSOFT.COMPUTE/VIRTUALMACHINES/WRITE"
event.outcomein
  • Success corpus 306 (elastic 306)
  • success corpus 306 (elastic 306)
field:"event.outcome" kind:in

Code Signing Policy Modification Through Registry

#
Status
production
Severity
medium
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies attempts to disable the code signing policy through the registry. Code signing provides authenticity on a program, and grants the user with the ability to check whether the program has been tampered with. By allowing the execution of unsigned or self-signed code, threat actors can craft and execute malicious code.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2023/01/31"
integration = ["endpoint", "windows", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/05/04"

[transform]
[[transform.osquery]]
label = "Osquery - Retrieve All Non-Microsoft Drivers with Virustotal Link"
query = """
SELECT concat('https://www.virustotal.com/gui/file/', sha1) AS VtLink, class, description, directory, image,
issuer_name, manufacturer, service, signed, subject_name FROM drivers JOIN authenticode ON drivers.image =
authenticode.path JOIN hash ON drivers.image = hash.path WHERE NOT (provider == "Microsoft" AND signed == "1")
"""

[[transform.osquery]]
label = "Osquery - Retrieve All Unsigned Drivers with Virustotal Link"
query = """
SELECT concat('https://www.virustotal.com/gui/file/', sha1) AS VtLink, class, description, directory, image,
issuer_name, manufacturer, service, signed, subject_name FROM drivers JOIN authenticode ON drivers.image =
authenticode.path JOIN hash ON drivers.image = hash.path WHERE signed == "0"
"""


[rule]
author = ["Elastic"]
description = """
Identifies attempts to disable the code signing policy through the registry. Code signing provides authenticity on a
program, and grants the user with the ability to check whether the program has been tampered with. By allowing the
execution of unsigned or self-signed code, threat actors can craft and execute malicious code.
"""
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 = "Code Signing Policy Modification Through Registry"
note = """## Triage and analysis

### Investigating Code Signing Policy Modification Through Registry

Microsoft created the Windows Driver Signature Enforcement (DSE) security feature to prevent drivers with invalid signatures from loading and executing into the kernel (ring 0). DSE aims to protect systems by blocking attackers from loading malicious drivers on targets. 

This protection is essential for maintaining system security. However, attackers or administrators can disable DSE and load untrusted drivers, which can put the system at risk. Therefore, it's important to keep this feature enabled and only load drivers from trusted sources to ensure system integrity and security.

This rule identifies registry modifications that can disable DSE.

> **Note**:
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/current/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.

#### Possible investigation steps

- Identify the user account that performed the action and whether it should perform this kind of action.
- 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.
- Use Osquery and endpoint driver events (`event.category = "driver"`) to investigate if suspicious drivers were loaded into the system after the registry was modified.
  - $osquery_0
  - $osquery_1
- Identify the driver's `Device Name` and `Service Name`.
- Check for alerts from the rules specified in the `Related Rules` section.

### False positive analysis

- This activity should not happen legitimately. The security team should address any potential benign true positive (B-TP), as this configuration can put the user and the domain at risk.

### Related Rules

- First Time Seen Driver Loaded - df0fd41e-5590-4965-ad5e-cd079ec22fa9
- Untrusted Driver Loaded - d8ab1ec1-feeb-48b9-89e7-c12e189448aa
- Code Signing Policy Modification Through Built-in tools - b43570de-a908-4f7f-8bdb-b2df6ffd8c80

### 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.
- Disable and uninstall all suspicious drivers found in the system. This can be done via Device Manager. (Note that this step may require you to boot the system into Safe Mode.)
- Remove the related services and registry keys found in the system. Note that the service will probably not stop if the driver is still installed.
  - This can be done via PowerShell `Remove-Service` cmdlet.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Remove and block malicious artifacts identified during triage.
- Ensure that the Driver Signature Enforcement is enabled on the system.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- 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)
"""

risk_score = 47
rule_id = "da7733b1-fe08-487e-b536-0a04c6d8b0cd"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Defense Evasion",
    "Data Source: Elastic Endgame",
    "Resources: Investigation Guide",
    "Data Source: Elastic Defend",
    "Data Source: 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: "BehaviorOnFailedVerify" and registry.data.strings : ("0", "0x00000000", "1", "0x00000001") and 
  not process.executable : 
                      ("?:\\Windows\\System32\\svchost.exe", 
                       "?:\\Windows\\CCM\\CcmExec.exe",
                       "\\Device\\HarddiskVolume*\\Windows\\system32\\svchost.exe", 
                       "\\Device\\HarddiskVolume*\\Windows\\CCM\\CcmExec.exe")
  /*
    Full registry key path omitted due to data source variations:
    "HKEY_USERS\\*\\Software\\Policies\\Microsoft\\Windows NT\\Driver Signing\\BehaviorOnFailedVerify"
  */
'''


[[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 = "T1553"
name = "Subvert Trust Controls"
reference = "https://attack.mitre.org/techniques/T1553/"
[[rule.threat.technique.subtechnique]]
id = "T1553.006"
name = "Code Signing Policy Modification"
reference = "https://attack.mitre.org/techniques/T1553/006/"



[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

Stages and Predicates

Stage 1: registry

registry where host.os.type == "windows" and event.type == "change" and
  registry.value: "BehaviorOnFailedVerify" and registry.data.strings : ("0", "0x00000000", "1", "0x00000001") and 
  not process.executable : 
                      ("?:\\Windows\\System32\\svchost.exe", 
                       "?:\\Windows\\CCM\\CcmExec.exe",
                       "\\Device\\HarddiskVolume*\\Windows\\system32\\svchost.exe", 
                       "\\Device\\HarddiskVolume*\\Windows\\CCM\\CcmExec.exe")
  /*
    Full registry key path omitted due to data source variations:
    "HKEY_USERS\\*\\Software\\Policies\\Microsoft\\Windows NT\\Driver Signing\\BehaviorOnFailedVerify"
  */

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.typeeq
  • change corpus 89 (elastic 89)
field:"event.type" kind:eq value:"change"
registry.data.stringswildcard
  • 0 corpus 17 (elastic 14, sigma 3)
  • 0x00000000 corpus 41 (splunk 33, elastic 8)
  • 0x00000001 corpus 61 (splunk 52, elastic 9)
  • 1 corpus 16 (elastic 14, splunk 2)
field:"Details" kind:wildcard
registry.valuewildcard
  • BehaviorOnFailedVerify
field:"registry_value_name" kind:wildcard value:"BehaviorOnFailedVerify"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.executablewildcard?:\Windows\System32\svchost.exe, ?:\Windows\CCM\CcmExec.exe, \Device\HarddiskVolume*\Windows\system32\svchost.exe, \Device\HarddiskVolume*\Windows\CCM\CcmExec.exeexcludes:process.executable

Entra ID OAuth Device Code Sign-in to Azure AD Graph Enumeration

#
Status
production
Severity
high
Time window
5m
Sequence by
azure.tenant_id, user.id
Author
Elastic
Source
github.com/elastic/detection-rules

Correlates a successful Entra ID device-code sign-in to the legacy Azure AD Graph audience (00000002-0000-0000-c000-000000000000) from an unmanaged device with directory enumeration against graph.windows.net by the same user within a short window. Device-code phishing is the dominant OAuth phishing variant against Microsoft tenants: the adversary initiates the flow, relays the user-facing code to the victim, and on redemption walks away with an access or refresh token bound to the targeted resource without ever handling the user's password or MFA factor. When the redeemed audience is AAD Graph and the redeeming device is unmanaged, the follow-on Graph traffic is the compromised cloud account being used by the attacker, not by the user. This rule fires when that token is immediately turned around against the directory under the same identity to read user, group, service principal, application, role assignment, directory object, policy, OAuth permission grant, or tenant detail collections.

Known False Positives

  • Authorized red team or audit activity (ROADrecon, ROADtools, AADInternals, roadtx). Document the engagement window and add exceptions on the calling user.
  • A developer or operator legitimately running first-party tooling under the device-code flow that then enumerates directory objects during onboarding or troubleshooting. Validate the calling app and source IP and exclude as appropriate.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2026/05/22"
integration = ["azure"]
maturity = "production"
updated_date = "2026/05/22"

[rule]
author = ["Elastic"]
description = """
Correlates a successful Entra ID device-code sign-in to the legacy Azure AD Graph audience
(00000002-0000-0000-c000-000000000000) from an unmanaged device with directory enumeration against graph.windows.net by
the same user within a short window. Device-code phishing is the dominant OAuth phishing variant against Microsoft
tenants: the adversary initiates the flow, relays the user-facing code to the victim, and on redemption walks away with
an access or refresh token bound to the targeted resource without ever handling the user's password or MFA factor. When
the redeemed audience is AAD Graph and the redeeming device is unmanaged, the follow-on Graph traffic is the compromised
cloud account being used by the attacker, not by the user. This rule fires when that token is immediately turned around
against the directory under the same identity to read user, group, service principal, application, role assignment,
directory object, policy, OAuth permission grant, or tenant detail collections.
"""
false_positives = [
    """
    Authorized red team or audit activity (ROADrecon, ROADtools, AADInternals, roadtx). Document the engagement window
    and add exceptions on the calling user.
    """,
    """
    A developer or operator legitimately running first-party tooling under the device-code flow that then enumerates
    directory objects during onboarding or troubleshooting. Validate the calling app and source IP and exclude as
    appropriate.
    """,
]
from = "now-9m"
index = ["logs-azure.signinlogs-*", "logs-azure.aadgraphactivitylogs-*"]
language = "eql"
license = "Elastic License v2"
name = "Entra ID OAuth Device Code Sign-in to Azure AD Graph Enumeration"
note = """## Triage and analysis

### Investigating Entra ID OAuth Device Code Sign-in to Azure AD Graph Enumeration

Device-code phishing redeems an OAuth access token directly into the adversary's hands without
ever touching the victim's password or MFA factor. When the redemption targets the legacy AAD
Graph audience from an unmanaged device, the resulting token is overwhelmingly used to drive
directory recon under the compromised identity. ROADrecon / ROADtools, AADInternals
(`Get-AADIntTenantDetails`, `Get-AADIntUsers`), and manual `roadtx` flows all match this shape.

### Possible investigation steps

- Confirm the sign-in shape.
    - `azure.signinlogs.properties.authentication_protocol` is `deviceCode`.
    - `azure.signinlogs.properties.resource_id` is `00000002-0000-0000-c000-000000000000` (legacy AAD Graph audience).
    - `azure.signinlogs.properties.device_detail.is_managed` is `false`.
- Identify the calling client used to drive the device-code grant.
    - `azure.signinlogs.properties.app_id`, `azure.signinlogs.properties.app_display_name`.
    - FOCI / pre-consented Microsoft clients (Teams, Office, Azure CLI, Azure PowerShell) are the canonical ride-along clients for device-code phishing because they bypass app consent.
- Review source posture for the redemption and the Graph follow-on independently.
    - `source.ip`, `source.as.organization.name`, `source.geo.country_name`. Residential / VPS / anonymising-network egress raises priority.
    - A code redeemed from one IP and Graph driven from another is a strong adversary-in-the-middle signal: the user clicked, the attacker is now driving the session.
- Review what was queried on the Graph side.
    - `url.path` on the second event. `applicationRefs`, `eligibleRoleAssignments`, and `directoryObjects` casts (`$/Microsoft.DirectoryServices.ServicePrincipal`) are the textbook ROADrecon signature; `tenantDetails` from an `AADInternals` user-agent is the AADInternals signature.
- Check the API version on the Graph call.
    - `azure.aadgraphactivitylogs.properties.api_version`. `1.61-internal` is a strong tooling indicator and returns data the public surface withholds (Conditional Access policies, MFA configuration on user objects).
- Pivot to surrounding sign-ins for the same user. Other device-code redemptions to Microsoft Graph, Azure Resource Manager, or Exchange in the same window suggest the attacker is multi-homing the token harvest.
- Confirm the activity is not attributable to authorized testing before treating as malicious.

### Response and remediation

- Revoke refresh tokens and active sessions for the compromised user.
    - `POST /v1.0/users/{id}/revokeSignInSessions`.
- Temporarily disable the user if the alert is high-confidence or you need to halt further activity while investigation continues.
    - `PATCH /v1.0/users/{id}` with body `{"accountEnabled": false}`.
- Check for device registrations created by the user during or around the burst window and remove rogue devices.
    - `GET /v1.0/users/{id}/registeredDevices` and `GET /v1.0/users/{id}/ownedDevices`, then `DELETE /v1.0/devices/{deviceObjectId}`.
    - Do this BEFORE session revocation: device-bound PRTs survive `revokeSignInSessions`.
- If the calling application has no legitimate AAD Graph dependency, block further use by that app.
    - `PATCH /beta/applications/{id}` with body `{"authenticationBehaviors": {"blockAzureADGraphAccess": true}}`.
    - This property lives on the Graph beta endpoint, not v1.0.
- Apply Conditional Access targeting the device-code grant: require a managed / compliant device or block the device-code grant outside of explicitly approved app + user populations.
"""
references = [
    "https://github.com/dirkjanm/ROADtools",
    "https://github.com/Gerenios/AADInternals",
    "https://learn.microsoft.com/en-us/graph/migrate-azure-ad-graph-overview",
]
risk_score = 73
rule_id = "aa04377a-19b5-4940-952f-aad173790d23"
setup = """#### Microsoft Entra ID Sign-in Logs and Azure AD Graph Activity Logs
Requires both data streams ingested via the Elastic Azure integration:
- Microsoft Entra ID sign-in logs into `logs-azure.signinlogs-*` (enable the `SignInLogs` diagnostic-settings category on Entra ID).
- Azure AD Graph Activity Logs into `logs-azure.aadgraphactivitylogs-*` (enable the `AzureADGraphActivityLogs` diagnostic-settings category on Entra ID).
"""
severity = "high"
tags = [
    "Domain: Cloud",
    "Domain: Identity",
    "Data Source: Azure",
    "Data Source: Microsoft Entra ID",
    "Data Source: Microsoft Entra ID Sign-in Logs",
    "Data Source: Azure AD Graph",
    "Data Source: Azure AD Graph Activity Logs",
    "Use Case: Identity and Access Audit",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Tactic: Initial Access",
    "Tactic: Discovery",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
sequence by user.id, azure.tenant_id with maxspan=5m
[authentication where
    data_stream.dataset == "azure.signinlogs" and
    event.outcome == "success" and
    azure.signinlogs.properties.authentication_protocol == "deviceCode" and
    azure.signinlogs.properties.device_detail.is_managed == false and
    azure.signinlogs.properties.resource_id == "00000002-0000-0000-c000-000000000000"]
[web where
    data_stream.dataset == "azure.aadgraphactivitylogs" and
    url.path : (
        "*/users*",
        "*/groups*",
        "*/servicePrincipals*",
        "*/applications*",
        "*/applicationRefs*",
        "*/devices*",
        "*/directoryRoles*",
        "*/roleAssignments*",
        "*/eligibleRoleAssignments*",
        "*/roleDefinitions*",
        "*/directoryObjects*",
        "*/policies*",
        "*/oauth2PermissionGrants*",
        "*/administrativeUnits*",
        "*/tenantDetails*",
        "*/directorySettingTemplates*",
        "*/me*"
    )]
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1528"
name = "Steal Application Access Token"
reference = "https://attack.mitre.org/techniques/T1528/"


[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"
[[rule.threat.technique.subtechnique]]
id = "T1078.004"
name = "Cloud Accounts"
reference = "https://attack.mitre.org/techniques/T1078/004/"



[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1069"
name = "Permission Groups Discovery"
reference = "https://attack.mitre.org/techniques/T1069/"
[[rule.threat.technique.subtechnique]]
id = "T1069.003"
name = "Cloud Groups"
reference = "https://attack.mitre.org/techniques/T1069/003/"


[[rule.threat.technique]]
id = "T1087"
name = "Account Discovery"
reference = "https://attack.mitre.org/techniques/T1087/"
[[rule.threat.technique.subtechnique]]
id = "T1087.004"
name = "Cloud Account"
reference = "https://attack.mitre.org/techniques/T1087/004/"


[[rule.threat.technique]]
id = "T1526"
name = "Cloud Service Discovery"
reference = "https://attack.mitre.org/techniques/T1526/"


[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"

[rule.investigation_fields]
field_names = [
    "user.id",
    "azure.tenant_id",
    "azure.signinlogs.properties.user_principal_name",
    "azure.signinlogs.properties.app_id",
    "azure.signinlogs.properties.app_display_name",
    "azure.signinlogs.properties.resource_id",
    "azure.signinlogs.properties.authentication_protocol",
    "azure.signinlogs.properties.device_detail.is_managed",
    "azure.aadgraphactivitylogs.properties.app_id",
    "azure.aadgraphactivitylogs.properties.api_version",
    "url.path",
    "user_agent.original",
    "source.ip",
    "source.as.organization.name",
    "source.geo.country_name",
]

Stages and Predicates

Ordered sequence: each step below must occur in order within 5m, correlated by azure.tenant_id, user.id.

Stage 1: authentication

[authentication where
    data_stream.dataset == "azure.signinlogs" and
    event.outcome == "success" and
    azure.signinlogs.properties.authentication_protocol == "deviceCode" and
    azure.signinlogs.properties.device_detail.is_managed == false and
    azure.signinlogs.properties.resource_id == "00000002-0000-0000-c000-000000000000"]

Stage 2: web

[web where
    data_stream.dataset == "azure.aadgraphactivitylogs" and
    url.path : (
        "*/users*",
        "*/groups*",
        "*/servicePrincipals*",
        "*/applications*",
        "*/applicationRefs*",
        "*/devices*",
        "*/directoryRoles*",
        "*/roleAssignments*",
        "*/eligibleRoleAssignments*",
        "*/roleDefinitions*",
        "*/directoryObjects*",
        "*/policies*",
        "*/oauth2PermissionGrants*",
        "*/administrativeUnits*",
        "*/tenantDetails*",
        "*/directorySettingTemplates*",
        "*/me*"
    )]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
azure.signinlogs.properties.authentication_protocoleq
  • deviceCode
field:"azure_ad::authentication_protocol" kind:eq value:"deviceCode"
azure.signinlogs.properties.device_detail.is_managedeq
  • false transforms: boolean
field:"azure.signinlogs.properties.device_detail.is_managed" kind:eq value:"false"
azure.signinlogs.properties.resource_ideq
  • 00000002-0000-0000-c000-000000000000
field:"azure_ad::resource_id" kind:eq value:"00000002-0000-0000-c000-000000000000"
data_stream.dataseteq
  • azure.aadgraphactivitylogs corpus 4 (elastic 4)
  • azure.signinlogs corpus 12 (elastic 12)
field:"data_stream.dataset" kind:eq
event.outcomeeq
  • success corpus 82 (elastic 82)
field:"event.outcome" kind:eq value:"success"
url.pathwildcard
  • */administrativeUnits*
  • */applicationRefs*
  • */applications*
  • */devices*
  • */directoryObjects*
  • */directoryRoles*
  • */directorySettingTemplates*
  • */eligibleRoleAssignments*
  • */groups*
  • */me*
  • */oauth2PermissionGrants*
  • */policies*
  • */roleAssignments*
  • */roleDefinitions*
  • */servicePrincipals*
  • */tenantDetails*
  • */users*
field:"url.path" kind:wildcard

Entra ID User Sign-in Brute Force Attempted

#
Status
production
Severity
medium
Time window
1h
Group by
Esql.time_window_date_trunc
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies potential brute-force attacks targeting user accounts by analyzing failed sign-in patterns in Microsoft Entra ID Sign-In Logs. This detection focuses on a high volume of failed interactive or non-interactive authentication attempts within a short time window, often indicative of password spraying, credential stuffing, or password guessing. Adversaries may use these techniques to gain unauthorized access to applications integrated with Entra ID or to compromise valid user accounts.

Known False Positives

  • Automated processes that attempt to authenticate using expired credentials or have misconfigured authentication settings may lead to false positives.

MITRE ATT&CK Coverage

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2024/09/06"
integration = ["azure"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Identifies potential brute-force attacks targeting user accounts by analyzing failed sign-in patterns in Microsoft Entra
ID Sign-In Logs. This detection focuses on a high volume of failed interactive or non-interactive authentication
attempts within a short time window, often indicative of password spraying, credential stuffing, or password guessing.
Adversaries may use these techniques to gain unauthorized access to applications integrated with Entra ID or to
compromise valid user accounts.
"""
false_positives = [
    """
    Automated processes that attempt to authenticate using expired credentials or have misconfigured authentication
    settings may lead to false positives.
    """,
]
from = "now-60m"
interval = "15m"
language = "esql"
license = "Elastic License v2"
name = "Entra ID User Sign-in Brute Force Attempted"
note = """## Triage and analysis

### Investigating Entra ID User Sign-in Brute Force Attempted

This rule detects brute-force authentication activity in Entra ID sign-in logs. It classifies failed sign-in attempts into behavior types such as password spraying, credential stuffing, or password guessing. The classification (`bf_type`) helps prioritize triage and incident response.

### Possible investigation steps

- Review `bf_type`: Determines the brute-force technique being used (`password_spraying`, `credential_stuffing`, or `password_guessing`).
- Examine `user_id_list`: Identify if high-value accounts (e.g., administrators, service principals, federated identities) are being targeted.
- Review `login_errors`: Repetitive error types like `"Invalid Grant"` or `"User Not Found"` suggest automated attacks.
- Check `ip_list` and `source_orgs`: Investigate if the activity originates from suspicious infrastructure (VPNs, hosting providers, etc.).
- Validate `unique_ips` and `countries`: Geographic diversity and IP volume may indicate distributed or botnet-based attacks.
- Compare `total_attempts` vs `duration_seconds`: High rate of failures in a short time period implies automation.
- Analyze `user_agent.original` and `device_detail_browser`: User agents like `curl`, `Python`, or generic libraries may indicate scripting tools.
- Investigate `client_app_display_name` and `incoming_token_type`: Detect potential abuse of legacy or unattended login mechanisms.
- Inspect `target_resource_display_name`: Understand what application or resource the attacker is trying to access.
- Pivot using `session_id` and `device_detail_device_id`: Determine if a device is targeting multiple accounts.
- Review `conditional_access_status`: If not enforced, ensure Conditional Access policies are scoped correctly.

### False positive analysis

- Legitimate automation (e.g., misconfigured scripts, sync processes) can trigger repeated failures.
- Internal red team activity or penetration tests may mimic brute-force behaviors.
- Certain service accounts or mobile clients may generate repetitive sign-in noise if not properly configured.

### Response and remediation

- Notify your identity security team for further analysis.
- Investigate and lock or reset impacted accounts if compromise is suspected.
- Block offending IPs or ASNs at the firewall, proxy, or using Conditional Access.
- Confirm MFA and Conditional Access are enforced for all user types.
- Audit targeted accounts for credential reuse across services.
- Implement account lockout or throttling for failed sign-in attempts where possible.
"""
references = [
    "https://www.proofpoint.com/us/blog/threat-insight/attackers-unleash-teamfiltration-account-takeover-campaign",
    "https://www.microsoft.com/en-us/security/blog/2025/05/27/new-russia-affiliated-actor-void-blizzard-targets-critical-sectors-for-espionage/",
    "https://cloud.hacktricks.xyz/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-password-spraying",
    "https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray",
    "https://learn.microsoft.com/en-us/purview/audit-log-detailed-properties",
    "https://securityscorecard.com/research/massive-botnet-targets-m365-with-stealthy-password-spraying-attacks/",
    "https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes",
    "https://github.com/0xZDH/Omnispray",
    "https://github.com/0xZDH/o365spray",
]
risk_score = 47
rule_id = "cca64114-fb8b-11ef-86e2-f661ea17fbce"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Domain: Identity",
    "Data Source: Azure",
    "Data Source: Entra ID",
    "Data Source: Entra ID Sign-in Logs",
    "Use Case: Identity and Access Audit",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"

query = '''
from logs-azure.signinlogs-*

// Define a time window for grouping and maintain the original event timestamp
| eval Esql.time_window_date_trunc = date_trunc(15 minutes, @timestamp)

// Filter relevant failed authentication events with specific error codes
| where data_stream.dataset == "azure.signinlogs"
    and event.category == "authentication"
    and azure.signinlogs.category in ("NonInteractiveUserSignInLogs", "SignInLogs")
    and event.outcome == "failure"
    and azure.signinlogs.properties.authentication_requirement == "singleFactorAuthentication"
    and azure.signinlogs.properties.status.error_code in (
        50034,  // UserAccountNotFound
        50126,  // InvalidUsernameOrPassword
        50055,  // PasswordExpired
        50056,  // InvalidPassword
        50057,  // UserDisabled
        50064,  // CredentialValidationFailure
        50076,  // MFARequiredButNotPassed
        50079,  // MFARegistrationRequired
        50105,  // EntitlementGrantsNotFound
        70000,  // InvalidGrant
        70008,  // ExpiredOrRevokedRefreshToken
        70043,  // BadTokenDueToSignInFrequency
        80002,  // OnPremisePasswordValidatorRequestTimedOut
        80005,  // OnPremisePasswordValidatorUnpredictableWebException
        50144,  // InvalidPasswordExpiredOnPremPassword
        50135,  // PasswordChangeCompromisedPassword
        50142,  // PasswordChangeRequiredConditionalAccess
        120000, // PasswordChangeIncorrectCurrentPassword
        120002, // PasswordChangeInvalidNewPasswordWeak
        120020  // PasswordChangeFailure
    )
    and azure.signinlogs.properties.user_principal_name is not null and azure.signinlogs.properties.user_principal_name != ""
    and user_agent.original != "Mozilla/5.0 (compatible; MSAL 1.0) PKeyAuth/1.0"
    and source.`as`.organization.name != "MICROSOFT-CORP-MSN-as-BLOCK"

| stats
    Esql.azure_signinlogs_properties_authentication_requirement_values = values(azure.signinlogs.properties.authentication_requirement),
    Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id),
    Esql.azure_signinlogs_properties_app_display_name_values = values(azure.signinlogs.properties.app_display_name),
    Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id),
    Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name),
    Esql.azure_signinlogs_properties_conditional_access_status_values = values(azure.signinlogs.properties.conditional_access_status),
    Esql.azure_signinlogs_properties_device_detail_browser_values = values(azure.signinlogs.properties.device_detail.browser),
    Esql.azure_signinlogs_properties_device_detail_device_id_values = values(azure.signinlogs.properties.device_detail.device_id),
    Esql.azure_signinlogs_properties_device_detail_operating_system_values = values(azure.signinlogs.properties.device_detail.operating_system),
    Esql.azure_signinlogs_properties_incoming_token_type_values = values(azure.signinlogs.properties.incoming_token_type),
    Esql.azure_signinlogs_properties_risk_state_values = values(azure.signinlogs.properties.risk_state),
    Esql.azure_signinlogs_properties_session_id_values = values(azure.signinlogs.properties.session_id),
    Esql.azure_signinlogs_properties_user_id_values = values(azure.signinlogs.properties.user_id),
    Esql_priv.azure_signinlogs_properties_user_principal_name_values = values(azure.signinlogs.properties.user_principal_name),
    Esql.azure_signinlogs_result_description_values = values(azure.signinlogs.result_description),
    Esql.azure_signinlogs_result_signature_values = values(azure.signinlogs.result_signature),
    Esql.azure_signinlogs_result_type_values = values(azure.signinlogs.result_type),

    Esql.azure_signinlogs_properties_user_id_count_distinct = count_distinct(azure.signinlogs.properties.user_id),
    Esql.azure_signinlogs_properties_user_id_list = values(azure.signinlogs.properties.user_id),
    Esql.azure_signinlogs_result_description_values_all = values(azure.signinlogs.result_description),
    Esql.azure_signinlogs_result_description_count_distinct = count_distinct(azure.signinlogs.result_description),
    Esql.azure_signinlogs_properties_status_error_code_values = values(azure.signinlogs.properties.status.error_code),
    Esql.azure_signinlogs_properties_status_error_code_count_distinct = count_distinct(azure.signinlogs.properties.status.error_code),
    Esql.azure_signinlogs_properties_incoming_token_type_values_all = values(azure.signinlogs.properties.incoming_token_type),
    Esql.azure_signinlogs_properties_app_display_name_values_all = values(azure.signinlogs.properties.app_display_name),
    Esql.source_ip_values = values(source.ip),
    Esql.source_ip_count_distinct = count_distinct(source.ip),
    Esql.source_as_organization_name_values = values(source.`as`.organization.name),
    Esql.source_geo_country_name_values = values(source.geo.country_name),
    Esql.source_geo_country_name_count_distinct = count_distinct(source.geo.country_name),
    Esql.source_as_organization_name_count_distinct = count_distinct(source.`as`.organization.name),
    Esql.timestamp_first_seen = min(@timestamp),
    Esql.timestamp_last_seen = max(@timestamp),
    Esql.event_count = count()
by Esql.time_window_date_trunc

| eval
    Esql.duration_seconds = date_diff("seconds", Esql.timestamp_first_seen, Esql.timestamp_last_seen),
    Esql.brute_force_type = case(
        Esql.azure_signinlogs_properties_user_id_count_distinct >= 10 and Esql.event_count >= 30 and Esql.azure_signinlogs_result_description_count_distinct <= 3
            and Esql.source_ip_count_distinct >= 5
            and Esql.duration_seconds <= 600
            and Esql.azure_signinlogs_properties_user_id_count_distinct > Esql.source_ip_count_distinct,
        "credential_stuffing",

        Esql.azure_signinlogs_properties_user_id_count_distinct >= 15 and Esql.azure_signinlogs_result_description_count_distinct == 1 and Esql.event_count >= 15 and Esql.duration_seconds <= 1800,
        "password_spraying",

        (Esql.azure_signinlogs_properties_user_id_count_distinct == 1 and Esql.azure_signinlogs_result_description_count_distinct == 1 and Esql.event_count >= 30 and Esql.duration_seconds <= 300)
            or (Esql.azure_signinlogs_properties_user_id_count_distinct <= 3 and Esql.source_ip_count_distinct > 30 and Esql.event_count >= 100),
        "password_guessing",

        "other"
    )

| keep
    Esql.time_window_date_trunc,
    Esql.brute_force_type,
    Esql.duration_seconds,
    Esql.event_count,
    Esql.timestamp_first_seen,
    Esql.timestamp_last_seen,
    Esql.azure_signinlogs_properties_user_id_count_distinct,
    Esql.azure_signinlogs_properties_user_id_list,
    Esql.azure_signinlogs_result_description_values_all,
    Esql.azure_signinlogs_result_description_count_distinct,
    Esql.azure_signinlogs_properties_status_error_code_count_distinct,
    Esql.azure_signinlogs_properties_status_error_code_values,
    Esql.azure_signinlogs_properties_incoming_token_type_values_all,
    Esql.azure_signinlogs_properties_app_display_name_values_all,
    Esql.source_ip_values,
    Esql.source_ip_count_distinct,
    Esql.source_as_organization_name_values,
    Esql.source_geo_country_name_values,
    Esql.source_geo_country_name_count_distinct,
    Esql.source_as_organization_name_count_distinct,
    Esql.azure_signinlogs_properties_authentication_requirement_values,
    Esql.azure_signinlogs_properties_app_id_values,
    Esql.azure_signinlogs_properties_app_display_name_values,
    Esql.azure_signinlogs_properties_resource_id_values,
    Esql.azure_signinlogs_properties_resource_display_name_values,
    Esql.azure_signinlogs_properties_conditional_access_status_values,
    Esql.azure_signinlogs_properties_device_detail_browser_values,
    Esql.azure_signinlogs_properties_device_detail_device_id_values,
    Esql.azure_signinlogs_properties_device_detail_operating_system_values,
    Esql.azure_signinlogs_properties_incoming_token_type_values,
    Esql.azure_signinlogs_properties_risk_state_values,
    Esql.azure_signinlogs_properties_session_id_values,
    Esql.azure_signinlogs_properties_user_id_values,
    Esql_priv.azure_signinlogs_properties_user_principal_name_values,
    Esql.azure_signinlogs_result_description_values,
    Esql.azure_signinlogs_result_signature_values,
    Esql.azure_signinlogs_result_type_values

| where Esql.brute_force_type != "other"
'''


[[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.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-azure.signinlogs-*

Stage 2: eval

| eval Esql.time_window_date_trunc = date_trunc(15 minutes, @timestamp)

Stage 3: where

| where data_stream.dataset == "azure.signinlogs"
    and event.category == "authentication"
    and azure.signinlogs.category in ("NonInteractiveUserSignInLogs", "SignInLogs")
    and event.outcome == "failure"
    and azure.signinlogs.properties.authentication_requirement == "singleFactorAuthentication"
    and azure.signinlogs.properties.status.error_code in (
        50034,
        50126,
        50055,
        50056,
        50057,
        50064,
        50076,
        50079,
        50105,
        70000,
        70008,
        70043,
        80002,
        80005,
        50144,
        50135,
        50142,
        120000,
        120002,
        120020
    )
    and azure.signinlogs.properties.user_principal_name is not null and azure.signinlogs.properties.user_principal_name != ""
    and user_agent.original != "Mozilla/5.0 (compatible; MSAL 1.0) PKeyAuth/1.0"
    and source.`as`.organization.name != "MICROSOFT-CORP-MSN-as-BLOCK"

Stage 4: stats

| stats
    Esql.azure_signinlogs_properties_authentication_requirement_values = values(azure.signinlogs.properties.authentication_requirement),
    Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id),
    Esql.azure_signinlogs_properties_app_display_name_values = values(azure.signinlogs.properties.app_display_name),
    Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id),
    Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name),
    Esql.azure_signinlogs_properties_conditional_access_status_values = values(azure.signinlogs.properties.conditional_access_status),
    Esql.azure_signinlogs_properties_device_detail_browser_values = values(azure.signinlogs.properties.device_detail.browser),
    Esql.azure_signinlogs_properties_device_detail_device_id_values = values(azure.signinlogs.properties.device_detail.device_id),
    Esql.azure_signinlogs_properties_device_detail_operating_system_values = values(azure.signinlogs.properties.device_detail.operating_system),
    Esql.azure_signinlogs_properties_incoming_token_type_values = values(azure.signinlogs.properties.incoming_token_type),
    Esql.azure_signinlogs_properties_risk_state_values = values(azure.signinlogs.properties.risk_state),
    Esql.azure_signinlogs_properties_session_id_values = values(azure.signinlogs.properties.session_id),
    Esql.azure_signinlogs_properties_user_id_values = values(azure.signinlogs.properties.user_id),
    Esql_priv.azure_signinlogs_properties_user_principal_name_values = values(azure.signinlogs.properties.user_principal_name),
    Esql.azure_signinlogs_result_description_values = values(azure.signinlogs.result_description),
    Esql.azure_signinlogs_result_signature_values = values(azure.signinlogs.result_signature),
    Esql.azure_signinlogs_result_type_values = values(azure.signinlogs.result_type),

    Esql.azure_signinlogs_properties_user_id_count_distinct = count_distinct(azure.signinlogs.properties.user_id),
    Esql.azure_signinlogs_properties_user_id_list = values(azure.signinlogs.properties.user_id),
    Esql.azure_signinlogs_result_description_values_all = values(azure.signinlogs.result_description),
    Esql.azure_signinlogs_result_description_count_distinct = count_distinct(azure.signinlogs.result_description),
    Esql.azure_signinlogs_properties_status_error_code_values = values(azure.signinlogs.properties.status.error_code),
    Esql.azure_signinlogs_properties_status_error_code_count_distinct = count_distinct(azure.signinlogs.properties.status.error_code),
    Esql.azure_signinlogs_properties_incoming_token_type_values_all = values(azure.signinlogs.properties.incoming_token_type),
    Esql.azure_signinlogs_properties_app_display_name_values_all = values(azure.signinlogs.properties.app_display_name),
    Esql.source_ip_values = values(source.ip),
    Esql.source_ip_count_distinct = count_distinct(source.ip),
    Esql.source_as_organization_name_values = values(source.`as`.organization.name),
    Esql.source_geo_country_name_values = values(source.geo.country_name),
    Esql.source_geo_country_name_count_distinct = count_distinct(source.geo.country_name),
    Esql.source_as_organization_name_count_distinct = count_distinct(source.`as`.organization.name),
    Esql.timestamp_first_seen = min(@timestamp),
    Esql.timestamp_last_seen = max(@timestamp),
    Esql.event_count = count()
by Esql.time_window_date_trunc

Stage 5: eval

| eval
    Esql.duration_seconds = date_diff("seconds", Esql.timestamp_first_seen, Esql.timestamp_last_seen),
    Esql.brute_force_type = case(
        Esql.azure_signinlogs_properties_user_id_count_distinct >= 10 and Esql.event_count >= 30 and Esql.azure_signinlogs_result_description_count_distinct <= 3
            and Esql.source_ip_count_distinct >= 5
            and Esql.duration_seconds <= 600
            and Esql.azure_signinlogs_properties_user_id_count_distinct > Esql.source_ip_count_distinct,
        "credential_stuffing",

        Esql.azure_signinlogs_properties_user_id_count_distinct >= 15 and Esql.azure_signinlogs_result_description_count_distinct == 1 and Esql.event_count >= 15 and Esql.duration_seconds <= 1800,
        "password_spraying",

        (Esql.azure_signinlogs_properties_user_id_count_distinct == 1 and Esql.azure_signinlogs_result_description_count_distinct == 1 and Esql.event_count >= 30 and Esql.duration_seconds <= 300)
            or (Esql.azure_signinlogs_properties_user_id_count_distinct <= 3 and Esql.source_ip_count_distinct > 30 and Esql.event_count >= 100),
        "password_guessing",

        "other"
    )
Esql.brute_force_type =
ifEsql.azure_signinlogs_properties_user_id_count_distinct >= 10 and Esql.event_count >= 30 and Esql.azure_signinlogs_result_description_count_distinct <= 3 and Esql.source_ip_count_distinct >= 5 and Esql.duration_seconds <= 600 and Esql.azure_signinlogs_properties_user_id_count_distinct > Esql.source_ip_count_distinct"credential_stuffing"
elifEsql.azure_signinlogs_properties_user_id_count_distinct >= 15 and Esql.azure_signinlogs_result_description_count_distinct == 1 and Esql.event_count >= 15 and Esql.duration_seconds <= 1800"password_spraying"
elif(Esql.azure_signinlogs_properties_user_id_count_distinct == 1 and Esql.azure_signinlogs_result_description_count_distinct == 1 and Esql.event_count >= 30 and Esql.duration_seconds <= 300) or (Esql.azure_signinlogs_properties_user_id_count_distinct <= 3 and Esql.source_ip_count_distinct > 30 and Esql.event_count >= 100)"password_guessing"
else"other"

Stage 6: keep

| keep
    Esql.time_window_date_trunc,
    Esql.brute_force_type,
    Esql.duration_seconds,
    Esql.event_count,
    Esql.timestamp_first_seen,
    Esql.timestamp_last_seen,
    Esql.azure_signinlogs_properties_user_id_count_distinct,
    Esql.azure_signinlogs_properties_user_id_list,
    Esql.azure_signinlogs_result_description_values_all,
    Esql.azure_signinlogs_result_description_count_distinct,
    Esql.azure_signinlogs_properties_status_error_code_count_distinct,
    Esql.azure_signinlogs_properties_status_error_code_values,
    Esql.azure_signinlogs_properties_incoming_token_type_values_all,
    Esql.azure_signinlogs_properties_app_display_name_values_all,
    Esql.source_ip_values,
    Esql.source_ip_count_distinct,
    Esql.source_as_organization_name_values,
    Esql.source_geo_country_name_values,
    Esql.source_geo_country_name_count_distinct,
    Esql.source_as_organization_name_count_distinct,
    Esql.azure_signinlogs_properties_authentication_requirement_values,
    Esql.azure_signinlogs_properties_app_id_values,
    Esql.azure_signinlogs_properties_app_display_name_values,
    Esql.azure_signinlogs_properties_resource_id_values,
    Esql.azure_signinlogs_properties_resource_display_name_values,
    Esql.azure_signinlogs_properties_conditional_access_status_values,
    Esql.azure_signinlogs_properties_device_detail_browser_values,
    Esql.azure_signinlogs_properties_device_detail_device_id_values,
    Esql.azure_signinlogs_properties_device_detail_operating_system_values,
    Esql.azure_signinlogs_properties_incoming_token_type_values,
    Esql.azure_signinlogs_properties_risk_state_values,
    Esql.azure_signinlogs_properties_session_id_values,
    Esql.azure_signinlogs_properties_user_id_values,
    Esql_priv.azure_signinlogs_properties_user_principal_name_values,
    Esql.azure_signinlogs_result_description_values,
    Esql.azure_signinlogs_result_signature_values,
    Esql.azure_signinlogs_result_type_values

Stage 7: where

| where Esql.brute_force_type != "other"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
Esql.brute_force_typene
  • other corpus 2 (elastic 2)
field:"Esql.brute_force_type" kind:ne value:"other"
azure.signinlogs.categoryin
  • NonInteractiveUserSignInLogs corpus 2 (elastic 2)
  • SignInLogs corpus 2 (elastic 2)
field:"azure_ad::signin_category" kind:in
azure.signinlogs.properties.authentication_requirementeq
  • singleFactorAuthentication
field:"azure_ad::authentication_requirement" kind:eq value:"singleFactorAuthentication"
azure.signinlogs.properties.status.error_codein
  • 120000 corpus 2 (elastic 2)
  • 120002 corpus 2 (elastic 2)
  • 120020 corpus 2 (elastic 2)
  • 50034 corpus 2 (elastic 2)
  • 50055 corpus 2 (elastic 2)
  • 50056 corpus 2 (elastic 2)
  • 50057 corpus 2 (elastic 2)
  • 50064 corpus 2 (elastic 2)
  • 50076 corpus 2 (elastic 2)
  • 50079 corpus 2 (elastic 2)
  • 50105 corpus 2 (elastic 2)
  • 50126 corpus 2 (elastic 2)
  • 50135 corpus 2 (elastic 2)
  • 50142 corpus 2 (elastic 2)
  • 50144 corpus 2 (elastic 2)
  • 70000 corpus 2 (elastic 2)
  • 70008 corpus 2 (elastic 2)
  • 70043 corpus 2 (elastic 2)
  • 80002 corpus 2 (elastic 2)
  • 80005 corpus 2 (elastic 2)
field:"azure_ad::result_type" kind:in
azure.signinlogs.properties.user_principal_nameis_not_null
  • (no value, null check)
field:"azure_ad::user_principal_name" kind:is_not_null
data_stream.dataseteq
  • azure.signinlogs corpus 12 (elastic 12)
field:"data_stream.dataset" kind:eq value:"azure.signinlogs"
event.categoryeq
  • authentication corpus 14 (elastic 14)
field:"event.category" kind:eq value:"authentication"
event.outcomeeq
  • failure corpus 10 (elastic 10)
field:"event.outcome" kind:eq value:"failure"
source.as.organization.namene
  • MICROSOFT-CORP-MSN-as-BLOCK corpus 2 (elastic 2)
field:"source.as.organization.name" kind:ne value:"MICROSOFT-CORP-MSN-as-BLOCK"
user_agent.originalne
  • Mozilla/5.0 (compatible; MSAL 1.0) PKeyAuth/1.0 corpus 2 (elastic 2)
field:"aws::userAgent" kind:ne value:"Mozilla/5.0 (compatible; MSAL 1.0) PKeyAuth/1.0"

Output Fields

These fields are emitted when the rule matches.

FieldSource
Esql.time_window_date_truncKEEP Esql.time_window_date_trunc
Esql.brute_force_typeKEEP Esql.brute_force_type
Esql.duration_secondsKEEP Esql.duration_seconds
Esql.event_countKEEP Esql.event_count
Esql.timestamp_first_seenKEEP Esql.timestamp_first_seen
Esql.timestamp_last_seenKEEP Esql.timestamp_last_seen
Esql.azure_signinlogs_properties_user_id_count_distinctKEEP Esql.azure_signinlogs_properties_user_id_count_distinct
Esql.azure_signinlogs_properties_user_id_listKEEP Esql.azure_signinlogs_properties_user_id_list
Esql.azure_signinlogs_result_description_values_allKEEP Esql.azure_signinlogs_result_description_values_all
Esql.azure_signinlogs_result_description_count_distinctKEEP Esql.azure_signinlogs_result_description_count_distinct
Esql.azure_signinlogs_properties_status_error_code_count_distinctKEEP Esql.azure_signinlogs_properties_status_error_code_count_distinct
Esql.azure_signinlogs_properties_status_error_code_valuesKEEP Esql.azure_signinlogs_properties_status_error_code_values
Esql.azure_signinlogs_properties_incoming_token_type_values_allKEEP Esql.azure_signinlogs_properties_incoming_token_type_values_all
Esql.azure_signinlogs_properties_app_display_name_values_allKEEP Esql.azure_signinlogs_properties_app_display_name_values_all
Esql.source_ip_valuesKEEP Esql.source_ip_values
Esql.source_ip_count_distinctKEEP Esql.source_ip_count_distinct
Esql.source_as_organization_name_valuesKEEP Esql.source_as_organization_name_values
Esql.source_geo_country_name_valuesKEEP Esql.source_geo_country_name_values
Esql.source_geo_country_name_count_distinctKEEP Esql.source_geo_country_name_count_distinct
Esql.source_as_organization_name_count_distinctKEEP Esql.source_as_organization_name_count_distinct
Esql.azure_signinlogs_properties_authentication_requirement_valuesKEEP Esql.azure_signinlogs_properties_authentication_requirement_values
Esql.azure_signinlogs_properties_app_id_valuesKEEP Esql.azure_signinlogs_properties_app_id_values
Esql.azure_signinlogs_properties_app_display_name_valuesKEEP Esql.azure_signinlogs_properties_app_display_name_values
Esql.azure_signinlogs_properties_resource_id_valuesKEEP Esql.azure_signinlogs_properties_resource_id_values
Esql.azure_signinlogs_properties_resource_display_name_valuesKEEP Esql.azure_signinlogs_properties_resource_display_name_values
Esql.azure_signinlogs_properties_conditional_access_status_valuesKEEP Esql.azure_signinlogs_properties_conditional_access_status_values
Esql.azure_signinlogs_properties_device_detail_browser_valuesKEEP Esql.azure_signinlogs_properties_device_detail_browser_values
Esql.azure_signinlogs_properties_device_detail_device_id_valuesKEEP Esql.azure_signinlogs_properties_device_detail_device_id_values
Esql.azure_signinlogs_properties_device_detail_operating_system_valuesKEEP Esql.azure_signinlogs_properties_device_detail_operating_system_values
Esql.azure_signinlogs_properties_incoming_token_type_valuesKEEP Esql.azure_signinlogs_properties_incoming_token_type_values
Esql.azure_signinlogs_properties_risk_state_valuesKEEP Esql.azure_signinlogs_properties_risk_state_values
Esql.azure_signinlogs_properties_session_id_valuesKEEP Esql.azure_signinlogs_properties_session_id_values
Esql.azure_signinlogs_properties_user_id_valuesKEEP Esql.azure_signinlogs_properties_user_id_values
Esql_priv.azure_signinlogs_properties_user_principal_name_valuesKEEP Esql_priv.azure_signinlogs_properties_user_principal_name_values
Esql.azure_signinlogs_result_description_valuesKEEP Esql.azure_signinlogs_result_description_values
Esql.azure_signinlogs_result_signature_valuesKEEP Esql.azure_signinlogs_result_signature_values
Esql.azure_signinlogs_result_type_valuesKEEP Esql.azure_signinlogs_result_type_values

ESXI Discovery via Grep

#
Status
production
Severity
medium
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies instances where a process named 'grep', 'egrep', or 'pgrep' is started on a Linux system with arguments related to virtual machine (VM) files, such as "vmdk", "vmx", "vmxf", "vmsd", "vmsn", "vswp", "vmss", "nvram", or "vmem". These file extensions are associated with VM-related file formats, and their presence in grep command arguments may indicate that a threat actor is attempting to search for, analyze, or manipulate VM files on the system.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2023/04/11"
integration = ["endpoint", "auditd_manager", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
Identifies instances where a process named 'grep', 'egrep', or 'pgrep' is started on a Linux system with arguments
related to virtual machine (VM) files, such as "vmdk", "vmx", "vmxf", "vmsd", "vmsn", "vswp", "vmss", "nvram", or
"vmem". These file extensions are associated with VM-related file formats, and their presence in grep command arguments
may indicate that a threat actor is attempting to search for, analyze, or manipulate VM files on the system.
"""
from = "now-9m"
index = [
    "auditbeat-*",
    "endgame-*",
    "logs-auditd_manager.auditd-*",
    "logs-endpoint.events.process*",
    "logs-sentinel_one_cloud_funnel.*",
    "logs-crowdstrike.fdr*",
]
language = "eql"
license = "Elastic License v2"
name = "ESXI Discovery via Grep"
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 ESXI Discovery via Grep

In Linux environments, tools like 'grep' are used to search through files for specific patterns. Adversaries may exploit these tools to locate and analyze virtual machine files, which are crucial for ESXi environments. The detection rule identifies suspicious use of 'grep' variants targeting VM file extensions, signaling potential reconnaissance or manipulation attempts by threat actors. This rule helps in early detection of such malicious activities by monitoring process execution patterns.

### Possible investigation steps

- Review the process execution details to confirm the presence of 'grep', 'egrep', or 'pgrep' with arguments related to VM file extensions such as "vmdk", "vmx", "vmxf", "vmsd", "vmsn", "vswp", "vmss", "nvram", or "vmem".
- Check the parent process of the suspicious 'grep' command to determine if it is a legitimate process or potentially malicious, ensuring it is not "/usr/share/qemu/init/qemu-kvm-init".
- Investigate the user account associated with the process execution to assess if the activity aligns with their typical behavior or if it appears anomalous.
- Examine recent system logs and other security alerts for additional indicators of compromise or related suspicious activities on the host.
- Assess the network activity from the host to identify any unusual connections or data exfiltration attempts that may correlate with the discovery activity.

### False positive analysis

- System administrators or automated scripts may use grep to search for VM-related files as part of routine maintenance or monitoring tasks. To handle this, create exceptions for known administrative scripts or processes by excluding specific parent processes or user accounts.
- Backup or snapshot management tools might invoke grep to verify the presence of VM files. Identify these tools and exclude their process names or paths from the detection rule to prevent false alerts.
- Developers or IT staff conducting legitimate audits or inventory checks on VM files may trigger this rule. Consider excluding specific user accounts or groups that are authorized to perform such activities.
- Security tools or monitoring solutions that perform regular checks on VM files could also cause false positives. Whitelist these tools by excluding their executable paths or process names from the rule.

### Response and remediation

- Isolate the affected Linux system from the network to prevent further unauthorized access or data exfiltration.
- Terminate any suspicious processes identified by the detection rule, specifically those involving 'grep', 'egrep', or 'pgrep' with VM-related file extensions.
- Conduct a thorough review of the system's recent process execution history and file access logs to identify any unauthorized access or changes to VM files.
- Restore any compromised or altered VM files from a known good backup to ensure system integrity and continuity.
- Implement stricter access controls and permissions on VM-related files to limit exposure to unauthorized users or processes.
- Escalate the incident to the security operations team for further investigation and to determine if additional systems are affected.
- Update and enhance monitoring rules to detect similar patterns of suspicious activity, ensuring early detection of future threats."""
references = [
    "https://www.bleepingcomputer.com/news/security/massive-esxiargs-ransomware-attack-targets-vmware-esxi-servers-worldwide/",
]
risk_score = 47
rule_id = "2b662e21-dc6e-461e-b5cf-a6eb9b235ec4"
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: Discovery",
    "Data Source: Elastic Defend",
    "Data Source: Elastic Endgame",
    "Data Source: Auditd Manager",
    "Data Source: SentinelOne",
    "Data Source: Crowdstrike",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "linux" and event.type == "start" and
event.action in ("exec", "exec_event", "start", "executed", "process_started", "ProcessRollup2") and
process.name in ("grep", "egrep", "pgrep") and
process.args in ("vmdk", "vmx", "vmxf", "vmsd", "vmsn", "vswp", "vmss", "nvram", "vmem") and
not ?process.parent.executable in ("/usr/share/qemu/init/qemu-kvm-init", "/etc/sysconfig/modules/kvm.modules")
'''

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1083"
name = "File and Directory Discovery"
reference = "https://attack.mitre.org/techniques/T1083/"

[[rule.threat.technique]]
id = "T1518"
name = "Software Discovery"
reference = "https://attack.mitre.org/techniques/T1518/"

[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"

Stages and Predicates

Stage 1: process

process where host.os.type == "linux" and event.type == "start" and
event.action in ("exec", "exec_event", "start", "executed", "process_started", "ProcessRollup2") and
process.name in ("grep", "egrep", "pgrep") and
process.args in ("vmdk", "vmx", "vmxf", "vmsd", "vmsn", "vswp", "vmss", "nvram", "vmem") and
not ?process.parent.executable in ("/usr/share/qemu/init/qemu-kvm-init", "/etc/sysconfig/modules/kvm.modules")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actionin
  • ProcessRollup2
  • exec
  • exec_event
  • executed
  • process_started
  • start
field:"EventType" kind:in
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
process.argsin
  • nvram
  • vmdk
  • vmem
  • vmsd
  • vmsn
  • vmss
  • vmx
  • vmxf
  • vswp
field:"process.args" kind:in
process.namein
  • egrep
  • grep
  • pgrep
field:"process_basename" kind:in

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.parent.executablein/etc/sysconfig/modules/kvm.modules, /usr/share/qemu/init/qemu-kvm-initexcludes:process.parent.executable field:"process.parent.executable" value:"/etc/sysconfig/modules/kvm.modules" field:"process.parent.executable" value:"/usr/share/qemu/init/qemu-kvm-init"

Execution from Unusual Directory

#
Source
github.com/elastic/protections-artifacts

Identifies process execution from suspicious default Windows directories. This may be abused by adversaries to hide malware in trusted paths.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies process execution from suspicious default Windows directories. This may be abused by adversaries to hide
malware in trusted paths.
"""
id = "16c84e67-e5e7-44ff-aefa-4d771bcafc0c"
license = "Elastic License v2"
name = "Execution from Unusual Directory"
os_list = ["windows"]
reference = [
    "https://www.elastic.co/security-labs/elastic-protects-against-data-wiper-malware-targeting-ukraine-hermeticwiper",
    "https://www.elastic.co/security-labs/hunting-for-lateral-movement-using-event-query-language",
    "https://www.elastic.co/security-labs/operation-bleeding-bear",
]
version = "1.0.48"

query = '''
process where event.action == "start" and
  process.name : ("wscript.exe",
                  "rundll32.exe",
                  "regsvr32.exe",
                  "cmstp.exe",
                  "RegAsm.exe",
                  "installutil.exe",
                  "mshta.exe",
                  "RegSvcs.exe",
                  "msbuild.exe",
                  "msxsl.exe",
                  "xwizard.exe") and
  /* add suspicious execution paths here */
  process.args : ("?:\\PerfLogs\\*",
                  "?:\\Users\\*\\Pictures\\*",
                  "?:\\Users\\*\\Music\\*",
                  "?:\\Users\\Public\\*",
                  "?:\\Windows\\Tasks\\*",
                  "?:\\Windows\\System32\\Tasks\\*",
                  "?:\\Intel\\*",
                  "?:\\AMD\\Temp\\*",
                  "?:\\Windows\\hp\\*",
                  "?:\\Windows\\AppReadiness\\*",
                  "?:\\Windows\\ServiceState\\*",
                  "?:\\Windows\\security\\*",
                  "?:\\Windows\\IdentityCRL\\*",
                  "?:\\Windows\\Branding\\*",
                  "?:\\Windows\\csc\\*",
                  "?:\\Windows\\DigitalLocker\\*",
                  "?:\\Windows\\en-US\\*",
                  "?:\\Windows\\wlansvc\\*",
                  "?:\\Windows\\Prefetch\\*",
                  "?:\\Windows\\Fonts\\*",
                  "?:\\Windows\\diagnostics\\*",
                  "?:\\Windows\\TAPI\\*",
                  "?:\\Windows\\INF\\*",
                  "?:\\windows\\tracing\\*",
                  "?:\\windows\\IME\\*",
                  "?:\\Windows\\Performance\\*",
                  "?:\\windows\\intel\\*",
                  "?:\\windows\\ms\\*",
                  "?:\\Windows\\dot3svc\\*",
                  "?:\\Windows\\ServiceProfiles\\*",
                  "?:\\Windows\\panther\\*",
                  "?:\\Windows\\RemotePackages\\*",
                  "?:\\Windows\\OCR\\*",
                  "?:\\Windows\\appcompat\\*",
                  "?:\\Windows\\apppatch\\*",
                  "?:\\Windows\\addins\\*",
                  "?:\\Windows\\Setup\\*",
                  "?:\\Windows\\Help\\*",
                  "?:\\Windows\\SKB\\*",
                  "?:\\Windows\\Vss\\*",
                  "?:\\Windows\\Web\\*",
                  "?:\\Windows\\servicing\\*",
                  "?:\\Windows\\CbsTemp\\*",
                  "?:\\Windows\\Logs\\*",
                  "?:\\Windows\\WaaS\\*",
                  "?:\\Windows\\twain_32\\*",
                  "?:\\Windows\\ShellExperiences\\*",
                  "?:\\Windows\\ShellComponents\\*",
                  "?:\\Windows\\PLA\\*",
                  "?:\\Windows\\Migration\\*",
                  "?:\\Windows\\debug\\*",
                  "?:\\Windows\\Cursors\\*",
                  "?:\\Windows\\Containers\\*",
                  "?:\\Windows\\Boot\\*",
                  "?:\\Windows\\bcastdvr\\*",
                  "?:\\Windows\\TextInput\\*",
                  "?:\\Windows\\schemas\\*",
                  "?:\\Windows\\SchCache\\*",
                  "?:\\Windows\\Resources\\*",
                  "?:\\Windows\\rescache\\*",
                  "?:\\Windows\\Provisioning\\*",
                  "?:\\Windows\\PrintDialog\\*",
                  "?:\\Windows\\PolicyDefinitions\\*",
                  "?:\\Windows\\media\\*",
                  "?:\\Windows\\Globalization\\*",
                  "?:\\Windows\\L2Schemas\\*",
                  "?:\\Windows\\LiveKernelReports\\*",
                  "?:\\Windows\\ModemLogs\\*",
                  "?:\\Windows\\ImmersiveControlPanel\\*",
                  "?:\\$Recycle.Bin\\*",
                  "?:\\Users\\*\\AppData\\Local\\Microsoft\\Windows\\INetCache\\IE\\*"
) and not
    (process.name : "rundll32.exe" and
     process.command_line : ("*uxtheme.dll,#64*", "*PRINTUI.DLL,PrintUIEntry*", "*OpenAs_RunDLL*", "*ShowNotificationDialog*")) and not
    /* Issue #322 */
    (process.name : "rundll32.exe" and
     process.command_line : ("*cryptext.dll*",
                             "*:\\Users\\*\\Documents\\DocuShare\\*",
                             "*dfshim.dll*ShOpenVerb*",
                             "*dvpack.dll,LaunchINFSection*\\Windows\\INF\\*",
                             "*PhotoViewer.dll*ImageView_Fu*",
                             "*GeneralTel.dll,RunGeneralTelemetry*",
                             "*setupapi,InstallHinfSection*",
                             "*mshtml.dll*PrintHTML*",
                             "*setupapi.dll,InstallHinfSection*")) and not
    (process.name : "regsvr32.exe" and process.command_line : "*:\\WINDOWS\\Help\\*" and
     process.parent.executable : ("?:\\Program Files (x86)\\Hewlett-Packard\\*.exe",
                                  "?:\\Program Files\\Hewlett-Packard\\*.exe",
                                  "?:\\Program Files (x86)\\HP\\*.exe",
                                  "?:\\Program Files\\HP\\*.exe",
                                  "?:\\ProgramData\\Hewlett-Packard\\UninstallHPSA.exe",
                                  "?:\\*\\setup.exe")) and not
    (process.name : "rundll32.exe" and process.parent.name : "svchost.exe" and process.parent.args : "LocalServiceNoNetworkFirewall") and not
    (process.name : "cscript.exe" and process.args : "RemoveServerPeformanceLog" and process.args : "?:\\PerfLogs\\*" and
     process.args : "?:\\Windows\\system32\\calluxxprovider.vbs") and not

     /* Issue #535 */
    (process.name : "rundll32.exe" and
     process.args : ("?:\\Windows\\system32\\themecpl.dll,OpenThemeAction",
                     "?:\\Users\\Public\\IBM\\ClientSolutions\\Start_Programs\\Windows_*\\acsnative.dll*",
                     "?:\\WINDOWS\\System32\\shimgvw.dll,*",
                     "C:\\WINDOWS\\system32\\dsquery.dll,OpenSavedDsQuery",
                     "?:\\Program Files\\Windows Photo Viewer\\PhotoViewer.dll*",
                     "?:\\Program Files\\CopyTrans HEIC for Windows\\CopyTransHEICforWindows.dll*",
                     "?:\\WINDOWS\\system32\\ieframe.dll,OpenURL",
                     "?:\\Program Files (x86)\\Common Files\\Microsoft Shared\\VSTO\\vstoee.dll,InstallVstoSolution",
                     "?:\\Program Files\\WIBU-SYSTEMS\\System\\WibuShellExt64.dll,OpenWbc",
                     "CopyTransHEICforWindows.dll,ConvertList",
                     "C:\\Program Files (x86)\\Common Files\\ADInstruments\\ADILauncher64.dll,",
                     "C:\\Windows\\diagnostics\\system\\Printer\\UpdatePrinterDriver.dll,UpdatePrinterDriverEntry")) and not
     /* MS Visual Studio */
     process.executable : ("?:\\Program Files (x86)\\Microsoft Visual Studio\\*.exe", "?:\\Program Files (x86)\\Microsoft Visual Studio\\*.exe") and

     not (process.parent.executable : "?:\\Windows\\system32\\CompatTelRunner.exe" and process.parent.args : "-m:appraiser.dll") and
     not (process.name : "regsvr32.exe" and process.parent.name == "InstallHPSA.exe" and process.args : "?:\\Windows\\Help\\OEM\\scripts\\checkmui.dll") and
     not (process.name : "wscript.exe" and
          process.args : ("?:\\PerfLogs\\Admin\\New.PerfMon.Log.Analyzer*.vb",
                          "?:\\Program Files\\Autodesk\\HSMWorks 2023\\installpost.js",
                          "C:\\Windows\\Setup\\Scripts\\UnlockStartLayout.vbs")) and
     not (process.name : "regsvr32.exe" and process.args : ("?:\\Windows\\servicing\\LCU\\Package_for_RollupFix~*", "C:\\WINDOWS\\Twain_32\\Instrumentarium\\dsd.ocx")) and
     not (process.name : "wscript.exe" and
          process.args : ("?:\\Users\\Public\\PSAppDeployToolkit\\AppDeployToolkit_BlockAppExecutionMessage.vbs",
                          "?:\\Users\\Public\\Desktop\\*",
                          "C:\\Windows\\Setup\\Scripts\\UnlockStartLayout.vbs")) and
     not process.parent.executable : ("?:\\Program Files (x86)\\DesktopCentral_Agent\\EndpointDLP\\bin\\MEDLP.exe", 
                                      "?:\\Program Files (x86)\\Intuit\\QuickBooks *\\QBW*.EXE", 
                                      "?:\\Program Files (x86)\\pdf*\\res\\drivedir\\pdfsave.exe",
                                      "?:\\Program Files\\Beyond Compare ?\\BCompare.exe") and
     not process.executable : ("?:\\Program Files\\*\\msbuild.exe", "?:\\Program Files (x86)\\*\\MSBuild.exe") and
     not process.command_line : ("\"C:\\Windows\\System32\\wscript.exe\" C:\\Windows\\Setup\\Scripts\\ShowAllTrayIcons.vbs",  "\"C:\\WINDOWS\\System32\\WScript.exe\" \"C:\\Users\\Public\\Desktop\\MapNetworkDrives.vbs\" ")
'''

min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.005"
name = "Visual Basic"
reference = "https://attack.mitre.org/techniques/T1059/005/"

[[threat.technique.subtechnique]]
id = "T1059.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"



[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"


[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Stage 1: process

process where event.action == "start" and
  process.name : ("wscript.exe",
                  "rundll32.exe",
                  "regsvr32.exe",
                  "cmstp.exe",
                  "RegAsm.exe",
                  "installutil.exe",
                  "mshta.exe",
                  "RegSvcs.exe",
                  "msbuild.exe",
                  "msxsl.exe",
                  "xwizard.exe") and
  process.args : ("?:\\PerfLogs\\*",
                  "?:\\Users\\*\\Pictures\\*",
                  "?:\\Users\\*\\Music\\*",
                  "?:\\Users\\Public\\*",
                  "?:\\Windows\\Tasks\\*",
                  "?:\\Windows\\System32\\Tasks\\*",
                  "?:\\Intel\\*",
                  "?:\\AMD\\Temp\\*",
                  "?:\\Windows\\hp\\*",
                  "?:\\Windows\\AppReadiness\\*",
                  "?:\\Windows\\ServiceState\\*",
                  "?:\\Windows\\security\\*",
                  "?:\\Windows\\IdentityCRL\\*",
                  "?:\\Windows\\Branding\\*",
                  "?:\\Windows\\csc\\*",
                  "?:\\Windows\\DigitalLocker\\*",
                  "?:\\Windows\\en-US\\*",
                  "?:\\Windows\\wlansvc\\*",
                  "?:\\Windows\\Prefetch\\*",
                  "?:\\Windows\\Fonts\\*",
                  "?:\\Windows\\diagnostics\\*",
                  "?:\\Windows\\TAPI\\*",
                  "?:\\Windows\\INF\\*",
                  "?:\\windows\\tracing\\*",
                  "?:\\windows\\IME\\*",
                  "?:\\Windows\\Performance\\*",
                  "?:\\windows\\intel\\*",
                  "?:\\windows\\ms\\*",
                  "?:\\Windows\\dot3svc\\*",
                  "?:\\Windows\\ServiceProfiles\\*",
                  "?:\\Windows\\panther\\*",
                  "?:\\Windows\\RemotePackages\\*",
                  "?:\\Windows\\OCR\\*",
                  "?:\\Windows\\appcompat\\*",
                  "?:\\Windows\\apppatch\\*",
                  "?:\\Windows\\addins\\*",
                  "?:\\Windows\\Setup\\*",
                  "?:\\Windows\\Help\\*",
                  "?:\\Windows\\SKB\\*",
                  "?:\\Windows\\Vss\\*",
                  "?:\\Windows\\Web\\*",
                  "?:\\Windows\\servicing\\*",
                  "?:\\Windows\\CbsTemp\\*",
                  "?:\\Windows\\Logs\\*",
                  "?:\\Windows\\WaaS\\*",
                  "?:\\Windows\\twain_32\\*",
                  "?:\\Windows\\ShellExperiences\\*",
                  "?:\\Windows\\ShellComponents\\*",
                  "?:\\Windows\\PLA\\*",
                  "?:\\Windows\\Migration\\*",
                  "?:\\Windows\\debug\\*",
                  "?:\\Windows\\Cursors\\*",
                  "?:\\Windows\\Containers\\*",
                  "?:\\Windows\\Boot\\*",
                  "?:\\Windows\\bcastdvr\\*",
                  "?:\\Windows\\TextInput\\*",
                  "?:\\Windows\\schemas\\*",
                  "?:\\Windows\\SchCache\\*",
                  "?:\\Windows\\Resources\\*",
                  "?:\\Windows\\rescache\\*",
                  "?:\\Windows\\Provisioning\\*",
                  "?:\\Windows\\PrintDialog\\*",
                  "?:\\Windows\\PolicyDefinitions\\*",
                  "?:\\Windows\\media\\*",
                  "?:\\Windows\\Globalization\\*",
                  "?:\\Windows\\L2Schemas\\*",
                  "?:\\Windows\\LiveKernelReports\\*",
                  "?:\\Windows\\ModemLogs\\*",
                  "?:\\Windows\\ImmersiveControlPanel\\*",
                  "?:\\$Recycle.Bin\\*",
                  "?:\\Users\\*\\AppData\\Local\\Microsoft\\Windows\\INetCache\\IE\\*"
) and not
    (process.name : "rundll32.exe" and
     process.command_line : ("*uxtheme.dll,#64*", "*PRINTUI.DLL,PrintUIEntry*", "*OpenAs_RunDLL*", "*ShowNotificationDialog*")) and not
    (process.name : "rundll32.exe" and
     process.command_line : ("*cryptext.dll*",
                             "*:\\Users\\*\\Documents\\DocuShare\\*",
                             "*dfshim.dll*ShOpenVerb*",
                             "*dvpack.dll,LaunchINFSection*\\Windows\\INF\\*",
                             "*PhotoViewer.dll*ImageView_Fu*",
                             "*GeneralTel.dll,RunGeneralTelemetry*",
                             "*setupapi,InstallHinfSection*",
                             "*mshtml.dll*PrintHTML*",
                             "*setupapi.dll,InstallHinfSection*")) and not
    (process.name : "regsvr32.exe" and process.command_line : "*:\\WINDOWS\\Help\\*" and
     process.parent.executable : ("?:\\Program Files (x86)\\Hewlett-Packard\\*.exe",
                                  "?:\\Program Files\\Hewlett-Packard\\*.exe",
                                  "?:\\Program Files (x86)\\HP\\*.exe",
                                  "?:\\Program Files\\HP\\*.exe",
                                  "?:\\ProgramData\\Hewlett-Packard\\UninstallHPSA.exe",
                                  "?:\\*\\setup.exe")) and not
    (process.name : "rundll32.exe" and process.parent.name : "svchost.exe" and process.parent.args : "LocalServiceNoNetworkFirewall") and not
    (process.name : "cscript.exe" and process.args : "RemoveServerPeformanceLog" and process.args : "?:\\PerfLogs\\*" and
     process.args : "?:\\Windows\\system32\\calluxxprovider.vbs") and not
    (process.name : "rundll32.exe" and
     process.args : ("?:\\Windows\\system32\\themecpl.dll,OpenThemeAction",
                     "?:\\Users\\Public\\IBM\\ClientSolutions\\Start_Programs\\Windows_*\\acsnative.dll*",
                     "?:\\WINDOWS\\System32\\shimgvw.dll,*",
                     "C:\\WINDOWS\\system32\\dsquery.dll,OpenSavedDsQuery",
                     "?:\\Program Files\\Windows Photo Viewer\\PhotoViewer.dll*",
                     "?:\\Program Files\\CopyTrans HEIC for Windows\\CopyTransHEICforWindows.dll*",
                     "?:\\WINDOWS\\system32\\ieframe.dll,OpenURL",
                     "?:\\Program Files (x86)\\Common Files\\Microsoft Shared\\VSTO\\vstoee.dll,InstallVstoSolution",
                     "?:\\Program Files\\WIBU-SYSTEMS\\System\\WibuShellExt64.dll,OpenWbc",
                     "CopyTransHEICforWindows.dll,ConvertList",
                     "C:\\Program Files (x86)\\Common Files\\ADInstruments\\ADILauncher64.dll,",
                     "C:\\Windows\\diagnostics\\system\\Printer\\UpdatePrinterDriver.dll,UpdatePrinterDriverEntry")) and not
     process.executable : ("?:\\Program Files (x86)\\Microsoft Visual Studio\\*.exe", "?:\\Program Files (x86)\\Microsoft Visual Studio\\*.exe") and
     not (process.parent.executable : "?:\\Windows\\system32\\CompatTelRunner.exe" and process.parent.args : "-m:appraiser.dll") and
     not (process.name : "regsvr32.exe" and process.parent.name == "InstallHPSA.exe" and process.args : "?:\\Windows\\Help\\OEM\\scripts\\checkmui.dll") and
     not (process.name : "wscript.exe" and
          process.args : ("?:\\PerfLogs\\Admin\\New.PerfMon.Log.Analyzer*.vb",
                          "?:\\Program Files\\Autodesk\\HSMWorks 2023\\installpost.js",
                          "C:\\Windows\\Setup\\Scripts\\UnlockStartLayout.vbs")) and
     not (process.name : "regsvr32.exe" and process.args : ("?:\\Windows\\servicing\\LCU\\Package_for_RollupFix~*", "C:\\WINDOWS\\Twain_32\\Instrumentarium\\dsd.ocx")) and
     not (process.name : "wscript.exe" and
          process.args : ("?:\\Users\\Public\\PSAppDeployToolkit\\AppDeployToolkit_BlockAppExecutionMessage.vbs",
                          "?:\\Users\\Public\\Desktop\\*",
                          "C:\\Windows\\Setup\\Scripts\\UnlockStartLayout.vbs")) and
     not process.parent.executable : ("?:\\Program Files (x86)\\DesktopCentral_Agent\\EndpointDLP\\bin\\MEDLP.exe",
                                      "?:\\Program Files (x86)\\Intuit\\QuickBooks *\\QBW*.EXE",
                                      "?:\\Program Files (x86)\\pdf*\\res\\drivedir\\pdfsave.exe",
                                      "?:\\Program Files\\Beyond Compare ?\\BCompare.exe") and
     not process.executable : ("?:\\Program Files\\*\\msbuild.exe", "?:\\Program Files (x86)\\*\\MSBuild.exe") and
     not process.command_line : ("\"C:\\Windows\\System32\\wscript.exe\" C:\\Windows\\Setup\\Scripts\\ShowAllTrayIcons.vbs",  "\"C:\\WINDOWS\\System32\\WScript.exe\" \"C:\\Users\\Public\\Desktop\\MapNetworkDrives.vbs\" ")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq value:"start"
process.argswildcard
  • ?:\$Recycle.Bin\*
  • ?:\AMD\Temp\*
  • ?:\Intel\*
  • ?:\PerfLogs\*
  • ?:\Users\*\AppData\Local\Microsoft\Windows\INetCache\IE\*
  • ?:\Users\*\Music\*
  • ?:\Users\*\Pictures\*
  • ?:\Users\Public\* corpus 6 (elastic 6)
  • ?:\Windows\AppReadiness\*
  • ?:\Windows\Boot\*
  • ?:\Windows\Branding\*
  • ?:\Windows\CbsTemp\*
  • ?:\Windows\Containers\*
  • ?:\Windows\Cursors\*
  • ?:\Windows\DigitalLocker\*
  • ?:\Windows\Fonts\*
  • ?:\Windows\Globalization\*
  • ?:\Windows\Help\*
  • ?:\Windows\INF\*
  • ?:\Windows\IdentityCRL\*
  • ?:\Windows\ImmersiveControlPanel\*
  • ?:\Windows\L2Schemas\*
  • ?:\Windows\LiveKernelReports\*
  • ?:\Windows\Logs\*
  • ?:\Windows\Migration\*
  • ?:\Windows\ModemLogs\*
  • ?:\Windows\OCR\*
  • ?:\Windows\PLA\*
  • ?:\Windows\Performance\*
  • ?:\Windows\PolicyDefinitions\*
  • ?:\Windows\Prefetch\*
  • ?:\Windows\PrintDialog\*
  • ?:\Windows\Provisioning\*
  • ?:\Windows\RemotePackages\*
  • ?:\Windows\Resources\*
  • ?:\Windows\SKB\*
  • ?:\Windows\SchCache\*
  • ?:\Windows\ServiceProfiles\*
  • ?:\Windows\ServiceState\*
  • ?:\Windows\Setup\*
  • +31 more values (see full rule source)
field:"process.args" kind:wildcard
process.namewildcard
  • RegAsm.exe corpus 25 (elastic 24, splunk 1)
  • RegSvcs.exe corpus 22 (elastic 21, splunk 1)
  • cmstp.exe corpus 25 (elastic 25)
  • installutil.exe corpus 36 (elastic 32, splunk 4)
  • msbuild.exe corpus 39 (elastic 36, splunk 3)
  • mshta.exe corpus 84 (elastic 80, splunk 4)
  • msxsl.exe corpus 22 (elastic 22)
  • regsvr32.exe corpus 74 (elastic 69, splunk 5)
  • rundll32.exe corpus 123 (elastic 100, splunk 23)
  • wscript.exe corpus 84 (elastic 82, splunk 1, kusto 1)
  • xwizard.exe corpus 16 (elastic 16)
field:"process_basename" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argseq?:\Windows\Help\OEM\scripts\checkmui.dllexcludes:process.args field:"process.args" value:"?:\Windows\Help\OEM\scripts\checkmui.dll"
process.nameeqregsvr32.exeexcludes:process.name field:"process.name" value:"regsvr32.exe"
process.parent.nameeqInstallHPSA.exeexcludes:process.parent.name field:"process.parent.name" value:"InstallHPSA.exe"
process.argseq?:\Windows\system32\calluxxprovider.vbsexcludes:process.args field:"process.args" value:"?:\Windows\system32\calluxxprovider.vbs"
process.argseqRemoveServerPeformanceLogexcludes:process.args field:"process.args" value:"RemoveServerPeformanceLog"
process.argsstarts_with?:\PerfLogs\excludes:process.args field:"process.args" value:"?:\PerfLogs\"
process.nameeqcscript.exeexcludes:process.name field:"process.name" value:"cscript.exe"
process.argswildcard?:\PerfLogs\Admin\New.PerfMon.Log.Analyzer*.vb, ?:\Program Files\Autodesk\HSMWorks 2023\installpost.js, C:\Windows\Setup\Scripts\UnlockStartLayout.vbsexcludes:process.args field:"process.args" value:"?:\PerfLogs\Admin\New.PerfMon.Log.Analyzer*.vb" field:"process.args" value:"?:\Program Files\Autodesk\HSMWorks 2023\installpost.js" field:"process.args" value:"C:\Windows\Setup\Scripts\UnlockStartLayout.vbs"
process.nameeqwscript.exeexcludes:process.name field:"process.name" value:"wscript.exe"
process.argswildcard?:\Users\Public\PSAppDeployToolkit\AppDeployToolkit_BlockAppExecutionMessage.vbs, ?:\Users\Public\Desktop\*, C:\Windows\Setup\Scripts\UnlockStartLayout.vbsexcludes:process.args field:"process.args" value:"?:\Users\Public\PSAppDeployToolkit\AppDeployToolkit_BlockAppExecutionMessage.vbs" field:"process.args" value:"?:\Users\Public\Desktop\*" field:"process.args" value:"C:\Windows\Setup\Scripts\UnlockStartLayout.vbs"
process.argswildcard?:\Windows\servicing\LCU\Package_for_RollupFix~*, C:\WINDOWS\Twain_32\Instrumentarium\dsd.ocxexcludes:process.args field:"process.args" value:"?:\Windows\servicing\LCU\Package_for_RollupFix~*" field:"process.args" value:"C:\WINDOWS\Twain_32\Instrumentarium\dsd.ocx"
process.argswildcard?:\Windows\system32\themecpl.dll,OpenThemeAction, ?:\Users\Public\IBM\ClientSolutions\Start_Programs\Windows_*\acsnative.dll*, ?:\WINDOWS\System32\shimgvw.dll,*, C:\WINDOWS\system32\dsquery.dll,OpenSavedDsQuery, ?:\Program Files\Windows Photo Viewer\PhotoViewer.dll*, ?:\Program Files\CopyTrans HEIC for Windows\CopyTransHEICforWindows.dll*, ?:\WINDOWS\system32\ieframe.dll,OpenURL, ?:\Program Files (x86)\Common Files\Microsoft Shared\VSTO\vstoee.dll,InstallVstoSolution, ?:\Program Files\WIBU-SYSTEMS\System\WibuShellExt64.dll,OpenWbc, CopyTransHEICforWindows.dll,ConvertList, C:\Program Files (x86)\Common Files\ADInstruments\ADILauncher64.dll,, C:\Windows\diagnostics\system\Printer\UpdatePrinterDriver.dll,UpdatePrinterDriverEntryexcludes:process.args
process.nameeqrundll32.exeexcludes:process.name field:"process.name" value:"rundll32.exe"
process.command_linematch:\WINDOWS\Help\excludes:process.command_line field:"process.command_line" value:":\WINDOWS\Help\"
process.parent.executablewildcard?:\Program Files (x86)\Hewlett-Packard\*.exe, ?:\Program Files\Hewlett-Packard\*.exe, ?:\Program Files (x86)\HP\*.exe, ?:\Program Files\HP\*.exe, ?:\ProgramData\Hewlett-Packard\UninstallHPSA.exe, ?:\*\setup.exeexcludes:process.parent.executable
process.command_linematchuxtheme.dll,#64, PRINTUI.DLL,PrintUIEntry, OpenAs_RunDLL, ShowNotificationDialogexcludes:process.command_line
process.command_linewildcard*cryptext.dll*, *:\Users\*\Documents\DocuShare\*, *dfshim.dll*ShOpenVerb*, *dvpack.dll,LaunchINFSection*\Windows\INF\*, *PhotoViewer.dll*ImageView_Fu*, *GeneralTel.dll,RunGeneralTelemetry*, *setupapi,InstallHinfSection*, *mshtml.dll*PrintHTML*, *setupapi.dll,InstallHinfSection*excludes:process.command_line
process.parent.argseqLocalServiceNoNetworkFirewallexcludes:process.parent.args field:"process.parent.args" value:"LocalServiceNoNetworkFirewall"
process.parent.nameeqsvchost.exeexcludes:process.parent.name field:"process.parent.name" value:"svchost.exe"
process.parent.argseq-m:appraiser.dllexcludes:process.parent.args field:"process.parent.args" value:"-m:appraiser.dll"
process.parent.executableeq?:\Windows\system32\CompatTelRunner.exeexcludes:process.parent.executable field:"process.parent.executable" value:"?:\Windows\system32\CompatTelRunner.exe"
process.command_lineeq"C:\Windows\System32\wscript.exe" C:\Windows\Setup\Scripts\ShowAllTrayIcons.vbs, "C:\WINDOWS\System32\WScript.exe" "C:\Users\Public\Desktop\MapNetworkDrives.vbs" excludes:process.command_line
process.executablewildcard?:\Program Files (x86)\Microsoft Visual Studio\*.exe, ?:\Program Files (x86)\Microsoft Visual Studio\*.exeexcludes:process.executable field:"process.executable" value:"?:\Program Files (x86)\Microsoft Visual Studio\*.exe" field:"process.executable" value:"?:\Program Files (x86)\Microsoft Visual Studio\*.exe"
process.executablewildcard?:\Program Files\*\msbuild.exe, ?:\Program Files (x86)\*\MSBuild.exeexcludes:process.executable field:"process.executable" value:"?:\Program Files\*\msbuild.exe" field:"process.executable" value:"?:\Program Files (x86)\*\MSBuild.exe"
process.parent.executablewildcard?:\Program Files (x86)\DesktopCentral_Agent\EndpointDLP\bin\MEDLP.exe, ?:\Program Files (x86)\Intuit\QuickBooks *\QBW*.EXE, ?:\Program Files (x86)\pdf*\res\drivedir\pdfsave.exe, ?:\Program Files\Beyond Compare ?\BCompare.exeexcludes:process.parent.executable

Execution of a File Downloaded via Windows OpenSSH

#
Time window
2m
Source
github.com/elastic/protections-artifacts

Identifies the execution of a file downloaded via SSH Windows binaries. Adversaries may abuse those utilities to download remote content.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the execution of a file downloaded via SSH Windows binaries. Adversaries may abuse those utilities to
download remote content.
"""
id = "2d8c7caa-a661-4989-be4f-289e4678bd5a"
license = "Elastic License v2"
name = "Execution of a File Downloaded via Windows OpenSSH"
os_list = ["windows"]
version = "1.0.2"

query = '''
sequence with maxspan=2m
 [file where event.action != "deletion" and
  process.executable : ("?:\\Windows\\System32\\OpenSSH\\scp.exe", "?:\\Windows\\System32\\OpenSSH\\ssh.exe") and
  (file.extension : ("exe", "pif", "scr", "js", "vbs", "wsh", "hta", "cpl", "jse", "vbe", "bat", "cmd", "dll", "msi", "ps1") or
   file.Ext.header_bytes : "4d5a*")] as event0
 [any where event.category in ("process", "library") and
   (
   (event.action == "start" and process.name : ("wscript.exe", "cscript.exe", "mshta.exe", "rundll32.exe", "regsvr32.exe") and
    stringcontains~(process.command_line, event0.file.name)) or

   (event.action == "load" and (dll.code_signature.trusted == false or dll.code_signature.exists == false) and
    stringcontains~(event0.file.path, dll.path))
    )]
'''

min_endpoint_version = "8.4.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.005"
name = "Visual Basic"
reference = "https://attack.mitre.org/techniques/T1059/005/"

[[threat.technique.subtechnique]]
id = "T1059.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"



[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"
[[threat.technique.subtechnique]]
id = "T1218.005"
name = "Mshta"
reference = "https://attack.mitre.org/techniques/T1218/005/"



[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1105"
name = "Ingress Tool Transfer"
reference = "https://attack.mitre.org/techniques/T1105/"


[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"

[internal]
min_endpoint_version = "8.4.0"

Stages and Predicates

Stage 1: file

[file where event.action != "deletion" and
  process.executable : ("?:\\Windows\\System32\\OpenSSH\\scp.exe", "?:\\Windows\\System32\\OpenSSH\\ssh.exe") and
  (file.extension : ("exe", "pif", "scr", "js", "vbs", "wsh", "hta", "cpl", "jse", "vbe", "bat", "cmd", "dll", "msi", "ps1") or
   file.Ext.header_bytes : "4d5a*")] as event0

Stage 2: any

[any where event.category in ("process", "library") and
   (
   (event.action == "start" and process.name : ("wscript.exe", "cscript.exe", "mshta.exe", "rundll32.exe", "regsvr32.exe") and
    stringcontains~(process.command_line, event0.file.name)) or

   (event.action == "load" and (dll.code_signature.trusted == false or dll.code_signature.exists == false) and
    stringcontains~(event0.file.path, dll.path))
    )]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
dll.code_signature.existseq
  • false transforms: boolean corpus 22 (elastic 22)
field:"dll.code_signature.exists" kind:eq value:"false"
dll.code_signature.trustedeq
  • false transforms: boolean corpus 21 (elastic 21)
field:"dll.code_signature.trusted" kind:eq value:"false"
event.actioneq
  • load corpus 23 (elastic 23)
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq
event.actionne
  • deletion corpus 90 (elastic 90)
field:"EventType" kind:ne value:"deletion"
event.categoryin
  • library corpus 6 (elastic 6)
  • process corpus 7 (elastic 7)
field:"event.category" kind:in
event0.file.pathcontains
  • dll.path (field reference)
field:"event0.file.path" kind:contains value:"dll.path"
file.Ext.header_byteswildcard
  • 4d5a* corpus 45 (elastic 45)
field:"file.Ext.header_bytes" kind:wildcard value:"4d5a*"
file.extensionwildcard
  • bat corpus 13 (elastic 13)
  • cmd corpus 15 (elastic 15)
  • cpl corpus 19 (elastic 19)
  • dll corpus 32 (elastic 32)
  • exe corpus 32 (elastic 32)
  • hta corpus 20 (elastic 20)
  • js corpus 22 (elastic 22)
  • jse corpus 18 (elastic 18)
  • msi corpus 3 (elastic 3)
  • pif corpus 18 (elastic 18)
  • ps1 corpus 9 (elastic 9)
  • scr corpus 17 (elastic 17)
  • vbe corpus 18 (elastic 18)
  • vbs corpus 19 (elastic 19)
  • wsh corpus 16 (elastic 16)
field:"file.extension" kind:wildcard
process.command_linecontains
  • event0.file.name (field reference)
field:"CommandLine" kind:contains value:"event0.file.name"
process.executablewildcard
  • ?:\Windows\System32\OpenSSH\scp.exe
  • ?:\Windows\System32\OpenSSH\ssh.exe corpus 3 (elastic 3)
field:"Image" kind:wildcard
process.namewildcard
  • cscript.exe corpus 68 (elastic 66, splunk 2)
  • mshta.exe corpus 84 (elastic 80, splunk 4)
  • regsvr32.exe corpus 74 (elastic 69, splunk 5)
  • rundll32.exe corpus 123 (elastic 100, splunk 23)
  • wscript.exe corpus 84 (elastic 82, splunk 1, kusto 1)
field:"process_basename" kind:wildcard

High Number of Protected Branch Force Pushes by User

#
Status
production
Severity
medium
Time window
9m
Group by
user.name
Author
Elastic
Source
github.com/elastic/detection-rules

Detects a high number of force push actions to protected branches by a single user within a short time frame. Adversaries may perform force pushes to overwrite commit history on protected branches, potentially leading to data loss or disruption of development workflows.

MITRE ATT&CK Coverage

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2025/12/16"
integration = ["github"]
maturity = "production"
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"
updated_date = "2026/07/20"

[rule]
author = ["Elastic"]
description = """
Detects a high number of force push actions to protected branches by a single user within a short
time frame. Adversaries may perform force pushes to overwrite commit history on protected branches,
potentially leading to data loss or disruption of development workflows.
"""
from = "now-9m"
interval = "8m"
language = "esql"
license = "Elastic License v2"
name = "High Number of Protected Branch Force Pushes by User"
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 High Number of Protected Branch Force Pushes by User

This rule flags a single user performing many force pushes to protected branches in a short window, signaling aggressive history rewrites on critical repositories. Such activity can erase commits, hide unauthorized changes, and disrupt builds or releases, indicating potential data destruction or sabotage. Example: a compromised maintainer acquires elevated access and repeatedly force-pushes rewritten history to the main branch to purge prior commits, remove security fixes, and introduce a backdoor while bypassing merge protections.

### Possible investigation steps

- Verify the user's current and recent org/repo roles and bypass permissions, along with any recent elevation, SSO changes, or new PAT/GitHub App installations linked to the account.
- Enumerate impacted repositories and protected branches, then reconstruct the overwritten history by comparing before/after SHAs from audit logs or local mirrors to determine what commits were removed or rewritten.
- Assess intent and legitimacy by contacting repo owners and checking change tickets or maintenance windows for planned history rewrites, and suspend override permissions if unplanned while preserving forensic evidence.
- Analyze sign-in and authentication telemetry around the events (IP, geo, MFA status, device, OAuth/PAT/App identifiers, off-hours) to spot account compromise indicators and pivot to other activity by the same token.
- Review diffs of the resulting branch heads and CI/CD artifacts to detect malicious changes (e.g., removed security fixes, inserted secrets/backdoors), and check for anomalous releases or workflows triggered by the rewritten commits.

### False positive analysis

- An authorized maintainer conducts a planned history rewrite (rebases/resets to remove problematic commits) across protected branches in multiple repositories, legitimately invoking policy overrides and issuing many force pushes in quick succession.
- A release owner executes an emergency rollback by resetting protected branches to a known-good commit across several repositories, causing repeated, intentional force pushes and protected-branch overrides.

### Response and remediation

- Immediately contain by removing the user from repo admin/maintain teams, revoking all active PATs/OAuth/App tokens linked to the account, and updating branch protection on affected branches to disallow force pushes and restrict pushes to a small trusted group.
- Freeze each impacted protected branch by creating an annotated tag at the last known-good commit SHA prior to the force pushes and temporarily pausing CI/CD workflows that build from those branch heads.
- Recover by restoring each branch head to the last known-good commit or signed tag from a trusted mirror/backup, verifying the target SHA, and re-enabling protections and required status checks after integrity confirmation.
- Eradicate unauthorized changes by diffing the pre-override and post-override branch heads, reverting malicious edits, rotating repository secrets referenced in code/workflows, and removing suspicious GitHub Apps installed by the user.
- Escalate to incident response and legal if any overwritten history includes production release branches or signed tags, if the user denies authorization, or if pushes originated from a new token/App unknown to repo owners.
- Harden by enforcing rulesets that block force pushes and require linear history on main and release/* branches, enabling CODEOWNERS-required reviews and signed commits, limiting bypass permissions to a small admin group, and using deploy keys or CI bots with short-lived tokens for pushes.
"""
references = [
    "https://www.wiz.io/blog/shai-hulud-2-0-ongoing-supply-chain-attack",
    "https://trigger.dev/blog/shai-hulud-postmortem",
    "https://posthog.com/blog/nov-24-shai-hulud-attack-post-mortem",
]
risk_score = 47
rule_id = "0428c618-27f5-4d94-99e6-b254585aba69"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Use Case: Threat Detection",
    "Tactic: Impact",
    "Tactic: Exfiltration",
    "Data Source: Github",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-github.audit-* metadata _id, _index, _version
| where
  data_stream.dataset == "github.audit" and
  event.type == "change" and
  event.action == "protected_branch.policy_override" and
  github.category == "protected_branch" and
  mv_contains(github.reasons.code, "force_push")
| stats
  Esql.event_count = COUNT(*),
  Esql.github_org_values = values(github.org),
  Esql.github_repo_values = values(github.repo),
  Esql.github_overridden_codes_values = values(github.overridden_codes),
  Esql.github_reasons_code_values = values(github.reasons.code),
  Esql.github_reasons_message_values = values(github.reasons.message),
  Esql.user_name_values = values(user.name),
  Esql.agent_id_values = values(agent.id),
  Esql.data_stream_dataset_values = values(data_stream.dataset),
  Esql.data_stream_namespace_values = values(data_stream.namespace)

  by user.name

| keep Esql.*

| where
  Esql.event_count >= 10
'''

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1485"
name = "Data Destruction"
reference = "https://attack.mitre.org/techniques/T1485/"

[[rule.threat.technique]]
id = "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 = "T1020"
name = "Automated Exfiltration"
reference = "https://attack.mitre.org/techniques/T1020/"

[[rule.threat.technique]]
id = "T1567"
name = "Exfiltration Over Web Service"
reference = "https://attack.mitre.org/techniques/T1567/"

[[rule.threat.technique.subtechnique]]
id = "T1567.001"
name = "Exfiltration to Code Repository"
reference = "https://attack.mitre.org/techniques/T1567/001/"

[rule.threat.tactic]
id = "TA0010"
name = "Exfiltration"
reference = "https://attack.mitre.org/tactics/TA0010/"

Stages and Predicates

Stage 1: from

from logs-github.audit-* metadata _id, _index, _version

Stage 2: where

| where
  data_stream.dataset == "github.audit" and
  event.type == "change" and
  event.action == "protected_branch.policy_override" and
  github.category == "protected_branch" and
  mv_contains(github.reasons.code, "force_push")

Stage 3: stats

| stats
  Esql.event_count = COUNT(*),
  Esql.github_org_values = values(github.org),
  Esql.github_repo_values = values(github.repo),
  Esql.github_overridden_codes_values = values(github.overridden_codes),
  Esql.github_reasons_code_values = values(github.reasons.code),
  Esql.github_reasons_message_values = values(github.reasons.message),
  Esql.user_name_values = values(user.name),
  Esql.agent_id_values = values(agent.id),
  Esql.data_stream_dataset_values = values(data_stream.dataset),
  Esql.data_stream_namespace_values = values(data_stream.namespace)

  by user.name

Stage 4: keep

| keep Esql.*

Stage 5: where

| where
  Esql.event_count >= 10

Indicators

These rows show field, operator, and value matches.

Output Fields

These fields are emitted when the rule matches.

FieldSource
Esql.*KEEP Esql.*

Initial Access via File Upload Followed by GET Request

#
Status
production
Severity
medium
Time window
5m
Sequence by
agent.id
Author
Elastic
Source
github.com/elastic/detection-rules

This rule detects potential initial access activity where an adversary uploads a web shell or malicious script to a web server via a file upload mechanism (e.g., through a web form using multipart/form-data), followed by a GET or POST request to access the uploaded file. By checking the body content of HTTP requests for file upload indicators such as "Content-Disposition: form-data" and "filename=", the rule identifies suspicious upload activities. This sequence of actions is commonly used by attackers to gain and maintain access to compromised web servers.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2025/11/27"
integration = ["endpoint", "network_traffic"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
This rule detects potential initial access activity where an adversary uploads a web shell or malicious script
to a web server via a file upload mechanism (e.g., through a web form using multipart/form-data), followed by
a GET or POST request to access the uploaded file. By checking the body content of HTTP requests for file upload
indicators such as "Content-Disposition: form-data" and "filename=", the rule identifies suspicious upload
activities. This sequence of actions is commonly used by attackers to gain and maintain access to compromised web
servers.
"""
from = "now-9m"
index = ["logs-endpoint.events.*", "logs-network_traffic.*"]
language = "eql"
license = "Elastic License v2"
name = "Initial Access via File Upload Followed by GET Request"
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 Initial Access via File Upload Followed by GET Request

This rule flags a common initial-access pattern: a multipart/form-data upload that drops a dynamic web script on a server, followed shortly by a request to execute that file and establish a foothold. Attackers exploit a permissive upload form to plant shell.php or shell.jsp in an uploads or temp directory, then immediately request it to spawn a web shell, enumerate files, and run commands—often leveraging redirects or 2xx/3xx responses that indicate successful placement and access.

### Possible investigation steps

- Correlate the upload transaction with the server-side file creation and the subsequent access to the same resource, matching timestamps, source IP, and path, and follow any redirects to the final executed file.
- Retrieve the uploaded artifact from disk, verify it sits in a web-accessible location, inspect content for web shell traits (eval/system/exec, obfuscation, password gates), and record hashes.
- Examine server process telemetry immediately after the access for interpreter or shell spawns and unexpected outbound connections originating from web server workers.
- Review application logs and access context to determine whether the upload was authenticated, which account or session performed it, and whether user-agent, referer, or headers deviate from normal clients.
- Broaden the timeline to identify related uploads, file renames, or repeated requests from the same actor, including parameterized calls that suggest command execution or directory enumeration.

### False positive analysis

- An authenticated administrator installs a legitimate plugin or module via the application’s upload form, which unpacks or renames .php or .jsp files and then auto-loads a setup page, producing the multipart upload, file creation/rename, and immediate GET pattern.
- Automated deployment or QA routines upload and deploy a .war or server-side script through a web-based admin interface and then perform health-check or warm-up requests, resulting in the same multipart upload, server-side file creation, and follow-up GET sequence.

### Response and remediation

- Immediately block access to the uploaded script that was invoked via GET/POST (e.g., /uploads/shell.php) and the source IPs that executed it, restrict the site to allowlisted IPs or maintenance mode, and temporarily disable the upload endpoint.
- Quarantine and remove the uploaded web shell and any additional executable scripts or WARs in web-accessible directories (uploads, webroot, temp), terminate interpreter or shell processes spawned by the web server account (www-data/nginx/w3wp/tomcat), and revert malicious .htaccess/web.config rewrites.
- Hunt for persistence and lateral-movement artifacts created after the upload, including recent .php/.jsp/.cgi file creations or renames in static asset folders, cron/systemd tasks, startup scripts, unauthorized admin users or plugins, and remove them.
- Restore altered application files from known-good backups or redeploy a clean container/VM, rotate database and API credentials stored in config files or environment variables, invalidate active sessions, and only re-enable uploads after confirming execution is blocked in upload directories.
- Escalate to incident command and privacy/legal if you observe command execution parameters on the uploaded page (?cmd=, ?exec=), shells spawning (/bin/sh, powershell.exe), database dumps, or outbound callbacks from web server processes to external hosts.
- Harden by storing uploads outside the webroot, denying execution in upload paths (disable PHP/CGI handlers and set noexec permissions), enforcing strict extension/MIME allowlists and AV/sandbox scanning for multipart/form-data, enabling file-integrity alerts on new .php/.jsp in served paths, and deploying WAF rules to block direct requests to uploaded executables.
"""
risk_score = 47
rule_id = "1d306bf0-7bcf-4acd-83fd-042f5711acc9"
setup = """## Setup

This rule requires data coming in from both Elastic Defend (for file events) and Network Packet Capture integrations (for HTTP traffic analysis).

### Network Packet Capture Integration Setup

**IMPORTANT**: This rule requires HTTP request body capture to be enabled in order to detect the multipart/form-data content containing WebKitFormBoundary indicators. The network traffic integration must be configured to capture HTTP request bodies for POST requests with `multipart/form-data` content type.

To enable HTTP request body capture, follow these steps:
1. Navigate to the Fleet policy leveraging the Network Packet Capture integration in Kibana.
2. Locate and select the "Network Packet Capture" integration, and edit the integration.
3. Locate "Change Default", and scroll down to the "HTTP" section.
4. Enable the "HTTP" toggle to capture HTTP traffic, add the correct ports for your web application, and click "advanced options".
5. Edit the integration settings to enable HTTP request body capture for POST requests with `multipart/form-data` content type.
6. Save the integration configuration and wait for the policy to deploy to the agents.
"""
severity = "medium"
tags = [
    "Domain: Endpoint",
    "Domain: Web",
    "Domain: Network",
    "OS: Linux",
    "OS: Windows",
    "OS: macOS",
    "Use Case: Threat Detection",
    "Tactic: Initial Access",
    "Tactic: Persistence",
    "Data Source: Elastic Defend",
    "Data Source: Network Traffic",
    "Resources: Investigation Guide",
]
type = "eql"
query = '''
sequence by agent.id with maxspan=5m
  [network where
   data_stream.dataset == "network_traffic.http" and
   http.request.method in ("POST", "PUT") and
   /* We can restrict to 200 in the future, but I prefer to broaden the scope and decrease it later if necessary */
   http.response.status_code in (200, 201, 204, 301, 302, 303, 409) and
   /* These should detect most common file upload activities, adhering to browser standards */
   http.request.body.content like "*Content-Disposition: form-data*" and
   http.request.body.content like "*filename=*"
   /* May add a lower/upper boundary limit to reduce FPs in the future, e.g.
   and http.request.body.bytes >= 500
   */
  ]
  [file where
   data_stream.dataset == "endpoint.events.file" and
   event.action in ("creation", "rename") and
   file.extension in ("php", "phtml", "pht", "php5", "asp", "aspx", "jsp", "jspx", "war", "cgi")
   /* We can add file.path values here in the future, if telemetry is noisy */
  ]
  [network where
   data_stream.dataset == "network_traffic.http" and
   http.request.method in ("GET", "POST") and
   /* we may restrict to 200, but keeping it broader right now */
   http.response.status_code >= 200 and http.response.status_code < 600 and
   url.extension in ("php", "phtml", "pht", "php5", "asp", "aspx", "jsp", "jspx", "war", "cgi")
  ]
'''

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1190"
name = "Exploit Public-Facing Application"
reference = "https://attack.mitre.org/techniques/T1190/"

[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 = "T1505"
name = "Server Software Component"
reference = "https://attack.mitre.org/techniques/T1505/"

[[rule.threat.technique.subtechnique]]
id = "T1505.003"
name = "Web Shell"
reference = "https://attack.mitre.org/techniques/T1505/003/"

[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1105"
name = "Ingress Tool Transfer"
reference = "https://attack.mitre.org/techniques/T1105/"

[rule.threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"

Stages and Predicates

Ordered sequence: each step below must occur in order within 5m, correlated by agent.id.

Stage 1: network

[network where
   data_stream.dataset == "network_traffic.http" and
   http.request.method in ("POST", "PUT") and
   http.response.status_code in (200, 201, 204, 301, 302, 303, 409) and
   http.request.body.content like "*Content-Disposition: form-data*" and
   http.request.body.content like "*filename=*"
   /* May add a lower/upper boundary limit to reduce FPs in the future, e.g.
   and http.request.body.bytes >= 500
   */
  ]

Stage 2: file

[file where
   data_stream.dataset == "endpoint.events.file" and
   event.action in ("creation", "rename") and
   file.extension in ("php", "phtml", "pht", "php5", "asp", "aspx", "jsp", "jspx", "war", "cgi")
  ]

Stage 3: network

[network where
   data_stream.dataset == "network_traffic.http" and
   http.request.method in ("GET", "POST") and
   http.response.status_code >= 200 and http.response.status_code < 600 and
   url.extension in ("php", "phtml", "pht", "php5", "asp", "aspx", "jsp", "jspx", "war", "cgi")
  ]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
data_stream.dataseteq
  • endpoint.events.file corpus 2 (elastic 2)
  • network_traffic.http corpus 2 (elastic 2)
field:"data_stream.dataset" kind:eq
event.actionin
  • creation corpus 32 (elastic 32)
  • rename corpus 25 (elastic 25)
field:"EventType" kind:in
file.extensionin
  • asp corpus 3 (elastic 3)
  • aspx corpus 3 (elastic 3)
  • cgi corpus 3 (elastic 3)
  • jsp corpus 4 (elastic 4)
  • jspx corpus 3 (elastic 3)
  • php corpus 3 (elastic 3)
  • php5 corpus 3 (elastic 3)
  • pht corpus 3 (elastic 3)
  • phtml corpus 3 (elastic 3)
  • war corpus 3 (elastic 3)
field:"file.extension" kind:in
http.request.body.contentwildcard
  • *Content-Disposition: form-data*
  • *filename=*
field:"http.request.body.content" kind:wildcard
http.request.methodin
  • GET
  • POST
  • PUT
field:"http.request.method" kind:in
http.response.status_codege
  • 200 transforms: number
field:"http.response.status_code" kind:ge value:"200"
http.response.status_codein
  • 200 transforms: number
  • 201 transforms: number
  • 204 transforms: number
  • 301 transforms: number
  • 302 transforms: number
  • 303 transforms: number corpus 2 (elastic 2)
  • 409 transforms: number
field:"http.response.status_code" kind:in
http.response.status_codelt
  • 600 transforms: number
field:"http.response.status_code" kind:lt value:"600"
url.extensionin
  • asp
  • aspx
  • cgi
  • jsp
  • jspx
  • php
  • php5
  • pht
  • phtml
  • war
field:"url.extension" kind:in

Known Desktop Application DLL Search Order Hijack

#
Source
github.com/elastic/protections-artifacts

Identifies attempts to load an unsigned DLL file to a known desktop application dependencies folder such as Slack, Teams or OneDrive. This may indicate an attempt to load a malicious module via DLL search order hijacking.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies attempts to load an unsigned DLL file to a known desktop application dependencies folder such as Slack, Teams
or OneDrive. This may indicate an attempt to load a malicious module via DLL search order hijacking.
"""
id = "60b68900-08b4-4bd3-832a-6e36e0921d74"
license = "Elastic License v2"
name = "Known Desktop Application DLL Search Order Hijack"
os_list = ["windows"]
reference = [
    "https://posts.specterops.io/automating-dll-hijack-discovery-81c4295904b0",
    "https://www.elastic.co/security-labs/Hunting-for-Suspicious-Windows-Libraries-for-Execution-and-Evasion",
]
version = "1.0.2"

query = '''
library where
 (dll.Ext.relative_file_creation_time <= 500 or dll.Ext.relative_file_name_modify_time <= 500) and
 (dll.code_signature.trusted == false or dll.code_signature.exists == false) and
  not dll.code_signature.status like "errorCode_endpoint*" and
  dll.path :
        ("?:\\Users\\*\\AppData\\*\\Microsoft\\OneDrive\\*.dll",
         "?:\\Users\\*\\AppData\\*\\Microsoft OneDrive\\*.dll",
         "?:\\Users\\*\\AppData\\*\\Microsoft\\Teams\\*.dll",
         "?:\\Users\\*\\AppData\\Local\\slack\\app-*\\*.dll",
         "?:\\Users\\*\\AppData\\Local\\Programs\\Microsoft VS Code\\*.dll",
         "?:\\Users\\*\\AppData\\Local\\*\\Well Known Domains\\*\\well_known_domains.dll",
         "?:\\Users\\*\\AppData\\Local\\*\\Domain Actions\\*\\domain_actions.dll") and
 not dll.path : ("?:\\Users\\*\\AppData\\Local\\Microsoft\\OneDrive\\*\\*.dll",
                  "?:\\Users\\*\\AppData\\Local\\Microsoft\\Teams\\current\\resources\\meeting-addin\\*",
                  "?:\\Users\\*\\Teams\\current\\*")
'''

min_endpoint_version = "8.10.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"
[[threat.technique.subtechnique]]
id = "T1574.001"
name = "DLL"
reference = "https://attack.mitre.org/techniques/T1574/001/"



[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

[internal]
min_endpoint_version = "8.10.0"

Stages and Predicates

Stage 1: library

library where
 (dll.Ext.relative_file_creation_time <= 500 or dll.Ext.relative_file_name_modify_time <= 500) and
 (dll.code_signature.trusted == false or dll.code_signature.exists == false) and
  not dll.code_signature.status like "errorCode_endpoint*" and
  dll.path :
        ("?:\\Users\\*\\AppData\\*\\Microsoft\\OneDrive\\*.dll",
         "?:\\Users\\*\\AppData\\*\\Microsoft OneDrive\\*.dll",
         "?:\\Users\\*\\AppData\\*\\Microsoft\\Teams\\*.dll",
         "?:\\Users\\*\\AppData\\Local\\slack\\app-*\\*.dll",
         "?:\\Users\\*\\AppData\\Local\\Programs\\Microsoft VS Code\\*.dll",
         "?:\\Users\\*\\AppData\\Local\\*\\Well Known Domains\\*\\well_known_domains.dll",
         "?:\\Users\\*\\AppData\\Local\\*\\Domain Actions\\*\\domain_actions.dll") and
 not dll.path : ("?:\\Users\\*\\AppData\\Local\\Microsoft\\OneDrive\\*\\*.dll",
                  "?:\\Users\\*\\AppData\\Local\\Microsoft\\Teams\\current\\resources\\meeting-addin\\*",
                  "?:\\Users\\*\\Teams\\current\\*")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
dll.Ext.relative_file_creation_timele
  • 500 transforms: number corpus 11 (elastic 11)
field:"dll.Ext.relative_file_creation_time" kind:le value:"500"
dll.Ext.relative_file_name_modify_timele
  • 500 transforms: number corpus 9 (elastic 9)
field:"dll.Ext.relative_file_name_modify_time" kind:le value:"500"
dll.code_signature.existseq
  • false transforms: boolean corpus 22 (elastic 22)
field:"dll.code_signature.exists" kind:eq value:"false"
dll.code_signature.trustedeq
  • false transforms: boolean corpus 21 (elastic 21)
field:"dll.code_signature.trusted" kind:eq value:"false"
dll.pathwildcard
  • ?:\Users\*\AppData\*\Microsoft OneDrive\*.dll
  • ?:\Users\*\AppData\*\Microsoft\OneDrive\*.dll
  • ?:\Users\*\AppData\*\Microsoft\Teams\*.dll
  • ?:\Users\*\AppData\Local\*\Domain Actions\*\domain_actions.dll
  • ?:\Users\*\AppData\Local\*\Well Known Domains\*\well_known_domains.dll
  • ?:\Users\*\AppData\Local\Programs\Microsoft VS Code\*.dll
  • ?:\Users\*\AppData\Local\slack\app-*\*.dll
field:"ImageLoaded" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
dll.code_signature.statusstarts_witherrorCode_endpointexcludes:dll.code_signature.status field:"dll.code_signature.status" value:"errorCode_endpoint"
dll.pathwildcard?:\Users\*\AppData\Local\Microsoft\OneDrive\*\*.dll, ?:\Users\*\AppData\Local\Microsoft\Teams\current\resources\meeting-addin\*, ?:\Users\*\Teams\current\*excludes:dll.path field:"dll.path" value:"?:\Users\*\AppData\Local\Microsoft\OneDrive\*\*.dll" field:"dll.path" value:"?:\Users\*\AppData\Local\Microsoft\Teams\current\resources\meeting-addin\*" field:"dll.path" value:"?:\Users\*\Teams\current\*"

Potential Evasion via Stack Rumbling

#
Source
github.com/elastic/protections-artifacts

Identifies modification of the Image File Execution Options registry value MinimumStackCommitInBytes. Adversaries may abuse this key to force the crash of an endpoint security solution due to stack overflow.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies modification of the Image File Execution Options registry value MinimumStackCommitInBytes. Adversaries may
abuse this key to force the crash of an endpoint security solution due to stack overflow.
"""
id = "d1abaedb-c95a-4c8e-ab8a-baf3b344892f"
license = "Elastic License v2"
name = "Potential Evasion via Stack Rumbling"
os_list = ["windows"]
reference = [
    "https://www.trendmicro.com/en_us/research/23/e/attack-on-security-titans-earth-longzhi-returns-with-new-tricks.html",
]
version = "1.0.12"

query = '''
registry where registry.data.strings != null and
 registry.path : ("HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\*\\MinimumStackCommitInBytes",
                  "HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\*\\MinimumStackCommitInBytes")
'''

min_endpoint_version = "8.8.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 = "T1546"
name = "Event Triggered Execution"
reference = "https://attack.mitre.org/techniques/T1546/"
[[threat.technique.subtechnique]]
id = "T1546.012"
name = "Image File Execution Options Injection"
reference = "https://attack.mitre.org/techniques/T1546/012/"



[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.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[[threat.technique.subtechnique]]
id = "T1562.001"
name = "Disable or Modify Tools"
reference = "https://attack.mitre.org/techniques/T1562/001/"



[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

[internal]
min_endpoint_version = "8.8.0"

Stages and Predicates

Stage 1: registry

registry where registry.data.strings != null and
 registry.path : ("HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\*\\MinimumStackCommitInBytes",
                  "HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\*\\MinimumStackCommitInBytes")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
registry.data.stringsis_not_null
  • (no value, null check)
field:"Details" kind:is_not_null
registry.pathwildcard
  • HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\*\MinimumStackCommitInBytes
  • HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\*\MinimumStackCommitInBytes
field:"TargetObject" kind:wildcard

Potential Masquerading as Svchost

#
Status
production
Severity
high
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies attempts to masquerade as the Service Host process svchost.exe to evade detection and blend in with normal system activity.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2025/11/12"
integration = ["endpoint", "windows", "system"]
maturity = "production"
updated_date = "2026/07/20"
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 attempts to masquerade as the Service Host process `svchost.exe` to evade detection and blend in with
normal system activity.
"""
from = "now-9m"
interval = "8m"
language = "esql"
license = "Elastic License v2"
name = "Potential Masquerading as Svchost"
risk_score = 73
rule_id = "32f95776-6498-4f3c-a90c-d4f6083e3901"
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Defense Evasion",
    "Resources: Investigation Guide",
    "Data Source: Elastic Defend",
    "Data Source: Windows Security Event Logs",
    "Data Source: Sysmon"
]
timestamp_override = "event.ingested"
type = "esql"

query = '''
FROM logs-endpoint.events.process-*, logs-windows.sysmon_operational-*, logs-system.security-*, logs-windows.*, winlogbeat-* metadata _id, _version, _index
| where event.category == "process" and event.type == "start" and
  match(process.name, "svchost.exe", { "fuzziness": 1, "max_expansions": 10 }) and
  not to_lower(process.executable) in ("c:\\windows\\syswow64\\svchost.exe", "c:\\windows\\system32\\svchost.exe") and
  not to_lower(process.executable) like """\\device\\harddiskvolume*\\windows\\system32\\svchost.exe""" and
  not to_lower(process.executable) like """\\device\\harddiskvolume*\\windows\\syswow64\\svchost.exe""" 
| keep *
'''

note = """## Triage and analysis

### Investigating Potential Masquerading as Svchost

#### Possible investigation steps

- Does the alert confirm a service-host-like name running from a noncanonical path?
  - Focus: `process.name`, `process.executable`, `process.command_line`, `process.parent.executable`, and `host.id`, comparing the path with `C:\\Windows\\System32\\svchost.exe` and `C:\\Windows\\SysWOW64\\svchost.exe`.
  - Hint: use `process.entity_id`, hash, and signer fields where present; if enrichments are missing, keep the gap unresolved and scope by `host.id`, path, and alert time.
  - Implication: escalate when svchost.exe or a near-match runs from a user-writable, temp, share-backed, or product-mismatched path; lower concern only when a recognized lab, build-test, or recovery workflow also fits later evidence.

- Is the file identity or rename timing consistent with Microsoft Service Host?
  - Focus: `process.hash.sha256`, `process.pe.original_file_name`, `process.code_signature.*`, rename timing, and file events for the same path. $investigate_0
  - Implication: escalate for an unfamiliar hash, unsigned/untrusted or non-Microsoft signer, recent rename, or original filename conflict; Microsoft identity and stable name timing reduce identity concern but do not clear the noncanonical path.

- Does the launch context fit service-controlled svchost.exe behavior?
  - Focus: `process.parent.name`, `process.parent.executable`, `process.parent.command_line`, `process.command_line`, and session context, checking for services.exe and service grouping arguments such as `-k <group>` or `-s <service>`.
  - Implication: escalate when the parent is a shell, script engine, Office process, archive tool, or user-run utility, when service-group arguments are absent, or when context is interactive; services.exe plus service grouping lowers launch-context concern, but the noncanonical path still needs explanation.

- Does this process instance behave like a launcher rather than a passive service host?
  - Focus: child starts where `process.parent.entity_id` matches `process.entity_id`, especially child `process.name`, `process.executable`, and `process.command_line`. $investigate_1
  - Hint: use `process.Ext.ancestry` only as a deeper fallback when direct parent-child lineage is missing or incomplete.
  - Implication: escalate when it spawns shells, script engines, admin tools, installers, additional lookalikes, or short-lived command chains; absent or service-like child activity narrows launcher risk but does not close the name/path anomaly.

- If local findings remain suspicious or unresolved, does related alert scope show reuse of the same masquerading path?
  - Focus: related alerts for the same `process.executable` or `process.hash.sha256`, comparing `host.id` and `user.id` where available. $investigate_2 $investigate_3
  - Implication: broaden scope and raise urgency when the same path or hash appears on other hosts, users, or alert types; keep local only when related alerts are absent and all local evidence supports one recognized lab, build, or recovery workflow.

- Escalate when the path anomaly plus identity, lineage, timing, child-process, or scope evidence points to masquerading or broader compromise; close only when path, identity, launch context, and bounded host/user scope prove one recognized lab, build, or recovery workflow; if telemetry cannot prove legitimacy, preserve artifacts and escalate.

### False positive analysis

- Controlled malware-analysis, image-build, or recovery testing can stage a service-host-like file outside canonical Windows paths. Confirm by aligning identity (`process.hash.sha256`, `process.pe.original_file_name`, signer trust/subject), launch context (`process.parent.executable`, `process.parent.command_line`, `process.command_line`), and scope (`host.id`, `host.name`, `user.id`). Without outside records, close only when process fields prove the controlled workflow.
- Treat a noncanonical svchost.exe name as suspicious until process evidence proves one complete benign workflow; a trusted Microsoft signer, familiar parent, or single quiet execution is not enough when the path or name still mimics Service Host.
- Before creating an exception, require recurring `process.executable`, `process.hash.sha256`, signer subject, parent executable, command-line shape, and `host.id` or controlled host cohort across prior alerts from this rule. Avoid exceptions on `process.name`, svchost.exe, `user.name`, or a host alone.

### Response and remediation

- If confirmed benign, reverse any temporary containment and record the exact workflow evidence: `process.executable`, `process.hash.sha256`, `process.code_signature.subject_name`, `process.parent.executable`, `process.command_line`, `host.id`, and the controlled lab, build, or recovery scope. Create an exception only after the same evidence pattern recurs.
- If suspicious but unconfirmed, preserve the alert, source process event, recovered `process.entity_id`, `process.executable`, `process.hash.sha256`, signature metadata, parent context, command line, and related-alert results before containment. Apply reversible controls first, such as heightened monitoring or temporary network restrictions for the affected `host.id`, and avoid termination or deletion until scope is clearer.
- If confirmed malicious, first preserve the recovered `process.entity_id`, command line, child-process list, path evidence, and forensic package for `process.executable`. Finish same-path and same-hash scoping, then isolate the endpoint when host criticality allows, terminate only the suspicious noncanonical service-host process, and remove the masquerading executable or launcher artifacts. Do not stop canonical Service Host instances unless that exact instance is proven malicious.
- After containment, restore any affected service-host component from known-good media if a legitimate file was replaced, restrict execution from user-writable or share-backed paths where feasible, and document the recovered command-line and parent-chain pattern that separated this fake service host from normal services.exe-launched instances.
"""

setup = """## Setup

This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.

Setup instructions: https://ela.st/install-elastic-defend

### Additional data sources

This rule also supports the following third-party data sources. For setup instructions, refer to the links below:

- [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
- [Windows Process Creation Logs](https://ela.st/audit-process-creation)
"""

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "host.name",
    "host.id",
    "user.name",
    "user.id",
    "process.name",
    "process.entity_id",
    "process.executable",
    "process.command_line",
    "process.hash.sha256",
    "process.pe.original_file_name",
    "process.code_signature.subject_name",
    "process.code_signature.trusted",
    "process.parent.executable",
    "process.parent.command_line",
]

[transform]

[[transform.investigate]]
label = "File events for the masquerading executable path"
description = ""
providers = [
  [
    { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "file.path", queryType = "phrase", value = "{{process.executable}}", valueType = "string" }
  ]
]
relativeFrom = "now-24h"
relativeTo = "now"

[[transform.investigate]]
label = "Child process starts from the masquerading svchost instance"
description = ""
providers = [
  [
    { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

[[transform.investigate]]
label = "Alerts associated with the same executable path"
description = ""
providers = [
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "process.executable", queryType = "phrase", value = "{{process.executable}}", valueType = "string" }
  ]
]
relativeFrom = "now-48h/h"
relativeTo = "now"

[[transform.investigate]]
label = "Alerts associated with the same executable hash"
description = ""
providers = [
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "process.hash.sha256", queryType = "phrase", value = "{{process.hash.sha256}}", valueType = "string" }
  ]
]
relativeFrom = "now-48h/h"
relativeTo = "now"

[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1036"
name = "Masquerading"
reference = "https://attack.mitre.org/techniques/T1036/"
[[rule.threat.technique.subtechnique]]
id = "T1036.005"
name = "Match Legitimate Resource Name or Location"
reference = "https://attack.mitre.org/techniques/T1036/005/"

[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

Stages and Predicates

Stage 1: from

FROM logs-endpoint.events.process-*, logs-windows.sysmon_operational-*, logs-system.security-*, logs-windows.*, winlogbeat-* metadata _id, _version, _index

Stage 2: where

| where event.category == "process" and event.type == "start" and
  match(process.name, "svchost.exe", { "fuzziness": 1, "max_expansions": 10 }) and
  not to_lower(process.executable) in ("c:\\windows\\syswow64\\svchost.exe", "c:\\windows\\system32\\svchost.exe") and
  not to_lower(process.executable) like """\\device\\harddiskvolume*\\windows\\system32\\svchost.exe""" and
  not to_lower(process.executable) like """\\device\\harddiskvolume*\\windows\\syswow64\\svchost.exe"""

Stage 3: keep

| keep *

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.categoryeq
  • process corpus 38 (elastic 38)
field:"event.category" kind:eq value:"process"
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.namematch
  • "max_expansions": 10 }
  • svchost.exe
  • { "fuzziness": 1
field:"process_basename" kind:match

Output Fields

The rule emits every field available at its final step.

Potential OpenSSH Backdoor Logging Activity

#
Status
production
Severity
low
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies a Secure Shell (SSH) client or server process creating a known SSH backdoor log file. Adversaries may modify SSH related binaries for persistence or credential access via patching sensitive functions to enable unauthorized access or to log SSH credentials for exfiltration.

Known False Positives

  • Updates to approved and trusted SSH executables can trigger this rule.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2020/12/21"
integration = ["endpoint", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2026/06/04"

[rule]
author = ["Elastic"]
description = """
Identifies a Secure Shell (SSH) client or server process creating a known SSH backdoor log file. Adversaries may
modify SSH related binaries for persistence or credential access via patching sensitive functions to enable
unauthorized access or to log SSH credentials for exfiltration.
"""
false_positives = ["Updates to approved and trusted SSH executables can trigger this rule."]
from = "now-9m"
index = [
    "logs-endpoint.events.file-*",
    "endgame-*",
    "logs-sentinel_one_cloud_funnel.*"
]
language = "eql"
license = "Elastic License v2"
name = "Potential OpenSSH Backdoor Logging Activity"
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 OpenSSH Backdoor Logging Activity

OpenSSH is a widely used protocol for secure remote administration and file transfers. Adversaries may exploit OpenSSH by modifying its binaries to log credentials or maintain unauthorized access. The detection rule identifies suspicious file changes linked to SSH processes, focusing on unusual file names, extensions, and paths indicative of backdoor activity, thus helping to uncover potential security breaches.

### Possible investigation steps

- Review the file change event details to identify the specific file name, extension, and path involved in the alert. Pay particular attention to unusual file names or extensions and paths listed in the query, such as "/usr/lib/*.so.*" or "/private/etc/ssh/.sshd_auth".
- Examine the process executable that triggered the alert, either "/usr/sbin/sshd" or "/usr/bin/ssh", to determine if it has been modified or replaced. Check the integrity of these binaries using hash comparisons against known good versions.
- Investigate the user account associated with the process that made the file change. Determine if the account has a history of suspicious activity or if it has been compromised.
- Check for any recent or unusual login attempts or sessions related to the SSH service on the host. Look for patterns that might indicate unauthorized access or credential harvesting.
- Analyze system logs, such as auth.log or secure.log, for any anomalies or entries that coincide with the time of the file change event. This can provide additional context or evidence of malicious activity.
- If a backdoor is suspected, consider isolating the affected system from the network to prevent further unauthorized access and begin remediation efforts, such as restoring from a clean backup or reinstalling the affected services.

### False positive analysis

- Routine system updates or package installations may trigger file changes in SSH-related directories. Users can create exceptions for known update processes to prevent false alerts.
- Custom scripts or administrative tasks that modify SSH configuration files for legitimate purposes might be flagged. Users should whitelist these scripts or processes if they are verified as non-malicious.
- Backup or synchronization tools that create temporary files with unusual extensions or names in SSH directories can cause false positives. Exclude these tools from monitoring if they are part of regular operations.
- Development or testing environments where SSH binaries are frequently modified for testing purposes may generate alerts. Implement exclusions for these environments to reduce noise.
- Automated configuration management tools like Ansible or Puppet that modify SSH settings as part of their operations can be excluded if they are part of authorized workflows.

### Response and remediation

- Immediately isolate the affected system from the network to prevent further unauthorized access or data exfiltration.
- Terminate any suspicious SSH processes identified in the alert to halt potential backdoor activity.
- Conduct a thorough review of the modified files and binaries, particularly those listed in the query, to assess the extent of the compromise and identify any malicious code or unauthorized changes.
- Restore affected files and binaries from a known good backup to ensure system integrity and remove any backdoor modifications.
- Change all SSH credentials and keys associated with the compromised system to prevent unauthorized access using potentially logged credentials.
- Implement additional monitoring on the affected system and network for any signs of persistence or further malicious activity, focusing on the paths and file types highlighted in the detection query.
- Escalate the incident to the security operations team for further investigation and to determine if additional systems may be affected, ensuring a coordinated response to the threat."""
references = [
    "https://github.com/eset/malware-ioc/tree/master/sshdoor",
    "https://www.welivesecurity.com/wp-content/uploads/2021/01/ESET_Kobalos.pdf",
]
risk_score = 21
rule_id = "f28e2be4-6eca-4349-bdd9-381573730c22"
setup = """## Setup

This rule requires data coming in from one of the following integrations:
- Elastic Defend
- Auditbeat

### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.

#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).

#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).

### Auditbeat Setup
Auditbeat is a lightweight shipper that you can install on your servers to audit the activities of users and processes on your systems. For example, you can use Auditbeat to collect and centralize audit events from the Linux Audit Framework. You can also use Auditbeat to detect changes to critical files, like binaries and configuration files, and identify potential security policy violations.

#### The following steps should be executed in order to add the Auditbeat on a Linux System:
- Elastic provides repositories available for APT and YUM-based distributions. Note that we provide binary packages, but no source packages.
- To install the APT and YUM repositories follow the setup instructions in this [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/setup-repositories.html).
- To run Auditbeat on Docker follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/running-on-docker.html).
- To run Auditbeat on Kubernetes follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/running-on-kubernetes.html).
- For complete “Setup and Run Auditbeat” information refer to the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/setting-up-and-running.html).

#### Custom Ingest Pipeline
For versions <8.2, you need to add a custom ingest pipeline to populate `event.ingested` with @timestamp for non-elastic-agent indexes, like auditbeats/filebeat/winlogbeat etc. For more details to add a custom ingest pipeline refer to the [guide](https://www.elastic.co/guide/en/fleet/current/data-streams-pipeline-tutorial.html).
"""
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Persistence",
    "Tactic: Credential Access",
    "Data Source: Elastic Endgame",
    "Data Source: Elastic Defend",
    "Data Source: SentinelOne",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
file where host.os.type == "linux" and event.type == "creation" and process.name in ("ssh", "sshd") and
  (
    (
      file.name : (".*", "~*", "*~") and not file.name : (
        ".cache", ".viminfo", ".bash_history", ".google_authenticator", ".jelenv", ".csvignore", ".rtreport", ".git*"
      )
    ) or
    file.extension : ("in", "out", "ini", "h", "gz", "so", "sock", "sync", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9") or
    file.path :
    (
      "/tmp/*",
      "/var/tmp/*",
      "/dev/shm/*",
      "/usr/share/*",
      "/usr/include/*",
      "/usr/local/include/*",
      "/usr/share/man/*",
      "/usr/local/share/*",
      "/usr/lib/*.so.*",
      "/usr/bin/ssd",
      "/var/run/sshd/sshd.pid",
      "/var/run/nscd/ns.pid",
      "/var/run/udev/ud.pid",
      "/var/run/udevd.pid"
    )
  ) and
  not file.path like ("/tmp/krb5cc*", "/tmp/ansible_*", "/storage/*", "/tmp/clearsigned.message.*", "/var/sftp/refinitiv/*", "/tmp/fileutil.message.*")
'''

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1556"
name = "Modify Authentication Process"
reference = "https://attack.mitre.org/techniques/T1556/"

[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1554"
name = "Compromise Host Software Binary"
reference = "https://attack.mitre.org/techniques/T1554/"

[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1074"
name = "Data Staged"
reference = "https://attack.mitre.org/techniques/T1074/"

[[rule.threat.technique.subtechnique]]
id = "T1074.001"
name = "Local Data Staging"
reference = "https://attack.mitre.org/techniques/T1074/001/"

[rule.threat.tactic]
id = "TA0009"
name = "Collection"
reference = "https://attack.mitre.org/tactics/TA0009/"

Stages and Predicates

Stage 1: file

file where host.os.type == "linux" and event.type == "creation" and process.name in ("ssh", "sshd") and
  (
    (
      file.name : (".*", "~*", "*~") and not file.name : (
        ".cache", ".viminfo", ".bash_history", ".google_authenticator", ".jelenv", ".csvignore", ".rtreport", ".git*"
      )
    ) or
    file.extension : ("in", "out", "ini", "h", "gz", "so", "sock", "sync", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9") or
    file.path :
    (
      "/tmp/*",
      "/var/tmp/*",
      "/dev/shm/*",
      "/usr/share/*",
      "/usr/include/*",
      "/usr/local/include/*",
      "/usr/share/man/*",
      "/usr/local/share/*",
      "/usr/lib/*.so.*",
      "/usr/bin/ssd",
      "/var/run/sshd/sshd.pid",
      "/var/run/nscd/ns.pid",
      "/var/run/udev/ud.pid",
      "/var/run/udevd.pid"
    )
  ) and
  not file.path like ("/tmp/krb5cc*", "/tmp/ansible_*", "/storage/*", "/tmp/clearsigned.message.*", "/var/sftp/refinitiv/*", "/tmp/fileutil.message.*")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.typeeq
  • creation
field:"event.type" kind:eq value:"creation"
file.extensionwildcard
  • 0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • gz
  • h
  • in
  • ini
  • out
  • so
  • sock
  • sync
field:"file.extension" kind:wildcard
file.namewildcard
  • *~
  • .*
  • ~*
field:"file.name" kind:wildcard
file.pathwildcard
  • /dev/shm/*
  • /tmp/*
  • /usr/bin/ssd
  • /usr/include/*
  • /usr/lib/*.so.*
  • /usr/local/include/*
  • /usr/local/share/*
  • /usr/share/*
  • /usr/share/man/*
  • /var/run/nscd/ns.pid
  • /var/run/sshd/sshd.pid
  • /var/run/udev/ud.pid
  • /var/run/udevd.pid
  • /var/tmp/*
field:"TargetFilename" kind:wildcard
process.namein
  • ssh
  • sshd
field:"process_basename" kind:in

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
file.pathstarts_with/tmp/krb5cc, /tmp/ansible_, /storage/, /tmp/clearsigned.message., /var/sftp/refinitiv/, /tmp/fileutil.message.excludes:file.path

SELinux Configuration Creation or Renaming

#
Status
production
Severity
low
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

This rule detects the creation or renaming of the SELinux configuration file. SELinux is a security module that provides access control security policies. Modifications to the SELinux configuration file may indicate an attempt to impair defenses by disabling or modifying security tools.

MITRE ATT&CK Coverage

TacticTechniques
Defense Impairment

Rule Body

[metadata]
creation_date = "2024/08/28"
integration = ["endpoint", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2025/12/18"

[rule]
author = ["Elastic"]
description = """
This rule detects the creation or renaming of the SELinux configuration file. SELinux is a security module that provides
access control security policies. Modifications to the SELinux configuration file may indicate an attempt to impair
defenses by disabling or modifying security tools.
"""
from = "now-9m"
index = ["logs-endpoint.events.file*", "endgame-*", "logs-sentinel_one_cloud_funnel.*"]
language = "eql"
license = "Elastic License v2"
name = "SELinux Configuration Creation or Renaming"
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 SELinux Configuration Creation or Renaming

SELinux, a Linux kernel security module, enforces access control policies to protect systems. Adversaries may target the SELinux configuration file to disable or alter these defenses, facilitating unauthorized access or evasion of security measures. The detection rule identifies suspicious activities like file creation or renaming in the SELinux configuration path, signaling potential defense evasion attempts.

### Possible investigation steps

- Review the alert details to confirm the event action is either "creation", "file_create_event", "rename", or "file_rename_event" and that the file path is "/etc/selinux/config".
- Check the timestamp of the event to determine when the SELinux configuration file was created or renamed.
- Identify the user account and process responsible for the action by examining the event logs for associated user and process information.
- Investigate the history of changes to the SELinux configuration file to determine if there have been any recent unauthorized modifications.
- Correlate the event with other security alerts or logs to identify any related suspicious activities or patterns on the host.
- Assess the current state of SELinux on the affected system to ensure it is configured correctly and has not been disabled or altered inappropriately.
- If unauthorized changes are confirmed, initiate a response plan to mitigate potential security risks, which may include restoring the original configuration and conducting a broader security assessment of the system.

### False positive analysis

- Routine system updates or administrative tasks may trigger file creation or renaming events in the SELinux configuration path. Users can create exceptions for known update processes or trusted administrative scripts to prevent unnecessary alerts.
- Automated configuration management tools like Ansible, Puppet, or Chef might modify the SELinux configuration file as part of their normal operations. Users should identify and whitelist these tools to reduce false positives.
- Initial system setup or reconfiguration activities often involve legitimate changes to the SELinux configuration. Users can temporarily disable the rule during planned maintenance windows or add exceptions for specific time frames to avoid false alerts.
- Security audits or compliance checks may involve accessing or modifying SELinux settings. Users should coordinate with audit teams to recognize these activities and adjust the rule settings accordingly.
- Custom scripts or applications developed in-house that interact with SELinux settings should be reviewed and, if deemed safe, added to an exception list to minimize false positives.

### Response and remediation

- Immediately isolate the affected system from the network to prevent further unauthorized access or potential lateral movement by the adversary.
- Verify the integrity of the SELinux configuration file by comparing it with a known good backup. If discrepancies are found, restore the file from a trusted backup.
- Conduct a thorough review of recent user and process activity on the affected system to identify any unauthorized changes or suspicious behavior that may have led to the SELinux configuration modification.
- Re-enable SELinux enforcement if it has been disabled, and ensure that the correct security policies are applied to maintain system protection.
- Escalate the incident to the security operations team for further investigation and to determine if additional systems may be affected.
- Implement additional monitoring on the affected system and similar systems to detect any further attempts to modify SELinux configurations or other critical security settings.
- Review and update access controls and permissions to ensure that only authorized personnel have the ability to modify SELinux configurations, reducing the risk of future unauthorized changes."""
risk_score = 21
rule_id = "7b981906-86b7-4544-8033-c30ec6eb45fc"
setup = """## Setup

This rule requires data coming in from one of the following integrations:
- Elastic Defend

### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.

#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).

#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Defense Evasion",
    "Data Source: Elastic Endgame",
    "Data Source: Elastic Defend",
    "Data Source: SentinelOne",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
file where host.os.type == "linux" and event.action in ("creation", "file_create_event", "rename", "file_rename_event")
and file.path : "/etc/selinux/config" and not (
  process.name in ("dockerd", "platform-python") or
  process.executable like (
    "/usr/libexec/platform-python*", "/dev/fd/3", "/usr/bin/podman", "/usr/local/cpanel/3rdparty/perl/*/bin/perl",
    "/kaniko/executor", "/usr/lib/systemd/systemd", "/usr/bin/insights-client", "/bin/podman"
  )
)
'''

[[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: file

file where host.os.type == "linux" and event.action in ("creation", "file_create_event", "rename", "file_rename_event")
and file.path : "/etc/selinux/config" and not (
  process.name in ("dockerd", "platform-python") or
  process.executable like (
    "/usr/libexec/platform-python*", "/dev/fd/3", "/usr/bin/podman", "/usr/local/cpanel/3rdparty/perl/*/bin/perl",
    "/kaniko/executor", "/usr/lib/systemd/systemd", "/usr/bin/insights-client", "/bin/podman"
  )
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actionin
  • creation
  • file_create_event
  • file_rename_event
  • rename
field:"EventType" kind:in
file.pathwildcard
  • /etc/selinux/config
field:"TargetFilename" kind:wildcard value:"/etc/selinux/config"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.executablewildcard/usr/libexec/platform-python*, /dev/fd/3, /usr/bin/podman, /usr/local/cpanel/3rdparty/perl/*/bin/perl, /kaniko/executor, /usr/lib/systemd/systemd, /usr/bin/insights-client, /bin/podmanexcludes:process.executable
process.nameindockerd, platform-pythonexcludes:process.name field:"process.name" value:"dockerd" field:"process.name" value:"platform-python"

Shadow Copy Service Disabled via Registry Modification

#
Source
github.com/elastic/protections-artifacts

Identifies attempt to disable the Windows Shadow Copy service via registry modification. Malware may include this type of suspicious service start changes to decrease system recovery chances.

MITRE ATT&CK Coverage

TacticTechniques
Persistence
Defense Impairment
Impact

Rule Body

[rule]
description = """
Identifies attempt to disable the Windows Shadow Copy service via registry modification. Malware may include this type
of suspicious service start changes to decrease system recovery chances.
"""
id = "b2409cd4-3b23-4b2d-82e4-bbb25594999a"
license = "Elastic License v2"
name = "Shadow Copy Service Disabled via Registry Modification"
os_list = ["windows"]
version = "1.0.28"

query = '''
registry where
 registry.path : "HKLM\\SYSTEM\\ControlSet*\\Services\\VSS\\Start" and registry.data.strings : "4" and
 not process.executable : "?:\\Windows\\System32\\services.exe" and process.executable : "?*" and
 not (process.code_signature.subject_name == "Enestech Software (Cyprus) Ltd" and process.code_signature.trusted == true)
'''

min_endpoint_version = "8.4.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "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/"
[[threat]]
framework = "MITRE ATT&CK"
[[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 = "8.4.0"

Stages and Predicates

Stage 1: registry

registry where
 registry.path : "HKLM\\SYSTEM\\ControlSet*\\Services\\VSS\\Start" and registry.data.strings : "4" and
 not process.executable : "?:\\Windows\\System32\\services.exe" and process.executable : "?*" and
 not (process.code_signature.subject_name == "Enestech Software (Cyprus) Ltd" and process.code_signature.trusted == true)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
process.executablewildcard
  • ?* corpus 3 (elastic 3)
field:"Image" kind:wildcard value:"?*"
registry.data.stringswildcard
  • 4 corpus 6 (elastic 6)
field:"Details" kind:wildcard value:"4"
registry.pathwildcard
  • HKLM\SYSTEM\ControlSet*\Services\VSS\Start corpus 2 (elastic 2)
field:"TargetObject" kind:wildcard value:"HKLM\SYSTEM\ControlSet*\Services\VSS\Start"

Exclusions

The rule actively suppresses these predicates.

Suspicious Curl to Raw IP via Perl

#
Time window
10s
Sequence by
process.entity_id
Source
github.com/elastic/protections-artifacts

Detects when curl or nscurl is spawned by Perl to make an outbound network connection to a raw IP address over HTTP (port 80). This technique is commonly observed in npm typosquatting attacks where malicious packages use Perl as an intermediary to execute curl commands for downloading additional payloads or exfiltrating data. Perl's trusted binary status on macOS makes it an attractive vector for adversaries to execute suspicious network operations while evading detection.

MITRE ATT&CK Coverage

TacticTechniques
Command & Control

Telemetry Coverage

Rule Body

[rule]
description = """
Detects when curl or nscurl is spawned by Perl to make an outbound network connection to a raw IP address over HTTP
(port 80). This technique is commonly observed in npm typosquatting attacks where malicious packages use Perl as an
intermediary to execute curl commands for downloading additional payloads or exfiltrating data. Perl's trusted binary
status on macOS makes it an attractive vector for adversaries to execute suspicious network operations while evading
detection.
"""
id = "19310762-9a8c-4a19-a226-18112fcad215"
license = "Elastic License v2"
name = "Suspicious Curl to Raw IP via Perl"
os_list = ["macos"]
reference = ["https://socket.dev/blog/10-npm-typosquatted-packages-deploy-credential-harvester"]
version = "1.0.1"

query = '''
sequence by process.entity_id with maxspan=10s
[process where event.type == "start" and event.action == "exec" and process.name in ("curl", "nscurl") and process.parent.name == "perl"]
[network where event.type == "start" and destination.domain == null and destination.port == 80]
'''

min_endpoint_version = "8.16.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1105"
name = "Ingress Tool Transfer"
reference = "https://attack.mitre.org/techniques/T1105/"


[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"

[internal]
min_endpoint_version = "8.16.0"

Stages and Predicates

Ordered sequence: each step below must occur in order within 10s, correlated by process.entity_id.

Stage 1: process

[process where event.type == "start" and event.action == "exec" and process.name in ("curl", "nscurl") and process.parent.name == "perl"]

Stage 2: network

[network where event.type == "start" and destination.domain == null and destination.port == 80]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
destination.domainis_null
  • (no value, null check)
field:"DestinationHostname" kind:is_null
destination.porteq
  • 80 transforms: number corpus 4 (elastic 4)
field:"DestinationPort" kind:eq value:"80"
event.actioneq
  • exec corpus 547 (elastic 547)
field:"EventType" kind:eq value:"exec"
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.namein
  • curl corpus 82 (elastic 82)
  • nscurl corpus 41 (elastic 41)
field:"process_basename" kind:in
process.parent.nameeq
  • perl corpus 3 (elastic 3)
field:"parent_process_basename" kind:eq value:"perl"

Suspicious Windows Service DLL Creation

#
Source
github.com/elastic/protections-artifacts

Identifies the creation of a new service via ServiceDLL registry modification instead of using the Windows Service Control Manager APIs, subsequently loaded by svchost.exe. Adversaries may use this technique to maintain persistence or run with System privileges.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the creation of a new service via ServiceDLL registry modification instead of using the Windows Service
Control Manager APIs, subsequently loaded by svchost.exe. Adversaries may use this technique to maintain persistence or
run with System privileges.
"""
id = "2c624716-75a1-42d9-bcb8-1defcb9bded9"
license = "Elastic License v2"
name = "Suspicious Windows Service DLL Creation"
os_list = ["windows"]
version = "1.0.36"

query = '''
registry where event.action == "modification" and 
 registry.value : "ServiceDLL" and process.executable : ("?:\\*", "\\Device\\Mup\\*") and
 not process.executable : ("?:\\Windows\\System32\\services.exe",
                           "?:\\Windows\\System32\\msiexec.exe",
                           "?:\\Windows\\SysWOW64\\msiexec.exe",
                           "?:\\Windows\\System32\\poqexec.exe",
                           "?:\\Windows\\System32\\w32tm.exe",
                           "?:\\Windows\\System32\\spoolsv.exe",
                           "?:\\Windows\\servicing\\TrustedInstaller.exe",
                           "?:\\Windows\\System32\\sdiagnhost.exe",
                           "?:\\Windows\\WinSxS\\*\\TiWorker.exe",
                           "?:\\Windows\\System32\\drvinst.exe",
                           "?:\\Program Files (x86)\\*.exe",
                           "?:\\Program Files\\*.exe",
                           "?:\\Windows\\Temp\\*-*-*\\DismHost.exe",
                           "?:\\$WINDOWS.~BT\\Work\\*\\DismHost.exe",
                           "?:\\$WinREAgent\\Scratch\\*\\DismHost.exe",
                           "?:\\Windows\\SoftwareDistribution\\*.exe",
                           "?:\\Windows\\regedit.exe",
                           "?:\\Windows\\System32\\reg.exe",
                           "?:\\Windows\\System32\\lsass.exe",
                           "?:\\Windows\\System32\\upfc.exe",
                           "?:\\Windows\\System32\\SearchProtocolHost.exe",
                           "?:\\Windows\\SystemApps\\Microsoft.Windows.Search_*\\SearchApp.exe",
                           "?:\\Windows\\System32\\conhost.exe",
                           "?:\\Windows\\System32\\oobe\\UserOOBEBroker.exe",
                           "?:\\Windows\\CCM\\SCNotification.exe",
                           "?:\\Windows\\System32\\PrintIsolationHost.exe",
                           "?:\\Windows\\System32\\sppsvc.exe",
                           "?:\\Windows\\System32\\backgroundTaskHost.exe",
                           "?:\\*\\procexp64.exe",
                           "C:\\Windows\\SystemTemp\\*\\DismHost.exe") and

 not (process.executable : ("?:\\Windows\\System32\\svchost.exe",
                            "?:\\Windows\\System32\\regsvr32.exe",
                            "?:\\Windows\\SysWOW64\\regsvr32.exe",
                            "?:\\Users\\*\\AppData\\Local\\Temp\\*\\DismHost.exe",
                            "?:\\Windows\\Temp\\osrssinst.exe",
                            "?:\\Windows\\regedit.exe",
                            "?:\\$WINDOWS.~BT\\Work\\*\\DismHost.exe") and
      registry.data.strings : ("%systemroot%\\system32\\*", "?:\\Windows\\System32\\*", "%systemroot%\\syswow64\\*",
                               "?:\\Windows\\SysWOW64\\*", "*:\\Program Files\\*", "*:\\Program Files (x86)\\*")) and

 not registry.data.strings : "?:\\WINDOWS\\system32\\spool\\drivers\\x64\\3\\PrintConfig.dll" and

 not (registry.data.strings : "?:\\Program Files (x86)\\dolphinpaper\\provider\\wpprovider.dll" and
      registry.path : "HKLM\\SYSTEM\\ControlSet*\\Services\\dolphinSvc\\Parameters\\ServiceDll") and

 not (process.code_signature.subject_name : ("Speckled Jay LLC", "Refraction Point, Inc", "Arcadia Laboratories Inc.") and process.code_signature.trusted == true) and

 not (process.name : "Dismhost.exe" and registry.data.strings : ("%systemroot%\\system32\\wuaueng.dll", "%SystemRoot%\\System32\\browser.dll") and
      process.code_signature.subject_name : "Microsoft*" and process.code_signature.trusted == true)
'''

min_endpoint_version = "8.1.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"
[[threat.technique.subtechnique]]
id = "T1543.003"
name = "Windows Service"
reference = "https://attack.mitre.org/techniques/T1543/003/"



[threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"

[internal]
min_endpoint_version = "8.1.0"

Stages and Predicates

Stage 1: registry

registry where event.action == "modification" and 
 registry.value : "ServiceDLL" and process.executable : ("?:\\*", "\\Device\\Mup\\*") and
 not process.executable : ("?:\\Windows\\System32\\services.exe",
                           "?:\\Windows\\System32\\msiexec.exe",
                           "?:\\Windows\\SysWOW64\\msiexec.exe",
                           "?:\\Windows\\System32\\poqexec.exe",
                           "?:\\Windows\\System32\\w32tm.exe",
                           "?:\\Windows\\System32\\spoolsv.exe",
                           "?:\\Windows\\servicing\\TrustedInstaller.exe",
                           "?:\\Windows\\System32\\sdiagnhost.exe",
                           "?:\\Windows\\WinSxS\\*\\TiWorker.exe",
                           "?:\\Windows\\System32\\drvinst.exe",
                           "?:\\Program Files (x86)\\*.exe",
                           "?:\\Program Files\\*.exe",
                           "?:\\Windows\\Temp\\*-*-*\\DismHost.exe",
                           "?:\\$WINDOWS.~BT\\Work\\*\\DismHost.exe",
                           "?:\\$WinREAgent\\Scratch\\*\\DismHost.exe",
                           "?:\\Windows\\SoftwareDistribution\\*.exe",
                           "?:\\Windows\\regedit.exe",
                           "?:\\Windows\\System32\\reg.exe",
                           "?:\\Windows\\System32\\lsass.exe",
                           "?:\\Windows\\System32\\upfc.exe",
                           "?:\\Windows\\System32\\SearchProtocolHost.exe",
                           "?:\\Windows\\SystemApps\\Microsoft.Windows.Search_*\\SearchApp.exe",
                           "?:\\Windows\\System32\\conhost.exe",
                           "?:\\Windows\\System32\\oobe\\UserOOBEBroker.exe",
                           "?:\\Windows\\CCM\\SCNotification.exe",
                           "?:\\Windows\\System32\\PrintIsolationHost.exe",
                           "?:\\Windows\\System32\\sppsvc.exe",
                           "?:\\Windows\\System32\\backgroundTaskHost.exe",
                           "?:\\*\\procexp64.exe",
                           "C:\\Windows\\SystemTemp\\*\\DismHost.exe") and

 not (process.executable : ("?:\\Windows\\System32\\svchost.exe",
                            "?:\\Windows\\System32\\regsvr32.exe",
                            "?:\\Windows\\SysWOW64\\regsvr32.exe",
                            "?:\\Users\\*\\AppData\\Local\\Temp\\*\\DismHost.exe",
                            "?:\\Windows\\Temp\\osrssinst.exe",
                            "?:\\Windows\\regedit.exe",
                            "?:\\$WINDOWS.~BT\\Work\\*\\DismHost.exe") and
      registry.data.strings : ("%systemroot%\\system32\\*", "?:\\Windows\\System32\\*", "%systemroot%\\syswow64\\*",
                               "?:\\Windows\\SysWOW64\\*", "*:\\Program Files\\*", "*:\\Program Files (x86)\\*")) and

 not registry.data.strings : "?:\\WINDOWS\\system32\\spool\\drivers\\x64\\3\\PrintConfig.dll" and

 not (registry.data.strings : "?:\\Program Files (x86)\\dolphinpaper\\provider\\wpprovider.dll" and
      registry.path : "HKLM\\SYSTEM\\ControlSet*\\Services\\dolphinSvc\\Parameters\\ServiceDll") and

 not (process.code_signature.subject_name : ("Speckled Jay LLC", "Refraction Point, Inc", "Arcadia Laboratories Inc.") and process.code_signature.trusted == true) and

 not (process.name : "Dismhost.exe" and registry.data.strings : ("%systemroot%\\system32\\wuaueng.dll", "%SystemRoot%\\System32\\browser.dll") and
      process.code_signature.subject_name : "Microsoft*" and process.code_signature.trusted == true)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • modification corpus 72 (elastic 72)
field:"EventType" kind:eq value:"modification"
process.executablewildcard
  • ?:\* corpus 18 (elastic 18)
  • \Device\Mup\* corpus 8 (elastic 8)
field:"Image" kind:wildcard
registry.valuewildcard
  • ServiceDLL corpus 2 (elastic 2)
field:"registry_value_name" kind:wildcard value:"ServiceDLL"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.code_signature.subject_nameeqSpeckled Jay LLC, Refraction Point, Inc, Arcadia Laboratories Inc.excludes:process.code_signature.subject_name field:"process.code_signature.subject_name" value:"Speckled Jay LLC" field:"process.code_signature.subject_name" value:"Refraction Point, Inc" field:"process.code_signature.subject_name" value:"Arcadia Laboratories Inc."
process.code_signature.trustedeqtrueexcludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true"
process.code_signature.subject_namestarts_withMicrosoftexcludes:process.code_signature.subject_name field:"process.code_signature.subject_name" value:"Microsoft"
process.nameeqDismhost.exeexcludes:process.name field:"process.name" value:"Dismhost.exe"
registry.data.stringseq%systemroot%\system32\wuaueng.dll, %SystemRoot%\System32\browser.dllexcludes:registry.data.strings field:"registry.data.strings" value:"%systemroot%\system32\wuaueng.dll" field:"registry.data.strings" value:"%SystemRoot%\System32\browser.dll"
process.executablewildcard?:\Windows\System32\svchost.exe, ?:\Windows\System32\regsvr32.exe, ?:\Windows\SysWOW64\regsvr32.exe, ?:\Users\*\AppData\Local\Temp\*\DismHost.exe, ?:\Windows\Temp\osrssinst.exe, ?:\Windows\regedit.exe, ?:\$WINDOWS.~BT\Work\*\DismHost.exeexcludes:process.executable
registry.data.stringswildcard%systemroot%\system32\*, ?:\Windows\System32\*, %systemroot%\syswow64\*, ?:\Windows\SysWOW64\*, *:\Program Files\*, *:\Program Files (x86)\*excludes:registry.data.strings
registry.data.stringseq?:\Program Files (x86)\dolphinpaper\provider\wpprovider.dllexcludes:registry.data.strings field:"registry.data.strings" value:"?:\Program Files (x86)\dolphinpaper\provider\wpprovider.dll"
registry.pathwildcardHKLM\SYSTEM\ControlSet*\Services\dolphinSvc\Parameters\ServiceDllexcludes:registry.path field:"registry.path" value:"HKLM\SYSTEM\ControlSet*\Services\dolphinSvc\Parameters\ServiceDll"
process.executablewildcard?:\Windows\System32\services.exe, ?:\Windows\System32\msiexec.exe, ?:\Windows\SysWOW64\msiexec.exe, ?:\Windows\System32\poqexec.exe, ?:\Windows\System32\w32tm.exe, ?:\Windows\System32\spoolsv.exe, ?:\Windows\servicing\TrustedInstaller.exe, ?:\Windows\System32\sdiagnhost.exe, ?:\Windows\WinSxS\*\TiWorker.exe, ?:\Windows\System32\drvinst.exe, ?:\Program Files (x86)\*.exe, ?:\Program Files\*.exe, ?:\Windows\Temp\*-*-*\DismHost.exe, ?:\$WINDOWS.~BT\Work\*\DismHost.exe, ?:\$WinREAgent\Scratch\*\DismHost.exe, ?:\Windows\SoftwareDistribution\*.exe, ?:\Windows\regedit.exe, ?:\Windows\System32\reg.exe, ?:\Windows\System32\lsass.exe, ?:\Windows\System32\upfc.exe, ?:\Windows\System32\SearchProtocolHost.exe, ?:\Windows\SystemApps\Microsoft.Windows.Search_*\SearchApp.exe, ?:\Windows\System32\conhost.exe, ?:\Windows\System32\oobe\UserOOBEBroker.exe, ?:\Windows\CCM\SCNotification.exe, ?:\Windows\System32\PrintIsolationHost.exe, ?:\Windows\System32\sppsvc.exe, ?:\Windows\System32\backgroundTaskHost.exe, ?:\*\procexp64.exe, C:\Windows\SystemTemp\*\DismHost.exeexcludes:process.executable
registry.data.stringseq?:\WINDOWS\system32\spool\drivers\x64\3\PrintConfig.dllexcludes:registry.data.strings field:"registry.data.strings" value:"?:\WINDOWS\system32\spool\drivers\x64\3\PrintConfig.dll"

Threat Intel IP Address Indicator Match

#
Status
production
Severity
high
Group by
destination.ip, source.ip, threat.indicator.ip
Author
Elastic
Source
github.com/elastic/detection-rules

This rule is triggered when an IP address indicator from the Threat Intel Filebeat module or integrations has a match against a network event.

Rule Body

[metadata]
creation_date = "2023/05/22"
maturity = "production"
updated_date = "2025/04/22"

[transform]
[[transform.osquery]]
label = "Osquery - Retrieve DNS Cache"
query = "SELECT * FROM dns_cache"

[[transform.osquery]]
label = "Osquery - Retrieve All Services"
query = "SELECT description, display_name, name, path, pid, service_type, start_type, status, user_account FROM services"

[[transform.osquery]]
label = "Osquery - Retrieve Services Running on User Accounts"
query = """
SELECT description, display_name, name, path, pid, service_type, start_type, status, user_account FROM services WHERE
NOT (user_account LIKE '%LocalSystem' OR user_account LIKE '%LocalService' OR user_account LIKE '%NetworkService' OR
user_account == null)
"""

[[transform.osquery]]
label = "Osquery - Retrieve Service Unsigned Executables with Virustotal Link"
query = """
SELECT concat('https://www.virustotal.com/gui/file/', sha1) AS VtLink, name, description, start_type, status, pid,
services.path FROM services JOIN authenticode ON services.path = authenticode.path OR services.module_path =
authenticode.path JOIN hash ON services.path = hash.path WHERE authenticode.result != 'trusted'
"""


[rule]
author = ["Elastic"]
description = """
This rule is triggered when an IP address indicator from the Threat Intel Filebeat module or integrations has a match
against a network event.
"""
from = "now-65m"
index = ["auditbeat-*", "endgame-*", "filebeat-*", "logs-*", "packetbeat-*", "winlogbeat-*"]
interval = "1h"
language = "kuery"
license = "Elastic License v2"
name = "Threat Intel IP Address Indicator Match"
note = """## Triage and analysis

### Investigating Threat Intel IP Address Indicator Match

Threat Intel indicator match rules allow matching from a local observation, such as an endpoint event that records a file hash with an entry of a file hash stored within the Threat Intel integrations index.

Matches are based on threat intelligence data that's been ingested during the last 30 days. Some integrations don't place expiration dates on their threat indicators, so we strongly recommend validating ingested threat indicators and reviewing match results. When reviewing match results, check associated activity to determine whether the event requires additional investigation.

This rule is triggered when an IP address indicator from the Threat Intel Filebeat module or a threat intelligence integration matches against a network event.

> **Note**:
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/current/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.

#### Possible investigation steps

- Gain context about the field that matched the local observation so you can understand the nature of the connection. This information can be found in the `threat.indicator.matched.field` field.
- Investigate the IP address, which can be found in the `threat.indicator.matched.atomic` field:
  - Check the reputation of the IP address in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.
  - Execute a reverse DNS lookup to retrieve hostnames associated with the given IP address.
- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.
- Identify the process responsible for the connection, and 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.
- Retrieve the involved process executable and examine the host for derived artifacts that indicate suspicious activities:
  - Analyze the process executable using a private sandboxed analysis system.
  - Observe and collect information about the following activities in both the sandbox and the alert subject host:
    - Attempts to contact external domains and addresses.
      - Use the Elastic Defend network events to determine domains and addresses contacted by the subject process by filtering by the process' `process.entity_id`.
      - Examine the DNS cache for suspicious or anomalous entries.
        - $osquery_0
    - Use the Elastic Defend registry events to examine registry keys accessed, modified, or created by the related processes in the process tree.
    - Examine the host services for suspicious or anomalous entries.
      - $osquery_1
      - $osquery_2
      - $osquery_3
- Using the data collected through the analysis, scope users targeted and other machines infected in the environment.

### False Positive Analysis

- When a match is found, it's important to consider the indicator's initial release date. Threat intelligence is useful for augmenting existing security processes but can quickly become outdated. In other words, some threat intelligence only represents a specific set of activity observed at a specific time. For example, an IP address may have hosted malware observed in a Dridex campaign months ago, but it's possible that IP has been remediated and no longer represents any threat.
- False positives might occur after large and publicly written campaigns if curious employees interact with attacker infrastructure.
- Some feeds may include internal or known benign addresses by mistake (e.g., 8.8.8.8, google.com, 127.0.0.1, etc.). Make sure you understand how blocking a specific domain or address might impact the organization or normal system functioning.

### 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.elastic.co/guide/en/beats/filebeat/current/filebeat-module-threatintel.html",
    "https://www.elastic.co/guide/en/security/current/es-threat-intel-integrations.html",
    "https://www.elastic.co/security/tip",
]
risk_score = 73
rule_id = "0c41e478-5263-4c69-8f9e-7dfd2c22da64"
setup = """## Setup

This rule needs threat intelligence indicators to work.
Threat intelligence indicators can be collected using an [Elastic Agent integration](https://www.elastic.co/guide/en/security/current/es-threat-intel-integrations.html#agent-ti-integration),
the [Threat Intel module](https://www.elastic.co/guide/en/security/current/es-threat-intel-integrations.html#ti-mod-integration),
or a [custom integration](https://www.elastic.co/guide/en/security/current/es-threat-intel-integrations.html#custom-ti-integration).

More information can be found [here](https://www.elastic.co/guide/en/security/current/es-threat-intel-integrations.html).
"""
severity = "high"
tags = ["OS: Windows", "Data Source: Elastic Endgame", "Rule Type: Threat Match", "Resources: Investigation Guide"]
threat_index = ["filebeat-*", "logs-ti_*"]
threat_indicator_path = "threat.indicator"
threat_language = "kuery"
threat_query = """
@timestamp >= "now-30d/d" and event.module:(threatintel or ti_*) and threat.indicator.ip:* and not
labels.is_ioc_transform_source:"true"
"""
timeline_id = "495ad7a7-316e-4544-8a0f-9c098daee76e"
timeline_title = "Generic Threat Match Timeline"
timestamp_override = "event.ingested"
type = "threat_match"

query = '''
source.ip:* or destination.ip:*
'''


[[rule.threat_filters]]

[rule.threat_filters."$state"]
store = "appState"
[rule.threat_filters.meta]
disabled = false
key = "event.category"
negate = false
type = "phrase"
[rule.threat_filters.meta.params]
query = "threat"
[rule.threat_filters.query.match_phrase]
"event.category" = "threat"
[[rule.threat_filters]]

[rule.threat_filters."$state"]
store = "appState"
[rule.threat_filters.meta]
disabled = false
key = "event.kind"
negate = false
type = "phrase"
[rule.threat_filters.meta.params]
query = "enrichment"
[rule.threat_filters.query.match_phrase]
"event.kind" = "enrichment"
[[rule.threat_filters]]

[rule.threat_filters."$state"]
store = "appState"
[rule.threat_filters.meta]
disabled = false
key = "event.type"
negate = false
type = "phrase"
[rule.threat_filters.meta.params]
query = "indicator"
[rule.threat_filters.query.match_phrase]
"event.type" = "indicator"
[[rule.threat_mapping]]

[[rule.threat_mapping.entries]]
field = "source.ip"
type = "mapping"
value = "threat.indicator.ip"

[[rule.threat_mapping]]

[[rule.threat_mapping.entries]]
field = "destination.ip"
type = "mapping"
value = "threat.indicator.ip"


Stages and Predicates

Stage 1: threat_match:event

(destination.ip:* or source.ip:*)

Stage 2: threat_match:indicator

(event.module:"threatintel" or event.module:ti_*) and not labels.is_ioc_transform_source:true and @timestamp >= "now-30d/d" and threat.indicator.ip:*

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
@timestampge
  • now-30d/d corpus 6 (elastic 6)
field:"@timestamp" kind:ge value:"now-30d/d"
destination.ipis_not_null
  • (no value, null check)
field:"dest_ip" kind:is_not_null
event.moduleeq
  • threatintel corpus 5 (elastic 5)
field:"event.module" kind:eq value:"threatintel"
event.modulewildcard
  • ti_* corpus 5 (elastic 5)
field:"event.module" kind:wildcard value:"ti_*"
source.ipis_not_null
  • (no value, null check)
field:"src_ip" kind:is_not_null
threat.indicator.ipis_not_null
  • (no value, null check)
field:"threat.indicator.ip" kind:is_not_null

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
labels.is_ioc_transform_sourceeqtrueexcludes:labels.is_ioc_transform_source field:"labels.is_ioc_transform_source" value:"true"

UAC Bypass via Hijacking WinMgmt MMC

#
Time window
1m
Sequence by
process.entity_id
Source
github.com/elastic/protections-artifacts

Identifies attempts to bypass User Account Control by sideloading a rouge ATL.dll from unusual folder into MMC. Attackers may attempt to hijack DLL search order and stealthily execute code with elevated permissions.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies attempts to bypass User Account Control by sideloading a rouge ATL.dll from unusual folder into MMC.
Attackers may attempt to hijack DLL search order and stealthily execute code with elevated permissions.
"""
id = "0723b937-2ca6-4fda-9da6-3de0026f4802"
license = "Elastic License v2"
name = "UAC Bypass via Hijacking WinMgmt MMC"
os_list = ["windows"]
reference = ["https://github.com/azAgarampur/byeintegrity9-uac"]
version = "1.0.17"

query = '''
sequence by process.entity_id with maxspan=1m
  [process where event.action == "start" and
   process.name : "mmc.exe" and process.command_line : "*WmiMgmt.msc*"]
  [library where
   dll.path : "?:\\Windows\\System32\\wbem\\ATL.dll" and
   not (dll.code_signature.subject_name : "Microsoft *" and dll.code_signature.trusted == true)]
'''

min_endpoint_version = "7.16.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1

[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 1

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1548"
name = "Abuse Elevation Control Mechanism"
reference = "https://attack.mitre.org/techniques/T1548/"
[[threat.technique.subtechnique]]
id = "T1548.002"
name = "Bypass User Account Control"
reference = "https://attack.mitre.org/techniques/T1548/002/"



[threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"
[[threat.technique.subtechnique]]
id = "T1574.001"
name = "DLL"
reference = "https://attack.mitre.org/techniques/T1574/001/"



[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

[internal]
min_endpoint_version = "7.16.0"

Stages and Predicates

Ordered sequence: each step below must occur in order within 1m, correlated by process.entity_id.

Stage 1: process

[process where event.action == "start" and
   process.name : "mmc.exe" and process.command_line : "*WmiMgmt.msc*"]

Stage 2: library

[library where
   dll.path : "?:\\Windows\\System32\\wbem\\ATL.dll" and
   not (dll.code_signature.subject_name : "Microsoft *" and dll.code_signature.trusted == true)]

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

Untrusted or Unsigned binary Execution via Osascript

#
Source
github.com/elastic/protections-artifacts

Detects when Osascript is used to execute an unsigned or untrusted binary. This is highly un-common and has been observed in several malware campaigns in order to execute second-stage payloads.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[rule]
description = """
Detects when Osascript is used to execute an unsigned or untrusted binary. This is highly un-common and has been
observed in several malware campaigns in order to execute second-stage payloads.
"""
id = "8d320f09-1887-4390-905b-6cad0df36653"
license = "Elastic License v2"
name = "Untrusted or Unsigned binary Execution via Osascript"
os_list = ["macos"]
reference = ["https://x.com/malwrhunterteam/status/1844466094159053019"]
version = "1.0.5"

query = '''
process where event.type == "start" and event.action == "exec" and process.parent.name == "osascript" and 
 (process.code_signature.trusted == false or process.code_signature.exists == false) and
 not process.executable like "/opt/homebrew/*" and
 not process.Ext.effective_parent.executable like "/Applications/Alfred 5.app/Contents/MacOS/Alfred"
'''

min_endpoint_version = "8.11.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.002"
name = "AppleScript"
reference = "https://attack.mitre.org/techniques/T1059/002/"



[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"

[internal]
min_endpoint_version = "8.11.0"

Stages and Predicates

Stage 1: process

process where event.type == "start" and event.action == "exec" and process.parent.name == "osascript" and 
 (process.code_signature.trusted == false or process.code_signature.exists == false) and
 not process.executable like "/opt/homebrew/*" and
 not process.Ext.effective_parent.executable like "/Applications/Alfred 5.app/Contents/MacOS/Alfred"

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.Ext.effective_parent.executableeq/Applications/Alfred 5.app/Contents/MacOS/Alfredexcludes:process.Ext.effective_parent.executable field:"process.Ext.effective_parent.executable" value:"/Applications/Alfred 5.app/Contents/MacOS/Alfred"
process.executablestarts_with/opt/homebrew/excludes:process.executable field:"process.executable" value:"/opt/homebrew/"

Unusual Linux Network Connection Discovery

#
Status
production
Severity
low
Author
Elastic
Source
github.com/elastic/detection-rules

Looks for commands related to system network connection discovery from an unusual user context. This can be due to uncommon troubleshooting activity or due to a compromised account. A compromised account may be used by a threat actor to engage in system network connection discovery in order to increase their understanding of connected services and systems. This information may be used to shape follow-up behaviors such as lateral movement or additional discovery.

Known False Positives

  • Uncommon user command activity can be due to an engineer logging onto a server instance in order to perform manual troubleshooting or reconfiguration.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2020/09/03"
integration = ["auditd_manager", "endpoint"]
maturity = "production"
updated_date = "2026/07/27"
min_stack_version = "9.4.0"
min_stack_comments = "Use EA (Entity Analytics) fields"

[rule]
anomaly_threshold = 25
author = ["Elastic"]
description = """
Looks for commands related to system network connection discovery from an unusual user context. This can be due to
uncommon troubleshooting activity or due to a compromised account. A compromised account may be used by a threat actor
to engage in system network connection discovery in order to increase their understanding of connected services and
systems. This information may be used to shape follow-up behaviors such as lateral movement or additional discovery.
"""
false_positives = [
    """
    Uncommon user command activity can be due to an engineer logging onto a server instance in order to perform manual
    troubleshooting or reconfiguration.
    """,
]
from = "now-45m"
interval = "15m"
license = "Elastic License v2"
machine_learning_job_id = ["v3_linux_network_connection_discovery_ea"]
name = "Unusual Linux Network Connection Discovery"
setup = """## Setup

This rule requires the installation of associated Machine Learning jobs, as well as data coming in from one of the following integrations:
- Elastic Defend
- Auditd Manager

### Anomaly Detection Setup

Once the rule is enabled, the associated Machine Learning job will start automatically. You can view the Machine Learning job linked under the "Definition" panel of the detection rule. If the job does not start due to an error, the issue must be resolved for the job to commence successfully. For more details on setting up anomaly detection jobs, refer to the [helper guide](https://www.elastic.co/guide/en/kibana/current/xpack-ml-anomalies.html).

### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.

#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).

#### The following steps should be executed in order to add the Elastic Defend integration to your system:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/current/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).

### Auditd Manager Integration Setup
The Auditd Manager Integration receives audit events from the Linux Audit Framework which is a part of the Linux kernel.
Auditd Manager provides a user-friendly interface and automation capabilities for configuring and monitoring system auditing through the auditd daemon. With `auditd_manager`, administrators can easily define audit rules, track system events, and generate comprehensive audit reports, improving overall security and compliance in the system.

#### The following steps should be executed in order to add the Elastic Agent System integration "auditd_manager" to your system:
- Go to the Kibana home page and click “Add integrations”.
- In the query bar, search for “Auditd Manager” and select the integration to see more details about it.
- Click “Add Auditd Manager”.
- Configure the integration name and optionally add a description.
- Review optional and advanced settings accordingly.
- Add the newly installed “auditd manager” to an existing or a new agent policy, and deploy the agent on a Linux system from which auditd log files are desirable.
- Click “Save and Continue”.
- For more details on the integration refer to the [helper guide](https://docs.elastic.co/integrations/auditd_manager).

#### Rule Specific Setup Note
Auditd Manager subscribes to the kernel and receives events as they occur without any additional configuration.
However, if more advanced configuration is required to detect specific behavior, audit rules can be added to the integration in either the "audit rules" configuration box or the "auditd rule files" box by specifying a file to read the audit rules from.
- For this detection rule no additional audit rules are required.
"""
risk_score = 21
rule_id = "c28c4d8c-f014-40ef-88b6-79a1d67cd499"
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "Data Source: Elastic Defend",
    "Data Source: Auditd Manager",
    "Use Case: Threat Detection",
    "Rule Type: ML",
    "Rule Type: Machine Learning",
    "Tactic: Discovery",
    "Resources: Investigation Guide",
]
type = "machine_learning"
note = """## Triage and analysis

> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

### Investigating Unusual Linux Network Connection Discovery

In Linux environments, network connection discovery tools help administrators understand system connectivity. Adversaries exploit these tools to map networks, aiding in lateral movement and further attacks. The detection rule leverages machine learning to identify atypical usage patterns by unusual users, signaling potential account compromise or unauthorized network probing activities.

### Possible investigation steps

- Review the alert details to identify the specific user account and the command executed that triggered the alert.
- Check the user's activity history to determine if this behavior is consistent with their normal usage patterns or if it is anomalous.
- Investigate the source IP address and hostname associated with the command execution to verify if they are known and trusted within the network.
- Examine system logs for any additional suspicious activities or commands executed by the same user account around the time of the alert.
- Assess the user's access permissions and recent changes to their account to identify any unauthorized modifications or potential compromise.
- Correlate the alert with other security events or alerts to determine if this activity is part of a larger attack pattern or campaign.

### False positive analysis

- Routine administrative tasks by system administrators can trigger alerts. Regularly review and whitelist known administrator accounts performing legitimate network discovery.
- Automated scripts or monitoring tools that perform network checks may be flagged. Identify and exclude these scripts from triggering alerts by adding them to an exception list.
- Uncommon troubleshooting activities by support teams might be misidentified. Document and approve these activities to prevent false positives.
- Scheduled maintenance activities involving network discovery should be accounted for. Create a schedule-based exception to avoid unnecessary alerts during these periods.
- New employees or contractors performing legitimate network discovery as part of their onboarding process can be mistaken for threats. Ensure their activities are monitored and approved by the IT department.

### Response and remediation

- Isolate the affected system from the network to prevent further unauthorized access or lateral movement.
- Terminate any suspicious processes or sessions initiated by the unusual user to halt ongoing network discovery activities.
- Conduct a thorough review of the affected user's account activity and permissions to identify any unauthorized changes or access patterns.
- Reset the credentials of the compromised account and enforce multi-factor authentication to prevent further unauthorized access.
- Analyze network logs and system logs to identify any additional systems that may have been accessed or probed by the threat actor.
- Escalate the incident to the security operations team for further investigation and to determine if additional systems or accounts are compromised.
- Update and enhance network monitoring and alerting rules to detect similar unauthorized network discovery activities in the future."""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1049"
name = "System Network Connections Discovery"
reference = "https://attack.mitre.org/techniques/T1049/"


[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"

Windows Defender Exclusions by Path

#
Time window
1m
Sequence by
process.name, registry.value
Source
github.com/elastic/protections-artifacts

Identifies modifications to the Windows Defender configuration settings to exclude a recently dropped or modified executable.

MITRE ATT&CK Coverage

TacticTechniques
Defense Impairment

Rule Body

[rule]
description = """
Identifies modifications to the Windows Defender configuration settings to exclude a recently dropped or modified
executable.
"""
id = "e6cebe64-0f47-42e9-813e-fd9a53aa59b1"
license = "Elastic License v2"
name = "Windows Defender Exclusions by Path"
os_list = ["windows"]
reference = [
    "https://docs.microsoft.com/en-us/powershell/module/defender/add-mppreference?view=windowsserver2019-ps",
]
version = "1.0.14"

query = '''
sequence with maxspan=1m
[process where event.action == "start" and
 (process.Ext.relative_file_creation_time <= 500 or process.Ext.relative_file_name_modify_time <= 500) and
 not (process.executable : ("?:\\Program Files (x86)\\*.exe", "?:\\Program Files\\*.exe") and process.code_signature.trusted == true) and
 not (process.code_signature.subject_name == "Datto Inc" and process.code_signature.trusted == true)
 ] by process.name
[registry where
 registry.path :
       ("HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Paths\\*",
        "HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Processes\\*")] by registry.value
'''

min_endpoint_version = "8.4.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[[threat.technique.subtechnique]]
id = "T1562.001"
name = "Disable or Modify Tools"
reference = "https://attack.mitre.org/techniques/T1562/001/"



[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

[internal]
min_endpoint_version = "8.4.0"

Stages and Predicates

Ordered sequence: each step below must occur in order within 1m, correlated by process.name, registry.value.

Stage 1: process

[process where event.action == "start" and
 (process.Ext.relative_file_creation_time <= 500 or process.Ext.relative_file_name_modify_time <= 500) and
 not (process.executable : ("?:\\Program Files (x86)\\*.exe", "?:\\Program Files\\*.exe") and process.code_signature.trusted == true) and
 not (process.code_signature.subject_name == "Datto Inc" and process.code_signature.trusted == true)
 ] by process.name

Stage 2: registry

[registry where
 registry.path :
       ("HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Paths\\*",
        "HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Processes\\*")] by registry.value

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq value:"start"
process.Ext.relative_file_creation_timele
  • 500 transforms: number corpus 28 (elastic 28)
field:"process.Ext.relative_file_creation_time" kind:le value:"500"
process.Ext.relative_file_name_modify_timele
  • 500 transforms: number corpus 21 (elastic 21)
field:"process.Ext.relative_file_name_modify_time" kind:le value:"500"
registry.pathwildcard
  • HKLM\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths\*
  • HKLM\SOFTWARE\Microsoft\Windows Defender\Exclusions\Processes\*
field:"TargetObject" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

Back to all Elastic rules