Link: Zoho Form Link from Unsolicited Sender

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.

Sublime rule (View on GitHub)

 1name: "Link: Zoho Form Link from Unsolicited Sender"
 2description: "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."
 3type: "rule"
 4severity: "medium"
 5source: |
 6  type.inbound
 7  // filter links to zoho forms
 8  and any(filter(body.links,
 9                 // zoho forms link
10                 .href_url.domain.domain == 'forms.zohopublic.com'
11                 // remove a common FP for linking directly 
12                 and not strings.istarts_with(.href_url.path, '/quickbooking/')
13          ),
14          // remove FPs by checking there is only one link
15          // ensure the link is within the current_thread
16          (
17            strings.contains(body.current_thread.text, .display_text)
18            or strings.contains(body.current_thread.text, .href_url.url)
19          )
20          // and ensure that link only occurs once within body.html
21          and (
22            (
23              body.html.raw is not null
24              and (
25                strings.count(body.html.raw, .display_text) == 1
26                or strings.count(body.html.raw, .href_url.url) == 1
27              )
28            )
29            or (
30              // and ensure that link only occurs once within plaintext if html.raw is null
31              body.plain.raw is not null
32              and (
33                strings.count(body.plain.raw, .display_text) == 1
34                or strings.count(body.plain.raw, .href_url.url) == 1
35              )
36            )
37          )
38  )
39  
40  // dont match messages with lots of links or long bodies, often marketing messages
41  and length(body.links) < 20
42  and length(body.current_thread.text) < 900
43  // not solicited or from malicious/spam user with no FPs
44  and (
45    not profile.by_sender().solicited
46    or (
47      profile.by_sender().any_messages_malicious_or_spam
48      and not profile.by_sender().any_false_positives
49    )
50  )
51  
52  // not from high trust sender root domains
53  and (
54    (
55      sender.email.domain.root_domain in $high_trust_sender_root_domains
56      and not headers.auth_summary.dmarc.pass
57    )
58    or sender.email.domain.root_domain not in $high_trust_sender_root_domains
59  )  
60attack_types:
61  - "Callback Phishing"
62tactics_and_techniques:
63  - "Free file host"
64detection_methods:
65  - "Content analysis"
66  - "URL analysis"
67  - "Sender analysis"
68id: "eb04a9f2-c40b-5fcc-97de-bee7111bc3d8"
to-top