Detection rules › Elastic

Elastic rules: 2h

Attempt to Delete an Okta Policy Rule

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

Detects attempts to delete a rule within an Okta policy. An adversary may attempt to delete an Okta policy rule in order to weaken an organization's security controls.

Known False Positives

  • Consider adding exceptions to this rule to filter false positives if Okta MFA rules are regularly modified in your organization.

MITRE ATT&CK Coverage

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2020/11/06"
integration = ["okta"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Detects attempts to delete a rule within an Okta policy. An adversary may attempt to delete an Okta policy rule in order
to weaken an organization's security controls.
"""
false_positives = [
    """
    Consider adding exceptions to this rule to filter false positives if Okta MFA rules are regularly modified in your
    organization.
    """,
]
index = ["filebeat-*", "logs-okta*"]
language = "kuery"
license = "Elastic License v2"
name = "Attempt to Delete an Okta Policy Rule"
note = """## Triage and analysis

### Investigating Attempt to Delete an Okta Policy Rule

Okta policy rules are integral components of an organization's security controls, as they define how user access to resources is managed. Deletion of a rule within an Okta policy could potentially weaken the organization's security posture, allowing for unauthorized access or facilitating other malicious activities.

This rule detects attempts to delete an Okta policy rule, which could indicate an adversary's attempt to weaken an organization's security controls. Adversaries may do this to circumvent security measures and enable further malicious activities.

#### Possible investigation steps:

- Identify the actor related to the alert by reviewing `okta.actor.id`, `okta.actor.type`, `okta.actor.alternate_id`, or `okta.actor.display_name` fields in the alert.
- Review the `okta.client.user_agent.raw_user_agent` field to understand the device and software used by the actor.
- Examine the `okta.outcome.reason` field for additional context around the deletion attempt.
- Check the `okta.outcome.result` field to confirm the policy rule deletion attempt.
- Check if there are multiple policy rule deletion attempts from the same actor or IP address (`okta.client.ip`).
- Check for successful logins immediately following the policy rule deletion attempt.
- Verify whether the actor's activity aligns with typical behavior or if any unusual activity took place around the time of the deletion attempt.

### False positive analysis:

- Check if there were issues with the Okta system at the time of the deletion attempt. This could indicate a system error rather than a genuine threat activity.
- Check the geographical location (`okta.request.ip_chain.geographical_context`) and time of the deletion attempt. If these match the actor's normal behavior, it might be a false positive.
- Verify the actor's administrative rights to ensure they are correctly configured.

### Response and remediation:

- If unauthorized policy rule deletion is confirmed, initiate the incident response process.
- Immediately lock the affected actor account and require a password change.
- Consider resetting MFA tokens for the actor and require re-enrollment.
- Check if the compromised account was used to access or alter any sensitive data or systems.
- If a specific deletion technique was used, ensure your systems are patched or configured to prevent such techniques.
- Assess the criticality of affected services and servers.
- Work with your IT team to minimize the impact on users and maintain business continuity.
- If multiple accounts are affected, consider a broader reset or audit of MFA tokens.
- Implement security best practices [outlined](https://www.okta.com/blog/2019/10/9-admin-best-practices-to-keep-your-org-secure/) by Okta.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).

## Setup

The Okta Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
references = [
    "https://help.okta.com/en/prod/Content/Topics/Security/Security_Policies.htm",
    "https://developer.okta.com/docs/reference/api/system-log/",
    "https://developer.okta.com/docs/reference/api/event-types/",
    "https://www.elastic.co/security-labs/testing-okta-visibility-and-detection-dorothy",
    "https://www.elastic.co/security-labs/monitoring-okta-threats-with-elastic-security",
    "https://www.elastic.co/security-labs/starter-guide-to-understanding-okta",
]
risk_score = 21
rule_id = "d5d86bf5-cf0c-4c06-b688-53fdc072fdfd"
severity = "low"
tags = [
    "Use Case: Identity and Access Audit",
    "Data Source: Okta",
    "Tactic: Defense Evasion",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset:okta.system and event.action:policy.rule.delete
'''


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

[[rule.threat.technique]]
id = "T1484"
name = "Domain or Tenant Policy Modification"
reference = "https://attack.mitre.org/techniques/T1484/"

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

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

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

Stages and Predicates

Stage 1: query

data_stream.dataset:okta.system and event.action:policy.rule.delete

Indicators

These rows show field, operator, and value matches.

AWS Account Discovery By Rare User

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

Identifies the first time, within a lookback window, an identity performs AWS Organizations or IAM account enumeration APIs. Attackers with compromised credentials often map the organization (accounts, OUs, roots, delegated admins) and account-level metadata (aliases, summary) using the AWS CLI or SDKs. This is a New Terms rule detecting a rare occurrence of the cloud.account.id and user.name pair for these actions.

Known False Positives

  • Organization and security administrators, billing tooling, landing-zone automation, and delegated administrator workflows may call these APIs legitimately. Interactive or one-off use from unusual principals warrants review.

MITRE ATT&CK Coverage

Telemetry Coverage

PlatformRecord / event type
AWSCloudTrail event GetAccountSummary: Retrieves a summary of IAM entity usage and quotas for the current AWS account.
AWSCloudTrail event ListAccountAliases: Lists the alias associated with the current AWS account, if any.
AWSCloudTrail event DescribeOrganization: Retrieves information about the organization that the calling account belongs to.
AWSCloudTrail event DescribeResourcePolicy: Retrieves the resource-based policy that is attached to the organization's management account.
AWSCloudTrail event ListAccounts: Lists all the accounts in the organization.
AWSCloudTrail event ListAccountsForParent: Lists the accounts in an organizational unit or the root that is specified as the parent.
AWSCloudTrail event ListAWSServiceAccessForOrganization: Returns a list of AWS services for which AWS Organizations has enabled integration (trusted access) with the organization.
AWSCloudTrail event ListDelegatedAdministrators: Lists the AWS accounts that are designated as delegated administrators for the specified AWS service in the organization.
AWSCloudTrail event ListDelegatedServicesForAccount: Lists the AWS services for which the specified account is a delegated administrator in the organization.
AWSCloudTrail event ListOrganizationalUnitsForParent: Lists the organizational units (OUs) in a parent root or OU.
AWSCloudTrail event ListPolicies: Retrieves the list of all policies in an organization of a specified type.
AWSCloudTrail event ListRoots: Lists the roots that are defined in the organization.

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2026/04/01"
integration = ["aws"]
maturity = "production"
updated_date = "2026/08/05"
min_stack_version = "9.3.0"
min_stack_comments = "Changing min stack to 9.3.0, the latest minimum supported version for 9.X releases."

[rule]
author = ["Elastic"]
description = """
Identifies the first time, within a lookback window, an identity performs AWS Organizations or IAM account enumeration
APIs. Attackers with compromised credentials often map the organization (accounts, OUs, roots, delegated admins) and
account-level metadata (aliases, summary) using the AWS CLI or SDKs. This is a New Terms rule detecting a rare
occurrence of the `cloud.account.id` and `user.name` pair for these actions.
"""
false_positives = [
    """
    Organization and security administrators, billing tooling, landing-zone automation, and delegated administrator
    workflows may call these APIs legitimately. Interactive or one-off use from unusual principals warrants review.
    """,
]
from = "now-6m"
index = ["logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS Account Discovery By Rare User"
note = """## Triage and analysis

### Investigating AWS Account Discovery By Rare User

AWS Organizations and IAM expose read APIs that reveal organization structure, member accounts, delegation, and
account-level aliases. Threat actors and tools such as Pacu (`organizations__enum`) chain these calls to understand
multi-account layout after credential access.

This rule uses [New Terms](https://www.elastic.co/guide/en/security/current/rules-ui-create.html#create-new-terms-rule) to detect when an identity makes a discovery API call that has not been seen in the configured history window.

### Possible investigation steps

**Identify the actor and session context**
- Confirm who `user.name` and `aws.cloudtrail.user_identity.arn` represent (human, workload role, automation).

**Analyze the source and origin**
- Review source.ip, geolocation, and whether the call aligns with normal egress for that principal.
- Inspect user_agent.original for CLI, Boto3/Botocore, consoles, or unfamiliar tooling.

**Correlate with additional events**
- Correlate with STS*(`GetCallerIdentity`, `AssumeRole`) and broader discovery or privilege changes in the same session.
- If the principal is new or rarely used, review IAM policies and recent key rotation.

### False positive analysis

- Documented org-admin or security roles in the management account; add exceptions by ARN if needed.
- Centralized compliance or CSPM that enumerates org structure on a schedule.

### Response and remediation

- If unexpected, rotate credentials for the implicated principal, review CloudTrail for follow-on API activity, and
  tighten least privilege on Organizations/IAM read APIs where appropriate.

### Additional information

- **[AWS IR Playbooks](https://github.com/aws-samples/aws-incident-response-playbooks)**
"""
references = [
    "https://kudelskisecurity.com/research/investigating-two-variants-of-the-trivy-supply-chain-compromise",
    "https://github.com/RhinoSecurityLabs/pacu/blob/master/pacu/modules/organizations__enum/main.py",
]
risk_score = 21
rule_id = "444c8fad-874f-4f59-b0ea-cf26cea478bd"
severity = "low"
tags = [
    "Domain: Cloud",
    "Domain: Identity",
    "Platform: AWS",
    "Data Source: AWS CloudTrail",
    "Service: AWS IAM",
    "Service: AWS Organizations",
    "Tactic: Discovery",
    "Rule Type: New Terms",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"

query = '''
data_stream.dataset: "aws.cloudtrail"
    and event.outcome: "success"
    and source.ip:*
    and not aws.cloudtrail.session_credential_from_console: "true"
    and not aws.cloudtrail.user_identity.type: "AWSService"
    and (
        (
            event.provider: "organizations.amazonaws.com"
            and event.action: (
                "DescribeOrganization" or "DescribeOrgnanizationalUnit" or "ListAccounts" or "ListRoots"
                or "ListOrganizationalUnitsForParent" or "ListAccountsForParent" or "ListPolicies"
                or "ListAWSServiceAccessForOrganization" or "ListDelegatedAdministrators"
                or "ListDelegatedServicesForAccount" or "DescribeResourcePolicy"
            )
        )
        or (
            event.provider: "iam.amazonaws.com"
            and event.action: ("ListAccountAliases" or "GetAccountSummary")
        )
    )
    and not user_agent.original: (*Terraform*)
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[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 = "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.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",
    "event.provider",
    "cloud.account.id",
    "cloud.region",
]

[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.outcome: "success"
    and source.ip:*
    and not aws.cloudtrail.session_credential_from_console: "true"
    and not aws.cloudtrail.user_identity.type: "AWSService"
    and (
        (
            event.provider: "organizations.amazonaws.com"
            and event.action: (
                "DescribeOrganization" or "DescribeOrgnanizationalUnit" or "ListAccounts" or "ListRoots"
                or "ListOrganizationalUnitsForParent" or "ListAccountsForParent" or "ListPolicies"
                or "ListAWSServiceAccessForOrganization" or "ListDelegatedAdministrators"
                or "ListDelegatedServicesForAccount" or "DescribeResourcePolicy"
            )
        )
        or (
            event.provider: "iam.amazonaws.com"
            and event.action: ("ListAccountAliases" or "GetAccountSummary")
        )
    )
    and not user_agent.original: (*Terraform*)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
data_stream.dataseteq
  • aws.cloudtrail corpus 143 (elastic 143)
field:"data_stream.dataset" kind:eq value:"aws.cloudtrail"
event.actionin
  • DescribeOrganization
  • DescribeOrgnanizationalUnit
  • DescribeResourcePolicy
  • GetAccountSummary corpus 2 (elastic 2)
  • ListAWSServiceAccessForOrganization
  • ListAccountAliases corpus 2 (elastic 2)
  • ListAccounts
  • ListAccountsForParent
  • ListDelegatedAdministrators
  • ListDelegatedServicesForAccount
  • ListOrganizationalUnitsForParent
  • ListPolicies
  • ListRoots
field:"EventType" kind:in
event.outcomeeq
  • success corpus 306 (elastic 306)
field:"event.outcome" kind:eq value:"success"
event.providereq
  • iam.amazonaws.com corpus 24 (elastic 24)
  • organizations.amazonaws.com corpus 3 (elastic 3)
field:"Provider_Name" kind:eq
source.ipis_not_null
  • (no value, null check)
field:"src_ip" kind:is_not_null

Exclusions

The rule actively suppresses these predicates.

Azure AD Graph Access with Unusual User and ASN

#
Status
production
Severity
medium
Time window
9m
Group by
source.as.number, user.id
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies Azure AD Graph (graph.windows.net) requests originating from network sources outside the major public-cloud and Microsoft ASNs that legitimate first-party callers normally come from. Adversary tooling typically rides on commodity hosting (residential ISPs, VPS providers, anonymisers) which produces an ASN distribution very different from the Microsoft / AWS / GCP / Akamai / Cloudflare ranges that dominate legitimate AAD Graph traffic.

Known False Positives

  • Users calling AAD Graph from corporate office networks or home ISPs with custom tooling. Tune the excluded ASN organisation list to your environment.
  • Cloud-hosted internal automation running outside the major providers (smaller cloud or colo). Add exceptions on the calling user or app ID after validation.

MITRE ATT&CK Coverage

TacticTechniques
Initial Access

Rule Body

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

[rule]
author = ["Elastic"]
description = """
Identifies Azure AD Graph (graph.windows.net) requests originating from network sources outside the major
public-cloud and Microsoft ASNs that legitimate first-party callers normally come from. Adversary tooling
typically rides on commodity hosting (residential ISPs, VPS providers, anonymisers) which produces an ASN
distribution very different from the Microsoft / AWS / GCP / Akamai / Cloudflare ranges that dominate
legitimate AAD Graph traffic.
"""
false_positives = [
    """
    Users calling AAD Graph from corporate office networks or home ISPs with custom tooling. Tune the
    excluded ASN organisation list to your environment.
    """,
    """
    Cloud-hosted internal automation running outside the major providers (smaller cloud or colo). Add
    exceptions on the calling user or app ID after validation.
    """,
]
from = "now-9m"
index = ["logs-azure.aadgraphactivitylogs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Azure AD Graph Access with Unusual User and ASN"
note = """## Triage and analysis

### Investigating Azure AD Graph Access with Unusual User and ASN

Legitimate AAD Graph callers in most tenants come from a small set of ASNs: Microsoft itself, the major
hyperscalers (AWS, GCP), and a handful of CDN / edge -networks that proxy first-party traffic. AAD Graph
traffic originating from outside that set, especially from residential ISPs, generic VPS providers, or
anonymising networks, is a signal worth a closer look. This rule excludes the common Microsoft / AWS /
GCP / Akamai / Cloudflare ASN organisations and surfaces everything else.

### Possible investigation steps

- Identify the ASN and the geographic context.
    - `source.as.organization.name`, `source.as.number`, `source.geo.country_name`, `source.geo.city_name`.
- Identify the user and whether the source matches normal behavior.
    - `user.id` and recent legitimate sign-in geo / network for the same user.
- Cross-check user-agent and calling client for known offensive tooling fingerprints.
    - `user_agent.original` (`aiohttp`, `AADInternals`, `curl`, etc.) and `azure.aadgraphactivitylogs.properties.app_id` (FOCI / first-party client IDs).
- Pivot to sign-in logs (`logs-azure.signinlogs-*`) for the same user / source IP to understand how the calling token was obtained.
- Check tenant-wide blast radius.
    - Are other users in the tenant calling from the same ASN within the window? If so, treat as a systematic intrusion rather than a single account compromise.
- Confirm the activity is not attributable to authorized testing (red team engagement, penetration test, internal tooling validation) before treating as malicious.

### Response and remediation

- Revoke refresh tokens and active sessions for the calling 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`.
- Apply Conditional Access requiring compliant device or trusted network for AAD Graph access for the affected user population.
- If the ASN belongs to known abusive infrastructure, add it to a tenant block list (Named Locations / CA policy).
"""
references = [
    "https://learn.microsoft.com/en-us/graph/migrate-azure-ad-graph-overview",
    "https://github.com/dirkjanm/ROADtools",
]
risk_score = 47
rule_id = "fb935960-d132-4bb5-853d-62f86cccc250"
setup = """#### Azure AD Graph Activity Logs
Requires Azure AD Graph Activity Logs ingested into `logs-azure.aadgraphactivitylogs-*` via the Elastic Azure
integration. Enable the `AzureADGraphActivityLogs` diagnostic-settings category on Entra ID. ASN enrichment
depends on the geoip / ASN ingest pipelines applied during integration ingestion.
"""
severity = "medium"
tags = [
    "Domain: Cloud",
    "Data Source: Azure",
    "Data Source: Azure AD Graph",
    "Data Source: Azure AD Graph Activity Logs",
    "Use Case: Identity and Access Audit",
    "Use Case: Threat Detection",
    "Tactic: Initial Access",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"

query = '''
data_stream.dataset:azure.aadgraphactivitylogs and
    user.id:* and source.as.number:(* and
        not (
            3598 or 7224 or 8068 or 8069 or 8070 or
            8071 or 8072 or 8073 or 8074 or 8075 or
            8987 or 12076 or 14618 or 15169 or 16509 or
            19527 or 36040 or 36384 or 36385 or 36492 or
            39111 or 394089 or 396982
        )
    )
'''

[rule.investigation_fields]
field_names = [
    "user.id",
    "source.ip",
    "source.as.number",
    "source.as.organization.name",
    "source.geo.country_name",
    "source.geo.city_name",
    "user_agent.original",
    "azure.aadgraphactivitylogs.properties.app_id",
    "azure.aadgraphactivitylogs.properties.api_version",
    "azure.tenant_id",
]

[[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.new_terms]
field = "new_terms_fields"
value = ["user.id", "source.as.number"]

[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-7d"

Stages and Predicates

Stage 1: new_terms

data_stream.dataset:azure.aadgraphactivitylogs and
    user.id:* and source.as.number:(* and
        not (
            3598 or 7224 or 8068 or 8069 or 8070 or
            8071 or 8072 or 8073 or 8074 or 8075 or
            8987 or 12076 or 14618 or 15169 or 16509 or
            19527 or 36040 or 36384 or 36385 or 36492 or
            39111 or 394089 or 396982
        )
    )

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
source.as.numberin12076, 14618, 15169, 16509, 19527, 3598, 36040, 36384, 36385, 36492, 39111, 394089, 396982, 7224, 8068, 8069, 8070, 8071, 8072, 8073, 8074, 8075, 8987excludes:source.as.number

Azure AD Graph Potential Enumeration (ROADrecon)

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

Detects an Azure AD Graph (graph.windows.net) burst from a user-agent identifying as "aiohttp" (the default HTTP library used by ROADrecon's "gather" command) where a single calling identity issues many requests in a short window. ROADrecon walks every interesting directory object type via aiohttp, producing a large volume of requests from one user / source IP / UA triple. The combination of "aiohttp" UA with a burst threshold is a structural ROADrecon signature; legitimate first-party Microsoft components do not identify as aiohttp.

Known False Positives

  • Developer activity using aiohttp against AAD Graph for prototyping. Rare in production tenants and typically low-volume; the burst threshold limits exposure.
  • Authorized red team activity exercising ROADrecon. Document the engagement window and add exceptions on the source IP or calling user.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2026/05/20"
integration = ["azure"]
maturity = "production"
updated_date = "2026/07/08"

[rule]
author = ["Elastic"]
description = """
Detects an Azure AD Graph (graph.windows.net) burst from a user-agent identifying as "aiohttp" (the default HTTP library
used by ROADrecon's "gather" command) where a single calling identity issues many requests in a short window. ROADrecon
walks every interesting directory object type via aiohttp, producing a large volume of requests from one
user / source IP / UA triple. The combination of "aiohttp" UA with a burst threshold is a structural ROADrecon
signature; legitimate first-party Microsoft components do not identify as aiohttp.
"""
false_positives = [
    """
    Developer activity using aiohttp against AAD Graph for prototyping. Rare in production tenants and typically
    low-volume; the burst threshold limits exposure.
    """,
    """
    Authorized red team activity exercising ROADrecon. Document the engagement window and add exceptions on the source
    IP or calling user.
    """,
]
from = "now-9m"
language = "esql"
license = "Elastic License v2"
name = "Azure AD Graph Potential Enumeration (ROADrecon)"
note = """## Triage and analysis

### Investigating Azure AD Graph Potential Enumeration (ROADrecon)

This is an ES|QL aggregation rule. Alert documents contain summarized fields per burst window: the calling identity, the tenant, and a one-minute bucket. The alert itself is the signal that something resembling ROADrecon's `gather` walk happened against AAD Graph; the actual investigation happens against the raw `logs-azure.aadgraphactivitylogs-*` events for the same identity and window.

### Possible investigation steps

- Confirm the burst by filtering raw AAD Graph activity for the alerting user, tenant, and time window.
    - Filter `logs-azure.aadgraphactivitylogs-*` on the alerting user, tenant, and burst window.
    - ROADrecon's full `gather` walks ~16 directory collections; five or more in a single minute is the structural fingerprint.
- Tool fingerprint: aiohttp UA plus the hardcoded internal API version.
    - `user_agent.original` contains `aiohttp`.
    - `api_version = 1.61-internal` (hardcoded in `gather.py`, returns internal-only fields like `strongAuthenticationDetail`).
    - No first-party Microsoft component identifies as aiohttp or pins `1.61-internal`.
- Calling client + auth method: the typical device-code-flow ROADrecon entrypoint.
    - ROADrecon is usually pointed at the Azure CLI client (`04b07795-…`) via the `-c` flag.
    - Uses a public-client auth method (no client secret or certificate).
- HTTP shape distinguishes enumeration from operator follow-on.
    - `gather` reads only, so GETs dominate.
    - A 403/404 tail indicates the identity probing endpoints it lacks permission for.
    - PATCH / POST / DELETE in the same burst means the operator did more than enumerate.
- Source posture: residential ISP, generic VPS, or anonymising-network egress raises triage priority.
- Pivot to sign-in logs (`logs-azure.signinlogs-*`) via the sign-in correlation ID on each AAD Graph event to land on the originating token-mint.
- Pivot to audit logs (`logs-azure.auditlogs-*`) for any directory writes by the same user near the burst that suggest persistence or modification activity.
- Confirm the activity is not attributable to authorized testing before treating as malicious.
    - Check for red team engagement, penetration test, or internal tooling validation.
    - Validate against the engagement window and the operator's known source range.

### Response and remediation

- Enumerate device registrations created by the user during or around the burst window.
    - `GET /v1.0/users/{id}/registeredDevices` and `GET /v1.0/users/{id}/ownedDevices`.
    - De-register anything not attributable to a known endpoint via `DELETE /v1.0/devices/{deviceObjectId}`.
    - Do this BEFORE session revocation: device-bound PRTs survive `revokeSignInSessions`.
- Revoke refresh tokens and active sessions for the calling 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}`.
- Audit OAuth grants and app role assignments the user holds; revoke anything minted from a kit-egress or otherwise suspicious source.
    - `GET /v1.0/oauth2PermissionGrants?$filter=principalId eq '{id}'`, revoke via `DELETE /v1.0/oauth2PermissionGrants/{grantId}`.
    - `GET /v1.0/users/{id}/appRoleAssignments`, revoke via `DELETE /v1.0/servicePrincipals/{spId}/appRoleAssignedTo/{assignmentId}`.
- Reset the user's password and audit authentication methods added during the window.
    - `GET /v1.0/users/{id}/authentication/methods` to list.
    - Remove anything unexpected via the method-type-specific endpoint.
- Audit directory writes by the user near the burst and roll back unauthorized changes.
    - Query `logs-azure.auditlogs-*` for `Register device`, `Update user`, `User registered security info`, role assignment activity by the same user in the window.
- 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.
"""
references = [
    "https://github.com/dirkjanm/ROADtools",
    "https://github.com/dirkjanm/ROADtools/blob/master/roadrecon/roadtools/roadrecon/gather.py",
    "https://learn.microsoft.com/en-us/graph/migrate-azure-ad-graph-overview",
]
risk_score = 73
rule_id = "80aa6cca-b343-457b-877e-5877cd71a1f8"
setup = """#### Azure AD Graph Activity Logs
Requires Azure AD Graph Activity Logs ingested into `logs-azure.aadgraphactivitylogs-*` via the Elastic Azure integration. Enable the `AzureADGraphActivityLogs` diagnostic-settings category on Entra ID.
"""
severity = "high"
tags = [
    "Domain: Cloud",
    "Data Source: Azure",
    "Data Source: Azure AD Graph",
    "Data Source: Azure AD Graph Activity Logs",
    "Use Case: Threat Detection",
    "Tactic: Discovery",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"

query = '''
from logs-azure.aadgraphactivitylogs-* metadata _id, _version, _index

| where data_stream.dataset == "azure.aadgraphactivitylogs"
  and to_lower(user_agent.original) like "*aiohttp*"

| eval Esql.target_endpoints = case(
    url.path like "*/eligibleRoleAssignments*", "eligibleRoleAssignments",
    url.path like "*/roleAssignments*",         "roleAssignments",
    url.path like "*/users*",                   "users",
    url.path like "*/groups*",                  "groups",
    url.path like "*/servicePrincipals*",       "servicePrincipals",
    url.path like "*/applications*",            "applications",
    url.path like "*/devices*",                 "devices",
    url.path like "*/directoryRoles*",          "directoryRoles",
    url.path like "*/roleDefinitions*",         "roleDefinitions",
    url.path like "*/administrativeUnits*",     "administrativeUnits",
    url.path like "*/contacts*",                "contacts",
    url.path like "*/oauth2PermissionGrants*",  "oauth2PermissionGrants",
    url.path like "*/authorizationPolicy*",     "authorizationPolicy",
    url.path like "*/settings*",                "settings",
    url.path like "*/policies*",                "policies",
    url.path like "*/tenantDetails*",           "tenantDetails",
    "other"
  )
| where Esql.target_endpoints != "other"

| eval Esql.time_window = date_trunc(1 minutes, @timestamp)

| stats
    Esql.request_count                = count(*),
    Esql.distinct_endpoints           = count_distinct(Esql.target_endpoints),
    Esql.api_versions                 = values(azure.aadgraphactivitylogs.properties.api_version),
    Esql.app_ids                      = values(azure.aadgraphactivitylogs.properties.app_id),
    Esql.user_agent                   = values(user_agent.original),
    Esql.http_methods                 = values(http.request.method),
    Esql.status_codes                 = values(http.response.status_code),
    Esql.source_ips                   = values(source.ip),
    Esql.source_asn_orgs              = values(source.`as`.organization.name),
    Esql.source_countries             = values(source.geo.country_name),
    Esql.actor_types                  = values(azure.aadgraphactivitylogs.properties.actor_type),
    Esql.client_auth_methods          = values(azure.aadgraphactivitylogs.properties.client_auth_method),
    Esql.session_ids                  = values(azure.aadgraphactivitylogs.properties.session_id),
    Esql.sign_in_activity_ids         = values(azure.aadgraphactivitylogs.properties.sign_in_activity_id),
    Esql.scopes                       = values(azure.aadgraphactivitylogs.properties.scopes),
    Esql.first_seen                   = min(@timestamp),
    Esql.last_seen                    = max(@timestamp)
  by
    user.id,
    azure.tenant_id,
    Esql.time_window

| where Esql.distinct_endpoints >= 5

| keep
    user.id,
    azure.tenant_id,
    Esql.*
'''

[rule.alert_suppression]
group_by = ["user.id", "azure.tenant_id"]
duration = {value = 5, unit = "m"}
missing_fields_strategy = "suppress"

[[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"]

Stages and Predicates

Stage 1: from

from logs-azure.aadgraphactivitylogs-* metadata _id, _version, _index

Stage 2: where

| where data_stream.dataset == "azure.aadgraphactivitylogs"
  and to_lower(user_agent.original) like "*aiohttp*"

Stage 3: eval

| eval Esql.target_endpoints = case(
    url.path like "*/eligibleRoleAssignments*", "eligibleRoleAssignments",
    url.path like "*/roleAssignments*",         "roleAssignments",
    url.path like "*/users*",                   "users",
    url.path like "*/groups*",                  "groups",
    url.path like "*/servicePrincipals*",       "servicePrincipals",
    url.path like "*/applications*",            "applications",
    url.path like "*/devices*",                 "devices",
    url.path like "*/directoryRoles*",          "directoryRoles",
    url.path like "*/roleDefinitions*",         "roleDefinitions",
    url.path like "*/administrativeUnits*",     "administrativeUnits",
    url.path like "*/contacts*",                "contacts",
    url.path like "*/oauth2PermissionGrants*",  "oauth2PermissionGrants",
    url.path like "*/authorizationPolicy*",     "authorizationPolicy",
    url.path like "*/settings*",                "settings",
    url.path like "*/policies*",                "policies",
    url.path like "*/tenantDetails*",           "tenantDetails",
    "other"
  )
Esql.target_endpoints =
ifurl.path like "*/eligibleRoleAssignments*""eligibleRoleAssignments"
elifurl.path like "*/roleAssignments*""roleAssignments"
elifurl.path like "*/users*""users"
elifurl.path like "*/groups*""groups"
elifurl.path like "*/servicePrincipals*""servicePrincipals"
elifurl.path like "*/applications*""applications"
elifurl.path like "*/devices*""devices"
elifurl.path like "*/directoryRoles*""directoryRoles"
elifurl.path like "*/roleDefinitions*""roleDefinitions"
elifurl.path like "*/administrativeUnits*""administrativeUnits"
elifurl.path like "*/contacts*""contacts"
elifurl.path like "*/oauth2PermissionGrants*""oauth2PermissionGrants"
elifurl.path like "*/authorizationPolicy*""authorizationPolicy"
elifurl.path like "*/settings*""settings"
elifurl.path like "*/policies*""policies"
elifurl.path like "*/tenantDetails*""tenantDetails"
else"other"

Stage 4: where

| where Esql.target_endpoints != "other"

Stage 5: eval

| eval Esql.time_window = date_trunc(1 minutes, @timestamp)

Stage 6: stats

| stats
    Esql.request_count                = count(*),
    Esql.distinct_endpoints           = count_distinct(Esql.target_endpoints),
    Esql.api_versions                 = values(azure.aadgraphactivitylogs.properties.api_version),
    Esql.app_ids                      = values(azure.aadgraphactivitylogs.properties.app_id),
    Esql.user_agent                   = values(user_agent.original),
    Esql.http_methods                 = values(http.request.method),
    Esql.status_codes                 = values(http.response.status_code),
    Esql.source_ips                   = values(source.ip),
    Esql.source_asn_orgs              = values(source.`as`.organization.name),
    Esql.source_countries             = values(source.geo.country_name),
    Esql.actor_types                  = values(azure.aadgraphactivitylogs.properties.actor_type),
    Esql.client_auth_methods          = values(azure.aadgraphactivitylogs.properties.client_auth_method),
    Esql.session_ids                  = values(azure.aadgraphactivitylogs.properties.session_id),
    Esql.sign_in_activity_ids         = values(azure.aadgraphactivitylogs.properties.sign_in_activity_id),
    Esql.scopes                       = values(azure.aadgraphactivitylogs.properties.scopes),
    Esql.first_seen                   = min(@timestamp),
    Esql.last_seen                    = max(@timestamp)
  by
    user.id,
    azure.tenant_id,
    Esql.time_window

Stage 7: where

| where Esql.distinct_endpoints >= 5

Stage 8: keep

| keep
    user.id,
    azure.tenant_id,
    Esql.*

Indicators

These rows show field, operator, and value matches.

Output Fields

These fields are emitted when the rule matches.

FieldSource
user.idKEEP user.id
azure.tenant_idKEEP azure.tenant_id
Esql.*KEEP Esql.*

Azure Compute Restore Point Collections Deleted

#
Status
production
Severity
high
Time window
9m
Group by
azure.activitylogs.identity.claims_initiated_by_user.name
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies multiple Azure Restore Point Collections being deleted by a single user within a short time period. Restore Point Collections contain recovery points for virtual machines, enabling point-in-time recovery capabilities. Mass deletion of these collections is a common tactic used by adversaries during ransomware attacks to prevent victim recovery or to maximize impact during destructive operations. Multiple deletions in rapid succession may indicate malicious intent.

Known False Positives

  • Planned decommissioning activities or large-scale infrastructure changes may result in legitimate bulk deletion of Restore Point Collections. Verify with the user and change management processes whether these deletions are authorized. Large-scale migration or cleanup projects should be coordinated and documented to avoid false positives.

MITRE ATT&CK Coverage

TacticTechniques
Impact

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2025/10/13"
integration = ["azure"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Identifies multiple Azure Restore Point Collections being deleted by a single user within a short time period. Restore
Point Collections contain recovery points for virtual machines, enabling point-in-time recovery capabilities. Mass
deletion of these collections is a common tactic used by adversaries during ransomware attacks to prevent victim
recovery or to maximize impact during destructive operations. Multiple deletions in rapid succession may indicate
malicious intent.
"""
false_positives = [
    """
    Planned decommissioning activities or large-scale infrastructure changes may result in legitimate bulk deletion of
    Restore Point Collections. Verify with the user and change management processes whether these deletions are
    authorized. Large-scale migration or cleanup projects should be coordinated and documented to avoid false positives.
    """,
]
from = "now-9m"
index = ["logs-azure.activitylogs-*", "filebeat-*"]
language = "kuery"
license = "Elastic License v2"
name = "Azure Compute Restore Point Collections Deleted"
note = """## Triage and analysis

### Investigating Azure Compute Restore Point Collections Deleted

Azure Compute Restore Point Collections are essential for disaster recovery, containing snapshots that enable point-in-time recovery
of virtual machines. The ability to quickly restore VMs from these recovery points is critical for business continuity and
incident response.

Adversaries conducting ransomware attacks or destructive operations often target backup and recovery infrastructure to
prevent victims from recovering their systems without paying a ransom. Mass deletion of Restore Point Collections is a
key indicator of such activity and represents a significant threat to an organization's resilience.

This rule detects when a single user deletes multiple Restore Point Collections within a short time window, which is
unusual in normal operations and highly suspicious when observed.

### Possible investigation steps

- Identify the user account responsible for the deletions by examining the `azure.activitylogs.identity.claims_initiated_by_user.name` or `user.name` field in the alerts.
- Review all deletion events from this user in the specified time window to determine the scope and scale of the activity.
- Check the `azure.resource.id` and `azure.resource.name` fields to identify which Restore Point Collections were deleted and assess their criticality to business operations.
- Verify whether the user account has legitimate administrative access and whether these deletions were authorized through change management or documented maintenance activities.
- Investigate the timeline of events leading up to the deletions, looking for other suspicious activities such as:
    - Privilege escalation attempts
    - Deletion of other backup resources (Recovery Services vaults, backup policies)
    - Unusual authentication patterns or geographic anomalies
    - Creation of persistence mechanisms or backdoor accounts
- Review Azure Activity Logs for any failed deletion attempts or access denied events that might indicate reconnaissance activities preceding the successful deletions.
- Check for related data destruction activities, such as deletion of virtual machines, disks, or storage accounts.
- Correlate with sign-in logs to identify any unusual login patterns or potential account compromise indicators.

### False positive analysis

- Large-scale decommissioning projects may involve legitimate deletion of multiple Restore Point Collections. Verify with change management records and create temporary exceptions during documented maintenance windows.
- Infrastructure migrations from Azure to another platform or between Azure regions may involve cleanup of old restore points. Confirm these activities are planned and documented before excluding them from monitoring.
- Automated cleanup scripts designed to manage storage costs by removing old restore points might trigger this alert. Identify the service accounts used for these operations and adjust the threshold or create exceptions as appropriate.
- Testing and development environments that are frequently rebuilt may see regular bulk deletion of resources. Consider excluding non-production environments or adjusting the threshold for these subscriptions.
- Review the threshold value (currently set to 3) and adjust based on your environment's baseline if legitimate administrative activities are frequently triggering false positives.

### Response and remediation

- Immediately isolate the affected user account to prevent further malicious activity. Reset credentials and revoke active sessions.
- Verify the legitimacy of the deletions with the account owner or their manager. If unauthorized, treat this as a confirmed security incident and activate incident response procedures.
- Check if any of the deleted Restore Point Collections can be recovered through Azure backup services, soft-delete features, or other recovery mechanisms. Time is critical as retention policies may limit recovery windows.
- Conduct a comprehensive review of all recent activities by the affected user account across the Azure environment to identify other potentially malicious actions or compromised resources.
- Assess the current disaster recovery posture and identify which VMs are now missing recovery points. Prioritize creation of new restore points for critical systems if they are unaffected.
- Review and strengthen access controls for Restore Point Collection management, implementing stricter RBAC policies and requiring multi-factor authentication for privileged operations.
- If ransomware activity is suspected or confirmed:
    - Activate the organization's ransomware response plan
    - Isolate affected systems to prevent spread
    - Search for ransomware indicators across the environment (encrypted files, ransom notes, suspicious processes)
    - Check for deletion of other recovery resources (Recovery Services vaults, backups, snapshots)
    - Do not pay ransom demands; engage with law enforcement and cybersecurity incident response teams
- Implement additional monitoring and alerting for related activities such as:
    - Deletion of Recovery Services resources
    - Modifications to backup policies
    - Unusual access to disaster recovery infrastructure
- Document the incident thoroughly and conduct a post-incident review to identify gaps in security controls and opportunities for improvement.
- Consider implementing Azure Resource Locks on critical recovery resources to prevent accidental or malicious deletion.
"""
references = [
    "https://www.microsoft.com/en-us/security/blog/2023/07/25/storm-0501-ransomware-attacks-expanding-to-hybrid-cloud-environments/",
]
risk_score = 73
rule_id = "d8f4e3b0-8a1b-11ef-9b4a-f661ea17fbce"
severity = "high"
tags = [
    "Domain: Cloud",
    "Domain: Storage",
    "Data Source: Azure",
    "Data Source: Azure Activity Logs",
    "Use Case: Threat Detection",
    "Tactic: Impact",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "threshold"

query = '''
data_stream.dataset: azure.activitylogs and
    event.action: "MICROSOFT.COMPUTE/RESTOREPOINTCOLLECTIONS/DELETE" and
    event.outcome: (Success or success)
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1490"
name = "Inhibit System Recovery"
reference = "https://attack.mitre.org/techniques/T1490/"


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

[rule.threshold]
field = ["azure.activitylogs.identity.claims_initiated_by_user.name"]
value = 1
[[rule.threshold.cardinality]]
field = "azure.activitylogs.resource.id"
value = 3


Stages and Predicates

Stage 1: query

data_stream.dataset: azure.activitylogs and
    event.action: "MICROSOFT.COMPUTE/RESTOREPOINTCOLLECTIONS/DELETE" and
    event.outcome: (Success or success)
Threshold
gte 1
Cardinality
azure.activitylogs.resource.id ≥ 3

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/RESTOREPOINTCOLLECTIONS/DELETE corpus 2 (elastic 2)
field:"EventType" kind:eq value:"MICROSOFT.COMPUTE/RESTOREPOINTCOLLECTIONS/DELETE"
event.outcomein
  • Success corpus 306 (elastic 306)
  • success corpus 306 (elastic 306)
field:"event.outcome" kind:in

Curl Execution via Env Binary

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

Detects when curl is executed via the env binary. This is a common technique used by adversaries to avoid standard curl focused detections.

MITRE ATT&CK Coverage

TacticTechniques
Command & Control

Rule Body

[rule]
description = """
Detects when curl is executed via the env binary. This is a common technique used by adversaries to avoid standard curl
focused detections.
"""
id = "6fbfa489-517a-4b1a-ada6-e88da2012e7b"
license = "Elastic License v2"
name = "Curl Execution via Env Binary"
os_list = ["macos"]
version = "1.0.8"

query = '''
sequence by process.parent.entity_id with maxspan=30s
[process where event.type == "start" and process.name == "env" and 
  process.args == "-c" and process.args like~ ("*curl*", "*nscurl*")]
[process where event.type == "start" and 
  process.name in ("bash", "sh", "zsh") and
  process.args == "-c" and process.args like~ ("*curl*", "*nscurl*")]
[process where event.type == "start" and process.name in ("curl", "nscurl") and
  not process.parent.executable like ("/Library/Developer/*", "/opt/homebrew/Cellar/*", "/Applications/Xcode.app/Contents/Developer/usr/bin/make")]
'''

min_endpoint_version = "8.5.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 2

[[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.5.0"

Stages and Predicates

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

Stage 1: process

[process where event.type == "start" and process.name == "env" and 
  process.args == "-c" and process.args like~ ("*curl*", "*nscurl*")]

Stage 2: process

[process where event.type == "start" and 
  process.name in ("bash", "sh", "zsh") and
  process.args == "-c" and process.args like~ ("*curl*", "*nscurl*")]

Stage 3: process

[process where event.type == "start" and process.name in ("curl", "nscurl") and
  not process.parent.executable like ("/Library/Developer/*", "/opt/homebrew/Cellar/*", "/Applications/Xcode.app/Contents/Developer/usr/bin/make")]

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

Dynamic Linker (ld.so) Creation

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

This rule detects the creation of the dynamic linker (ld.so). The dynamic linker is used to load shared libraries needed by an executable. Attackers may attempt to replace the dynamic linker with a malicious version to execute arbitrary code.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2024/12/16"
integration = ["endpoint", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
This rule detects the creation of the dynamic linker (ld.so). The dynamic linker is used to load shared libraries
needed by an executable. Attackers may attempt to replace the dynamic linker with a malicious version to execute
arbitrary code.
"""
from = "now-9m"
index = ["logs-endpoint.events.file*", "logs-sentinel_one_cloud_funnel.*", "endgame-*"]
language = "eql"
license = "Elastic License v2"
name = "Dynamic Linker (ld.so) Creation"
note = """## Triage and analysis

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

### Investigating Dynamic Linker (ld.so) Creation

The dynamic linker, ld.so, is crucial in Linux environments for loading shared libraries required by executables. Adversaries may exploit this by replacing it with a malicious version to execute unauthorized code, achieving persistence or evading defenses. The detection rule identifies suspicious creation of ld.so files, excluding benign processes, to flag potential threats.

### Possible investigation steps

- Review the process that triggered the alert by examining the process.executable field to understand which application attempted to create the ld.so file.
- Check the process.name field to ensure the process is not one of the benign processes listed in the exclusion criteria, such as "dockerd", "yum", "dnf", "microdnf", or "pacman".
- Investigate the file.path to confirm the location of the newly created ld.so file and verify if it matches any of the specified directories like "/lib", "/lib64", "/usr/lib", or "/usr/lib64".
- Analyze the parent process of the suspicious executable to determine if it was initiated by a legitimate or potentially malicious source.
- Look for any recent changes or anomalies in the system logs around the time of the file creation event to identify any related suspicious activities.
- Cross-reference the event with other security tools or logs, such as Elastic Defend or SentinelOne, to gather additional context or corroborating evidence of malicious activity.
- Assess the risk and impact of the event by considering the system's role and the potential consequences of a compromised dynamic linker on that system.

### False positive analysis

- Package managers like yum, dnf, microdnf, and pacman can trigger false positives when they update or install packages that involve the dynamic linker. These processes are already excluded in the rule, but ensure any custom package managers or scripts are also considered for exclusion.
- Container management tools such as dockerd may create or modify ld.so files during container operations. If you use other container tools, consider adding them to the exclusion list to prevent false positives.
- System updates or maintenance scripts that involve library updates might create ld.so files. Review these scripts and add them to the exclusion list if they are verified as non-threatening.
- Custom administrative scripts or automation tools that interact with shared libraries could inadvertently trigger the rule. Identify these scripts and exclude them if they are part of regular, secure operations.
- Development environments where ld.so files are frequently created or modified during testing and compilation processes may need specific exclusions for development tools or environments to avoid false positives.

### Response and remediation

- Immediately isolate the affected system from the network to prevent further malicious activity and lateral movement.
- Verify the integrity of the dynamic linker (ld.so) on the affected system by comparing it with a known good version from a trusted source or repository.
- If the dynamic linker has been tampered with, replace it with the verified version and ensure all system binaries are intact.
- Conduct a thorough scan of the system using updated antivirus or endpoint detection tools to identify and remove any additional malicious files or processes.
- Review system logs and the process creation history to identify the source of the unauthorized ld.so creation and any associated malicious activity.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if other systems are affected.
- Implement additional monitoring and alerting for similar suspicious activities, such as unauthorized file creations in critical system directories, to enhance future detection capabilities."""
risk_score = 47
rule_id = "06d555e4-c8ce-4d90-90e1-ec7f66df5a6a"
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: Defense Evasion",
    "Tactic: Execution",
    "Tactic: Persistence",
    "Data Source: Elastic Defend",
    "Data Source: SentinelOne",
    "Data Source: Elastic Endgame",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
file where host.os.type == "linux" and event.type == "creation" and process.executable != null and
file.path like~ ("/lib/ld-linux*.so*", "/lib64/ld-linux*.so*", "/usr/lib/ld-linux*.so*", "/usr/lib64/ld-linux*.so*") and
not (
  process.executable in (
    "/bin/dpkg", "/usr/bin/dpkg", "/bin/dockerd", "/usr/bin/dockerd", "/usr/sbin/dockerd", "/bin/microdnf",
    "/usr/bin/microdnf", "/bin/rpm", "/usr/bin/rpm", "/bin/snapd", "/usr/bin/snapd", "/bin/yum", "/usr/bin/yum",
    "/bin/dnf", "/usr/bin/dnf", "/bin/podman", "/usr/bin/podman", "/bin/dnf-automatic", "/usr/bin/dnf-automatic",
    "/bin/pacman", "/usr/bin/pacman", "/usr/bin/dpkg-divert", "/bin/dpkg-divert", "/sbin/apk", "/usr/sbin/apk",
    "/usr/local/sbin/apk", "/usr/bin/apt", "/usr/sbin/pacman", "/bin/podman", "/usr/bin/podman", "/usr/bin/puppet",
    "/bin/puppet", "/opt/puppetlabs/puppet/bin/puppet", "/usr/bin/chef-client", "/bin/chef-client",
    "/bin/autossl_check", "/usr/bin/autossl_check", "/proc/self/exe", "/dev/fd/*",  "/usr/bin/pamac-daemon",
    "/bin/pamac-daemon", "/usr/lib/snapd/snapd", "/usr/local/bin/dockerd", "/usr/libexec/platform-python",
    "/usr/lib/snapd/snap-update-ns", "./usr/bin/podman", "/usr/bin/crio", "/usr/bin/buildah", "/bin/dnf5",
    "/usr/bin/dnf5", "/usr/bin/pamac", "/dev/fd/3"
  ) or
  process.executable like (
    "/snap/docker/*/bin/dockerd", "/usr/bin/python*", "/nix/store/*/docker/dockerd", "/var/lib/docker/overlay2/*/dockerd",
    "/rpool/data/*usr/bin/dockerd"
  )
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"

[[rule.threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"

[[rule.threat.technique.subtechnique]]
id = "T1574.006"
name = "Dynamic Linker Hijacking"
reference = "https://attack.mitre.org/techniques/T1574/006/"

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

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

[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"

[[rule.threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"

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

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

[[rule.threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"

[[rule.threat.technique.subtechnique]]
id = "T1574.006"
name = "Dynamic Linker Hijacking"
reference = "https://attack.mitre.org/techniques/T1574/006/"

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

Stages and Predicates

Stage 1: file

file where host.os.type == "linux" and event.type == "creation" and process.executable != null and
file.path like~ ("/lib/ld-linux*.so*", "/lib64/ld-linux*.so*", "/usr/lib/ld-linux*.so*", "/usr/lib64/ld-linux*.so*") and
not (
  process.executable in (
    "/bin/dpkg", "/usr/bin/dpkg", "/bin/dockerd", "/usr/bin/dockerd", "/usr/sbin/dockerd", "/bin/microdnf",
    "/usr/bin/microdnf", "/bin/rpm", "/usr/bin/rpm", "/bin/snapd", "/usr/bin/snapd", "/bin/yum", "/usr/bin/yum",
    "/bin/dnf", "/usr/bin/dnf", "/bin/podman", "/usr/bin/podman", "/bin/dnf-automatic", "/usr/bin/dnf-automatic",
    "/bin/pacman", "/usr/bin/pacman", "/usr/bin/dpkg-divert", "/bin/dpkg-divert", "/sbin/apk", "/usr/sbin/apk",
    "/usr/local/sbin/apk", "/usr/bin/apt", "/usr/sbin/pacman", "/bin/podman", "/usr/bin/podman", "/usr/bin/puppet",
    "/bin/puppet", "/opt/puppetlabs/puppet/bin/puppet", "/usr/bin/chef-client", "/bin/chef-client",
    "/bin/autossl_check", "/usr/bin/autossl_check", "/proc/self/exe", "/dev/fd/*",  "/usr/bin/pamac-daemon",
    "/bin/pamac-daemon", "/usr/lib/snapd/snapd", "/usr/local/bin/dockerd", "/usr/libexec/platform-python",
    "/usr/lib/snapd/snap-update-ns", "./usr/bin/podman", "/usr/bin/crio", "/usr/bin/buildah", "/bin/dnf5",
    "/usr/bin/dnf5", "/usr/bin/pamac", "/dev/fd/3"
  ) or
  process.executable like (
    "/snap/docker/*/bin/dockerd", "/usr/bin/python*", "/nix/store/*/docker/dockerd", "/var/lib/docker/overlay2/*/dockerd",
    "/rpool/data/*usr/bin/dockerd"
  )
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.typeeq
  • creation
field:"event.type" kind:eq value:"creation"
file.pathwildcard
  • /lib/ld-linux*.so*
  • /lib64/ld-linux*.so*
  • /usr/lib/ld-linux*.so*
  • /usr/lib64/ld-linux*.so*
field:"TargetFilename" kind:wildcard
process.executableis_not_null
  • (no value, null check)
field:"Image" kind:is_not_null

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.executablein./usr/bin/podman, /bin/autossl_check, /bin/chef-client, /bin/dnf, /bin/dnf-automatic, /bin/dnf5, /bin/dockerd, /bin/dpkg, /bin/dpkg-divert, /bin/microdnf, /bin/pacman, /bin/pamac-daemon, /bin/podman, /bin/puppet, /bin/rpm, /bin/snapd, /bin/yum, /dev/fd/*, /dev/fd/3, /opt/puppetlabs/puppet/bin/puppet, /proc/self/exe, /sbin/apk, /usr/bin/apt, /usr/bin/autossl_check, /usr/bin/buildah, /usr/bin/chef-client, /usr/bin/crio, /usr/bin/dnf, /usr/bin/dnf-automatic, /usr/bin/dnf5, /usr/bin/dockerd, /usr/bin/dpkg, /usr/bin/dpkg-divert, /usr/bin/microdnf, /usr/bin/pacman, /usr/bin/pamac, /usr/bin/pamac-daemon, /usr/bin/podman, /usr/bin/puppet, /usr/bin/rpm, /usr/bin/snapd, /usr/bin/yum, /usr/lib/snapd/snap-update-ns, /usr/lib/snapd/snapd, /usr/libexec/platform-python, /usr/local/bin/dockerd, /usr/local/sbin/apk, /usr/sbin/apk, /usr/sbin/dockerd, /usr/sbin/pacmanexcludes:process.executable
process.executablewildcard/snap/docker/*/bin/dockerd, /usr/bin/python*, /nix/store/*/docker/dockerd, /var/lib/docker/overlay2/*/dockerd, /rpool/data/*usr/bin/dockerdexcludes:process.executable

Entra ID Actor Token User Impersonation Abuse

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

Identifies potential abuse of actor tokens in Microsoft Entra ID audit logs. Actor tokens are undocumented backend mechanisms used by Microsoft for service-to-service (S2S) operations, allowing services to perform actions on behalf of users. These tokens appear in logs with the service's display name but the impersonated user's UPN. While some legitimate Microsoft operations use actor tokens, unexpected usage may indicate exploitation of CVE-2025-55241, which allowed unauthorized access to Azure AD Graph API across tenants before being patched by Microsoft.

Known False Positives

  • Creating specific groups via the Exchange Online PowerShell module will make Exchange use an Actor token on your behalf. The rule excludes group operations and directory feature operations to reduce false positives from these legitimate administrative activities.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2025/09/18"
integration = ["azure"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
Identifies potential abuse of actor tokens in Microsoft Entra ID audit logs. Actor tokens are undocumented backend
mechanisms used by Microsoft for service-to-service (S2S) operations, allowing services to perform actions on behalf
of users. These tokens appear in logs with the service's display name but the impersonated user's UPN. While some
legitimate Microsoft operations use actor tokens, unexpected usage may indicate exploitation of CVE-2025-55241, which
allowed unauthorized access to Azure AD Graph API across tenants before being patched by Microsoft.
"""
false_positives = [
    """
    Creating specific groups via the Exchange Online PowerShell module will make Exchange use an Actor token on your
    behalf. The rule excludes group operations and directory feature operations to reduce false positives from these
    legitimate administrative activities.
    """,
]
from = "now-9m"
interval = "8m"
language = "esql"
license = "Elastic License v2"
name = "Entra ID Actor Token User Impersonation Abuse"
note = """## Triage and analysis

### Investigating Entra ID Actor Token User Impersonation Abuse

This rule detects when Microsoft services use actor tokens to perform operations in audit logs. Actor tokens are undocumented backend mechanisms used by Microsoft for service-to-service (S2S) communication. They appear with a mismatch: the service's display name but the impersonated user's UPN. While some operations legitimately use actor tokens, unexpected usage may indicate exploitation of CVE-2025-55241, which allowed attackers to obtain Global Admin privileges across any Entra ID tenant. Note that this vulnerability has been patched by Microsoft as of September 2025.

### Possible investigation steps

- Review the `azure.auditlogs.properties.initiated_by.user.userPrincipalName` field to identify which service principals are exhibiting this behavior.
- Check the `azure.auditlogs.properties.initiated_by.user.displayName` to confirm these are legitimate Microsoft services.
- Analyze the actions performed by these service principals - look for privilege escalations, permission grants, or unusual administrative operations.
- Review the timing and frequency of these events to identify potential attack patterns or automated exploitation.
- Cross-reference with recent administrative changes or service configurations that might explain legitimate use cases.
- Check if any new applications or service principals were registered recently that could be related to this activity.
- Investigate any correlation with other suspicious authentication events or privilege escalation attempts in your tenant.

### False positive analysis

- Legitimate Microsoft service migrations or updates may temporarily exhibit this behavior.
- Third-party integrations using Microsoft Graph or other APIs might trigger this pattern during normal operations.
- Automated administrative tools or scripts using service principal authentication could be misconfigured.

### Response and remediation

- Immediately review and audit all service principal permissions and recent consent grants in your Entra ID tenant.
- Disable or restrict any suspicious service principals exhibiting this behavior until verified.
- Review and revoke any unnecessary application permissions, especially those with high privileges.
- Enable and review Entra ID audit logs for any permission grants or role assignments made by these service principals.
- Implement Conditional Access policies to restrict service principal authentication from unexpected locations or conditions.
- Enable Entra ID Identity Protection to detect and respond to risky service principal behaviors.
- Review and harden application consent policies to prevent unauthorized service principal registrations.
- Consider implementing privileged identity management (PIM) for service principal role assignments.
"""
references = [
    "https://dirkjanm.io/obtaining-global-admin-in-every-entra-id-tenant-with-actor-tokens/",
    "https://msrc.microsoft.com/update-guide/en-US/advisory/CVE-2025-55241"
]
risk_score = 47
rule_id = "8e7a4f2c-9b3d-4e5a-a1b6-c2d8f7e9b3a5"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Domain: Identity",
    "Data Source: Azure",
    "Data Source: Entra ID",
    "Data Source: Entra Audit Logs",
    "Use Case: Identity and Access Audit",
    "Use Case: Threat Detection",
    "Tactic: Initial Access",
    "Tactic: Privilege Escalation",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"

query = '''
from logs-azure.auditlogs-* metadata _id, _version, _index
| where azure.auditlogs.properties.initiated_by.user.displayName in (
    "Office 365 Exchange Online",
    "Skype for Business Online",
    "Dataverse",
    "Office 365 SharePoint Online",
    "Microsoft Dynamics ERP"
  ) and
  not azure.auditlogs.operation_name like "*group*" and
  azure.auditlogs.operation_name != "Set directory feature on tenant"
  and azure.auditlogs.properties.initiated_by.user.userPrincipalName rlike ".+@[A-Za-z0-9.]+\\.[A-Za-z]{2,}"
| keep
    @timestamp,
    azure.*,
    client.*,
    event.*,
    source.*,
    _id,
    _version,
    _index
'''


[[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 = "T1548"
name = "Abuse Elevation Control Mechanism"
reference = "https://attack.mitre.org/techniques/T1548/"

[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"

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

[[rule.threat.technique]]
id = "T1550"
name = "Use Alternate Authentication Material"
reference = "https://attack.mitre.org/techniques/T1550/"

[[rule.threat.technique.subtechnique]]
id = "T1550.001"
name = "Application Access Token"
reference = "https://attack.mitre.org/techniques/T1550/001/"

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

Stages and Predicates

Stage 1: from

from logs-azure.auditlogs-* metadata _id, _version, _index

Stage 2: where

| where azure.auditlogs.properties.initiated_by.user.displayName in (
    "Office 365 Exchange Online",
    "Skype for Business Online",
    "Dataverse",
    "Office 365 SharePoint Online",
    "Microsoft Dynamics ERP"
  ) and
  not azure.auditlogs.operation_name like "*group*" and
  azure.auditlogs.operation_name != "Set directory feature on tenant"
  and azure.auditlogs.properties.initiated_by.user.userPrincipalName rlike ".+@[A-Za-z0-9.]+\\.[A-Za-z]{2,}"

Stage 3: keep

| keep
    @timestamp,
    azure.*,
    client.*,
    event.*,
    source.*,
    _id,
    _version,
    _index

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
azure.auditlogs.operation_namematchgroupexcludes:azure.auditlogs.operation_name field:"azure.auditlogs.operation_name" value:"group"

Output Fields

These fields are emitted when the rule matches.

FieldSource
@timestampKEEP @timestamp
azure.*KEEP azure.*
client.*KEEP client.*
event.*KEEP event.*
source.*KEEP source.*
_idKEEP _id
_versionKEEP _version
_indexKEEP _index

GenAI Process Connection to Suspicious Top Level Domain

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

Detects when GenAI tools connect to domains using suspicious TLDs commonly abused for malware C2 infrastructure. TLDs like .top, .xyz, .ml, .cf, .onion are frequently used in phishing and malware campaigns. Legitimate GenAI services use well-established domains (.com, .ai, .io), so connections to suspicious TLDs may indicate compromised tools, malicious plugins, or AI-generated code connecting to attacker infrastructure.

MITRE ATT&CK Coverage

TacticTechniques
Command & Control

MITRE ATLAS Coverage

Adversarial-ML threat framework (not MITRE ATT&CK).

Rule Body

[metadata]
creation_date = "2025/12/04"
integration = ["endpoint", "windows"]
maturity = "production"
updated_date = "2025/12/04"

[rule]
author = ["Elastic"]
description = """
Detects when GenAI tools connect to domains using suspicious TLDs commonly abused for malware C2 infrastructure. TLDs
like .top, .xyz, .ml, .cf, .onion are frequently used in phishing and malware campaigns. Legitimate GenAI services use
well-established domains (.com, .ai, .io), so connections to suspicious TLDs may indicate compromised tools, malicious
plugins, or AI-generated code connecting to attacker infrastructure.
"""
from = "now-9m"
index = ["logs-endpoint.events.network*", "winlogbeat-*", "logs-windows.sysmon_operational-*"]
language = "eql"
license = "Elastic License v2"
name = "GenAI Process Connection to Suspicious Top Level Domain"
note = """## Triage and analysis

### Investigating GenAI Process Connection to Suspicious Top Level Domain

This rule detects GenAI tools connecting to domains with TLDs commonly abused by malware. The suspicious TLD filter makes this a high-signal rule with low expected volume.

### Possible investigation steps

- Review the GenAI process command line to identify which tool is running and verify if it's an expected/authorized tool.
- Examine the network connection details (destination IP, port, protocol) to understand the nature of the communication.
- Check the process execution chain to identify the full attack path and initial entry point.
- Investigate the user account associated with the GenAI process to determine if this activity is expected for that user.
- Review network traffic patterns to identify data exfiltration or command and control communications.
- Check for other alerts or suspicious activity on the same host around the same time.
- Verify if the GenAI tool is from a trusted source and if it's authorized for use in your environment.
- Confirm whether the suspicious domain is used by package registries, CDN mirrors, or AI plugin repos.
- Check if the GenAI tool attempted follow-up actions such as downloading scripts, connecting to IPs directly, or loading remote models.
- Inspect whether the domain matches prompt-redirections, malicious AI plugins, or compromised package dependencies.

### False positive analysis

- Legitimate GenAI tools may occasionally connect to domains using suspicious TLDs if they're legitimate services.
- Package managers (npx, pnpm, yarn, bunx) may connect to package registries or CDNs that use suspicious TLDs. Review and exclude known legitimate package registries if needed.
- Some third-party AI plugin ecosystems (VSCode AI plugins, Cursor extensions) may download assets from unusual TLDs; verify allowlists.

### Response and remediation

- Terminate the GenAI process and any spawned child processes to stop the malicious activity.
- Review and revoke any API keys, tokens, or credentials that may have been exposed or used by the GenAI tool.
- Block the identified suspicious domains at the network level.
- Investigate the GenAI tool configuration to identify how it was configured and what it was authorized to access.
- Update security policies to restrict or monitor GenAI tool usage in the environment, especially for network communications.
- Add detection for secondary indicators (reverse shells, encoded C2 traffic, odd user-agent strings).
"""
references = [
    "https://www.cybercrimeinfocenter.org/top-20-tlds-by-malicious-phishing-domains",
    "https://atlas.mitre.org/techniques/AML.T0086",
    "https://www.elastic.co/security-labs/elastic-advances-llm-security",
]
risk_score = 47
rule_id = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: macOS",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Command and Control",
    "Data Source: Elastic Defend",
    "Data Source: Sysmon",
    "Resources: Investigation Guide",
    "Domain: LLM",
    "Mitre Atlas: T0086",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
network where host.os.type in ("macos", "windows") and

  // GenAI processes
  process.name in (
    "ollama.exe", "ollama", "Ollama",
    "textgen.exe", "textgen", "text-generation-webui.exe", "oobabooga.exe",
    "lmstudio.exe", "lmstudio", "LM Studio",
    "claude.exe", "claude", "Claude",
    "cursor.exe", "cursor", "Cursor",
    "copilot.exe", "copilot", "Copilot",
    "codex.exe", "codex",
    "Jan", "jan.exe", "jan",
    "gpt4all.exe", "gpt4all", "GPT4All",
    "gemini-cli.exe", "gemini-cli",
    "genaiscript.exe", "genaiscript",
    "grok.exe", "grok",
    "qwen.exe", "qwen",
    "koboldcpp.exe", "koboldcpp", "KoboldCpp",
    "llama-server", "llama-cli",
    "deno.exe", "deno",
    "npx", "pnpm", "yarn", "bunx"
  ) and

  // Suspicious TLDs 
  (
    // Windows DNS events
    (host.os.type == "windows" and dns.question.name != null and
     dns.question.name regex """.*\.(top|buzz|xyz|rest|ml|cf|gq|ga|onion|monster|cyou|quest|cc|bar|cfd|click|cam|surf|tk|shop|club|icu|pw|ws|online|fun|life|boats|store|hair|skin|motorcycles|christmas|lol|makeup|mom|bond|beauty|biz|live|work|zip|country|accountant|date|party|science|loan|win|men|faith|review|racing|download|host)""") or

    // macOS network events
    (host.os.type == "macos" and destination.domain != null and
     destination.domain regex """.*\.(top|buzz|xyz|rest|ml|cf|gq|ga|onion|monster|cyou|quest|cc|bar|cfd|click|cam|surf|tk|shop|club|icu|pw|ws|online|fun|life|boats|store|hair|skin|motorcycles|christmas|lol|makeup|mom|bond|beauty|biz|live|work|zip|country|accountant|date|party|science|loan|win|men|faith|review|racing|download|host)""")

    // Linux DNS events
    // Revist when available
  )
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"
[[rule.threat.technique.subtechnique]]
id = "T1071.004"
name = "DNS"
reference = "https://attack.mitre.org/techniques/T1071/004/"



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

Stages and Predicates

Stage 1: network

network where host.os.type in ("macos", "windows") and
  process.name in (
    "ollama.exe", "ollama", "Ollama",
    "textgen.exe", "textgen", "text-generation-webui.exe", "oobabooga.exe",
    "lmstudio.exe", "lmstudio", "LM Studio",
    "claude.exe", "claude", "Claude",
    "cursor.exe", "cursor", "Cursor",
    "copilot.exe", "copilot", "Copilot",
    "codex.exe", "codex",
    "Jan", "jan.exe", "jan",
    "gpt4all.exe", "gpt4all", "GPT4All",
    "gemini-cli.exe", "gemini-cli",
    "genaiscript.exe", "genaiscript",
    "grok.exe", "grok",
    "qwen.exe", "qwen",
    "koboldcpp.exe", "koboldcpp", "KoboldCpp",
    "llama-server", "llama-cli",
    "deno.exe", "deno",
    "npx", "pnpm", "yarn", "bunx"
  ) and
  (
    (host.os.type == "windows" and dns.question.name != null and
     dns.question.name regex """.*\.(top|buzz|xyz|rest|ml|cf|gq|ga|onion|monster|cyou|quest|cc|bar|cfd|click|cam|surf|tk|shop|club|icu|pw|ws|online|fun|life|boats|store|hair|skin|motorcycles|christmas|lol|makeup|mom|bond|beauty|biz|live|work|zip|country|accountant|date|party|science|loan|win|men|faith|review|racing|download|host)""") or
    (host.os.type == "macos" and destination.domain != null and
     destination.domain regex """.*\.(top|buzz|xyz|rest|ml|cf|gq|ga|onion|monster|cyou|quest|cc|bar|cfd|click|cam|surf|tk|shop|club|icu|pw|ws|online|fun|life|boats|store|hair|skin|motorcycles|christmas|lol|makeup|mom|bond|beauty|biz|live|work|zip|country|accountant|date|party|science|loan|win|men|faith|review|racing|download|host)""")
  )

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
destination.domainis_not_null
  • (no value, null check)
field:"DestinationHostname" kind:is_not_null
destination.domainregex_match
  • .*.(top|buzz|xyz|rest|ml|cf|gq|ga|onion|monster|cyou|quest|cc|bar|cfd|click|cam|surf|tk|shop|club|icu|pw|ws|online|fun|life|boats|store|hair|skin|motorcycles|christmas|lol|makeup|mom|bond|beauty|biz|live|work|zip|country|accountant|date|party|science|loan|win|men|faith|review|racing|download|host)
field:"DestinationHostname" kind:regex_match value:".*.(top|buzz|xyz|rest|ml|cf|gq|ga|onion|monster|cyou|quest|cc|bar|cfd|click|cam|surf|tk|shop|club|icu|pw|ws|online|fun|life|boats|store|hair|skin|motorcycles|christmas|lol|makeup|mom|bond|beauty|biz|live|work|zip|country|accountant|date|party|science|loan|win|men|faith|review|racing|download|host)"
dns.question.nameis_not_null
  • (no value, null check)
field:"QueryName" kind:is_not_null
dns.question.nameregex_match
  • .*.(top|buzz|xyz|rest|ml|cf|gq|ga|onion|monster|cyou|quest|cc|bar|cfd|click|cam|surf|tk|shop|club|icu|pw|ws|online|fun|life|boats|store|hair|skin|motorcycles|christmas|lol|makeup|mom|bond|beauty|biz|live|work|zip|country|accountant|date|party|science|loan|win|men|faith|review|racing|download|host)
field:"QueryName" kind:regex_match value:".*.(top|buzz|xyz|rest|ml|cf|gq|ga|onion|monster|cyou|quest|cc|bar|cfd|click|cam|surf|tk|shop|club|icu|pw|ws|online|fun|life|boats|store|hair|skin|motorcycles|christmas|lol|makeup|mom|bond|beauty|biz|live|work|zip|country|accountant|date|party|science|loan|win|men|faith|review|racing|download|host)"
process.namein
  • Claude
  • Copilot
  • Cursor corpus 2 (elastic 2)
  • GPT4All
  • Jan
  • KoboldCpp
  • LM Studio corpus 2 (elastic 2)
  • Ollama
  • bunx
  • claude corpus 3 (elastic 3)
  • claude.exe corpus 3 (elastic 3)
  • codex corpus 3 (elastic 3)
  • codex.exe corpus 3 (elastic 3)
  • copilot corpus 3 (elastic 3)
  • copilot.exe corpus 3 (elastic 3)
  • cursor corpus 4 (elastic 4)
  • cursor.exe corpus 2 (elastic 2)
  • deno corpus 8 (elastic 8)
  • deno.exe
  • gemini-cli corpus 3 (elastic 3)
  • gemini-cli.exe corpus 3 (elastic 3)
  • genaiscript corpus 2 (elastic 2)
  • genaiscript.exe corpus 2 (elastic 2)
  • gpt4all corpus 2 (elastic 2)
  • gpt4all.exe corpus 2 (elastic 2)
  • grok corpus 2 (elastic 2)
  • grok.exe corpus 2 (elastic 2)
  • jan corpus 2 (elastic 2)
  • jan.exe corpus 2 (elastic 2)
  • koboldcpp corpus 2 (elastic 2)
  • koboldcpp.exe corpus 2 (elastic 2)
  • llama-cli corpus 2 (elastic 2)
  • llama-server corpus 2 (elastic 2)
  • lmstudio corpus 2 (elastic 2)
  • lmstudio.exe corpus 2 (elastic 2)
  • npx corpus 2 (elastic 2)
  • ollama corpus 4 (elastic 4)
  • ollama.exe corpus 4 (elastic 4)
  • oobabooga.exe corpus 2 (elastic 2)
  • pnpm
  • qwen corpus 2 (elastic 2)
  • qwen.exe corpus 2 (elastic 2)
  • text-generation-webui.exe corpus 2 (elastic 2)
  • textgen corpus 2 (elastic 2)
  • textgen.exe corpus 2 (elastic 2)
  • yarn corpus 2 (elastic 2)
field:"process_basename" kind:in

Ingress Tool Transfer via CURL

#
Source
github.com/elastic/protections-artifacts

Identifies downloads of remote content using Windows CURL executable. This tactic may be indicative of malicious activity where malware is downloading second stage payloads using built-in Windows programs.

MITRE ATT&CK Coverage

TacticTechniques
Command & Control

Rule Body

[rule]
description = """
Identifies downloads of remote content using Windows CURL executable. This tactic may be indicative of malicious
activity where malware is downloading second stage payloads using built-in Windows programs.
"""
id = "336ada1c-69f8-46e8-bdd2-790c85429696"
license = "Elastic License v2"
name = "Ingress Tool Transfer via CURL"
os_list = ["windows"]
version = "1.0.34"

query = '''
process where event.action == "start" and

 /* renamed curl or curl running from normal users writable folders are very noisy */
 process.executable : ("?:\\Windows\\System32\\curl.exe", "?:\\Windows\\SysWOW64\\curl.exe") and

 (
  (process.args_count == 2 and process.command_line : "*http*" and process.parent.name : "cmd.exe" and
   process.parent.command_line : "*  /c curl*") or

  (process.args : ("-o", "--output") and
   (
    (process.parent.name : ("powershell.exe", "mshta.exe", "wscript.exe", "cscript.exe", "rundll32.exe", "regsvr32.exe") and
     process.parent.args_count >= 2) or

     (process.parent.name : "cmd.exe" and process.parent.command_line : ("*curl*", "*^*^*^*")) or

     descendant of [process where process.name : ("winword.exe", "excel.exe", "powerpnt.exe", "wscript.exe")] or

     process.parent.executable : ("?:\\Users\\Public\\*", "?:\\Users\\*\\AppData\\*", "?:\\ProgramData\\*")
   ))
  ) and
  /* lot of legit curl execution via custom bat scripts or interactively via cmd or powershell */
  not (process.parent.name : "cmd.exe" and process.parent.args :( "*.bat*", "\\\\*.jpg", "curl -L -o \\\\*", "config_%c%a%b_%d%e%f.xml")) and
  not (process.parent.name : ("cmd.exe", "powershell.exe") and process.parent.args_count == 1) and
  not process.parent.executable : "?:\\Users\\*\\AppData\\Local\\Temp\\nsc*.tmp\\*.exe" and
  not process.command_line : ("*curl -o \\\\.\\nul -v -I -L -s --connect-timeout*", "*http://127.0.0.1:*", "*http://localhost:*") and
  not process.args : ("https://mirror.init7.net/ctan/systems*", "http://localhost:*",
                      "https://*.ctan.org*", "texlive/curl", "http*.local/*",
                      "http://control.firstvoucher.com/api/build/*zip",
                      "https://blackhole.blob.core.windows.net/*",
                      "https://*.cw-onlineupdate.de/*",
                      "https://gitea.*.prod/*",
                      "https://dl.google.com/*") and

  /* avoid breaking privileged install */
  not user.id : "S-1-5-18" and
  not (process.parent.name : "cmd.exe" and process.parent.command_line like~ "*oi-vscode-server*run.app*") and
  not (process.parent.name : "cmd.exe" and process.parent.command_line like~ "*nexuspayables.com*showImage.php*") and
  not (process.parent.command_line like~ "*VoicemodInstaller*" and process.parent.name like~ "VoicemodInstaller*")
'''

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

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


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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Stage 1: process

process where event.action == "start" and
 process.executable : ("?:\\Windows\\System32\\curl.exe", "?:\\Windows\\SysWOW64\\curl.exe") and
 (
  (process.args_count == 2 and process.command_line : "*http*" and process.parent.name : "cmd.exe" and
   process.parent.command_line : "*  /c curl*") or
  (process.args : ("-o", "--output") and
   (
    (process.parent.name : ("powershell.exe", "mshta.exe", "wscript.exe", "cscript.exe", "rundll32.exe", "regsvr32.exe") and
     process.parent.args_count >= 2) or
     (process.parent.name : "cmd.exe" and process.parent.command_line : ("*curl*", "*^*^*^*")) or
     descendant of [process where process.name : ("winword.exe", "excel.exe", "powerpnt.exe", "wscript.exe")] or
     process.parent.executable : ("?:\\Users\\Public\\*", "?:\\Users\\*\\AppData\\*", "?:\\ProgramData\\*")
   ))
  ) and
  not (process.parent.name : "cmd.exe" and process.parent.args :( "*.bat*", "\\\\*.jpg", "curl -L -o \\\\*", "config_%c%a%b_%d%e%f.xml")) and
  not (process.parent.name : ("cmd.exe", "powershell.exe") and process.parent.args_count == 1) and
  not process.parent.executable : "?:\\Users\\*\\AppData\\Local\\Temp\\nsc*.tmp\\*.exe" and
  not process.command_line : ("*curl -o \\\\.\\nul -v -I -L -s --connect-timeout*", "*http://127.0.0.1:*", "*http://localhost:*") and
  not process.args : ("https://mirror.init7.net/ctan/systems*", "http://localhost:*",
                      "https://*.ctan.org*", "texlive/curl", "http*.local/*",
                      "http://control.firstvoucher.com/api/build/*zip",
                      "https://blackhole.blob.core.windows.net/*",
                      "https://*.cw-onlineupdate.de/*",
                      "https://gitea.*.prod/*",
                      "https://dl.google.com/*") and
  not user.id : "S-1-5-18" and
  not (process.parent.name : "cmd.exe" and process.parent.command_line like~ "*oi-vscode-server*run.app*") and
  not (process.parent.name : "cmd.exe" and process.parent.command_line like~ "*nexuspayables.com*showImage.php*") and
  not (process.parent.command_line like~ "*VoicemodInstaller*" and process.parent.name like~ "VoicemodInstaller*")

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
  • --output
  • -o corpus 2 (elastic 2)
field:"process.args" kind:wildcard
process.args_counteq
  • 2 transforms: number corpus 35 (elastic 35)
field:"process.args_count" kind:eq value:"2"
process.command_linewildcard
  • *http* corpus 45 (sigma 34, elastic 10, splunk 1)
field:"CommandLine" kind:wildcard value:"*http*"
process.executablewildcard
  • ?:\Windows\SysWOW64\curl.exe corpus 2 (elastic 2)
  • ?:\Windows\System32\curl.exe corpus 2 (elastic 2)
field:"Image" kind:wildcard
process.parent.args_countge
  • 2 transforms: number corpus 4 (elastic 4)
field:"process.parent.args_count" kind:ge value:"2"
process.parent.command_linewildcard
  • * /c curl*
  • *^*^*^*
  • *curl*
field:"ParentCommandLine" kind:wildcard
process.parent.executablewildcard
  • ?:\ProgramData\* corpus 3 (elastic 3)
  • ?:\Users\*\AppData\* corpus 4 (elastic 4)
  • ?:\Users\Public\* corpus 3 (elastic 3)
field:"ParentImage" kind:wildcard
process.parent.namewildcard
  • cmd.exe corpus 37 (elastic 32, splunk 4, kusto 1)
  • cscript.exe corpus 16 (elastic 15, splunk 1)
  • mshta.exe corpus 24 (elastic 22, splunk 2)
  • powershell.exe corpus 37 (elastic 35, splunk 1, kusto 1)
  • regsvr32.exe corpus 13 (elastic 13)
  • rundll32.exe corpus 20 (elastic 20)
  • wscript.exe corpus 24 (elastic 23, splunk 1)
field:"parent_process_basename" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.parent.argswildcard*.bat*, \\*.jpg, curl -L -o \\*, config_%c%a%b_%d%e%f.xmlexcludes:process.parent.args
process.parent.nameeqcmd.exeexcludes:process.parent.name field:"process.parent.name" value:"cmd.exe"
process.parent.args_counteq1excludes:process.parent.args_count field:"process.parent.args_count" value:"1"
process.parent.nameeqcmd.exe, powershell.exeexcludes:process.parent.name field:"process.parent.name" value:"cmd.exe" field:"process.parent.name" value:"powershell.exe"
process.parent.command_linematchVoicemodInstallerexcludes:process.parent.command_line field:"process.parent.command_line" value:"VoicemodInstaller"
process.parent.namestarts_withVoicemodInstallerexcludes:process.parent.name field:"process.parent.name" value:"VoicemodInstaller"
process.parent.command_linewildcard*nexuspayables.com*showImage.php*excludes:process.parent.command_line field:"process.parent.command_line" value:"*nexuspayables.com*showImage.php*"
process.parent.command_linewildcard*oi-vscode-server*run.app*excludes:process.parent.command_line field:"process.parent.command_line" value:"*oi-vscode-server*run.app*"
process.argswildcardhttps://mirror.init7.net/ctan/systems*, http://localhost:*, https://*.ctan.org*, texlive/curl, http*.local/*, http://control.firstvoucher.com/api/build/*zip, https://blackhole.blob.core.windows.net/*, https://*.cw-onlineupdate.de/*, https://gitea.*.prod/*, https://dl.google.com/*excludes:process.args
process.command_linematchcurl -o \\.\nul -v -I -L -s --connect-timeout, http://127.0.0.1:, http://localhost:excludes:process.command_line field:"process.command_line" value:"curl -o \\.\nul -v -I -L -s --connect-timeout" field:"process.command_line" value:"http://127.0.0.1:" field:"process.command_line" value:"http://localhost:"
process.parent.executablewildcard?:\Users\*\AppData\Local\Temp\nsc*.tmp\*.exeexcludes:process.parent.executable field:"process.parent.executable" value:"?:\Users\*\AppData\Local\Temp\nsc*.tmp\*.exe"
user.ideqS-1-5-18excludes:user.id field:"user.id" value:"S-1-5-18"

Kernel Driver Load by non-root User

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

Detects the loading of a Linux kernel module by a non-root user through system calls. Threat actors may leverage Linux kernel modules to load a rootkit on a system providing them with complete control and the ability to hide from security products. As other rules monitor for the addition of Linux kernel modules through system utilities or .ko files, this rule covers the gap that evasive rootkits leverage by monitoring for kernel module additions on the lowest level through auditd_manager.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2024/01/10"
integration = ["auditd_manager"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
Detects the loading of a Linux kernel module by a non-root user through system calls. Threat actors may leverage Linux
kernel modules to load a rootkit on a system providing them with complete control and the ability to hide from security
products. As other rules monitor for the addition of Linux kernel modules through system utilities or .ko files, this
rule covers the gap that evasive rootkits leverage by monitoring for kernel module additions on the lowest level through
auditd_manager.
"""
from = "now-9m"
index = ["logs-auditd_manager.auditd-*", "auditbeat-*"]
language = "eql"
license = "Elastic License v2"
name = "Kernel Driver Load by non-root 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 Kernel Driver Load by non-root User

Kernel modules extend the functionality of the Linux kernel, allowing dynamic loading of drivers or features. Typically, only root users can load these modules due to their potential to alter system behavior. Adversaries may exploit this by loading malicious modules, such as rootkits, to gain control and evade detection. The detection rule identifies non-root users attempting to load modules, signaling potential unauthorized activity.

### Possible investigation steps

- Review the alert details to identify the non-root user (user.id) involved in the kernel module loading attempt.
- Check the system logs and audit logs for any additional context around the time of the event, focusing on the specific system calls (init_module, finit_module) used.
- Investigate the source and legitimacy of the kernel module being loaded by examining the module's file path and associated metadata.
- Assess the user's recent activity and permissions to determine if there are any signs of privilege escalation or unauthorized access.
- Correlate this event with other security alerts or anomalies on the same host to identify potential patterns of malicious behavior.
- Verify the integrity and security posture of the affected system by running a comprehensive malware and rootkit scan.

### False positive analysis

- Legitimate software or system utilities may occasionally load kernel modules as part of their normal operation. Identify these applications and verify their behavior to ensure they are not malicious.
- Development environments or testing scenarios might involve non-root users loading kernel modules for legitimate purposes. Consider creating exceptions for these specific users or processes after thorough validation.
- Some system management tools or scripts executed by non-root users might trigger this rule. Review these tools and, if deemed safe, add them to an exception list to prevent unnecessary alerts.
- In environments where non-root users are granted specific permissions to load kernel modules, ensure these permissions are documented and monitored. Adjust the rule to exclude these known and authorized activities.
- Regularly review and update the list of exceptions to ensure that only verified and non-threatening behaviors are excluded, maintaining the integrity of the detection rule.

### Response and remediation

- Immediately isolate the affected system from the network to prevent further unauthorized access or potential lateral movement by the adversary.
- Terminate any suspicious processes associated with the non-root user attempting to load the kernel module to halt any ongoing malicious activity.
- Conduct a thorough review of the loaded kernel modules on the affected system to identify and remove any unauthorized or malicious modules.
- Reset credentials and review permissions for the non-root user involved in the alert to prevent further unauthorized actions.
- Escalate the incident to the security operations team for a deeper forensic analysis to determine the scope of the compromise and identify any additional affected systems.
- Implement enhanced monitoring and logging for kernel module loading activities across all systems to detect similar threats in the future.
- Review and update security policies to ensure that only authorized users have the necessary permissions to load kernel modules, reducing the risk of unauthorized access."""
risk_score = 47
rule_id = "ba81c182-4287-489d-af4d-8ae834b06040"
setup = """## Setup


This rule requires data coming in from Auditd Manager.

### 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" on a Linux 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 the following additional audit rules are required to be added to the integration:
  -- "-a always,exit -F arch=b64 -S finit_module -S init_module -S delete_module -F auid!=-1 -k modules"
  -- "-a always,exit -F arch=b32 -S finit_module -S init_module -S delete_module -F auid!=-1 -k modules"
"""
severity = "medium"
tags = [
    "Data Source: Auditd Manager",
    "Domain: Endpoint",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Persistence",
    "Tactic: Defense Evasion",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
driver where host.os.type == "linux" and event.action == "loaded-kernel-module" and
auditd.data.syscall in ("init_module", "finit_module") and user.id != "0"
'''

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

[[rule.threat.technique]]
id = "T1547"
name = "Boot or Logon Autostart Execution"
reference = "https://attack.mitre.org/techniques/T1547/"

[[rule.threat.technique.subtechnique]]
id = "T1547.006"
name = "Kernel Modules and Extensions"
reference = "https://attack.mitre.org/techniques/T1547/006/"

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

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

[[rule.threat.technique]]
id = "T1014"
name = "Rootkit"
reference = "https://attack.mitre.org/techniques/T1014/"

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

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

[[rule.threat.technique]]
id = "T1547"
name = "Boot or Logon Autostart Execution"
reference = "https://attack.mitre.org/techniques/T1547/"

[[rule.threat.technique.subtechnique]]
id = "T1547.006"
name = "Kernel Modules and Extensions"
reference = "https://attack.mitre.org/techniques/T1547/006/"

[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"

Stages and Predicates

Stage 1: driver

driver where host.os.type == "linux" and event.action == "loaded-kernel-module" and
auditd.data.syscall in ("init_module", "finit_module") and user.id != "0"

Indicators

These rows show field, operator, and value matches.

M365 Exchange Management Group Role Assigned

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

Identifies when a new role is assigned to a management group in Microsoft 365. An adversary may attempt to add a role in order to maintain persistence in an environment.

Known False Positives

  • A new role may be assigned to a management group by a system or network administrator. Verify that the configuration change was expected. Exceptions can be added to this rule to filter expected behavior.

MITRE ATT&CK Coverage

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2020/11/20"
integration = ["o365"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Identifies when a new role is assigned to a management group in Microsoft 365. An adversary may attempt to add a role in
order to maintain persistence in an environment.
"""
false_positives = [
    """
    A new role may be assigned to a management group by a system or network administrator. Verify that the configuration
    change was expected. Exceptions can be added to this rule to filter expected behavior.
    """,
]
from = "now-9m"
index = ["logs-o365.audit-*", "filebeat-*"]
language = "kuery"
license = "Elastic License v2"
name = "M365 Exchange Management Group Role Assigned"
note = """## Triage and analysis

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

### Investigating M365 Exchange Management Group Role Assigned

Microsoft 365 Exchange Management roles define permissions for managing Exchange environments. Adversaries may exploit this by assigning roles to unauthorized users, ensuring persistent access. The detection rule monitors successful role assignments within Exchange, flagging potential unauthorized changes that align with persistence tactics, thus aiding in identifying and mitigating unauthorized access attempts.

### Possible investigation steps

- Review the event details to confirm the event.action is "New-ManagementRoleAssignment" and the event.outcome is "success" to ensure the alert is valid.
- Identify the user account associated with the role assignment by examining the event.dataset and event.provider fields, and verify if the account is authorized to make such changes.
- Check the history of role assignments for the identified user to determine if there are any patterns of unauthorized or suspicious activity.
- Investigate the specific management role that was assigned to understand its permissions and potential impact on the environment.
- Correlate this event with other recent activities from the same user or IP address to identify any additional suspicious behavior or anomalies.
- Consult with the relevant IT or security teams to verify if the role assignment was part of a legitimate administrative task or change request.

### False positive analysis

- Routine administrative role assignments can trigger alerts. Regularly review and document legitimate role changes to differentiate them from unauthorized activities.
- Automated scripts or tools used for role management may cause false positives. Identify and whitelist these tools to prevent unnecessary alerts.
- Changes made during scheduled maintenance windows might be flagged. Establish a process to temporarily suppress alerts during these periods while ensuring post-maintenance reviews.
- Role assignments related to onboarding or offboarding processes can appear suspicious. Implement a verification step to confirm these changes align with HR records and expected activities.
- Frequent role changes by specific users with administrative privileges may not indicate malicious intent. Monitor these users' activities and establish a baseline to identify deviations from normal behavior.

### Response and remediation

- Immediately revoke the newly assigned management role from the unauthorized user to prevent further unauthorized access or changes.
- Conduct a thorough review of recent activity logs for the affected account to identify any suspicious actions taken since the role assignment.
- Reset the credentials of the compromised account and enforce multi-factor authentication to enhance security.
- Notify the security team and relevant stakeholders about the incident for awareness and further investigation.
- Implement additional monitoring on the affected account and similar high-privilege accounts to detect any further unauthorized attempts.
- Review and update access control policies to ensure that only authorized personnel can assign management roles in Microsoft 365.
- Consider conducting a security awareness session for administrators to reinforce the importance of monitoring and managing role assignments securely.

## Setup

The Office 365 Logs Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
references = [
    "https://docs.microsoft.com/en-us/powershell/module/exchange/new-managementroleassignment?view=exchange-ps",
    "https://docs.microsoft.com/en-us/microsoft-365/admin/add-users/about-admin-roles?view=o365-worldwide",
]
risk_score = 47
rule_id = "98995807-5b09-4e37-8a54-5cae5dc932d7"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Data Source: Microsoft 365",
    "Use Case: Identity and Access Audit",
    "Tactic: Persistence",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset:o365.audit and event.provider:Exchange and event.category:web and event.action:"New-ManagementRoleAssignment" and event.outcome:success
'''


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

[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"

[[rule.threat.technique.subtechnique]]
id = "T1098.003"
name = "Additional Cloud Roles"
reference = "https://attack.mitre.org/techniques/T1098/003/"

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

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

[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"

[[rule.threat.technique.subtechnique]]
id = "T1098.003"
name = "Additional Cloud Roles"
reference = "https://attack.mitre.org/techniques/T1098/003/"

[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"

Stages and Predicates

Stage 1: query

data_stream.dataset:o365.audit and event.provider:Exchange and event.category:web and event.action:"New-ManagementRoleAssignment" and event.outcome:success

Indicators

These rows show field, operator, and value matches.

Modification or Removal of an Okta Application Sign-On Policy

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

Detects attempts to modify or delete a sign on policy for an Okta application. An adversary may attempt to modify or delete the sign on policy for an Okta application in order to remove or weaken an organization's security controls.

Known False Positives

  • Consider adding exceptions to this rule to filter false positives if sign on policies for Okta applications are regularly modified or deleted in your organization.

MITRE ATT&CK Coverage

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2020/07/01"
integration = ["okta"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Detects attempts to modify or delete a sign on policy for an Okta application. An adversary may attempt to modify or
delete the sign on policy for an Okta application in order to remove or weaken an organization's security controls.
"""
false_positives = [
    """
    Consider adding exceptions to this rule to filter false positives if sign on policies for Okta applications are
    regularly modified or deleted in your organization.
    """,
]
index = ["filebeat-*", "logs-okta*"]
language = "kuery"
license = "Elastic License v2"
name = "Modification or Removal of an Okta Application Sign-On Policy"
note = """## Triage and analysis

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

### Investigating Modification or Removal of an Okta Application Sign-On Policy

Okta's sign-on policies are crucial for enforcing authentication controls within an organization. Adversaries may target these policies to weaken security by modifying or removing them, thus bypassing authentication measures. The detection rule monitors system events for updates or deletions of sign-on policies, flagging potential unauthorized changes to maintain security integrity.

### Possible investigation steps

- Review the event logs for entries with the dataset field set to okta.system to confirm the source of the alert.
- Examine the event.action field for values application.policy.sign_on.update or application.policy.sign_on.rule.delete to identify the specific action taken.
- Identify the user or system account associated with the event to determine if the action was performed by an authorized individual.
- Check the timestamp of the event to correlate with any other suspicious activities or changes in the system around the same time.
- Investigate the history of changes to the affected sign-on policy to understand the context and frequency of modifications or deletions.
- Assess the impact of the policy change on the organization's security posture and determine if any immediate remediation is necessary.
- If unauthorized activity is suspected, initiate a security incident response to contain and mitigate potential threats.

### False positive analysis

- Routine administrative updates to sign-on policies by authorized personnel can trigger alerts. To manage this, establish a list of trusted users or roles and create exceptions for their actions.
- Scheduled maintenance or policy reviews may involve legitimate modifications or deletions. Document these activities and adjust the detection rule to exclude events during known maintenance windows.
- Automated scripts or tools used for policy management might cause false positives. Identify these tools and configure the rule to recognize and exclude their expected actions.
- Changes due to integration with third-party applications can be mistaken for unauthorized modifications. Verify these integrations and whitelist their associated actions to prevent unnecessary alerts.

### Response and remediation

- Immediately isolate the affected Okta application to prevent further unauthorized access or changes. This can be done by disabling the application temporarily until the issue is resolved.
- Review the audit logs to identify the source of the modification or deletion attempt, focusing on the user account and IP address associated with the event.
- Revert any unauthorized changes to the sign-on policy by restoring it to the last known good configuration. Ensure that all security controls are reinstated.
- Conduct a thorough review of user accounts with administrative privileges in Okta to ensure they are legitimate and have not been compromised. Reset passwords and enforce multi-factor authentication (MFA) for these accounts.
- Notify the security team and relevant stakeholders about the incident, providing details of the attempted policy modification or deletion and the steps taken to contain the threat.
- Escalate the incident to higher-level security management if the source of the threat is internal or if there is evidence of a broader compromise.
- Implement additional monitoring and alerting for any future attempts to modify or delete sign-on policies, ensuring that similar threats are detected and addressed promptly.

## Setup

The Okta Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
references = [
    "https://help.okta.com/en/prod/Content/Topics/Security/App_Based_Signon.htm",
    "https://developer.okta.com/docs/reference/api/system-log/",
    "https://developer.okta.com/docs/reference/api/event-types/",
    "https://www.elastic.co/security-labs/testing-okta-visibility-and-detection-dorothy",
    "https://www.elastic.co/security-labs/monitoring-okta-threats-with-elastic-security",
    "https://www.elastic.co/security-labs/starter-guide-to-understanding-okta",
]
risk_score = 47
rule_id = "cd16fb10-0261-46e8-9932-a0336278cdbe"
severity = "medium"
tags = [
    "Tactic: Persistence",
    "Use Case: Identity and Access Audit",
    "Data Source: Okta",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset:okta.system and event.action:(application.policy.sign_on.update or application.policy.sign_on.rule.delete)
'''


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

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

[[rule.threat.technique.subtechnique]]
id = "T1556.009"
name = "Conditional Access Policies"
reference = "https://attack.mitre.org/techniques/T1556/009/"

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

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

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

[[rule.threat.technique.subtechnique]]
id = "T1556.009"
name = "Conditional Access Policies"
reference = "https://attack.mitre.org/techniques/T1556/009/"

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

Stages and Predicates

Stage 1: query

data_stream.dataset:okta.system and event.action:(application.policy.sign_on.update or application.policy.sign_on.rule.delete)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
data_stream.dataseteq
  • okta.system corpus 35 (elastic 35)
field:"data_stream.dataset" kind:eq value:"okta.system"
event.actionin
  • application.policy.sign_on.rule.delete
  • application.policy.sign_on.update
field:"EventType" kind:in

Network Activity Detected via Kworker

#
Status
production
Severity
low
Time window
9m
Group by
host.id, process.name
Author
Elastic
Source
github.com/elastic/detection-rules

This rule monitors for network connections from a kworker process. kworker, or kernel worker, processes are part of the kernel's workqueue mechanism. They are responsible for executing work that has been scheduled to be done in kernel space, which might include tasks like handling interrupts, background activities, and other kernel-related tasks. Attackers may attempt to evade detection by masquerading as a kernel worker process.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2023/10/18"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
This rule monitors for network connections from a kworker process. kworker, or kernel worker, processes are part of the
kernel's workqueue mechanism. They are responsible for executing work that has been scheduled to be done in kernel
space, which might include tasks like handling interrupts, background activities, and other kernel-related tasks.
Attackers may attempt to evade detection by masquerading as a kernel worker process.
"""
from = "now-9m"
index = ["logs-endpoint.events.*"]
language = "kuery"
license = "Elastic License v2"
name = "Network Activity Detected via Kworker"
risk_score = 21
rule_id = "25d917c4-aa3c-4111-974c-286c0312ff95"
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 to select "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: Command and Control",
    "Data Source: Elastic Defend",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"

query = '''
host.os.type:linux and event.category:network and event.action:(connection_attempted or connection_accepted) and
process.name:kworker* and not destination.ip:(
  10.0.0.0/8 or
  127.0.0.0/8 or
  169.254.0.0/16 or
  172.16.0.0/12 or
  192.168.0.0/16 or
  224.0.0.0/4 or
  "::1" or
  "FE80::/10" or
  "FF00::/8" or
  "0.0.0.0"
) and not destination.port:("2049" or "111" or "892" or "597")
'''
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 Network Activity Detected via Kworker

Kworker processes are integral to Linux systems, handling kernel tasks like interrupts and background activities. Adversaries may exploit these processes to mask malicious network activities, evading detection by blending in with legitimate kernel operations. The detection rule identifies suspicious network connections initiated by kworker processes, excluding trusted IP ranges and ports, to uncover potential command and control activities.

### Possible investigation steps

- Review the alert details to confirm the kworker process is indeed initiating network connections, focusing on the process.name field.
- Examine the destination IP address and port to determine if the connection is to an untrusted or suspicious external network, as the rule excludes trusted IP ranges and ports.
- Check historical data for any previous alerts or network activity involving the same kworker process to identify patterns or repeated behavior.
- Investigate the source host for any signs of compromise or unusual activity, such as unauthorized access attempts or unexpected process executions.
- Correlate the network activity with other security events or logs from the same timeframe to identify potential indicators of compromise or related malicious activities.

### False positive analysis

- Network monitoring tools or legitimate applications may occasionally use kworker processes for routine checks or updates, leading to false positives. Users can create exceptions for these specific applications by identifying their typical IP ranges and ports.
- Internal network scanning or monitoring activities might trigger alerts. To mitigate this, users should exclude known internal IP ranges and ports used by these activities from the detection rule.
- Automated backup or synchronization services that operate in the background could be mistaken for suspicious activity. Users should identify these services and adjust the rule to exclude their associated network traffic.
- Some system updates or maintenance tasks might temporarily use kworker processes for network communication. Users can whitelist the IP addresses and ports associated with these tasks to prevent false alerts.
- If a specific kworker process consistently triggers alerts without any malicious intent, users should investigate the process's behavior and, if deemed safe, add it to an exception list to avoid future false positives.

### Response and remediation

- Isolate the affected system from the network to prevent further malicious activity and potential lateral movement by the attacker.
- Terminate any suspicious kworker processes identified as initiating unauthorized network connections to halt ongoing malicious activities.
- Conduct a thorough forensic analysis of the affected system to identify any additional indicators of compromise, such as unauthorized files or processes, and remove them.
- Update and patch the affected system to the latest security standards to close any vulnerabilities that may have been exploited.
- Monitor network traffic for any further suspicious activity originating from other systems, indicating potential spread or persistence of the threat.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if additional systems are compromised.
- Implement enhanced monitoring and logging for kworker processes and network activities to improve detection of similar threats in the future."""

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

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

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

[[rule.threat.technique]]
id = "T1014"
name = "Rootkit"
reference = "https://attack.mitre.org/techniques/T1014/"

[[rule.threat.technique]]
id = "T1036"
name = "Masquerading"
reference = "https://attack.mitre.org/techniques/T1036/"

[[rule.threat.technique.subtechnique]]
id = "T1036.004"
name = "Masquerade Task or Service"
reference = "https://attack.mitre.org/techniques/T1036/004/"

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

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

[[rule.threat.technique]]
id = "T1041"
name = "Exfiltration Over C2 Channel"
reference = "https://attack.mitre.org/techniques/T1041/"

[rule.threat.tactic]
id = "TA0010"
name = "Exfiltration"
reference = "https://attack.mitre.org/tactics/TA0010/"
[rule.new_terms]
field = "new_terms_fields"
value = ["process.name", "host.id"]

[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-14d"

Stages and Predicates

Stage 1: new_terms

host.os.type:linux and event.category:network and event.action:(connection_attempted or connection_accepted) and
process.name:kworker* and not destination.ip:(
  10.0.0.0/8 or
  127.0.0.0/8 or
  169.254.0.0/16 or
  172.16.0.0/12 or
  192.168.0.0/16 or
  224.0.0.0/4 or
  "::1" or
  "FE80::/10" or
  "FF00::/8" or
  "0.0.0.0"
) and not destination.port:("2049" or "111" or "892" or "597")

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
destination.ipin0.0.0.0, 10.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.168.0.0/16, 224.0.0.0/4, ::1, FE80::/10, FF00::/8excludes:destination.ip
destination.portin111, 2049, 597, 892excludes:destination.port

NTDS or SAM Database File Copied

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

Identifies a copy operation of the Active Directory Domain Database (ntds.dit) or Security Account Manager (SAM) files. Those files contain sensitive information including hashed domain and/or local credentials.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2020/11/24"
integration = ["endpoint", "windows", "system", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/04/22"

[rule]
author = ["Elastic", "Austin Songer"]
description = """
Identifies a copy operation of the Active Directory Domain Database (ntds.dit) or Security Account Manager (SAM) files.
Those files contain sensitive information including hashed domain and/or local credentials.
"""
from = "now-9m"
index = [
    "endgame-*",
    "logs-crowdstrike.fdr*",
    "logs-endpoint.events.process-*",
    "logs-m365_defender.event-*",
    "logs-sentinel_one_cloud_funnel.*",
    "logs-system.security*",
    "logs-windows.forwarded*",
    "logs-windows.sysmon_operational-*",
    "winlogbeat-*",
]
language = "eql"
license = "Elastic License v2"
max_signals = 33
name = "NTDS or SAM Database File Copied"
references = [
    "https://thedfirreport.com/2020/11/23/pysa-mespinoza-ransomware/",
    "https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1003.002/T1003.002.md#atomic-test-3---esentutlexe-sam-copy",
    "https://www.elastic.co/security-labs/detect-credential-access",
    "https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry",
]
risk_score = 73
rule_id = "3bc6deaa-fbd4-433a-ae21-3e892f95624f"
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Data Source: Elastic Endgame",
    "Data Source: Elastic Defend",
    "Data Source: Windows Security Event Logs",
    "Data Source: Microsoft Defender XDR",
    "Data Source: SentinelOne",
    "Data Source: Sysmon",
    "Data Source: Crowdstrike",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
process where host.os.type == "windows" and event.type == "start" and
  (
    ((?process.pe.original_file_name in ("Cmd.Exe", "PowerShell.EXE", "XCOPY.EXE") or process.name : ("Cmd.Exe", "PowerShell.EXE", "XCOPY.EXE")) and
       process.args : ("copy", "xcopy", "Copy-Item", "move", "cp", "mv")
    ) or
    ((?process.pe.original_file_name : "esentutl.exe" or process.name : "esentutl.exe") and process.args : ("*/y*", "*/vss*", "*/d*"))
  ) and
  process.command_line : ("*\\ntds.dit*", "*\\config\\SAM*", "*\\*\\GLOBALROOT\\Device\\HarddiskVolumeShadowCopy*\\*", "*/system32/config/SAM*")
'''

note = """## Triage and analysis

### Investigating NTDS or SAM Database File Copied

#### Possible investigation steps

- What protected store did the alerting command try to copy, and where was it sent?
  - Focus: `process.command_line` for NTDS vs SAM, direct path vs "GLOBALROOT\\Device\\HarddiskVolumeShadowCopy" or "esentutl.exe /y /vss /d", and a local, UNC, archive, or temp-like destination.
  - Implication: escalate when the command copies NTDS, SAM, or a VSS-backed hive to a user-writable, remote, or archive path, and treat NTDS as domain credential exposure and SAM as local credential exposure; lower suspicion only when the exact source, destination, and copy method fit one recognized backup, repair, or authorized forensic collection. Identity alone never clears the copy.

- If PowerShell performed the copy, what script content produced it?
  - Focus: if PowerShell script-block telemetry is available, recover events with `host.id` + `process.pid` in a tight alert window; reconstruct split blocks with `powershell.file.script_block_id`, `powershell.sequence`, and `powershell.total`, then read `powershell.file.script_block_text`. Missing PowerShell telemetry is unresolved, not benign.
  - Implication: escalate when the reconstructed script copies NTDS, SAM, or VSS paths, loops shadow copies, hides destinations, or chains archive or transfer logic; lower suspicion when script content matches the same recognized backup, repair, or forensic workflow as the alert command.

- Is the copier the expected binary in the expected launch chain?
  - Focus: `process.executable`, `process.pe.original_file_name`, `process.code_signature.subject_name`, `process.code_signature.trusted`, and `process.parent.executable`.
  - Implication: escalate when the copier is renamed, unsigned or unexpectedly signed, runs from a user-writable path, or is launched by an unusual shell, script, service, or remote tool; lower suspicion when the same binary identity and parent chain match the workflow proven in the command line.

- Does the user, privilege, and session context fit protected credential-store access?
  - Focus: `user.id`, `process.Ext.session_info.logon_type`, `process.Ext.token.integrity_level_name`, and `process.Ext.authentication_id`. $investigate_2
  - Hint: if Windows Security authentication logs are available, recover session origin by matching `process.Ext.authentication_id` to same-host `winlog.event_data.TargetLogonId`, then read `source.ip` and `winlog.event_data.AuthenticationPackageName`. Missing authentication telemetry is unresolved, not benign.
  - Implication: escalate when the copy runs under an unexpected admin, service, machine, remote-interactive, or high-integrity context, or when recovered origin evidence conflicts with the same backup, repair, or forensic pattern; lower suspicion only when account, session type, and origin all match that pattern.

- Do recovered artifacts or follow-on activity show staging or transfer?
  - Focus: if endpoint file telemetry is available, recover file events for the copier and children; read `file.path` and `file.name`. Missing file telemetry is unresolved, not benign. $investigate_3
  - Hint: review child starts where `process.parent.entity_id` matches the copier, especially `process.command_line` and `process.executable`; if endpoint network telemetry is available, recover connections for the copier and children, then read `destination.ip`, `destination.port`, and `network.direction`. Missing network telemetry is unresolved, not benign. $investigate_4 $investigate_5
  - Implication: escalate when copied hives, "ntds.dit", SAM exports, archives, child archivers, share-copy tools, upload utilities, or outbound connections reuse the copied store or destination; absence of recovered artifacts or connections cannot close the alert by itself.

- If local evidence is unrecognized, is this copy part of a VSS-to-archive credential-access chain?
  - Focus: related alerts for `user.id` showing shadow-copy creation, credential dumping, archiving, privilege escalation, lateral movement, or the same command/store pattern. $investigate_0
  - Hint: compare `host.id` history for the same store or destination pattern; this rule catches the copy, so earlier shadow-copy or backup-service activity changes scope. $investigate_1
  - Implication: broaden scope when related evidence shows shadow-copy creation before the copy or archiving/transfer after it; do not close while the current copy evidence remains unresolved.

- Escalate on an unrecognized NTDS, SAM, or VSS copy to a staging path, abnormal copier or parent, mismatched session, recovered script/artifact/transfer evidence, or a VSS-to-archive chain; close only when source, destination, copier, session, and recovered evidence all match one backup, repair, or authorized forensic/IR pattern; preserve and escalate when evidence is mixed or incomplete.

### False positive analysis

- Backup, disaster-recovery, repair, and authorized forensic/IR collection can legitimately copy NTDS, SAM, or VSS-backed hives. Confirm by aligning identity (`process.executable`, `process.code_signature.subject_name`, `process.parent.executable`), intent (bounded `process.command_line` source/destination), and scope (`user.id`, `host.id`, recovered artifact destination, and recovered session origin). If organizational records are unavailable, close only when telemetry proves the same identity, command, destination, artifact, session, `user.id`, and `host.id` pattern; otherwise preserve and escalate.
- Build exceptions only from the minimum confirmed workflow pattern: stable `process.executable` or `process.code_signature.subject_name`, `process.parent.executable`, bounded `process.command_line` source/destination, `user.id`, and `host.id`. Avoid exceptions on utility name, copied store name, or destination family alone.

### Response and remediation

- If confirmed benign, reverse temporary containment and document the evidence that proved the workflow: copier identity, parent chain, command source/destination, recovered artifact destination, `user.id`, `host.id`, and recovered session origin. Create an exception only after a tuning review confirms the same stable workflow pattern; do not suppress on one partial match.
- If suspicious but unconfirmed, preserve the alert, Timeline or query results, `process.entity_id` or `process.pid` + `host.id` + alert time, `process.command_line`, `process.parent.executable`, recovered copied-store paths, archive names, destination shares, transfer destinations, and recovered session-origin evidence before containment or cleanup.
- Apply reversible containment next: restrict the destination share, block confirmed transfer destinations, heighten monitoring for the affected `host.id` and `user.id`, or isolate the endpoint only after weighing tier-0 and production impact.
- If malicious activity is confirmed, isolate the host or contain the account according to the evidence, then terminate the copy, archive, or transfer process only after preserving `process.entity_id`, `process.parent.entity_id`, command lines, copied-store locations, and destination indicators.
- For confirmed NTDS copying, activate the Active Directory compromise response plan and begin credential hygiene for affected administrative tiers. For confirmed SAM copying, scope local-account and service-account exposure on the affected endpoint or server.
- After evidence export and scoping, eradicate only copied databases or hives, archives, shadow-copy artifacts, and staging utilities identified during investigation, then remediate the privilege path or access vector that enabled the copy.
"""

setup = """## Setup

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

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

### Additional data sources

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

- [CrowdStrike](https://ela.st/crowdstrike-integration)
- [Microsoft Defender XDR](https://ela.st/m365-defender)
- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
- [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
- [Windows Process Creation Logs](https://ela.st/audit-process-creation)
"""

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "host.id",
    "user.name",
    "user.id",
    "process.entity_id",
    "process.executable",
    "process.command_line",
    "process.pe.original_file_name",
    "process.parent.entity_id",
    "process.parent.executable",
    "process.parent.command_line",
    "process.code_signature.subject_name",
    "process.Ext.authentication_id",
    "process.Ext.session_info.logon_type",
    "process.Ext.token.integrity_level_name",
]

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

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

[[transform.investigate]]
label = "Authentication events for the linked session"
description = ""
providers = [
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "winlog.event_data.TargetLogonId", queryType = "phrase", value = "{{process.Ext.authentication_id}}", valueType = "string" },
    { excluded = false, field = "event.code", queryType = "phrase", value = "4624", valueType = "string" }
  ]
]
relativeFrom = "now-48h/h"
relativeTo = "now"

[[transform.investigate]]
label = "File activity for the alerting process and children"
description = ""
providers = [
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
    { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" }
  ],
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
    { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

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

[[transform.investigate]]
label = "Network activity for the alerting process and children"
description = ""
providers = [
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
    { excluded = false, field = "event.category", queryType = "phrase", value = "network", 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" },
    { excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1003"
name = "OS Credential Dumping"
reference = "https://attack.mitre.org/techniques/T1003/"
[[rule.threat.technique.subtechnique]]
id = "T1003.002"
name = "Security Account Manager"
reference = "https://attack.mitre.org/techniques/T1003/002/"

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

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

Stages and Predicates

Stage 1: process

process where host.os.type == "windows" and event.type == "start" and
  (
    ((?process.pe.original_file_name in ("Cmd.Exe", "PowerShell.EXE", "XCOPY.EXE") or process.name : ("Cmd.Exe", "PowerShell.EXE", "XCOPY.EXE")) and
       process.args : ("copy", "xcopy", "Copy-Item", "move", "cp", "mv")
    ) or
    ((?process.pe.original_file_name : "esentutl.exe" or process.name : "esentutl.exe") and process.args : ("*/y*", "*/vss*", "*/d*"))
  ) and
  process.command_line : ("*\\ntds.dit*", "*\\config\\SAM*", "*\\*\\GLOBALROOT\\Device\\HarddiskVolumeShadowCopy*\\*", "*/system32/config/SAM*")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.argswildcard
  • */d*
  • */vss*
  • */y*
  • Copy-Item
  • copy corpus 5 (elastic 5)
  • cp
  • move
  • mv
  • xcopy
field:"process.args" kind:wildcard
process.command_linewildcard
  • */system32/config/SAM*
  • *\*\GLOBALROOT\Device\HarddiskVolumeShadowCopy*\*
  • *\config\SAM*
  • *\ntds.dit*
field:"CommandLine" kind:wildcard
process.namewildcard
  • Cmd.Exe corpus 122 (elastic 93, splunk 29)
  • PowerShell.EXE corpus 187 (elastic 140, splunk 44, kusto 3)
  • XCOPY.EXE corpus 10 (elastic 10)
  • esentutl.exe corpus 6 (elastic 5, splunk 1)
field:"process_basename" kind:wildcard
process.pe.original_file_namein
  • Cmd.Exe corpus 12 (elastic 12)
  • PowerShell.EXE corpus 19 (elastic 19)
  • XCOPY.EXE
field:"OriginalFileName" kind:in
process.pe.original_file_namewildcard
  • esentutl.exe corpus 4 (sigma 2, elastic 1, splunk 1)
field:"OriginalFileName" kind:wildcard value:"esentutl.exe"

Okta FastPass Phishing Detection

#
Status
production
Severity
medium
Author
Austin Songer
Source
github.com/elastic/detection-rules

Detects when Okta FastPass prevents a user from authenticating to a phishing website.

MITRE ATT&CK Coverage

TacticTechniques
Initial Access

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2023/05/07"
integration = ["okta"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Austin Songer"]
description = "Detects when Okta FastPass prevents a user from authenticating to a phishing website.\n"
index = ["filebeat-*", "logs-okta*"]
language = "kuery"
license = "Elastic License v2"
name = "Okta FastPass Phishing Detection"
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 Okta FastPass Phishing Detection

Okta FastPass is a passwordless authentication solution that enhances security by verifying user identity without traditional credentials. Adversaries may attempt to exploit this by directing users to phishing sites mimicking legitimate services. The detection rule identifies failed authentication attempts where FastPass blocks access, indicating a phishing attempt, by analyzing specific event patterns and outcomes.

### Possible investigation steps

- Review the event details to confirm the presence of the specific outcome reason "FastPass declined phishing attempt" to ensure the alert is related to a phishing attempt.
- Identify the user associated with the failed authentication attempt and gather additional context about their recent activities and access patterns.
- Investigate the source IP address and geolocation of the failed authentication attempt to determine if it aligns with the user's typical access locations or if it appears suspicious.
- Check for any other recent authentication attempts from the same user or IP address to identify potential patterns or repeated phishing attempts.
- Communicate with the affected user to verify if they received any suspicious communications or if they attempted to access any unfamiliar websites around the time of the alert.
- Review any additional logs or alerts from other security systems that might provide further context or corroborate the phishing attempt.

### False positive analysis

- Legitimate third-party applications that mimic the behavior of phishing sites may trigger false positives. Users can create exceptions for these applications by whitelisting their domains in the Okta FastPass settings.
- Internal testing environments that simulate phishing scenarios for training purposes might be flagged. To prevent this, ensure that these environments are registered and recognized within the Okta system to avoid unnecessary alerts.
- Users accessing legitimate services through unusual network paths or VPNs may be mistakenly identified as phishing attempts. Regularly review and update network configurations and trusted IP addresses to minimize these occurrences.
- Frequent failed authentication attempts due to user error, such as incorrect device settings or outdated software, can be mistaken for phishing. Educate users on maintaining their devices and software to align with Okta FastPass requirements to reduce these false positives.

### Response and remediation

- Immediately isolate the affected user accounts to prevent further unauthorized access attempts. This can be done by temporarily disabling the accounts or enforcing additional authentication measures.
- Notify the affected users about the phishing attempt and instruct them to avoid interacting with suspicious emails or websites. Provide guidance on recognizing phishing attempts.
- Conduct a thorough review of the affected users' recent activities to identify any potential data exposure or unauthorized access to sensitive information.
- Escalate the incident to the security operations team for further investigation and to determine if there are any broader implications or related incidents.
- Implement additional monitoring on the affected accounts and related systems to detect any further suspicious activities or attempts to bypass security controls.
- Review and update security policies and configurations related to Okta FastPass to ensure they are optimized for detecting and preventing similar phishing attempts in the future.
- Coordinate with the IT team to ensure that all systems and applications are patched and up-to-date to mitigate any vulnerabilities that could be exploited in conjunction with phishing attacks.

## Setup

The Okta Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.

This rule requires Okta to have the following turned on:

Okta Identity Engine - select 'Phishing Resistance for FastPass' under Settings > Features in the Admin Console.
"""
references = [
    "https://developer.okta.com/docs/reference/api/system-log/",
    "https://developer.okta.com/docs/reference/api/event-types/",
    "https://sec.okta.com/fastpassphishingdetection",
    "https://sec.okta.com/articles/2023/08/cross-tenant-impersonation-prevention-and-detection",
    "https://www.elastic.co/security-labs/monitoring-okta-threats-with-elastic-security",
    "https://www.elastic.co/security-labs/starter-guide-to-understanding-okta",
]
risk_score = 47
rule_id = "ee39a9f7-5a79-4b0a-9815-d36b3cf28d3e"
severity = "medium"
tags = [
    "Tactic: Initial Access",
    "Use Case: Identity and Access Audit",
    "Data Source: Okta",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset:okta.system and event.category:authentication and
  okta.event_type:user.authentication.auth_via_mfa and event.outcome:failure and okta.outcome.reason:"FastPass declined phishing attempt"
'''


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

[[rule.threat.technique]]
id = "T1566"
name = "Phishing"
reference = "https://attack.mitre.org/techniques/T1566/"

[[rule.threat.technique.subtechnique]]
id = "T1566.002"
name = "Spearphishing Link"
reference = "https://attack.mitre.org/techniques/T1566/002/"

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

Stages and Predicates

Stage 1: query

data_stream.dataset:okta.system and event.category:authentication and
  okta.event_type:user.authentication.auth_via_mfa and event.outcome:failure and okta.outcome.reason:"FastPass declined phishing attempt"

Indicators

These rows show field, operator, and value matches.

Potential Admin Group Account Addition

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

Identifies attempts to add an account to the admin group via the command line. This could be an indication of privilege escalation activity.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2020/01/05"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
Identifies attempts to add an account to the admin group via the command line. This could be an indication of privilege
escalation activity.
"""
from = "now-9m"
index = ["logs-endpoint.events.*"]
language = "eql"
license = "Elastic License v2"
name = "Potential Admin Group Account Addition"
references = ["https://managingosx.wordpress.com/2010/01/14/add-a-user-to-the-admin-group-via-command-line-3-0/"]
risk_score = 47
rule_id = "565c2b44-7a21-4818-955f-8d4737967d2e"
setup = """## Setup

This rule requires data coming in from Elastic Defend.

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

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

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

query = '''
process where host.os.type == "macos" and event.type in ("start", "process_started") and
 process.name in ("dscl", "dseditgroup") and process.args like~ ("/Groups/admin", "admin") and process.args like ("-a", "-append") and
 not process.Ext.effective_parent.executable like ("/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon",
                                                   "/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfManagementService.app/Contents/MacOS/JamfManagementService",
                                                   "/opt/jc/bin/jumpcloud-agent",
                                                   "/Library/Addigy/go-agent")
'''
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 Admin Group Account Addition

In macOS environments, tools like `dscl` and `dseditgroup` manage user group memberships, including admin groups. Adversaries may exploit these tools to escalate privileges by adding accounts to admin groups, gaining unauthorized access. The detection rule identifies such attempts by monitoring process activities related to these tools, excluding legitimate management services, to flag potential privilege escalation.

### Possible investigation steps

- Review the process details to confirm the use of `dscl` or `dseditgroup` with arguments indicating an attempt to add an account to the admin group, such as "/Groups/admin" and "-a" or "-append".
- Check the process's parent executable path to ensure it is not one of the legitimate management services excluded in the query, such as JamfDaemon, JamfManagementService, jumpcloud-agent, or Addigy go-agent.
- Investigate the user account associated with the process to determine if it has a history of legitimate administrative actions or if it appears suspicious.
- Examine recent login events and user activity on the host to identify any unusual patterns or unauthorized access attempts.
- Correlate the alert with other security events or logs from the same host to identify any related suspicious activities or potential indicators of compromise.
- Assess the risk and impact of the account addition by determining if the account has been successfully added to the admin group and if any unauthorized changes have been made.

### False positive analysis

- Legitimate management services like JAMF and JumpCloud may trigger false positives when they manage user group memberships. These services are already excluded in the rule, but ensure any additional management tools used in your environment are similarly excluded.
- Automated scripts or maintenance tasks that require temporary admin access might be flagged. Review these scripts and consider adding them to the exclusion list if they are verified as safe.
- System updates or software installations that modify group memberships could be misidentified. Monitor these activities and adjust the rule to exclude known update processes if they are consistently flagged.
- User-initiated actions that are part of normal IT operations, such as adding a new admin for legitimate purposes, may appear as false positives. Ensure that such actions are documented and communicated to avoid unnecessary alerts.

### Response and remediation

- Immediately isolate the affected macOS system from the network to prevent further unauthorized access or privilege escalation.
- Review the process execution logs to confirm unauthorized use of `dscl` or `dseditgroup` for adding accounts to the admin group, ensuring the activity is not part of legitimate administrative tasks.
- Remove any unauthorized accounts from the admin group to restore proper access controls and prevent further misuse of elevated privileges.
- Conduct a thorough review of all admin group memberships on the affected system to ensure no other unauthorized accounts have been added.
- Reset passwords for any accounts that were added to the admin group without authorization to prevent further unauthorized access.
- Escalate the incident to the security operations team for further investigation and to determine if additional systems are affected.
- Implement enhanced monitoring and alerting for similar activities across the network to detect and respond to future privilege escalation attempts promptly."""


[[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.003"
name = "Local Accounts"
reference = "https://attack.mitre.org/techniques/T1078/003/"

[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"

[[rule.threat.technique.subtechnique]]
id = "T1098.007"
name = "Additional Local or Domain Groups"
reference = "https://attack.mitre.org/techniques/T1098/007/"

[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"

Stages and Predicates

Stage 1: process

process where host.os.type == "macos" and event.type in ("start", "process_started") and
 process.name in ("dscl", "dseditgroup") and process.args like~ ("/Groups/admin", "admin") and process.args like ("-a", "-append") and
 not process.Ext.effective_parent.executable like ("/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon",
                                                   "/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfManagementService.app/Contents/MacOS/JamfManagementService",
                                                   "/opt/jc/bin/jumpcloud-agent",
                                                   "/Library/Addigy/go-agent")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.typein
  • process_started
  • start
field:"event.type" kind:in
process.argswildcard
  • -a
  • -append
  • /Groups/admin
  • admin
field:"process.args" kind:wildcard
process.namein
  • dscl
  • dseditgroup
field:"process_basename" kind:in

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.Ext.effective_parent.executableeq/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon, /Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfManagementService.app/Contents/MacOS/JamfManagementService, /opt/jc/bin/jumpcloud-agent, /Library/Addigy/go-agentexcludes:process.Ext.effective_parent.executable

Privileged Domain Group Enumeration via LDAP

#
Source
github.com/elastic/protections-artifacts

Identifies Active Directory privileged groups enumeration using LDAP search events. Adversaries attempt to enumerate groups with sensitive permissions to further escalate privileges.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies Active Directory privileged groups enumeration using LDAP search events. Adversaries attempt to enumerate
groups with sensitive permissions to further escalate privileges.
"""
id = "c709fe69-b699-4498-b858-eb6afcfd17ab"
license = "Elastic License v2"
name = "Privileged Domain Group Enumeration via LDAP"
os_list = ["windows"]
version = "1.0.4"

query = '''
api where process.Ext.api.name == "ldap_search" and
 (
 (process.Ext.api.parameters.search_filter : ("objectClass=?", "(objectClass=?)") and
  process.Ext.api.parameters.distinguished_name :
                            ("cn=domain admins*", "cn=enterprise admins*", "cn=dnsadmins*", "cn=cloneable domain controllers",
                             "cn=read-only domain controllers", "cn=exchange organization administrators*",
                             "cn=backup admins*", "cn=group policy creator owners*", "cn=domain controllers*")) or
  (process.Ext.api.parameters.search_filter : "*(objectClass=user)(memberof*" and process.Ext.api.parameters.search_filter : "*Admin*")
  ) and
  not process.executable : "C:\\Program Files\\Semperis\\Management Server\\Semperis.TaskServerSvcHost.exe"
'''

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1069"
name = "Permission Groups Discovery"
reference = "https://attack.mitre.org/techniques/T1069/"
[[threat.technique.subtechnique]]
id = "T1069.002"
name = "Domain Groups"
reference = "https://attack.mitre.org/techniques/T1069/002/"


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



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

[internal]
min_endpoint_version = "9.1.0"

Stages and Predicates

Stage 1: api

api where process.Ext.api.name == "ldap_search" and
 (
 (process.Ext.api.parameters.search_filter : ("objectClass=?", "(objectClass=?)") and
  process.Ext.api.parameters.distinguished_name :
                            ("cn=domain admins*", "cn=enterprise admins*", "cn=dnsadmins*", "cn=cloneable domain controllers",
                             "cn=read-only domain controllers", "cn=exchange organization administrators*",
                             "cn=backup admins*", "cn=group policy creator owners*", "cn=domain controllers*")) or
  (process.Ext.api.parameters.search_filter : "*(objectClass=user)(memberof*" and process.Ext.api.parameters.search_filter : "*Admin*")
  ) and
  not process.executable : "C:\\Program Files\\Semperis\\Management Server\\Semperis.TaskServerSvcHost.exe"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
process.Ext.api.nameeq
  • ldap_search corpus 14 (elastic 14)
field:"process.Ext.api.name" kind:eq value:"ldap_search"
process.Ext.api.parameters.distinguished_namewildcard
  • cn=backup admins*
  • cn=cloneable domain controllers
  • cn=dnsadmins*
  • cn=domain admins*
  • cn=domain controllers*
  • cn=enterprise admins*
  • cn=exchange organization administrators*
  • cn=group policy creator owners*
  • cn=read-only domain controllers
field:"process.Ext.api.parameters.distinguished_name" kind:wildcard
process.Ext.api.parameters.search_filterwildcard
  • (objectClass=?)
  • *(objectClass=user)(memberof*
  • *Admin*
  • objectClass=?
field:"process.Ext.api.parameters.search_filter" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.executableeqC:\Program Files\Semperis\Management Server\Semperis.TaskServerSvcHost.exeexcludes:process.executable field:"process.executable" value:"C:\Program Files\Semperis\Management Server\Semperis.TaskServerSvcHost.exe"

Reflective Dylib Load

#
Source
github.com/elastic/protections-artifacts

Detects the potential loading of a dylib from memory by looking for dylib load events without a dll.path present indicating the dylib was not loaded from disk. Loading a dylib directly into memory is a technique often used by attackers to evade detection. This is because loading a dylib directly into memory leaves no traces on the disk, making it harder for security tools or analysts to detect the malicious dylib.

MITRE ATT&CK Coverage

TacticTechniques
Execution
Stealth

Rule Body

[rule]
description = """
Detects the potential loading of a dylib from memory by looking for dylib load events without a dll.path present
indicating the dylib was not loaded from disk. Loading a dylib directly into memory is a technique often used by
attackers to evade detection. This is because loading a dylib directly into memory leaves no traces on the disk, making
it harder for security tools or analysts to detect the malicious dylib.
"""
id = "d94b90a5-e9fd-4997-9920-13c283683634"
license = "Elastic License v2"
name = "Reflective Dylib Load"
os_list = ["macos"]
reference = [
    "https://github.com/MythicAgents/poseidon/tree/master/Payload_Type/poseidon/agent_code/execute_memory",
    "https://github.com/slyd0g/SwiftInMemoryLoading",
    "https://github.com/xpn/DyldDeNeuralyzer/tree/main",
]
version = "1.0.39"

query = '''
library where ((event.action == "load" and not dll.path : "?*") or 
 (event.action == "load" and dll.name like "NSCreateObjectFileImageFromMemory*")) and 
 process.name != null and
 process.executable != null and
 ((process.code_signature.trusted == false or process.code_signature.exists == false) or
  process.name like~ ("osascript", "bash", "sh", "zsh", "node")) and
 not process.code_signature.signing_id like "com.steinberg.cubase*" and
 not process.executable like "/private/tmp/PKInstallSandbox.*" and
 not Effective_process.executable like ("/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon",
                                        "/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfManagementService.app/Contents/MacOS/JamfManagementService",
                                        "/Library/Kandji/Kandji Agent.app/Contents/Helpers/Kandji Library Manager.app/Contents/MacOS/kandji-library-manager",
                                        "/Library/Intune/Microsoft Intune Agent.app/Contents/MacOS/IntuneMdmDaemon", 
                                        "/Applications/iZotope Product Portal.app/Contents/MacOS/Product Portal")
'''

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1106"
name = "Native API"
reference = "https://attack.mitre.org/techniques/T1106/"


[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1620"
name = "Reflective Code Loading"
reference = "https://attack.mitre.org/techniques/T1620/"


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

[internal]
min_endpoint_version = "8.11.0"

Stages and Predicates

Stage 1: library

library where ((event.action == "load" and not dll.path : "?*") or 
 (event.action == "load" and dll.name like "NSCreateObjectFileImageFromMemory*")) and 
 process.name != null and
 process.executable != null and
 ((process.code_signature.trusted == false or process.code_signature.exists == false) or
  process.name like~ ("osascript", "bash", "sh", "zsh", "node")) and
 not process.code_signature.signing_id like "com.steinberg.cubase*" and
 not process.executable like "/private/tmp/PKInstallSandbox.*" and
 not Effective_process.executable like ("/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon",
                                        "/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfManagementService.app/Contents/MacOS/JamfManagementService",
                                        "/Library/Kandji/Kandji Agent.app/Contents/Helpers/Kandji Library Manager.app/Contents/MacOS/kandji-library-manager",
                                        "/Library/Intune/Microsoft Intune Agent.app/Contents/MacOS/IntuneMdmDaemon", 
                                        "/Applications/iZotope Product Portal.app/Contents/MacOS/Product Portal")

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
Effective_process.executableeq/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon, /Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfManagementService.app/Contents/MacOS/JamfManagementService, /Library/Kandji/Kandji Agent.app/Contents/Helpers/Kandji Library Manager.app/Contents/MacOS/kandji-library-manager, /Library/Intune/Microsoft Intune Agent.app/Contents/MacOS/IntuneMdmDaemon, /Applications/iZotope Product Portal.app/Contents/MacOS/Product Portalexcludes:Effective_process.executable
process.code_signature.signing_idstarts_withcom.steinberg.cubaseexcludes:process.code_signature.signing_id field:"process.code_signature.signing_id" value:"com.steinberg.cubase"
process.executablestarts_with/private/tmp/PKInstallSandbox.excludes:process.executable field:"process.executable" value:"/private/tmp/PKInstallSandbox."

SMB (Windows File Sharing) Activity to the Internet

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

This rule detects network events that may indicate the use of Windows file sharing (also called SMB or CIFS) traffic to the Internet. SMB is commonly used within networks to share files, printers, and other system resources amongst trusted systems. It should almost never be directly exposed to the Internet, as it is frequently targeted and exploited by threat actors as an initial access or backdoor vector or for data exfiltration.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2020/02/18"
integration = ["network_traffic", "panw", "fortinet_fortigate", "pfsense", "zeek", "corelight"]
maturity = "production"
updated_date = "2026/08/26"

[rule]
author = ["Elastic"]
description = """
This rule detects network events that may indicate the use of Windows file sharing (also called SMB or CIFS) traffic to
the Internet. SMB is commonly used within networks to share files, printers, and other system resources amongst trusted
systems. It should almost never be directly exposed to the Internet, as it is frequently targeted and exploited by
threat actors as an initial access or backdoor vector or for data exfiltration.
"""
from = "now-9m"
index = ["logs-network_traffic.*", "logs-panw.panos*", "logs-fortinet_fortigate.log-*", "logs-pfsense.log-*", "logs-zeek.*", "logs-corelight.*"]
language = "kuery"
license = "Elastic License v2"
name = "SMB (Windows File Sharing) Activity to the Internet"
references = ["https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml"]
risk_score = 47
rule_id = "c82b2bd8-d701-420c-ba43-f11a155b681a"
severity = "medium"
tags = ["Tactic: Initial Access",
        "Tactic: Exfiltration",
        "Domain: Network",
        "Use Case: Threat Detection",
        "Data Source: Corelight",
        "Data Source: Fortinet",
        "Data Source: PAN-OS",
        "Data Source: Network Traffic",
        "Data Source: pfSense",
        "Data Source: Zeek",
        "Resources: Investigation Guide"]
timestamp_override = "event.ingested"
type = "new_terms"

query = '''
(data_stream.dataset:(fortinet_fortigate.log or network_traffic.flow or zeek.smb_cmd or zeek.smb_files or zeek.smb_mapping) or event.category:(network or network_traffic))
  and network.transport:tcp and destination.port:(139 or 445)
  and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)
  and not destination.ip:(10.0.0.0/8
    or 100.64.0.0/10
    or 127.0.0.0/8
    or 169.254.0.0/16
    or 172.16.0.0/12
    or 192.0.0.0/24
    or 192.0.0.0/29
    or 192.0.0.10/32
    or 192.0.0.170/32
    or 192.0.0.171/32
    or 192.0.0.8/32
    or 192.0.0.9/32
    or 192.0.2.0/24
    or 192.168.0.0/16
    or 192.175.48.0/24
    or 192.31.196.0/24
    or 192.52.193.0/24
    or 192.88.99.0/24
    or 198.18.0.0/15
    or 198.51.100.0/24
    or 203.0.113.0/24
    or 224.0.0.0/4
    or 240.0.0.0/4
    or "::1"
    or "FE80::/10"
    or "FF00::/8")
'''
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 SMB (Windows File Sharing) Activity to the Internet

SMB, a protocol for sharing files and resources within trusted networks, is vulnerable when exposed to the Internet. Adversaries exploit it for unauthorized access or data theft. The detection rule identifies suspicious SMB traffic from internal IPs to external networks, flagging potential threats by monitoring specific ports and excluding known safe IP ranges.

### Possible investigation steps

- Review the source IP address from the alert to identify the internal system initiating the SMB traffic. Check if this IP belongs to a known device or user within the organization.
- Investigate the destination IP address to determine if it is associated with any known malicious activity or if it belongs to a legitimate external service that might require SMB access.
- Analyze network logs to identify any patterns or anomalies in the SMB traffic, such as unusual data transfer volumes or repeated access attempts, which could indicate malicious activity.
- Check for any recent changes or updates on the source system that might explain the SMB traffic, such as new software installations or configuration changes.
- Correlate the alert with other security events or logs, such as authentication logs or endpoint security alerts, to gather additional context and determine if this is part of a broader attack or isolated incident.
- Consult threat intelligence sources to see if there are any known vulnerabilities or exploits related to the SMB traffic observed, which could provide insight into potential attack vectors.

### False positive analysis

- Internal testing environments may generate SMB traffic to external IPs for legitimate reasons. Identify and whitelist these IPs to prevent false positives.
- Cloud services or remote backup solutions might use SMB for data transfer. Verify these services and add their IP ranges to the exception list if they are trusted.
- VPN connections can sometimes appear as external traffic. Ensure that VPN IP ranges are included in the list of known safe IPs to avoid misclassification.
- Misconfigured network devices might inadvertently route SMB traffic externally. Regularly audit network configurations and update the rule exceptions to include any legitimate device IPs.
- Some third-party applications may use SMB for updates or data synchronization. Confirm the legitimacy of these applications and exclude their associated IPs from the detection rule.

### Response and remediation

- Immediately isolate the affected system from the network to prevent further unauthorized access or data exfiltration.
- Conduct a thorough review of firewall and network configurations to ensure SMB traffic is not allowed to the Internet, and block any unauthorized outbound SMB traffic on ports 139 and 445.
- Perform a comprehensive scan of the isolated system for malware or unauthorized access tools, focusing on identifying any backdoors or persistence mechanisms.
- Reset credentials and review access permissions for any accounts that may have been compromised or used in the suspicious activity.
- Notify the security operations center (SOC) and relevant stakeholders about the incident for further analysis and potential escalation.
- Implement additional monitoring and logging for SMB traffic to detect any future unauthorized attempts to access the Internet.
- Review and update security policies and procedures to prevent similar incidents, ensuring that SMB services are only accessible within trusted network segments."""


[[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 = "T1048"
name = "Exfiltration Over Alternative Protocol"
reference = "https://attack.mitre.org/techniques/T1048/"


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


[rule.new_terms]
field = "new_terms_fields"
value = ["source.ip"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-5d"

Stages and Predicates

Stage 1: new_terms

(data_stream.dataset:(fortinet_fortigate.log or network_traffic.flow or zeek.smb_cmd or zeek.smb_files or zeek.smb_mapping) or event.category:(network or network_traffic))
  and network.transport:tcp and destination.port:(139 or 445)
  and source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)
  and not destination.ip:(10.0.0.0/8
    or 100.64.0.0/10
    or 127.0.0.0/8
    or 169.254.0.0/16
    or 172.16.0.0/12
    or 192.0.0.0/24
    or 192.0.0.0/29
    or 192.0.0.10/32
    or 192.0.0.170/32
    or 192.0.0.171/32
    or 192.0.0.8/32
    or 192.0.0.9/32
    or 192.0.2.0/24
    or 192.168.0.0/16
    or 192.175.48.0/24
    or 192.31.196.0/24
    or 192.52.193.0/24
    or 192.88.99.0/24
    or 198.18.0.0/15
    or 198.51.100.0/24
    or 203.0.113.0/24
    or 224.0.0.0/4
    or 240.0.0.0/4
    or "::1"
    or "FE80::/10"
    or "FF00::/8")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
data_stream.datasetin
  • fortinet_fortigate.log
  • network_traffic.flow
  • zeek.smb_cmd
  • zeek.smb_files
  • zeek.smb_mapping
field:"data_stream.dataset" kind:in
destination.portin
  • 139
  • 445
field:"DestinationPort" kind:in
event.categoryin
  • network
  • network_traffic
field:"event.category" kind:in
network.transporteq
  • tcp
field:"Protocol" kind:eq value:"tcp"
source.ipin
  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.168.0.0/16
field:"src_ip" kind:in

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
destination.ipin10.0.0.0/8, 100.64.0.0/10, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.0.0.0/24, 192.0.0.0/29, 192.0.0.10/32, 192.0.0.170/32, 192.0.0.171/32, 192.0.0.8/32, 192.0.0.9/32, 192.0.2.0/24, 192.168.0.0/16, 192.175.48.0/24, 192.31.196.0/24, 192.52.193.0/24, 192.88.99.0/24, 198.18.0.0/15, 198.51.100.0/24, 203.0.113.0/24, 224.0.0.0/4, 240.0.0.0/4, ::1, FE80::/10, FF00::/8excludes:destination.ip

Systemd Timer Created

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

Detects the creation of a systemd timer within any of the default systemd timer directories. Systemd timers can be used by an attacker to gain persistence, by scheduling the execution of a command or script. Similarly to cron/at, systemd timers can be set up to execute on boot time, or on a specific point in time, which allows attackers to regain access in case the connection to the infected asset was lost.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2023/02/24"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"

[transform]
[[transform.osquery]]
label = "Osquery - Retrieve File Information"
query = "SELECT * FROM file WHERE path = {{file.path}}"

[[transform.osquery]]
label = "Osquery - Retrieve File Listing Information"
query = """
SELECT * FROM file WHERE (path LIKE '/etc/systemd/system/%' OR path LIKE '/usr/local/lib/systemd/system/%' OR path LIKE
'/lib/systemd/system/%' OR path LIKE '/usr/lib/systemd/system/%' OR path LIKE
'/home/{{user.name}}/.config/systemd/user/%' OR path LIKE '/home/{{user.name}}/.local/share/systemd/user/%' OR path LIKE
'/root/.config/systemd/user/%' OR path LIKE '/root/.local/share/systemd/user/%' OR path LIKE '/etc/systemd/user/%' OR
path LIKE '/usr/lib/systemd/user/%')
"""

[[transform.osquery]]
label = "Osquery - Retrieve Additional File Listing Information"
query = """
SELECT f.path, u.username AS file_owner, g.groupname AS group_owner, datetime(f.atime, 'unixepoch') AS
file_last_access_time, datetime(f.mtime, 'unixepoch') AS file_last_modified_time, datetime(f.ctime, 'unixepoch') AS
file_last_status_change_time, datetime(f.btime, 'unixepoch') AS file_created_time, f.size AS size_bytes FROM file f LEFT
JOIN users u ON f.uid = u.uid LEFT JOIN groups g ON f.gid = g.gid WHERE ( path LIKE '/etc/systemd/system/%' OR path LIKE
'/usr/local/lib/systemd/system/%' OR path LIKE '/lib/systemd/system/%' OR path LIKE '/usr/lib/systemd/system/%' OR path
LIKE '/home/{{user.name}}/.config/systemd/user/%' OR path LIKE '/home/{{user.name}}/.local/share/systemd/user/%' OR path
LIKE '/root/.config/systemd/user/%' OR path LIKE '/root/.local/share/systemd/user/%' OR path LIKE '/etc/systemd/user/%'
OR path LIKE '/usr/lib/systemd/user/%')
"""

[[transform.osquery]]
label = "Osquery - Retrieve Running Processes by User"
query = "SELECT pid, username, name FROM processes p JOIN users u ON u.uid = p.uid ORDER BY username"

[[transform.osquery]]
label = "Osquery - Retrieve Crontab Information"
query = "SELECT * FROM crontab"

[rule]
author = ["Elastic"]
description = """
Detects the creation of a systemd timer within any of the default systemd timer directories. Systemd timers can be used
by an attacker to gain persistence, by scheduling the execution of a command or script. Similarly to cron/at, systemd
timers can be set up to execute on boot time, or on a specific point in time, which allows attackers to regain access in
case the connection to the infected asset was lost.
"""
from = "now-9m"
index = ["logs-endpoint.events.file*"]
language = "eql"
license = "Elastic License v2"
name = "Systemd Timer Created"
note = """## Triage and analysis

### Investigating Systemd Timer Created

Systemd timers are used for scheduling and automating recurring tasks or services on Linux systems. 

Attackers can leverage systemd timers to run scripts, commands, or malicious software at system boot or on a set time interval by creating a systemd timer and a corresponding systemd service file. 

This rule monitors the creation of new systemd timer files, potentially indicating the creation of a persistence mechanism.

> **Note**:
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/current/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.
> This investigation guide uses [placeholder fields](https://www.elastic.co/guide/en/security/current/osquery-placeholder-fields.html) to dynamically pass alert data into Osquery queries. Placeholder fields were introduced in Elastic Stack version 8.7.0. If you're using Elastic Stack version 8.6.0 or earlier, you'll need to manually adjust this investigation guide's queries to ensure they properly run.

#### Possible Investigation Steps

- Investigate the timer file that was created or modified.
  - $osquery_0
- Investigate the currently enabled systemd timers through the following command `sudo systemctl list-timers`.
- Search for the systemd service file named similarly to the timer that was created.
- Investigate whether any other files in any of the available systemd directories have been altered through OSQuery.
  - $osquery_1
  - $osquery_2
- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence and whether they are located in expected locations.
  - $osquery_3
- Investigate other alerts associated with the user/host during the past 48 hours.
- Validate the activity is not related to planned patches, updates, network administrator activity, or legitimate software installations.
- Investigate whether the altered scripts call other malicious scripts elsewhere on the file system. 
  - If scripts or executables were dropped, retrieve the files and determine if they are malicious:
    - Use a private sandboxed malware analysis system to perform analysis.
      - Observe and collect information about the following activities:
        - Attempts to contact external domains and addresses.
          - Check if the domain is newly registered or unexpected.
          - Check the reputation of the domain or IP address.
        - File access, modification, and creation activities.
        - Cron jobs, services and other persistence mechanisms.
            - $osquery_4

### False Positive Analysis

- If this activity is related to new benign software installation activity, consider adding exceptions — preferably with a combination of user and command line conditions.
- If this activity is related to a system administrator who uses systemd timers for administrative purposes, consider adding exceptions for this specific administrator user account. 
- Try to understand the context of the execution by thinking about the user, machine, or business purpose. A small number of endpoints, such as servers with unique software, might appear unusual but satisfy a specific business need.

### Response and remediation

- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- If the triage identified malware, search the environment for additional compromised hosts.
  - Implement temporary network rules, procedures, and segmentation to contain the malware.
  - Stop suspicious processes.
  - Immediately block the identified indicators of compromise (IoCs).
  - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that attackers could use to reinfect the system.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Delete the service/timer or restore its original configuration.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Leverage the incident response data and logging to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
references = [
    "https://opensource.com/article/20/7/systemd-timers",
    "https://pberba.github.io/security/2022/01/30/linux-threat-hunting-for-persistence-systemd-timers-cron/",
    "https://www.elastic.co/security-labs/primer-on-persistence-mechanisms",
]
risk_score = 21
rule_id = "7fb500fa-8e24-4bd1-9480-2a819352602c"
setup = """## Setup

This rule requires data coming in from Elastic Defend.

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

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

#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Persistence",
    "Resources: Investigation Guide",
    "Data Source: Elastic Defend",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
file where host.os.type == "linux" and event.action in ("rename", "creation") and file.path : (
  "/etc/systemd/system/*", "/etc/systemd/user/*", "/usr/local/lib/systemd/system/*",
  "/lib/systemd/system/*", "/usr/lib/systemd/system/*", "/usr/lib/systemd/user/*",
  "/home/*/.config/systemd/user/*", "/home/*/.local/share/systemd/user/*",
  "/root/.config/systemd/user/*", "/root/.local/share/systemd/user/*"
) and file.extension == "timer" and not (
  process.executable in (
    "/bin/dpkg", "/usr/bin/dpkg", "/bin/dockerd", "/usr/bin/dockerd", "/usr/sbin/dockerd", "/bin/microdnf",
    "/usr/bin/microdnf", "/bin/rpm", "/usr/bin/rpm", "/bin/snapd", "/usr/bin/snapd", "/bin/yum", "/usr/bin/yum",
    "/bin/dnf", "/usr/bin/dnf", "/bin/podman", "/usr/bin/podman", "/bin/dnf-automatic", "/usr/bin/dnf-automatic",
    "/bin/pacman", "/usr/bin/pacman", "/usr/bin/dpkg-divert", "/bin/dpkg-divert", "/sbin/apk", "/usr/sbin/apk",
    "/usr/local/sbin/apk", "/usr/bin/apt", "/usr/sbin/pacman", "/bin/podman", "/usr/bin/podman", "/usr/bin/puppet",
    "/bin/puppet", "/opt/puppetlabs/puppet/bin/puppet", "/usr/bin/chef-client", "/bin/chef-client",
    "/bin/autossl_check", "/usr/bin/autossl_check", "/proc/self/exe", "/usr/bin/pamac-daemon", "./usr/bin/podman",
    "/bin/pamac-daemon", "/usr/lib/snapd/snapd", "/usr/local/bin/dockerd", "/usr/bin/crio", "/usr/sbin/crond",
    "/opt/puppetlabs/puppet/bin/ruby", "/usr/libexec/platform-python", "/kaniko/kaniko-executor",
    "/usr/local/bin/dockerd", "/usr/bin/podman", "/bin/install", "/proc/self/exe", "/kaniko/executor",
    "/etc/checkpoint/common/install.sh", "/usr/bin/dnf5", "/usr/libexec/packagekitd", "/usr/sbin/dnf",
    "/opt/kaniko/executor", "/usr/bin/env", "/usr/local/bin/teleport-update", "/usr/bin/buildah",
    "/usr/lib/systemd/systemd", "/usr/local/bin/defender"
  ) or
  process.name like (
    "python*", "crio", "apt-get", "install", "snapd", "cloudflared", "sshd", "convert-usrmerge", "docker-init",
    "google_metadata_script_runner", "ssm-agent-worker", "pacman", "convert2rhel", "platform-python*"
  ) or
  file.extension in ("swp", "swpx", "swx", "dpkg-remove") or
  file.Ext.original.extension == "dpkg-new" or
  process.executable like (
    "/nix/store/*", "/var/lib/dpkg/*", "/tmp/vmis.*", "/snap/*", "/dev/fd/*", "/usr/lib/virtualbox/*",
    "/var/lib/docker/overlay2/*/dockerd", "/home/*/bin/dockerd", "/var/lib/containers/storage/overlay/*/dockerd"
  ) or
  process.executable == null or
  (process.name == "sed" and file.name : "sed*") or
  (process.name == "perl" and file.name : "e2scrub_all.tmp*") 
)
'''

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

[[rule.threat.technique]]
id = "T1053"
name = "Scheduled Task/Job"
reference = "https://attack.mitre.org/techniques/T1053/"

[[rule.threat.technique.subtechnique]]
id = "T1053.006"
name = "Systemd Timers"
reference = "https://attack.mitre.org/techniques/T1053/006/"

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

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

[[rule.threat.technique]]
id = "T1053"
name = "Scheduled Task/Job"
reference = "https://attack.mitre.org/techniques/T1053/"

[[rule.threat.technique.subtechnique]]
id = "T1053.006"
name = "Systemd Timers"
reference = "https://attack.mitre.org/techniques/T1053/006/"

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

Stages and Predicates

Stage 1: file

file where host.os.type == "linux" and event.action in ("rename", "creation") and file.path : (
  "/etc/systemd/system/*", "/etc/systemd/user/*", "/usr/local/lib/systemd/system/*",
  "/lib/systemd/system/*", "/usr/lib/systemd/system/*", "/usr/lib/systemd/user/*",
  "/home/*/.config/systemd/user/*", "/home/*/.local/share/systemd/user/*",
  "/root/.config/systemd/user/*", "/root/.local/share/systemd/user/*"
) and file.extension == "timer" and not (
  process.executable in (
    "/bin/dpkg", "/usr/bin/dpkg", "/bin/dockerd", "/usr/bin/dockerd", "/usr/sbin/dockerd", "/bin/microdnf",
    "/usr/bin/microdnf", "/bin/rpm", "/usr/bin/rpm", "/bin/snapd", "/usr/bin/snapd", "/bin/yum", "/usr/bin/yum",
    "/bin/dnf", "/usr/bin/dnf", "/bin/podman", "/usr/bin/podman", "/bin/dnf-automatic", "/usr/bin/dnf-automatic",
    "/bin/pacman", "/usr/bin/pacman", "/usr/bin/dpkg-divert", "/bin/dpkg-divert", "/sbin/apk", "/usr/sbin/apk",
    "/usr/local/sbin/apk", "/usr/bin/apt", "/usr/sbin/pacman", "/bin/podman", "/usr/bin/podman", "/usr/bin/puppet",
    "/bin/puppet", "/opt/puppetlabs/puppet/bin/puppet", "/usr/bin/chef-client", "/bin/chef-client",
    "/bin/autossl_check", "/usr/bin/autossl_check", "/proc/self/exe", "/usr/bin/pamac-daemon", "./usr/bin/podman",
    "/bin/pamac-daemon", "/usr/lib/snapd/snapd", "/usr/local/bin/dockerd", "/usr/bin/crio", "/usr/sbin/crond",
    "/opt/puppetlabs/puppet/bin/ruby", "/usr/libexec/platform-python", "/kaniko/kaniko-executor",
    "/usr/local/bin/dockerd", "/usr/bin/podman", "/bin/install", "/proc/self/exe", "/kaniko/executor",
    "/etc/checkpoint/common/install.sh", "/usr/bin/dnf5", "/usr/libexec/packagekitd", "/usr/sbin/dnf",
    "/opt/kaniko/executor", "/usr/bin/env", "/usr/local/bin/teleport-update", "/usr/bin/buildah",
    "/usr/lib/systemd/systemd", "/usr/local/bin/defender"
  ) or
  process.name like (
    "python*", "crio", "apt-get", "install", "snapd", "cloudflared", "sshd", "convert-usrmerge", "docker-init",
    "google_metadata_script_runner", "ssm-agent-worker", "pacman", "convert2rhel", "platform-python*"
  ) or
  file.extension in ("swp", "swpx", "swx", "dpkg-remove") or
  file.Ext.original.extension == "dpkg-new" or
  process.executable like (
    "/nix/store/*", "/var/lib/dpkg/*", "/tmp/vmis.*", "/snap/*", "/dev/fd/*", "/usr/lib/virtualbox/*",
    "/var/lib/docker/overlay2/*/dockerd", "/home/*/bin/dockerd", "/var/lib/containers/storage/overlay/*/dockerd"
  ) or
  process.executable == null or
  (process.name == "sed" and file.name : "sed*") or
  (process.name == "perl" and file.name : "e2scrub_all.tmp*") 
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actionin
  • creation
  • rename
field:"EventType" kind:in
file.extensioneq
  • timer
field:"file.extension" kind:eq value:"timer"
file.pathwildcard
  • /etc/systemd/system/*
  • /etc/systemd/user/*
  • /home/*/.config/systemd/user/*
  • /home/*/.local/share/systemd/user/*
  • /lib/systemd/system/*
  • /root/.config/systemd/user/*
  • /root/.local/share/systemd/user/*
  • /usr/lib/systemd/system/*
  • /usr/lib/systemd/user/*
  • /usr/local/lib/systemd/system/*
field:"TargetFilename" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
file.namestarts_withe2scrub_all.tmpexcludes:file.name field:"file.name" value:"e2scrub_all.tmp"
process.nameeqperlexcludes:process.name field:"process.name" value:"perl"
file.namestarts_withsedexcludes:file.name field:"file.name" value:"sed"
process.nameeqsedexcludes:process.name field:"process.name" value:"sed"
file.Ext.original.extensioneqdpkg-newexcludes:file.Ext.original.extension field:"file.Ext.original.extension" value:"dpkg-new"
file.extensionindpkg-remove, swp, swpx, swxexcludes:file.extension
process.executablein./usr/bin/podman, /bin/autossl_check, /bin/chef-client, /bin/dnf, /bin/dnf-automatic, /bin/dockerd, /bin/dpkg, /bin/dpkg-divert, /bin/install, /bin/microdnf, /bin/pacman, /bin/pamac-daemon, /bin/podman, /bin/puppet, /bin/rpm, /bin/snapd, /bin/yum, /etc/checkpoint/common/install.sh, /kaniko/executor, /kaniko/kaniko-executor, /opt/kaniko/executor, /opt/puppetlabs/puppet/bin/puppet, /opt/puppetlabs/puppet/bin/ruby, /proc/self/exe, /sbin/apk, /usr/bin/apt, /usr/bin/autossl_check, /usr/bin/buildah, /usr/bin/chef-client, /usr/bin/crio, /usr/bin/dnf, /usr/bin/dnf-automatic, /usr/bin/dnf5, /usr/bin/dockerd, /usr/bin/dpkg, /usr/bin/dpkg-divert, /usr/bin/env, /usr/bin/microdnf, /usr/bin/pacman, /usr/bin/pamac-daemon, /usr/bin/podman, /usr/bin/puppet, /usr/bin/rpm, /usr/bin/snapd, /usr/bin/yum, /usr/lib/snapd/snapd, /usr/lib/systemd/systemd, /usr/libexec/packagekitd, /usr/libexec/platform-python, /usr/local/bin/defender, /usr/local/bin/dockerd, /usr/local/bin/teleport-update, /usr/local/sbin/apk, /usr/sbin/apk, /usr/sbin/crond, /usr/sbin/dnf, /usr/sbin/dockerd, /usr/sbin/pacmanexcludes:process.executable
process.executableis_null(no value, null check)excludes:process.executable
process.executablewildcard/nix/store/*, /var/lib/dpkg/*, /tmp/vmis.*, /snap/*, /dev/fd/*, /usr/lib/virtualbox/*, /var/lib/docker/overlay2/*/dockerd, /home/*/bin/dockerd, /var/lib/containers/storage/overlay/*/dockerdexcludes:process.executable
process.namewildcardpython*, crio, apt-get, install, snapd, cloudflared, sshd, convert-usrmerge, docker-init, google_metadata_script_runner, ssm-agent-worker, pacman, convert2rhel, platform-python*excludes:process.name

Windows Console Execution from Unbacked Memory

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

Identifies the creation of a Windows console host process where the creating thread's stack contains frames pointing outside any known executable image. This may be indicative of the use of a built-in Windows shell from an injected process.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the creation of a Windows console host process where the creating thread's stack contains frames pointing
outside any known executable image. This may be indicative of the use of a built-in Windows shell from an injected
process.
"""
id = "7b186a20-22eb-4ea2-81ec-6d15dd6ee341"
license = "Elastic License v2"
name = "Windows Console Execution from Unbacked Memory"
os_list = ["windows"]
reference = [
    "https://www.elastic.co/security-labs/upping-the-ante-detecting-in-memory-threats-with-kernel-call-stacks",
]
version = "1.0.27"

query = '''
sequence with maxspan=5m
[process where event.action == "start" and process.parent.executable != null and
 process.parent.thread.Ext.call_stack_contains_unbacked == true and
 (process.executable : "?:\\Windows\\Sys*\\conhost.exe" and process.args : "0xffffffff") and
  process.parent.thread.Ext.call_stack_summary :
               ("ntdll.dll|kernelbase.dll|Unbacked",
                "ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|Unbacked",
                "ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|Unbacked|kernel32.dll|ntdll.dll") and
  not (user.id == "S-1-5-18" and
       process.parent.executable :
                     ("?:\\ProgramData\\*.exe",
                      "?:\\Program Files\\*.exe",
                      "?:\\Program Files (x86)\\*.exe",
                      "?:\\Windows\\LTSvc\\LTSVC.exe",
                      "?:\\Windows\\System32\\msiexec.exe",
                      "C:\\Windows\\_ScriptingFramework\\Modul\\Engine.exe",
                      "C:\\Windows\\_ScriptingFramework\\Modul\\ScriptingFrameworkEngine.exe",
                      "C:\\Windows\\SysWOW64\\SmartDeploy\\ClientService.exe",
                      "I:\\RSA\\Microsoft Azure Recovery Services Agent\\bin\\cbengine.exe",
                      "C:\\Drivers\\Nord\\NordSec ThreatProtection\\nordsec-threatprotection-service.exe")) and
  not (process.parent.executable : "?:\\Windows\\System32\\WindowsPowerShell\\*\\powershell.exe" and user.id : "S-1-5-18" and
       process.code_signature.trusted == true) and
  not (process.code_signature.subject_name : "ProVation Medical" and process.code_signature.trusted == true) and
  not (process.parent.code_signature.subject_name in ("UiPath, Inc.", "QSR International Pty Ltd") and process.parent.code_signature.trusted == true) and
  not (process.parent.code_signature.subject_name : "Microsoft Corporation" and
       process.parent.code_signature.trusted == true and
       process.parent.executable : ("?:\\*\\Microsoft.SQLServer.*.Express.*.exe",
                                     "?:\\*\\SQL*-SSEI-Expr.exe")) and
  not process.parent.executable :
                    ("?:\\Packages\\Plugins\\Microsoft.GuestConfiguration.ConfigurationforWindows\\*\\gc_service.exe",
                     "?:\\Windows\\System32\\wsmprovhost.exe",
                     "?:\\Program Files (x86)\\Wondershare\\*.exe",
                     "?:\\Windows\\System32\\drivers\\*.exe",
                     "?:\\Program Files*\\Cloudflare\\*.exe",
                     "?:\\Program Files (x86)\\Universal\\Universal.Server.exe",
                     "?:\\Program Files*\\Listary\\Listary.exe",
                     "?:\\Program Files*\\ExpressConnect\\ECDBWMService.exe",
                     "?:\\ProVation\\Utilities\\ProVation.DataExport\\ProVation.DataExport.exe",
                     "?:\\Windows\\System32\\WindowsPowerShell\\*\\powershell_ise.exe",
                     "?:\\WINDOWS\\_ScriptingFramework\\Modul\\Engine.exe",
                     "?:\\Program Files\\Citrix\\Telemetry Service\\TelemetryService.exe",
                     "?:\\ProVation\\Utilities\\Database Utilities\\ProVation.DataExport.exe",
                     "?:\\Program Files*\\UiPath\\Studio\\UiPath.Studio.Project.exe",
                     "?:\\Program Files*\\Microsoft System Center\\Operations Manager\\Server\\MonitoringHost.exe",
                     "?:\\Program Files (x86)\\Canfield Scientific Inc\\PortalService\\CanfieldRegister.exe",
                     "?:\\Program Files*\\Microsoft System Center\\Operations Manager\\Server\\MonitoringHost.exe",
                     "?:\\Drivers\\MITS_FATClient_SupportTool\\MITS_FATClient_SupportTool_admin.exe",
                     "?:\\Program Files*\\Microsoft Visual Studio\\*\\Community\\Common?\\IDE\\devenv.exe",
                     "?:\\Program Files\\ObserveIT\\WebsiteCat\\WebsiteCat.Manager.exe",
                     "?:\\Program Files\\Microsoft Azure Active Directory Connect\\AzureADConnect.exe",
                     "?:\\Program Files (x86)\\vMix\\vMix64.exe",
                     "?:\\Work\\HP DIAG TOOL\\ImageDiags.exe",
                     "C:\\Work\\ImageDiags.exe",
                     "?:\\Program Files (x86)\\Driver Support One\\DSOneWeb.exe",
                     "?:\\Program Files (x86)\\Team Shinkansen\\Hakchi2 CE\\hakchi.exe",
                     "?:\\Program Files (x86)\\HP DIAG TOOL\\ImageDiags.exe",
                     "?:\\ProVation\\Utilities\\Database Utilities\\ProVation.DataExport19c\\ProVation.DataExport.exe",
                     "?:\\Program Files\\WindowsApps\\*\\DCv2\\DCv2.exe",
                     "?:\\Users\\*\\Desktop\\HP DIAG TOOL\\ImageDiags.exe",
                     "?:\\ProVation\\Utilities\\Database Utilities\\ProVation.DataExport*\\ProVation.DataExport.exe",
                     "\\Device\\Mup\\*\\Release\\CorrespondanceDownload.vshost.exe",
                     "?:\\Users\\*\\AppData\\Local\\Programs\\UiPath\\Studio\\UiPath.Studio.Project.exe",
                     "D:\\*\\Exporter\\bin\\Debug\\Exporter.vshost.exe",
                     "C:\\Windows\\SysWOW64\\SmartDeploy\\ClientService.exe",
                     "C:\\Program Files\\QSR\\NVivo ??\\NVivo.exe",
                     "C:\\Program Files\\McCormick Systems\\McCormick Estimating\\MaintenanceUtility.exe",
                     "D:\\PROGRAMS\\UiPath\\Studio\\UiPath.Studio.Project.exe",
                     "C:\\Users\\*\\AppData\\Roaming\\GWP\\MSOffice-AddIns\\Deploy-MSOfficeAddIns.exe",
                     "C:\\Program Files\\Devolutions\\Remote Desktop Manager\\RemoteDesktopManager.exe",
                     "C:\\Program Files\\QSR\\NVivo 14\\NVivo.exe",
                     "C:\\Program Files (x86)\\Genetec SV Control Panel\\Control Panel\\SVControlPanel.exe",
                     "D:\\PROGRAMS\\UiPath\\Studio\\UiPath.Studio.Project.exe",
                     "C:\\Program Files (x86)\\Chocolatey GUI\\ChocolateyGui.exe",
                     "C:\\Program Files\\Royal TS V7\\RoyalTS.exe",
                     "C:\\Program Files\\QSR\\NVivo ??\\NVivo.exe",
                     "C:\\Program Files\\Password Safe and Repository*\\PSRServer.exe",
                     "C:\\Program Files\\WindowsApps\\Microsoft.GetHelp_*\\GetHelp.exe", 
                     "C:\\Program Files\\WindowsApps\\Microsoft.DesktopAppInstaller_*\\DotNet\\ConfigurationRemotingServer.exe",
                     "C:\\Program Files (x86)\\CentraStage\\CagService.exe", 
                     "D:\\Microsoft Azure\\Microsoft Azure Recovery Services Agent\\bin\\cbengine.exe", 
                     "C:\\Program Files (x86)\\BMW\\ISPI\\ISVM\\IMIBNext\\Ediabas\\bin\\EbasServer.exe", 
                     "C:\\Program Files\\ASUS\\ASUS VeriView\\ASUSEventClient.exe", 
                     "C:\\Program Files (x86)\\Kovai Ltd\\BizTalk360\\Service\\BHMCollect.exe", 
                     "C:\\Program Files\\Common Files\\eClinicalWorks\\plugin\\WinProjectE.exe", 
                     "C:\\Program Files (x86)\\BizTalkHealthMonitor\\BHMCollect.exe", 
                     "?:\\Program Files (x86)\\Welch Allyn\\Connex\\Server\\*\\DataBaseInstaller\\DatabaseInstaller.exe") and
  not _arraysearch(process.parent.thread.Ext.call_stack, $entry,
                   $entry.callsite_trailing_bytes :
                              ("c6460c01833d*e85ff0f95c00fb6c00fb6c0c6460c01488b559048895610488d65c85b5e5f415c415d415e415f",
                               "*48895610488d65c85b5e5f415c415d415e415f5dc30000001910090010c20c300b60*",
                               "*95c00fb6c0488b5588488956104883c4785b5e5f415c41*",
                               "c6460c01833d9c8c755e007406ff15a495755e85c00f95c00fb6c00fb6c0c6460c01488b559048895610488d65c85b5e5f415c415d415e415f5dc31910090010"))

  ] by process.parent.entity_id
[network where true] by process.entity_id
'''

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

[[actions]]
action = "kill_process"
field = "process.parent.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.003"
name = "Windows Command Shell"
reference = "https://attack.mitre.org/techniques/T1059/003/"



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


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

[internal]
min_endpoint_version = "8.10.0"

Stages and Predicates

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

Stage 1: process

[process where event.action == "start" and process.parent.executable != null and
 process.parent.thread.Ext.call_stack_contains_unbacked == true and
 (process.executable : "?:\\Windows\\Sys*\\conhost.exe" and process.args : "0xffffffff") and
  process.parent.thread.Ext.call_stack_summary :
               ("ntdll.dll|kernelbase.dll|Unbacked",
                "ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|Unbacked",
                "ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|Unbacked|kernel32.dll|ntdll.dll") and
  not (user.id == "S-1-5-18" and
       process.parent.executable :
                     ("?:\\ProgramData\\*.exe",
                      "?:\\Program Files\\*.exe",
                      "?:\\Program Files (x86)\\*.exe",
                      "?:\\Windows\\LTSvc\\LTSVC.exe",
                      "?:\\Windows\\System32\\msiexec.exe",
                      "C:\\Windows\\_ScriptingFramework\\Modul\\Engine.exe",
                      "C:\\Windows\\_ScriptingFramework\\Modul\\ScriptingFrameworkEngine.exe",
                      "C:\\Windows\\SysWOW64\\SmartDeploy\\ClientService.exe",
                      "I:\\RSA\\Microsoft Azure Recovery Services Agent\\bin\\cbengine.exe",
                      "C:\\Drivers\\Nord\\NordSec ThreatProtection\\nordsec-threatprotection-service.exe")) and
  not (process.parent.executable : "?:\\Windows\\System32\\WindowsPowerShell\\*\\powershell.exe" and user.id : "S-1-5-18" and
       process.code_signature.trusted == true) and
  not (process.code_signature.subject_name : "ProVation Medical" and process.code_signature.trusted == true) and
  not (process.parent.code_signature.subject_name in ("UiPath, Inc.", "QSR International Pty Ltd") and process.parent.code_signature.trusted == true) and
  not (process.parent.code_signature.subject_name : "Microsoft Corporation" and
       process.parent.code_signature.trusted == true and
       process.parent.executable : ("?:\\*\\Microsoft.SQLServer.*.Express.*.exe",
                                     "?:\\*\\SQL*-SSEI-Expr.exe")) and
  not process.parent.executable :
                    ("?:\\Packages\\Plugins\\Microsoft.GuestConfiguration.ConfigurationforWindows\\*\\gc_service.exe",
                     "?:\\Windows\\System32\\wsmprovhost.exe",
                     "?:\\Program Files (x86)\\Wondershare\\*.exe",
                     "?:\\Windows\\System32\\drivers\\*.exe",
                     "?:\\Program Files*\\Cloudflare\\*.exe",
                     "?:\\Program Files (x86)\\Universal\\Universal.Server.exe",
                     "?:\\Program Files*\\Listary\\Listary.exe",
                     "?:\\Program Files*\\ExpressConnect\\ECDBWMService.exe",
                     "?:\\ProVation\\Utilities\\ProVation.DataExport\\ProVation.DataExport.exe",
                     "?:\\Windows\\System32\\WindowsPowerShell\\*\\powershell_ise.exe",
                     "?:\\WINDOWS\\_ScriptingFramework\\Modul\\Engine.exe",
                     "?:\\Program Files\\Citrix\\Telemetry Service\\TelemetryService.exe",
                     "?:\\ProVation\\Utilities\\Database Utilities\\ProVation.DataExport.exe",
                     "?:\\Program Files*\\UiPath\\Studio\\UiPath.Studio.Project.exe",
                     "?:\\Program Files*\\Microsoft System Center\\Operations Manager\\Server\\MonitoringHost.exe",
                     "?:\\Program Files (x86)\\Canfield Scientific Inc\\PortalService\\CanfieldRegister.exe",
                     "?:\\Program Files*\\Microsoft System Center\\Operations Manager\\Server\\MonitoringHost.exe",
                     "?:\\Drivers\\MITS_FATClient_SupportTool\\MITS_FATClient_SupportTool_admin.exe",
                     "?:\\Program Files*\\Microsoft Visual Studio\\*\\Community\\Common?\\IDE\\devenv.exe",
                     "?:\\Program Files\\ObserveIT\\WebsiteCat\\WebsiteCat.Manager.exe",
                     "?:\\Program Files\\Microsoft Azure Active Directory Connect\\AzureADConnect.exe",
                     "?:\\Program Files (x86)\\vMix\\vMix64.exe",
                     "?:\\Work\\HP DIAG TOOL\\ImageDiags.exe",
                     "C:\\Work\\ImageDiags.exe",
                     "?:\\Program Files (x86)\\Driver Support One\\DSOneWeb.exe",
                     "?:\\Program Files (x86)\\Team Shinkansen\\Hakchi2 CE\\hakchi.exe",
                     "?:\\Program Files (x86)\\HP DIAG TOOL\\ImageDiags.exe",
                     "?:\\ProVation\\Utilities\\Database Utilities\\ProVation.DataExport19c\\ProVation.DataExport.exe",
                     "?:\\Program Files\\WindowsApps\\*\\DCv2\\DCv2.exe",
                     "?:\\Users\\*\\Desktop\\HP DIAG TOOL\\ImageDiags.exe",
                     "?:\\ProVation\\Utilities\\Database Utilities\\ProVation.DataExport*\\ProVation.DataExport.exe",
                     "\\Device\\Mup\\*\\Release\\CorrespondanceDownload.vshost.exe",
                     "?:\\Users\\*\\AppData\\Local\\Programs\\UiPath\\Studio\\UiPath.Studio.Project.exe",
                     "D:\\*\\Exporter\\bin\\Debug\\Exporter.vshost.exe",
                     "C:\\Windows\\SysWOW64\\SmartDeploy\\ClientService.exe",
                     "C:\\Program Files\\QSR\\NVivo ??\\NVivo.exe",
                     "C:\\Program Files\\McCormick Systems\\McCormick Estimating\\MaintenanceUtility.exe",
                     "D:\\PROGRAMS\\UiPath\\Studio\\UiPath.Studio.Project.exe",
                     "C:\\Users\\*\\AppData\\Roaming\\GWP\\MSOffice-AddIns\\Deploy-MSOfficeAddIns.exe",
                     "C:\\Program Files\\Devolutions\\Remote Desktop Manager\\RemoteDesktopManager.exe",
                     "C:\\Program Files\\QSR\\NVivo 14\\NVivo.exe",
                     "C:\\Program Files (x86)\\Genetec SV Control Panel\\Control Panel\\SVControlPanel.exe",
                     "D:\\PROGRAMS\\UiPath\\Studio\\UiPath.Studio.Project.exe",
                     "C:\\Program Files (x86)\\Chocolatey GUI\\ChocolateyGui.exe",
                     "C:\\Program Files\\Royal TS V7\\RoyalTS.exe",
                     "C:\\Program Files\\QSR\\NVivo ??\\NVivo.exe",
                     "C:\\Program Files\\Password Safe and Repository*\\PSRServer.exe",
                     "C:\\Program Files\\WindowsApps\\Microsoft.GetHelp_*\\GetHelp.exe", 
                     "C:\\Program Files\\WindowsApps\\Microsoft.DesktopAppInstaller_*\\DotNet\\ConfigurationRemotingServer.exe",
                     "C:\\Program Files (x86)\\CentraStage\\CagService.exe", 
                     "D:\\Microsoft Azure\\Microsoft Azure Recovery Services Agent\\bin\\cbengine.exe", 
                     "C:\\Program Files (x86)\\BMW\\ISPI\\ISVM\\IMIBNext\\Ediabas\\bin\\EbasServer.exe", 
                     "C:\\Program Files\\ASUS\\ASUS VeriView\\ASUSEventClient.exe", 
                     "C:\\Program Files (x86)\\Kovai Ltd\\BizTalk360\\Service\\BHMCollect.exe", 
                     "C:\\Program Files\\Common Files\\eClinicalWorks\\plugin\\WinProjectE.exe", 
                     "C:\\Program Files (x86)\\BizTalkHealthMonitor\\BHMCollect.exe", 
                     "?:\\Program Files (x86)\\Welch Allyn\\Connex\\Server\\*\\DataBaseInstaller\\DatabaseInstaller.exe") and
  not _arraysearch(process.parent.thread.Ext.call_stack, $entry,
                   $entry.callsite_trailing_bytes :
                              ("c6460c01833d*e85ff0f95c00fb6c00fb6c0c6460c01488b559048895610488d65c85b5e5f415c415d415e415f",
                               "*48895610488d65c85b5e5f415c415d415e415f5dc30000001910090010c20c300b60*",
                               "*95c00fb6c0488b5588488956104883c4785b5e5f415c41*",
                               "c6460c01833d9c8c755e007406ff15a495755e85c00f95c00fb6c00fb6c0c6460c01488b559048895610488d65c85b5e5f415c415d415e415f5dc31910090010"))

  ] by process.parent.entity_id

Stage 2: network

[network where true] by process.entity_id

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
  • 0xffffffff
field:"process.args" kind:wildcard value:"0xffffffff"
process.executablewildcard
  • ?:\Windows\Sys*\conhost.exe
field:"Image" kind:wildcard value:"?:\Windows\Sys*\conhost.exe"
process.parent.executableis_not_null
  • (no value, null check)
field:"ParentImage" kind:is_not_null
process.parent.thread.Ext.call_stack_contains_unbackedeq
  • true transforms: boolean corpus 7 (elastic 7)
field:"process.parent.thread.Ext.call_stack_contains_unbacked" kind:eq value:"true"
process.parent.thread.Ext.call_stack_summarywildcard
  • ntdll.dll|kernelbase.dll|Unbacked corpus 4 (elastic 4)
  • ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|Unbacked corpus 4 (elastic 4)
  • ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|kernelbase.dll|Unbacked|kernel32.dll|ntdll.dll corpus 4 (elastic 4)
field:"process.parent.thread.Ext.call_stack_summary" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.code_signature.subject_nameeqProVation Medicalexcludes:process.code_signature.subject_name field:"process.code_signature.subject_name" value:"ProVation Medical"
process.code_signature.trustedeqtrueexcludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true"
process.parent.executablewildcard?:\Windows\System32\WindowsPowerShell\*\powershell.exeexcludes:process.parent.executable field:"process.parent.executable" value:"?:\Windows\System32\WindowsPowerShell\*\powershell.exe"
user.ideqS-1-5-18excludes:user.id field:"user.id" value:"S-1-5-18"
process.parent.code_signature.subject_nameeqMicrosoft Corporationexcludes:process.parent.code_signature.subject_name field:"process.parent.code_signature.subject_name" value:"Microsoft Corporation"
process.parent.code_signature.trustedeqtrueexcludes:process.parent.code_signature.trusted field:"process.parent.code_signature.trusted" value:"true"
process.parent.executablewildcard?:\*\Microsoft.SQLServer.*.Express.*.exe, ?:\*\SQL*-SSEI-Expr.exeexcludes:process.parent.executable field:"process.parent.executable" value:"?:\*\Microsoft.SQLServer.*.Express.*.exe" field:"process.parent.executable" value:"?:\*\SQL*-SSEI-Expr.exe"
process.parent.code_signature.subject_nameinQSR International Pty Ltd, UiPath, Inc.excludes:process.parent.code_signature.subject_name field:"process.parent.code_signature.subject_name" value:"QSR International Pty Ltd" field:"process.parent.code_signature.subject_name" value:"UiPath, Inc."
process.parent.executablewildcard?:\ProgramData\*.exe, ?:\Program Files\*.exe, ?:\Program Files (x86)\*.exe, ?:\Windows\LTSvc\LTSVC.exe, ?:\Windows\System32\msiexec.exe, C:\Windows\_ScriptingFramework\Modul\Engine.exe, C:\Windows\_ScriptingFramework\Modul\ScriptingFrameworkEngine.exe, C:\Windows\SysWOW64\SmartDeploy\ClientService.exe, I:\RSA\Microsoft Azure Recovery Services Agent\bin\cbengine.exe, C:\Drivers\Nord\NordSec ThreatProtection\nordsec-threatprotection-service.exeexcludes:process.parent.executable
process.parent.thread.Ext.call_stackarray_any(no value, null check)excludes:process.parent.thread.Ext.call_stack
process.parent.executablewildcard?:\Packages\Plugins\Microsoft.GuestConfiguration.ConfigurationforWindows\*\gc_service.exe, ?:\Windows\System32\wsmprovhost.exe, ?:\Program Files (x86)\Wondershare\*.exe, ?:\Windows\System32\drivers\*.exe, ?:\Program Files*\Cloudflare\*.exe, ?:\Program Files (x86)\Universal\Universal.Server.exe, ?:\Program Files*\Listary\Listary.exe, ?:\Program Files*\ExpressConnect\ECDBWMService.exe, ?:\ProVation\Utilities\ProVation.DataExport\ProVation.DataExport.exe, ?:\Windows\System32\WindowsPowerShell\*\powershell_ise.exe, ?:\WINDOWS\_ScriptingFramework\Modul\Engine.exe, ?:\Program Files\Citrix\Telemetry Service\TelemetryService.exe, ?:\ProVation\Utilities\Database Utilities\ProVation.DataExport.exe, ?:\Program Files*\UiPath\Studio\UiPath.Studio.Project.exe, ?:\Program Files*\Microsoft System Center\Operations Manager\Server\MonitoringHost.exe, ?:\Program Files (x86)\Canfield Scientific Inc\PortalService\CanfieldRegister.exe, ?:\Program Files*\Microsoft System Center\Operations Manager\Server\MonitoringHost.exe, ?:\Drivers\MITS_FATClient_SupportTool\MITS_FATClient_SupportTool_admin.exe, ?:\Program Files*\Microsoft Visual Studio\*\Community\Common?\IDE\devenv.exe, ?:\Program Files\ObserveIT\WebsiteCat\WebsiteCat.Manager.exe, ?:\Program Files\Microsoft Azure Active Directory Connect\AzureADConnect.exe, ?:\Program Files (x86)\vMix\vMix64.exe, ?:\Work\HP DIAG TOOL\ImageDiags.exe, C:\Work\ImageDiags.exe, ?:\Program Files (x86)\Driver Support One\DSOneWeb.exe, ?:\Program Files (x86)\Team Shinkansen\Hakchi2 CE\hakchi.exe, ?:\Program Files (x86)\HP DIAG TOOL\ImageDiags.exe, ?:\ProVation\Utilities\Database Utilities\ProVation.DataExport19c\ProVation.DataExport.exe, ?:\Program Files\WindowsApps\*\DCv2\DCv2.exe, ?:\Users\*\Desktop\HP DIAG TOOL\ImageDiags.exe, ?:\ProVation\Utilities\Database Utilities\ProVation.DataExport*\ProVation.DataExport.exe, \Device\Mup\*\Release\CorrespondanceDownload.vshost.exe, ?:\Users\*\AppData\Local\Programs\UiPath\Studio\UiPath.Studio.Project.exe, D:\*\Exporter\bin\Debug\Exporter.vshost.exe, C:\Windows\SysWOW64\SmartDeploy\ClientService.exe, C:\Program Files\QSR\NVivo ??\NVivo.exe, C:\Program Files\McCormick Systems\McCormick Estimating\MaintenanceUtility.exe, D:\PROGRAMS\UiPath\Studio\UiPath.Studio.Project.exe, C:\Users\*\AppData\Roaming\GWP\MSOffice-AddIns\Deploy-MSOfficeAddIns.exe, C:\Program Files\Devolutions\Remote Desktop Manager\RemoteDesktopManager.exe, C:\Program Files\QSR\NVivo 14\NVivo.exe, C:\Program Files (x86)\Genetec SV Control Panel\Control Panel\SVControlPanel.exe, D:\PROGRAMS\UiPath\Studio\UiPath.Studio.Project.exe, C:\Program Files (x86)\Chocolatey GUI\ChocolateyGui.exe, C:\Program Files\Royal TS V7\RoyalTS.exe, C:\Program Files\QSR\NVivo ??\NVivo.exe, C:\Program Files\Password Safe and Repository*\PSRServer.exe, C:\Program Files\WindowsApps\Microsoft.GetHelp_*\GetHelp.exe, C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_*\DotNet\ConfigurationRemotingServer.exe, C:\Program Files (x86)\CentraStage\CagService.exe, D:\Microsoft Azure\Microsoft Azure Recovery Services Agent\bin\cbengine.exe, C:\Program Files (x86)\BMW\ISPI\ISVM\IMIBNext\Ediabas\bin\EbasServer.exe, C:\Program Files\ASUS\ASUS VeriView\ASUSEventClient.exe, C:\Program Files (x86)\Kovai Ltd\BizTalk360\Service\BHMCollect.exe, C:\Program Files\Common Files\eClinicalWorks\plugin\WinProjectE.exe, C:\Program Files (x86)\BizTalkHealthMonitor\BHMCollect.exe, ?:\Program Files (x86)\Welch Allyn\Connex\Server\*\DataBaseInstaller\DatabaseInstaller.exeexcludes:process.parent.executable

Windows Firewall Disabled via PowerShell

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

Identifies when the Windows Firewall is disabled using PowerShell cmdlets, which can help attackers evade network constraints, like internet and network lateral communication restrictions.

Known False Positives

  • Windows Firewall can be disabled by a system administrator. Verify whether the user identity, user agent, and/or hostname should be making changes in your environment. Windows Profile being disabled by unfamiliar users should be investigated. If known behavior is causing false positives, it can be exempted from the rule.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2021/10/15"
integration = ["endpoint", "windows", "system", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/05/04"

[rule]
author = ["Austin Songer"]
description = """
Identifies when the Windows Firewall is disabled using PowerShell cmdlets, which can help attackers evade network
constraints, like internet and network lateral communication restrictions.
"""
false_positives = [
    """
    Windows Firewall can be disabled by a system administrator. Verify whether the user identity, user agent, and/or
    hostname should be making changes in your environment. Windows Profile being disabled by unfamiliar users should be
    investigated. If known behavior is causing false positives, it can be exempted from the rule.
    """,
]
from = "now-9m"
index = [
    "endgame-*",
    "logs-crowdstrike.fdr*",
    "logs-endpoint.events.process-*",
    "logs-m365_defender.event-*",
    "logs-sentinel_one_cloud_funnel.*",
    "logs-system.security*",
    "logs-windows.forwarded*",
    "logs-windows.sysmon_operational-*",
    "winlogbeat-*",
]
language = "eql"
license = "Elastic License v2"
name = "Windows Firewall Disabled via PowerShell"
note = """## Triage and analysis

### Investigating Windows Firewall Disabled via PowerShell

Windows Defender Firewall is a native component that provides host-based, two-way network traffic filtering for a device and blocks unauthorized network traffic flowing into or out of the local device.

Attackers can disable the Windows firewall or its rules to enable lateral movement and command and control activity.

This rule identifies patterns related to disabling the Windows firewall or its rules using the `Set-NetFirewallProfile` PowerShell cmdlet.

#### Possible investigation steps

- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.
- Identify the user account that performed the action and whether it should perform this kind of action.
- Contact the account owner and confirm whether they are aware of this activity.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Inspect the host for suspicious or abnormal behavior in the alert timeframe.

### False positive analysis

- This mechanism can be used legitimately. Check whether the user is an administrator and is legitimately performing troubleshooting.
- In case of an allowed benign true positive (B-TP), assess adding rules to allow needed traffic and re-enable the firewall.

### Response and remediation

- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved hosts to prevent further post-compromise behavior.
- Re-enable the firewall with its desired configurations.
- 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.
- Review the privileges assigned to the involved users to ensure that the least privilege principle is being followed.
- 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 Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
- [Windows Process Creation Logs](https://ela.st/audit-process-creation)
"""

references = [
    "https://docs.microsoft.com/en-us/powershell/module/netsecurity/set-netfirewallprofile?view=windowsserver2019-ps",
    "https://www.tutorialspoint.com/how-to-get-windows-firewall-profile-settings-using-powershell",
    "http://powershellhelp.space/commands/set-netfirewallrule-psv5.php",
    "http://woshub.com/manage-windows-firewall-powershell/",
]
risk_score = 47
rule_id = "f63c8e3c-d396-404f-b2ea-0379d3942d73"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Defense Evasion",
    "Tactic: Execution",
    "Resources: Investigation Guide",
    "Data Source: Elastic Endgame",
    "Data Source: Elastic Defend",
    "Data Source: Windows Security Event Logs",
    "Data Source: Microsoft Defender XDR",
    "Data Source: Sysmon",
    "Data Source: SentinelOne",
    "Data Source: Crowdstrike",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
process where host.os.type == "windows" and event.type == "start" and
  (
    process.name : ("powershell.exe", "pwsh.exe", "powershell_ise.exe") or
    ?process.pe.original_file_name in ("PowerShell.EXE", "pwsh.dll", "powershell_ise.EXE")
  ) and
  process.args : "*Set-NetFirewallProfile*" and
  process.args : "*-Enabled*" and process.args : "*False*" and
  process.args : ("*-All*", "*Public*", "*Domain*", "*Private*")
'''


[[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.004"
name = "Disable or Modify System Firewall"
reference = "https://attack.mitre.org/techniques/T1562/004/"



[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"



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

Stages and Predicates

Stage 1: process

process where host.os.type == "windows" and event.type == "start" and
  (
    process.name : ("powershell.exe", "pwsh.exe", "powershell_ise.exe") or
    ?process.pe.original_file_name in ("PowerShell.EXE", "pwsh.dll", "powershell_ise.EXE")
  ) and
  process.args : "*Set-NetFirewallProfile*" and
  process.args : "*-Enabled*" and process.args : "*False*" and
  process.args : ("*-All*", "*Public*", "*Domain*", "*Private*")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.argswildcard
  • *-All*
  • *-Enabled*
  • *Domain*
  • *False*
  • *Private*
  • *Public*
  • *Set-NetFirewallProfile*
field:"process.args" kind:wildcard
process.namewildcard
  • powershell.exe corpus 187 (elastic 140, splunk 44, kusto 3)
  • powershell_ise.exe corpus 53 (splunk 29, elastic 24)
  • pwsh.exe corpus 78 (elastic 49, splunk 29)
field:"process_basename" kind:wildcard
process.pe.original_file_namein
  • PowerShell.EXE corpus 19 (elastic 19)
  • powershell_ise.EXE corpus 8 (elastic 8)
  • pwsh.dll corpus 8 (elastic 8)
field:"OriginalFileName" kind:in

Windows Registry File Creation in SMB Share

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

Identifies the creation or modification of a medium-size registry hive file on a Server Message Block (SMB) share, which may indicate an exfiltration attempt of a previously dumped Security Account Manager (SAM) registry hive for credential extraction on an attacker-controlled system.

MITRE ATT&CK Coverage

Telemetry Coverage

ProviderRecord / event type
SysmonEvent ID 11: FileCreate

Rule Body

[metadata]
creation_date = "2022/02/16"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/05/04"

[rule]
author = ["Elastic"]
description = """
Identifies the creation or modification of a medium-size registry hive file on a Server Message Block (SMB) share, which
may indicate an exfiltration attempt of a previously dumped Security Account Manager (SAM) registry hive for credential
extraction on an attacker-controlled system.
"""
from = "now-9m"
index = ["logs-endpoint.events.file-*"]
language = "eql"
license = "Elastic License v2"
name = "Windows Registry File Creation in SMB Share"
note = """## Triage and analysis

### Investigating Windows Registry File Creation in SMB Share

Dumping registry hives is a common way to access credential information. Some hives store credential material, as is the case for the SAM hive, which stores locally cached credentials (SAM secrets), and the SECURITY hive, which stores domain cached credentials (LSA secrets). Dumping these hives in combination with the SYSTEM hive enables the attacker to decrypt these secrets.

Attackers can try to evade detection on the host by transferring this data to a system that is not monitored to be parsed and decrypted. This rule identifies the creation or modification of a medium-size registry hive file on an SMB share, which may indicate this kind of exfiltration attempt.

#### Possible investigation steps

- Investigate other alerts associated with the user/source host during the past 48 hours.
- Identify the user account that performed the action and whether it should perform this kind of action.
- Contact the account owner and confirm whether they are aware of this activity.
- Inspect the source host for suspicious or abnormal behaviors in the alert timeframe.
- Capture the registry file(s) to determine the extent of the credential compromise in an eventual incident response.

### False positive analysis

- Administrators can export registry hives for backup purposes. Check whether the user should be performing this kind of activity and is aware of it.

### Related rules

- Credential Acquisition via Registry Hive Dumping - a7e7bfa3-088e-4f13-b29e-3986e0e756b8

### Response and remediation

- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved hosts to prevent further post-compromise behavior.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Reimage the host operating system and restore compromised files to clean versions.
- 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).
"""

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
"""

references = ["https://www.elastic.co/security-labs/detect-credential-access"]
risk_score = 47
rule_id = "a4c7473a-5cb4-4bc1-9d06-e4a75adbc494"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Lateral Movement",
    "Tactic: Credential Access",
    "Resources: Investigation Guide",
    "Data Source: Elastic Defend",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
file where host.os.type == "windows" and event.type == "creation" and
 /* regf file header */
 file.Ext.header_bytes : "72656766*" and file.size >= 30000 and
 process.pid == 4 and user.id : ("S-1-5-21*", "S-1-12-1-*") and
 not file.path : (
    "?:\\*\\UPM_Profile\\NTUSER.DAT",
    "?:\\*\\UPM_Profile\\NTUSER.DAT.LASTGOODLOAD",
    "?:\\*\\UPM_Profile\\AppData\\Local\\Microsoft\\Windows\\UsrClass.dat*",
    "?:\\Windows\\Netwrix\\Temp\\????????.???.offreg",
    "?:\\*\\AppData\\Local\\Packages\\Microsoft.*\\Settings\\settings.dat*"
 )
'''


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

[[rule.threat.technique]]
id = "T1003"
name = "OS Credential Dumping"
reference = "https://attack.mitre.org/techniques/T1003/"

[[rule.threat.technique.subtechnique]]
id = "T1003.002"
name = "Security Account Manager"
reference = "https://attack.mitre.org/techniques/T1003/002/"

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

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

[[rule.threat.technique]]
id = "T1021"
name = "Remote Services"
reference = "https://attack.mitre.org/techniques/T1021/"

[[rule.threat.technique.subtechnique]]
id = "T1021.002"
name = "SMB/Windows Admin Shares"
reference = "https://attack.mitre.org/techniques/T1021/002/"

[rule.threat.tactic]
id = "TA0008"
name = "Lateral Movement"
reference = "https://attack.mitre.org/tactics/TA0008/"

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

[[rule.threat.technique]]
id = "T1048"
name = "Exfiltration Over Alternative Protocol"
reference = "https://attack.mitre.org/techniques/T1048/"

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

Stages and Predicates

Stage 1: file

file where host.os.type == "windows" and event.type == "creation" and
 file.Ext.header_bytes : "72656766*" and file.size >= 30000 and
 process.pid == 4 and user.id : ("S-1-5-21*", "S-1-12-1-*") and
 not file.path : (
    "?:\\*\\UPM_Profile\\NTUSER.DAT",
    "?:\\*\\UPM_Profile\\NTUSER.DAT.LASTGOODLOAD",
    "?:\\*\\UPM_Profile\\AppData\\Local\\Microsoft\\Windows\\UsrClass.dat*",
    "?:\\Windows\\Netwrix\\Temp\\????????.???.offreg",
    "?:\\*\\AppData\\Local\\Packages\\Microsoft.*\\Settings\\settings.dat*"
 )

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.typeeq
  • creation corpus 48 (elastic 48)
field:"event.type" kind:eq value:"creation"
file.Ext.header_byteswildcard
  • 72656766* corpus 2 (elastic 2)
field:"file.Ext.header_bytes" kind:wildcard value:"72656766*"
file.sizege
  • 30000 transforms: number corpus 5 (elastic 5)
field:"file.size" kind:ge value:"30000"
process.pideq
  • 4 transforms: number corpus 17 (elastic 17)
field:"process_id" kind:eq value:"4"
user.idwildcard
  • S-1-12-1-* corpus 6 (elastic 6)
  • S-1-5-21* corpus 26 (elastic 26)
field:"user.id" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
file.pathwildcard?:\*\UPM_Profile\NTUSER.DAT, ?:\*\UPM_Profile\NTUSER.DAT.LASTGOODLOAD, ?:\*\UPM_Profile\AppData\Local\Microsoft\Windows\UsrClass.dat*, ?:\Windows\Netwrix\Temp\????????.???.offreg, ?:\*\AppData\Local\Packages\Microsoft.*\Settings\settings.dat*excludes:file.path

Back to all Elastic rules