Skip to content

Commit 2fc7984

Browse files
[Shared Samples] [PR #4751] added rule: PR# 4751 - Brand impersonation: Microsoft Teams invitation
1 parent 6ce061a commit 2fc7984

1 file changed

Lines changed: 124 additions & 0 deletions

File tree

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
name: "PR# 4751 - Brand impersonation: Microsoft Teams invitation"
2+
description: "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."
3+
type: "rule"
4+
severity: "high"
5+
source: |
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+
)
108+
attack_types:
109+
- "Credential Phishing"
110+
tactics_and_techniques:
111+
- "Impersonation: Brand"
112+
- "Social engineering"
113+
detection_methods:
114+
- "Content analysis"
115+
- "Header analysis"
116+
- "HTML analysis"
117+
- "URL analysis"
118+
id: "71dfd1cb-938a-55e7-8be3-34ee2bc2f1b1"
119+
tags:
120+
- created_from_open_prs
121+
- rule_status_modified
122+
- pr_author_zoomequipd
123+
references:
124+
- https://github.com/sublime-security/sublime-rules/pull/4751

0 commit comments

Comments
 (0)