Brand impersonation: DocuSign
Attack impersonating a DocuSign request for signature.
Sublime rule (View on GitHub)
1name: "Brand impersonation: DocuSign"
2description: |
3 Attack impersonating a DocuSign request for signature.
4references:
5 - "https://playground.sublimesecurity.com?id=2d2c6472-fabb-4952-b902-573a6294aa2f"
6type: "rule"
7severity: "high"
8source: |
9 type.inbound
10 and (
11 // orgs can have docusign.company.com
12 strings.ilike(sender.email.email, '*docusign.net*', '*docusign.com*')
13
14 // if the above is true, you'll see a "via Docusign"
15 or strings.ilike(sender.display_name, '*docusign*')
16
17 // detects 1 character variations,
18 // such as DocuSlgn (with an "L" instead of an "I")
19 or strings.ilevenshtein(sender.display_name, "docusign") == 1
20 or strings.ilike(sender.display_name, "*docuonline*", "*via *signature*")
21 or (
22 strings.istarts_with(body.html.inner_text, "docusign")
23 and not strings.istarts_with(body.current_thread.text, "docusign")
24 )
25 or (
26 (
27 regex.icontains(body.html.raw, '<font size="[0-9]">DocuSign</font>')
28 or regex.icontains(body.html.raw, '\nDocu(?:<[^\>]+>\s*)+Sign<')
29 or regex.icontains(body.html.raw,
30 '<span[^>]*style="[^"]*">DocuSign<\/span>'
31 )
32 or regex.icontains(body.html.raw,
33 '<span[^>]*style="[^"]*">(Docu|D(?:ocu?)?)<\/span><span[^>]*style="[^"]*">(Sign|S(?:ign?)?)<\/span>'
34 )
35 or regex.icontains(body.html.raw, '<strong>DocuSign</strong>')
36 or regex.icontains(body.html.raw, '<div class="logo">DocuSign</div>')
37 or regex.icontains(body.html.raw,
38 'D󠀤󠀤o󠀤󠀤c︀uS󠀤󠀤i︀gn'
39 )
40 )
41 and (
42 regex.icontains(body.html.raw, 'background:\s*rgb\(30,\s*76,\s*161\)')
43 or regex.icontains(body.html.raw,
44 'background-color:\s*rgb\(30,\s*76,\s*161\)'
45 )
46 or regex.icontains(body.html.raw,
47 'background-color:\s*rgb\(61,\s*170,\s*73\)'
48 )
49 or regex.icontains(body.html.raw,
50 '<div[^>]*BACKGROUND-COLOR: #1e4ca1[^>]*>',
51 '<td[^>]*BACKGROUND-COLOR: #1e4ca1[^>]*>',
52 '<table[^>]*background-color:\s*#1e4ca1'
53 )
54 or regex.icontains(body.html.raw, 'background-color:#214e9f;')
55 or regex.icontains(body.html.raw, 'background-color:#3260a7')
56 or regex.icontains(body.html.raw, 'background-color:#0056b3')
57 or regex.icontains(body.html.raw, 'BACKGROUND-COLOR:#1e4ca1')
58 or regex.icontains(body.html.raw, 'background-color:#214395')
59 or regex.icontains(body.html.raw,
60 '<table[^>]*style="[^"]*background:\s*#1E4CA1[^"]*"[^>]*>(.*?)<\/table>'
61 )
62 or regex.icontains(body.html.raw, '<title>Document.{0,50}</title>')
63 or any(body.links, regex.icontains(.display_text, 'view.{0,3}doc'))
64 or any(body.links, regex.contains(.display_text, '\bDOCUMENT'))
65 )
66 )
67 )
68
69 // identifies the main CTA in the email, eg "Review now" or "Review document"
70 // this should always be a known docusign domain,
71 // even with branded docusign subdomains
72 and (
73 any(body.links,
74 // we've observed invisible characters in the display name
75 // such as U+034f(look carefully): "Revi͏ew Now"
76 (
77 strings.ilevenshtein(.display_text, "Review Now") <= 3
78 or (
79 strings.icontains(.display_text, "Review")
80 and not strings.icontains(.display_text, "Review Us")
81 )
82 or strings.icontains(.display_text, "Now")
83 or strings.icontains(.display_text, "document")
84 )
85 and not .href_url.domain.root_domain in ("docusign.com", "docusign.net")
86 and not (
87 .href_url.domain.root_domain == "mimecastprotect.com"
88 and (
89 .href_url.query_params is not null
90 and (
91 regex.icontains(.href_url.query_params,
92 'domain=(?:\w+.)?docusign.net'
93 )
94 or regex.icontains(.href_url.query_params,
95 'domain=(?:\w+.)?docusign.com'
96 )
97 )
98 )
99 )
100 )
101 // Suspicious attachment
102 or any(attachments,
103 (
104 .file_extension in~ ("html", "htm", "shtml", "dhtml")
105 or .file_extension in~ $file_extensions_common_archives
106 or .file_type == "html"
107 or .content_type == "text/html"
108 )
109 and 1 of (
110 (
111 regex.icontains(file.parse_html(.).raw, '\s{0,}<script.*')
112 and regex.icontains(file.parse_html(.).raw, "</script>")
113 ),
114 strings.ilike(file.parse_html(.).raw,
115 "*createElement*",
116 "*appendChild*",
117 "*createObjectURL*"
118 ),
119 strings.icount(file.parse_html(.).raw, "/*") > 10,
120 any($free_subdomain_hosts, strings.icontains(..file_name, .))
121 )
122 )
123 )
124
125 // negate highly trusted sender domains unless they fail DMARC authentication
126 and (
127 coalesce(sender.email.domain.root_domain in $high_trust_sender_root_domains
128 and not headers.auth_summary.dmarc.pass,
129 false
130 )
131 or sender.email.domain.root_domain not in $high_trust_sender_root_domains
132 )
133
134 // adding negation for messages originating from docusigns api
135 // and the sender.display.name contains "via"
136 and not (
137 any(headers.hops,
138 any(.fields,
139 .name == "X-Api-Host" and strings.ends_with(.value, "docusign.net")
140 )
141 )
142 and strings.contains(sender.display_name, "via")
143 )
144 and (
145 not profile.by_sender().solicited
146 or (
147 profile.by_sender().any_messages_malicious_or_spam
148 and not profile.by_sender().any_false_positives
149 )
150 )
151attack_types:
152 - "Credential Phishing"
153tactics_and_techniques:
154 - "Impersonation: Brand"
155 - "Lookalike domain"
156 - "Social engineering"
157 - "Spoofing"
158detection_methods:
159 - "Header analysis"
160 - "Sender analysis"
161 - "URL analysis"
162id: "4d29235c-08b9-5f9b-950e-60b05c4691fb"