Credential Phishing: Fake Password Expiration from New and Unsolicited sender
This rule looks for password expiration verbiage in the subject and body. Requiring between 1 - 9 links, a short body, and NLU in addition to statically specified term anchors. High trust senders are also negated.
Sublime rule (View on GitHub)
1name: "Credential Phishing: Fake Password Expiration from New and Unsolicited sender"
2description: "This rule looks for password expiration verbiage in the subject and body. Requiring between 1 - 9 links, a short body, and NLU in addition to statically specified term anchors. High trust senders are also negated."
3type: "rule"
4severity: "medium"
5source: |
6 type.inbound
7
8 // few links
9 and 0 < length(body.links) < 10
10
11 // no attachments or suspicious attachment
12 and (
13 length(attachments) == 0
14 or any(attachments,
15 .file_type in ("pdf", "doc", "docx")
16 and any(file.explode(.),
17 .scan.entropy.entropy > 7 and length(.scan.ocr.raw) < 20
18 )
19 )
20 )
21
22 // body contains expire, expiration, loose, lose
23 and (
24 regex.icontains(body.current_thread.text,
25 '(expir(e)?(ation|s)|\blo(o)?se\b|(?:offices?|microsoft).365|re.{0,3}confirm)|due for update'
26 )
27 and not strings.icontains(body.current_thread.text, 'link expires in ')
28 )
29 and (
30 // subject or body contains account or access
31 any([subject.subject, body.current_thread.text],
32 regex.icontains(., "account|access|your email")
33 )
34 // suspicious use of recipients email address
35 or any(recipients.to,
36 any([subject.subject, body.current_thread.text],
37 strings.icontains(strings.replace_confusables(.),
38 ..email.local_part
39 )
40 or strings.icontains(strings.replace_confusables(.), ..email.email)
41 )
42 )
43 )
44
45 // subject or body must contains password
46 and any([
47 strings.replace_confusables(subject.subject),
48 strings.replace_confusables(body.current_thread.text)
49 ],
50 regex.icontains(., '\bpassword\b', '\bmulti.?factor\b')
51 )
52 and (
53 any(ml.nlu_classifier(strings.replace_confusables(body.current_thread.text)).intents,
54 .name == "cred_theft" and .confidence == "high"
55 )
56 or length(filter([
57 "password",
58 "expiration",
59 "expire",
60 "expiring",
61 "kindly",
62 "renew",
63 "review",
64 "click below",
65 "kicked out",
66 "prevent",
67 "required now",
68 "immediate action",
69 "security update",
70 "blocked",
71 "locked",
72 "interruption",
73 "stay connected",
74 ],
75 strings.icontains(strings.replace_confusables(body.current_thread.text
76 ),
77 .
78 )
79 )
80 ) >= 3
81 )
82
83 // body length between 200 and 2000
84 and (
85 200 < length(body.current_thread.text) < 2000
86
87 // excessive whitespace
88 or (
89 regex.icontains(body.html.raw, '(?:(?:<br\s*/?>\s*){20,}|\n{20,})')
90 or regex.icontains(body.html.raw, '(?:<p[^>]*>\s*<br\s*/?>\s*</p>\s*){30,}')
91 or regex.icontains(body.html.raw,
92 '(?:<p class=".*?"><span style=".*?"><o:p> </o:p></span></p>\s*){30,}'
93 )
94 or regex.icontains(body.html.raw, '(?:<p>\s* \s*</p>\s*){7,}')
95 or regex.icontains(body.html.raw, '(?:<p>\s* \s*</p>\s*<br>\s*){7,}')
96 or regex.icontains(body.html.raw, '(?:<p[^>]*>\s* \s*<br>\s*</p>\s*){5,}')
97 or regex.icontains(body.html.raw, '(?:<p[^>]*> </p>\s*){7,}')
98 )
99 )
100
101 // a body link does not match the sender domain
102 and any(body.links,
103 .href_url.domain.root_domain != sender.email.domain.root_domain
104 and .href_url.domain.root_domain not in $org_domains
105 )
106
107 // and no false positives and not solicited
108 and (
109 not profile.by_sender().any_false_positives
110 and not profile.by_sender().solicited
111 )
112
113 // not a reply
114 and (
115 length(headers.references) == 0
116 or not any(headers.hops, any(.fields, strings.ilike(.name, "In-Reply-To")))
117 )
118
119 // negate highly trusted sender domains unless they fail DMARC authentication
120 and (
121 (
122 sender.email.domain.root_domain in $high_trust_sender_root_domains
123 and (
124 any(distinct(headers.hops, .authentication_results.dmarc is not null),
125 strings.ilike(.authentication_results.dmarc, "*fail")
126 )
127 )
128 )
129 or sender.email.domain.root_domain not in $high_trust_sender_root_domains
130 )
131
132attack_types:
133 - "Credential Phishing"
134tactics_and_techniques:
135 - "Social engineering"
136detection_methods:
137 - "Content analysis"
138 - "Natural Language Understanding"
139 - "Sender analysis"
140id: "5d9c3a75-5f57-5d0c-a07f-0f300bbde076"