Home/Detection rules

Deployable detection rules

1,678 vendor-native detections · ready to paste into your SIEM · cross-linked to ATT&CK

Detections

50 shown of 1,678
Elastic EQL high T1574, T1574.006 ↗
Dynamic Linker Modification Detected via Defend for Containers
This rule detects the creation or modification of the dynamic linker preload shared object (ld.so.preload) inside a container. The Linux dynamic linker is used to load libraries needed by a program at runtime. Adversaries may hijack the dynamic linker by modifying the /etc/ld.so.preload file to point to malicious libraries. This behavior can be used to grant unauthorized access to system resources and has been used to evade detection of malicious processes in container environments.
Show query
file where host.os.type == "linux" and event.type != "deletion" and
file.path like ("/etc/ld.so.preload", "/etc/ld.so.conf.d/*", "/etc/ld.so.conf") and
process.interactive == true and container.id like "*" 
Elastic KQL high T1098, T1098.006 ↗
EKS Authentication Configuration Modified
Detects modifications to the aws-auth ConfigMap in Amazon EKS clusters. The aws-auth ConfigMap maps AWS IAM roles and users to Kubernetes RBAC groups, an attacker who modifies it can grant any IAM role cluster-admin access by adding a mapping to the system:masters group. This is a well-documented persistence technique that survives pod restarts, node replacements, and RBAC changes because the authentication mapping exists outside of normal Kubernetes Role objects. Modifications to aws-auth are rare in normal operations, the ConfigMap is typically set during cluster provisioning and updated only during node group or access configuration changes.
Show query
data_stream.dataset:"kubernetes.audit_logs" and
kubernetes.audit.objectRef.resource:"configmaps" and 
kubernetes.audit.objectRef.name:"aws-auth" and 
kubernetes.audit.verb:("update" or "patch" or "delete") and 
kubernetes.audit.objectRef.namespace:"kube-system" and 
kubernetes.audit.annotations.authorization_k8s_io/decision:"allow" and
not user.name:"eks:kms-storage-migrator"
Elastic Defend Alert Followed by Telemetry Loss
Detects when an Elastic Defend endpoint alert is generated on a host and is not followed by any subsequent endpoint telemetry (process, network, registry, library, or DNS events) within a short time window. This behavior may indicate endpoint security evasion, agent tampering, sensor disablement, service termination, system crash, or malicious interference with telemetry collection following detection.
Show query
sequence by host.id with maxspan=5m
 [any where data_stream.dataset == "endpoint.alerts"]
 ![any where event.category in ("process", "library", "registry", "network", "dns", "file")]
Elastic ESQL high
Elastic Defend and Email Alerts Correlation
This rule correlates any Elastic Defend alert with an email security related alert by target user name. This may indicate the successful execution of a phishing attack.
Show query
from logs-endpoint.alerts-*, logs-checkpoint_email.event-* metadata _id
// Email or Elastic Defend alerts where user name is populated
| where
  (event.category == "email" and event.kind == "alert" and destination.user.name is not null) or
  (event.module == "endpoint" and data_stream.dataset == "endpoint.alerts" and user.name is not null)

// extract target user name from email and endpoint alerts
| eval email_alert_target_user_name = CASE(event.category == "email", destination.user.name, null),
       elastic_defend_alert_user_name = CASE(event.module == "endpoint" and data_stream.dataset == "endpoint.alerts", user.name, null)
| eval Esql.target_user_name = COALESCE(email_alert_target_user_name, elastic_defend_alert_user_name)
| where Esql.target_user_name is not null

// group by Esql.target_user_name
| stats Esql.alerts_count = COUNT(*),
        Esql.event_module_distinct_count = COUNT_DISTINCT(event.module),
        Esql.event_module_values = VALUES(event.module),
        Esql.message_values = VALUES(message),
        Esql.event_action_values = VALUES(event.action),
        Esql.process_executable_values = VALUES(process.executable),
        Esql.host_id_values = VALUES(host.id),
        Esql.source_user_name = VALUES(source.user.name),
        Esql.rule_name_values = VALUES(rule.name)
        by Esql.target_user_name
// alert when same user is observed in an endpoint and email alert
| where Esql.event_module_distinct_count >= 2
| keep Esql.alerts_count, Esql.event_module_values, Esql.host_id_values, Esql.source_user_name, Esql.target_user_name, Esql.message_values, Esql.rule_name_values, Esql.event_action_values
Elastic ESQL high
Elastic Defend and Network Security Alerts Correlation
This rule correlate any Elastic Defend alert with a set of suspicious events from Network security devices like Palo Alto Networks (PANW) and Fortinet Fortigate by host.ip and source.ip. This may indicate that this host is compromised and triggering multi-datasource alerts.
Show query
FROM logs-* metadata _id
| WHERE
        // Elastic Defend Alerts
        (event.module == "endpoint" and data_stream.dataset == "endpoint.alerts") or

        // PANW suspicious events
        (data_stream.dataset == "panw.panos" and
         event.action in ("virus_detected", "wildfire_virus_detected", "c2_communication", "spyware_detected", "large_upload", "denied", "exploit_detected")) or

        // Fortigate suspicious events
        (data_stream.dataset == "fortinet_fortigate.log" and
         (event.action in ("outbreak-prevention", "infected", "blocked") or message like "backdoor*" or message like "Proxy*" or message like "anomaly*" or message like "P2P*" or message like "misc*" or message like "DNS.Over.HTTPS" or message like "Remote.Access")) or

        // Suricata
        (data_stream.dataset == "suricata.eve" and message in ("Command and Control Traffic", "Potentially Bad Traffic", "A Network Trojan was detected", "Detection of a Network Scan", "Domain Observed Used for C2 Detected", "Malware Command and Control Activity Detected"))

// extract source.ip from PANW or Fortigate events and host.ip from Elastic Defend alert
|eval fw_alert_source_ip = CASE(data_stream.dataset in ("panw.panos", "fortinet_fortigate.log"), source.ip, null),
      elastic_defend_alert_host_ip = CASE(event.module == "endpoint" and data_stream.dataset == "endpoint.alerts", host.ip, null)
| eval Esql.source_ip = COALESCE(fw_alert_source_ip, elastic_defend_alert_host_ip)
| where Esql.source_ip is not null

// group by host_source_ip shared between FG/PANW and Elastic Defend
| stats Esql.alerts_count = COUNT(*),
        Esql.event_module_distinct_count = COUNT_DISTINCT(event.module),
        Esql.message_values_distinct_count = COUNT_DISTINCT(message),
        Esql.event_module_values = VALUES(event.module),
        Esql.message_values = VALUES(message),
        Esql.event_action_values = VALUES(event.action),
        Esql.process_executable_values = VALUES(process.executable),
        Esql.process_hash_sha256_values = VALUES(process.hash.sha256),
        Esql.process_cmdline_values = VALUES(process.command_line),
        Esql.file_path_values = VALUES(file.path),
        Esql.file_hash_sha256_values = VALUES(file.hash.sha256),
        Esql.host_id_values = VALUES(host.id),
        Esql.user_name_values = VALUES(user.name),
        Esql.destination_ip_values = VALUES(destination.ip)
        by Esql.source_ip
| where Esql.event_module_distinct_count >= 2 AND Esql.message_values_distinct_count >= 2
| eval concat_module_values = MV_CONCAT(Esql.event_module_values, ",")
// Make sure an endpoint alert is present along one of the network ones
| where concat_module_values like "*endpoint*"

// Move single values to their corresponding ECS fields for alerts exclusion
| eval source.ip = mv_min(Esql.source_ip),
       host.id = mv_min(Esql.host_id_values),
       user.name = mv_min(Esql.user_name_values)

| keep source.ip, host.id, user.name, Esql.*
Entra ID Concurrent Sign-in with Suspicious Properties
Identifies concurrent azure signin events for the same user and from multiple sources, and where one of the authentication event has some suspicious properties often associated to DeviceCode and OAuth phishing. Adversaries may steal Refresh Tokens (RTs) via phishing to bypass multi-factor authentication (MFA) and gain unauthorized access to Azure resources.
Show query
from logs-azure.signinlogs-* metadata _id, _version, _index

// Scheduled to run every hour, reviewing events from past hour
| where
  @timestamp > now() - 1 hours
  and data_stream.dataset == "azure.signinlogs"
  and source.ip is not null
  and azure.signinlogs.identity is not null
  and to_lower(event.outcome) == "success"

// keep relevant raw fields
| keep
  @timestamp,
  azure.signinlogs.identity,
  source.ip,
  azure.signinlogs.properties.authentication_requirement,
  azure.signinlogs.properties.app_id,
  azure.signinlogs.properties.resource_display_name,
  azure.signinlogs.properties.authentication_protocol,
  azure.signinlogs.properties.app_display_name

// case classifications for identity usage
| eval
      Esql.azure_signinlogs_properties_authentication_device_code_case = case(
      azure.signinlogs.properties.authentication_protocol == "deviceCode"
      and azure.signinlogs.properties.authentication_requirement != "multiFactorAuthentication",
      azure.signinlogs.identity,
      null),

    Esql.azure_signinlogs_auth_visual_studio_case = case(
      azure.signinlogs.properties.app_id == "aebc6443-996d-45c2-90f0-388ff96faa56"
      and azure.signinlogs.properties.resource_display_name == "Microsoft Graph",
      azure.signinlogs.identity,
      null),

    Esql.azure_signinlogs_auth_other_case = case(
      azure.signinlogs.properties.authentication_protocol != "deviceCode"
      and azure.signinlogs.properties.app_id != "aebc6443-996d-45c2-90f0-388ff96faa56",
      azure.signinlogs.identity,
      null)

// Aggregate metrics by user identity
| stats
    Esql.event_count = count(*),
    Esql.azure_signinlogs_properties_authentication_device_code_case_count_distinct = count_distinct(Esql.azure_signinlogs_properties_authentication_device_code_case),
    Esql.azure_signinlogs_properties_auth_visual_studio_count_distinct = count_distinct(Esql.azure_signinlogs_auth_visual_studio_case),
    Esql.azure_signinlogs_properties_auth_other_count_distinct = count_distinct(Esql.azure_signinlogs_auth_other_case),
    Esql.azure_signinlogs_properties_source_ip_count_distinct = count_distinct(source.ip),
    Esql.azure_signinlogs_properties_source_ip_values = values(source.ip),
    Esql.azure_signinlogs_properties_client_app_values = values(azure.signinlogs.properties.app_display_name),
    Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name),
    Esql.azure_signinlogs_properties_auth_requirement_values = values(azure.signinlogs.properties.authentication_requirement)
  by azure.signinlogs.identity

// Detect multiple unique IPs for one user with signs of deviceCode or VSC OAuth usage
| where
  Esql.azure_signinlogs_properties_source_ip_count_distinct >= 2
  and (
    Esql.azure_signinlogs_properties_authentication_device_code_case_count_distinct > 0
    or Esql.azure_signinlogs_properties_auth_visual_studio_count_distinct > 0
  )
Entra ID Domain Federation Configuration Change
Detects when domain federation settings are configured or modified in an Entra ID tenant via the Microsoft Graph API. Adversaries with Global Administrator or Domain Administrator privileges may add a custom domain, verify ownership, and configure it to federate authentication with an attacker-controlled identity provider. Once federated, the adversary can forge SAML or WS-Federation tokens to authenticate as any user under that domain, bypassing MFA and conditional access policies. This technique, commonly known as Golden SAML, was used by UNC2452 (APT29) during the SolarWinds campaign for persistent, stealthy access to victim tenants.
Show query
data_stream.dataset: azure.auditlogs
    and azure.auditlogs.properties.category: DirectoryManagement
    and event.action: ("Set domain authentication" or "Set federation settings on domain")
    and event.outcome: success
Elastic KQL high T1098, T1098.003 ↗
Entra ID Elevated Access to User Access Administrator
Identifies when a user has elevated their access to User Access Administrator for their Azure Resources. The User Access Administrator role allows users to manage user access to Azure resources, including the ability to assign roles and permissions. Adversaries may target an Entra ID Global Administrator or other privileged role to elevate their access to User Access Administrator, which can lead to further privilege escalation and unauthorized access to sensitive resources. This is a New Terms rule that only signals if the user principal name has not been seen doing this activity in the last 14 days.
Show query
data_stream.dataset: azure.auditlogs
    and (
      azure.auditlogs.operation_name: "User has elevated their access to User Access Administrator for their Azure Resources" or
      azure.auditlogs.properties.additional_details.value: "Microsoft.Authorization/elevateAccess/action"
    ) and event.outcome: "success"
Entra ID Excessive Account Lockouts Detected
Identifies a high count of failed Microsoft Entra ID sign-in attempts as the result of the target user account being locked out. Adversaries may attempt to brute-force user accounts by repeatedly trying to authenticate with incorrect credentials, leading to account lockouts by Entra ID Smart Lockout policies.
Show query
data_stream.dataset: "azure.signinlogs" and event.category: "authentication"
    and azure.signinlogs.category: ("NonInteractiveUserSignInLogs" or "SignInLogs")
    and event.outcome: "failure"
    and azure.signinlogs.properties.authentication_requirement: "singleFactorAuthentication"
    and azure.signinlogs.properties.status.error_code: 50053
    and azure.signinlogs.properties.user_principal_name: (* and not "")
    and not source.as.organization.name: "MICROSOFT-CORP-MSN-as-BLOCK"
    and not source.ip: ("10.0.0.0/8" or "172.16.0.0/12" or "192.168.0.0/16" or "127.0.0.0/8" or "::1/128" or "fd00::/8")
Entra ID Federated Identity Credential Issuer Modified
Detects when the issuer URL of a federated identity credential is changed on an Entra ID application. Adversaries may modify the issuer to point to an attacker-controlled identity provider, enabling them to authenticate as the application's service principal and gain persistent access to Azure resources. This technique allows bypassing traditional authentication controls by federating trust with a malicious external identity provider.
Show query
from logs-azure.auditlogs-* metadata _id, _version, _index
| where event.action == "Update application"
| where `azure.auditlogs.properties.target_resources.0.modified_properties.0.display_name` == "FederatedIdentityCredentials"
| eval Esql.target_resources_old_value_clean = replace(`azure.auditlogs.properties.target_resources.0.modified_properties.0.old_value`, "\\\\", "")
| eval Esql.target_resources_new_value_clean = replace(`azure.auditlogs.properties.target_resources.0.modified_properties.0.new_value`, "\\\\", "")
| dissect Esql.target_resources_old_value_clean "%{}\"Issuer\":\"%{Esql.external_idp_old_issuer}\"%{}"
| dissect Esql.target_resources_new_value_clean "%{}\"Issuer\":\"%{Esql.external_idp_new_issuer}\"%{}"
| where Esql.external_idp_old_issuer is not null and Esql.external_idp_new_issuer is not null
| where Esql.external_idp_old_issuer != Esql.external_idp_new_issuer
| keep @timestamp, Esql.*, azure.*, event.*, cloud.*, related.*, tags, source.*, agent.*, client.*, _id, _version, _index, data_stream.namespace
Elastic KQL high T1098, T1098.003 ↗
Entra ID Global Administrator Role Assigned
In Microsoft Entra ID, permissions to manage resources are assigned using roles. The Global Administrator is a role that enables users to have access to all administrative features in Microsoft Entra ID and services that use Microsoft Entra ID identities like the Microsoft 365 Defender portal, the Microsoft 365 compliance center, Exchange, SharePoint Online, and Skype for Business Online. Attackers can add users as Global Administrators to maintain access and manage all subscriptions and their settings and resources. They can also elevate privilege to User Access Administrator to pivot into Azure resources.
Show query
data_stream.dataset:azure.auditlogs and
    azure.auditlogs.properties.category:RoleManagement and
    azure.auditlogs.operation_name:"Add member to role" and
    azure.auditlogs.properties.target_resources.*.modified_properties.*.new_value: "\"Global Administrator\"""
Elastic KQL high T1078, T1078.004 ↗
Entra ID High Risk Sign-in
Identifies high risk Microsoft Entra ID sign-ins by leveraging Microsoft's Identity Protection machine learning and heuristics. Identity Protection categorizes risk into three tiers: low, medium, and high. While Microsoft does not provide specific details about how risk is calculated, each level brings higher confidence that the user or sign-in is compromised.
Show query
data_stream.dataset:azure.signinlogs and
  (
    azure.signinlogs.properties.risk_level_during_signin:high or
    azure.signinlogs.properties.risk_level_aggregated:high
  )
Entra ID Kali365 Default User-Agent Detected
Identifies the default user agent string associated with Kali365 (also referred to as Kali365 Live), a phishing-as-a-service (PhaaS) platform that automates OAuth 2.0 device code phishing and adversary-in-the-middle (AiTM) session capture against Microsoft 365 and Microsoft Entra ID. The Kali365 Electron desktop client identifies itself with the user agent `kali365-live/1.0.0` when polling for and replaying captured OAuth tokens, so its appearance in Entra ID sign-in logs, Entra ID audit logs, or the Microsoft 365 unified audit log indicates that an attacker-controlled Kali365 client is interacting with the tenant using stolen tokens. Unlike dual-use offensive tooling, Kali365 is a criminal service with no legitimate enterprise use, making this user agent a high-fidelity indicator of active account compromise.
Show query
data_stream.dataset : ("azure.signinlogs" or "azure.auditlogs" or "o365.audit") and user_agent.original: kali365-live/*
Entra ID Microsoft Authentication Broker DRS Sign-In from Suspicious ASN
Detects Microsoft Entra ID sign-in activity where the Microsoft Authentication Broker requests the Device Registration Service from a source autonomous system number (ASN) associated with VPN, residential proxy, or hosting egress commonly observed in OAuth phishing and adversary-in-the-middle device registration flows. This pattern can indicate device join or primary refresh token acquisition staged from attacker-controlled infrastructure after a user completes authentication.
Show query
data_stream.dataset:"azure.signinlogs" and event.action:"Sign-in activity" and
source.as.number:(
    399629 or 14061 or 136787 or 9009 or 45102 or 215540 or 29802 or 62240 or 204957 or 395092 or 393406 or 400940 or
    59711 or 132203
) and
azure.signinlogs.properties.app_display_name:"Microsoft Authentication Broker" and
azure.signinlogs.properties.resource_display_name:"Device Registration Service"
Entra ID Microsoft Authentication Broker Sign-In with Non-Standard User Agent
Detects Microsoft Entra ID sign-in activity where the Microsoft Authentication Broker authenticates is using a user agent that is not consistent with common browser, mobile, or Windows platform authentication clients. Adversary-in-the-middle and OAuth phishing tooling often presents scripted or relayed user agents (for example Node.js, Python, or generic HTTP libraries) while still targeting first-party resources through the broker.
Show query
data_stream.dataset:"azure.signinlogs" and event.action:"Sign-in activity" and event.outcome:(success or Success) and
(azure.signinlogs.properties.app_display_name:"Microsoft Authentication Broker" or azure.signinlogs.properties.app_id:"29d9ed98-a469-4536-ade2-f981bc1d605e") and
user_agent.original:(* and not (Mozilla* or Dalvik* or *CFNetwork* or Windows-AzureAD-Authentication-Provider* or Java*ThinkPad*)) and
azure.signinlogs.properties.resource_display_name:*
Entra ID OAuth Device Code Flow with Concurrent Sign-ins
Identifies Entra ID device code authentication flows where multiple user agents are observed within the same session. This pattern is indicative of device code phishing, where an attacker's polling client (e.g., Python script) and the victim's browser both appear in the same authentication session. In legitimate device code flows, the user authenticates via browser while the requesting application polls for tokens - when these have distinctly different user agents (e.g., Python Requests vs Chrome), it may indicate the code was phished and redeemed by an attacker.
Show query
from logs-azure.signinlogs-* metadata _id, _version, _index

| where event.category == "authentication" and data_stream.dataset == "azure.signinlogs" and
        azure.signinlogs.properties.original_transfer_method == "deviceCodeFlow"

// Track events with deviceCode authentication protocol (browser auth) vs polling client
| eval is_device_code_auth = case(azure.signinlogs.properties.authentication_protocol == "deviceCode", 1, 0)

| stats Esql.count_logon = count(*),
        Esql.device_code_auth_count = sum(is_device_code_auth),
        Esql.timestamp_values = values(@timestamp),
        Esql.source_ip_count_distinct = count_distinct(source.ip),
        Esql.user_agent_count_distinct = count_distinct(user_agent.original),
        Esql.user_agent_values = values(user_agent.original),
        Esql.authentication_protocol_values = values(azure.signinlogs.properties.authentication_protocol),
        Esql.azure_signinlogs_properties_client_app_values = values(azure.signinlogs.properties.app_display_name),
        Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id),
        Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name),
        Esql.azure_signinlogs_properties_auth_requirement_values = values(azure.signinlogs.properties.authentication_requirement),
        Esql.azure_signinlogs_properties_tenant_id = values(azure.tenant_id),
        Esql.azure_signinlogs_properties_status_error_code_values = values(azure.signinlogs.properties.status.error_code),
        Esql.message_values = values(message),
        Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id),
        Esql.source_ip_values = values(source.ip)
        by azure.signinlogs.properties.session_id, azure.signinlogs.identity

// Require: 2+ events, at least one deviceCode auth protocol event, and either 2+ IPs or 2+ user agents
| where Esql.count_logon >= 2 and Esql.device_code_auth_count >= 1 and (Esql.source_ip_count_distinct >= 2 or Esql.user_agent_count_distinct >= 2)
| keep
       Esql.*,
       azure.signinlogs.properties.session_id,
       azure.signinlogs.identity
Entra ID OAuth Flow by Microsoft Authentication Broker to Device Registration Service (DRS)
Identifies separate OAuth authorization flows in Microsoft Entra ID where the same user principal and session ID are observed across multiple IP addresses within a 5-minute window. These flows involve the Microsoft Authentication Broker (MAB) as the client application and the Device Registration Service (DRS) as the target resource. This pattern is highly indicative of OAuth phishing activity, where an adversary crafts a legitimate Microsoft login URL to trick a user into completing authentication and sharing the resulting authorization code, which is then exchanged for an access and refresh token by the attacker.
Show query
from logs-azure.signinlogs-* metadata _id, _version, _index
| where
    data_stream.dataset == "azure.signinlogs" and
    event.outcome == "success" and
    azure.signinlogs.properties.user_type == "Member" and
    azure.signinlogs.identity is not null and
    azure.signinlogs.properties.user_principal_name is not null and
    source.address is not null and
    azure.signinlogs.properties.app_id == "29d9ed98-a469-4536-ade2-f981bc1d605e" and  // MAB
    azure.signinlogs.properties.resource_id == "01cb2876-7ebd-4aa4-9cc9-d28bd4d359a9"  // DRS

| eval
    Esql.time_window_date_trunc = date_trunc(30 minutes, @timestamp),
    Esql.azure_signinlogs_properties_session_id = azure.signinlogs.properties.session_id,
    Esql.is_browser_case = case(
        to_lower(azure.signinlogs.properties.device_detail.browser) rlike "(chrome|firefox|edge|safari).*", 1, 0
    )

| stats
    Esql_priv.azure_signinlogs_properties_user_display_name_values = values(azure.signinlogs.properties.user_display_name),
    Esql_priv.azure_signinlogs_properties_user_principal_name_values = values(azure.signinlogs.properties.user_principal_name),
    Esql.azure_signinlogs_properties_session_id_values = values(azure.signinlogs.properties.session_id),
    Esql.azure_signinlogs_properties_unique_token_identifier_values = values(azure.signinlogs.properties.unique_token_identifier),

    Esql.source_geo_city_name_values = values(source.geo.city_name),
    Esql.source_geo_country_name_values = values(source.geo.country_name),
    Esql.source_geo_region_name_values = values(source.geo.region_name),
    Esql.source_address_values = values(source.address),
    Esql.source_address_count_distinct = count_distinct(source.address),
    Esql.source_as_organization_name_values = values(source.`as`.organization.name),

    Esql.azure_signinlogs_properties_authentication_protocol_values = values(azure.signinlogs.properties.authentication_protocol),
    Esql.azure_signinlogs_properties_authentication_requirement_values = values(azure.signinlogs.properties.authentication_requirement),
    Esql.azure_signinlogs_properties_is_interactive_values = values(azure.signinlogs.properties.is_interactive),

    Esql.azure_signinlogs_properties_incoming_token_type_values = values(azure.signinlogs.properties.incoming_token_type),
    Esql.azure_signinlogs_properties_token_protection_status_details_sign_in_session_status_values = values(azure.signinlogs.properties.token_protection_status_details.sign_in_session_status),
    Esql.azure_signinlogs_properties_session_id_count_distinct = count_distinct(azure.signinlogs.properties.session_id),
    Esql.azure_signinlogs_properties_app_display_name_values = values(azure.signinlogs.properties.app_display_name),
    Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id),
    Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id),
    Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name),

    Esql.azure_signinlogs_properties_app_owner_tenant_id_values = values(azure.signinlogs.properties.app_owner_tenant_id),
    Esql.azure_signinlogs_properties_resource_owner_tenant_id_values = values(azure.signinlogs.properties.resource_owner_tenant_id),

    Esql.azure_signinlogs_properties_conditional_access_status_values = values(azure.signinlogs.properties.conditional_access_status),
    Esql.azure_signinlogs_properties_risk_state_values = values(azure.signinlogs.properties.risk_state),
    Esql.azure_signinlogs_properties_risk_level_aggregated_values = values(azure.signinlogs.properties.risk_level_aggregated),

    Esql.azure_signinlogs_properties_device_detail_browser_values = values(azure.signinlogs.properties.device_detail.browser),
    Esql.azure_signinlogs_properties_device_detail_operating_system_values = values(azure.signinlogs.properties.device_detail.operating_system),
    Esql.user_agent_original_values = values(user_agent.original),
    Esql.is_browser_case_max = max(Esql.is_browser_case),

    Esql.event_count = count(*)
  by
    Esql.time_window_date_trunc,
    azure.signinlogs.properties.user_principal_name,
    azure.signinlogs.properties.session_id

| keep
    Esql.time_window_date_trunc,
    Esql_priv.azure_signinlogs_properties_user_display_name_values,
    Esql_priv.azure_signinlogs_properties_user_principal_name_values,
    Esql.azure_signinlogs_properties_session_id_values,
    Esql.azure_signinlogs_properties_unique_token_identifier_values,
    Esql.source_geo_city_name_values,
    Esql.source_geo_country_name_values,
    Esql.source_geo_region_name_values,
    Esql.source_address_values,
    Esql.source_address_count_distinct,
    Esql.source_as_organization_name_values,
    Esql.azure_signinlogs_properties_authentication_protocol_values,
    Esql.azure_signinlogs_properties_authentication_requirement_values,
    Esql.azure_signinlogs_properties_is_interactive_values,
    Esql.azure_signinlogs_properties_incoming_token_type_values,
    Esql.azure_signinlogs_properties_token_protection_status_details_sign_in_session_status_values,
    Esql.azure_signinlogs_properties_session_id_count_distinct,
    Esql.azure_signinlogs_properties_app_display_name_values,
    Esql.azure_signinlogs_properties_app_id_values,
    Esql.azure_signinlogs_properties_resource_id_values,
    Esql.azure_signinlogs_properties_resource_display_name_values,
    Esql.azure_signinlogs_properties_app_owner_tenant_id_values,
    Esql.azure_signinlogs_properties_resource_owner_tenant_id_values,
    Esql.azure_signinlogs_properties_conditional_access_status_values,
    Esql.azure_signinlogs_properties_risk_state_values,
    Esql.azure_signinlogs_properties_risk_level_aggregated_values,
    Esql.azure_signinlogs_properties_device_detail_browser_values,
    Esql.azure_signinlogs_properties_device_detail_operating_system_values,
    Esql.user_agent_original_values,
    Esql.is_browser_case_max,
    Esql.event_count

| where
    Esql.source_address_count_distinct >= 2 and
    Esql.azure_signinlogs_properties_session_id_count_distinct == 1 and
    Esql.is_browser_case_max >= 1 and
    Esql.event_count >= 2
Elastic KQL high T1566, T1539 ↗
Entra ID Potential AiTM Sign-In via OfficeHome (Tycoon2FA)
Detects Microsoft Entra ID sign-ins consistent with Tycoon2FA phishing-as-a-service (PhaaS) adversary-in-the-middle (AiTM) activity: the Microsoft Authentication Broker requesting tokens for Microsoft Graph or Exchange Online, or the Office web client application authenticating to itself, combined with Node.js-style user agents (node, axios, undici). Tycoon 2FA bypasses MFA by relaying authentication and capturing session material, often targeting Microsoft 365 and Gmail. Baseline legitimate automation and developer tooling before tuning.
Show query
data_stream.dataset:"azure.signinlogs" and event.category:"authentication" and
event.action:"Sign-in activity" and
(
    (
        azure.signinlogs.properties.app_id:"29d9ed98-a469-4536-ade2-f981bc1d605e" and
        azure.signinlogs.properties.resource_id:(
            "00000002-0000-0ff1-ce00-000000000000" or "00000003-0000-0000-c000-000000000000"
        )
    ) or
    (
        azure.signinlogs.properties.app_id:"4765445b-32c6-49b0-83e6-1d93765276ca" and
        azure.signinlogs.properties.resource_id:"4765445b-32c6-49b0-83e6-1d93765276ca"
    )
) and user_agent.original:(node or axios* or undici)
Entra ID Protection - Risk Detection - Sign-in Risk
Identifies sign-in risk detection events via Microsofts Entra ID Protection service. Entra ID Protection detects sign-in activity such as anonymized IP addresses, unlikely travel, password spray, and more.
Show query
data_stream.dataset: "azure.identity_protection" and
    event.action: "User Risk Detection" and
    azure.identityprotection.properties.activity: "signin" and
    not azure.identityprotection.properties.risk_state: (
        "remediated" or "dismissed" or "confirmedSafe"
    )
Entra ID Protection - Risk Detection - User Risk
Identifies user risk detection events via Microsofts Entra ID Protection service. Entra ID Protection detects user risk activity such as anonymized IP addresses, unlikely travel, password spray, and more.
Show query
data_stream.dataset: "azure.identity_protection" and
    event.action: ("User Risk Detection" or "Risky user") and
    azure.identityprotection.properties.activity: "user" and
    not azure.identityprotection.properties.risk_state: (
        "remediated" or "dismissed" or "confirmedSafe"
    )
Elastic EQL high T1078, T1078.004 ↗
Entra ID Protection Alerts for User Detected
Identifies more than two Microsoft Entra ID Protection alerts associated to the user principal in a short time period. Microsoft Entra ID Protection alerts are triggered by suspicious sign-in activity, such as anomalous IP addresses, risky sign-ins, or other risk detections. Multiple alerts in a short time frame may indicate an ongoing attack or compromised account.
Show query
sequence by azure.identityprotection.properties.user_principal_name with maxspan=10m
[any where event.module == "azure" and data_stream.dataset == "azure.identity_protection"] with runs=2
Entra ID Protection User Alert and Device Registration
Identifies sequence of events where a Microsoft Entra ID protection alert is followed by an attempt to register a new device by the same user principal. This behavior may indicate an adversary using a compromised account to register a device, potentially leading to unauthorized access to resources or persistence in the environment.
Show query
sequence with maxspan=5m
[any where data_stream.dataset == "azure.identity_protection"] by azure.identityprotection.properties.user_principal_name
[any where data_stream.dataset == "azure.auditlogs" and event.action == "Register device"] by azure.auditlogs.properties.initiated_by.user.userPrincipalName
Elastic KQL high T1486 ↗
Excessive AWS S3 Object Encryption with SSE-C
Identifies a high-volume of AWS S3 objects stored in a bucket using using Server-Side Encryption with Customer-Provided Keys (SSE-C). Adversaries with compromised AWS credentials can encrypt objects in an S3 bucket using their own encryption keys, rendering the objects unreadable or recoverable without the key. This can be used as a form of ransomware to extort the bucket owner for the decryption key. This is a Threshold rule that triggers when this behavior is observed multiple times for a specific bucket in a short time-window.
Show query
data_stream.dataset: "aws.cloudtrail"
    and event.provider: "s3.amazonaws.com"
    and event.action: "PutObject"
    and event.outcome: "success"
    and aws.cloudtrail.flattened.request_parameters.x-amz-server-side-encryption-customer-algorithm: "AES256"
Executable Masquerading as Kernel Process
Monitors for kernel processes with associated process executable fields that are not empty. Unix kernel processes such as kthreadd and kworker typically do not have process.executable fields associated to them. Attackers may attempt to hide their malicious programs by masquerading as legitimate kernel processes.
Show query
process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "exec_event", "start", "ProcessRollup2") and
process.name : ("kworker*", "kthread*") and process.executable != null
Execution of File Written or Modified by Microsoft Office
Identifies an executable created by a Microsoft Office application and subsequently executed. These processes are often launched via scripts inside documents or during exploitation of Microsoft Office applications.
Show query
sequence with maxspan=2h
  [file where host.os.type == "windows" and event.type != "deletion" and file.extension : "exe" and
    process.name : (
      "WINWORD.EXE", "EXCEL.EXE", "OUTLOOK.EXE", "POWERPNT.EXE",
      "eqnedt32.exe", "fltldr.exe", "MSPUB.EXE", "MSACCESS.EXE"
    )
  ] by host.id, file.path
  [process where host.os.type == "windows" and event.type == "start" and 
   not (process.name : "NewOutlookInstaller.exe" and process.code_signature.subject_name : "Microsoft Corporation" and process.code_signature.trusted == true) and 
   not (process.name : "ShareFileForOutlook-v*.exe" and process.code_signature.subject_name : "Citrix Systems, Inc." and process.code_signature.trusted == true)
  ] by host.id, process.executable
Elastic EQL high T1021, T1021.001, T1570 ↗
Execution via TSClient Mountpoint
Identifies execution from the Remote Desktop Protocol (RDP) shared mountpoint tsclient on the target host. This may indicate a lateral movement attempt.
Show query
process where host.os.type == "windows" and event.type == "start" and process.executable : "\\Device\\Mup\\tsclient\\*.exe"
Elastic KQL high T1203, T1068 ↗
Exploit - Detected - Elastic Endgame
Elastic Endgame detected an Exploit. Click the Elastic Endgame icon in the event.module column or the link in the rule.reference column for additional information.
Show query
event.kind:alert and event.module:endgame and endgame.metadata.type:detection and (event.action:exploit_event or endgame.event_subtype_full:exploit_event)
File Creation, Execution and Self-Deletion in Suspicious Directory
This rule monitors for the creation of a file, followed by its execution and self-deletion in a short timespan within a directory often used for malicious purposes by threat actors. This behavior is often used by malware to execute malicious code and delete itself to hide its tracks.
Show query
sequence by host.id, user.id with maxspan=1m
  [file where host.os.type == "linux" and event.action == "creation" and
   process.name in ("curl", "wget", "fetch", "ftp", "sftp", "scp", "rsync", "ld") and
   file.path : ("/dev/shm/*", "/run/shm/*", "/tmp/*", "/var/tmp/*",
     "/run/*", "/var/run/*", "/var/www/*", "/proc/*/fd/*")] by file.name
  [process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and
   process.parent.name in ("bash", "dash", "ash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and
   not process.parent.executable like (
     "/tmp/VeeamApp*", "/tmp/rajh/spack-stage/*", "plz-out/bin/vault/bridge/test/e2e/base/bridge-dev",
     "/usr/bin/ranlib", "/usr/bin/ar", "plz-out/bin/vault/bridge/test/e2e/base/local-k8s"
   )] by process.name
  [file where host.os.type == "linux" and event.action == "deletion" and
   file.path : (
     "/dev/shm/*", "/run/shm/*", "/tmp/*", "/var/tmp/*", "/run/*", "/var/run/*", "/var/www/*", "/proc/*/fd/*"
    ) and not process.name in ("rm", "ld", "conftest", "link", "gcc", "getarch", "ld")] by file.name
Elastic KQL high T1222, T1222.002 ↗
File Permission Modification in Writable Directory
Identifies file permission modifications in common writable directories by a non-root user. Adversaries often drop files or payloads into a writable directory and change permissions prior to execution.
Show query
host.os.type:"linux" and event.category:process and event.type:"start" and event.action:"exec" and
process.name:("chattr" or "chgrp" or "chmod") and process.working_directory:("/dev/shm" or "/tmp" or "/var/tmp") and
not (
  process.args:(
    "+r" or "640" or /tmp/apt-key-gpghome* or "/usr/bin/coreutils" or "/opt/eset/eei/uninstall.sh" or /tmp/era.repository.*.bin
  ) or
  process.parent.args:"/var/illumio_pce/illumio/scripts/consul" or
  process.parent.name:(
    apt-key or update-motd-updates-available or apt-get or java or pilot or PassengerAgent or nginx
  ) or
  process.parent.executable:(
    "/usr/local/bin/afb-ssh-setup-keys.sh" or "/usr/local/bin/afb-ssh-setup-keys.sh" or "/opt/puppetlabs/puppet/bin/ruby" or
    "/usr/sbin/update-exim4.conf" or "/bin/dracut"
  )
)
First Time Seen Account Performing DCSync
This rule identifies when a User Account starts the Active Directory Replication Process for the first time. Attackers can use the DCSync technique to get credential information of individual accounts or the entire domain, thus compromising the entire domain.
Show query
event.code:"4662" and host.os.type:"windows" and
  winlog.event_data.Properties:(
    *DS-Replication-Get-Changes* or *DS-Replication-Get-Changes-All* or
    *DS-Replication-Get-Changes-In-Filtered-Set* or *1131f6ad-9c07-11d1-f79f-00c04fc2dcd2* or
    *1131f6aa-9c07-11d1-f79f-00c04fc2dcd2* or *89e95b76-444d-4c62-991a-0facbeda640c*) and
  not winlog.event_data.SubjectUserName:(*$ or MSOL_*)
Elastic ESQL high T1078 ↗
First-Time FortiGate Administrator Login
This rule detects the first observed successful login of a user with the Administrator role to the FortiGate management interface within the last 5 days. First-time administrator logins can indicate newly provisioned accounts, misconfigurations, or unauthorized access using valid credentials and should be reviewed promptly.
Show query
FROM logs-fortinet_fortigate.*, filebeat-* metadata _id

| WHERE data_stream.dataset == "fortinet_fortigate.log" and
        event.category == "authentication" and event.action == "login" and
        event.outcome == "success" and source.user.roles == "Administrator" and source.user.name is not null
| stats Esql.logon_count = count(*),
       Esql.first_time_seen = MIN(@timestamp),
       Esql.source_ip_values = VALUES(source.ip),
       Esql.message_values = VALUES(message) by source.user.name, fortinet.firewall.profile

// first time seen is within 6m of the rule execution time and for the last 5d of events history
| eval Esql.recent = DATE_DIFF("minute", Esql.first_time_seen, now())
| where Esql.recent <= 6 and Esql.logon_count == 1

// move dynamic fields to ECS equivalent for rule exceptions
| eval source.ip = MV_FIRST(Esql.source_ip_values)

| keep source.ip,
       source.user.name,
       fortinet.firewall.profile,
       Esql.logon_count,
       Esql.first_time_seen,
       Esql.source_ip_values,
       Esql.message_values,
       Esql.recent
Elastic ESQL high T1078 ↗
FortiGate Administrator Login from Multiple IP Addresses
This rule detects successful logins to the FortiGate management interface using the same Administrator account from multiple distinct source IP addresses within an 24-hour period. Administrator logins from multiple locations in a short time window may indicate credential sharing, compromised credentials, or unauthorized access and should be investigated.
Show query
FROM logs-fortinet_fortigate.*, filebeat-* metadata _id

| WHERE data_stream.dataset == "fortinet_fortigate.log" and
        event.category == "authentication" and event.action == "login" and
        event.outcome == "success" and source.user.roles == "Administrator" and
        source.user.name is not null and source.ip is not null
| stats Esql.logon_count = count(*),
        Esql.source_ip_count_distinct = COUNT_DISTINCT(source.ip),
        Esql.max_timestamp = MAX(@timestamp),
        Esql.source_ip_values = VALUES(source.ip),
        Esql.message_values = VALUES(message),
        Esql.source_geo_country_name_values = VALUES(source.geo.country_name) by source.user.name

// last logon event timestamp is within 6m of the rule execution time to avoid duplicates
| eval Esql.recent = DATE_DIFF("minute", Esql.max_timestamp, now())
| where Esql.recent <= 6 and Esql.logon_count >= 2 and Esql.source_ip_count_distinct >= 2

// move dynamic fields to ECS equivalent for rule exceptions
| eval source.ip = MV_FIRST(Esql.source_ip_values)

| keep source.ip, source.user.name, Esql.*
Elastic EQL high T1562, T1562.004 ↗
FortiGate Overly Permissive Firewall Policy Created
This rule detects the creation or modification of a FortiGate firewall policy that permits all sources, all destinations, and all services. An overly permissive policy effectively bypasses all firewall protections. Threat actors exploiting CVE-2026-24858 have been observed creating such policies to allow unrestricted traffic flow through compromised FortiGate devices.
Show query
any where data_stream.dataset == "fortinet_fortigate.log" and
    event.code == "0100044547" and
    fortinet.firewall.cfgpath == "firewall.policy" and
    fortinet.firewall.action in ("Add", "Edit") and
    fortinet.firewall.cfgattr like~ "*srcaddr[all]*" and
    fortinet.firewall.cfgattr like~ "*dstaddr[all]*" and
    fortinet.firewall.cfgattr like~ "*service[all]*"
Elastic EQL high T1136, T1136.001, T1190 ↗
FortiGate SSO Login Followed by Administrator Account Creation
This rule detects a FortiCloud SSO login followed by administrator account creation on the same FortiGate device within 15 minutes. This sequence is a high-confidence indicator of the FG-IR-26-060 attack pattern, where threat actors authenticate via SAML-based SSO bypass and immediately create local administrator accounts for persistence.
Show query
sequence by observer.name with maxspan=15m
  [authentication where data_stream.dataset == "fortinet_fortigate.log" and
    event.action == "login" and event.outcome == "success" and
    (fortinet.firewall.method == "sso" or fortinet.firewall.ui like~ "sso*")]
  [any where data_stream.dataset == "fortinet_fortigate.log" and
    event.code == "0100044547" and
    fortinet.firewall.cfgpath == "system.admin" and
    fortinet.firewall.action == "Add"]
Elastic KQL high
Forwarded Google Workspace Security Alert
Identifies the occurrence of a security alert from the Google Workspace alerts center. Google Workspace's security alert center provides an overview of actionable alerts that may be affecting an organization's domain. An alert is a warning of a potential security issue that Google has detected.
Show query
data_stream.dataset: google_workspace.alert
Gatekeeper Override and Execution
Detects when macOS Gatekeeper is overridden followed by execution of the same binary from a suspicious location. This behavior indicates an attempt to bypass Apple's security controls and execute potentially malicious software downloaded from the internet.
Show query
configuration where host.os.type == "macos" and event.action == "gatekeeper_override" and
  file.path like ("/Volumes/*", "/Users/*/Applications/*", "/Applications/*",
                  "/tmp/*", "/private/tmp/*", "/var/tmp/*", "/private/var/tmp/*", "/Users/Shared/*",
                  "/Users/*/Downloads/*", "/Users/*/Desktop/*", "/Users/*/Documents/*")
GenAI Process Accessing Sensitive Files
Detects when GenAI tools access sensitive files such as cloud credentials, SSH keys, browser password databases, or shell configurations. Attackers leverage GenAI agents to systematically locate and exfiltrate credentials, API keys, and tokens. Access to credential stores (.aws/credentials, .ssh/id_*) suggests harvesting, while writes to shell configs (.bashrc, .zshrc) indicate persistence attempts. Note: On linux only creation events are available. Access events are not yet implemented.
Show query
file where event.action in ("open", "creation", "modification") and event.outcome == "success" and

  // GenAI process 
    (
      process.name in~ (
        "ollama.exe", "ollama",
        "textgen.exe", "textgen", "text-generation-webui.exe", "oobabooga.exe",
        "lmstudio.exe", "lmstudio", "LM Studio",
        "claude.exe", "claude",
        "cursor.exe", "cursor",
        "copilot.exe", "copilot",
        "codex.exe", "codex",
        "jan.exe", "jan",
        "gpt4all.exe", "gpt4all",
        "gemini-cli.exe", "gemini-cli", "gemini.exe",
        "genaiscript.exe", "genaiscript",
        "grok.exe", "grok",
        "qwen.exe", "qwen",
        "koboldcpp.exe", "koboldcpp",
        "llama-server", "llama-cli",
        "windsurf.exe", "windsurf",
        "zed.exe", "zed",
        "opencode.exe", "opencode",
        "goose.exe", "goose"
      )
    ) and

  // Sensitive file paths
  (
    // Persistence via Shell configs
    file.name in (".bashrc", ".bash_profile", ".zshrc", ".zshenv", ".zprofile", ".profile", ".bash_logout") or

    // Credentials In Files 
    file.name like~ 
                 ("key?.db", 
                  "logins.json", 
                  "Login Data", 
                  "Local State",
                  "signons.sqlite",
                  "Cookies", 
                  "cookies.sqlite",
                  "Cookies.binarycookies", 
                  "login.keychain-db", 
                  "System.keychain", 
                  "credentials.db", 
                  "credentials", 
                  "access_tokens.db", 
                  "accessTokens.json", 
                  "azureProfile.json",
                  "RDCMan.settings", 
                  "known_hosts", 
                  "KeePass.config.xml", 
                  "Unattended.xml")
  ) and not (
    host.os.type == "windows" and
    process.name : ("claude.exe", "Claude") and
    file.path : ("?:\\Users\\*\\AppData\\Roaming\\Claude\\Local State",
                 "?:\\Users\\*\\AppData\\Local\\Packages\\Claude_*\\LocalCache\\Roaming\\Claude\\Local State")
  )
Google Calendar C2 via Script Interpreter
Detects a two-stage Google Calendar C2 pattern where a scripting runtime (Node.js, Python, osascript) first connects to calendar.app.google to retrieve a hidden C2 address, then initiates a secondary connection to the decoded C2 host. This sequence is characteristic of packages using Unicode steganography in Google Calendar events to stage dynamic command-and-control endpoints.
Show query
sequence by process.entity_id with maxspan=20s
  [network where host.os.type == "macos" and event.type == "start" and
    (process.name in ("node", "osascript") or process.name like "python*" or
     process.code_signature.trusted == false or process.code_signature.exists == false) and
    destination.domain like "calendar.app.google*"]
  [network where host.os.type == "macos" and event.type == "start" and destination.domain == null]
Elastic KQL high T1098, T1098.003 ↗
Google Workspace Admin Role Assigned to a User
Assigning the administrative role to a user will grant them access to the Google Admin console and grant them administrator privileges which allow them to access and manage various resources and applications. An adversary may create a new administrator account for persistence or apply the admin role to an existing user to carry out further intrusion efforts. Users with super-admin privileges can bypass single-sign on if enabled in Google Workspace.
Show query
data_stream.dataset:"google_workspace.admin" and event.category:"iam" and event.action:"ASSIGN_ROLE"
  and google_workspace.event.type:"DELEGATED_ADMIN_SETTINGS" and google_workspace.admin.role.name : *_ADMIN_ROLE
Google Workspace Device Registration After OAuth from Suspicious ASN
Detects when a Google Workspace account completes OAuth authorization for a specific Google OAuth client from a high-risk autonomous system number (ASN), followed within 30 seconds by a device registration event with account state REGISTERED. This sequence can indicate device enrollment or join flows initiated from attacker-controlled or residential-proxy infrastructure after a user authorizes a sensitive client.
Show query
sequence by user.name with maxspan=30s
  [iam where data_stream.dataset == "google_workspace.token" and event.action == "authorize" and
      google_workspace.token.client.id == "77185425430.apps.googleusercontent.com" and
      source.as.number in (9009, 45102, 215540, 29802, 62240, 204957, 395092)]
  [any where data_stream.dataset == "google_workspace.device" and google_workspace.device.account_state == "REGISTERED"]
Elastic EQL high T1552, T1552.004, T1530 ↗
Google Workspace Drive Encryption Key(s) Accessed from Anonymous User
Detects when an external (anonymous) user has viewed, copied or downloaded an encryption key file from a Google Workspace drive. Adversaries may gain access to encryption keys stored in private drives from rogue access links that do not have an expiration. Access to encryption keys may allow adversaries to access sensitive data or authenticate on behalf of users.
Show query
file where data_stream.dataset == "google_workspace.drive" and event.action : ("copy", "view", "download") and
    google_workspace.drive.visibility: "people_with_link" and source.user.email == "" and
    file.extension: (
        "token","assig", "pssc", "keystore", "pub", "pgp.asc", "ps1xml", "pem", "gpg.sig", "der", "key",
        "p7r", "p12", "asc", "jks", "p7b", "signature", "gpg", "pgp.sig", "sst", "pgp", "gpgz", "pfx", "crt",
        "p8", "sig", "pkcs7", "jceks", "pkcs8", "psc1", "p7c", "csr", "cer", "spc", "ps2xml")
Elastic EQL high T1484, T1484.001 ↗
Group Policy Abuse for Privilege Addition
Detects the first occurrence of a modification to Group Policy Object Attributes to add privileges to user accounts or use them to add users as local admins.
Show query
any where host.os.type == "windows" and event.code: "5136" and
  winlog.event_data.AttributeLDAPDisplayName: "gPCMachineExtensionNames" and
  winlog.event_data.AttributeValue: "*827D319E-6EAC-11D2-A4EA-00C04F79F83A*" and
  winlog.event_data.AttributeValue: "*803E14A0-B4FB-11D0-A0D0-00A0C90F574B*"
Halfbaked Command and Control Beacon
Halfbaked is a malware family used to establish persistence in a contested network. This rule detects a network activity algorithm leveraged by Halfbaked implant beacons for command and control.
Show query
(data_stream.dataset: (network_traffic.tls OR network_traffic.http) OR
  (event.category: (network OR network_traffic) AND network.protocol: http)) AND
  network.transport:tcp AND url.full:/http:\/\/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}\/cd/ AND
  destination.port:(53 OR 80 OR 8080 OR 443)
Elastic EQL high T1562, T1562.002 ↗
IIS HTTP Logging Disabled
Identifies when Internet Information Services (IIS) HTTP Logging is disabled on a server. An attacker with IIS server access via a webshell or other mechanism can disable HTTP Logging as an effective anti-forensics measure.
Show query
process where host.os.type == "windows" and event.type == "start" and
  (process.name : "appcmd.exe" or ?process.pe.original_file_name == "appcmd.exe") and
  process.args : "/dontLog*:*True" and
  not process.parent.name : "iissetup.exe"
Incoming DCOM Lateral Movement via MSHTA
Identifies the use of Distributed Component Object Model (DCOM) to execute commands from a remote host, which are launched via the HTA Application COM Object. This behavior may indicate an attacker abusing a DCOM application to move laterally while attempting to evade detection.
Show query
sequence with maxspan=1m
  [process where host.os.type == "windows" and event.type == "start" and
     process.name : "mshta.exe" and process.args : "-Embedding"
  ] by host.id, process.entity_id
  [network where host.os.type == "windows" and event.type == "start" and process.name : "mshta.exe" and
     network.direction : ("incoming", "ingress") and network.transport == "tcp" and
     source.port > 49151 and destination.port > 49151 and source.ip != "127.0.0.1" and source.ip != "::1"
  ] by host.id, process.entity_id
Incoming DCOM Lateral Movement with MMC
Identifies the use of Distributed Component Object Model (DCOM) to run commands from a remote host, which are launched via the MMC20 Application COM Object. This behavior may indicate an attacker abusing a DCOM application to move laterally.
Show query
sequence by host.id with maxspan=1m
 [network where host.os.type == "windows" and event.type == "start" and process.name : "mmc.exe" and source.port >= 49152 and
  destination.port >= 49152 and source.ip != "127.0.0.1" and source.ip != "::1" and
  network.direction : ("incoming", "ingress") and network.transport == "tcp"
 ] by process.entity_id
 [process where host.os.type == "windows" and event.type == "start" and process.parent.name : "mmc.exe"
 ] by process.parent.entity_id
Ingress Tool Transfer Followed by Execution and Deletion Detected via Defend for Containers
This rule detects the creation, execution, and deletion of files inside a container, a common technique used by attackers to evade detection.
Show query
sequence by container.id, user.id with maxspan=10s
  [file where event.action == "creation" and (
     process.name in ("curl", "wget", "fetch", "ftp", "sftp", "scp", "rsync", "ld") or
     (
       process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox") and
       process.args in (
         "curl", "/bin/curl", "/usr/bin/curl", "/usr/local/bin/curl",
         "wget", "/bin/wget", "/usr/bin/wget", "/usr/local/bin/wget",
         "fetch", "/bin/fetch", "/usr/bin/fetch", "/usr/local/bin/fetch",
         "ftp", "/bin/ftp", "/usr/bin/ftp", "/usr/local/bin/ftp",
         "sftp", "/bin/sftp", "/usr/bin/sftp", "/usr/local/bin/sftp",
         "scp", "/bin/scp", "/usr/bin/scp", "/usr/local/bin/scp",
         "rsync", "/bin/rsync", "/usr/bin/rsync", "/usr/local/bin/rsync",
         "ld", "/bin/ld", "/usr/bin/ld", "/usr/local/bin/ld"
       ) and
       /* default exclusion list to not FP on default multi-process commands */
       not process.args in (
         "which", "/bin/which", "/usr/bin/which", "/usr/local/bin/which",
         "man", "/bin/man", "/usr/bin/man", "/usr/local/bin/man",
         "chmod", "/bin/chmod", "/usr/bin/chmod", "/usr/local/bin/chmod",
         "chown", "/bin/chown", "/usr/bin/chown", "/usr/local/bin/chown"
       )
     )
   ) and file.path like (
     "/dev/shm/*", "/run/shm/*", "/tmp/*", "/var/tmp/*", "/run/*", "/var/run/*", "/var/www/*",
     "/proc/*/fd/*", "/home/*/*", "/root/*", "/opt/*"
   )
  ] by file.name
  [process where event.type == "start" and event.action == "exec" and
   process.parent.name in ("bash", "dash", "ash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox")
  ] by process.name
  [file where event.action == "deletion" and file.path like (
     "/dev/shm/*", "/run/shm/*", "/tmp/*", "/var/tmp/*", "/run/*", "/var/run/*", "/var/www/*",
     "/proc/*/fd/*", "/home/*/*", "/root/*", "/opt/*"
    ) and not process.name in ("rm", "ld", "conftest", "link", "gcc", "getarch", "ld")
  ] by file.name
Interactive Logon by an Unusual Process
Identifies interactive logon attempt with alternate credentials and by an unusual process. Adversaries may create a new token to escalate privileges and bypass access controls.
Show query
authentication where
 host.os.type : "windows" and winlog.event_data.LogonProcessName : "Advapi*" and
 winlog.logon.type == "Interactive" and winlog.event_data.SubjectUserSid : ("S-1-5-21*", "S-1-12-*") and
 winlog.event_data.TargetUserSid : ("S-1-5-21*", "S-1-12-*")  and process.executable : "C:\\*" and
 not startswith~(winlog.event_data.SubjectUserSid, winlog.event_data.TargetUserSid) and
 not process.executable :
            ("?:\\Windows\\System32\\winlogon.exe",
             "?:\\Windows\\System32\\wininit.exe",
             "?:\\Program Files\\*.exe",
             "?:\\Program Files (x86)\\*.exe",
             "?:\\Windows\\SysWOW64\\inetsrv\\w3wp.exe",
             "?:\\Windows\\System32\\inetsrv\\w3wp.exe",
             "?:\\Windows\\SysWOW64\\msiexec.exe")
Elastic EQL high T1059, T1059.004 ↗
Interactive Terminal Spawned via Perl
Identifies when a terminal (tty) is spawned via Perl. Attackers may upgrade a simple reverse shell to a fully interactive tty after obtaining initial access to a host.
Show query
process where host.os.type == "linux" and event.type == "start" and
event.action in ("exec", "exec_event", "start", "ProcessRollup2", "executed", "process_started") and
process.name == "perl" and process.args == "exec" and
process.args in (
  "\"sh\";", "\"dash\";", "\"bash\";", "\"zsh\";",
  "\"/bin/sh\";", "\"/bin/dash\";", "\"/bin/bash\";", "\"/bin/zsh\";",
  "\"/usr/bin/sh\";", "\"/usr/bin/dash\";", "\"/usr/bin/bash\";", "\"/usr/bin/zsh\";",
  "\"/usr/local/bin/sh\";", "\"/usr/local/bin/dash\";", "\"/usr/local/bin/bash\";", "\"/usr/local/bin/zsh\";"
)
Interactive Terminal Spawned via Python
Identifies when a terminal (tty) is spawned via Python. Attackers may upgrade a simple reverse shell to a fully interactive tty after obtaining initial access to a host.
Show query
process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "exec_event", "start") and
(
  (process.parent.name : "python*" and process.name in ("bash", "dash", "ash", "sh", "tcsh", "csh", "zsh", "ksh",
   "fish") and process.parent.args_count >= 3 and process.parent.args : "*pty.spawn*" and process.parent.args : "-c") or
  (process.parent.name : "python*" and process.name in ("bash", "dash", "ash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and
   process.args in (
     "sh", "dash", "bash", "zsh",
     "/bin/sh", "/bin/dash", "/bin/bash", "/bin/zsh",
     "/usr/bin/sh", "/usr/bin/dash", "/usr/bin/bash", "/usr/bin/zsh",
     "/usr/local/bin/sh", "/usr/local/bin/dash", "/usr/local/bin/bash", "/usr/local/bin/zsh"
   ) and process.args_count == 1 and process.parent.args_count == 1
  )
)
Showing 101-150 of 1,678