From 297b21c967f49d33712e23770b364e671b06359d Mon Sep 17 00:00:00 2001 From: Luke Wescott <69780712+IndiaAce@users.noreply.github.com> Date: Mon, 30 Mar 2026 12:27:39 -0400 Subject: [PATCH 1/6] Create impersonate_hubspot_suspicious_content.yml --- ...impersonate_hubspot_suspicious_content.yml | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 detection-rules/impersonate_hubspot_suspicious_content.yml diff --git a/detection-rules/impersonate_hubspot_suspicious_content.yml b/detection-rules/impersonate_hubspot_suspicious_content.yml new file mode 100644 index 00000000000..30618cd34d5 --- /dev/null +++ b/detection-rules/impersonate_hubspot_suspicious_content.yml @@ -0,0 +1,62 @@ +name: "Brand impersonation: HubSpot with QR code or suspicious content" +description: "Detects messages impersonating HubSpot by using the company name in the sender display name and including HubSpot-related content or addresses, while containing suspicious elements like QR codes, unsubscribe manipulation language, or account reconnection requests. Legitimate HubSpot communications are excluded through domain and authentication verification." +type: "rule" +severity: "medium" +source: | + type.inbound + and strings.icontains(sender.display_name, 'hubspot') + and 2 of ( + regex.contains(body.current_thread.text, '(?:HubSpot, Inc.|HubSpot)'), + strings.icontains(body.current_thread.text, '2 Canal Park Cambridge'), + strings.icontains(body.current_thread.text, '25 first street'), + strings.icontains(body.current_thread.text, 'MA 02141') + ) + and ( + // contains a QR code + // + // This rule makes use of a beta feature and is subject to change without notice + // using the beta feature in custom rules is not suggested until it has been formally released + // + ( + beta.scan_qr(file.message_screenshot()).found + and any(beta.scan_qr(file.message_screenshot()).items, .type == "url") + ) + or strings.icontains(body.current_thread.text, "you can't unsubscribe") + or regex.icontains(body.current_thread.text, + '(?:reconnect.{0,200}account|deactivat)' + ) + ) + // exclude legitimate HubSpot sends + and not ( + ( + ( + strings.iends_with(sender.email.domain.root_domain, 'hubspot.com') + or strings.iends_with(sender.email.domain.root_domain, 'hubspotqa.com') + ) + and coalesce(headers.auth_summary.dmarc.pass, false) + ) + or ( + ( + strings.iends_with(headers.return_path.domain.root_domain, 'hubspot.com') + or strings.icontains(headers.message_id, '@notifybf') + or strings.icontains(headers.message_id, '.hubspot.com') + ) + and ( + any(headers.domains, strings.iends_with(.root_domain, 'hubspot.com')) + or any(headers.ips, + strings.icontains(headers.from.email.email, 'hubspot') + ) + ) + ) + ) +attack_types: + - "Credential Phishing" +tactics_and_techniques: + - "Impersonation: Brand" + - "QR code" + - "Social engineering" +detection_methods: + - "Sender analysis" + - "Content analysis" + - "QR code analysis" + - "Header analysis" From 60e212f0783c82edeb57eb53091a0deec0222f4b Mon Sep 17 00:00:00 2001 From: CI Bot Date: Mon, 30 Mar 2026 16:33:30 +0000 Subject: [PATCH 2/6] Auto-format MQL and add rule IDs --- detection-rules/impersonate_hubspot_suspicious_content.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/detection-rules/impersonate_hubspot_suspicious_content.yml b/detection-rules/impersonate_hubspot_suspicious_content.yml index 30618cd34d5..6562c0fa82f 100644 --- a/detection-rules/impersonate_hubspot_suspicious_content.yml +++ b/detection-rules/impersonate_hubspot_suspicious_content.yml @@ -60,3 +60,4 @@ detection_methods: - "Content analysis" - "QR code analysis" - "Header analysis" +id: "5df09a5b-8a87-59be-9a73-bd8765dbcc20" From 19e9e6bcc0eab69732d2d54599f3b5e15db30a8e Mon Sep 17 00:00:00 2001 From: Luke Wescott <69780712+IndiaAce@users.noreply.github.com> Date: Tue, 7 Apr 2026 12:35:59 -0400 Subject: [PATCH 3/6] Update impersonate_hubspot_suspicious_content.yml --- ...impersonate_hubspot_suspicious_content.yml | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/detection-rules/impersonate_hubspot_suspicious_content.yml b/detection-rules/impersonate_hubspot_suspicious_content.yml index 6562c0fa82f..78d16b67577 100644 --- a/detection-rules/impersonate_hubspot_suspicious_content.yml +++ b/detection-rules/impersonate_hubspot_suspicious_content.yml @@ -11,19 +11,20 @@ source: | strings.icontains(body.current_thread.text, '25 first street'), strings.icontains(body.current_thread.text, 'MA 02141') ) - and ( - // contains a QR code - // - // This rule makes use of a beta feature and is subject to change without notice - // using the beta feature in custom rules is not suggested until it has been formally released - // - ( - beta.scan_qr(file.message_screenshot()).found - and any(beta.scan_qr(file.message_screenshot()).items, .type == "url") - ) - or strings.icontains(body.current_thread.text, "you can't unsubscribe") - or regex.icontains(body.current_thread.text, - '(?:reconnect.{0,200}account|deactivat)' + and 2 of ( + any(ml.nlu_classifier(body.current_thread.text).topics, + .name in ( + "Security and Authentication", + "Software and App Updates", + "Customer Service and Support" + ) + and .confidence != "low" + ), + any(ml.nlu_classifier(body.current_thread.text).intents, + .name == "cred_theft" and .confidence != "low" + ), + regex.icontains(body.current_thread.text, + '(?:account|disactiv|deactiv|disabl|delet|profile)' ) ) // exclude legitimate HubSpot sends @@ -43,12 +44,14 @@ source: | ) and ( any(headers.domains, strings.iends_with(.root_domain, 'hubspot.com')) - or any(headers.ips, - strings.icontains(headers.from.email.email, 'hubspot') - ) + or strings.icontains(headers.from.email.email, 'hubspot') ) ) ) + and not ( + sender.email.domain.root_domain in $high_trust_sender_root_domains + and coalesce(headers.auth_summary.dmarc.pass, false) + ) attack_types: - "Credential Phishing" tactics_and_techniques: From f8b023ffa6d5b93da9c798d9c0631b54cac90997 Mon Sep 17 00:00:00 2001 From: Luke Wescott <69780712+IndiaAce@users.noreply.github.com> Date: Mon, 18 May 2026 11:35:25 -0400 Subject: [PATCH 4/6] Update impersonate_hubspot_suspicious_content.yml --- detection-rules/impersonate_hubspot_suspicious_content.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/detection-rules/impersonate_hubspot_suspicious_content.yml b/detection-rules/impersonate_hubspot_suspicious_content.yml index 78d16b67577..cfd18cc843a 100644 --- a/detection-rules/impersonate_hubspot_suspicious_content.yml +++ b/detection-rules/impersonate_hubspot_suspicious_content.yml @@ -1,5 +1,5 @@ -name: "Brand impersonation: HubSpot with QR code or suspicious content" -description: "Detects messages impersonating HubSpot by using the company name in the sender display name and including HubSpot-related content or addresses, while containing suspicious elements like QR codes, unsubscribe manipulation language, or account reconnection requests. Legitimate HubSpot communications are excluded through domain and authentication verification." +name: "Brand impersonation: HubSpot credential theft" +description: "Detects fraudulent messages impersonating HubSpot that contain legitimate HubSpot branding elements and address information, combined with security-related topics and credential theft indicators, while excluding authenticated legitimate HubSpot communications." type: "rule" severity: "medium" source: | From ab18a898bb3ee587682f94f2cd4da70b615e1ff6 Mon Sep 17 00:00:00 2001 From: IndiaAce Date: Fri, 29 May 2026 13:15:09 -0400 Subject: [PATCH 5/6] Reduce FPs: negate senders with 'hubspot' in email address Legitimate HubSpot ecosystem senders (andopen.co gifting, Wisetek, Deloitte immigration, HubSpot QA) all have 'hubspot' in their sender email. Attackers use unrelated domains or 'hubsp0t' typosquatting. Co-Authored-By: Claude Opus 4.6 --- detection-rules/impersonate_hubspot_suspicious_content.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/detection-rules/impersonate_hubspot_suspicious_content.yml b/detection-rules/impersonate_hubspot_suspicious_content.yml index cfd18cc843a..a93996d979c 100644 --- a/detection-rules/impersonate_hubspot_suspicious_content.yml +++ b/detection-rules/impersonate_hubspot_suspicious_content.yml @@ -27,6 +27,7 @@ source: | '(?:account|disactiv|deactiv|disabl|delet|profile)' ) ) + and not strings.icontains(sender.email.email, 'hubspot') // exclude legitimate HubSpot sends and not ( ( From 8356063f5fc5f982a907c87280e86b86a7860a60 Mon Sep 17 00:00:00 2001 From: Luke Wescott <69780712+IndiaAce@users.noreply.github.com> Date: Fri, 29 May 2026 15:33:31 -0400 Subject: [PATCH 6/6] Update impersonate_hubspot_suspicious_content.yml --- ...impersonate_hubspot_suspicious_content.yml | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/detection-rules/impersonate_hubspot_suspicious_content.yml b/detection-rules/impersonate_hubspot_suspicious_content.yml index a93996d979c..439d459a7dd 100644 --- a/detection-rules/impersonate_hubspot_suspicious_content.yml +++ b/detection-rules/impersonate_hubspot_suspicious_content.yml @@ -5,29 +5,31 @@ severity: "medium" source: | type.inbound and strings.icontains(sender.display_name, 'hubspot') - and 2 of ( - regex.contains(body.current_thread.text, '(?:HubSpot, Inc.|HubSpot)'), - strings.icontains(body.current_thread.text, '2 Canal Park Cambridge'), - strings.icontains(body.current_thread.text, '25 first street'), - strings.icontains(body.current_thread.text, 'MA 02141') - ) - and 2 of ( - any(ml.nlu_classifier(body.current_thread.text).topics, - .name in ( - "Security and Authentication", - "Software and App Updates", - "Customer Service and Support" - ) - and .confidence != "low" - ), - any(ml.nlu_classifier(body.current_thread.text).intents, - .name == "cred_theft" and .confidence != "low" - ), - regex.icontains(body.current_thread.text, - '(?:account|disactiv|deactiv|disabl|delet|profile)' + and ( + // branding elements: copying HubSpot's footer + 2 of ( + regex.contains(body.current_thread.text, '(?:HubSpot, Inc\.|HubSpot)'), + strings.icontains(body.current_thread.text, '2 Canal Park'), + strings.icontains(body.current_thread.text, '25 first street'), + strings.icontains(body.current_thread.text, 'MA 02141') + ) + // or typosquatting/confusable "hubspot" in sender domain + or ( + not strings.icontains(strings.replace_confusables(sender.email.domain.domain + ), + 'hubspot' + ) + and strings.icontains(sender.email.domain.domain, 'hubsp') ) ) - and not strings.icontains(sender.email.email, 'hubspot') + and not ( + strings.icontains(sender.email.local_part, 'hubspot') + or regex.icontains(sender.email.domain.domain, '^hubspot\.') + ) + // negate if links go to HubSpot's click-tracking domain + and not any(body.current_thread.links, + .href_url.domain.root_domain == "hubspotlinks.com" + ) // exclude legitimate HubSpot sends and not ( ( @@ -53,6 +55,7 @@ source: | sender.email.domain.root_domain in $high_trust_sender_root_domains and coalesce(headers.auth_summary.dmarc.pass, false) ) + attack_types: - "Credential Phishing" tactics_and_techniques: