Credential Phishing: Suspicious E-sign Agreement Document Notification
Detects phishing attempts disguised as e-signature requests, characterized by common document sharing phrases, unusual HTML padding, and suspicious link text.
Sublime rule (View on GitHub)
1name: "Credential Phishing: Suspicious E-sign Agreement Document Notification"
2description: "Detects phishing attempts disguised as e-signature requests, characterized by common document sharing phrases, unusual HTML padding, and suspicious link text."
3type: "rule"
4severity: "medium"
5source: |
6 type.inbound
7 and any([subject.subject, sender.display_name],
8 regex.icontains(strings.replace_confusables(.),
9 "DocuLink",
10 "Access.&.Approved",
11 "Agreement.{0,5}Review",
12 "Attend.and.Review",
13 "Completed.File",
14 "Dochsared",
15 "Docshared",
16 "DocsPoint",
17 "Document.Shared",
18 "DocuCentre",
19 "DocuCenter",
20 "DocCenter",
21 "DocsOnline",
22 "DocSend",
23 "docsign",
24 "\\beSign",
25 "e\\.sign",
26 "esign.online",
27 "e-doc",
28 "e-signature",
29 "eSignature",
30 "eSign&Return",
31 "eSignOnline",
32 "Fileshare",
33 "Review.and.Complete",
34 "Review.&.Sign",
35 "SignOnline",
36 "Signature.Request",
37 "Shared.Completed",
38 "Sign.and.Seal",
39 "viaSign",
40 "D0cuSign",
41 "DocsID",
42 "Complete.{0,10}DocuSign",
43 "Enroll & Sign",
44 "Review and Sign",
45 "SignReport",
46 "SignDoc",
47 "Docxxx",
48 "docufile",
49 "E-Sign&Return",
50 "document.signature",
51 "Electronic.?Signature",
52 "Complete: ",
53 "Please Review"
54 )
55 )
56 and (
57 // unusual repeated patterns in HTML
58 regex.icontains(body.html.raw, '((<br\s*/?>\s*){20,}|\n{20,})')
59 or regex.icontains(body.html.raw, '(<p[^>]*>\s*<br\s*/?>\s*</p>\s*){30,}')
60 or regex.icontains(body.html.raw,
61 '(<p class=".*?"><span style=".*?"><o:p> </o:p></span></p>\s*){30,}'
62 )
63 or regex.icontains(body.html.raw, '(<p> </p>\s*){7,}')
64 or regex.icontains(body.html.raw, '(<p[^>]*>\s* <br>\s*</p>\s*){5,}')
65 or regex.icontains(body.html.raw, '(<p[^>]*> </p>\s*){7,}')
66 or strings.count(body.html.raw, '  ') > 50
67 or regex.count(body.html.raw,
68 '<span\s*class\s*=\s*"[^\"]+"\s*>\s*[a-z]\s*<\/span><span\s*class\s*=\s*"[^\"]+"\s*>\s*[a-z]+\s*<\/span>'
69 ) > 50
70 // lookalike docusign
71 or regex.icontains(body.html.raw, '>Docus[1l]gn<')
72 or (regex.icontains(body.html.inner_text, 'Document') and length(body.html.inner_text) < 300)
73 // common greetings via email.local_part
74 or any(recipients.to,
75 // use count to ensure the email address is not part of a disclaimer
76 strings.icount(body.current_thread.text, .email.local_part) >
77 // sum allows us to add more logic as needed
78 sum([
79 strings.icount(body.current_thread.text,
80 strings.concat('was sent to ', .email.email)
81 ),
82 strings.icount(body.current_thread.text,
83 strings.concat('intended for ', .email.email)
84 )
85 ]
86 )
87 )
88 // HR impersonation
89 or strings.ilike(sender.display_name, "HR", "H?R", "*Human Resources*")
90 )
91 and (
92 any(body.links,
93 regex.icontains(.display_text,
94 "activate",
95 "re-auth",
96 "verify",
97 "acknowledg",
98 "(keep|change).{0,20}(active|password|access)",
99 '((verify|view|click|download|goto|keep|Vιew|release).{0,15}(attachment|current|download|fax|file|document|message|same)s?)',
100 'use.same.pass',
101 'validate.{0,15}account',
102 'recover.{0,15}messages',
103 '(retry|update).{0,10}payment',
104 'check activity',
105 '(listen|play).{0,10}(vm|voice)',
106 'clarify.{0,20}(deposit|wallet|funds)',
107 'enter.{0,15}teams',
108 'Review and sign',
109 'REVIEW.*DOCUMENT'
110
111 )
112 )
113 or any(body.links,
114 (
115 regex.contains(.display_text,
116 "\\bVIEW",
117 "DOWNLOAD",
118 "CHECK",
119 "KEEP.(SAME|MY)",
120 "VERIFY",
121 "ACCESS\\b",
122 "SIGN\\b",
123 "ENABLE\\b",
124 "RETAIN",
125 "PLAY",
126 "LISTEN",
127 )
128 and regex.match(.display_text, "^[^a-z]*[A-Z][^a-z]*$")
129 )
130 )
131 or (
132 length(attachments) > 0
133 and any(attachments,
134 (
135 regex.icontains(beta.ocr(.).text,
136 "activate",
137 "re-auth",
138 "verify",
139 "acknowledg",
140 "(keep|change).{0,20}(active|password|access)",
141 '((verify|view|click|download|goto|keep|Vιew|release).{0,15}(attachment|current|download|fax|file|document|message|same)s?)',
142 'use.same.pass',
143 'validate.{0,15}account',
144 'recover.{0,15}messages',
145 '(retry|update).{0,10}payment',
146 'check activity',
147 '(listen|play).{0,10}(vm|voice)',
148 'clarify.{0,20}(deposit|wallet|funds)',
149 'enter.{0,15}teams',
150 'Review and sign'
151 )
152 )
153 or (
154 any(file.explode(.),
155 regex.icontains(.scan.ocr.raw,
156 "activate",
157 "re-auth",
158 "verify",
159 "acknowledg",
160 "(keep|change).{0,20}(active|password|access)",
161 '((verify|view|click|download|goto|keep|Vιew|release).{0,15}(attachment|current|download|fax|file|document|message|same)s?)',
162 'use.same.pass',
163 'validate.{0,15}account',
164 'recover.{0,15}messages',
165 '(retry|update).{0,10}payment',
166 'check activity',
167 '(listen|play).{0,10}(vm|voice)',
168 'clarify.{0,20}(deposit|wallet|funds)',
169 'enter.{0,15}teams',
170 'Review and sign'
171 )
172 )
173 )
174 )
175 )
176 )
177 and (
178 not profile.by_sender().solicited
179 or (
180 profile.by_sender().any_messages_malicious_or_spam
181 and not profile.by_sender().any_false_positives
182 )
183 )
184 and not profile.by_sender().any_false_positives
185
186 // negate replies/fowards containing legitimate docs
187 and not (
188 length(headers.references) > 0
189 or any(headers.hops, any(.fields, strings.ilike(.name, "In-Reply-To")))
190 )
191
192 // negate highly trusted sender domains unless they fail DMARC authentication
193 and (
194 (
195 sender.email.domain.root_domain in $high_trust_sender_root_domains
196 and (
197 any(distinct(headers.hops, .authentication_results.dmarc is not null),
198 strings.ilike(.authentication_results.dmarc, "*fail")
199 )
200 )
201 )
202 or sender.email.domain.root_domain not in $high_trust_sender_root_domains
203 )
204attack_types:
205 - "Credential Phishing"
206tactics_and_techniques:
207 - "Social engineering"
208detection_methods:
209 - "Content analysis"
210 - "Header analysis"
211 - "HTML analysis"
212 - "URL analysis"
213 - "Sender analysis"
214id: "9b68c2d8-951e-5e04-9fa3-2ca67d9226a6"