Link: Multistage Landing - Microsoft Forms Abuse
The detection rule matches on message groups which make use of Microsoft Forms as a landing page. The landing page contains links which are newly registered, use free file or subdomain hosts, URL shorteners or when visited are phishing pages, lead to a captcha or redirect to a top website.
Sublime rule (View on GitHub)
1name: "Link: Multistage Landing - Microsoft Forms Abuse"
2description: "The detection rule matches on message groups which make use of Microsoft Forms as a landing page. The landing page contains links which are newly registered, use free file or subdomain hosts, URL shorteners or when visited are phishing pages, lead to a captcha or redirect to a top website."
3type: "rule"
4severity: "high"
5source: |
6 type.inbound
7 and any(filter(body.links, .href_url.domain.domain == "forms.office.com"),
8 // avoid doing Link Analysis if the display-text has strong indications of phishing
9 (
10 // replace confusables - observed ITW
11 regex.icontains(strings.replace_confusables(.display_text),
12 'review|proposal|document|efax|restore|[o0]pen|secure|messaging|reset|account|verify|login|notification|alert|urgent|immediate|access|support|\bupdate\b|download|attachment|service|payment|remittance|invoice'
13 )
14 // add confidence to these strings by using profile.by_sender()
15 and (
16 not profile.by_sender().solicited
17 and profile.by_sender().prevalence in ('new', 'outlier')
18 )
19 )
20 or
21 // look at the final_dom.raw
22 // if the page has been taken down, match
23 strings.icontains(ml.link_analysis(., mode="aggressive").final_dom.raw,
24 'This form was blocked due to privacy or safety concerns.'
25 )
26 // this error has been shown before with the text "Phishing form from content scan. Inner Message: This form has been flagged for potential phishing."
27 or any(ml.link_analysis(., mode="aggressive").additional_responses,
28 strings.icontains(.json["error"]["message"], "phishing")
29 )
30 // or MS thinks there are phishing keywords
31 or any(ml.link_analysis(., mode="aggressive").additional_responses,
32 any(.json["form"]["questions"],
33 .["subtitleHasPhishingKeywords"] == true
34 )
35 or any(.json["form"]["questions"],
36 .["titleHasPhishingKeywords"] == true
37 )
38 or any(.json["form"]["descriptiveQuestions"],
39 .["titleHasPhishingKeywords"] == true
40 )
41 or any(.json["form"]["descriptiveQuestions"],
42 .["titleHasPhishingKeywords"] == true
43 )
44 )
45 // this logic checks for three abnormal cases
46 // 1) no questions
47 // 2) questions, but no inputs
48 // 3) a bunch of new lines (used to push down the submit button of the form)
49 // AND
50 // // there is one or two links that isn't "standard" on the form
51 or (
52 (
53 // 1) doesn't contain any sections or questions
54 any(ml.link_analysis(., mode="aggressive").additional_responses,
55 length(.json["form"]["descriptiveQuestions"]) == 0
56 and length(.json["form"]["questions"]) == 0
57 )
58 or
59 // 2) Contains a form section header, but no actual inputs
60 // possible question types are .Choice, .TextField, .Rating, .DateTime, .Ranking, .MatrixChoiceGroup, .MatrixChoice, and .NPS
61 any(ml.link_analysis(., mode="aggressive").additional_responses,
62 length(.json["form"]["descriptiveQuestions"]) > 0
63 and length(.json["form"]["questions"]) == 0
64 )
65 or
66 // 3) a bunch of new lines (used to push down the submit button of the form)
67 (
68 strings.icount(ml.link_analysis(., mode="aggressive").final_dom.raw,
69 '<br><br>'
70 ) > 20
71 or strings.icount(ml.link_analysis(., mode="aggressive").final_dom.raw,
72 '\n\n'
73 ) > 20
74 or strings.icount(ml.link_analysis(., mode="aggressive").final_dom.raw,
75 '<span><span>'
76 ) > 20
77 or any(ml.link_analysis(., mode="aggressive").additional_responses,
78 any(.json["form"]["questions"],
79 strings.icount(.["formsProRTQuestionTitle"],
80 '<br><br>'
81 ) > 20
82 or strings.icount(.["formsProRTQuestionTitle"], '\n\n') > 20
83 or strings.icount(.["formsProRTQuestionTitle"],
84 '<span><span>'
85 ) > 20
86 )
87 )
88 )
89 )
90 // AND
91 and
92 // there is one or two links to another page
93 0 < length(filter(ml.link_analysis(.).final_dom.links,
94 not (
95 (
96 (
97 .display_text =~ "Privacy and cookies"
98 or .display_text =~ "terms of use"
99 or .display_text =~ "report abuse"
100 )
101 and .href_url.domain.root_domain =~ 'microsoft.com'
102 )
103 or .href_url.domain.root_domain =~ sender.email.domain.root_domain
104 or .href_url.domain.tld == "ms"
105 )
106 )
107 ) <= 2
108 and (
109 not strings.contains(ml.link_analysis(., mode="aggressive").final_dom.raw,
110 'role="progressbar" aria-label="Page 1 of '
111 )
112 or any(ml.link_analysis(., mode="aggressive").additional_responses,
113 .json["form"]["progressBarEnabled"] == false
114 )
115 )
116 )
117 )
118attack_types:
119 - "Credential Phishing"
120tactics_and_techniques:
121 - "Impersonation: Brand"
122 - "Social engineering"
123detection_methods:
124 - "HTML analysis"
125 - "URL analysis"
126 - "Content analysis"
127id: "85a2cd12-af74-5451-8bfb-4f36f71eecb7"