Brand impersonation: Sharepoint
Body, attached images or pdf contains a Sharepoint logo. The message contains a link and credential theft language.
Sublime rule (View on GitHub)
1name: "Brand impersonation: Sharepoint"
2description: |
3 Body, attached images or pdf contains a Sharepoint logo. The message contains a link and credential theft language.
4type: "rule"
5severity: "high"
6source: |
7 type.inbound
8 and length(body.links) > 0
9 and (
10 any(attachments,
11 (.file_type in $file_types_images or .file_type == "pdf")
12 and any(ml.logo_detect(.).brands, .name == "Microsoft SharePoint")
13 )
14 or any(ml.logo_detect(file.message_screenshot()).brands,
15 .name == "Microsoft SharePoint"
16 )
17 or strings.istarts_with(strings.replace_confusables(body.current_thread.text),
18 "Sharepoint"
19 )
20 or regex.icontains(body.html.raw,
21 '<img.*(title=|alt=).share.*src=""'
22 ) // broken Sharepoint logo
23 or (
24 strings.icontains(strings.replace_confusables(body.plain.raw), "SharePoint")
25 // message body references file deletion
26 and regex.icontains(body.plain.raw,
27 '(expired )?file\s(was|has been|will be|scheduled (for|to be))\s?delet(ed|ion)'
28 )
29 )
30 or (
31 strings.icontains(body.current_thread.text, 'Sharepoint')
32 and (
33 regex.icontains(body.html.raw, '{(?:domain|randomNumber\d?)}')
34 or any(body.links,
35 regex.icontains(.href_url.url, 'mailto:[^@]+@{domain}')
36 )
37 or regex.icontains(body.html.raw, '<title>[^<]*Easearch[^<]*</title>')
38 )
39 )
40 )
41 and (
42 (
43 any(ml.nlu_classifier(body.current_thread.text).intents,
44 .name == "cred_theft" and .confidence == "high"
45 )
46 //
47 // This rule makes use of a beta feature and is subject to change without notice
48 // using the beta feature in custom rules is not suggested until it has been formally released
49 //
50 or any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents,
51 .name == "cred_theft" and .confidence == "high"
52 )
53 or any(attachments,
54 .file_type == "pdf"
55 and beta.parse_exif(.).page_count == 1
56 and any(file.explode(.),
57 any(ml.nlu_classifier(.scan.ocr.raw).intents,
58 .name == "cred_theft" and .confidence == "high"
59 )
60 )
61 )
62 )
63 or any(ml.nlu_classifier(body.current_thread.text).entities,
64 .name == "urgency" and strings.ilike(.text, "*encrypted*")
65 )
66 or any(body.links,
67 regex.imatch(.display_text,
68 '(?:re)?view (?:(?:&|and) (?:e([[:punct:]]|\s)?)?sign )?(?:complete )?(?:document|file)'
69 )
70 )
71 )
72 and not (
73 (
74 (
75 strings.istarts_with(subject.subject, "RE:")
76 or strings.istarts_with(subject.subject, "R:")
77 or strings.istarts_with(subject.subject, "ODG:")
78 or strings.istarts_with(subject.subject, "答复:")
79 or strings.istarts_with(subject.subject, "AW:")
80 or strings.istarts_with(subject.subject, "TR:")
81 or strings.istarts_with(subject.subject, "FWD:")
82 or regex.imatch(subject.subject, '(\[[^\]]+\]\s?){0,3}(re|fwd?)\s?:')
83 or regex.imatch(subject.subject,
84 '^\[?(EXT|EXTERNAL)\]?[: ]\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*'
85 )
86 )
87 and (
88 (length(headers.references) > 0 or headers.in_reply_to is not null)
89 // ensure that there are actual threads
90 and (
91 length(body.previous_threads) > 0
92 or (length(body.html.display_text) - length(body.current_thread.text)) > 200
93 )
94 )
95 )
96 )
97 and (
98 profile.by_sender_email().prevalence != 'common'
99 or not profile.by_sender_email().solicited
100 or profile.by_sender().any_messages_malicious_or_spam
101 )
102 and not profile.by_sender().any_messages_benign
103
104 // negate highly trusted sender domains unless they fail DMARC authentication
105 and (
106 (
107 sender.email.domain.root_domain in $high_trust_sender_root_domains
108 and not headers.auth_summary.dmarc.pass
109 )
110 or sender.email.domain.root_domain not in $high_trust_sender_root_domains
111 )
112
113 // negate sharepoint file share
114 and not (
115 // based on the message id format
116 (
117 (
118 strings.starts_with(headers.message_id, '<Share-')
119 and strings.ends_with(headers.message_id, '@odspnotify>')
120 )
121 // negate legitimate access request to file
122 or (
123 strings.starts_with(headers.message_id, '<Sharing')
124 and strings.ends_with(headers.message_id, '@odspnotify>')
125 )
126 // deal with Google thinking the message ID is "broke"
127 or (
128 strings.icontains(headers.message_id, 'SMTPIN_ADDED_BROKEN')
129 and any(headers.hops,
130 any(.fields,
131 .name == "X-Google-Original-Message-ID"
132 and strings.starts_with(.value, '<Share-')
133 and strings.ends_with(.value, '@odspnotify>')
134 )
135 )
136 )
137 )
138 // all of the "action" links are sharepoint/ms
139 and all(filter(body.links,
140 strings.icontains(subject.subject, .display_text)
141 or .display_text == "Open"
142 ),
143 .href_url.domain.root_domain in ("sharepoint.com", "1drv.ms")
144 or (
145 .href_url.domain.tld == "ms"
146 // Microsoft does not own the .ms TLD, this checks to ensure it is one of their domains
147 and (
148 network.whois(.href_url.domain).registrant_company == "Microsoft Corporation"
149 or strings.ilike(network.whois(.href_url.domain).registrar_name,
150 "*MarkMonitor*",
151 "*CSC Corporate*",
152 "*com laude*"
153 )
154 )
155 )
156 )
157 )
158 // negate sharepoint file shares with mimecast rewrites
159 and not (
160 // rewritten message ID
161 strings.iends_with(headers.message_id, 'mimecast.lan>')
162 and all(filter(body.links,
163 strings.icontains(subject.subject, .display_text)
164 or .display_text == "Open"
165 ),
166 .href_url.domain.root_domain in (
167 "mimecastprotect.com",
168 "mimecast.com"
169 )
170 and any(.href_url.query_params_decoded["domain"],
171 strings.parse_domain(.).tld == "ms"
172 or strings.parse_domain(.).root_domain == "sharepoint.com"
173 )
174 )
175 )
176attack_types:
177 - "Credential Phishing"
178tactics_and_techniques:
179 - "Impersonation: Brand"
180 - "Social engineering"
181detection_methods:
182 - "Computer Vision"
183 - "Content analysis"
184 - "File analysis"
185 - "Natural Language Understanding"
186 - "Sender analysis"
187id: "284b1b70-8daa-5adf-9df8-15d4c6b5ead9"