From f95a7bb65ea54ff439f470ae0869b88a50f36d7a Mon Sep 17 00:00:00 2001 From: Cameron Dunn Date: Wed, 11 Dec 2024 10:23:21 -0800 Subject: [PATCH 01/43] Increase page size & debug test rule removal (#2211) --- .github/workflows/clear-old-test-rules.yml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/clear-old-test-rules.yml b/.github/workflows/clear-old-test-rules.yml index f0cefca1ccb..a5a06aef464 100644 --- a/.github/workflows/clear-old-test-rules.yml +++ b/.github/workflows/clear-old-test-rules.yml @@ -26,12 +26,15 @@ jobs: uses: actions/github-script@v4 with: script: | - github.pulls.list({ - owner: context.repo.owner, - repo: context.repo.repo, - state: 'open' - }).then((result) => { - const openPRs = result.data.map(pr => pr.number); + github.paginate( + github.pulls.list, + { + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + }, + (response) => response.data.map((pr) => pr.number) + ).then((openPRs) => { console.log(`::set-output name=open_prs::${openPRs.join(',')}`); }); @@ -43,6 +46,8 @@ jobs: echo "This is a forked repository. Skipping the job." exit 0 fi + + echo "Open PRs: [$OPEN_PRS]" echo "Scheduled cleanup" > message.txt echo "" >> message.txt @@ -61,6 +66,7 @@ jobs: fi done + echo "$file is in open PR: $in_open_pr. File PR num: $file_pr_num" if [[ "$in_open_pr" = "false" ]]; then rm $file echo "Removed $file_pr_num" >> ../message.txt From 450267aec485137c288e41e66d684a6518ff650d Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Thu, 12 Dec 2024 11:22:44 -0800 Subject: [PATCH 02/43] Update body_extortion.yml (#2207) --- detection-rules/body_extortion.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/detection-rules/body_extortion.yml b/detection-rules/body_extortion.yml index a37e4abde09..ebeb51ed28f 100644 --- a/detection-rules/body_extortion.yml +++ b/detection-rules/body_extortion.yml @@ -9,34 +9,34 @@ source: | type.inbound and ( ( - any(ml.nlu_classifier(body.current_thread.text).intents, + any(ml.nlu_classifier(strings.replace_confusables(body.current_thread.text)).intents, .name == "extortion" and .confidence == "high" ) - and any(ml.nlu_classifier(body.current_thread.text).entities, + and any(ml.nlu_classifier(strings.replace_confusables(body.current_thread.text)).entities, .name == "financial" ) ) // manual indicators failsafe or 3 of ( // malware terms - regex.icontains(body.current_thread.text, "((spy|mal)ware|trojan|remote control)"), + regex.icontains(strings.replace_confusables(body.current_thread.text), "((spy|mal)ware|trojan|remote control)"), // actions recorded - regex.icontains(body.current_thread.text, + regex.icontains(strings.replace_confusables(body.current_thread.text), "porn|adult (web)?site|webcam|masturbating|jerking off|pleasuring yourself|getting off" ), - regex.icontains(body.current_thread.text, "pervert|perversion|masturbat"), + regex.icontains(strings.replace_confusables(body.current_thread.text), "pervert|perversion|masturbat"), // a timeframe to pay - regex.icontains(body.current_thread.text, '\d\d hours', '(?:one|two|three|\d) days?'), + regex.icontains(strings.replace_confusables(body.current_thread.text), '\d\d hours', '(?:one|two|three|\d) days?'), // a promise from the actor - regex.icontains(body.current_thread.text, + regex.icontains(strings.replace_confusables(body.current_thread.text), 'permanently delete|(remove|destroy) (?:\w+\s*){0,4} (?:data|evidence|videos?)' ), // a threat from the actor - regex.icontains(body.current_thread.text, + regex.icontains(strings.replace_confusables(body.current_thread.text), 'sen[dt]\s*(?:\w+\s*){0,2}\s*to\s*(?:\w+\s*){0,3}\s*your contacts'), // bitcoin language (excluding newsletters) ( - regex.icontains(body.current_thread.text, 'bitcoin|\bbtc\b|blockchain') + regex.icontains(strings.replace_confusables(body.current_thread.text), 'bitcoin|\bbtc\b|blockchain') // negate cryptocurrency newsletters and not ( any(body.links, @@ -56,14 +56,14 @@ source: | ), // bitcoin wallet address + threat ( - strings.icontains(body.current_thread.text, + strings.icontains(strings.replace_confusables(body.current_thread.text), "contact the police" ) - and regex.icontains(body.current_thread.text, + and regex.icontains(strings.replace_confusables(body.current_thread.text), '(\b[13][a-km-zA-HJ-NP-Z0-9]{24,33}\b)|\bX[1-9A-HJ-NP-Za-km-z]{33}\b|\b(0x[a-fA-F0-9]{40})\b|\b[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}\b|\b[48][0-9AB][1-9A-HJ-NP-Za-km-z]{93}\b' ) ), - regex.icontains(body.current_thread.text, 'bc1q.{0,50}\b') + regex.icontains(strings.replace_confusables(body.current_thread.text), 'bc1q.{0,50}\b') ) ) and ( From 921ae3ccb47c71cf285ba0d11b70ed7a65486f76 Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Thu, 12 Dec 2024 11:23:24 -0800 Subject: [PATCH 03/43] Update attachment_free_subdomain_suspicious_link_language.yml (#2212) --- ...ree_subdomain_suspicious_link_language.yml | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/detection-rules/attachment_free_subdomain_suspicious_link_language.yml b/detection-rules/attachment_free_subdomain_suspicious_link_language.yml index 80600bb8977..b3436acbefc 100644 --- a/detection-rules/attachment_free_subdomain_suspicious_link_language.yml +++ b/detection-rules/attachment_free_subdomain_suspicious_link_language.yml @@ -10,12 +10,30 @@ source: | and .href_url.domain.subdomain is not null and .href_url.domain.subdomain != "www" ) - and (length(recipients.to) == 0 or all(recipients.to, .display_name == "Undisclosed recipients")) - and length(recipients.cc) == 0 - and length(recipients.bcc) == 0 + and ( + ( + ( + length(recipients.to) == 0 + or all(recipients.to, .display_name == "Undisclosed recipients") + ) + and length(recipients.cc) == 0 + and length(recipients.bcc) == 0 + ) + or ( + length(recipients.to) == 1 + and any(recipients.to, .email.email == sender.email.email) + ) + or ( + length(recipients.to) == 0 + and length(recipients.cc) == 0 + and length(recipients.bcc) > 0 + ) + ) and any(body.links, any(file.explode(ml.link_analysis(.).screenshot), - any(ml.nlu_classifier(.scan.ocr.raw).intents, .name == "cred_theft" and .confidence != "low") + any(ml.nlu_classifier(.scan.ocr.raw).intents, + .name == "cred_theft" and .confidence != "low" + ) ) ) tags: From 18af1961656ccedf3d1b834173838a0114d57c53 Mon Sep 17 00:00:00 2001 From: Peter Djordjevic <116412909+peterdj45@users.noreply.github.com> Date: Thu, 12 Dec 2024 12:11:06 -0800 Subject: [PATCH 04/43] Update impersonation_vip_urgent_request.yml (#2087) Co-authored-by: Sam Scholten --- detection-rules/impersonation_vip_urgent_request.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/detection-rules/impersonation_vip_urgent_request.yml b/detection-rules/impersonation_vip_urgent_request.yml index bad63d6041b..e955fde6c2b 100644 --- a/detection-rules/impersonation_vip_urgent_request.yml +++ b/detection-rules/impersonation_vip_urgent_request.yml @@ -31,7 +31,12 @@ source: | and not profile.by_sender().any_false_positives ) ) - + // negate sharepoint notifications originating from within the org + and not ( + sender.email.email in ('no-reply@sharepointonline.com') + and length(headers.reply_to) > 0 + and all(headers.reply_to, .email.domain.root_domain in $org_domains) + ) // negate highly trusted sender domains unless they fail DMARC authentication and ( ( From 4e8a5ebdca831989460984f834af0ea292466c19 Mon Sep 17 00:00:00 2001 From: Peter Djordjevic <116412909+peterdj45@users.noreply.github.com> Date: Fri, 13 Dec 2024 08:21:14 -0800 Subject: [PATCH 05/43] Update suspicious_request_for_quote_or_purchase.yml (#2217) --- detection-rules/suspicious_request_for_quote_or_purchase.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detection-rules/suspicious_request_for_quote_or_purchase.yml b/detection-rules/suspicious_request_for_quote_or_purchase.yml index cb5738d04f6..4253793cd24 100644 --- a/detection-rules/suspicious_request_for_quote_or_purchase.yml +++ b/detection-rules/suspicious_request_for_quote_or_purchase.yml @@ -39,7 +39,7 @@ source: | '(sign(ed?)|view).{0,10}(purchase order)|Request for a Quot(e|ation)' ) ), - (regex.icontains(body.current_thread.text, '(please|kindly).{0,30}quote')), + (regex.icontains(body.current_thread.text, '(please|kindly).{0,30}quot(e|ation)')), ( regex.icontains(subject.subject, '(request for (purchase|quot(e|ation))|\bRFQ\b|\bRFP\b)' From eaff6101908b2dc169cc6729f01c0a3e1aae3d5b Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Fri, 13 Dec 2024 08:43:51 -0800 Subject: [PATCH 06/43] Update impersonation_sharepoint_fake_file_share.yml (#2213) --- detection-rules/impersonation_sharepoint_fake_file_share.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detection-rules/impersonation_sharepoint_fake_file_share.yml b/detection-rules/impersonation_sharepoint_fake_file_share.yml index b24422a89ef..25d3ad383fc 100644 --- a/detection-rules/impersonation_sharepoint_fake_file_share.yml +++ b/detection-rules/impersonation_sharepoint_fake_file_share.yml @@ -264,7 +264,7 @@ source: | or sender.email.domain.root_domain not in $high_trust_sender_root_domains ) and ( - (not profile.by_sender().solicited) + not profile.by_sender_email().solicited or ( profile.by_sender().any_messages_malicious_or_spam and not profile.by_sender().any_false_positives From 5f67fa175dfd1548b359591240899e7469305b99 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Mon, 16 Dec 2024 07:49:44 -0600 Subject: [PATCH 07/43] Update impersonation_sharepoint_fake_file_share.yml (#2219) Co-authored-by: Sam Scholten --- ...personation_sharepoint_fake_file_share.yml | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/detection-rules/impersonation_sharepoint_fake_file_share.yml b/detection-rules/impersonation_sharepoint_fake_file_share.yml index 25d3ad383fc..024f1f19389 100644 --- a/detection-rules/impersonation_sharepoint_fake_file_share.yml +++ b/detection-rules/impersonation_sharepoint_fake_file_share.yml @@ -15,7 +15,9 @@ source: | "*shared a file with you*", "*shared with you*", "*invited you to access a file*", - "*you've received a document*" + "*received a document*", + "*shared a document*", + "*shared this document*" ) ) or any(file.explode(beta.message_screenshot()), @@ -23,7 +25,9 @@ source: | "*shared a file with you*", "*shared with you*", "*invited you to access a file*", - "*you've received a document*" + "*received a document*", + "*shared a document*", + "*shared this document*" ) ) ) @@ -40,8 +44,14 @@ source: | "*PowerPoint*", "*OneNote*" ) + or any(body.links, strings.icontains(.display_text, "OPEN DOCUMENT")) or subject.subject is null or subject.subject == "" + // the org as determined by NLU is in the subject + or any(ml.nlu_classifier(body.current_thread.text).entities, + .name == "org" and strings.icontains(subject.subject, .text) + ) + ) ) or any([ @@ -210,7 +220,7 @@ source: | regex.icontains(body.html.raw, 'rgb\((25[0-5]),\s?(20[0-2]),\s?([0-7])\)') ) or regex.icontains(body.html.raw, - ']+style="[^"]*background-color:\s*#[0-9A-F]{2}[5-9A-F]{2}[0-9A-F]{2}[^"]*"[^>]*>[^<]*(?:open)[^<]*' // blue button containing the word "open" + ']+style="[^"]*background-color:\s*#[0-9A-F]{2}[5-9A-F]{2}[0-9A-F]{2}[^"]*"[^>]*>[^<]*(?:open)[^<]*' // blue button containing the word "open" ) or ( any(recipients.to, @@ -264,7 +274,8 @@ source: | or sender.email.domain.root_domain not in $high_trust_sender_root_domains ) and ( - not profile.by_sender_email().solicited + profile.by_sender().solicited == false + or profile.by_sender_email().prevalence == "new" or ( profile.by_sender().any_messages_malicious_or_spam and not profile.by_sender().any_false_positives From c4dd4865e34fe5a6950c506c862629d66cc2a1d4 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Mon, 16 Dec 2024 07:49:56 -0600 Subject: [PATCH 08/43] Update impersonation_employee_payroll_fraud.yml (#2220) --- detection-rules/impersonation_employee_payroll_fraud.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detection-rules/impersonation_employee_payroll_fraud.yml b/detection-rules/impersonation_employee_payroll_fraud.yml index a2bbff19da2..b7c8409840e 100644 --- a/detection-rules/impersonation_employee_payroll_fraud.yml +++ b/detection-rules/impersonation_employee_payroll_fraud.yml @@ -26,7 +26,7 @@ source: | ) ) and ( - not profile.by_sender().solicited + not profile.by_sender_email().solicited or ( profile.by_sender().any_messages_malicious_or_spam and not profile.by_sender().any_false_positives From 9cbe2f678aa615697d1ed15b80e72bc7e551dcd5 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Mon, 16 Dec 2024 09:08:16 -0600 Subject: [PATCH 09/43] Update impersonation_x_with_credphish_nlu.yml (#2221) --- detection-rules/impersonation_x_with_credphish_nlu.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/detection-rules/impersonation_x_with_credphish_nlu.yml b/detection-rules/impersonation_x_with_credphish_nlu.yml index 3ebc1eda1d1..37523123103 100644 --- a/detection-rules/impersonation_x_with_credphish_nlu.yml +++ b/detection-rules/impersonation_x_with_credphish_nlu.yml @@ -30,6 +30,7 @@ source: | profile.by_sender().any_messages_malicious_or_spam and not profile.by_sender().any_false_positives ) + or sender.email.email in ("noreply@salesforce.com", "support@salesforce.com") ) // negate highly trusted sender domains unless they fail DMARC authentication @@ -39,6 +40,9 @@ source: | and not headers.auth_summary.dmarc.pass ) or sender.email.domain.root_domain not in $high_trust_sender_root_domains + + // salesforce has been abused for x/twitter phishing campaigns repeatedly + or sender.email.domain.root_domain == "salesforce.com" ) attack_types: - "Credential Phishing" From ddbc3da7e6b3e30017038dae1f38ce6ded8d79e8 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Mon, 16 Dec 2024 09:08:32 -0600 Subject: [PATCH 10/43] Create abuse_quickbooks_impersonation_intuit.yml (#2054) Co-authored-by: ID Generator Co-authored-by: Aiden Mitchell --- .../abuse_quickbooks_impersonation_intuit.yml | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 detection-rules/abuse_quickbooks_impersonation_intuit.yml diff --git a/detection-rules/abuse_quickbooks_impersonation_intuit.yml b/detection-rules/abuse_quickbooks_impersonation_intuit.yml new file mode 100644 index 00000000000..f2cbfede2ed --- /dev/null +++ b/detection-rules/abuse_quickbooks_impersonation_intuit.yml @@ -0,0 +1,43 @@ +name: "Brand Impersonation: QuickBooks Notification From Intuit Themed Company Name" +description: "This detection rule matches on QuickBooks notifications that feature company names impersonating Intuit and QuickBooks." +type: "rule" +severity: "medium" +source: | + type.inbound + + // Legitimate Intuit sending infratructure + and sender.email.email == "quickbooks@notification.intuit.com" + and headers.auth_summary.spf.pass + and headers.auth_summary.dmarc.pass + and strings.ends_with(headers.auth_summary.spf.details.designator, + '.intuit.com' + ) + and ( + // subject also contains the company name + strings.icontains(subject.subject, "Quickbooks") + or strings.icontains(subject.subject, "Intuit") + // the reply-to contains Inuit Themes + or any(headers.reply_to, + ( + strings.icontains(.email.email, 'intuit') + or strings.icontains(.email.domain.domain, 'quickbooks') + ) + and not (.email.domain.root_domain in ('intuit.com', 'quickbooks.com')) + ) + // the "company" part of the message + or regex.icontains(body.html.raw, + '

.*(?:Intuit|Quickbooks).*

' + ) + ) +attack_types: + - "Callback Phishing" + - "Credential Phishing" + - "BEC/Fraud" +tactics_and_techniques: + - "Evasion" + - "Social engineering" +detection_methods: + - "Content analysis" + - "Sender analysis" + - "Header analysis" +id: "42058fc4-d700-5bc3-9ee9-91641d9343c2" From ab0c1f38bd00972523f8bbad42423e7ab2a1d967 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Mon, 16 Dec 2024 09:09:42 -0600 Subject: [PATCH 11/43] Update abuse_docusign_unsolicited_reply-to.yml (#2204) --- detection-rules/abuse_docusign_unsolicited_reply-to.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detection-rules/abuse_docusign_unsolicited_reply-to.yml b/detection-rules/abuse_docusign_unsolicited_reply-to.yml index 07fe308cdf3..4fa5b80c72a 100644 --- a/detection-rules/abuse_docusign_unsolicited_reply-to.yml +++ b/detection-rules/abuse_docusign_unsolicited_reply-to.yml @@ -44,7 +44,7 @@ source: | or .email.domain.domain not in $free_email_providers ) ), - .email.domain.root_domain in $sender_domains + .email.domain.domain in $sender_domains ) ) tags: From bb05c14ec13032ff4d247f79b52cc1ae8ba65420 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Mon, 16 Dec 2024 09:10:02 -0600 Subject: [PATCH 12/43] Update impersonation_usps.yml (#2206) --- detection-rules/impersonation_usps.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/detection-rules/impersonation_usps.yml b/detection-rules/impersonation_usps.yml index 2f6b310cc6e..d730a013bdd 100644 --- a/detection-rules/impersonation_usps.yml +++ b/detection-rules/impersonation_usps.yml @@ -26,11 +26,16 @@ source: | // no links go to usps.com all(body.links, .href_url.domain.root_domain != "usps.com") ) - and ( - sender.email.domain.root_domain not in ("usps.com") + sender.email.domain.root_domain not in ( + "usps.com", + "opinions-inmoment.com" // https://faq.usps.com/s/article/USPS-Customer-Experience-Surveys + ) or ( - sender.email.domain.root_domain in ("usps.com") + sender.email.domain.root_domain in ( + "usps.com", + "opinions-inmoment.com" // https://faq.usps.com/s/article/USPS-Customer-Experience-Surveys + ) and not headers.auth_summary.dmarc.pass ) ) From 214b2a603dd3e8384e30b2a80d5477293d3a364c Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Mon, 16 Dec 2024 09:10:26 -0600 Subject: [PATCH 13/43] Update impersonation_paypal.yml (#2208) --- detection-rules/impersonation_paypal.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/detection-rules/impersonation_paypal.yml b/detection-rules/impersonation_paypal.yml index eb9a0edaa07..3f02037438b 100644 --- a/detection-rules/impersonation_paypal.yml +++ b/detection-rules/impersonation_paypal.yml @@ -8,9 +8,9 @@ severity: "medium" source: | type.inbound and ( - sender.display_name =~ "paypal" - or strings.ilevenshtein(sender.display_name, 'paypal') <= 1 - or strings.ilike(sender.email.domain.domain, '*paypal*') + strings.replace_confusables(sender.display_name) =~ "paypal" + or strings.ilevenshtein(strings.replace_confusables(sender.display_name), 'paypal') <= 1 + or strings.ilike(strings.replace_confusables(sender.display_name), '*paypal*') or any(attachments, (.file_type in $file_types_images or .file_type == "pdf") and any(ml.logo_detect(.).brands, .name == "PayPal") From e9eb47533f7f963b82d1cb155e34989c26343923 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Mon, 16 Dec 2024 09:10:40 -0600 Subject: [PATCH 14/43] Update link_multistage_adobe_express.yml (#2209) --- .../link_multistage_adobe_express.yml | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/detection-rules/link_multistage_adobe_express.yml b/detection-rules/link_multistage_adobe_express.yml index 696391ccaf7..3578e588fdc 100644 --- a/detection-rules/link_multistage_adobe_express.yml +++ b/detection-rules/link_multistage_adobe_express.yml @@ -4,12 +4,25 @@ type: "rule" severity: "high" source: | type.inbound - and any(body.links, - // it is a new.express.adobe.com page - .href_url.domain.domain == "new.express.adobe.com" - and strings.starts_with(.href_url.path, "/webpage/") - - // filter down the links on express.adobe.com page to those that are external to adobe + and any(filter(body.links, + // the link is a new.express.adobe.com page + .href_url.domain.domain == "new.express.adobe.com" + and strings.starts_with(.href_url.path, "/webpage/") + ), + // filter down the links on express.adobe.com page to those that are external to adobe + // check that the length of external links is reasonable + length(distinct(filter(ml.link_analysis(., mode="aggressive").final_dom.links, + // filter any links on the adobe express page which are + // on express.adobe.com + .href_url.domain.domain != 'new.express.adobe.com' + // or www.adobe.com (privacy page/report abuse/etc) + and .href_url.domain.domain != 'www.adobe.com' + // relative links (no domains) + and .href_url.domain.domain is not null + ), + .href_url.domain.domain + ) + ) <= 10 and any(filter(ml.link_analysis(., mode="aggressive").final_dom.links, // filter any links on the adobe express page which are // on express.adobe.com From 7c75163ea0fdd1af57639b25db2e730646c3687a Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Mon, 16 Dec 2024 09:11:05 -0600 Subject: [PATCH 15/43] Update link_microsoft_low_reputation.yml (#2214) --- detection-rules/link_microsoft_low_reputation.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/detection-rules/link_microsoft_low_reputation.yml b/detection-rules/link_microsoft_low_reputation.yml index af2dc0dd9ca..83c4e1b605d 100644 --- a/detection-rules/link_microsoft_low_reputation.yml +++ b/detection-rules/link_microsoft_low_reputation.yml @@ -70,7 +70,8 @@ source: | .file_type in $file_types_images and any(ml.logo_detect(.).brands, strings.starts_with(.name, "Microsoft")) ) - or strings.istarts_with(body.current_thread.text, "Microsoft ") + or strings.istarts_with(strings.replace_confusables(body.current_thread.text), "Microsoft ") + or regex.icontains(strings.replace_confusables(body.current_thread.text), '(?:^|\n)[o0O]ff[il1]ce\b') or any(ml.logo_detect(beta.message_screenshot()).brands, strings.starts_with(.name, "Microsoft") ) @@ -331,7 +332,7 @@ source: | "sharepointonline.com", "yammer.com", ) - + // negate legitimate Office 365 bouncebacks and not ( length(attachments) > 0 @@ -340,7 +341,7 @@ source: | ) and (sender.email.local_part in ('postmaster', 'mailer-daemon')) ) - + // negate Microsoft "welcome to the X group" notifications and not ( headers.auth_summary.dmarc.pass From a0f0c1a4a2d753183f200e83e00bcef66b6f86b8 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Mon, 16 Dec 2024 09:11:28 -0600 Subject: [PATCH 16/43] Update abuse_dropbox_sus_names.yml (#2218) --- detection-rules/abuse_dropbox_sus_names.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/detection-rules/abuse_dropbox_sus_names.yml b/detection-rules/abuse_dropbox_sus_names.yml index 982458a9a1c..51a683658fd 100644 --- a/detection-rules/abuse_dropbox_sus_names.yml +++ b/detection-rules/abuse_dropbox_sus_names.yml @@ -58,8 +58,10 @@ source: | // the filename is also contianed in the subject line or ( + // untitled.paper + regex.icontains(subject.subject, 'shared.*\"Untitled.paper') // scanner themed - regex.icontains(subject.subject, 'shared.*\".*scanne[rd]') + or regex.icontains(subject.subject, 'shared.*\".*scanne[rd]') // image theme or regex.icontains(subject.subject, 'shared.*\".*_IMG_') or regex.icontains(subject.subject, 'shared.*\".*IMG[_-](?:\d|\W)+\"') From 110ef6d2d23b6020535bf31b2f466658c4aada19 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Mon, 16 Dec 2024 09:12:27 -0600 Subject: [PATCH 17/43] Update attachment_extortion.yml (#2201) --- detection-rules/attachment_extortion.yml | 192 ++++++++++++++++------- 1 file changed, 137 insertions(+), 55 deletions(-) diff --git a/detection-rules/attachment_extortion.yml b/detection-rules/attachment_extortion.yml index 144ac7ef31b..c6efe4cdae9 100644 --- a/detection-rules/attachment_extortion.yml +++ b/detection-rules/attachment_extortion.yml @@ -15,68 +15,150 @@ source: | ) ) and any(attachments, - (.file_type in $file_types_images or .file_type == "pdf") - and any(filter(file.explode(.), .scan.ocr.raw is not null), - ( - any(ml.nlu_classifier(.scan.ocr.raw).intents, - .name == "extortion" and .confidence == "high" - ) - and any(ml.nlu_classifier(.scan.ocr.raw).entities, - .name == "financial" + // use ocr output from file.explode on pdfs/images + ( + (.file_type in $file_types_images or .file_type == "pdf") + and any(filter(file.explode(.), .scan.ocr.raw is not null), + ( + any(ml.nlu_classifier(.scan.ocr.raw).intents, + .name == "extortion" and .confidence == "high" + ) + and any(ml.nlu_classifier(.scan.ocr.raw).entities, + .name == "financial" + ) ) - ) - or 3 of ( - // malware terms - regex.icontains(.scan.ocr.raw, "((spy|mal)ware|trojan|remote control)"), - // actions recorded - regex.icontains(.scan.ocr.raw, - "porn|adult (web)?site|webcam|masturbating|jerking off|pleasuring yourself|getting off" - ), - regex.icontains(.scan.ocr.raw, - "pervert|perversion|masturbat" - ), - // a timeframe to pay - regex.icontains(.scan.ocr.raw, '\d\d hours', '(?:one|two|three) days?'), - // a promise from the actor - regex.icontains(.scan.ocr.raw, + or 3 of ( + // malware terms + regex.icontains(.scan.ocr.raw, + "((spy|mal)ware|trojan|remote control)" + ), + // actions recorded + regex.icontains(.scan.ocr.raw, + "porn|adult (web)?site|webcam|masturbating|jerking off|pleasuring yourself|getting off" + ), + regex.icontains(.scan.ocr.raw, + "pervert|perversion|masturbat" + ), + // a timeframe to pay + regex.icontains(.scan.ocr.raw, + '\d\d hours', + '(?:one|two|three) days?' + ), + // a promise from the actor + regex.icontains(.scan.ocr.raw, 'permanently delete|destroy (?:\w+\s*){0,4} (?:data|evidence|videos?)' - ), - // a threat from the actor - regex.icontains(.scan.ocr.raw, - 'sen[dt]\s*(?:\w+\s*){0,2}\s*to\s*(?:\w+\s*){0,3}\s*your contacts'), - // bitcoin - ( + ), + // a threat from the actor regex.icontains(.scan.ocr.raw, - 'bitcoin|\bbtc\b|blockchain' - ) - // negate cryptocurrency newsletters - and not ( - any(body.links, - strings.icontains(.display_text, "unsubscribe") - and ( - strings.icontains(.href_url.path, "unsubscribe") - // handle mimecast URL rewrites - or ( - .href_url.domain.root_domain == 'mimecastprotect.com' - and strings.icontains(.href_url.query_params, - sender.email.domain.root_domain + 'sen[dt]\s*(?:\w+\s*){0,2}\s*to\s*(?:\w+\s*){0,3}\s*your contacts' + ), + // bitcoin + ( + regex.icontains(.scan.ocr.raw, + 'bitcoin|\bbtc\b|blockchain' + ) + // negate cryptocurrency newsletters + and not ( + any(body.links, + strings.icontains(.display_text, "unsubscribe") + and ( + strings.icontains(.href_url.path, "unsubscribe") + // handle mimecast URL rewrites + or ( + .href_url.domain.root_domain == 'mimecastprotect.com' + and strings.icontains(.href_url.query_params, + sender.email.domain.root_domain + ) ) ) - ) + ) ) - ) - ), - // bitcoin wallet address + threat - ( - strings.icontains(.scan.ocr.raw, - "contact the police" - ) - and regex.icontains(.scan.ocr.raw, - '(\b[13][a-km-zA-HJ-NP-Z0-9]{24,33}\b)|\bX[1-9A-HJ-NP-Za-km-z]{33}\b|\b(0x[a-fA-F0-9]{40})\b|\b[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}\b|\b[48][0-9AB][1-9A-HJ-NP-Za-km-z]{93}\b' - ) - ), - regex.icontains(.scan.ocr.raw, 'bc1q.{0,50}\b') + ), + // bitcoin wallet address + threat + ( + strings.icontains(.scan.ocr.raw, "contact the police") + and regex.icontains(.scan.ocr.raw, + '(\b[13][a-km-zA-HJ-NP-Z0-9]{24,33}\b)|\bX[1-9A-HJ-NP-Za-km-z]{33}\b|\b(0x[a-fA-F0-9]{40})\b|\b[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}\b|\b[48][0-9AB][1-9A-HJ-NP-Za-km-z]{93}\b' + ) + ), + regex.icontains(.scan.ocr.raw, 'bc1q.{0,50}\b') + ) + ) + ) + or + // use beta.parse_text on plain text files + ( + ( + .file_extension in ("txt") + and ( + ( + any(ml.nlu_classifier(beta.parse_text(.).text).intents, + .name == "extortion" and .confidence == "high" ) + and any(ml.nlu_classifier(beta.parse_text(.).text).entities, + .name == "financial" + ) + ) + or 3 of ( + // malware terms + regex.icontains(beta.parse_text(.).text, + "((spy|mal)ware|trojan|remote control)" + ), + // actions recorded + regex.icontains(beta.parse_text(.).text, + "porn|adult (web)?site|webcam|masturbating|jerking off|pleasuring yourself|getting off" + ), + regex.icontains(beta.parse_text(.).text, + "pervert|perversion|masturbat" + ), + // a timeframe to pay + regex.icontains(beta.parse_text(.).text, + '\d\d hours', + '(?:one|two|three) days?' + ), + // a promise from the actor + regex.icontains(beta.parse_text(.).text, + 'permanently delete|destroy (?:\w+\s*){0,4} (?:data|evidence|videos?)' + ), + // a threat from the actor + regex.icontains(beta.parse_text(.).text, + 'sen[dt]\s*(?:\w+\s*){0,2}\s*to\s*(?:\w+\s*){0,3}\s*your contacts' + ), + // bitcoin + ( + regex.icontains(beta.parse_text(.).text, + 'bitcoin|\bbtc\b|blockchain' + ) + // negate cryptocurrency newsletters + and not ( + any(body.links, + strings.icontains(.display_text, "unsubscribe") + and ( + strings.icontains(.href_url.path, "unsubscribe") + // handle mimecast URL rewrites + or ( + .href_url.domain.root_domain == 'mimecastprotect.com' + and strings.icontains(.href_url.query_params, + sender.email.domain.root_domain + ) + ) + ) + ) + ) + ), + // bitcoin wallet address + threat + ( + strings.icontains(beta.parse_text(.).text, + "contact the police" + ) + and regex.icontains(beta.parse_text(.).text, + '(\b[13][a-km-zA-HJ-NP-Z0-9]{24,33}\b)|\bX[1-9A-HJ-NP-Za-km-z]{33}\b|\b(0x[a-fA-F0-9]{40})\b|\b[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}\b|\b[48][0-9AB][1-9A-HJ-NP-Za-km-z]{93}\b' + ) + ), + regex.icontains(beta.parse_text(.).text, 'bc1q.{0,50}\b') + ) + ) + ) ) ) and ( From fc6e8997501ba43334eaae55a42ac73013936116 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Mon, 16 Dec 2024 09:13:00 -0600 Subject: [PATCH 18/43] Update abuse_docusign_sus_names.yml (#2205) --- detection-rules/abuse_docusign_sus_names.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detection-rules/abuse_docusign_sus_names.yml b/detection-rules/abuse_docusign_sus_names.yml index 1e0aee78607..96b8507f448 100644 --- a/detection-rules/abuse_docusign_sus_names.yml +++ b/detection-rules/abuse_docusign_sus_names.yml @@ -42,7 +42,7 @@ source: | or .email.domain.domain not in $free_email_providers ) ), - .email.domain.root_domain in $sender_domains + .email.domain.domain in $sender_domains ) ) From 7cf05c226f7f864390e6f1935a274f828dff6b5d Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Mon, 16 Dec 2024 09:16:01 -0600 Subject: [PATCH 19/43] Create abuse_google_drive_unsolicited_reply-to.yml (#2185) Co-authored-by: ID Generator --- ...buse_google_drive_unsolicited_reply-to.yml | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 detection-rules/abuse_google_drive_unsolicited_reply-to.yml diff --git a/detection-rules/abuse_google_drive_unsolicited_reply-to.yml b/detection-rules/abuse_google_drive_unsolicited_reply-to.yml new file mode 100644 index 00000000000..c0e47f3c1e1 --- /dev/null +++ b/detection-rules/abuse_google_drive_unsolicited_reply-to.yml @@ -0,0 +1,57 @@ +name: "Service Abuse: Google Drive Share From an Unsolicited Reply-To Address" +description: "Identifies messages appearing to come from Google Drive sharing notifications that contain a reply-to address not previously seen in organizational communications. This tactic exploits trust in legitimate Google services while attempting to establish unauthorized communication channels." +type: "rule" +severity: "medium" +source: | + type.inbound + and sender.email.email in ( + 'drive-shares-dm-noreaply@google.com', + 'drive-shares-noreply@google.com', + ) + and not any(headers.reply_to, .email.domain.domain in $org_domains) + + // the message needs to have a reply-to address + and length(headers.reply_to) > 0 + + // reply-to email address has never been sent an email by the org + and not ( + any(headers.reply_to, .email.email in $recipient_emails) + // if the reply-to email address is NOT in free_email_providers, check the domain in recipient_domains + or any(filter(headers.reply_to, + // filter the list to only emails that are not in free_email_providers + ( + .email.domain.domain not in $free_email_providers + or .email.domain.root_domain not in $free_email_providers + ) + ), + .email.domain.domain in $recipient_domains + ) + ) + // reply-to address has never sent an email to the org + and not ( + any(headers.reply_to, .email.email in $sender_emails) + // if the reply-to address is NOT in free_email_providers, check the domain in sender_domains + or any(filter(headers.reply_to, + // filter the list to only emails that are not in free_email_providers + ( + .email.domain.domain not in $free_email_providers + or .email.domain.domain not in $free_email_providers + ) + ), + .email.domain.root_domain in $sender_domains + ) + ) +tags: + - "Attack surface reduction" +attack_types: + - "BEC/Fraud" + - "Callback Phishing" + - "Credential Phishing" +tactics_and_techniques: + - "Free email provider" + - "Social engineering" + - "Free file host" +detection_methods: + - "Header analysis" + - "Sender analysis" +id: "4581ec0c-aed2-50ed-8e16-2c9ca1d350ff" From 621394d719a9cc779ba51daeb33e6c594b7bee15 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Mon, 16 Dec 2024 09:19:00 -0600 Subject: [PATCH 20/43] Update link_fake_password_expiration.yml (#2215) --- .../link_fake_password_expiration.yml | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/detection-rules/link_fake_password_expiration.yml b/detection-rules/link_fake_password_expiration.yml index b9d1bc57bc2..fa96f7828c7 100644 --- a/detection-rules/link_fake_password_expiration.yml +++ b/detection-rules/link_fake_password_expiration.yml @@ -5,8 +5,8 @@ severity: "medium" source: | type.inbound - // few links - and 0 < length(body.links) < 10 + // few links which are not in $org_domains + and 0 < length(filter(body.links, .href_url.domain.domain not in $org_domains)) <= 10 // no attachments or suspicious attachment and ( @@ -17,6 +17,18 @@ source: | .scan.entropy.entropy > 7 and length(.scan.ocr.raw) < 20 ) ) + // or there are duplicate pdfs in name + or ( + length(filter(attachments, .file_type == "pdf")) > length(distinct(filter(attachments, + .file_type == "pdf" + ), + .file_name + ) + ) + or + // all PDFs are the same MD5 + length(distinct(filter(attachments, .file_type == "pdf"), .md5)) == 1 + ) ) // body contains expire, expiration, loose, lose @@ -93,11 +105,13 @@ source: | ) or regex.icontains(body.html.raw, '(?:

\s* \s*

\s*){7,}') or regex.icontains(body.html.raw, '(?:

\s* \s*

\s*
\s*){7,}') - or regex.icontains(body.html.raw, '(?:]*>\s* \s*
\s*

\s*){5,}') + or regex.icontains(body.html.raw, + '(?:]*>\s* \s*
\s*

\s*){5,}' + ) or regex.icontains(body.html.raw, '(?:]*> 

\s*){7,}') ) ) - + // a body link does not match the sender domain and any(body.links, .href_url.domain.root_domain != sender.email.domain.root_domain From be50bd0652ef108c00015a6cd0dada1e4b19c149 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Mon, 16 Dec 2024 09:19:55 -0600 Subject: [PATCH 21/43] Create abuse_quickbooks_new_domain.yml (#2052) Co-authored-by: ID Generator --- .../abuse_quickbooks_new_domain.yml | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 detection-rules/abuse_quickbooks_new_domain.yml diff --git a/detection-rules/abuse_quickbooks_new_domain.yml b/detection-rules/abuse_quickbooks_new_domain.yml new file mode 100644 index 00000000000..c05a552f12e --- /dev/null +++ b/detection-rules/abuse_quickbooks_new_domain.yml @@ -0,0 +1,45 @@ +name: "Service Abuse: QuickBooks Notification From New Domain" +description: "This Attack Surface Reduction (ASR) rule matches on QuickBooks notifications with recently registered reply-to domains." +type: "rule" +severity: "medium" +source: | + type.inbound + + // Legitimate Intuit sending infratructure + and sender.email.email == "quickbooks@notification.intuit.com" + and headers.auth_summary.spf.pass + and headers.auth_summary.dmarc.pass + and strings.ends_with(headers.auth_summary.spf.details.designator, + '.intuit.com' + ) + + // remove payment confirmation messages + and not strings.starts_with(subject.subject, 'Payment confirmation:') + + // the message needs to have a reply-to address + and length(headers.reply_to) > 0 + + // reply-to email address has never received an email from your org + and not any(headers.reply_to, .email.email in $recipient_emails) + + // new reply-to + and any(filter(headers.reply_to, + // negate .com.au which doesn't provide created date for domains + .email.domain.tld not in ('com.au') + ), + network.whois(.email.domain).days_old < 30 + ) +tags: + - "Attack surface reduction" +attack_types: + - "Callback Phishing" + - "Credential Phishing" + - "BEC/Fraud" +tactics_and_techniques: + - "Evasion" + - "Social engineering" +detection_methods: + - "Content analysis" + - "Sender analysis" + - "Header analysis" +id: "c4f46473-0f5a-56d6-bb7e-489460bdb20f" From b337c7f1dbe94aa9de9374791ae7faf4dfc802bd Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Mon, 16 Dec 2024 09:20:09 -0600 Subject: [PATCH 22/43] Create abuse_quickbooks_suspicious_comments.yml (#2053) Co-authored-by: ID Generator --- .../abuse_quickbooks_suspicious_comments.yml | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 detection-rules/abuse_quickbooks_suspicious_comments.yml diff --git a/detection-rules/abuse_quickbooks_suspicious_comments.yml b/detection-rules/abuse_quickbooks_suspicious_comments.yml new file mode 100644 index 00000000000..ec436e55852 --- /dev/null +++ b/detection-rules/abuse_quickbooks_suspicious_comments.yml @@ -0,0 +1,39 @@ +name: "Service Abuse: QuickBooks Notification with Suspicious Comments" +description: "This detection rule matches QuickBooks notifications that contain suspicious keywords within the comments section of the notification" +type: "rule" +severity: "medium" +source: | + type.inbound + + // Legitimate Intuit sending infratructure + and sender.email.email == "quickbooks@notification.intuit.com" + and headers.auth_summary.spf.pass + and headers.auth_summary.dmarc.pass + and strings.ends_with(headers.auth_summary.spf.details.designator, + '.intuit.com' + ) + + // remove payment confirmation messages + and not strings.starts_with(subject.subject, 'Payment confirmation:') + + and body.html.raw is not null + // Comments contains suspicious phrases + and ( + // three different templates where commonly observed, on regex for each template + // this could optionally be converted into a "2 of" logic against current_thread if FN are discovered + regex.icontains(body.html.raw, '
\s*.*\b(?:your subscription renewal|couldn.?t be processed|trouble renewing subscription|update your details|just update your|continue your subscription|prefer to use EFT|change payment method|verify your account|suspended due to issue|payment declined notice|account needs verification|confirm your billing|immediate action required|failed payment notification|billing information update|service interruption warning|unable to process payment|subscription payment failed|action needed now|update banking information|subscription expiration notice|payment method change)\b.*
') + or regex.icontains(body.html.raw, '
.*\b(?:your subscription renewal|couldn.?t be processed|trouble renewing subscription|update your details|just update your|continue your subscription|prefer to use EFT|change payment method|verify your account|suspended due to issue|payment declined notice|account needs verification|confirm your billing|immediate action required|failed payment notification|billing information update|service interruption warning|unable to process payment|subscription payment failed|action needed now|update banking information|subscription expiration notice|payment method change)\b.*
') + or regex.icontains(body.html.raw, '(?:\s*)?\s*\s*') + ) +attack_types: + - "Callback Phishing" + - "Credential Phishing" + - "BEC/Fraud" +tactics_and_techniques: + - "Evasion" + - "Social engineering" +detection_methods: + - "Content analysis" + - "Sender analysis" + - "Header analysis" +id: "a23d0950-9117-5199-bc74-7192217b80ff" From b23155072f27fb6f3da9f782792fce13bf1ad95c Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Mon, 16 Dec 2024 10:21:09 -0500 Subject: [PATCH 23/43] Update link_microsoft_low_reputation.yml (#2216) --- detection-rules/link_microsoft_low_reputation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detection-rules/link_microsoft_low_reputation.yml b/detection-rules/link_microsoft_low_reputation.yml index 83c4e1b605d..95c91a63b02 100644 --- a/detection-rules/link_microsoft_low_reputation.yml +++ b/detection-rules/link_microsoft_low_reputation.yml @@ -4,7 +4,7 @@ type: "rule" severity: "medium" source: | type.inbound - and 0 < length(body.links) < 100 + and 0 < length(body.links) < 50 // suspicious link and any(body.links, ( From ee16b91043b54e457170feabe8ee314152708b20 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Tue, 17 Dec 2024 17:15:52 -0600 Subject: [PATCH 24/43] fix typo in drive-shares-dm-noreaply (#2231) --- detection-rules/abuse_google_drive_unsolicited_reply-to.yml | 2 +- detection-rules/link_google_presentation_open_redirect.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/detection-rules/abuse_google_drive_unsolicited_reply-to.yml b/detection-rules/abuse_google_drive_unsolicited_reply-to.yml index c0e47f3c1e1..b01aa73250b 100644 --- a/detection-rules/abuse_google_drive_unsolicited_reply-to.yml +++ b/detection-rules/abuse_google_drive_unsolicited_reply-to.yml @@ -5,7 +5,7 @@ severity: "medium" source: | type.inbound and sender.email.email in ( - 'drive-shares-dm-noreaply@google.com', + 'drive-shares-dm-noreply@google.com', 'drive-shares-noreply@google.com', ) and not any(headers.reply_to, .email.domain.domain in $org_domains) diff --git a/detection-rules/link_google_presentation_open_redirect.yml b/detection-rules/link_google_presentation_open_redirect.yml index f06fe291a15..65e5d89c90c 100644 --- a/detection-rules/link_google_presentation_open_redirect.yml +++ b/detection-rules/link_google_presentation_open_redirect.yml @@ -85,7 +85,7 @@ source: | or ( sender.email.email in ( 'comments-noreply@docs.google.com', - 'drive-shares-dm-noreaply@google.com', + 'drive-shares-dm-noreply@google.com', 'drive-shares-noreply@google.com', 'calendar-notification@google.com' ) From 34ce2e70a1eb15c67fe8dd1df47f29c0bfa9614f Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Tue, 17 Dec 2024 19:53:44 -0500 Subject: [PATCH 25/43] Update impersonation_microsoft_credential_theft.yml (#2200) --- detection-rules/impersonation_microsoft_credential_theft.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/detection-rules/impersonation_microsoft_credential_theft.yml b/detection-rules/impersonation_microsoft_credential_theft.yml index 36f64134c9e..fc4d734c2be 100644 --- a/detection-rules/impersonation_microsoft_credential_theft.yml +++ b/detection-rules/impersonation_microsoft_credential_theft.yml @@ -52,6 +52,11 @@ source: | and not profile.by_sender().any_false_positives ) ) + and not ( + sender.email.domain.domain == "planner.office365.com" + and headers.return_path.email == "noreply@planner.office365.com" + and headers.auth_summary.dmarc.details.from.domain == "planner.office365.com" + ) // negate highly trusted sender domains unless they fail DMARC authentication and ( From 52332b7816cb7a5c7864709c90fb4ce570fde1c3 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Tue, 17 Dec 2024 22:45:16 -0600 Subject: [PATCH 26/43] Update attachment_extortion.yml (#2227) --- detection-rules/attachment_extortion.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/detection-rules/attachment_extortion.yml b/detection-rules/attachment_extortion.yml index c6efe4cdae9..02878275278 100644 --- a/detection-rules/attachment_extortion.yml +++ b/detection-rules/attachment_extortion.yml @@ -92,10 +92,10 @@ source: | .file_extension in ("txt") and ( ( - any(ml.nlu_classifier(beta.parse_text(.).text).intents, + any(ml.nlu_classifier(file.parse_text(.).text).intents, .name == "extortion" and .confidence == "high" ) - and any(ml.nlu_classifier(beta.parse_text(.).text).entities, + and any(ml.nlu_classifier(file.parse_text(.).text).entities, .name == "financial" ) ) From facda96e0946097bf2bbefb9e35f746d6dc273a0 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Tue, 17 Dec 2024 22:46:08 -0600 Subject: [PATCH 27/43] Update impersonation_facebook.yml (#2226) --- detection-rules/impersonation_facebook.yml | 24 ++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/detection-rules/impersonation_facebook.yml b/detection-rules/impersonation_facebook.yml index f1db3377bf2..a74ad1b8b1e 100644 --- a/detection-rules/impersonation_facebook.yml +++ b/detection-rules/impersonation_facebook.yml @@ -8,6 +8,8 @@ severity: "low" source: | type.inbound and ( + // sender display name is a strong enough indicator + // that it can be used without any other impersonation logic ( strings.ilike(sender.display_name, '*facebook ads*', @@ -21,10 +23,16 @@ source: | or ( strings.ilevenshtein(sender.display_name, 'meta support') <= 2 // negation for Zeta Support - and not (sender.display_name == "Zeta Support" and sender.email.domain.root_domain == 'zetaglobal.net') + and not ( + sender.display_name == "Zeta Support" + and sender.email.domain.root_domain == 'zetaglobal.net' + ) ) or strings.ilike(sender.email.domain.domain, '*facebook*') ) + // the use of these keywords (facebook, meta, meta.*support) + // or the levenshtien distance to facebook + // are less strong and thus need to be combined with logo detection or nlu or ( ( ( @@ -51,6 +59,17 @@ source: | ) ) ) + // salesforce sender combined with logo detection and nlu is enough + or ( + sender.email.domain.root_domain == "salesforce.com" + and any(ml.logo_detect(beta.message_screenshot()).brands, + .name in ("Facebook", "Meta") + ) + and any(ml.nlu_classifier(body.current_thread.text).intents, + .name in ("cred_theft", "callback_scam", "steal_pii") + and .confidence in ("high") + ) + ) or // or the body contains a facebook/meta footer with the address citing "community support" ( @@ -92,7 +111,8 @@ source: | profile.by_sender().any_messages_malicious_or_spam and not profile.by_sender().any_false_positives ) - or sender.email.email == "noreply@salesforce.com" + // if saleforce is being abused, sender profiles aren't very useful + or sender.email.email in ("noreply@salesforce.com", "support@salesforce.com") // sent via Google group or any(headers.hops, any(.fields, .name == "X-Google-Group-Id")) ) From c64a7b6034c4b21e0611138a105cd014c7a8e9e7 Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Tue, 17 Dec 2024 21:04:08 -0800 Subject: [PATCH 28/43] Update attachment_office_file_relationship_cred_theft.yml (#2229) --- .../attachment_file_scheme_link_to_executable_filetype.yml | 1 + .../attachment_office_file_relationship_cred_theft.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/detection-rules/attachment_file_scheme_link_to_executable_filetype.yml b/detection-rules/attachment_file_scheme_link_to_executable_filetype.yml index d50ce32802b..32c32f8b4cb 100644 --- a/detection-rules/attachment_file_scheme_link_to_executable_filetype.yml +++ b/detection-rules/attachment_file_scheme_link_to_executable_filetype.yml @@ -15,6 +15,7 @@ source: | and .size < 100000000 ) ) + and length(file.oletools(.).relationships) < 500 and any(file.oletools(.).relationships, .target_url.scheme == "file" and regex.icontains(.target_url.path, diff --git a/detection-rules/attachment_office_file_relationship_cred_theft.yml b/detection-rules/attachment_office_file_relationship_cred_theft.yml index 8945b4622bc..9d0dc17d383 100644 --- a/detection-rules/attachment_office_file_relationship_cred_theft.yml +++ b/detection-rules/attachment_office_file_relationship_cred_theft.yml @@ -15,6 +15,7 @@ source: | and .size < 100000000 ) ) + and length(file.oletools(.).relationships) < 500 and any(file.oletools(.).relationships, ( any(ml.nlu_classifier(ml.link_analysis(.target_url).final_dom.display_text From fdcf1fdfdca2a92295e7248c5bf286972fab7e77 Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Tue, 17 Dec 2024 21:04:25 -0800 Subject: [PATCH 29/43] Update attachment_docusign_suspicious_links.yml (#2222) --- .../attachment_docusign_suspicious_links.yml | 100 +++++++++--------- 1 file changed, 51 insertions(+), 49 deletions(-) diff --git a/detection-rules/attachment_docusign_suspicious_links.yml b/detection-rules/attachment_docusign_suspicious_links.yml index 58ec4ac0d39..0b532459c9a 100644 --- a/detection-rules/attachment_docusign_suspicious_links.yml +++ b/detection-rules/attachment_docusign_suspicious_links.yml @@ -65,56 +65,58 @@ source: | ) ) ) - + // accomidate truncated pngs and GIF files which can cause logodetect/OCR failures - or any(attachments, - ( - .file_type =~ "gif" - or any(file.explode(.), - any(.scan.exiftool.fields, - .key == "Warning" and .value == "Truncated PNG image" - ) - ) - ) - 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(file.explode(beta.message_screenshot()), - ( - any(ml.nlu_classifier(.scan.ocr.raw).intents, - .name == "cred_theft" and .confidence != "low" - ) - or regex.icontains(.scan.ocr.raw, - "((re)?view|access|complete(d)?) document(s)?", - "[^d][^o][^c][^u]sign", - "important edocs", - // German (Document (check|check|sign|sent)) - "Dokument (überprüfen|prüfen|unterschreiben|geschickt)", - // German (important|urgent|immediate) - "(wichtig|dringend|sofort)" - ) + or ( + any(attachments, + ( + .file_type =~ "gif" + or any(file.explode(.), + any(.scan.exiftool.fields, + .key == "Warning" and .value == "Truncated PNG image" ) - ) - ) - and not any(file.explode(beta.message_screenshot()), - ( - strings.ilike(.scan.ocr.raw, "*DocuSigned By*") - and not strings.ilike(.scan.ocr.raw, - "*DocuSign Envelope ID*" - ) - and not strings.ilike(.scan.ocr.raw, - "*Certificate Of Completion*" - ) - ) - ) - ) + ) + ) + ) + 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(file.explode(beta.message_screenshot()), + ( + any(ml.nlu_classifier(.scan.ocr.raw).intents, + .name == "cred_theft" and .confidence != "low" + ) + or regex.icontains(.scan.ocr.raw, + "((re)?view|access|complete(d)?) document(s)?", + "[^d][^o][^c][^u]sign", + "important edocs", + // German (Document (check|check|sign|sent)) + "Dokument (überprüfen|prüfen|unterschreiben|geschickt)", + // German (important|urgent|immediate) + "(wichtig|dringend|sofort)" + ) + ) + ) + ) + and not any(file.explode(beta.message_screenshot()), + ( + strings.ilike(.scan.ocr.raw, "*DocuSigned By*") + and not strings.ilike(.scan.ocr.raw, + "*DocuSign Envelope ID*" + ) + and not strings.ilike(.scan.ocr.raw, + "*Certificate Of Completion*" + ) + ) + ) + ) ) ) and ( @@ -125,7 +127,7 @@ source: | ) ) and not profile.by_sender().any_false_positives - + // negate docusign 'via' messages and not ( any(headers.hops, From 099d32735eb35a1410cabec91f115962e13e7ef8 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Wed, 18 Dec 2024 09:34:10 -0600 Subject: [PATCH 30/43] Update link_microsoft_low_reputation.yml (#2232) --- detection-rules/link_microsoft_low_reputation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detection-rules/link_microsoft_low_reputation.yml b/detection-rules/link_microsoft_low_reputation.yml index 95c91a63b02..67b83e08151 100644 --- a/detection-rules/link_microsoft_low_reputation.yml +++ b/detection-rules/link_microsoft_low_reputation.yml @@ -71,7 +71,7 @@ source: | and any(ml.logo_detect(.).brands, strings.starts_with(.name, "Microsoft")) ) or strings.istarts_with(strings.replace_confusables(body.current_thread.text), "Microsoft ") - or regex.icontains(strings.replace_confusables(body.current_thread.text), '(?:^|\n)[o0O]ff[il1]ce\b') + or regex.imatch(strings.replace_confusables(body.current_thread.text), '[\n\s]*[o0O]ff[il1]ce\b.*') or any(ml.logo_detect(beta.message_screenshot()).brands, strings.starts_with(.name, "Microsoft") ) From 6eda67a2869a8c6de9dbcc504ecc3c2178e888af Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Wed, 18 Dec 2024 09:48:31 -0600 Subject: [PATCH 31/43] Create abuse_docsend_new_domain.yml (#2164) Co-authored-by: ID Generator Co-authored-by: Aiden Mitchell --- detection-rules/abuse_docsend_new_domain.yml | 37 ++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 detection-rules/abuse_docsend_new_domain.yml diff --git a/detection-rules/abuse_docsend_new_domain.yml b/detection-rules/abuse_docsend_new_domain.yml new file mode 100644 index 00000000000..48d295da824 --- /dev/null +++ b/detection-rules/abuse_docsend_new_domain.yml @@ -0,0 +1,37 @@ +name: "Service Abuse: DocSend Share From Newly Registered Domain" +description: "This Attack Surface Reduction (ASR) rule matches on DocSend notifications with recently registered reply-to domains." +type: "rule" +severity: "high" +source: | + type.inbound + + // Legitimate DocSend sending infratructure + and sender.email.email == "no-reply@docsend.com" + and headers.auth_summary.spf.pass + and headers.auth_summary.dmarc.pass + + // the message needs to have a reply-to address + and length(headers.reply_to) > 0 + + // reply-to email address has never received an email from your org + and not any(headers.reply_to, .email.email in $recipient_emails) + + // new reply-to + and any(headers.reply_to, + network.whois(.email.domain).days_old < 30 + ) +tags: + - "Attack surface reduction" +attack_types: + - "BEC/Fraud" + - "Credential Phishing" +tactics_and_techniques: + - "Evasion" + - "Free file host" + - "Impersonation: Brand" + - "Social engineering" +detection_methods: + - "Content analysis" + - "Header analysis" + - "Sender analysis" +id: "3bc152f2-6722-57be-b924-055c35fa1e60" From 23c41ebe5da78a86cc23b2ef52387a58cc78fe5c Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Wed, 18 Dec 2024 09:51:57 -0600 Subject: [PATCH 32/43] Create header_onmicrosoft_traversal.yml (#2060) Co-authored-by: ID Generator Co-authored-by: Aiden Mitchell --- .../header_onmicrosoft_traversal.yml | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 detection-rules/header_onmicrosoft_traversal.yml diff --git a/detection-rules/header_onmicrosoft_traversal.yml b/detection-rules/header_onmicrosoft_traversal.yml new file mode 100644 index 00000000000..c6ba1546391 --- /dev/null +++ b/detection-rules/header_onmicrosoft_traversal.yml @@ -0,0 +1,37 @@ +name: "Message Traversed Multiple onmicrosoft.com Tenants" +description: "This detection rule identifies messages that have traversed multiple distinct onmicrosoft.com tenants. This technique has been observed as an evasion tactic to distribute a single message across a list of targeted recipients." +type: "rule" +severity: "medium" +source: | + type.inbound + and length(recipients.to) == 1 + and all(recipients.to, + .email.domain.root_domain == "onmicrosoft.com" + and not .email.domain.domain in $org_domains + ) + // the message has traversed two or more different "onmicrosoft.com" subdomains + and length(distinct(map(filter(headers.hops, + strings.icontains(.authentication_results.spf_details.designator, + '.onmicrosoft.com' + ) + and not strings.contains(.authentication_results.spf_details.designator, + "@" + ) + ), + .authentication_results.spf_details.designator + ), + . + ) + ) > 1 + + and all(recipients.to, .email.domain.domain != headers.return_path.domain.domain) +attack_types: + - "Callback Phishing" +tactics_and_techniques: + - "Evasion" + - "Free email provider" + - "Free subdomain host" +detection_methods: + - "Sender analysis" + - "Header analysis" +id: "9cf01c0d-95d5-5ea6-8150-cf5879834e06" From 5eb78b361fd87be5dca81fa7788f9c1d19f7b7af Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Wed, 18 Dec 2024 09:54:38 -0600 Subject: [PATCH 33/43] Update suspicious_sharepoint_file_shared.yml (#2178) --- detection-rules/suspicious_sharepoint_file_shared.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/detection-rules/suspicious_sharepoint_file_shared.yml b/detection-rules/suspicious_sharepoint_file_shared.yml index 2b0e481a4ff..3a21411caaa 100644 --- a/detection-rules/suspicious_sharepoint_file_shared.yml +++ b/detection-rules/suspicious_sharepoint_file_shared.yml @@ -1,5 +1,5 @@ name: "Suspicious SharePoint File Sharing" -description: "This rule detect potential credential phishing leveraging SharePoint file sharing to deliver a PDF or OneNote file using indicators such as suspicious sender analysis and link characteristics." +description: "This rule detect potential credential phishing leveraging SharePoint file sharing to deliver a PDF, OneNote, or Unknown file type file using indicators such as suspicious sender analysis and link characteristics." type: "rule" severity: "medium" source: | @@ -61,6 +61,7 @@ source: | and ( strings.icontains(.href_url.path, '/:o:/') or strings.icontains(.href_url.path, '/:b:/') + or strings.icontains(.href_url.path, '/:u:/') ) ) From bf237eea34de573758a61535bafe6bcef76dec26 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Wed, 18 Dec 2024 09:56:12 -0600 Subject: [PATCH 34/43] Update unsolicited_reply-to rules (#2233) --- detection-rules/abuse_docusign_unsolicited_reply-to.yml | 2 +- detection-rules/abuse_google_drive_unsolicited_reply-to.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/detection-rules/abuse_docusign_unsolicited_reply-to.yml b/detection-rules/abuse_docusign_unsolicited_reply-to.yml index 4fa5b80c72a..a796593ddc4 100644 --- a/detection-rules/abuse_docusign_unsolicited_reply-to.yml +++ b/detection-rules/abuse_docusign_unsolicited_reply-to.yml @@ -41,7 +41,7 @@ source: | // filter the list to only emails that are not in free_email_providers ( .email.domain.domain not in $free_email_providers - or .email.domain.domain not in $free_email_providers + or .email.domain.root_domain not in $free_email_providers ) ), .email.domain.domain in $sender_domains diff --git a/detection-rules/abuse_google_drive_unsolicited_reply-to.yml b/detection-rules/abuse_google_drive_unsolicited_reply-to.yml index b01aa73250b..fc1dfe73eab 100644 --- a/detection-rules/abuse_google_drive_unsolicited_reply-to.yml +++ b/detection-rules/abuse_google_drive_unsolicited_reply-to.yml @@ -35,7 +35,7 @@ source: | // filter the list to only emails that are not in free_email_providers ( .email.domain.domain not in $free_email_providers - or .email.domain.domain not in $free_email_providers + or .email.domain.root_domain not in $free_email_providers ) ), .email.domain.root_domain in $sender_domains From e9078db87236bbfe6ccdd9a6656305569207da45 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:00:24 -0600 Subject: [PATCH 35/43] Create abuse_docsend_unsolicited_reply-to.yml (#2165) Co-authored-by: ID Generator Co-authored-by: Aiden Mitchell --- .../abuse_docsend_unsolicited_reply-to.yml | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 detection-rules/abuse_docsend_unsolicited_reply-to.yml diff --git a/detection-rules/abuse_docsend_unsolicited_reply-to.yml b/detection-rules/abuse_docsend_unsolicited_reply-to.yml new file mode 100644 index 00000000000..f4e6bc0ab78 --- /dev/null +++ b/detection-rules/abuse_docsend_unsolicited_reply-to.yml @@ -0,0 +1,56 @@ +name: "Service Abuse: DocSend Share From an Unsolicited Reply-To Address" +description: "DocSend shares which contain a reply-to address or domain that has not been previously observed by the recipient organization." +type: "rule" +severity: "high" +source: | + type.inbound + + // Legitimate DocSend sending infratructure + and sender.email.email == "no-reply@docsend.com" + and headers.auth_summary.spf.pass + and headers.auth_summary.dmarc.pass + + // the message needs to have a reply-to address + and length(headers.reply_to) > 0 + + // reply-to email address has never been sent an email by the org + and not ( + any(headers.reply_to, .email.email in $recipient_emails) + // if the reply-to email address is NOT in free_email_providers, check the domain in recipient_domains + or any(filter(headers.reply_to, + // filter the list to only emails that are not in free_email_providers + ( + .email.domain.domain not in $free_email_providers + or .email.domain.root_domain not in $free_email_providers + ) + ), + .email.domain.domain in $recipient_domains + ) + ) + // reply-to address has never sent an email to the org + and not ( + any(headers.reply_to, .email.email in $sender_emails) + // if the reply-to address is NOT in free_email_providers, check the domain in sender_domains + or any(filter(headers.reply_to, + // filter the list to only emails that are not in free_email_providers + ( + .email.domain.domain not in $free_email_providers + or .email.domain.root_domain not in $free_email_providers + ) + ), + .email.domain.domain in $sender_domains + ) + ) +tags: + - "Attack surface reduction" +attack_types: + - "Credential Phishing" +tactics_and_techniques: + - "Evasion" + - "Free file host" + - "Social engineering" +detection_methods: + - "Content analysis" + - "Header analysis" + - "Sender analysis" +id: "b377e64c-21bd-5040-86ec-534e545a42db" From 50dc51459a691f194a5980232e72a3649bbf7697 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:01:35 -0600 Subject: [PATCH 36/43] Create abuse_dropbox_unsolicited_reply-to.yml (#2078) Co-authored-by: ID Generator Co-authored-by: Aiden Mitchell --- .../abuse_dropbox_unsolicited_reply-to.yml | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 detection-rules/abuse_dropbox_unsolicited_reply-to.yml diff --git a/detection-rules/abuse_dropbox_unsolicited_reply-to.yml b/detection-rules/abuse_dropbox_unsolicited_reply-to.yml new file mode 100644 index 00000000000..92811c145ff --- /dev/null +++ b/detection-rules/abuse_dropbox_unsolicited_reply-to.yml @@ -0,0 +1,59 @@ +name: "Service Abuse: Dropbox Share From an Unsolicited Reply-To Address" +description: "This rule detects Dropbox share notifications which contain a reply-to address or domain that has not been previously observed sending messages to or receiving messages from the recipient organization." +type: "rule" +severity: "medium" +source: | + type.inbound + + // Legitimate Dropbox sending infratructure + and sender.email.email == "no-reply@dropbox.com" + and headers.auth_summary.spf.pass + and headers.auth_summary.dmarc.pass + and strings.ends_with(headers.auth_summary.spf.details.designator, + '.dropbox.com' + ) + and strings.icontains(subject.subject, 'shared') + and strings.icontains(subject.subject, 'with you') + + and length(headers.reply_to) > 0 + // reply-to email address has never been sent an email by the org + and not ( + any(headers.reply_to, .email.email in $recipient_emails) + // if the reply-to email address is NOT in free_email_providers, check the domain in recipient_domains + or any(filter(headers.reply_to, + // filter the list to only emails that are not in free_email_providers + ( + .email.domain.domain not in $free_email_providers + or .email.domain.root_domain not in $free_email_providers + ) + ), + .email.domain.domain in $recipient_domains + ) + ) + // reply-to address has never sent an email to the org + and not ( + any(headers.reply_to, .email.email in $sender_emails) + // if the reply-to address is NOT in free_email_providers, check the domain in sender_domains + or any(filter(headers.reply_to, + // filter the list to only emails that are not in free_email_providers + ( + .email.domain.domain not in $free_email_providers + or .email.domain.root_domain not in $free_email_providers + ) + ), + .email.domain.domain in $sender_domains + ) + ) +tags: + - "Attack surface reduction" +attack_types: + - "Callback Phishing" + - "BEC/Fraud" +tactics_and_techniques: + - "Evasion" + - "Social engineering" +detection_methods: + - "Sender analysis" + - "Header analysis" + - "Content analysis" +id: "50a1499f-bb59-5ee0-b4f4-e3cc84a5c41e" From bd3af67d389becb66e67738155e6b444661ef5a3 Mon Sep 17 00:00:00 2001 From: Peter Djordjevic <116412909+peterdj45@users.noreply.github.com> Date: Wed, 18 Dec 2024 20:04:05 -0800 Subject: [PATCH 37/43] Update attachment_callback_phish_with_pdf.yml (#2237) --- detection-rules/attachment_callback_phish_with_pdf.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/detection-rules/attachment_callback_phish_with_pdf.yml b/detection-rules/attachment_callback_phish_with_pdf.yml index 73fecdfc794..94fdd799bcf 100644 --- a/detection-rules/attachment_callback_phish_with_pdf.yml +++ b/detection-rules/attachment_callback_phish_with_pdf.yml @@ -74,6 +74,10 @@ source: | strings.icontains(.scan.ocr.raw, "norton"), strings.icontains(.scan.ocr.raw, "ebay"), strings.icontains(.scan.ocr.raw, "paypal"), + // suspicious attachment name + ( + regex.icontains(.file_name, 'INV(?:_|\s)?\d+(.pdf)$') + ) ) // Negate bank statements and not ( From 3dd4a2ff48edd2ad91c1ac52ab0c7c888852ced4 Mon Sep 17 00:00:00 2001 From: "Brandon 2: Brandon Harder" Date: Thu, 19 Dec 2024 09:41:02 -0600 Subject: [PATCH 38/43] Update link_cyrillic_substitutions_unsolicited.yml (#2240) Co-authored-by: Aiden Mitchell --- .../link_cyrillic_substitutions_unsolicited.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/detection-rules/link_cyrillic_substitutions_unsolicited.yml b/detection-rules/link_cyrillic_substitutions_unsolicited.yml index df81e883528..353772b6628 100644 --- a/detection-rules/link_cyrillic_substitutions_unsolicited.yml +++ b/detection-rules/link_cyrillic_substitutions_unsolicited.yml @@ -6,7 +6,14 @@ source: | type.inbound // message contains between 1 and 9 links - and 0 < length(body.links) < 10 + and ( + 0 < length(body.links) < 10 + or ( + length(body.links) == 0 + and length(attachments) > 0 + and body.current_thread.text == "" + ) + ) // display name or subject contains Cyrillic vowels in addition to standard letters and any([subject.subject, sender.display_name], From 36925e953bb9c734e34367df98e7938745b6e700 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Thu, 19 Dec 2024 10:55:06 -0600 Subject: [PATCH 39/43] Update attachment_callback_phish_with_pdf.yml (#2239) --- detection-rules/attachment_callback_phish_with_pdf.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/detection-rules/attachment_callback_phish_with_pdf.yml b/detection-rules/attachment_callback_phish_with_pdf.yml index 94fdd799bcf..942e53bcce7 100644 --- a/detection-rules/attachment_callback_phish_with_pdf.yml +++ b/detection-rules/attachment_callback_phish_with_pdf.yml @@ -74,9 +74,9 @@ source: | strings.icontains(.scan.ocr.raw, "norton"), strings.icontains(.scan.ocr.raw, "ebay"), strings.icontains(.scan.ocr.raw, "paypal"), - // suspicious attachment name + // suspicious attachment name from the attachment object not file.explode() output ( - regex.icontains(.file_name, 'INV(?:_|\s)?\d+(.pdf)$') + regex.icontains(..file_name, 'INV(?:_|\s)?\d+(.pdf)$') ) ) // Negate bank statements From 6631bf081530e53a19f63ea15281f9c57daf29b0 Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Thu, 19 Dec 2024 09:28:24 -0800 Subject: [PATCH 40/43] Update paypal_invoice_abuse.yml (#2236) --- detection-rules/paypal_invoice_abuse.yml | 35 ++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/detection-rules/paypal_invoice_abuse.yml b/detection-rules/paypal_invoice_abuse.yml index 87e2d188b3c..61de2bd572b 100644 --- a/detection-rules/paypal_invoice_abuse.yml +++ b/detection-rules/paypal_invoice_abuse.yml @@ -20,6 +20,41 @@ source: | and ( strings.ilike(body.html.display_text, "*seller note*") or strings.ilike(body.html.display_text, "*Note from *") + // phone number in subject + // the subject contains the seller's "name", attacks have been seen with the entire callback text in the seller's name + or ( + regex.icontains(strings.replace_confusables(subject.subject), + '.*\+?([lo0-9]{1}.)?\(?[lo0-9]{3}?\)?.[lo0-9]{3}.?[lo0-9]{4}.*' + ) + or regex.icontains(strings.replace_confusables(subject.subject), + '.*\+[lo0-9]{1,3}[lo0-9]{10}.*' + ) + or // +12028001238 + regex.icontains(strings.replace_confusables(subject.subject), + '.*[lo0-9]{3}\.[lo0-9]{3}\.[lo0-9]{4}.*' + ) + or // 202-800-1238 + regex.icontains(strings.replace_confusables(subject.subject), + '.*[lo0-9]{3}-[lo0-9]{3}-[lo0-9]{4}.*' + ) + or // (202) 800-1238 + regex.icontains(strings.replace_confusables(subject.subject), + '.*\([lo0-9]{3}\)\s[lo0-9]{3}-[lo0-9]{4}.*' + ) + or // (202)-800-1238 + regex.icontains(strings.replace_confusables(subject.subject), + '.*\([lo0-9]{3}\)-[lo0-9]{3}-[lo0-9]{4}.*' + ) + or ( // 8123456789 + regex.icontains(strings.replace_confusables(subject.subject), + '.*8[lo0-9]{9}.*' + ) + and regex.icontains(strings.replace_confusables(subject.subject + ), + '\+[1l]' + ) + ) + ) ) and ( ( From aefd975f6d9c35b39e392f12c61a17f1fac08e67 Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Thu, 19 Dec 2024 09:30:25 -0800 Subject: [PATCH 41/43] Create sender_domain_similar_to_cc.yml (#2234) --- insights/sender/sender_domain_similar_to_cc.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 insights/sender/sender_domain_similar_to_cc.yml diff --git a/insights/sender/sender_domain_similar_to_cc.yml b/insights/sender/sender_domain_similar_to_cc.yml new file mode 100644 index 00000000000..2ea3b0f4346 --- /dev/null +++ b/insights/sender/sender_domain_similar_to_cc.yml @@ -0,0 +1,15 @@ +name: "CC'd domains similar to sender domain" +type: "query" +source: | + distinct(map(filter(recipients.cc, + any(recipients.cc, + 0 < strings.ilevenshtein(sender.email.domain.sld, + .email.domain.sld + ) < 4 + ) + ), + .email.domain.domain + ), + . + ) +severity: "medium" From 93cbe2ff8c38051ae86f2e09dd35e6a786db6372 Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Thu, 19 Dec 2024 09:33:14 -0800 Subject: [PATCH 42/43] Update suspicious_request_for_quote_or_purchase.yml (#2224) --- ...spicious_request_for_quote_or_purchase.yml | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/detection-rules/suspicious_request_for_quote_or_purchase.yml b/detection-rules/suspicious_request_for_quote_or_purchase.yml index 4253793cd24..1f1476624df 100644 --- a/detection-rules/suspicious_request_for_quote_or_purchase.yml +++ b/detection-rules/suspicious_request_for_quote_or_purchase.yml @@ -10,7 +10,12 @@ source: | ( ( length(recipients.to) == 0 - or all(recipients.to, .display_name == "Undisclosed recipients") + or all(recipients.to, + .display_name in ( + "Undisclosed recipients", + "undisclosed-recipients" + ) + ) ) and length(recipients.cc) == 0 and length(recipients.bcc) == 0 @@ -39,10 +44,14 @@ source: | '(sign(ed?)|view).{0,10}(purchase order)|Request for a Quot(e|ation)' ) ), - (regex.icontains(body.current_thread.text, '(please|kindly).{0,30}quot(e|ation)')), + ( + regex.icontains(body.current_thread.text, + '(please|kindly).{0,30}quot(e|ation)' + ) + ), ( regex.icontains(subject.subject, - '(request for (purchase|quot(e|ation))|\bRFQ\b|\bRFP\b)' + '(request for (purchase|quot(e|ation))|\bRFQ\b|\bRFP\b|bid invit(e|ation))' ) ), ( @@ -63,6 +72,22 @@ source: | .name == "purchase_order" and .confidence == "high" ) ), + ( + 0 < length(filter(body.links, + ( + .href_url.domain.domain in $free_subdomain_hosts + or .href_url.domain.domain in $free_file_hosts + or network.whois(.href_url.domain).days_old < 30 + ) + and ( + regex.match(.display_text, '[A-Z ]+') + or any(ml.nlu_classifier(.display_text).entities, + .name in ("request", "urgency") + ) + ) + ) + ) < 3 + ) ) or ( length(attachments) == 1 From 9615ee363e741a4601177566b55f783d3f902a72 Mon Sep 17 00:00:00 2001 From: Aiden Mitchell Date: Thu, 19 Dec 2024 14:30:32 -0800 Subject: [PATCH 43/43] Update impersonation_microsoft_credential_theft.yml (#2242) --- .../impersonation_microsoft_credential_theft.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/detection-rules/impersonation_microsoft_credential_theft.yml b/detection-rules/impersonation_microsoft_credential_theft.yml index fc4d734c2be..6874acdcd09 100644 --- a/detection-rules/impersonation_microsoft_credential_theft.yml +++ b/detection-rules/impersonation_microsoft_credential_theft.yml @@ -58,6 +58,12 @@ source: | and headers.auth_summary.dmarc.details.from.domain == "planner.office365.com" ) + // message is not from sharepoint actual (additional check in case DMARC check above fails to bail out) + and not ( + strings.ilike(headers.message_id, '') + ) + // negate highly trusted sender domains unless they fail DMARC authentication and ( (
\s*.*\b(?:your subscription renewal|couldn.?t be processed|trouble renewing subscription|update your details|just update your|continue your subscription|prefer to use EFT|change payment method|verify your account|suspended due to issue|payment declined notice|account needs verification|confirm your billing|immediate action required|failed payment notification|billing information update|service interruption warning|unable to process payment|subscription payment failed|action needed now|update banking information|subscription expiration notice|payment method change)\b.*