Brand impersonation: DocuSign branded attachment lure with no DocuSign links
Detects DocuSign phishing messages with no DocuSign links, a DocuSign logo or verbage within an image or PDF attachment, from an untrusted sender.
Sublime rule (View on GitHub)
  1name: "Brand impersonation: DocuSign branded attachment lure with no DocuSign links"
  2description: "Detects DocuSign phishing messages with no DocuSign links, a DocuSign logo or verbage within an image or PDF attachment, from an untrusted sender."
  3type: "rule"
  4severity: "high"
  5source: |
  6  type.inbound
  7  and (
  8    (
  9      0 < length(attachments) <= 8
 10      and length(filter(attachments, .file_type in $file_types_images)) > 0
 11    )
 12    or (
 13      length(attachments) > 0
 14      and all(attachments,
 15              .file_type in $file_types_images
 16              or .file_type == 'pdf'
 17              or (
 18                .file_extension == "ics"
 19                or .content_type in ("text/calendar", "application/ics")
 20              )
 21      )
 22    )
 23  )
 24  and (
 25    // if there are links, ensure they are not docusign links
 26    (
 27      length(body.links) != 0
 28      and any(body.links,
 29              not strings.ilike(.href_url.domain.root_domain, "docusign.*")
 30      )
 31    )
 32    // sometimes there are no body links and it's all in the PDF attachment
 33    or length(body.links) == 0
 34  )
 35  and (
 36    // check the image or pdf attachments for Docusign 
 37    any(filter(attachments,
 38               .file_type in $file_types_images or .file_type == 'pdf'
 39        ),
 40        (
 41          any(ml.logo_detect(.).brands, .name == "DocuSign")
 42          or any(file.explode(.),
 43                 strings.ilike(.scan.ocr.raw, "*DocuSign*")
 44                 and (
 45                   any(ml.nlu_classifier(.scan.ocr.raw).intents,
 46                       .name == "cred_theft" and .confidence != "low"
 47                   )
 48                   or (
 49                     regex.icontains(.scan.ocr.raw,
 50                                     "((re)?view|access|complete(d)?) document(s)?",
 51                                     '[^d][^o][^cd][^ue]sign(?:\b|ature)',
 52                                     "important edocs",
 53                                     // German (Document (check|check|sign|sent))
 54                                     "Dokument (überprüfen|prüfen|unterschreiben|geschickt)",
 55                                     // German (important|urgent|immediate)
 56                                     "(wichtig|dringend|sofort)"
 57                     )
 58                     and any(ml.nlu_classifier(.scan.ocr.raw).topics,
 59                             .name == "E-Signature"
 60                     )
 61                     and not strings.count(.scan.ocr.raw, "\n\n\n\n\n\n\n\n\n\n") > 3
 62                   )
 63                 )
 64          )
 65        )
 66        and not any(file.explode(.),
 67                    strings.ilike(.scan.ocr.raw,
 68                                  "*DocuSigned By*",
 69                                  "*DocuSign Envelope ID*",
 70                                  "*Certificate Of Completion*",
 71                                  "*Adobe Sign*",
 72                                  // Additional Adobe Acrobat Sign check
 73                                  "*Powered by\nAdobe\nAcrobat Sign*"
 74                    )
 75                    or (
 76                      .depth == 0
 77                      and (
 78                        (
 79                          .scan.exiftool.page_count > 10
 80                          and length(.scan.strings.strings) > 8000
 81                        )
 82                        or (
 83                          .scan.exiftool.producer == "Acrobat Sign"
 84                          and any(.scan.exiftool.fields,
 85                                  .key == "SigningReason"
 86                                  and .value == "Certified by Adobe Acrobat Sign"
 87                          )
 88                        )
 89                      )
 90                    )
 91                    // negate resume related messages
 92                    or (
 93                      any(ml.nlu_classifier(body.current_thread.text).topics,
 94                          .name == "Professional and Career Development"
 95                          and .confidence == "high"
 96                      )
 97                      and any(ml.nlu_classifier(.scan.ocr.raw).intents,
 98                              .name == "benign" and .confidence != "low"
 99                      )
100                    )
101        )
102    )
103  
104    // accomidate truncated pngs and GIF files which can cause logodetect/OCR failures
105    or (
106      any(attachments,
107          .file_type =~ "gif"
108          //
109          // This rule makes use of a beta feature and is subject to change without notice
110          // using the beta feature in custom rules is not suggested until it has been formally released
111          //
112          or any(beta.parse_exif(.).fields,
113                 .key == "Warning" and .value == "Truncated PNG image"
114          )
115      )
116      and (
117        any(ml.logo_detect(file.message_screenshot()).brands, .name == "DocuSign")
118        //
119        // This rule makes use of a beta feature and is subject to change without notice
120        // using the beta feature in custom rules is not suggested until it has been formally released
121        //
122        or strings.ilike(beta.ocr(file.message_screenshot()).text, "*DocuSign*")
123      )
124      and (
125        (
126          any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents,
127              .name == "cred_theft" and .confidence != "low"
128          )
129          or regex.icontains(beta.ocr(file.message_screenshot()).text,
130                             "((re)?view|access|complete(d)?) document(s)?",
131                             "[^d][^o][^c][^u]sign",
132                             "important edocs",
133                             // German (Document (check|check|sign|sent))
134                             "Dokument (überprüfen|prüfen|unterschreiben|geschickt)",
135                             // German (important|urgent|immediate)
136                             "(wichtig|dringend|sofort)"
137          )
138        )
139      )
140      and not strings.ilike(beta.ocr(file.message_screenshot()).text,
141                            "*DocuSigned By*",
142                            "*DocuSign Envelope ID*",
143                            "*Certificate Of Completion*",
144                            "*Adobe Sign*"
145      )
146    )
147  )
148  and (
149    not profile.by_sender_email().solicited
150    or profile.by_sender_email().prevalence == "new"
151    or (
152      profile.by_sender_email().any_messages_malicious_or_spam
153      and not profile.by_sender_email().any_messages_benign
154    )
155  )
156  and not profile.by_sender_email().any_messages_benign
157  
158  // negate docusign 'via' messages
159  and not (
160    any(headers.hops,
161        any(.fields,
162            .name == "X-Api-Host" and strings.ends_with(.value, "docusign.net")
163        )
164    )
165    and strings.contains(sender.display_name, "via")
166  )
167  // negate docusign originated emails
168  and not any(headers.hops,
169              regex.imatch(.received.server.raw, ".+.docusign.(net|com)")
170  )
171  
172  // negate replies to docusign notifications
173  and not any(headers.references, strings.iends_with(., '@camail.docusign.net'))  
174attack_types:
175  - "Credential Phishing"
176tactics_and_techniques:
177  - "Impersonation: Brand"
178  - "Social engineering"
179detection_methods:
180  - "Computer Vision"
181  - "Content analysis"
182  - "Header analysis"
183  - "Natural Language Understanding"
184  - "Optical Character Recognition"
185  - "Sender analysis"
186  - "URL screenshot"
187id: "814a5694-d626-5bf4-a1ba-a1dbcb625279"