Brand impersonation: Microsoft Teams invitation
Detects messages impersonating a Microsoft Teams invites by matching known invite text patterns while containing join links that do not resolve to Microsoft domains. Additional verification includes checking for absent phone dial-in options and missing standard Teams help text or HTML meeting components.
Sublime rule (View on GitHub)
1name: "Brand impersonation: Microsoft Teams invitation"
2description: "Detects messages impersonating a Microsoft Teams invites by matching known invite text patterns while containing join links that do not resolve to Microsoft domains. Additional verification includes checking for absent phone dial-in options and missing standard Teams help text or HTML meeting components."
3type: "rule"
4severity: "high"
5source: |
6 type.inbound
7 and (
8 (
9 strings.icontains(body.current_thread.text, 'Microsoft Teams')
10 and strings.icontains(body.current_thread.text,
11 'join the meeting',
12 'confirm your attendance',
13 'confirm attendance'
14 )
15 and strings.contains(body.current_thread.text, 'Meeting ID:')
16 and strings.contains(body.current_thread.text, 'Passcode:')
17 )
18 or (
19 strings.icontains(body.current_thread.text, "teams")
20 // strings that give us confidence it's teams
21 and 2 of (
22 strings.icontains(body.current_thread.text, "internal"),
23 strings.icontains(body.current_thread.text, "message"),
24 strings.icontains(body.current_thread.text, "meeting"),
25 strings.icontains(body.current_thread.text, "Download Teams")
26 )
27 )
28 // either the subject or sender.display name containt Microsoft Teams and Meeting
29 or (
30 any([subject.base, sender.display_name],
31 strings.icontains(., 'Microsoft Teams')
32 and strings.icontains(., 'meeting')
33 )
34 )
35 )
36 // not a reply
37 and length(headers.references) == 0
38 and headers.in_reply_to is null
39 // few links
40 and length(distinct(body.links, .href_url.url)) < 10
41 // short body
42 and length(body.current_thread.text) < 600
43 // no unsubscribe links
44 // common in newsletters which link to a webinar style event
45 and not any(body.links, strings.icontains(.display_text, "unsub"))
46
47 // one of the links contains is a CTA that doesn't link to MS
48 and any(body.current_thread.links,
49 (
50 .display_text =~ "join the meeting"
51 or strings.icontains(.display_text, "join the meeting")
52 or strings.icontains(.display_text, "play recording")
53 // is a mismatched domain via .display_url
54 or (
55 .display_url.domain.root_domain in (
56 "microsoft.com",
57 "microsoft.us",
58 "microsoft.cn",
59 "live.com"
60 )
61 and .mismatched
62 )
63 )
64 and .href_url.domain.root_domain not in (
65 "microsoft.com",
66 "microsoft.us",
67 "microsoft.cn",
68 "live.com"
69 )
70 and not (
71 .href_url.domain.root_domain == "mimecastprotect.com"
72 and (
73 strings.parse_domain(.href_url.query_params_decoded["domain"][0]).root_domain in (
74 "microsoft.com",
75 "microsoft.us",
76 "microsoft.cn",
77 "live.com"
78 )
79 or strings.parse_domain(.href_url.query_params_decoded["domain"][0]).root_domain in $bulk_mailer_url_root_domains
80 )
81 )
82 // rewriters often abstract the link
83 and .href_url.domain.root_domain not in $bulk_mailer_url_root_domains
84 )
85 // missing the dial by phone element
86 and not strings.icontains(body.current_thread.text, 'Dial in by phone')
87
88 // any of these suspicious elements from the body
89 and (
90 // malicious samples leveraged recipient domain branding here
91 not strings.icontains(body.current_thread.text, 'Microsoft Teams Need help?')
92 // malicious samples contained unique html elements not present in legit ones
93 or strings.icontains(body.html.raw, '<div class="meeting-title">')
94 or strings.icontains(body.html.raw, '<div class="meeting-time">')
95 or strings.icontains(body.html.raw, '<div class="meeting-location">')
96 or strings.icontains(body.html.raw, '<span class="conflict-badge">')
97 or strings.icontains(body.html.raw, 'class="join-button"')
98 )
99
100 // negate highly trusted sender domains unless they fail DMARC authentication
101 and (
102 (
103 sender.email.domain.root_domain in $high_trust_sender_root_domains
104 and not headers.auth_summary.dmarc.pass
105 )
106 or sender.email.domain.root_domain not in $high_trust_sender_root_domains
107 )
108attack_types:
109 - "Credential Phishing"
110tactics_and_techniques:
111 - "Impersonation: Brand"
112 - "Social engineering"
113detection_methods:
114 - "Content analysis"
115 - "Header analysis"
116 - "HTML analysis"
117 - "URL analysis"
118id: "46410ad8-3465-505f-a78e-f77704910a91"