diff --git a/detection-rules/impersonation_vip_bec_loose.yml b/detection-rules/impersonation_vip_bec_loose.yml index bb9e57f53b2..9f686449535 100644 --- a/detection-rules/impersonation_vip_bec_loose.yml +++ b/detection-rules/impersonation_vip_bec_loose.yml @@ -8,7 +8,30 @@ severity: "medium" source: | type.inbound and any($org_vips, - 0 <= strings.ilevenshtein(sender.display_name, .display_name) < 4 + ( + .display_name != "" + and 0 <= strings.ilevenshtein(sender.display_name, .display_name) < 4 + ) + or ( + .first_name != "" + and .last_name != "" + and 0 <= strings.ilevenshtein(sender.display_name, + strings.concat(.first_name, + " ", + .last_name + ) + ) < 4 + ) + or ( + .first_name != "" + and .last_name != "" + and 0 <= strings.ilevenshtein(sender.display_name, + strings.concat(.last_name, + ", ", + .first_name + ) + ) < 4 + ) ) and any(ml.nlu_classifier(body.current_thread.text).intents, .name == "bec" and .confidence in ("medium", "high") diff --git a/detection-rules/impersonation_vip_invoicing_request.yml b/detection-rules/impersonation_vip_invoicing_request.yml index 6e6e2ec76f9..9dfa48e28a9 100644 --- a/detection-rules/impersonation_vip_invoicing_request.yml +++ b/detection-rules/impersonation_vip_invoicing_request.yml @@ -4,7 +4,26 @@ type: "rule" severity: "high" source: | type.inbound - and any($org_vips, strings.contains(sender.display_name, .display_name)) + and any($org_vips, + ( + .display_name != "" + and strings.contains(sender.display_name, .display_name) + ) + or ( + .first_name != "" + and .last_name != "" + and strings.contains(sender.display_name, + strings.concat(.first_name, " ", .last_name) + ) + ) + or ( + .first_name != "" + and .last_name != "" + and strings.contains(sender.display_name, + strings.concat(.last_name, ", ", .first_name) + ) + ) + ) and ( ( sender.email.domain.domain in $org_domains @@ -26,7 +45,7 @@ source: | ) ) - // and the reply to email address has never been contacted + // and the reply to email address has never been contacted and any(headers.reply_to, .email.email not in $recipient_emails) // negate highly trusted sender domains unless they fail DMARC authentication @@ -37,7 +56,6 @@ source: | ) or sender.email.domain.root_domain not in $high_trust_sender_root_domains ) - attack_types: - "BEC/Fraud" tactics_and_techniques: diff --git a/detection-rules/impersonation_vip_urgent_request.yml b/detection-rules/impersonation_vip_urgent_request.yml index 9d876acf77f..0ee35b49453 100644 --- a/detection-rules/impersonation_vip_urgent_request.yml +++ b/detection-rules/impersonation_vip_urgent_request.yml @@ -7,7 +7,19 @@ type: "rule" severity: "high" source: | type.inbound - and any($org_vips, .display_name =~ sender.display_name) + and any($org_vips, + (.display_name != "" and .display_name =~ sender.display_name) + or ( + .first_name != "" + and .last_name != "" + and strings.concat(.first_name, " ", .last_name) =~ sender.display_name + ) + or ( + .first_name != "" + and .last_name != "" + and strings.concat(.last_name, ", ", .first_name) =~ sender.display_name + ) + ) and ( any(ml.nlu_classifier(body.current_thread.text).intents, .name == "bec" and .confidence in ("medium", "high") diff --git a/detection-rules/impersonation_vip_w2_request.yml b/detection-rules/impersonation_vip_w2_request.yml index 2c4fc6cc1a1..609a0eb2bea 100644 --- a/detection-rules/impersonation_vip_w2_request.yml +++ b/detection-rules/impersonation_vip_w2_request.yml @@ -5,7 +5,26 @@ severity: "high" source: | type.inbound and ( - any($org_vips, strings.contains(sender.display_name, .display_name)) + any($org_vips, + ( + .display_name != "" + and strings.contains(sender.display_name, .display_name) + ) + or ( + .first_name != "" + and .last_name != "" + and strings.contains(sender.display_name, + strings.concat(.first_name, " ", .last_name) + ) + ) + or ( + .first_name != "" + and .last_name != "" + and strings.contains(sender.display_name, + strings.concat(.last_name, ", ", .first_name) + ) + ) + ) or any(regex.extract(sender.display_name, '^(?\S+)\s+(?\S+)$'), any($org_vips, strings.contains(.display_name, ..named_groups["first"]) diff --git a/detection-rules/vip_impersonation.yml b/detection-rules/vip_impersonation.yml index 0dddec63618..20fa052b8c6 100644 --- a/detection-rules/vip_impersonation.yml +++ b/detection-rules/vip_impersonation.yml @@ -14,13 +14,51 @@ source: | type.inbound and ( // the display name matches a name on the orgs vip list - any($org_vips, .display_name =~ sender.display_name) + any($org_vips, + (.display_name != "" and .display_name =~ sender.display_name) + or ( + .first_name != "" + and .last_name != "" + and strings.concat(.first_name, " ", .last_name) =~ sender.display_name + ) + or ( + .first_name != "" + and .last_name != "" + and strings.concat(.last_name, ", ", .first_name) =~ sender.display_name + ) + ) // or the display name starts with the name on the orgs vip list or ( any($org_vips, - strings.istarts_with(sender.display_name, .display_name) - // and it is longer than just their name (eg. John Doe CEO) - and length(sender.display_name) > length(.display_name) + ( + .display_name != "" + and strings.istarts_with(sender.display_name, .display_name) + and length(sender.display_name) > length(.display_name) + ) + or ( + .first_name != "" + and .last_name != "" + and strings.istarts_with(sender.display_name, + strings.concat(.first_name, " ", .last_name) + ) + and length(sender.display_name) > length(strings.concat(.first_name, + " ", + .last_name + ) + ) + ) + or ( + .first_name != "" + and .last_name != "" + and strings.istarts_with(sender.display_name, + strings.concat(.last_name, ", ", .first_name) + ) + and length(sender.display_name) > length(strings.concat(.last_name, + ", ", + .first_name + ) + ) + ) ) // and we have confidence it's BEC and any(ml.nlu_classifier(body.current_thread.text).intents,