From 4788c8b3863eedaa61f8f049c700b5cb9219ded8 Mon Sep 17 00:00:00 2001 From: Bobby Filar <29960025+bfilar@users.noreply.github.com> Date: Tue, 19 Sep 2023 15:56:59 +0200 Subject: [PATCH 01/35] Adding to distinct counts for better accounting (#799) --- signals/links/link_appspot_in_url_path_distinct.yml | 8 ++++---- signals/links/link_free_file_host_distinct.yml | 8 ++++---- signals/links/link_free_subdomain_host_distinct.yml | 10 +++++----- signals/links/link_freenom_tld_distinct.yml | 11 +++++++---- signals/links/link_google_open_redirect_distinct.yml | 9 ++++----- signals/links/link_low_reputation_distinct.yml | 8 ++++---- signals/links/link_mimatched_distinct.yml | 8 ++++---- signals/links/link_suspicious_tld_distinct.yml | 8 ++++---- signals/links/link_url_shortener_distinct.yml | 8 ++++---- 9 files changed, 40 insertions(+), 38 deletions(-) diff --git a/signals/links/link_appspot_in_url_path_distinct.yml b/signals/links/link_appspot_in_url_path_distinct.yml index 9259f5420c3..d00ffa94e69 100644 --- a/signals/links/link_appspot_in_url_path_distinct.yml +++ b/signals/links/link_appspot_in_url_path_distinct.yml @@ -1,4 +1,4 @@ -'name': "Link: Appspot in URL Path Unique Count" -'type': "query" -'source': | - length(distinct(body.links, strings.ilike(.href_url.path, "*appspot.com*"))) +name: "Link: Appspot in URL Path Unique Count" +type: "query" +source: | + length(distinct(filter(body.links, strings.ilike(.href_url.path, "*appspot.com*")), .href_url.url)) diff --git a/signals/links/link_free_file_host_distinct.yml b/signals/links/link_free_file_host_distinct.yml index d2c06ca5aff..9bcf4195b1e 100644 --- a/signals/links/link_free_file_host_distinct.yml +++ b/signals/links/link_free_file_host_distinct.yml @@ -1,4 +1,4 @@ -'name': "Link: Free File Host Unique Count" -'type': "query" -'source': | - length(distinct(body.links, .href_url.domain.domain in $free_file_hosts)) +name: "Link: Free File Host Unique Count" +type: "query" +source: | + length(distinct(filter(body.links, .href_url.domain.domain in $free_file_hosts), .href_url.url)) diff --git a/signals/links/link_free_subdomain_host_distinct.yml b/signals/links/link_free_subdomain_host_distinct.yml index f76c1871058..d59d6345997 100644 --- a/signals/links/link_free_subdomain_host_distinct.yml +++ b/signals/links/link_free_subdomain_host_distinct.yml @@ -1,8 +1,8 @@ -'name': "Link: Free Subdomain Host Unique Count" -'type': "query" -'source': | - length(distinct(body.links, +name: "Link: Free Subdomain Host Unique Count" +type: "query" +source: | + length(distinct(filter(body.links, .href_url.domain.root_domain in $free_subdomain_hosts and .href_url.domain.subdomain is not null and .href_url.domain.subdomain != "www" - )) + ), .href_url.url)) diff --git a/signals/links/link_freenom_tld_distinct.yml b/signals/links/link_freenom_tld_distinct.yml index 96be991225b..3610f00c3e4 100644 --- a/signals/links/link_freenom_tld_distinct.yml +++ b/signals/links/link_freenom_tld_distinct.yml @@ -1,4 +1,7 @@ -'name': "Link: Freenom TLD Unique Count" -'type': "query" -'source': | - length(distinct(body.links, .href_url.domain.tld in ("tk", "ml", "ga", "cf", "gq"))) +name: "Link: Freenom TLD Unique Count" +type: "query" +source: | + length(distinct(filter(body.links, .href_url.domain.tld in ("tk", "ml", "ga", "cf", "gq")), + .href_url.url + ) + ) diff --git a/signals/links/link_google_open_redirect_distinct.yml b/signals/links/link_google_open_redirect_distinct.yml index 40330e11f95..3f22fe8b759 100644 --- a/signals/links/link_google_open_redirect_distinct.yml +++ b/signals/links/link_google_open_redirect_distinct.yml @@ -1,5 +1,4 @@ -'name': "Link: Google Open Redirect Unique Count" -'type': "query" -'source': | - length(distinct(body.links, - regex.icontains(.href_url.url, "https?://(www.)?google.[a-zA-Z]{2,}/url\\?q=https?://.+"))) +name: "Link: Google Open Redirect Unique Count" +type: "query" +source: | + length(distinct(filter(body.links, regex.icontains(.href_url.url, "https?://(www.)?google.[a-zA-Z]{2,}/url\\?q=https?://.+")), .href_url.url)) \ No newline at end of file diff --git a/signals/links/link_low_reputation_distinct.yml b/signals/links/link_low_reputation_distinct.yml index 43959030b5d..2a862d6fb2b 100644 --- a/signals/links/link_low_reputation_distinct.yml +++ b/signals/links/link_low_reputation_distinct.yml @@ -1,4 +1,4 @@ -'name': "Link: Low Reputation Unique Count" -'type': "query" -'source': | - length(distinct(body.links, .href_url.domain.root_domain not in $tranco_1m)) +name: "Link: Low Reputation Unique Count" +type: "query" +source: | + length(distinct(filter(body.links, .href_url.domain.root_domain not in $tranco_1m), .href_url.url)) diff --git a/signals/links/link_mimatched_distinct.yml b/signals/links/link_mimatched_distinct.yml index 5505135f9f2..c54815c5f21 100644 --- a/signals/links/link_mimatched_distinct.yml +++ b/signals/links/link_mimatched_distinct.yml @@ -1,4 +1,4 @@ -'name': "Link: Mismatch Unique Count" -'type': "query" -'source': | - length(distinct(body.links, .mismatched)) +name: "Link: Mismatch Unique Count" +type: "query" +source: | + length(distinct(filter(body.links, .mismatched), .href_url.url)) diff --git a/signals/links/link_suspicious_tld_distinct.yml b/signals/links/link_suspicious_tld_distinct.yml index c32122e5107..a58ea167640 100644 --- a/signals/links/link_suspicious_tld_distinct.yml +++ b/signals/links/link_suspicious_tld_distinct.yml @@ -1,4 +1,4 @@ -'name': "Link: Suspicious TLD Unique Count" -'type': "query" -'source': | - length(distinct(body.links, .href_url.domain.tld in $suspicious_tlds)) +name: "Link: Suspicious TLD Unique Count" +type: "query" +source: | + length(distinct(filter(body.links, .href_url.domain.tld in $suspicious_tlds), .href_url.url)) diff --git a/signals/links/link_url_shortener_distinct.yml b/signals/links/link_url_shortener_distinct.yml index 07ed3b2e666..130f7d81145 100644 --- a/signals/links/link_url_shortener_distinct.yml +++ b/signals/links/link_url_shortener_distinct.yml @@ -1,4 +1,4 @@ -'name': "Link: URL Shortener Unique Count" -'type': "query" -'source': | - length(distinct(body.links, .href_url.domain.root_domain in $url_shorteners)) +name: "Link: URL Shortener Unique Count" +type: "query" +source: | + length(distinct(filter(body.links, .href_url.domain.root_domain in $url_shorteners), .href_url.url)) From 7bd862d63b73ea35633d8b2825ce9b798b6feba8 Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Tue, 19 Sep 2023 14:47:58 -0400 Subject: [PATCH 02/35] Update link_google_open_redirect_with_suspicious_indicators.yml (#749) --- ...le_open_redirect_with_suspicious_indicators.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/detection-rules/link_google_open_redirect_with_suspicious_indicators.yml b/detection-rules/link_google_open_redirect_with_suspicious_indicators.yml index e91911a9a39..a96f0c4381d 100644 --- a/detection-rules/link_google_open_redirect_with_suspicious_indicators.yml +++ b/detection-rules/link_google_open_redirect_with_suspicious_indicators.yml @@ -6,11 +6,13 @@ type: "rule" severity: "medium" source: | type.inbound - // All attachments are images - and length(attachments) > 0 - and all(attachments, .file_type in $file_types_images) + // All attachments are images or 0 attachments + and ( + (length(attachments) > 0 and all(attachments, .file_type in $file_types_images)) + or length(attachments) == 0 + ) and sender.email.domain.root_domain not in $org_domains - + // not a reply and ( length(headers.references) == 0 @@ -52,7 +54,7 @@ source: | ( any(ml.nlu_classifier(body.current_thread.text).entities, .name == "urgency") ), - + // White font is found in html raw ( length(body.html.display_text) < 500 @@ -60,7 +62,7 @@ source: | '
0 - + // negate legitimate message senders and ( sender.email.domain.root_domain not in ("protectedtrust.com") and any(body.links, .href_url.domain.root_domain != sender.email.domain.root_domain ) + // Negate known secure mailer(s) + and not all(body.links, .href_url.domain.root_domain in ("mimecast.com")) ) - + // first-time sender and ( ( From 822924b703455ea7b259c63fe27699716f44bf40 Mon Sep 17 00:00:00 2001 From: Josh Kamdjou Date: Wed, 20 Sep 2023 08:35:43 -0700 Subject: [PATCH 04/35] Exclude automatic out of office replies (#801) --- .../body_business_email_compromise_new_sender.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/detection-rules/body_business_email_compromise_new_sender.yml b/detection-rules/body_business_email_compromise_new_sender.yml index 1c509c258c0..16fb9df2d5f 100644 --- a/detection-rules/body_business_email_compromise_new_sender.yml +++ b/detection-rules/body_business_email_compromise_new_sender.yml @@ -10,7 +10,12 @@ source: | ) // negating legit replies and not ( - strings.istarts_with(subject.subject, "RE:") + ( + strings.istarts_with(subject.subject, "RE:") + // out of office auto-reply + // the NLU model will handle these better natively soon + or strings.istarts_with(subject.subject, "Automatic reply:") + ) and ( length(headers.references) > 0 or any(headers.hops, any(.fields, strings.ilike(.name, "In-Reply-To"))) From ea97cf31683043e62e05c18ad0148230c65b6ced Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Wed, 20 Sep 2023 12:03:10 -0400 Subject: [PATCH 05/35] Negate FP: link_credential_phishing_voicemail_language.yml (#803) --- ...credential_phishing_voicemail_language.yml | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/detection-rules/link_credential_phishing_voicemail_language.yml b/detection-rules/link_credential_phishing_voicemail_language.yml index 0df96e25fe3..a5eb16d114e 100644 --- a/detection-rules/link_credential_phishing_voicemail_language.yml +++ b/detection-rules/link_credential_phishing_voicemail_language.yml @@ -25,7 +25,11 @@ source: | all(body.links, .href_url.domain.root_domain != sender.email.domain.root_domain and .href_url.domain.root_domain not in $org_domains - and .href_url.domain.root_domain not in ("unitelvoice.com", "googleapis.com", "dialmycalls.com") + and .href_url.domain.root_domain not in ( + "unitelvoice.com", + "googleapis.com", + "dialmycalls.com" + ) ) ), ( @@ -34,6 +38,20 @@ source: | ), ) and sender.email.domain.root_domain not in ("magicjack.com", "unitelvoice.com") + + // negating legit replies + and not ( + ( + strings.istarts_with(subject.subject, "RE:") + // out of office auto-reply + // the NLU model will handle these better natively soon + or strings.istarts_with(subject.subject, "Automatic reply:") + ) + and ( + length(headers.references) > 0 + or any(headers.hops, any(.fields, strings.ilike(.name, "In-Reply-To"))) + ) + ) and ( ( sender.email.domain.root_domain in $free_email_providers From d7b5d348325202ca46d9d0749c4be897c99da121 Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Wed, 20 Sep 2023 12:54:36 -0400 Subject: [PATCH 06/35] New Rule: Credential Phishing: Suspicious language, link, recipients and other indicators (#804) Co-authored-by: ID Generator --- ...icious_language_undisclosed_recipients.yml | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 detection-rules/link_suspicious_language_undisclosed_recipients.yml diff --git a/detection-rules/link_suspicious_language_undisclosed_recipients.yml b/detection-rules/link_suspicious_language_undisclosed_recipients.yml new file mode 100644 index 00000000000..7fcb7a130ba --- /dev/null +++ b/detection-rules/link_suspicious_language_undisclosed_recipients.yml @@ -0,0 +1,61 @@ +name: "Credential Phishing: Suspicious language, link, recipients and other indicators" +description: | + The rule flags inbound messages with no visible recipients, contain all-caps text, and include links from certain free hosts. It also checks for signs of credential theft using machine learning classifiers and is from a first-time sender. +type: "rule" +severity: "medium" +source: | + type.inbound + + // no recipients defined + and (length(recipients.to) == 0 or all(recipients.to, .display_name == "Undisclosed recipients")) + and length(recipients.cc) == 0 + and length(recipients.bcc) == 0 + + and any(body.links, + + // suspicious link + // we've particularly seen 1drv.ms abused + // if using the full list causes FPs, we can reduce the + // scope to a hard-coded list or add exclusions + ( + .href_url.domain.domain in $free_file_hosts + or .href_url.domain.root_domain in $free_subdomain_hosts + ) + + // link text is in all caps + and regex.match(.display_text, "[A-Z ]+") + ) + + // any confidence cred_theft classification + and any(ml.nlu_classifier(body.current_thread.text).intents, .name == "cred_theft") + + // 'org' entity is in all caps + and any(ml.nlu_classifier(body.current_thread.text).entities, + .name == "org" and regex.match(.text, "[A-Z ]+") + ) + + // subject is in all caps + and regex.match(subject.subject, "[A-Z ]+") + + // first-time sender + and ( + ( + sender.email.domain.root_domain in $free_email_providers + and sender.email.email not in $sender_emails + ) + or ( + sender.email.domain.root_domain not in $free_email_providers + and sender.email.domain.domain not in $sender_domains + ) + ) +attack_types: + - "Credential Phishing" +tactics_and_techniques: + - "Evasion" +detection_methods: + - "Content analysis" + - "Header analysis" + - "Natural Language Understanding" + - "Sender analysis" + - "URL analysis" +id: "dcb39190-7ea1-5e82-8d6b-0242affdb6e3" From a979ae94d59db87d9bf9d34df96705cb986cfeab Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Wed, 20 Sep 2023 13:12:05 -0400 Subject: [PATCH 07/35] FP fix: Update link_microsoft_low_reputation.yml (#791) Co-authored-by: Josh Kamdjou --- .../link_microsoft_low_reputation.yml | 253 +++++++++--------- 1 file changed, 129 insertions(+), 124 deletions(-) diff --git a/detection-rules/link_microsoft_low_reputation.yml b/detection-rules/link_microsoft_low_reputation.yml index 3579bb944e5..5e467937174 100644 --- a/detection-rules/link_microsoft_low_reputation.yml +++ b/detection-rules/link_microsoft_low_reputation.yml @@ -3,134 +3,139 @@ description: "Detects low reputation links with Microsoft specific indicators in type: "rule" severity: "medium" source: | - type.inbound - // suspicious link - and any(body.links, - ( - .href_url.domain.root_domain not in $tranco_1m - or .href_url.domain.domain in $free_file_hosts - or .href_url.domain.root_domain in $free_subdomain_hosts - or .href_url.domain.domain in $url_shorteners - or - - // mass mailer link, masks the actual URL - .href_url.domain.root_domain in ("hubspotlinks.com", "mandrillapp.com", "sendgrid.net") - - // Google AMP redirect - or ( - .href_url.domain.sld == "google" - and strings.starts_with(.href_url.path, "/amp/") - ) - ) - - // exclude sources of potential FPs - and .href_url.domain.root_domain not in ( - "svc.ms", - "sharepoint.com", - "1drv.ms", - "microsoft.com" - ) - ) - - // not a reply - and ( - length(headers.references) == 0 - or not any(headers.hops, any(.fields, strings.ilike(.name, "In-Reply-To"))) - ) - - // Microsoft logo - and ( - any(attachments, - .file_type in $file_types_images - and any(ml.logo_detect(.).brands, strings.starts_with(.name, "Microsoft")) - ) - or any(ml.logo_detect(beta.message_screenshot()).brands, strings.starts_with(.name, "Microsoft")) - ) - - // suspicious content - and ( - ( - strings.ilike(body.plain.raw, - "*password*", - "*document*", - "*voicemail*", - "*cache*", - "*fax*", - "*storage*", - "*quota*", - "*messages*" - ) - and strings.ilike(body.plain.raw, - "*terminated*", - "*review*", - "*expire*", - "*click*", - "*view*", - "*exceed*", - "*clear*", - "*only works*", - "*failed*", - "*deleted*" - ) - ) - or ( - any(attachments, + type.inbound + // suspicious link + and any(body.links, + ( + .href_url.domain.root_domain not in $tranco_1m + or .href_url.domain.domain in $free_file_hosts + or .href_url.domain.root_domain in $free_subdomain_hosts + or .href_url.domain.domain in $url_shorteners + or + + // mass mailer link, masks the actual URL + .href_url.domain.root_domain in ("hubspotlinks.com", "mandrillapp.com", "sendgrid.net") + + // Google AMP redirect + or (.href_url.domain.sld == "google" and strings.starts_with(.href_url.path, "/amp/")) + ) + + // exclude sources of potential FPs + and ( + .href_url.domain.root_domain not in ( + "svc.ms", + "sharepoint.com", + "1drv.ms", + "microsoft.com", + "aka.ms", + "msftauthimages.net" + ) + or any(body.links, .href_url.domain.domain in $free_file_hosts) + ) + ) + + // not a reply + and ( + length(headers.references) == 0 + or not any(headers.hops, any(.fields, strings.ilike(.name, "In-Reply-To"))) + ) + + // Microsoft logo + and ( + any(attachments, + .file_type in $file_types_images + and any(ml.logo_detect(.).brands, strings.starts_with(.name, "Microsoft")) + ) + or any(ml.logo_detect(beta.message_screenshot()).brands, strings.starts_with(.name, "Microsoft")) + ) + + // suspicious content + and ( + ( + strings.ilike(body.plain.raw, + "*password*", + "*document*", + "*voicemail*", + "*cache*", + "*fax*", + "*storage*", + "*quota*", + "*messages*" + ) + and strings.ilike(body.plain.raw, + "*terminated*", + "*review*", + "*expire*", + "*click*", + "*view*", + "*exceed*", + "*clear*", + "*only works*", + "*failed*", + "*deleted*" + ) + ) + or ( + any(attachments, + .file_type in $file_types_images + and any(file.explode(.), + strings.ilike(.scan.ocr.raw, + "*password*", + "*document*", + "*voicemail*", + "*cache*", + "*fax*", + "*storage*", + "*quota*", + "*messages*" + ) + and strings.ilike(.scan.ocr.raw, + "*terminated*", + "*review*", + "*expire*", + "*click*", + "*view*", + "*exceed*", + "*clear*", + "*only works*", + "*failed*", + "*deleted*" + ) + ) + ) + ) + ) + and ( + any(ml.nlu_classifier(body.current_thread.text).intents, + .name == "cred_theft" and .confidence in~ ("medium", "high") + ) + or any(attachments, .file_type in $file_types_images and any(file.explode(.), - strings.ilike(.scan.ocr.raw, - "*password*", - "*document*", - "*voicemail*", - "*cache*", - "*fax*", - "*storage*", - "*quota*", - "*messages*" - ) - and strings.ilike(.scan.ocr.raw, - "*terminated*", - "*review*", - "*expire*", - "*click*", - "*view*", - "*exceed*", - "*clear*", - "*only works*", - "*failed*", - "*deleted*" + any(ml.nlu_classifier(.scan.ocr.raw).intents, + .name == "cred_theft" and .confidence in ("medium", "high") ) ) - ) - ) - ) - and ( - any(ml.nlu_classifier(body.html.inner_text).intents, - .name == "cred_theft" and .confidence in~ ("medium", "high") - ) - or any(attachments, - .file_type in $file_types_images - and any(file.explode(.), - any(ml.nlu_classifier(.scan.ocr.raw).intents, .name == "cred_theft") - ) - ) - or ( - any(ml.nlu_classifier(body.html.inner_text).entities, .name == "urgency") - and not any(ml.nlu_classifier(body.current_thread.text).intents, - .name == "benign" and .confidence == "high" - ) - ) - ) - and sender.email.domain.root_domain not in ( - "bing.com", - "microsoft.com", - "microsoftonline.com", - "microsoftsupport.com", - "microsoft365.com", - "office.com", - "onedrive.com", - "sharepointonline.com", - "yammer.com" - ) + ) + or ( + any(ml.nlu_classifier(body.html.inner_text).entities, .name == "urgency") + and not any(ml.nlu_classifier(body.current_thread.text).intents, + .name == "benign" and .confidence == "high" + ) + ) + ) + and sender.email.domain.root_domain not in ( + "bing.com", + "microsoft.com", + "microsoftonline.com", + "microsoftsupport.com", + "microsoft365.com", + "office.com", + "onedrive.com", + "sharepointonline.com", + "yammer.com" + ) + attack_types: - "Credential Phishing" tactics_and_techniques: From eb1e15e181786b3fd462b80a509410ff6c885eb4 Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Thu, 21 Sep 2023 14:46:24 -0400 Subject: [PATCH 08/35] New Rule: HTML smuggling with decimal encoding (#806) Co-authored-by: ID Generator --- ...chment_html_smuggling_decimal_encoding.yml | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 detection-rules/attachment_html_smuggling_decimal_encoding.yml diff --git a/detection-rules/attachment_html_smuggling_decimal_encoding.yml b/detection-rules/attachment_html_smuggling_decimal_encoding.yml new file mode 100644 index 00000000000..236d94bf693 --- /dev/null +++ b/detection-rules/attachment_html_smuggling_decimal_encoding.yml @@ -0,0 +1,39 @@ +name: "Attachment: HTML smuggling with decimal encoding" +description: | + Potential HTML smuggling attack based on large blocks of decimal encoding. Attackers often use decimal encoding as an obfuscation technique to bypass traditional email security measures. +type: "rule" +severity: "high" +source: | + type.inbound + and any(attachments, + ( + .file_extension in~ ("html", "htm", "shtml", "dhtml", "xhtml") + or ( + .file_extension is null + and .file_type == "unknown" + and .content_type == "application/octet-stream" + ) + or .file_extension in~ $file_extensions_common_archives + or .file_type == "html" + or .content_type == "text/html" + ) + and any(file.explode(.), + // suspicious identifiers + any(.scan.strings.strings, + regex.contains(., '(\d{2,3},){60,}') + ) + ) + ) +attack_types: + - "Credential Phishing" + - "Malware/Ransomware" +tactics_and_techniques: + - "Evasion" + - "HTML smuggling" + - "Scripting" +detection_methods: + - "Archive analysis" + - "Content analysis" + - "File analysis" + - "HTML analysis" +id: "f99213c4-7031-50b1-ae81-b45f790d3fa4" From f6052cbd996c95ed67a4200af7f65dc6ec3c1b0e Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Thu, 21 Sep 2023 18:12:26 -0400 Subject: [PATCH 09/35] New Rule: Attachment: HTML smuggling 'body onload' linking to suspicious destination (#808) Co-authored-by: ID Generator --- .../attachment_html_smuggling_body_onload.yml | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 detection-rules/attachment_html_smuggling_body_onload.yml diff --git a/detection-rules/attachment_html_smuggling_body_onload.yml b/detection-rules/attachment_html_smuggling_body_onload.yml new file mode 100644 index 00000000000..2b401202409 --- /dev/null +++ b/detection-rules/attachment_html_smuggling_body_onload.yml @@ -0,0 +1,49 @@ +name: "Attachment: HTML smuggling 'body onload' linking to suspicious destination" +description: | + Potential HTML Smuggling. + This rule inspects HTML attachments that contain a single link and leveraging an HTML body onload event. The linked domain must be in the URLhaus trusted repoters list, or have a suspicious TLD. +type: "rule" +severity: "high" +source: | + type.inbound + and any(attachments, + ( + .file_extension in~ ("html", "htm", "shtml", "dhtml", "xhtml") + or ( + .file_extension is null + and .file_type == "unknown" + and .content_type == "application/octet-stream" + ) + or .file_extension in~ $file_extensions_common_archives + or .file_type == "html" + or .content_type == "text/html" + ) + and any(file.explode(.), + not length(.scan.url.invalid_urls) > 0 + and length(.scan.url.urls) == 1 + and any(.scan.strings.strings, strings.ilike(., "*body onload*")) + and ( + any(.scan.url.urls, + .domain.root_domain in $abuse_ch_urlhaus_domains_trusted_reporters + + // To-do uncomment below when list is created + //or .domain.root_domain in $suspicious_root_domains + or .domain.tld in $suspicious_tlds + ) + ) + ) + ) +attack_types: + - "Credential Phishing" + - "Malware/Ransomware" +tactics_and_techniques: + - "Evasion" + - "HTML smuggling" + - "Scripting" +detection_methods: + - "Archive analysis" + - "Content analysis" + - "File analysis" + - "HTML analysis" + - "Link analysis" +id: "c1e2beed-e71e-58d2-b922-9601337645b2" From 0fe045043a5b15e2acb30f0df6d960a736c2d254 Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Fri, 22 Sep 2023 07:47:13 -0400 Subject: [PATCH 10/35] Negate FP: body_business_email_compromise_unsolicited.yml (#802) --- ...y_business_email_compromise_unsolicited.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/detection-rules/body_business_email_compromise_unsolicited.yml b/detection-rules/body_business_email_compromise_unsolicited.yml index f47916f189f..a3181b43bd8 100644 --- a/detection-rules/body_business_email_compromise_unsolicited.yml +++ b/detection-rules/body_business_email_compromise_unsolicited.yml @@ -27,7 +27,22 @@ source: | ) ), ) - + + // negate "via" senders via dmarc authentication or gmail autoforwards + and ( + not ( + any(distinct(headers.hops, .authentication_results.dmarc is not null), + strings.ilike(.authentication_results.dmarc, "pass") + or ( + not any([headers.return_path.email], + strings.ilike(headers.return_path.local_part, "*+caf_=*") + ) + and strings.contains(sender.display_name, "via") + ) + ) + ) + ) + // unsolicited and ( ( @@ -39,6 +54,7 @@ source: | and sender.email.domain.domain not in $recipient_domains ) ) + attack_types: - "BEC/Fraud" tactics_and_techniques: From 59084976ac69b8a9369047c2b1daf148a193db69 Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Fri, 22 Sep 2023 13:32:48 -0400 Subject: [PATCH 11/35] Update attachment_html_smuggling_body_onload.yml (#810) --- detection-rules/attachment_html_smuggling_body_onload.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detection-rules/attachment_html_smuggling_body_onload.yml b/detection-rules/attachment_html_smuggling_body_onload.yml index 2b401202409..98dbb8d552b 100644 --- a/detection-rules/attachment_html_smuggling_body_onload.yml +++ b/detection-rules/attachment_html_smuggling_body_onload.yml @@ -45,5 +45,5 @@ detection_methods: - "Content analysis" - "File analysis" - "HTML analysis" - - "Link analysis" + - "URL analysis" id: "c1e2beed-e71e-58d2-b922-9601337645b2" From 5683d77b84cafcba47efa97e5340be9fcdb3cc02 Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Fri, 22 Sep 2023 15:19:59 -0400 Subject: [PATCH 12/35] Fixing FN: attachment_html_recipient_in_javascript_identifiers.yml (#805) --- ...tml_recipient_in_javascript_identifiers.yml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/detection-rules/attachment_html_recipient_in_javascript_identifiers.yml b/detection-rules/attachment_html_recipient_in_javascript_identifiers.yml index 849592d655b..92325b3de87 100644 --- a/detection-rules/attachment_html_recipient_in_javascript_identifiers.yml +++ b/detection-rules/attachment_html_recipient_in_javascript_identifiers.yml @@ -7,25 +7,29 @@ source: | type.inbound and any(attachments, ( - .file_extension in~ ("html", "htm", "shtml", "dhtml") + .file_extension in~ ("html", "htm", "shtml", "dhtml", "xhtml") or ( .file_extension is null and .file_type == "unknown" and .content_type == "application/octet-stream" - and .size < 100000000 ) or .file_extension in~ $file_extensions_common_archives or .file_type == "html" + or .content_type == "text/html" ) and any(file.explode(.), // suspicious identifiers - any(.scan.javascript.identifiers, strings.like(., "atob", "decrypt")) - // Recipients address found in javascript - and any(recipients.to, - any(..scan.javascript.strings, strings.icontains(., ..email.email)) + any([.scan.strings.strings, .scan.javascript.identifiers], + any(., strings.like(., "*atob*", "*decrypt*")) ) ) - ) + // Recipients address found in javascript + and any(file.explode(.), + any(recipients.to, + any(..scan.javascript.strings, strings.icontains(., ..email.email)) + ) + ) + ) attack_types: - "Credential Phishing" tactics_and_techniques: From 7a7921a25eb59b3ba3aba0b4d866ee6fac873ed1 Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Fri, 22 Sep 2023 18:30:47 -0400 Subject: [PATCH 13/35] Update attachment_html_smuggling_unescape.yml (#816) --- detection-rules/attachment_html_smuggling_unescape.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/detection-rules/attachment_html_smuggling_unescape.yml b/detection-rules/attachment_html_smuggling_unescape.yml index b4ccb82ceb2..7096c7d740b 100644 --- a/detection-rules/attachment_html_smuggling_unescape.yml +++ b/detection-rules/attachment_html_smuggling_unescape.yml @@ -13,7 +13,10 @@ source: | or .file_extension in~ $file_extensions_common_archives or .file_type == "html" ) - and any(file.explode(.), any(.scan.javascript.identifiers, . == "unescape")) + and any(file.explode(.), + any(.scan.javascript.identifiers, . == "unescape") + or any(.scan.strings.strings, regex.contains(., "document.write.{0,10}unescape")) + ) ) attack_types: - "Credential Phishing" From de9bfce656ff21b7456e5a84c13ce2ada84df12f Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Mon, 25 Sep 2023 13:18:06 -0400 Subject: [PATCH 14/35] =?UTF-8?q?FP=20Update:=20Update=20attachment=5Fhtml?= =?UTF-8?q?=5Frecipient=5Fin=5Fjavascript=5Fidentifiers=E2=80=A6=20(#820)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...attachment_html_recipient_in_javascript_identifiers.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/detection-rules/attachment_html_recipient_in_javascript_identifiers.yml b/detection-rules/attachment_html_recipient_in_javascript_identifiers.yml index 92325b3de87..b57a8a5a500 100644 --- a/detection-rules/attachment_html_recipient_in_javascript_identifiers.yml +++ b/detection-rules/attachment_html_recipient_in_javascript_identifiers.yml @@ -28,8 +28,15 @@ source: | any(recipients.to, any(..scan.javascript.strings, strings.icontains(., ..email.email)) ) + + // Negating Cisco Secure Email Encryption + and not any(.scan.javascript.strings, + strings.contains(., "Cisco Registered Envelope Service") + and not strings.contains(., "https://res.cisco.com:443") + ) ) ) + attack_types: - "Credential Phishing" tactics_and_techniques: From 8a09102b111886b8288468669eddbab80a242e0e Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Mon, 25 Sep 2023 12:30:49 -0700 Subject: [PATCH 15/35] New Rule (Attachment): HTML smuggling 'body onload' with high entropy and suspicious text (#814) Co-authored-by: ID Generator Co-authored-by: Sam Scholten --- ...hment_html_smuggling_suspicious_onload.yml | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 detection-rules/attachment_html_smuggling_suspicious_onload.yml diff --git a/detection-rules/attachment_html_smuggling_suspicious_onload.yml b/detection-rules/attachment_html_smuggling_suspicious_onload.yml new file mode 100644 index 00000000000..9e007fa74a1 --- /dev/null +++ b/detection-rules/attachment_html_smuggling_suspicious_onload.yml @@ -0,0 +1,39 @@ +name: "Attachment: HTML smuggling 'body onload' with high entropy and suspicious text" +description: | + Potential HTML Smuggling. This rule inspects HTML attachments that contain "body unload", high entropy, and suspicious text. +type: "rule" +severity: "high" +source: | + type.inbound + and any(attachments, + ( + .file_extension in~ ("html", "htm", "shtml", "dhtml", "xhtml") + or ( + .file_extension is null + and .file_type == "unknown" + and .content_type == "application/octet-stream" + ) + or .file_extension in~ $file_extensions_common_archives + or .file_type == "html" + or .content_type == "text/html" + ) + and any(file.explode(.), + .scan.entropy.entropy >= 5 + and any(.scan.strings.strings, strings.ilike(., "*body onload*")) + and any(.scan.strings.strings, regex.icontains(., 'data:image/.*;base64')) + and any(.scan.strings.strings, strings.ilike(., "*document pass*")) + ) + ) +attack_types: + - "Credential Phishing" + - "Malware/Ransomware" +tactics_and_techniques: + - "Evasion" + - "HTML smuggling" + - "Scripting" +detection_methods: + - "Archive analysis" + - "Content analysis" + - "File analysis" + - "HTML analysis" +id: "329ac12d-f74e-577c-936c-1db80ccf860e" From b6f9ef6d278b89c4d6e1fa54338608c9b243f854 Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Tue, 26 Sep 2023 07:45:13 -0700 Subject: [PATCH 16/35] Updating rule: attachment_pdf_with_google_ae_redirect.yml (#809) Co-authored-by: Sam Scholten --- .../attachment_pdf_with_google_ae_redirect.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/detection-rules/attachment_pdf_with_google_ae_redirect.yml b/detection-rules/attachment_pdf_with_google_ae_redirect.yml index a002b8b967d..c0a09fcdff2 100644 --- a/detection-rules/attachment_pdf_with_google_ae_redirect.yml +++ b/detection-rules/attachment_pdf_with_google_ae_redirect.yml @@ -1,5 +1,5 @@ -name: "PDF attachment with Google (AE) redirecting to a php file" -description: "Detects a PDF attachment with a link that contains a Google.ae redirect URL" +name: "PDF attachment with Google (AE) redirecting to a php or zip file" +description: "Detects a PDF attachment with a link that contains a Google.ae redirect URL." references: - "https://twitter.com/Cryptolaemus1/status/1649200761610571776?s=20" - "https://analyzer.sublime.security?id=142822c9-8195-47bd-96e3-b8a26267c03c" @@ -13,8 +13,11 @@ source: | any(.scan.pdf.urls, // url encoded q=http strings.starts_with(.query_params, "q=%68%74%74%70") - // url encoded .php - and strings.contains(.query_params, ".%70%68%70") + // url encoded .php or .zip + and ( + strings.contains(.query_params, ".%70%68%70") + or strings.contains(.query_params, "%2e%7a%69%70") + ) and .domain.root_domain == "google.ae" ) ) From 9ed2b695a818634f6803595688a337277ff00e82 Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Tue, 26 Sep 2023 13:35:54 -0400 Subject: [PATCH 17/35] FN: Update attachment_microsoft_image_lure_qr_code.yml (#823) Co-authored-by: Ross Wolf <31489089+rw-access@users.noreply.github.com> --- ...ttachment_microsoft_image_lure_qr_code.yml | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/detection-rules/attachment_microsoft_image_lure_qr_code.yml b/detection-rules/attachment_microsoft_image_lure_qr_code.yml index 893ce305af0..7b024a35f89 100644 --- a/detection-rules/attachment_microsoft_image_lure_qr_code.yml +++ b/detection-rules/attachment_microsoft_image_lure_qr_code.yml @@ -19,12 +19,33 @@ source: | regex.icontains(.scan.ocr.raw, 'scan|camera') and regex.icontains(.scan.ocr.raw, '\bQR\b|Q\.R\.|barcode') ) - ) - or ( - any(file.explode(.), - .scan.qr.type == "url" - // recipient email address is present in the URL, a common tactic used in credential phishing attacks - and any(recipients.to, strings.icontains(..scan.qr.data, .email.email)) + or ( + any(file.explode(.), + .scan.qr.type == "url" + // recipient email address is present in the URL, a common tactic used in credential phishing attacks + and any(recipients.to, + strings.icontains(..scan.qr.data, .email.email) + + // the recipients sld is in the senders display name + or any(recipients.to, + strings.icontains(sender.display_name, .email.domain.sld) + ) + + // the recipient local is in the body + or any(recipients.to, + strings.icontains(body.current_thread.text, .email.local_part) + ) + + // or the body is null + or body.current_thread.text is null + or body.current_thread.text == "" + + // or the subject contains authentication/urgency verbiage + or regex.contains(subject.subject, + "(Authenticat(e|or|ion)|2fa|Multi.Factor|(qr|bar).code|action.require|alert|Att(n|ention):)" + ) + ) + ) ) ) ) @@ -46,6 +67,7 @@ source: | and sender.email.domain.domain not in $recipient_domains ) ) + attack_types: - "Credential Phishing" tactics_and_techniques: From 83b7a4ac0a168f2abe2852d2973cdca39fd793c0 Mon Sep 17 00:00:00 2001 From: Cameron Dunn Date: Tue, 26 Sep 2023 15:09:29 -0700 Subject: [PATCH 18/35] Skip LA rules in upate-test-rules workflow (#824) --- .github/workflows/update-test-rules.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/update-test-rules.yml b/.github/workflows/update-test-rules.yml index 89c681c27e0..7a6507a2537 100644 --- a/.github/workflows/update-test-rules.yml +++ b/.github/workflows/update-test-rules.yml @@ -122,6 +122,12 @@ jobs: # but it doesn't seem any simpler). And then add testing metadata. # If multiple PRs modify the same file, only one can be tested. This is solveable, but not something we see often. for file in $files_changed; do + # Skip any LA rules. We'll ignore these downstream anyway, but best to keep the branch clean. + la_count=$(grep -c 'beta.linkanalysis' detection-rules/$file || true) + if [[ "$la_count" != '0' ]]; then + continue + fi + cp source/$file destination/$file yq -i '.testing_pr = env(pr_num)' destination/$file yq -i '.testing_sha = env(sha)' destination/$file From ccb9bfa4d3d5da48daadd11ce18d6dd5066a0993 Mon Sep 17 00:00:00 2001 From: Cameron Dunn Date: Tue, 26 Sep 2023 15:55:53 -0700 Subject: [PATCH 19/35] Remove detection_rules/ prefix (#825) --- .github/workflows/update-test-rules.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-test-rules.yml b/.github/workflows/update-test-rules.yml index 7a6507a2537..9e67a0863ca 100644 --- a/.github/workflows/update-test-rules.yml +++ b/.github/workflows/update-test-rules.yml @@ -123,7 +123,7 @@ jobs: # If multiple PRs modify the same file, only one can be tested. This is solveable, but not something we see often. for file in $files_changed; do # Skip any LA rules. We'll ignore these downstream anyway, but best to keep the branch clean. - la_count=$(grep -c 'beta.linkanalysis' detection-rules/$file || true) + la_count=$(grep -c 'beta.linkanalysis' $file || true) if [[ "$la_count" != '0' ]]; then continue fi From a9e5e035ed9b1efa1ab3bc78d282012c5ea2eada Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Thu, 28 Sep 2023 07:06:26 -0700 Subject: [PATCH 20/35] Adding delivr.to rule (#826) Co-authored-by: ID Generator --- detection-rules/attachment_cve_2023_38831.yml | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 detection-rules/attachment_cve_2023_38831.yml diff --git a/detection-rules/attachment_cve_2023_38831.yml b/detection-rules/attachment_cve_2023_38831.yml new file mode 100644 index 00000000000..22f0b734b1b --- /dev/null +++ b/detection-rules/attachment_cve_2023_38831.yml @@ -0,0 +1,67 @@ +name: "Attachment: Zip Exploiting CVE-2023-38831 (Unsolicited)" +description: | + A Zip attachment that exhibits attributes required to exploit CVE-2023-38831, a vulnerability in WinRAR (prior to 6.23). +type: "rule" +severity: "critical" +authors: + - twitter: "delivr_to" +references: + - https://twitter.com/GroupIB_TI/status/1694277126944633328 + - https://www.group-ib.com/blog/cve-2023-38831-winrar-zero-day/ + - https://github.com/b1tg/CVE-2023-38831-winrar-exploit/ + - https://delivr.to/payloads?id=ab969e8a-bf5c-45a6-acd0-0dd2b2a34750 +source: | + type.inbound + and any(attachments, + .file_extension in $file_extensions_common_archives and + any(file.explode(.), + ( + .depth == 0 and + any(.scan.zip.all_paths, + regex.match(., + // zip contains a path with spaces and file extensions + // lure.pdf /lure.pdf .cmd + // + // /= Initial file name + // | + // | /= Space + // | | + // | | /= Folder + // | | | + // | | | /= Repeated file name + // | | | | + // | | | | /= Space + // | | | | | + // | | | | | /= Real script ending + // | | | | | | + '\w+\.\w+\s\/\w+\.\w+\s\.\w+' + ) + ) + ) and + ( + // One file name is present in another, e.g. + // delivrto.pdf + // delivrto.pdf /delivrto.pdf .cmd + any(.scan.zip.all_paths, + any(..scan.zip.all_paths, + . != .. and + strings.starts_with(., ..) + ) + ) + ) + ) + ) + and ( + ( + sender.email.domain.root_domain in $free_email_providers + and sender.email.email not in $recipient_emails + ) + or ( + sender.email.domain.root_domain not in $free_email_providers + and sender.email.domain.domain not in $recipient_domains + ) + ) +tags: + - "Suspicious Attachment" + - "CVE-2023-38831" +id: "926b96ae-f40b-525d-a312-bd6c9a5f19fb" From f2ff8155ad78e601e8736ad68e5c3a18b20d22e6 Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Thu, 28 Sep 2023 10:13:11 -0400 Subject: [PATCH 21/35] Update Rule: Update link_credential_phishing_voicemail_language.yml (#822) --- ...credential_phishing_voicemail_language.yml | 94 +++++++++++-------- 1 file changed, 53 insertions(+), 41 deletions(-) diff --git a/detection-rules/link_credential_phishing_voicemail_language.yml b/detection-rules/link_credential_phishing_voicemail_language.yml index a5eb16d114e..e9259e4983a 100644 --- a/detection-rules/link_credential_phishing_voicemail_language.yml +++ b/detection-rules/link_credential_phishing_voicemail_language.yml @@ -1,57 +1,69 @@ name: "Fake voicemail notification (unsolicited)" description: | This rule detects a common credential phishing vector enticing the user to engage with links under the premise that they have a voicemail to retrieve. - The rule ensures at least a single link is present with either voicemail in the display name, body, subject or a combination of those elements with a medium to high credential theft NLU Intent from an unsolicited sender. + The rule looks for voicemail verbiage in the display name, body, subject or a combination of those elements with emojis or a medium to high credential theft NLU Intent from an unsolicited sender. type: "rule" severity: "medium" source: | type.inbound - and length(body.links) > 0 - + and length(body.links) < 5 // voicemail related and ( - regex.icontains(body.current_thread.text, 'voice\s?(mail|message|recording|call)') - or (regex.icontains(subject.subject, 'voice\s?(mail|message|recording|call)')) - ) - and 2 of ( - ( - any(ml.nlu_classifier(body.current_thread.text).intents, - .name in ("cred_theft") and .confidence in ("medium", "high") - ) - ), - (regex.icontains(sender.display_name, 'voice\s?(mail|message|recording|call)')), - ( - // sender domain matches no body domains - all(body.links, - .href_url.domain.root_domain != sender.email.domain.root_domain - and .href_url.domain.root_domain not in $org_domains - and .href_url.domain.root_domain not in ( - "unitelvoice.com", - "googleapis.com", - "dialmycalls.com" - ) - ) - ), - ( - // recipient's SLD is in the sender's display name - any(recipients.to, strings.icontains(sender.display_name, .email.domain.sld)) - ), + any([subject.subject, sender.display_name, ], + regex.icontains(., '(voice)\s?(mail|message|recording|call)|transcription') + or regex.contains(body.current_thread.text, '(voice)\s?(mail|message|recording|call)') + ) ) - and sender.email.domain.root_domain not in ("magicjack.com", "unitelvoice.com") - - // negating legit replies - and not ( - ( - strings.istarts_with(subject.subject, "RE:") - // out of office auto-reply - // the NLU model will handle these better natively soon - or strings.istarts_with(subject.subject, "Automatic reply:") + and 2 of ( + ( + any(ml.nlu_classifier(body.current_thread.text).intents, + .name in ("cred_theft") and .confidence in ("medium", "high") + ) + ), + (regex.icontains(sender.display_name, 'voice\s?(mail|message|recording|call|transcription)')), + ( + // sender domain matches no body domains + all(body.links, + .href_url.domain.root_domain != sender.email.domain.root_domain + and .href_url.domain.root_domain not in $org_domains + and .href_url.domain.root_domain not in ( + "unitelvoice.com", + "googleapis.com", + "dialmycalls.com" + ) + ) + ), + ( + // recipient's SLD is in the sender's display name + any(recipients.to, strings.icontains(sender.display_name, .email.domain.sld)) + ), + ( + any([sender.display_name, subject.subject, body.current_thread.text], + regex.contains(., + '[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}]' + ) + ) + ), ) and ( - length(headers.references) > 0 - or any(headers.hops, any(.fields, strings.ilike(.name, "In-Reply-To"))) + sender.email.domain.root_domain not in ("magicjack.com", "unitelvoice.com", "voipinterface.net") + or not any(attachments, strings.starts_with(.content_type, "audio")) ) - ) + + // negating legit replies + and not ( + ( + strings.istarts_with(subject.subject, "RE:") + // out of office auto-reply + // the NLU model will handle these better natively soon + or strings.istarts_with(subject.subject, "Automatic reply:") + ) + and ( + length(headers.references) > 0 + or any(headers.hops, any(.fields, strings.ilike(.name, "In-Reply-To"))) + ) + ) + and ( ( sender.email.domain.root_domain in $free_email_providers From 9062c5475aa464846c987ac941e86b7f6e466189 Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Thu, 28 Sep 2023 13:04:06 -0400 Subject: [PATCH 22/35] New Rule: QR code with credential phishing indicators (#827) Co-authored-by: ID Generator Co-authored-by: Josh Kamdjou --- ...tachment_qr_code_suspicious_components.yml | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 detection-rules/attachment_qr_code_suspicious_components.yml diff --git a/detection-rules/attachment_qr_code_suspicious_components.yml b/detection-rules/attachment_qr_code_suspicious_components.yml new file mode 100644 index 00000000000..bb2a94dfca4 --- /dev/null +++ b/detection-rules/attachment_qr_code_suspicious_components.yml @@ -0,0 +1,83 @@ +name: "Attachment: QR code with credential phishing indicators" +description: | + Detects messages with between 1-3 attachments containing a QR code with suspicious credential theft indicators, such as: LinkAnalysis credential phishing conclusion, decoded QR code url traverses suspicious infrastructure, the final destination is in URLhaus, decoded URL downloads a zip or executable, leverages URL shorteners, known QR abused openredirects, and more. +type: "rule" +severity: "high" +source: | + type.inbound + and 1 <= length(attachments) < 3 + + // Inspects image attachments for QR codes + and any(attachments, + .file_type in $file_types_images + and ( + any(file.explode(.), + .scan.qr.type == "url" + and ( + // pass the QR URL to LinkAnalysis + any([beta.linkanalysis(.scan.qr.url)], + .credphish.disposition == "phishing" + + // any routing traverses via $suspicious_tld list + or any(.redirect_history, .domain.tld in $suspicious_tlds) + + // effective destination in $suspicious_tld list + or .effective_url.domain.tld in $suspicious_tlds + + // or the effective destination domain is in $abuse_ch_urlhaus_domains_trusted_reporters + or .effective_url.domain.root_domain in $abuse_ch_urlhaus_domains_trusted_reporters + + // or any files downloaded are zips or executables + or any(.files_downloaded, + .file_extension in $file_extensions_common_archives + or .file_extension in $file_extensions_executables + ) + ) + or ( + + // or the QR code's root domain is a url_shortener + .scan.qr.url.domain.root_domain in $url_shorteners + + // exclude google maps + and not strings.starts_with(.scan.qr.url.url, 'https://goo.gl/maps') + ) + + // the QR code url is a bing open redirect + or .scan.qr.url.domain.root_domain == 'bing.com' and .scan.qr.url.path =~ '/ck/a' + or ( + + // usap-dc open redirect + .scan.qr.url.domain.root_domain == "usap-dc.org" + and .scan.qr.url.path =~ "/tracker" + and strings.starts_with(.scan.qr.url.query_params, "type=dataset&url=http") + ) + ) + ) + ) + ) + + // first time sender + and ( + ( + sender.email.domain.root_domain in $free_email_providers + and sender.email.email not in $sender_emails + ) + or ( + sender.email.domain.root_domain not in $free_email_providers + and sender.email.domain.domain not in $sender_domains + ) + ) +attack_types: + - "Credential Phishing" +tactics_and_techniques: + - "QR code" + - "Social engineering" +detection_methods: + - "Computer Vision" + - "Header analysis" + - "Natural Language Understanding" + - "QR code analysis" + - "Sender analysis" + - "URL analysis" + - "URL screenshot" +id: "9f1681e1-8c15-5edd-9aaa-eb5af1729322" From 8d5066193de13c73434eac8f05cd747499831dbb Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Fri, 29 Sep 2023 10:51:25 -0400 Subject: [PATCH 23/35] New Insight - QR code in attachments (#830) --- insights/attachments/links_qr_code.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 insights/attachments/links_qr_code.yml diff --git a/insights/attachments/links_qr_code.yml b/insights/attachments/links_qr_code.yml new file mode 100644 index 00000000000..b66dc2d74f7 --- /dev/null +++ b/insights/attachments/links_qr_code.yml @@ -0,0 +1,7 @@ +name: "QR code in attachments" +type: "query" +source: | + map(filter(attachments, .file_type in $file_types_images or .file_type == "pdf"), + map(filter(file.explode(.), .scan.qr.type == "url"), .scan.qr.url.url) + ) +severity: "medium" From 87ff06de675c957c0a6cbc8cb075423045eee05d Mon Sep 17 00:00:00 2001 From: Cameron Dunn Date: Mon, 2 Oct 2023 09:26:17 -0700 Subject: [PATCH 24/35] Prefix file path with source/ (#833) --- .github/workflows/update-test-rules.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-test-rules.yml b/.github/workflows/update-test-rules.yml index 9e67a0863ca..1fa24a4adb3 100644 --- a/.github/workflows/update-test-rules.yml +++ b/.github/workflows/update-test-rules.yml @@ -123,7 +123,7 @@ jobs: # If multiple PRs modify the same file, only one can be tested. This is solveable, but not something we see often. for file in $files_changed; do # Skip any LA rules. We'll ignore these downstream anyway, but best to keep the branch clean. - la_count=$(grep -c 'beta.linkanalysis' $file || true) + la_count=$(grep -c 'beta.linkanalysis' source/$file || true) if [[ "$la_count" != '0' ]]; then continue fi From cd5a99ed852df0d5e49fd4d244ef5be72b429f52 Mon Sep 17 00:00:00 2001 From: Cameron Dunn Date: Mon, 2 Oct 2023 12:19:35 -0700 Subject: [PATCH 25/35] Request max page size for update-test-rules (#834) --- .github/workflows/update-test-rules.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/update-test-rules.yml b/.github/workflows/update-test-rules.yml index 1fa24a4adb3..4ca584c97f1 100644 --- a/.github/workflows/update-test-rules.yml +++ b/.github/workflows/update-test-rules.yml @@ -104,12 +104,13 @@ jobs: done # This workflow is trigerred from an issue comment so we don't automatically have context on what changed in the PR + # TODO: We can only retrieve 100 results, we need to add pagination support. curl -L \ -o pr_files.json \ -H "Accept: application/vnd.github+json" \ -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"\ -H "X-GitHub-Api-Version: 2022-11-28" \ - https://api.github.com/repos/sublime-security/sublime-rules/pulls/$pr_num/files + https://api.github.com/repos/sublime-security/sublime-rules/pulls/$pr_num/files?per_page=100 # Any files added/changed/modified will be copied to test-rules files_changed=$(jq -r '.[] | select(.status == "added" or .status == "modified" or .status == "changed") | .filename' pr_files.json) @@ -125,6 +126,7 @@ jobs: # Skip any LA rules. We'll ignore these downstream anyway, but best to keep the branch clean. la_count=$(grep -c 'beta.linkanalysis' source/$file || true) if [[ "$la_count" != '0' ]]; then + echo "Ignoring $file because of linkanalysis usage" continue fi From d33fb374b71485ffc0a3a9089820a26e2c67bbd7 Mon Sep 17 00:00:00 2001 From: Cameron Dunn Date: Mon, 2 Oct 2023 14:47:06 -0700 Subject: [PATCH 26/35] MQL Mimic: Change to PR CI, detect changes (#828) --- .github/workflows/mql-mimic-tests.yml | 40 --------------------- .github/workflows/rule-validate.yml | 51 +++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 40 deletions(-) delete mode 100644 .github/workflows/mql-mimic-tests.yml diff --git a/.github/workflows/mql-mimic-tests.yml b/.github/workflows/mql-mimic-tests.yml deleted file mode 100644 index de506e94e80..00000000000 --- a/.github/workflows/mql-mimic-tests.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: MQL Mimic Tests - -on: - push: - branches: [ "**" ] - -concurrency: - group: ${{ github.ref }} - cancel-in-progress: true - -jobs: - trigger-via-zapier: - name: Trigger Test Run - runs-on: ubuntu-20.04 - permissions: - checks: write - - steps: - - - name: "Trigger MQL Mimic Tests" - env: - trigger_url: '${{ secrets.MQL_MOCK_TRIGGER }}' - branch: '${{ github.ref_name }}' - repo: '${{ github.repository }}' - token: '${{ secrets.GITHUB_TOKEN }}' - sha: '${{ github.sha }}' - run: | - curl -X POST $trigger_url \ - -H 'Content-Type: application/json' \ - -d '{"branch":"'$branch'","repo":"'$repo'","token":"'$token'","sha":"'$sha'"}' - - - name: Wait for check to be completed - uses: fountainhead/action-wait-for-check@v1.1.0 - id: wait-for-build - # Wait for results so that the token remains valid while the test suite is executing and posting a check here. - with: - token: ${{ secrets.GITHUB_TOKEN }} - checkName: "MQL Mimic Tests" - ref: ${{ github.sha }} - timeoutSeconds: 3600 diff --git a/.github/workflows/rule-validate.yml b/.github/workflows/rule-validate.yml index 78efe60f6dc..dc15f63eeba 100644 --- a/.github/workflows/rule-validate.yml +++ b/.github/workflows/rule-validate.yml @@ -30,6 +30,7 @@ jobs: with: ref: ${{ github.head_ref }} repository: ${{ github.event.pull_request.head.repo.full_name }} + depth: 0 - uses: actions/setup-python@v4 with: @@ -92,6 +93,45 @@ jobs: id: get_head run: echo "##[set-output name=HEAD;]$(git rev-parse HEAD)" + - name: Get changed detection-rules + id: changed-files + uses: tj-actions/changed-files@v39 + with: + files: "detection-rules/**" + recover_deleted_files: true + + - name: "Find updated rule IDs" + id: find_ids + run: | + for file in ${{ steps.changed-files.outputs.all_changed_and_modified_files }}; do + echo "$file was changed" + rule_id=$(yq '.id' $file) + + echo "$file has rule ID $rule_id" + altered_rule_ids=$(echo "$rule_id"" ""$altered_rule_ids") + done + + echo "Altered Ruled IDs: [$altered_rule_ids]" + echo "##[set-output name=rule_ids;]$(echo $altered_rule_ids)" + # TODO: This doesn't solve for a modified rule_id. We could merge with any files known on 'main', but changing + # a rule ID is a separate problem. + + - name: "Trigger MQL Mimic Tests" + env: + trigger_url: '${{ secrets.MQL_MOCK_TRIGGER }}' + branch: ${{ github.event_name == 'pull_request_target' && github.head_ref || github.ref }} + repo: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.full_name || github.repository }} + token: '${{ secrets.GITHUB_TOKEN }}' + sha: '${{ steps.get_head.outputs.HEAD }}' + only_rule_ids: '${{ steps.find_ids.outputs.rule_ids }}' + run: | + body='{"branch":"'$branch'","repo":"'$repo'","token":"'$token'","sha":"'$sha'","only_rule_ids":"'$only_rule_ids'"}' + echo $body + + curl -X POST $trigger_url \ + -H 'Content-Type: application/json' \ + -d "$body" + # When we add a commit, GitHub won't trigger actions on the auto commit, so we're missing a required check on the # HEAD commit. # Various alternatives were explored, but all run into issues when dealing with forks. This sets a "Check" for @@ -126,3 +166,14 @@ jobs: text: "Rule Tests and ID Updated", }, }); + + - name: Wait for MQL Mimic check to be completed + uses: fountainhead/action-wait-for-check@v1.1.0 + id: wait-for-build + # Wait for results so that the token remains valid while the test suite is executing and posting a check here. + with: + token: ${{ secrets.GITHUB_TOKEN }} + checkName: "MQL Mimic Tests" + ref: ${{ steps.get_head.outputs.HEAD }} + timeoutSeconds: 3600 + From d53efda124e0c36c12b1b141371ebe91fd74fa3c Mon Sep 17 00:00:00 2001 From: Bobby Filar <29960025+bfilar@users.noreply.github.com> Date: Mon, 2 Oct 2023 18:53:44 -0500 Subject: [PATCH 27/35] Signal: Hidden text/0-pixel font (#835) --- signals/content/body_hidden_text.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 signals/content/body_hidden_text.yml diff --git a/signals/content/body_hidden_text.yml b/signals/content/body_hidden_text.yml new file mode 100644 index 00000000000..93edbc61088 --- /dev/null +++ b/signals/content/body_hidden_text.yml @@ -0,0 +1,4 @@ +name: "Content: Hidden text/0-pixel font" +type: "query" +source: | + regex.icontains(body.html.raw, 'font-size: ?0\b') From 19e287401bccd1f921966673710ea04c094e5068 Mon Sep 17 00:00:00 2001 From: Josh Kamdjou Date: Tue, 3 Oct 2023 16:10:01 -0400 Subject: [PATCH 28/35] Signals: New link and sender domains (#818) Co-authored-by: Bobby Filar Co-authored-by: Bobby Filar <29960025+bfilar@users.noreply.github.com> --- signals/links/link_new_domain_L14D.yml | 4 ++++ signals/links/link_new_domain_L3D.yml | 4 ++++ signals/sender/sender_new_domain_L14D.yml | 4 ++++ signals/sender/sender_new_domain_L3D.yml | 4 ++++ 4 files changed, 16 insertions(+) create mode 100644 signals/links/link_new_domain_L14D.yml create mode 100644 signals/links/link_new_domain_L3D.yml create mode 100644 signals/sender/sender_new_domain_L14D.yml create mode 100644 signals/sender/sender_new_domain_L3D.yml diff --git a/signals/links/link_new_domain_L14D.yml b/signals/links/link_new_domain_L14D.yml new file mode 100644 index 00000000000..0ab79efa571 --- /dev/null +++ b/signals/links/link_new_domain_L14D.yml @@ -0,0 +1,4 @@ +name: "Link: Domain registered less than 14 days ago" +type: "query" +source: | + length(filter(body.links, beta.whois(.href_url.domain).days_old < 14)) diff --git a/signals/links/link_new_domain_L3D.yml b/signals/links/link_new_domain_L3D.yml new file mode 100644 index 00000000000..781b9016866 --- /dev/null +++ b/signals/links/link_new_domain_L3D.yml @@ -0,0 +1,4 @@ +name: "Link: Domain registered less than 3 days ago" +type: "query" +source: | + length(filter(body.links, beta.whois(.href_url.domain).days_old < 3)) diff --git a/signals/sender/sender_new_domain_L14D.yml b/signals/sender/sender_new_domain_L14D.yml new file mode 100644 index 00000000000..404e3a3cb21 --- /dev/null +++ b/signals/sender/sender_new_domain_L14D.yml @@ -0,0 +1,4 @@ +name: "Sender: Domain registered less than 14 days ago" +type: "query" +source: | + beta.whois(sender.email.domain).days_old < 14 diff --git a/signals/sender/sender_new_domain_L3D.yml b/signals/sender/sender_new_domain_L3D.yml new file mode 100644 index 00000000000..05a1649b3cb --- /dev/null +++ b/signals/sender/sender_new_domain_L3D.yml @@ -0,0 +1,4 @@ +name: "Sender: Domain registered less than 3 days ago" +type: "query" +source: | + beta.whois(sender.email.domain).days_old < 3 From 8fa73134983726b0db5258030487082b1c2eb236 Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Tue, 3 Oct 2023 13:50:39 -0700 Subject: [PATCH 29/35] Updating Rule: Marking as ASR (#787) --- detection-rules/recipients_undisclosed_free_subdomain_host.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/detection-rules/recipients_undisclosed_free_subdomain_host.yml b/detection-rules/recipients_undisclosed_free_subdomain_host.yml index 0554bc90112..b66cf12cb3c 100644 --- a/detection-rules/recipients_undisclosed_free_subdomain_host.yml +++ b/detection-rules/recipients_undisclosed_free_subdomain_host.yml @@ -31,6 +31,8 @@ source: | and sender.email.domain.domain not in $sender_domains ) ) +tags: + - "Attack surface reduction" tactics_and_techniques: - "Free subdomain host" detection_methods: From 1ee74aece7581953caac16d34a3b3cca357cfc2d Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Tue, 3 Oct 2023 14:00:52 -0700 Subject: [PATCH 30/35] Updating rule: attachment_free_subdomain_suspicious_link_language.yml (#767) --- .../attachment_free_subdomain_suspicious_link_language.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detection-rules/attachment_free_subdomain_suspicious_link_language.yml b/detection-rules/attachment_free_subdomain_suspicious_link_language.yml index 11fa2309c25..628ae4b8c27 100644 --- a/detection-rules/attachment_free_subdomain_suspicious_link_language.yml +++ b/detection-rules/attachment_free_subdomain_suspicious_link_language.yml @@ -15,7 +15,7 @@ source: | and length(recipients.bcc) == 0 and any(body.links, any(file.explode(beta.linkanalysis(.).screenshot), - any(ml.nlu_classifier(.scan.ocr.raw).intents, .name == "cred_theft") + any(ml.nlu_classifier(.scan.ocr.raw).intents, .name == "cred_theft" and .confidence != "low") ) ) attack_types: From 254c6cb884899bc450da1191a5f24d709f28eef4 Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Tue, 3 Oct 2023 14:01:54 -0700 Subject: [PATCH 31/35] Updating Rule: attachment_docusign_image_suspicious_links.yml (#761) Co-authored-by: Sam Scholten --- ...chment_docusign_image_suspicious_links.yml | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/detection-rules/attachment_docusign_image_suspicious_links.yml b/detection-rules/attachment_docusign_image_suspicious_links.yml index 514b82554c1..32fae6b6654 100644 --- a/detection-rules/attachment_docusign_image_suspicious_links.yml +++ b/detection-rules/attachment_docusign_image_suspicious_links.yml @@ -27,12 +27,23 @@ source: | ) and ( ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails + ( + sender.email.domain.root_domain in $free_email_providers + and sender.email.email not in $sender_emails + ) + or ( + sender.email.domain.root_domain not in $free_email_providers + and sender.email.domain.domain not in $sender_domains + ) ) or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + sender.email.email in $sender_emails + and any(distinct(headers.hops, .received_spf.verdict is not null), + regex.icontains(.received_spf.verdict, "fail|error") + or any(distinct(headers.hops, .authentication_results.dmarc is not null), + strings.ilike(.authentication_results.dmarc, "*fail") + ) + ) ) ) attack_types: From 8369b78f608d6f23f281372edb1552c980dc6b14 Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Wed, 4 Oct 2023 10:46:56 -0700 Subject: [PATCH 32/35] Updating rule: attachment_microsoft_image_lure_qr_code.yml (#812) Co-authored-by: Sam Scholten --- .../attachment_microsoft_image_lure_qr_code.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/detection-rules/attachment_microsoft_image_lure_qr_code.yml b/detection-rules/attachment_microsoft_image_lure_qr_code.yml index 7b024a35f89..8ad0f0d1947 100644 --- a/detection-rules/attachment_microsoft_image_lure_qr_code.yml +++ b/detection-rules/attachment_microsoft_image_lure_qr_code.yml @@ -7,13 +7,18 @@ source: | type.inbound and ( any(attachments, - .file_type in $file_types_images + (.file_type in $file_types_images or .file_type == "pdf") and any(ml.logo_detect(.).brands, strings.starts_with(.name, "Microsoft")) ) or any(ml.logo_detect(beta.message_screenshot()).brands, strings.starts_with(.name, "Microsoft")) + or (any(attachments, .file_type in~ $file_extensions_macros)) ) and any(attachments, - .file_type in $file_types_images + ( + .file_type in $file_types_images + or .file_type == "pdf" + or .file_type in $file_extensions_macros + ) and ( any(file.explode(.), regex.icontains(.scan.ocr.raw, 'scan|camera') @@ -72,6 +77,7 @@ attack_types: - "Credential Phishing" tactics_and_techniques: - "Impersonation: Brand" + - "PDF" - "QR code" - "Social engineering" detection_methods: From 9b20913cebe372cfc883546dc2a94f692ace38c6 Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Wed, 4 Oct 2023 18:39:28 -0400 Subject: [PATCH 33/35] Sender Profiles: Prevalence and Past behavior (#815) Co-authored-by: Cameron Dunn Co-authored-by: Josh Kamdjou --- .../attachment_adobe_image_lure_fts.yml | 9 +++----- ...chment_any_html_in_archive_unsolicited.yml | 9 +++----- .../attachment_any_html_new_sender.yml | 11 +++------- .../attachment_any_html_unsolicited.yml | 11 +++------- .../attachment_callback_phish_with_img.yml | 9 +++----- .../attachment_callback_phish_with_pdf.yml | 9 +++----- ...chment_docusign_image_suspicious_links.yml | 21 ++++--------------- ...achment_dropbox_image_suspicious_links.yml | 9 +++----- detection-rules/attachment_eml_cred_theft.yml | 11 +++------- .../attachment_eml_with_html_attachment.yml | 11 +++------- ...hment_emotet_heavily_padded_doc_in_zip.yml | 9 +++----- .../attachment_encrypted_ole_unsolicited.yml | 9 +++----- .../attachment_html_attachment_login_page.yml | 10 +++------ ...ment_html_smuggling_double_encoded_zip.yml | 9 +++----- ...chment_html_smuggling_microsoft_signin.yml | 9 +++----- .../attachment_js_file_execution.yml | 10 +++------ detection-rules/attachment_malwarebazaar.yml | 9 +++----- .../attachment_mht_embedded_vbscript.yml | 11 +++------- ...ttachment_microsoft_image_lure_qr_code.yml | 10 +++------ .../attachment_office365_image.yml | 10 +++------ ...nt_office_file_relationship_cred_theft.yml | 9 +++----- .../attachment_pdf_link_to_dmg.yml | 12 +++-------- ...pdf_linking_to_password_protected_file.yml | 9 +++----- ...ow_reputation_link_to_suspicious_files.yml | 10 +++------ ...f_with_low_reputation_link_to_zip_file.yml | 10 +++------ ...tachment_qr_code_suspicious_components.yml | 2 -- .../attachment_soliciting_enable_macros.yml | 9 +++----- ...suspicious_vba_macro_first_time_sender.yml | 9 +++----- .../attachment_svg_embedded_js.yml | 11 +++------- ...chment_vba_macro_auto_exec_unsolicited.yml | 9 +++----- ...chment_vba_macro_auto_open_unsolicited.yml | 9 +++----- ...hment_vba_macro_employee_impersonation.yml | 9 +++----- .../attachment_vba_macro_high_risk.yml | 9 +++----- ...achment_with_encrypted_zip_unsolicited.yml | 9 +++----- ...ent_with_suspicious_author_unsolicited.yml | 9 +++----- ...with_unknown_encrypted_zip_unsolicited.yml | 9 +++----- ...y_business_email_compromise_new_sender.yml | 10 +++------ ..._business_email_compromise_unsolicited.yml | 11 +++------- .../body_callback_phishing_no_attachment.yml | 9 +++----- detection-rules/body_job_scam_new_sender.yml | 9 +++----- ...lback_phishing_nlu_body_or_attachments.yml | 9 +++----- ...ing_link_from_suspicious_sender_domain.yml | 9 +++----- .../file_sharing_link_suspicious_subject.yml | 9 +++----- ...d_recipients_no_links_freemail_replyto.yml | 9 +++----- ...headers_replyto_new_domain_nlu_request.yml | 11 +++------- .../headers_russia_return_path.yml | 9 +++----- .../impersonation_amazon_suspicious_text.yml | 10 +++------ detection-rules/impersonation_barracuda.yml | 14 +++++-------- detection-rules/impersonation_chase.yml | 13 +++++------- detection-rules/impersonation_dhl.yml | 10 +++------ detection-rules/impersonation_docusign.yml | 10 +++------ .../impersonation_employee_payroll_fraud.yml | 9 +++----- .../impersonation_employee_subject.yml | 10 +++------ .../impersonation_employee_urgent_request.yml | 11 +++------- ...hread_mismatched_from_freemail_replyto.yml | 11 +++------- detection-rules/impersonation_finra.yml | 11 +++------- detection-rules/impersonation_github.yml | 9 +++----- .../impersonation_human_resources.yml | 9 +++----- detection-rules/impersonation_microsoft.yml | 11 +++------- detection-rules/impersonation_paypal.yml | 11 +++------- .../impersonation_recipient_domain.yml | 10 +++------ ...tion_recipient_sld_in_sender_local_fts.yml | 9 +++----- detection-rules/impersonation_ripple.yml | 9 +++----- detection-rules/impersonation_spotify.yml | 10 +++------ detection-rules/impersonation_stellar.yml | 9 +++----- .../impersonation_sublime_security.yml | 10 +++------ .../impersonation_vip_urgent_request.yml | 10 +++------ detection-rules/inline_image_as_message.yml | 9 +++----- detection-rules/link_credential_phishing.yml | 10 +++------ ...l_phishing_intent_and_other_indicators.yml | 11 +++------- ...ink_credential_phishing_secure_message.yml | 11 +++------- ...hing_suspicious_sender_tld_and_signals.yml | 10 +++------ ...credential_phishing_voicemail_language.yml | 9 +++----- ...k_download_disk_image_in_encrypted_zip.yml | 10 +++------ .../link_download_suspicious_file.yml | 10 +++------ .../link_fake_fax_low_reputation.yml | 11 +++------- .../link_google_apps_script_macro.yml | 10 +++------ detection-rules/link_google_translate.yml | 9 +++----- ...ink_html_smuggling_with_adobe_branding.yml | 10 +++------ ...l_smuggling_with_google_drive_branding.yml | 10 +++------ ..._fake_customer_service_freemail_sender.yml | 1 - detection-rules/link_ipfs_phishing.yml | 10 +++------ detection-rules/link_login_or_captcha.yml | 11 +++------- .../link_microsoft_device_code_phish.yml | 11 +++------- ...crosoft_impersonation_using_hosted_png.yml | 11 +++------- ...k_new_domain_in_link_first_time_sender.yml | 9 +++----- detection-rules/link_notion_file_share.yml | 11 +++------- .../link_qr_code_suspicious_language_fts.yml | 10 +++------ ...icious_language_undisclosed_recipients.yml | 10 +++------ ..._campaign_recipient_address_new_sender.yml | 11 +++------- detection-rules/open_redirect_avast.yml | 9 +++----- ...pients_undisclosed_free_subdomain_host.yml | 9 +++----- ...nder_new_from_domain_first_time_sender.yml | 9 +++----- ...n_excessive_display_text_with_keywords.yml | 10 +++------ detection-rules/spam_new_domain_emojis.yml | 11 +++------- detection-rules/spam_url_shortener_emojis.yml | 11 +++------- ...impersonation_attack_surface_reduction.yml | 20 ++++++------------ 97 files changed, 293 insertions(+), 672 deletions(-) diff --git a/detection-rules/attachment_adobe_image_lure_fts.yml b/detection-rules/attachment_adobe_image_lure_fts.yml index 78125362de3..1c222cd97d9 100644 --- a/detection-rules/attachment_adobe_image_lure_fts.yml +++ b/detection-rules/attachment_adobe_image_lure_fts.yml @@ -20,13 +20,10 @@ source: | ) ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/attachment_any_html_in_archive_unsolicited.yml b/detection-rules/attachment_any_html_in_archive_unsolicited.yml index ddf0659e54e..f7ab205f57a 100644 --- a/detection-rules/attachment_any_html_in_archive_unsolicited.yml +++ b/detection-rules/attachment_any_html_in_archive_unsolicited.yml @@ -14,13 +14,10 @@ source: | and any(file.explode(.), .depth > 0 and .file_extension in~ ("html", "htm")) ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: diff --git a/detection-rules/attachment_any_html_new_sender.yml b/detection-rules/attachment_any_html_new_sender.yml index cc22e73e915..117804f24ce 100644 --- a/detection-rules/attachment_any_html_new_sender.yml +++ b/detection-rules/attachment_any_html_new_sender.yml @@ -11,16 +11,11 @@ severity: "medium" source: | type.inbound and any(attachments, .file_extension in~ ('htm', 'html') or .file_type == "html") - - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: diff --git a/detection-rules/attachment_any_html_unsolicited.yml b/detection-rules/attachment_any_html_unsolicited.yml index 075feda5569..c5549895fd3 100644 --- a/detection-rules/attachment_any_html_unsolicited.yml +++ b/detection-rules/attachment_any_html_unsolicited.yml @@ -11,16 +11,11 @@ severity: "low" source: | type.inbound and any(attachments, .file_extension in~ ('htm', 'html') or .file_type == "html") - - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: diff --git a/detection-rules/attachment_callback_phish_with_img.yml b/detection-rules/attachment_callback_phish_with_img.yml index e9ce44623c7..19c4f46b120 100644 --- a/detection-rules/attachment_callback_phish_with_img.yml +++ b/detection-rules/attachment_callback_phish_with_img.yml @@ -10,13 +10,10 @@ severity: "high" source: | type.inbound and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) and sender.email.domain.root_domain in $free_email_providers diff --git a/detection-rules/attachment_callback_phish_with_pdf.yml b/detection-rules/attachment_callback_phish_with_pdf.yml index 1b6f24a320b..e707ca72c80 100644 --- a/detection-rules/attachment_callback_phish_with_pdf.yml +++ b/detection-rules/attachment_callback_phish_with_pdf.yml @@ -8,13 +8,10 @@ severity: "high" source: | type.inbound and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) diff --git a/detection-rules/attachment_docusign_image_suspicious_links.yml b/detection-rules/attachment_docusign_image_suspicious_links.yml index 32fae6b6654..7d802543568 100644 --- a/detection-rules/attachment_docusign_image_suspicious_links.yml +++ b/detection-rules/attachment_docusign_image_suspicious_links.yml @@ -26,24 +26,11 @@ source: | ) ) and ( - ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) - or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains - ) - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.email in $sender_emails - and any(distinct(headers.hops, .received_spf.verdict is not null), - regex.icontains(.received_spf.verdict, "fail|error") - or any(distinct(headers.hops, .authentication_results.dmarc is not null), - strings.ilike(.authentication_results.dmarc, "*fail") - ) - ) + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives + ) ) attack_types: diff --git a/detection-rules/attachment_dropbox_image_suspicious_links.yml b/detection-rules/attachment_dropbox_image_suspicious_links.yml index 1de0a856b31..478744466bc 100644 --- a/detection-rules/attachment_dropbox_image_suspicious_links.yml +++ b/detection-rules/attachment_dropbox_image_suspicious_links.yml @@ -14,13 +14,10 @@ source: | ) ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/attachment_eml_cred_theft.yml b/detection-rules/attachment_eml_cred_theft.yml index a85a54f7777..d3b647aa504 100644 --- a/detection-rules/attachment_eml_cred_theft.yml +++ b/detection-rules/attachment_eml_cred_theft.yml @@ -29,16 +29,11 @@ source: | and not any(attachments, .content_type == "message/delivery-status") // if the "References" is in the body of the message, it's probably a bounce and not any(headers.references, strings.contains(body.html.display_text, .)) - - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/attachment_eml_with_html_attachment.yml b/detection-rules/attachment_eml_with_html_attachment.yml index 68fac95489f..f719bf69097 100644 --- a/detection-rules/attachment_eml_with_html_attachment.yml +++ b/detection-rules/attachment_eml_with_html_attachment.yml @@ -40,16 +40,11 @@ source: | and not any(attachments, .content_type == "message/delivery-status") // if the "References" is in the body of the message, it's probably a bounce and not any(headers.references, strings.contains(body.html.display_text, .)) - - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: diff --git a/detection-rules/attachment_emotet_heavily_padded_doc_in_zip.yml b/detection-rules/attachment_emotet_heavily_padded_doc_in_zip.yml index b23bcff7ba2..0f1e36c18ac 100644 --- a/detection-rules/attachment_emotet_heavily_padded_doc_in_zip.yml +++ b/detection-rules/attachment_emotet_heavily_padded_doc_in_zip.yml @@ -19,13 +19,10 @@ source: | ) ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: diff --git a/detection-rules/attachment_encrypted_ole_unsolicited.yml b/detection-rules/attachment_encrypted_ole_unsolicited.yml index 6e591479b56..10df0004afc 100644 --- a/detection-rules/attachment_encrypted_ole_unsolicited.yml +++ b/detection-rules/attachment_encrypted_ole_unsolicited.yml @@ -13,13 +13,10 @@ source: | and file.oletools(.).indicators.encryption.exists ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/attachment_html_attachment_login_page.yml b/detection-rules/attachment_html_attachment_login_page.yml index 6f720efda3f..0f513c19103 100644 --- a/detection-rules/attachment_html_attachment_login_page.yml +++ b/detection-rules/attachment_html_attachment_login_page.yml @@ -68,15 +68,11 @@ source: | ) ) ) - // Unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/attachment_html_smuggling_double_encoded_zip.yml b/detection-rules/attachment_html_smuggling_double_encoded_zip.yml index d1d56ea9890..0d7374033c7 100644 --- a/detection-rules/attachment_html_smuggling_double_encoded_zip.yml +++ b/detection-rules/attachment_html_smuggling_double_encoded_zip.yml @@ -13,13 +13,10 @@ authors: source: | type.inbound and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) and any(attachments, diff --git a/detection-rules/attachment_html_smuggling_microsoft_signin.yml b/detection-rules/attachment_html_smuggling_microsoft_signin.yml index 5bc76594293..ec988219191 100644 --- a/detection-rules/attachment_html_smuggling_microsoft_signin.yml +++ b/detection-rules/attachment_html_smuggling_microsoft_signin.yml @@ -25,13 +25,10 @@ source: | ) ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) // allow Microsoft domains just to be safe diff --git a/detection-rules/attachment_js_file_execution.yml b/detection-rules/attachment_js_file_execution.yml index 642e8a53016..788d141ed21 100644 --- a/detection-rules/attachment_js_file_execution.yml +++ b/detection-rules/attachment_js_file_execution.yml @@ -15,15 +15,11 @@ source: | ) ) ) - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: diff --git a/detection-rules/attachment_malwarebazaar.yml b/detection-rules/attachment_malwarebazaar.yml index 96091611291..b8b6025bcd1 100644 --- a/detection-rules/attachment_malwarebazaar.yml +++ b/detection-rules/attachment_malwarebazaar.yml @@ -6,13 +6,10 @@ source: | type.inbound and any(attachments, .sha256 in $abuse_ch_malwarebazaar_sha256_trusted_reporters) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: diff --git a/detection-rules/attachment_mht_embedded_vbscript.yml b/detection-rules/attachment_mht_embedded_vbscript.yml index dd75945472b..7820e2b3caa 100644 --- a/detection-rules/attachment_mht_embedded_vbscript.yml +++ b/detection-rules/attachment_mht_embedded_vbscript.yml @@ -14,16 +14,11 @@ source: | and any(file.explode(.), .file_extension =~ "mht") and any(file.explode(.), any(.scan.html.scripts, .language == "VBScript")) ) - - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/attachment_microsoft_image_lure_qr_code.yml b/detection-rules/attachment_microsoft_image_lure_qr_code.yml index 8ad0f0d1947..f130fcdcaaa 100644 --- a/detection-rules/attachment_microsoft_image_lure_qr_code.yml +++ b/detection-rules/attachment_microsoft_image_lure_qr_code.yml @@ -61,15 +61,11 @@ source: | and sender.email.domain.domain == "microsoft.com" ) ) - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) diff --git a/detection-rules/attachment_office365_image.yml b/detection-rules/attachment_office365_image.yml index 012788a6b7a..9622f79a11f 100644 --- a/detection-rules/attachment_office365_image.yml +++ b/detection-rules/attachment_office365_image.yml @@ -54,15 +54,11 @@ source: | and sender.email.domain.domain in ("microsoft.com", "sharepointonline.com") ) ) - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/attachment_office_file_relationship_cred_theft.yml b/detection-rules/attachment_office_file_relationship_cred_theft.yml index bf5dd44065f..f7735b69322 100644 --- a/detection-rules/attachment_office_file_relationship_cred_theft.yml +++ b/detection-rules/attachment_office_file_relationship_cred_theft.yml @@ -23,13 +23,10 @@ source: | ) ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/attachment_pdf_link_to_dmg.yml b/detection-rules/attachment_pdf_link_to_dmg.yml index da3da87d685..81874a50ef1 100644 --- a/detection-rules/attachment_pdf_link_to_dmg.yml +++ b/detection-rules/attachment_pdf_link_to_dmg.yml @@ -39,17 +39,11 @@ source: | ) ) ) - - - // first time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: diff --git a/detection-rules/attachment_pdf_linking_to_password_protected_file.yml b/detection-rules/attachment_pdf_linking_to_password_protected_file.yml index ee11e2e24b8..14cc93e7b84 100644 --- a/detection-rules/attachment_pdf_linking_to_password_protected_file.yml +++ b/detection-rules/attachment_pdf_linking_to_password_protected_file.yml @@ -19,13 +19,10 @@ source: | ) ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/attachment_pdf_with_low_reputation_link_to_suspicious_files.yml b/detection-rules/attachment_pdf_with_low_reputation_link_to_suspicious_files.yml index c89d21b1247..1b322cbc3a6 100644 --- a/detection-rules/attachment_pdf_with_low_reputation_link_to_suspicious_files.yml +++ b/detection-rules/attachment_pdf_with_low_reputation_link_to_suspicious_files.yml @@ -17,15 +17,11 @@ source: | ) ) ) - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: diff --git a/detection-rules/attachment_pdf_with_low_reputation_link_to_zip_file.yml b/detection-rules/attachment_pdf_with_low_reputation_link_to_zip_file.yml index b198d9f3d6b..d7e2cc43fe0 100644 --- a/detection-rules/attachment_pdf_with_low_reputation_link_to_zip_file.yml +++ b/detection-rules/attachment_pdf_with_low_reputation_link_to_zip_file.yml @@ -18,15 +18,11 @@ source: | ) ) ) - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: diff --git a/detection-rules/attachment_qr_code_suspicious_components.yml b/detection-rules/attachment_qr_code_suspicious_components.yml index bb2a94dfca4..c081611dfd6 100644 --- a/detection-rules/attachment_qr_code_suspicious_components.yml +++ b/detection-rules/attachment_qr_code_suspicious_components.yml @@ -55,8 +55,6 @@ source: | ) ) ) - - // first time sender and ( ( sender.email.domain.root_domain in $free_email_providers diff --git a/detection-rules/attachment_soliciting_enable_macros.yml b/detection-rules/attachment_soliciting_enable_macros.yml index 3ba77138bc1..c502919588b 100644 --- a/detection-rules/attachment_soliciting_enable_macros.yml +++ b/detection-rules/attachment_soliciting_enable_macros.yml @@ -19,13 +19,10 @@ source: | ) ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/attachment_suspicious_vba_macro_first_time_sender.yml b/detection-rules/attachment_suspicious_vba_macro_first_time_sender.yml index c76d0b80421..5cc38d278ec 100644 --- a/detection-rules/attachment_suspicious_vba_macro_first_time_sender.yml +++ b/detection-rules/attachment_suspicious_vba_macro_first_time_sender.yml @@ -11,13 +11,10 @@ source: | and ml.macro_classifier(.).confidence in ("high") ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/attachment_svg_embedded_js.yml b/detection-rules/attachment_svg_embedded_js.yml index 0daca577a33..1bb935303aa 100644 --- a/detection-rules/attachment_svg_embedded_js.yml +++ b/detection-rules/attachment_svg_embedded_js.yml @@ -21,16 +21,11 @@ source: | and any(.scan.strings.strings, strings.icontains(., "CDATA")) ) ) - - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/attachment_vba_macro_auto_exec_unsolicited.yml b/detection-rules/attachment_vba_macro_auto_exec_unsolicited.yml index 37e28fd0864..8cc39d8b582 100644 --- a/detection-rules/attachment_vba_macro_auto_exec_unsolicited.yml +++ b/detection-rules/attachment_vba_macro_auto_exec_unsolicited.yml @@ -14,13 +14,10 @@ source: | and any(file.oletools(.).macros.keywords, .type =~ "autoexec") ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) diff --git a/detection-rules/attachment_vba_macro_auto_open_unsolicited.yml b/detection-rules/attachment_vba_macro_auto_open_unsolicited.yml index 15d1abef2b1..7bbe7543329 100644 --- a/detection-rules/attachment_vba_macro_auto_open_unsolicited.yml +++ b/detection-rules/attachment_vba_macro_auto_open_unsolicited.yml @@ -15,13 +15,10 @@ source: | and any(file.explode(.), any(.scan.vba.auto_exec, . == "AutoOpen")) ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/attachment_vba_macro_employee_impersonation.yml b/detection-rules/attachment_vba_macro_employee_impersonation.yml index 56297c4fc66..ac8d8b2fbba 100644 --- a/detection-rules/attachment_vba_macro_employee_impersonation.yml +++ b/detection-rules/attachment_vba_macro_employee_impersonation.yml @@ -21,13 +21,10 @@ source: | and file.oletools(.).indicators.vba_macros.exists ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/attachment_vba_macro_high_risk.yml b/detection-rules/attachment_vba_macro_high_risk.yml index 87e0802a0d1..8b9ab322c5e 100644 --- a/detection-rules/attachment_vba_macro_high_risk.yml +++ b/detection-rules/attachment_vba_macro_high_risk.yml @@ -12,13 +12,10 @@ source: | and file.oletools(.).indicators.vba_macros.risk == "high" ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/attachment_with_encrypted_zip_unsolicited.yml b/detection-rules/attachment_with_encrypted_zip_unsolicited.yml index 02c3d167ed8..e21351fe9b1 100644 --- a/detection-rules/attachment_with_encrypted_zip_unsolicited.yml +++ b/detection-rules/attachment_with_encrypted_zip_unsolicited.yml @@ -12,13 +12,10 @@ source: | and any(file.explode(.), any(.flavors.yara, . == 'encrypted_zip')) ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/attachment_with_suspicious_author_unsolicited.yml b/detection-rules/attachment_with_suspicious_author_unsolicited.yml index b1a0aefa868..29e1e71901e 100644 --- a/detection-rules/attachment_with_suspicious_author_unsolicited.yml +++ b/detection-rules/attachment_with_suspicious_author_unsolicited.yml @@ -13,13 +13,10 @@ source: | and any(file.explode(.), strings.ilike(.scan.docx.author, "root")) ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/attachment_with_unknown_encrypted_zip_unsolicited.yml b/detection-rules/attachment_with_unknown_encrypted_zip_unsolicited.yml index ea490e8480e..badc0f2862d 100644 --- a/detection-rules/attachment_with_unknown_encrypted_zip_unsolicited.yml +++ b/detection-rules/attachment_with_unknown_encrypted_zip_unsolicited.yml @@ -16,13 +16,10 @@ source: | ) ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/body_business_email_compromise_new_sender.yml b/detection-rules/body_business_email_compromise_new_sender.yml index 16fb9df2d5f..ffec5179bee 100644 --- a/detection-rules/body_business_email_compromise_new_sender.yml +++ b/detection-rules/body_business_email_compromise_new_sender.yml @@ -21,15 +21,11 @@ source: | or any(headers.hops, any(.fields, strings.ilike(.name, "In-Reply-To"))) ) ) - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/body_business_email_compromise_unsolicited.yml b/detection-rules/body_business_email_compromise_unsolicited.yml index a3181b43bd8..2eb2383c0c6 100644 --- a/detection-rules/body_business_email_compromise_unsolicited.yml +++ b/detection-rules/body_business_email_compromise_unsolicited.yml @@ -42,16 +42,11 @@ source: | ) ) ) - - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) diff --git a/detection-rules/body_callback_phishing_no_attachment.yml b/detection-rules/body_callback_phishing_no_attachment.yml index b946d070b17..b4a1caf7d3d 100644 --- a/detection-rules/body_callback_phishing_no_attachment.yml +++ b/detection-rules/body_callback_phishing_no_attachment.yml @@ -9,13 +9,10 @@ source: | type.inbound and length(attachments) == 0 and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) and sender.email.domain.root_domain in $free_email_providers diff --git a/detection-rules/body_job_scam_new_sender.yml b/detection-rules/body_job_scam_new_sender.yml index e8f38c799a2..9d002d17203 100644 --- a/detection-rules/body_job_scam_new_sender.yml +++ b/detection-rules/body_job_scam_new_sender.yml @@ -11,13 +11,10 @@ source: | and any(ml.nlu_classifier(body.current_thread.text).entities, .name == "financial") ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/callback_phishing_nlu_body_or_attachments.yml b/detection-rules/callback_phishing_nlu_body_or_attachments.yml index 2eaa5c00728..b5b1f1a0c7f 100644 --- a/detection-rules/callback_phishing_nlu_body_or_attachments.yml +++ b/detection-rules/callback_phishing_nlu_body_or_attachments.yml @@ -25,13 +25,10 @@ source: | and strings.icontains(body.html.raw, "bigcommerce.com") ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/file_sharing_link_from_suspicious_sender_domain.yml b/detection-rules/file_sharing_link_from_suspicious_sender_domain.yml index 025a1355b86..09b81756466 100644 --- a/detection-rules/file_sharing_link_from_suspicious_sender_domain.yml +++ b/detection-rules/file_sharing_link_from_suspicious_sender_domain.yml @@ -8,13 +8,10 @@ source: | and any(body.links, .href_url.domain.domain in $free_file_hosts) and sender.email.domain.tld in $suspicious_tlds and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/file_sharing_link_suspicious_subject.yml b/detection-rules/file_sharing_link_suspicious_subject.yml index 88d8b23f04c..09ed51da703 100644 --- a/detection-rules/file_sharing_link_suspicious_subject.yml +++ b/detection-rules/file_sharing_link_suspicious_subject.yml @@ -18,13 +18,10 @@ source: | and regex.icontains(subject.subject, 'immediately', 'urgent') and any(ml.nlu_classifier(body.current_thread.text).intents, .name != "benign") and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/headers_bec_masked_recipients_no_links_freemail_replyto.yml b/detection-rules/headers_bec_masked_recipients_no_links_freemail_replyto.yml index f255d1269da..4970785d8d3 100644 --- a/detection-rules/headers_bec_masked_recipients_no_links_freemail_replyto.yml +++ b/detection-rules/headers_bec_masked_recipients_no_links_freemail_replyto.yml @@ -16,13 +16,10 @@ source: | and not .email.domain.domain == sender.email.domain.domain ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/headers_replyto_new_domain_nlu_request.yml b/detection-rules/headers_replyto_new_domain_nlu_request.yml index ca6fcd540c8..c26b16bc096 100644 --- a/detection-rules/headers_replyto_new_domain_nlu_request.yml +++ b/detection-rules/headers_replyto_new_domain_nlu_request.yml @@ -24,16 +24,11 @@ source: | .name is not null and .confidence in ("medium", "high") ) ) - - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/headers_russia_return_path.yml b/detection-rules/headers_russia_return_path.yml index a1aa279d27f..2daabd83ce5 100644 --- a/detection-rules/headers_russia_return_path.yml +++ b/detection-rules/headers_russia_return_path.yml @@ -8,13 +8,10 @@ source: | and headers.return_path.domain.tld == "ru" and sender.email.email not in $recipient_emails and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/impersonation_amazon_suspicious_text.yml b/detection-rules/impersonation_amazon_suspicious_text.yml index 018882fa9dc..e2c7744ad7e 100644 --- a/detection-rules/impersonation_amazon_suspicious_text.yml +++ b/detection-rules/impersonation_amazon_suspicious_text.yml @@ -33,15 +33,11 @@ source: | ) ) ) - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) and sender.email.domain.root_domain not in~ ( diff --git a/detection-rules/impersonation_barracuda.yml b/detection-rules/impersonation_barracuda.yml index ac9b348cb8c..76987ffe608 100644 --- a/detection-rules/impersonation_barracuda.yml +++ b/detection-rules/impersonation_barracuda.yml @@ -20,16 +20,12 @@ source: | 'sharkssports.net', 'sjbarracuda.com' ) - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) - or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains - ) + profile.by_sender().prevalence in ("new", "outlier") + or ( + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives + ) ) attack_types: - "Credential Phishing" diff --git a/detection-rules/impersonation_chase.yml b/detection-rules/impersonation_chase.yml index 40990223d26..15a8108ef0b 100644 --- a/detection-rules/impersonation_chase.yml +++ b/detection-rules/impersonation_chase.yml @@ -24,14 +24,11 @@ source: | and sender.display_name not in~ ("chaser", "case") and sender.email.domain.root_domain not in~ ('chase.com', 'united.com', 'transunion.com', 'shopping-chase.com') and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) - or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains - ) + profile.by_sender().prevalence in ("new", "outlier") + or ( + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives + ) ) attack_types: - "Credential Phishing" diff --git a/detection-rules/impersonation_dhl.yml b/detection-rules/impersonation_dhl.yml index 3fee425bae3..99d9d08539b 100644 --- a/detection-rules/impersonation_dhl.yml +++ b/detection-rules/impersonation_dhl.yml @@ -24,15 +24,11 @@ source: | 'dhl.de', 'dhl.fr' ) - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/impersonation_docusign.yml b/detection-rules/impersonation_docusign.yml index 07d58391c7a..cfb1539a93b 100644 --- a/detection-rules/impersonation_docusign.yml +++ b/detection-rules/impersonation_docusign.yml @@ -51,15 +51,11 @@ source: | ) and strings.contains(sender.display_name, "via") ) - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/impersonation_employee_payroll_fraud.yml b/detection-rules/impersonation_employee_payroll_fraud.yml index 253133f8f10..108b809ed80 100644 --- a/detection-rules/impersonation_employee_payroll_fraud.yml +++ b/detection-rules/impersonation_employee_payroll_fraud.yml @@ -25,13 +25,10 @@ source: | ) ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/impersonation_employee_subject.yml b/detection-rules/impersonation_employee_subject.yml index 1897f23e05d..7704a421d80 100644 --- a/detection-rules/impersonation_employee_subject.yml +++ b/detection-rules/impersonation_employee_subject.yml @@ -15,15 +15,11 @@ source: | any(ml.nlu_classifier(.).intents, .name == "bec" and .confidence in ("medium", "high")) ) - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/impersonation_employee_urgent_request.yml b/detection-rules/impersonation_employee_urgent_request.yml index 3f6978174c4..e8d2abda54a 100644 --- a/detection-rules/impersonation_employee_urgent_request.yml +++ b/detection-rules/impersonation_employee_urgent_request.yml @@ -23,16 +23,11 @@ source: | and not strings.istarts_with(subject.subject, "fwd:") ) ) - - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/impersonation_fake_msg_thread_mismatched_from_freemail_replyto.yml b/detection-rules/impersonation_fake_msg_thread_mismatched_from_freemail_replyto.yml index 126d35c2cd8..ec61e357ec8 100644 --- a/detection-rules/impersonation_fake_msg_thread_mismatched_from_freemail_replyto.yml +++ b/detection-rules/impersonation_fake_msg_thread_mismatched_from_freemail_replyto.yml @@ -8,16 +8,11 @@ type: "rule" severity: "medium" source: | type.inbound - - // First-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) diff --git a/detection-rules/impersonation_finra.yml b/detection-rules/impersonation_finra.yml index 8922f317c38..65c10058643 100644 --- a/detection-rules/impersonation_finra.yml +++ b/detection-rules/impersonation_finra.yml @@ -12,16 +12,11 @@ source: | or strings.ilevenshtein(sender.email.domain.sld, 'finra') <= 1 ) and sender.email.domain.root_domain not in~ ('finra.org', 'finrax.com') - - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/impersonation_github.yml b/detection-rules/impersonation_github.yml index 8b3b3e79a5f..7606ceab8ff 100644 --- a/detection-rules/impersonation_github.yml +++ b/detection-rules/impersonation_github.yml @@ -29,13 +29,10 @@ source: | 'lithub.com' ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/impersonation_human_resources.yml b/detection-rules/impersonation_human_resources.yml index 96c9e0d6bdc..00516688e71 100644 --- a/detection-rules/impersonation_human_resources.yml +++ b/detection-rules/impersonation_human_resources.yml @@ -18,13 +18,10 @@ source: | and not length(ml.nlu_classifier(body.current_thread.text).intents) == 0 ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/impersonation_microsoft.yml b/detection-rules/impersonation_microsoft.yml index 19f7c44aa24..d67692062f6 100644 --- a/detection-rules/impersonation_microsoft.yml +++ b/detection-rules/impersonation_microsoft.yml @@ -42,16 +42,11 @@ source: | 'office.com', 'teams-events.com' ) - - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) diff --git a/detection-rules/impersonation_paypal.yml b/detection-rules/impersonation_paypal.yml index f8c180384a7..dfb3d3f7e8e 100644 --- a/detection-rules/impersonation_paypal.yml +++ b/detection-rules/impersonation_paypal.yml @@ -52,16 +52,11 @@ source: | 'paypal-prepaid.com', 'xoom.com' ) - - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/impersonation_recipient_domain.yml b/detection-rules/impersonation_recipient_domain.yml index d02e2a84f81..89a05768ac4 100644 --- a/detection-rules/impersonation_recipient_domain.yml +++ b/detection-rules/impersonation_recipient_domain.yml @@ -32,15 +32,11 @@ source: | and all(recipients.to, .email.email != sender.email.email) - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/impersonation_recipient_sld_in_sender_local_fts.yml b/detection-rules/impersonation_recipient_sld_in_sender_local_fts.yml index 193fc25d260..53985558905 100644 --- a/detection-rules/impersonation_recipient_sld_in_sender_local_fts.yml +++ b/detection-rules/impersonation_recipient_sld_in_sender_local_fts.yml @@ -27,13 +27,10 @@ source: | ) and sender.email.domain.root_domain not in $org_domains and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/impersonation_ripple.yml b/detection-rules/impersonation_ripple.yml index da3450cfb57..b3ddee751d1 100644 --- a/detection-rules/impersonation_ripple.yml +++ b/detection-rules/impersonation_ripple.yml @@ -11,13 +11,10 @@ source: | and regex.imatch(sender.display_name, '\bripple\b') and sender.email.domain.root_domain not in ("ripple.com", "ripplejobs.co.uk") and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: diff --git a/detection-rules/impersonation_spotify.yml b/detection-rules/impersonation_spotify.yml index cfddbc55737..c1fe24ce78d 100644 --- a/detection-rules/impersonation_spotify.yml +++ b/detection-rules/impersonation_spotify.yml @@ -20,15 +20,11 @@ source: | 'anchor.fm' ) and sender.email.domain.domain not in~ ('privaterelay.appleid.com') - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/impersonation_stellar.yml b/detection-rules/impersonation_stellar.yml index 0a6c3a65b1e..9cea84869ec 100644 --- a/detection-rules/impersonation_stellar.yml +++ b/detection-rules/impersonation_stellar.yml @@ -11,13 +11,10 @@ source: | and regex.imatch(sender.display_name, '\bstellar\b') and sender.email.domain.root_domain != "stellar.org" and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: diff --git a/detection-rules/impersonation_sublime_security.yml b/detection-rules/impersonation_sublime_security.yml index 092022258c8..e69db5c1101 100644 --- a/detection-rules/impersonation_sublime_security.yml +++ b/detection-rules/impersonation_sublime_security.yml @@ -12,15 +12,11 @@ source: | or strings.ilevenshtein(sender.email.domain.domain, 'sublimesecurity.com') <= 2 ) and sender.email.domain.domain != 'sublimesecurity.com' - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/impersonation_vip_urgent_request.yml b/detection-rules/impersonation_vip_urgent_request.yml index a0b24a6fd91..13f1a9ab7a9 100644 --- a/detection-rules/impersonation_vip_urgent_request.yml +++ b/detection-rules/impersonation_vip_urgent_request.yml @@ -15,15 +15,11 @@ source: | and any(ml.nlu_classifier(body.current_thread.text).entities, .name == "request") ) ) - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/inline_image_as_message.yml b/detection-rules/inline_image_as_message.yml index ce0948fce12..d9cdfc3b964 100644 --- a/detection-rules/inline_image_as_message.yml +++ b/detection-rules/inline_image_as_message.yml @@ -21,13 +21,10 @@ source: | ) and strings.ilike(body.html.raw, "*img*cid*") and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/link_credential_phishing.yml b/detection-rules/link_credential_phishing.yml index 214ae9fda81..08e9ef5f47e 100644 --- a/detection-rules/link_credential_phishing.yml +++ b/detection-rules/link_credential_phishing.yml @@ -9,15 +9,11 @@ source: | beta.linkanalysis(.).credphish.disposition == "phishing" and beta.linkanalysis(.).credphish.confidence in ("medium", "high") ) - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/link_credential_phishing_intent_and_other_indicators.yml b/detection-rules/link_credential_phishing_intent_and_other_indicators.yml index c564026ff9a..a9ecc3b8de4 100644 --- a/detection-rules/link_credential_phishing_intent_and_other_indicators.yml +++ b/detection-rules/link_credential_phishing_intent_and_other_indicators.yml @@ -296,16 +296,11 @@ source: | // doesn't match any links in the body or all(body.links, .href_url.domain.root_domain != sender.email.domain.root_domain) ) - - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/link_credential_phishing_secure_message.yml b/detection-rules/link_credential_phishing_secure_message.yml index 60f0fe56787..1960d5ee9e5 100644 --- a/detection-rules/link_credential_phishing_secure_message.yml +++ b/detection-rules/link_credential_phishing_secure_message.yml @@ -29,16 +29,11 @@ source: | // Negate known secure mailer(s) and not all(body.links, .href_url.domain.root_domain in ("mimecast.com")) ) - - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/link_credential_phishing_suspicious_sender_tld_and_signals.yml b/detection-rules/link_credential_phishing_suspicious_sender_tld_and_signals.yml index f8d7ac3732c..a0019a6fe00 100644 --- a/detection-rules/link_credential_phishing_suspicious_sender_tld_and_signals.yml +++ b/detection-rules/link_credential_phishing_suspicious_sender_tld_and_signals.yml @@ -44,15 +44,11 @@ source: | any(recipients.to, strings.icontains(subject.subject, .email.email)), ) - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/link_credential_phishing_voicemail_language.yml b/detection-rules/link_credential_phishing_voicemail_language.yml index e9259e4983a..dc215ca3218 100644 --- a/detection-rules/link_credential_phishing_voicemail_language.yml +++ b/detection-rules/link_credential_phishing_voicemail_language.yml @@ -65,13 +65,10 @@ source: | ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/link_download_disk_image_in_encrypted_zip.yml b/detection-rules/link_download_disk_image_in_encrypted_zip.yml index 4d4019a331e..264ebacb2bc 100644 --- a/detection-rules/link_download_disk_image_in_encrypted_zip.yml +++ b/detection-rules/link_download_disk_image_in_encrypted_zip.yml @@ -24,15 +24,11 @@ source: | ) ) ) - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: diff --git a/detection-rules/link_download_suspicious_file.yml b/detection-rules/link_download_suspicious_file.yml index 969c0ef8cdb..367753b3220 100644 --- a/detection-rules/link_download_suspicious_file.yml +++ b/detection-rules/link_download_suspicious_file.yml @@ -33,15 +33,11 @@ source: | ) ) ) - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/link_fake_fax_low_reputation.yml b/detection-rules/link_fake_fax_low_reputation.yml index 0974ab392d0..f2654141930 100644 --- a/detection-rules/link_fake_fax_low_reputation.yml +++ b/detection-rules/link_fake_fax_low_reputation.yml @@ -43,16 +43,11 @@ source: | ) ) ) - - // first time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/link_google_apps_script_macro.yml b/detection-rules/link_google_apps_script_macro.yml index 646a0a9f669..a71f3ae38bb 100644 --- a/detection-rules/link_google_apps_script_macro.yml +++ b/detection-rules/link_google_apps_script_macro.yml @@ -11,15 +11,11 @@ source: | and any(body.links, .href_url.domain.domain == "script.google.com" and strings.ilike(.href_url.path, "/macros*") ) - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/link_google_translate.yml b/detection-rules/link_google_translate.yml index e77a82d2eb9..06a07041f60 100644 --- a/detection-rules/link_google_translate.yml +++ b/detection-rules/link_google_translate.yml @@ -12,13 +12,10 @@ source: | type.inbound and any(body.links, .href_url.domain.root_domain == "translate.goog") and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: diff --git a/detection-rules/link_html_smuggling_with_adobe_branding.yml b/detection-rules/link_html_smuggling_with_adobe_branding.yml index 28d17dd563f..2a5e63ff55d 100644 --- a/detection-rules/link_html_smuggling_with_adobe_branding.yml +++ b/detection-rules/link_html_smuggling_with_adobe_branding.yml @@ -25,15 +25,11 @@ source: | ) ) ) - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: diff --git a/detection-rules/link_html_smuggling_with_google_drive_branding.yml b/detection-rules/link_html_smuggling_with_google_drive_branding.yml index 0038b4ffdf7..68c8ae319e3 100644 --- a/detection-rules/link_html_smuggling_with_google_drive_branding.yml +++ b/detection-rules/link_html_smuggling_with_google_drive_branding.yml @@ -30,15 +30,11 @@ source: | ) ) ) - // Unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: diff --git a/detection-rules/link_invoice_fake_customer_service_freemail_sender.yml b/detection-rules/link_invoice_fake_customer_service_freemail_sender.yml index bd50ed86d42..020199d5b67 100644 --- a/detection-rules/link_invoice_fake_customer_service_freemail_sender.yml +++ b/detection-rules/link_invoice_fake_customer_service_freemail_sender.yml @@ -20,7 +20,6 @@ source: | ) ) ) - // First time sender exclusions are in place to avoid legitimate messages from known freemail senders. and sender.email.email not in $sender_emails attack_types: - "BEC/Fraud" diff --git a/detection-rules/link_ipfs_phishing.yml b/detection-rules/link_ipfs_phishing.yml index bb6973c2c02..84337314f44 100644 --- a/detection-rules/link_ipfs_phishing.yml +++ b/detection-rules/link_ipfs_phishing.yml @@ -31,15 +31,11 @@ source: | // adding negation block for legitimate domains with ipfs in their name and not sender.email.domain.domain in ("shipfsl.com") - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/link_login_or_captcha.yml b/detection-rules/link_login_or_captcha.yml index 5e9aed2b023..70b12b721a0 100644 --- a/detection-rules/link_login_or_captcha.yml +++ b/detection-rules/link_login_or_captcha.yml @@ -28,16 +28,11 @@ source: | // exclude FP prone senders and sender.email.domain.root_domain not in ("sharepointonline.com") - - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/link_microsoft_device_code_phish.yml b/detection-rules/link_microsoft_device_code_phish.yml index 6553b9b081d..c9e50476872 100644 --- a/detection-rules/link_microsoft_device_code_phish.yml +++ b/detection-rules/link_microsoft_device_code_phish.yml @@ -32,16 +32,11 @@ source: | // A nine character string containing a combination of letters and characters regex.icontains(body.html.display_text, '[\W]([A-Z0-9]{9})[\W]') ) - - // Unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/link_microsoft_impersonation_using_hosted_png.yml b/detection-rules/link_microsoft_impersonation_using_hosted_png.yml index 1469d86d458..330c173024a 100644 --- a/detection-rules/link_microsoft_impersonation_using_hosted_png.yml +++ b/detection-rules/link_microsoft_impersonation_using_hosted_png.yml @@ -32,16 +32,11 @@ source: | // org domain in the subject of the message and any($org_domains, strings.icontains(subject.subject, .)) - - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/link_new_domain_in_link_first_time_sender.yml b/detection-rules/link_new_domain_in_link_first_time_sender.yml index ea1ed146a45..6f303b2fbaa 100644 --- a/detection-rules/link_new_domain_in_link_first_time_sender.yml +++ b/detection-rules/link_new_domain_in_link_first_time_sender.yml @@ -8,13 +8,10 @@ source: | and length(body.links) > 0 and any(body.links, beta.whois(.href_url.domain).days_old <= 10) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: diff --git a/detection-rules/link_notion_file_share.yml b/detection-rules/link_notion_file_share.yml index 8491cd00bac..b7a7cd744c2 100644 --- a/detection-rules/link_notion_file_share.yml +++ b/detection-rules/link_notion_file_share.yml @@ -43,16 +43,11 @@ source: | ) ) and sender.email.domain.domain != 'mail.notion.so' - - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/link_qr_code_suspicious_language_fts.yml b/detection-rules/link_qr_code_suspicious_language_fts.yml index cdae99e81c3..526c001c888 100644 --- a/detection-rules/link_qr_code_suspicious_language_fts.yml +++ b/detection-rules/link_qr_code_suspicious_language_fts.yml @@ -44,15 +44,11 @@ source: | ) ) - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/link_suspicious_language_undisclosed_recipients.yml b/detection-rules/link_suspicious_language_undisclosed_recipients.yml index 7fcb7a130ba..b2a20cbb845 100644 --- a/detection-rules/link_suspicious_language_undisclosed_recipients.yml +++ b/detection-rules/link_suspicious_language_undisclosed_recipients.yml @@ -37,15 +37,11 @@ source: | // subject is in all caps and regex.match(subject.subject, "[A-Z ]+") - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/mass_campaign_recipient_address_new_sender.yml b/detection-rules/mass_campaign_recipient_address_new_sender.yml index 92faf055f48..3c6a51ba966 100644 --- a/detection-rules/mass_campaign_recipient_address_new_sender.yml +++ b/detection-rules/mass_campaign_recipient_address_new_sender.yml @@ -15,16 +15,11 @@ source: | // exclude To: Undisclosed recipients:; // since we won't have a valid recipient email and any(recipients.to, .email.domain.valid == true) - - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) and ( diff --git a/detection-rules/open_redirect_avast.yml b/detection-rules/open_redirect_avast.yml index 5ff4fcde8b6..4468bf1bfdc 100644 --- a/detection-rules/open_redirect_avast.yml +++ b/detection-rules/open_redirect_avast.yml @@ -10,13 +10,10 @@ source: | ) and sender.email.domain.root_domain != "avast.com" and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/recipients_undisclosed_free_subdomain_host.yml b/detection-rules/recipients_undisclosed_free_subdomain_host.yml index b66cf12cb3c..91ab346d706 100644 --- a/detection-rules/recipients_undisclosed_free_subdomain_host.yml +++ b/detection-rules/recipients_undisclosed_free_subdomain_host.yml @@ -22,13 +22,10 @@ source: | ) ) and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: diff --git a/detection-rules/sender_new_from_domain_first_time_sender.yml b/detection-rules/sender_new_from_domain_first_time_sender.yml index ba5fbdbf256..d623bcb7187 100644 --- a/detection-rules/sender_new_from_domain_first_time_sender.yml +++ b/detection-rules/sender_new_from_domain_first_time_sender.yml @@ -7,13 +7,10 @@ source: | type.inbound and beta.whois(sender.email.domain).days_old <= 10 and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: diff --git a/detection-rules/spam_campaign_excessive_display_text_with_keywords.yml b/detection-rules/spam_campaign_excessive_display_text_with_keywords.yml index 55e02712629..e2f035b548e 100644 --- a/detection-rules/spam_campaign_excessive_display_text_with_keywords.yml +++ b/detection-rules/spam_campaign_excessive_display_text_with_keywords.yml @@ -10,15 +10,11 @@ source: | and length(body.links) > 0 and any(body.links, length(.display_text) > 3000) and any(body.links, regex.icontains(.display_text, '(\bPassword:)', 'Hi.{0,5}Welcome\b')) - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/spam_new_domain_emojis.yml b/detection-rules/spam_new_domain_emojis.yml index 8b01256663d..f9f729955b7 100644 --- a/detection-rules/spam_new_domain_emojis.yml +++ b/detection-rules/spam_new_domain_emojis.yml @@ -21,16 +21,11 @@ source: | '[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}]' ) ) - - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/spam_url_shortener_emojis.yml b/detection-rules/spam_url_shortener_emojis.yml index e793b36b770..121f88ea7d0 100644 --- a/detection-rules/spam_url_shortener_emojis.yml +++ b/detection-rules/spam_url_shortener_emojis.yml @@ -24,16 +24,11 @@ source: | '[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}]' ) ) - - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) attack_types: diff --git a/detection-rules/vip_impersonation_attack_surface_reduction.yml b/detection-rules/vip_impersonation_attack_surface_reduction.yml index 34f8fe317c9..36971da13ad 100644 --- a/detection-rules/vip_impersonation_attack_surface_reduction.yml +++ b/detection-rules/vip_impersonation_attack_surface_reduction.yml @@ -21,27 +21,19 @@ source: | or sender.display_name != mailbox.display_name ) - // first-time sender and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $sender_emails - ) + profile.by_sender().prevalence in ("new", "outlier") or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $sender_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) - // unsolicited and ( - ( - sender.email.domain.root_domain in $free_email_providers - and sender.email.email not in $recipient_emails - ) + not profile.by_sender().solicited or ( - sender.email.domain.root_domain not in $free_email_providers - and sender.email.domain.domain not in $recipient_domains + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives ) ) tags: From 1dc009e994a60a8602cdce0ace3783a0ef614b37 Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Thu, 5 Oct 2023 12:03:53 -0400 Subject: [PATCH 34/35] New Rule: QR Code with suspicious indicators (#817) Co-authored-by: ID Generator --- .../qr_code_suspicious_indicators.yml | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 detection-rules/qr_code_suspicious_indicators.yml diff --git a/detection-rules/qr_code_suspicious_indicators.yml b/detection-rules/qr_code_suspicious_indicators.yml new file mode 100644 index 00000000000..b929c268a99 --- /dev/null +++ b/detection-rules/qr_code_suspicious_indicators.yml @@ -0,0 +1,59 @@ +name: "QR Code with suspicious indicators" +description: | + This rule flags messages with QR codes in attachments when there are three or fewer attachments. If no attachments are present, the rule captures a screenshot of the message for analysis. Additional triggers include: sender's name containing the recipient's SLD, recipient's email mentioned in the body, an empty message body, a suspicious subject, or undisclosed recipients. +type: "rule" +severity: "high" +source: | + type.inbound + and ( + length(attachments) <= 3 + and ( + any(attachments, + .file_type in $file_types_images and (any(file.explode(.), .scan.qr.type == "url")) + ) + or ( + length(attachments) == 0 + and any(file.explode(beta.message_screenshot()), .scan.qr.type == "url") + ) + ) + and not sender.email.domain.root_domain in $org_display_names + and ( + any(recipients.to, strings.icontains(sender.display_name, .email.domain.sld)) + or any(recipients.to, strings.icontains(body.current_thread.text, .email.local_part)) + or length(body.current_thread.text) is null + or body.current_thread.text == "" + or regex.contains(subject.subject, + "(Authenticat(e|or|ion)|2fa|Multi.Factor|(qr|bar).code|action.require|alert|Att(n|ention):)" + ) + or (any(recipients.to, strings.icontains(subject.subject, .display_name))) + or ( + (length(recipients.to) == 0 or all(recipients.to, .display_name == "Undisclosed recipients")) + and length(recipients.cc) == 0 + and length(recipients.bcc) == 0 + ) + ) + ) + + // sender profile is new or outlier + and ( + profile.by_sender().prevalence in ("new", "outlier") + or ( + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives + ) + ) + +attack_types: + - "Credential Phishing" +tactics_and_techniques: + - "QR code" + - "Social engineering" +detection_methods: + - "Content analysis" + - "Header analysis" + - "Computer Vision" + - "Natural Language Understanding" + - "QR code analysis" + - "Sender analysis" + - "URL analysis" +id: "04f5c34f-6518-512d-916c-4c2c2827c6a9" From c67418bfbfd892d7f0f0ee99dfa0d35846158d66 Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Thu, 5 Oct 2023 13:53:43 -0700 Subject: [PATCH 35/35] Update link_microsoft_low_reputation.yml (#846) Co-authored-by: Ross Wolf <31489089+rw-access@users.noreply.github.com> --- detection-rules/link_microsoft_low_reputation.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/detection-rules/link_microsoft_low_reputation.yml b/detection-rules/link_microsoft_low_reputation.yml index 5e467937174..eb4fec631e1 100644 --- a/detection-rules/link_microsoft_low_reputation.yml +++ b/detection-rules/link_microsoft_low_reputation.yml @@ -32,6 +32,7 @@ source: | ) or any(body.links, .href_url.domain.domain in $free_file_hosts) ) + and .href_url.domain.root_domain not in $org_domains ) // not a reply