Detection rules › Elastic
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.
Rule body elastic
[metadata]
creation_date = "2025/11/19"
integration = ["endpoint", "checkpoint_email"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
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.
"""
from = "now-1h"
interval = "45m"
language = "esql"
license = "Elastic License v2"
name = "Elastic Defend and Email Alerts Correlation"
risk_score = 73
rule_id = "c562a800-cf97-464e-9d6f-84db91e86e10"
severity = "high"
tags = [
"Use Case: Threat Detection",
"Rule Type: Higher-Order Rule",
"Resources: Investigation Guide",
"Data Source: Elastic Defend",
"Data Source: Check Point Harmony Email & Collaboration",
"Domain: Email",
"Domain: Endpoint"
]
timestamp_override = "event.ingested"
type = "esql"
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
'''
note = """## Triage and analysis
### Investigating Elastic Defend and Email Alerts Correlation
This rule correlates any Elastic Defend alert with an email security related alert by target user name.
### Possible investigation steps
- Review the alert details to identify the specific host and users involved.
- Investigate the individual alerts for the target user name and see if they are related.
- Review all emails received from Esql.source_user_name and if there are other impacted users.
- Correlate the alert data with other logs and telemetry from the host, such as process creation, network connections, and file modifications, to gather additional context.
- Assess the impact and scope of the potential compromise by determining if other hosts or systems have similar alerts or related activity.
### False positive analysis
- Legitimate email marked as suspicious.
- Legitimate file or behavior marked as suspicious by Elastic Defend.
- Unrelated alerts where the target user name is too generic.
### Response and remediation
- Isolate the affected host from the network immediately to prevent further lateral movement by the adversary.
- Conduct a thorough forensic analysis of the host.
- Remove any identified malicious software or unauthorized access tools from the host, ensuring all persistence mechanisms are eradicated.
- Restore the host from a known good backup if necessary, ensuring that the backup is free from compromise.
- Monitor the host and network for any signs of re-infection or further suspicious activity, using enhanced logging and alerting based on the identified attack patterns.
- Escalate the incident to the appropriate internal or external cybersecurity teams for further investigation and potential legal action if the attack is part of a larger campaign."""
Stages and Predicates
Stage 1: from
from logs-endpoint.alerts-*, logs-checkpoint_email.event-* metadata _id
Stage 2: where
| 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)
Stage 3: eval
| 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)
elastic_defend_alert_user_name =event.module == "endpoint" and data_stream.dataset == "endpoint.alerts"user.namenullemail_alert_target_user_name =event.category == "email"destination.user.namenullStage 4: eval
| eval Esql.target_user_name = COALESCE(email_alert_target_user_name, elastic_defend_alert_user_name)
Stage 5: where
| where Esql.target_user_name is not null
Stage 6: stats
| 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
Stage 7: where
| where Esql.event_module_distinct_count >= 2
Stage 8: keep
| 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
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
Esql.event_module_distinct_count | ge |
|
Esql.target_user_name | is_not_null | |
data_stream.dataset | eq |
|
destination.user.name | is_not_null | |
event.category | eq |
|
event.kind | eq |
|
event.module | eq |
|
user.name | is_not_null |
Output fields
Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.
| Field | Source |
|---|---|
Esql.alerts_count | KEEP Esql.alerts_count |
Esql.event_module_values | KEEP Esql.event_module_values |
Esql.host_id_values | KEEP Esql.host_id_values |
Esql.source_user_name | KEEP Esql.source_user_name |
Esql.target_user_name | KEEP Esql.target_user_name |
Esql.message_values | KEEP Esql.message_values |
Esql.rule_name_values | KEEP Esql.rule_name_values |
Esql.event_action_values | KEEP Esql.event_action_values |