From cd865ca6456f2b3444c11fc3771a9b5f37090844 Mon Sep 17 00:00:00 2001 From: Josh Kamdjou Date: Mon, 20 Nov 2023 18:19:04 -0500 Subject: [PATCH 01/19] Expand attached EML cred theft coverage (#1007) --- detection-rules/attachment_eml_cred_theft.yml | 68 +++++++++++++------ 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/detection-rules/attachment_eml_cred_theft.yml b/detection-rules/attachment_eml_cred_theft.yml index 39555ddc1e5..e6b862102d5 100644 --- a/detection-rules/attachment_eml_cred_theft.yml +++ b/detection-rules/attachment_eml_cred_theft.yml @@ -1,36 +1,61 @@ name: "Attachment: EML with link to credential phishing page" description: | - Attached EML links to a credential phishing site. + Attached EML links to a credential phishing site or exhibits unusual behavior such as multiple suspicious redirects. type: "rule" severity: "medium" source: | type.inbound and length(attachments) == 1 and any(attachments, - .content_type == "message/rfc822" - and ( - any(file.explode(.), - any(.scan.url.urls, - ( - ( - .domain.root_domain in $free_subdomain_hosts - or .domain.root_domain in ("sharepoint.com") - or .domain.root_domain not in $tranco_1m - ) - and beta.linkanalysis(.).credphish.disposition == "phishing" - ) - // or any links in the final dom lead to a suspicious tld - or any(beta.linkanalysis(.).final_dom.links, - beta.linkanalysis(.href_url).effective_url.domain.tld in $suspicious_tlds + (.content_type == "message/rfc822" or .file_extension =~ "eml") + and any(file.parse_eml(.).body.links, + ( + beta.linkanalysis(., mode="aggressive").credphish.disposition == "phishing" + and beta.linkanalysis(., mode="aggressive").credphish.confidence in ( + "medium", + "high" ) - ) + ) + + // or any links in the final dom lead to a suspicious tld + or any(beta.linkanalysis(.).final_dom.links, + .href_url.domain.tld in $suspicious_tlds + or beta.linkanalysis(.href_url).effective_url.domain.tld in $suspicious_tlds + ) + + // link redirects to a suspicious TLD + or any(beta.linkanalysis(., mode="aggressive").redirect_history, + .domain.tld in $suspicious_tlds + ) + or ( + // suspicious redirects + // 3 or more different domains with 2 or more different TLDs + // careful because click trackers will always make this at least 2 + // different domains and not unlikely 2 or more TLDs + length(distinct(map(beta.linkanalysis(., mode="aggressive").redirect_history, + .domain.tld + ) + ) + ) >= 2 + and length(distinct(map(beta.linkanalysis(., + mode="aggressive" + ).redirect_history, + .domain.domain + ) + ) + ) >= 3 + ) + ) + // engaging language in the original body or EML + and ( + any(ml.nlu_classifier(body.html.display_text).entities, + .name == "request" + ) + or any(ml.nlu_classifier(file.parse_eml(.).body.html.display_text).entities, + .name == "request" ) ) ) - - // engaging language in the original body - and any(ml.nlu_classifier(body.html.display_text).entities, .name == "request") - // exclude bounce backs & read receipts and not strings.like(sender.email.local_part, "*postmaster*", @@ -48,6 +73,7 @@ source: | and not profile.by_sender().any_false_positives ) ) + and not profile.by_sender().any_false_positives attack_types: - "Credential Phishing" From 8b51eb9f05a12765983337f73c17178a4b784438 Mon Sep 17 00:00:00 2001 From: Josh Kamdjou Date: Mon, 20 Nov 2023 19:37:07 -0500 Subject: [PATCH 02/19] Add profiles for FP reduction (#1008) --- detection-rules/headers_replyto_new_domain_nlu_request.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/detection-rules/headers_replyto_new_domain_nlu_request.yml b/detection-rules/headers_replyto_new_domain_nlu_request.yml index 65b1bd2945b..3196791752e 100644 --- a/detection-rules/headers_replyto_new_domain_nlu_request.yml +++ b/detection-rules/headers_replyto_new_domain_nlu_request.yml @@ -21,6 +21,13 @@ source: | .name is not null and .confidence in ("medium", "high") ) ) + and ( + not profile.by_sender().solicited + or ( + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives + ) + ) and not profile.by_sender().any_false_positives attack_types: From 1196da932eda8727396addfcd3469630fcb28108 Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Tue, 21 Nov 2023 06:01:49 -0800 Subject: [PATCH 03/19] Update link_deactivated_bitly.yml (#998) --- detection-rules/link_deactivated_bitly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detection-rules/link_deactivated_bitly.yml b/detection-rules/link_deactivated_bitly.yml index cb78681c762..3f6202ab040 100644 --- a/detection-rules/link_deactivated_bitly.yml +++ b/detection-rules/link_deactivated_bitly.yml @@ -11,7 +11,7 @@ source: | // link doesn't forward through and beta.linkanalysis(.).effective_url.domain.domain == "bit.ly" // blocked or gated by bit.ly - and strings.ilike(beta.linkanalysis(.).final_dom.display_text, "*link*blocked*", "*flagged*by*") + and strings.ilike(beta.linkanalysis(.).final_dom.display_text, "*link*blocked*", "*flagged*by*", "*been*deactivated*") ) attack_types: - "Credential Phishing" From b306c0f61e9d23da1927d5222c7b0b8855534851 Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Tue, 21 Nov 2023 07:26:05 -0800 Subject: [PATCH 04/19] New Rule: Office file with suspicious function calls or downloaded file path (#681) Co-authored-by: ID Generator Co-authored-by: Sam Scholten --- ...attachment_office_suspicious_functions.yml | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 detection-rules/attachment_office_suspicious_functions.yml diff --git a/detection-rules/attachment_office_suspicious_functions.yml b/detection-rules/attachment_office_suspicious_functions.yml new file mode 100644 index 00000000000..305e00f0d34 --- /dev/null +++ b/detection-rules/attachment_office_suspicious_functions.yml @@ -0,0 +1,41 @@ +name: "Attachment: Office file with suspicious function calls or downloaded file path" +description: "Attached Office file contains suspicious function calls or known malicious file path pattern." +references: + - "https://app.docguard.io/c3e75d7a32a4959724f24c1004724951482cd732db7d287989c873c09166ff95/c3036de5-89b1-49c6-9681-706f5b9af264/0/results/dashboard" +type: "rule" +severity: "high" +source: | + type.inbound + and any(attachments, + ( + // office files + .file_extension in~ $file_extensions_macros + or .file_extension in~ $file_extensions_common_archives + or ( + .file_extension is null + and .file_type == "unknown" + and .content_type == "application/octet-stream" + and .size < 100000 + ) + ) + and ( + any(file.explode(.), + ( + any(.scan.strings.strings, strings.ilike(., '*URLDownloadToFile*')) + and any(.scan.strings.strings, strings.ilike(., '*Auto_Open*')) + ) + or any(.scan.strings.strings, + regex.icontains(., 'C:\\[A-Za-z]{7}\\[A-Za-z]{7}\\[A-Za-z]{7}') + ) + ) + ) + ) +attack_types: + - "Malware/Ransomware" +tactics_and_techniques: + - "Evasion" + - "Scripting" +detection_methods: + - "Archive analysis" + - "File analysis" +id: "4c78b969-9df8-59e1-8f65-43afdb06c817" From ef91b1a7c138d8eb566ac0871d7c6d73fd3fd8be Mon Sep 17 00:00:00 2001 From: Josh Kamdjou Date: Tue, 21 Nov 2023 10:44:38 -0500 Subject: [PATCH 05/19] Add unsolicited (#1009) --- detection-rules/attachment_any_html_new_sender.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/detection-rules/attachment_any_html_new_sender.yml b/detection-rules/attachment_any_html_new_sender.yml index 303df0db404..24b9045117d 100644 --- a/detection-rules/attachment_any_html_new_sender.yml +++ b/detection-rules/attachment_any_html_new_sender.yml @@ -12,7 +12,10 @@ source: | type.inbound and any(attachments, .file_extension in~ ('htm', 'html') or .file_type == "html") and ( - profile.by_sender().prevalence in ("new", "outlier") + ( + profile.by_sender().prevalence in ("new", "outlier") + and not profile.by_sender().solicited + ) or profile.by_sender().any_messages_malicious_or_spam ) and not profile.by_sender().any_false_positives From 1e9d716da9e3b1eb40ebb24646060a557e4289a8 Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Tue, 21 Nov 2023 08:28:02 -0800 Subject: [PATCH 06/19] Update impersonation_human_resources.yml (#1006) Co-authored-by: Sam Scholten --- detection-rules/impersonation_human_resources.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/detection-rules/impersonation_human_resources.yml b/detection-rules/impersonation_human_resources.yml index 0e4a77e8fe4..316da757473 100644 --- a/detection-rules/impersonation_human_resources.yml +++ b/detection-rules/impersonation_human_resources.yml @@ -12,7 +12,15 @@ source: | // Negate common marketing mailers and not regex.icontains(sender.display_name, 'HR (Events|Expert)') - and (0 < length(body.links) < 10 or length(attachments) > 0) + and ( + (0 < length(body.links) < 10 or length(attachments) > 0) + // mass-mailer infra abuse results in an inflated link count due to mailer templates that include links for unsubbing, changing preferences, etc. + // loosening the link count check as a result ensures we fire even with these conditions + or ( + any(body.links, strings.ilike(.display_text, "*unsubscribe*", "update your preferences", "add us to your address book")) + and 0 < length(body.links) < 15 + ) + ) // Request and Urgency and any(ml.nlu_classifier(body.current_thread.text).entities, .name == "request") and any(ml.nlu_classifier(body.current_thread.text).entities, .name == "urgency") From caa333f1e5fe21156279f07900121a54b40d7491 Mon Sep 17 00:00:00 2001 From: Josh Kamdjou Date: Tue, 21 Nov 2023 12:37:15 -0500 Subject: [PATCH 07/19] New credential phishing rules (#995) --- .../link_content_credential_phishing.yml | 61 ++++++++++ ...phishing_intent_and_other_indicators_2.yml | 112 ++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 detection-rules/link_content_credential_phishing.yml create mode 100644 detection-rules/link_credential_phishing_intent_and_other_indicators_2.yml diff --git a/detection-rules/link_content_credential_phishing.yml b/detection-rules/link_content_credential_phishing.yml new file mode 100644 index 00000000000..733dfe4874e --- /dev/null +++ b/detection-rules/link_content_credential_phishing.yml @@ -0,0 +1,61 @@ +name: "Credential phishing content and link (first-time sender)" +description: | + Message contains credential theft language and a link to a credential phishing page from an unknown sender. + We use Link Analysis in aggressive mode to increase our chances of scanning. +type: "rule" +severity: "high" +source: | + type.inbound + and ( + any(ml.nlu_classifier(body.current_thread.text).intents, + .name == "cred_theft" and .confidence in ("medium", "high") + ) + // embedded in an image attachment + // note: don't use message_screenshot() for now + // because it's not limited to current_thread and may FP + or any(attachments, + .file_type in $file_types_images + and any(file.explode(.), + any(ml.nlu_classifier(.scan.ocr.raw).intents, + .name == "cred_theft" and .confidence in ("medium", "high") + ) + ) + ) + ) + and any(body.links, + beta.linkanalysis(., mode="aggressive").credphish.disposition == "phishing" + and beta.linkanalysis(., mode="aggressive").credphish.confidence in ( + "medium", + "high" + ) + ) + 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 + ) + ) + + // negate highly trusted sender domains unless they fail DMARC authentication + and ( + ( + sender.email.domain.root_domain in $high_trust_sender_root_domains + and ( + any(distinct(headers.hops, .authentication_results.dmarc is not null), + strings.ilike(.authentication_results.dmarc, "*fail") + ) + ) + ) + or sender.email.domain.root_domain not in $high_trust_sender_root_domains + ) +attack_types: + - "Credential Phishing" +tactics_and_techniques: + - "Social engineering" +detection_methods: + - "Computer Vision" + - "Sender analysis" + - "URL analysis" + - "URL screenshot" +id: "f0c95bb7-afeb-5c8d-a654-74b5e026007f" diff --git a/detection-rules/link_credential_phishing_intent_and_other_indicators_2.yml b/detection-rules/link_credential_phishing_intent_and_other_indicators_2.yml new file mode 100644 index 00000000000..eab55a5ff08 --- /dev/null +++ b/detection-rules/link_credential_phishing_intent_and_other_indicators_2.yml @@ -0,0 +1,112 @@ +name: "Credential phishing language and suspicious indicators (unknown sender)" +description: | + Message contains various suspicious indicators as well as engaging language resembling credential theft from an unknown sender. +type: "rule" +severity: "medium" +source: | + type.inbound + and ( + any(ml.nlu_classifier(body.current_thread.text).intents, + .name == "cred_theft" and .confidence in ("medium", "high") + ) + // embedded in an image attachment + // note: don't use message_screenshot() + // because it's not limited to current_thread and may FP + or any(attachments, + .file_type in $file_types_images + and any(file.explode(.), + any(ml.nlu_classifier(.scan.ocr.raw).intents, + .name == "cred_theft" and .confidence == "high" + ) + ) + ) + ) + and 4 of ( + // impersonation of the recipient's domain or email address + // in the subject to make it look more personalized + any(recipients.to, + strings.icontains(subject.subject, .email.local_part) + or strings.icontains(subject.subject, .email.domain.sld) + ), + // recipient's email address in the body. this is not very uncommon + // for legit credential themed messages either + any(recipients.to, + .email.domain.valid + and strings.icontains(body.current_thread.text, .email.email) + ), + ( + // freemail providers should never be sending this type of email + sender.email.domain.domain in $free_email_providers + + // if not freemail, it's suspicious if the sender's root domain + // doesn't match any links in the body + or ( + length(body.links) > 0 + and all(body.links, + .href_url.domain.root_domain != sender.email.domain.root_domain + ) + ) + ), + strings.contains(body.current_thread.text, + "Your mailbox can no longer send or receive messages." + ), + // link redirects to a suspicious TLD + any(body.links, + any(beta.linkanalysis(., mode="aggressive").redirect_history, .domain.tld in $suspicious_tlds) + ), + ( + // suspicious redirects + // 3 or more different domains with 2 or more different TLDs + // careful because click trackers will always make this at least 2 + // different domains and not unlikely 2 or more TLDs + any(body.links, + length(distinct(map(beta.linkanalysis(., mode="aggressive").redirect_history, + .domain.tld + ) + ) + ) >= 2 + and length(distinct(map(beta.linkanalysis(., mode="aggressive").redirect_history, + .domain.domain + ) + ) + ) >= 3 + ) + ), + // maybe: any brand logo with high confidence + // maybe: recipients BCCd or undisclosed + ) + and ( + ( + profile.by_sender().prevalence in ("new", "outlier") + and not profile.by_sender().solicited + ) + or ( + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives + ) + ) + + // negate highly trusted sender domains unless they fail DMARC authentication + and ( + ( + sender.email.domain.root_domain in $high_trust_sender_root_domains + and ( + any(distinct(headers.hops, .authentication_results.dmarc is not null), + strings.ilike(.authentication_results.dmarc, "*fail") + ) + ) + ) + or sender.email.domain.root_domain not in $high_trust_sender_root_domains + ) +attack_types: + - "Credential Phishing" +tactics_and_techniques: + - "Free email provider" + - "Social engineering" +detection_methods: + - "Content analysis" + - "Header analysis" + - "Natural Language Understanding" + - "Sender analysis" + - "URL analysis" +id: "89c186f7-8c8d-55db-8b6f-da6ead587b1d" From c51ba0cb11672d385c3abf760d0df84891972ad8 Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Tue, 21 Nov 2023 12:47:38 -0500 Subject: [PATCH 08/19] New Rule: Docusign embedded image lure (#1003) Co-authored-by: ID Generator Co-authored-by: Josh Kamdjou --- ..._phishing_docusign_embedded_image_lure.yml | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 detection-rules/credential_phishing_docusign_embedded_image_lure.yml diff --git a/detection-rules/credential_phishing_docusign_embedded_image_lure.yml b/detection-rules/credential_phishing_docusign_embedded_image_lure.yml new file mode 100644 index 00000000000..809dddbe2a4 --- /dev/null +++ b/detection-rules/credential_phishing_docusign_embedded_image_lure.yml @@ -0,0 +1,53 @@ +name: "Credential Phishing: DocuSign embedded image lure with no DocuSign domains in links" +description: "Detects DocuSign phishing emails with no DocuSign links, a DocuSign logo embedded in the body of the message, from a new sender." +type: "rule" +severity: "high" +source: | + type.inbound + and length(attachments) == 0 + and any(body.links, + not strings.ilike(.href_url.domain.root_domain, "docusign.*") + ) + and ( + any(ml.logo_detect(beta.message_screenshot()).brands, + .name == "DocuSign" + or any(file.explode(beta.message_screenshot()), + strings.ilike(.scan.ocr.raw, "*DocuSign*") + and any(ml.nlu_classifier(.scan.ocr.raw).intents, + .name == "cred_theft" and .confidence != "low" + ) + ) + ) + ) + and any(file.explode(beta.message_screenshot()), + regex.icontains(.scan.ocr.raw, + "review document", + "[^d][^o][^c][^u]sign", + "important edocs", + "completed document" + ) + ) + and ( + ( + not profile.by_sender().solicited + 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: + - "Impersonation: Brand" + - "Social engineering" +detection_methods: + - "Computer Vision" + - "Content analysis" + - "Header analysis" + - "Natural Language Understanding" + - "Optical Character Recognition" + - "Sender analysis" +id: "dfe8715e-6318-579b-9131-ddfc9854dc95" From fca8797a7c4a64e5c57e2f4172ada215c0764e19 Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Tue, 21 Nov 2023 10:26:34 -0800 Subject: [PATCH 09/19] Create impersonation_dotloop.yml (#999) Co-authored-by: ID Generator Co-authored-by: Sam Scholten Co-authored-by: Sam Scholten --- detection-rules/impersonation_dotloop.yml | 41 +++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 detection-rules/impersonation_dotloop.yml diff --git a/detection-rules/impersonation_dotloop.yml b/detection-rules/impersonation_dotloop.yml new file mode 100644 index 00000000000..7c0797e311d --- /dev/null +++ b/detection-rules/impersonation_dotloop.yml @@ -0,0 +1,41 @@ +name: "Brand impersonation: Dotloop" +description: "Impersonation of Dotloop, a real estate transaction management platform." +type: "rule" +severity: "medium" +source: | + type.inbound + and ( + strings.ilike(sender.display_name, '*dotloop*') + or strings.ilike(sender.email.domain.domain, '*dotloop*') + ) + and sender.email.domain.root_domain not in~ ('dotloop.com', 'showingtime.com') + and ( + ( + profile.by_sender().prevalence in ("new", "outlier") + and not profile.by_sender().solicited + ) + or profile.by_sender().any_messages_malicious_or_spam + ) + and not profile.by_sender().any_false_positives + + // negate highly trusted sender domains unless they fail DMARC authentication + and ( + ( + sender.email.domain.root_domain in $high_trust_sender_root_domains + and ( + any(distinct(headers.hops, .authentication_results.dmarc is not null), + strings.ilike(.authentication_results.dmarc, "*fail") + ) + ) + ) + or sender.email.domain.root_domain not in $high_trust_sender_root_domains + ) +attack_types: + - "Credential Phishing" +tactics_and_techniques: + - "Impersonation: Brand" + - "Social engineering" +detection_methods: + - "Header analysis" + - "Sender analysis" +id: "f997581a-ca08-5b21-8a52-ee0ca78fcea5" From a8f7ce54543ad557c9ddbcd62b00800caba12172 Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Tue, 21 Nov 2023 10:36:19 -0800 Subject: [PATCH 10/19] Create impersonation_adobe_suspicious_language_link.yml (#1002) Co-authored-by: ID Generator Co-authored-by: Sam Scholten --- ...onation_adobe_suspicious_language_link.yml | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 detection-rules/impersonation_adobe_suspicious_language_link.yml diff --git a/detection-rules/impersonation_adobe_suspicious_language_link.yml b/detection-rules/impersonation_adobe_suspicious_language_link.yml new file mode 100644 index 00000000000..5cce19644c1 --- /dev/null +++ b/detection-rules/impersonation_adobe_suspicious_language_link.yml @@ -0,0 +1,63 @@ +name: "Brand impersonation: Adobe with suspicious language and link" +description: "Email contains an Adobe logo, at least one link, and suspicious link language from a new sender." +type: "rule" +severity: "high" +source: | + type.inbound + and length(attachments) == 0 + and length(body.links) > 0 + and any(ml.logo_detect(beta.message_screenshot()).brands, + .name == "Adobe" and .confidence in ("high") + ) + and ( + any(file.explode(beta.message_screenshot()), + strings.ilike(.scan.ocr.raw, + "*review*", + "*sign*", + "*view*", + "*completed document*", + "*open agreement*", + "*open document*" + ) + ) + or any(body.links, + strings.ilike(.display_text, + "*review*", + "*sign*", + "*view*", + "*completed document*", + "*open agreement*", + "*open document*" + ) + ) + ) + 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 + ) + ) + // negate highly trusted sender domains unless they fail DMARC authentication + and ( + ( + sender.email.domain.root_domain in $high_trust_sender_root_domains + and ( + any(distinct(headers.hops, .authentication_results.dmarc is not null), + strings.ilike(.authentication_results.dmarc, "*fail") + ) + ) + ) + or sender.email.domain.root_domain not in $high_trust_sender_root_domains + ) +attack_types: + - "Credential Phishing" +tactics_and_techniques: + - "Impersonation: Brand" + - "Social engineering" +detection_methods: + - "Computer Vision" + - "Content analysis" + - "Header analysis" + - "Sender analysis" +id: "32cc8bf1-f4d7-549f-a970-eade24b7c6ae" From d16b9bfba1cc5210d7da9304e93564af4375c6a7 Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Tue, 21 Nov 2023 15:27:38 -0500 Subject: [PATCH 11/19] Update impersonation_twitter.yml (#1017) --- detection-rules/impersonation_twitter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detection-rules/impersonation_twitter.yml b/detection-rules/impersonation_twitter.yml index 82ec602f085..2039f9bed6d 100644 --- a/detection-rules/impersonation_twitter.yml +++ b/detection-rules/impersonation_twitter.yml @@ -12,7 +12,7 @@ source: | or strings.ilevenshtein(sender.display_name, 'twitter') <= 1 or strings.ilike(sender.email.domain.domain, '*twitter*') ) - and sender.email.domain.domain not in~ ('twitter.com', 'privaterelay.appleid.com', 'stripe.com', 'x.com') + and sender.email.domain.domain not in~ ('twitter.com', 'privaterelay.appleid.com', 'stripe.com', 'x.com', 'twitter.discoursemail.com') and sender.email.email not in $recipient_emails attack_types: - "Credential Phishing" From 77a3865ea5531bfdaccbde63bbf1e133ca4ae5a1 Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Tue, 21 Nov 2023 16:50:37 -0500 Subject: [PATCH 12/19] Update link_deactivated_bitly.yml (#1018) --- detection-rules/link_deactivated_bitly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detection-rules/link_deactivated_bitly.yml b/detection-rules/link_deactivated_bitly.yml index 3f6202ab040..cb78681c762 100644 --- a/detection-rules/link_deactivated_bitly.yml +++ b/detection-rules/link_deactivated_bitly.yml @@ -11,7 +11,7 @@ source: | // link doesn't forward through and beta.linkanalysis(.).effective_url.domain.domain == "bit.ly" // blocked or gated by bit.ly - and strings.ilike(beta.linkanalysis(.).final_dom.display_text, "*link*blocked*", "*flagged*by*", "*been*deactivated*") + and strings.ilike(beta.linkanalysis(.).final_dom.display_text, "*link*blocked*", "*flagged*by*") ) attack_types: - "Credential Phishing" From 7e26202e2c4ca0b8d24e2dcfb45811658ec96e4a Mon Sep 17 00:00:00 2001 From: Josh Kamdjou Date: Tue, 21 Nov 2023 17:34:03 -0500 Subject: [PATCH 13/19] Add high trust (#1019) --- ...edential_phishing_intent_and_other_indicators.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) 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 c75a5b61962..02a008bb949 100644 --- a/detection-rules/link_credential_phishing_intent_and_other_indicators.yml +++ b/detection-rules/link_credential_phishing_intent_and_other_indicators.yml @@ -331,6 +331,18 @@ source: | and not profile.by_sender().any_false_positives ) ) + // negate highly trusted sender domains unless they fail DMARC authentication + and ( + ( + sender.email.domain.root_domain in $high_trust_sender_root_domains + and ( + any(distinct(headers.hops, .authentication_results.dmarc is not null), + strings.ilike(.authentication_results.dmarc, "*fail") + ) + ) + ) + or sender.email.domain.root_domain not in $high_trust_sender_root_domains + ) attack_types: - "Credential Phishing" tactics_and_techniques: From 67d7589b73d046c18633470236ddba20c86266ca Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Tue, 21 Nov 2023 17:38:27 -0500 Subject: [PATCH 14/19] Update qr_code_suspicious_indicators.yml (#1021) --- .../qr_code_suspicious_indicators.yml | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/detection-rules/qr_code_suspicious_indicators.yml b/detection-rules/qr_code_suspicious_indicators.yml index 838bf8e4756..ded089aca61 100644 --- a/detection-rules/qr_code_suspicious_indicators.yml +++ b/detection-rules/qr_code_suspicious_indicators.yml @@ -15,21 +15,27 @@ source: | // exclude images taken with mobile cameras and screenshots from android and not any(.scan.exiftool.fields, .key == "Model" - or .key == "Software" and strings.starts_with(.value, "Android") + or .key == "Software" + and strings.starts_with(.value, "Android") ) // exclude images taken with mobile cameras and screenshots from Apple and not any(.scan.exiftool.fields, - .key == "DeviceManufacturer" and .value == "Apple Computer Inc." + .key == "DeviceManufacturer" + and .value == "Apple Computer Inc." ) ) ) or ( length(attachments) == 0 - and any(file.explode(beta.message_screenshot()), .scan.qr.type is not null) + and any(file.explode(beta.message_screenshot()), + .scan.qr.type is not null and regex.contains(.scan.qr.data, '\.') + ) ) ) and ( - any(recipients.to, strings.icontains(sender.display_name, .email.domain.sld)) + any(recipients.to, + strings.icontains(sender.display_name, .email.domain.sld) + ) or length(body.current_thread.text) is null or body.current_thread.text == "" or regex.contains(subject.subject, @@ -37,11 +43,16 @@ source: | ) or (any(recipients.to, strings.icontains(subject.subject, .display_name))) or ( - (length(recipients.to) == 0 or all(recipients.to, .display_name == "Undisclosed recipients")) + ( + length(recipients.to) == 0 + or all(recipients.to, .display_name == "Undisclosed recipients") + ) and length(recipients.cc) == 0 and length(recipients.bcc) == 0 ) - or any(file.explode(beta.message_screenshot()), (.scan.qr.url.domain.tld in $suspicious_tlds)) + or any(file.explode(beta.message_screenshot()), + (.scan.qr.url.domain.tld in $suspicious_tlds) + ) or any(attachments, .file_type in $file_types_images and any(file.explode(.), .scan.qr.url.domain.tld in $suspicious_tlds) From 448cf016481a5dd6fb36677294511fb1853c311d Mon Sep 17 00:00:00 2001 From: Josh Kamdjou Date: Tue, 21 Nov 2023 17:46:09 -0500 Subject: [PATCH 15/19] New rule - Display name impersonation using recipient SLD (new sender) (#1010) Co-authored-by: ID Generator --- ...sonation_recipient_domain_display_name.yml | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 detection-rules/impersonation_recipient_domain_display_name.yml diff --git a/detection-rules/impersonation_recipient_domain_display_name.yml b/detection-rules/impersonation_recipient_domain_display_name.yml new file mode 100644 index 00000000000..8093026b2a9 --- /dev/null +++ b/detection-rules/impersonation_recipient_domain_display_name.yml @@ -0,0 +1,77 @@ +name: "Display name impersonation using recipient SLD (new sender)" +description: | + The recipient domain's SLD is used in the sender's display name + in order to impersonate the organization. +type: "rule" +severity: "medium" +source: | + type.inbound + and ( + // recipient SLD is being impersonated in the subject + display name + ( + // these are usually targeted with just 1 recipient, + // but sometimes they CC themselves or have a blank CC + length(recipients.to) + length(recipients.cc) + length(recipients.bcc) <= 2 + and any(recipients.to, + // ensure that we're checking the org SLD + .email.domain.sld in $org_slds + and strings.icontains(sender.display_name, .email.domain.sld) + ) + ) + or ( + // accounts for BCC'd messages where the recipients are empty + // if BCC, sometimes the recipient will be the attacker's email + length(recipients.to) + length(recipients.cc) + length(recipients.bcc) <= 2 + and strings.icontains(sender.display_name, mailbox.email.domain.sld) + ) + ) + + and ( + // at least 1 link or non-image attachment + ( + length(body.links) > 0 + // these attacks all use compromosed senders, so we look for a domain + // that doesn't match the sender's domain to weed out legit messages + and any(body.links, .href_url.domain.root_domain != sender.email.domain.root_domain) + ) + or length(filter(attachments, .file_type not in $file_types_images)) > 0 + ) + + and not ( + strings.contains(sender.display_name, "on behalf of") + and sender.email.domain.root_domain == "microsoftonline.com" + ) + + and all(recipients.to, .email.email != sender.email.email) + + // negate highly trusted sender domains unless they fail DMARC authentication + and ( + ( + sender.email.domain.root_domain in $high_trust_sender_root_domains + and ( + any(distinct(headers.hops, .authentication_results.dmarc is not null), + strings.ilike(.authentication_results.dmarc, "*fail") + ) + ) + ) + or sender.email.domain.root_domain not in $high_trust_sender_root_domains + ) + and ( + ( + profile.by_sender().prevalence in ("new", "outlier") + and not profile.by_sender().solicited + ) + or ( + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives + ) + ) + and not profile.by_sender().any_false_positives +attack_types: + - "Credential Phishing" +tactics_and_techniques: + - "Social engineering" +detection_methods: + - "Header analysis" + - "Sender analysis" +id: "81a8ed12-0e26-5998-90ae-03334f358704" From 6b00961dc18b94f3f09c88f87eaf58fab0d2e7a8 Mon Sep 17 00:00:00 2001 From: Josh Kamdjou Date: Tue, 21 Nov 2023 17:50:29 -0500 Subject: [PATCH 16/19] New rule - Display name and subject impersonation using recipient SLD (new sender) (#1011) Co-authored-by: ID Generator --- ..._recipient_domain_display_name_subject.yml | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 detection-rules/impersonation_recipient_domain_display_name_subject.yml diff --git a/detection-rules/impersonation_recipient_domain_display_name_subject.yml b/detection-rules/impersonation_recipient_domain_display_name_subject.yml new file mode 100644 index 00000000000..6b48c49a252 --- /dev/null +++ b/detection-rules/impersonation_recipient_domain_display_name_subject.yml @@ -0,0 +1,79 @@ +name: "Display name and subject impersonation using recipient SLD (new sender)" +description: | + The recipient domain's SLD is used in the sender's display name + and in the subject to impersonate the organization. +type: "rule" +severity: "medium" +source: | + type.inbound + and ( + // recipient SLD is being impersonated in the subject + display name + ( + // these are usually targeted with just 1 recipient, + // but sometimes they CC themselves or have a blank CC + length(recipients.to) + length(recipients.cc) + length(recipients.bcc) <= 2 + and any(recipients.to, + // ensure that we're checking the org SLD + .email.domain.sld in $org_slds + and strings.icontains(subject.subject, .email.domain.sld) + and strings.icontains(sender.display_name, .email.domain.sld) + ) + ) + or ( + // accounts for BCC'd messages where the recipients are empty + // if BCC, sometimes the recipient will be the attacker's email + length(recipients.to) + length(recipients.cc) + length(recipients.bcc) <= 2 + and strings.icontains(subject.subject, mailbox.email.domain.sld) + and strings.icontains(sender.display_name, mailbox.email.domain.sld) + ) + ) + + and ( + // at least 1 link or non-image attachment + ( + length(body.links) > 0 + // these attacks all use compromosed senders, so we look for a domain + // that doesn't match the sender's domain to weed out legit messages + and any(body.links, .href_url.domain.root_domain != sender.email.domain.root_domain) + ) + or length(filter(attachments, .file_type not in $file_types_images)) > 0 + ) + + and not ( + strings.contains(sender.display_name, "on behalf of") + and sender.email.domain.root_domain == "microsoftonline.com" + ) + + and all(recipients.to, .email.email != sender.email.email) + + // negate highly trusted sender domains unless they fail DMARC authentication + and ( + ( + sender.email.domain.root_domain in $high_trust_sender_root_domains + and ( + any(distinct(headers.hops, .authentication_results.dmarc is not null), + strings.ilike(.authentication_results.dmarc, "*fail") + ) + ) + ) + or sender.email.domain.root_domain not in $high_trust_sender_root_domains + ) + and ( + ( + profile.by_sender().prevalence in ("new", "outlier") + and not profile.by_sender().solicited + ) + or ( + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives + ) + ) + and not profile.by_sender().any_false_positives +attack_types: + - "Credential Phishing" +tactics_and_techniques: + - "Social engineering" +detection_methods: + - "Header analysis" + - "Sender analysis" +id: "cb2b3ed3-268f-5753-9d2b-194d2ee1ed2e" From cf5ed97d68f16aa33c5d24e1f712197b423fd24b Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Tue, 21 Nov 2023 15:04:36 -0800 Subject: [PATCH 17/19] Create links_recipient_email.yml (#1016) Co-authored-by: Sam Scholten --- insights/attachments/links_recipient_email.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 insights/attachments/links_recipient_email.yml diff --git a/insights/attachments/links_recipient_email.yml b/insights/attachments/links_recipient_email.yml new file mode 100644 index 00000000000..69527074ca4 --- /dev/null +++ b/insights/attachments/links_recipient_email.yml @@ -0,0 +1,12 @@ +name: "Recipient email in attachment link" +type: "query" +source: | + filter( + map(attachments, + map(file.explode(.), + distinct(map(filter(.scan.url.urls, any(recipients.to, strings.icontains(..url, .email.email))), .url), .) + ) + ), + length(.) > 0 + ) +severity: "medium" From 1b78311ff8a176e2601cdf4664a6db286cbead16 Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Tue, 21 Nov 2023 15:08:33 -0800 Subject: [PATCH 18/19] Create image_as_content_open_redir.yml (#1005) Co-authored-by: ID Generator --- .../image_as_content_open_redir.yml | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 detection-rules/image_as_content_open_redir.yml diff --git a/detection-rules/image_as_content_open_redir.yml b/detection-rules/image_as_content_open_redir.yml new file mode 100644 index 00000000000..8deb03c68b7 --- /dev/null +++ b/detection-rules/image_as_content_open_redir.yml @@ -0,0 +1,51 @@ +name: "Image as content linking to an open redirect" +description: "Body contains little, no, or only disclaimer text, and an image linking to an open redirect." +type: "rule" +severity: "high" +source: | + type.inbound + and length(body.links) < 3 + and 0 < (length(attachments)) < 3 + and all(attachments, (.file_type in $file_types_images)) + and ( + // body text is very short + ( + 0 <= (length(body.current_thread.text)) < 10 + or body.current_thread.text is null + ) + or ( + length(body.current_thread.text) < 900 + // or body is most likely all warning banner (text contains the sender and common warning banner language) + and ( + ( + strings.contains(body.current_thread.text, sender.email.email) + and strings.contains(body.current_thread.text, 'caution') + ) + or regex.icontains(body.current_thread.text, + "intended recipient's use only|external email|sent from outside|you don't often|confidential" + ) + ) + ) + ) + and ( + any(body.links, + any(.href_url.rewrite.encoders, strings.icontains(., "open_redirect")) + ) + or any(body.links, + .href_url.domain.root_domain == 'sng.link' + and strings.ilike(.href_url.query_params, "*fallback_redirect*") + ) + ) +attack_types: + - "Credential Phishing" + - "Malware/Ransomware" +tactics_and_techniques: + - "Evasion" + - "Image as content" + - "Open redirect" + - "Social engineering" +detection_methods: + - "Content analysis" + - "HTML analysis" + - "URL analysis" +id: "f5cec36b-76ea-5cd6-958b-74f819d73a47" From a3ed2863921641e5c6f653e7b744b2cb38b71547 Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Tue, 21 Nov 2023 15:13:11 -0800 Subject: [PATCH 19/19] Create recipient_address_in_link.yml (#1014) Co-authored-by: Sam Scholten --- insights/links/recipient_address_in_link.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 insights/links/recipient_address_in_link.yml diff --git a/insights/links/recipient_address_in_link.yml b/insights/links/recipient_address_in_link.yml new file mode 100644 index 00000000000..b81fd2924d7 --- /dev/null +++ b/insights/links/recipient_address_in_link.yml @@ -0,0 +1,7 @@ +name: "Recipient email in link" +type: "query" +source: | + distinct(map(filter(body.links, any(recipients.to, strings.icontains(..href_url.url, .email.email))), .href_url.url), .) +severity: "low" +tags: + - "Suspicious links"