From efd29c27de41c9ed4e6a52b7b754f293f62fcea5 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Mon, 23 Sep 2024 14:12:38 -0500 Subject: [PATCH 1/9] Create link_zoho_forms_unsolicited.yml --- .../link_zoho_forms_unsolicited.yml | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 detection-rules/link_zoho_forms_unsolicited.yml diff --git a/detection-rules/link_zoho_forms_unsolicited.yml b/detection-rules/link_zoho_forms_unsolicited.yml new file mode 100644 index 00000000000..f67876af09b --- /dev/null +++ b/detection-rules/link_zoho_forms_unsolicited.yml @@ -0,0 +1,35 @@ +name: "Link: Zoho Form Link from Unsolicited Sender" +description: "This detection rule matches on messaging containing at least one link to forms.zohopublic.com from an unsolicited sender. Zoho provides a free plan enabling users to create custom websites and file hosting. This services has been abused by threat actors to host landing pages via forms directing victims to a next stage of credential phishing." +type: "rule" +severity: "medium" +source: | + type.inbound + and any(body.links, + // webflow link + .href_url.domain.domain == 'forms.zohopublic.com' + ) + // not solicited or from malicious/spam user with no FPs + and ( + not profile.by_sender().solicited + or ( + profile.by_sender().any_messages_malicious_or_spam + and not profile.by_sender().any_false_positives + ) + ) + + // not from high trust sender root domains + and ( + ( + sender.email.domain.root_domain in $high_trust_sender_root_domains + and not headers.auth_summary.dmarc.pass + ) + or sender.email.domain.root_domain not in $high_trust_sender_root_domains + ) +attack_types: + - "Callback Phishing" +tactics_and_techniques: + - "Free file host" +detection_methods: + - "Content analysis" + - "URL analysis" + - "Sender analysis" From 9c0d84111d48ab5819a7936b6cee90216e2be193 Mon Sep 17 00:00:00 2001 From: ID Generator Date: Mon, 23 Sep 2024 19:14:12 +0000 Subject: [PATCH 2/9] Auto add rule ID --- detection-rules/link_zoho_forms_unsolicited.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/detection-rules/link_zoho_forms_unsolicited.yml b/detection-rules/link_zoho_forms_unsolicited.yml index f67876af09b..c262a01d52b 100644 --- a/detection-rules/link_zoho_forms_unsolicited.yml +++ b/detection-rules/link_zoho_forms_unsolicited.yml @@ -33,3 +33,4 @@ detection_methods: - "Content analysis" - "URL analysis" - "Sender analysis" +id: "eb04a9f2-c40b-5fcc-97de-bee7111bc3d8" From 791130d93f8a6e9c2052449ddf51d252eedbfbd0 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Mon, 30 Sep 2024 08:44:25 -0500 Subject: [PATCH 3/9] Update link_zoho_forms_unsolicited.yml --- detection-rules/link_zoho_forms_unsolicited.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detection-rules/link_zoho_forms_unsolicited.yml b/detection-rules/link_zoho_forms_unsolicited.yml index c262a01d52b..db647fc05e5 100644 --- a/detection-rules/link_zoho_forms_unsolicited.yml +++ b/detection-rules/link_zoho_forms_unsolicited.yml @@ -5,7 +5,7 @@ severity: "medium" source: | type.inbound and any(body.links, - // webflow link + // zoho forms link .href_url.domain.domain == 'forms.zohopublic.com' ) // not solicited or from malicious/spam user with no FPs From 3ea938c5c11a50946450c9cd5cb223a1af6d023a Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Tue, 8 Oct 2024 13:09:16 -0500 Subject: [PATCH 4/9] Update link_zoho_forms_unsolicited.yml --- detection-rules/link_zoho_forms_unsolicited.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detection-rules/link_zoho_forms_unsolicited.yml b/detection-rules/link_zoho_forms_unsolicited.yml index db647fc05e5..ef7f02a1c00 100644 --- a/detection-rules/link_zoho_forms_unsolicited.yml +++ b/detection-rules/link_zoho_forms_unsolicited.yml @@ -1,5 +1,5 @@ name: "Link: Zoho Form Link from Unsolicited Sender" -description: "This detection rule matches on messaging containing at least one link to forms.zohopublic.com from an unsolicited sender. Zoho provides a free plan enabling users to create custom websites and file hosting. This services has been abused by threat actors to host landing pages via forms directing victims to a next stage of credential phishing." +description: "This detection rule matches on messages containing at least one link to forms.zohopublic.com from an unsolicited sender. Zoho provides a free plan enabling users to create custom websites and file hosting. This service has been abused by threat actors to host landing pages via forms directing victims to a next stage of credential phishing." type: "rule" severity: "medium" source: | From 6c26b797dab0fe934e825e540e7db7737e44963b Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Tue, 8 Oct 2024 13:26:11 -0500 Subject: [PATCH 5/9] Update link_zoho_forms_unsolicited.yml --- detection-rules/link_zoho_forms_unsolicited.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/detection-rules/link_zoho_forms_unsolicited.yml b/detection-rules/link_zoho_forms_unsolicited.yml index ef7f02a1c00..7fc75739d79 100644 --- a/detection-rules/link_zoho_forms_unsolicited.yml +++ b/detection-rules/link_zoho_forms_unsolicited.yml @@ -7,7 +7,10 @@ source: | and any(body.links, // zoho forms link .href_url.domain.domain == 'forms.zohopublic.com' + // remove a common FP for linking directly + and not strings.istarts_with(.href_url.path, '/quickbooking/') ) + and length(body.current_thread.text) < 900 // not solicited or from malicious/spam user with no FPs and ( not profile.by_sender().solicited From 39cfc3f825a53b5d817ce51922eb9e481998de14 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Tue, 8 Oct 2024 13:27:20 -0500 Subject: [PATCH 6/9] Update link_zoho_forms_unsolicited.yml --- detection-rules/link_zoho_forms_unsolicited.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detection-rules/link_zoho_forms_unsolicited.yml b/detection-rules/link_zoho_forms_unsolicited.yml index 7fc75739d79..85ecd22455f 100644 --- a/detection-rules/link_zoho_forms_unsolicited.yml +++ b/detection-rules/link_zoho_forms_unsolicited.yml @@ -7,7 +7,7 @@ source: | and any(body.links, // zoho forms link .href_url.domain.domain == 'forms.zohopublic.com' - // remove a common FP for linking directly + // remove a common FP for linking directly to booking hotels at room rates and not strings.istarts_with(.href_url.path, '/quickbooking/') ) and length(body.current_thread.text) < 900 From a561ca91dbb416b6612ba4d887ec0dff13637259 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Tue, 8 Oct 2024 13:36:11 -0500 Subject: [PATCH 7/9] Update link_zoho_forms_unsolicited.yml --- detection-rules/link_zoho_forms_unsolicited.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/detection-rules/link_zoho_forms_unsolicited.yml b/detection-rules/link_zoho_forms_unsolicited.yml index 85ecd22455f..641c4fd5b02 100644 --- a/detection-rules/link_zoho_forms_unsolicited.yml +++ b/detection-rules/link_zoho_forms_unsolicited.yml @@ -7,9 +7,11 @@ source: | and any(body.links, // zoho forms link .href_url.domain.domain == 'forms.zohopublic.com' - // remove a common FP for linking directly to booking hotels at room rates + // remove a common FP for linking directly and not strings.istarts_with(.href_url.path, '/quickbooking/') ) + // dont match messages with lots of links or long bodies, often marketing messages + and length(body.links) < 20 and length(body.current_thread.text) < 900 // not solicited or from malicious/spam user with no FPs and ( From 23a2387a4231a63be4447596bad83fb556fcf58a Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Thu, 24 Oct 2024 11:05:54 -0500 Subject: [PATCH 8/9] reduce fps by ensuring link occurs within body.current_thread.text --- detection-rules/link_zoho_forms_unsolicited.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/detection-rules/link_zoho_forms_unsolicited.yml b/detection-rules/link_zoho_forms_unsolicited.yml index 641c4fd5b02..72695dd81de 100644 --- a/detection-rules/link_zoho_forms_unsolicited.yml +++ b/detection-rules/link_zoho_forms_unsolicited.yml @@ -9,6 +9,12 @@ source: | .href_url.domain.domain == 'forms.zohopublic.com' // remove a common FP for linking directly and not strings.istarts_with(.href_url.path, '/quickbooking/') + // ensure the link is within the current_thread + and ( + strings.contains(body.current_thread.text, .display_text) + or + strings.contains(body.current_thread.text, .href_url.url) + ) ) // dont match messages with lots of links or long bodies, often marketing messages and length(body.links) < 20 From 28862848ae76d0b6935b94e4bb1c0ca753263003 Mon Sep 17 00:00:00 2001 From: Brandon Murphy <4827852+zoomequipd@users.noreply.github.com> Date: Thu, 24 Oct 2024 13:06:19 -0500 Subject: [PATCH 9/9] Update link_zoho_forms_unsolicited.yml --- .../link_zoho_forms_unsolicited.yml | 37 +++++++++++++++---- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/detection-rules/link_zoho_forms_unsolicited.yml b/detection-rules/link_zoho_forms_unsolicited.yml index 72695dd81de..7f04f7dcbba 100644 --- a/detection-rules/link_zoho_forms_unsolicited.yml +++ b/detection-rules/link_zoho_forms_unsolicited.yml @@ -4,18 +4,39 @@ type: "rule" severity: "medium" source: | type.inbound - and any(body.links, - // zoho forms link - .href_url.domain.domain == 'forms.zohopublic.com' - // remove a common FP for linking directly - and not strings.istarts_with(.href_url.path, '/quickbooking/') + // filter links to zoho forms + and any(filter(body.links, + // zoho forms link + .href_url.domain.domain == 'forms.zohopublic.com' + // remove a common FP for linking directly + and not strings.istarts_with(.href_url.path, '/quickbooking/') + ), + // remove FPs by checking there is only one link // ensure the link is within the current_thread + ( + strings.contains(body.current_thread.text, .display_text) + or strings.contains(body.current_thread.text, .href_url.url) + ) + // and ensure that link only occurs once within body.html and ( - strings.contains(body.current_thread.text, .display_text) - or - strings.contains(body.current_thread.text, .href_url.url) + ( + body.html.raw is not null + and ( + strings.count(body.html.raw, .display_text) == 1 + or strings.count(body.html.raw, .href_url.url) == 1 + ) + ) + or ( + // and ensure that link only occurs once within plaintext if html.raw is null + body.plain.raw is not null + and ( + strings.count(body.plain.raw, .display_text) == 1 + or strings.count(body.plain.raw, .href_url.url) == 1 + ) + ) ) ) + // dont match messages with lots of links or long bodies, often marketing messages and length(body.links) < 20 and length(body.current_thread.text) < 900