Skip to content

Commit 75bd192

Browse files
[Shared Samples] [PR #4391] added rule: PR# 4391 - Credential phishing: Generic document share template
1 parent a119f7d commit 75bd192

1 file changed

Lines changed: 125 additions & 0 deletions

File tree

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
name: "PR# 4391 - Credential phishing: Generic document share template"
2+
description: "Detects messages that incorporate recipient-specific information (email domain, local part, or domain elements) alongside document-themed Unicode symbols and keywords. The rule identifies various targeting patterns including greeting-based personalization, attention-grabbing prefixes and multiple recipient elements. It also catches broken template attacks where recipient placeholders remain visible."
3+
type: "rule"
4+
severity: "low"
5+
source: |
6+
type.inbound
7+
and (
8+
// nlu capture for wide scope of greetings to reduce evasion
9+
any(filter(ml.nlu_classifier(body.current_thread.text).entities,
10+
.name == "greeting"
11+
),
12+
any([
13+
recipients.to[0].email.domain.sld,
14+
recipients.to[0].email.local_part,
15+
recipients.to[0].email.domain.domain
16+
],
17+
// recipient entity follows the greeting in the body text
18+
strings.icontains(body.current_thread.text,
19+
strings.concat(..text, " ", .)
20+
)
21+
)
22+
)
23+
or (
24+
// nlu capture for wide scope of greetings to reduce evasion
25+
any(filter(ml.nlu_classifier(body.current_thread.text).entities,
26+
.name == "greeting"
27+
),
28+
any(filter(ml.nlu_classifier(body.current_thread.text).entities,
29+
.name == "recipient"
30+
),
31+
// recipient entity follows the greeting in the body text
32+
strings.icontains(body.current_thread.text,
33+
strings.concat(..text, " ", .text)
34+
)
35+
// the named recipient doesn't match the actual "to" recipient
36+
and not any([
37+
recipients.to[0].email.domain.sld,
38+
recipients.to[0].email.local_part,
39+
recipients.to[0].email.domain.domain
40+
],
41+
strings.icontains(..text, .)
42+
)
43+
)
44+
)
45+
)
46+
or any([
47+
recipients.to[0].email.domain.sld,
48+
recipients.to[0].email.local_part,
49+
recipients.to[0].email.domain.domain
50+
],
51+
// strings logic for non-greeting body starter
52+
strings.icontains(body.current_thread.text,
53+
strings.concat("attn: ", .)
54+
)
55+
// strings logic for recipient as starter
56+
or strings.icontains(body.current_thread.text,
57+
strings.concat(., " balance statement")
58+
)
59+
)
60+
// count of all recipient elements is higher 2 or greater
61+
or length(filter([
62+
recipients.to[0].email.domain.sld,
63+
recipients.to[0].email.local_part,
64+
recipients.to[0].email.domain.domain
65+
],
66+
strings.icontains(body.current_thread.text, .)
67+
)
68+
) >= 2
69+
70+
// logic for broken attack
71+
or any(ml.nlu_classifier(body.current_thread.text).entities,
72+
.name == "recipient" and regex.icontains(.text, '[{}]')
73+
)
74+
)
75+
76+
// unicode + keyword generic template
77+
and (
78+
regex.icontains(body.current_thread.text,
79+
'(?:\x{2710}|\x{270D}|\x{270E}|\x{270F}|\x{1F4C1}|\x{1F4C4}|\x{1F4D1}|\x{1F4DD}|\x{1F4EC}|\x{1F589})\n?.{0,15}(?:document|completion|remit|review|statement|agree|shar(?:ed|ing)|receiv|\bmail\b)',
80+
'(?:document|completion|remit|review|statement|agree|shar(?:ed|ing)|receiv|\bmail\b)\n?.{0,15}(?:\x{2710}|\x{270D}|\x{270E}|\x{270F}|\x{1F4C1}|\x{1F4C4}|\x{1F4D1}|\x{1F4DD}|\x{1F4EC}|\x{1F589})'
81+
)
82+
// negate sharepoint paths with unicode
83+
and not any(body.links,
84+
regex.icontains(.display_url.path,
85+
'(?:\x{2710}|\x{270D}|\x{270E}|\x{270F}|\x{1F4C1}|\x{1F4C4}|\x{1F4D1}|\x{1F4DD}|\x{1F4EC}|\x{1F589})'
86+
)
87+
)
88+
)
89+
90+
// nlu negation for FP's
91+
and any(ml.nlu_classifier(body.current_thread.text).intents, .name != "benign")
92+
93+
// negate highly trusted sender domains unless they fail DMARC authentication
94+
and (
95+
(
96+
sender.email.domain.root_domain in $high_trust_sender_root_domains
97+
and not headers.auth_summary.dmarc.pass
98+
)
99+
or sender.email.domain.root_domain not in $high_trust_sender_root_domains
100+
)
101+
102+
// negate legitimate conversations
103+
and not (
104+
(length(headers.references) > 0 or headers.in_reply_to is not null)
105+
and (subject.is_forward or subject.is_reply)
106+
and length(body.previous_threads) >= 1
107+
)
108+
109+
tags:
110+
- "Attack surface reduction"
111+
- pr_author_missingn0pe
112+
- created_from_open_prs
113+
- rule_status_modified
114+
attack_types:
115+
- "BEC/Fraud"
116+
- "Credential Phishing"
117+
tactics_and_techniques:
118+
- "Social engineering"
119+
- "Evasion"
120+
detection_methods:
121+
- "Content analysis"
122+
- "Natural Language Understanding"
123+
id: "44d63e59-9ec9-57d6-9a6f-79e1f53d589a"
124+
references:
125+
- https://github.com/sublime-security/sublime-rules/pull/4391

0 commit comments

Comments
 (0)