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  )
21
22  // identifies the main CTA in the email, eg "Review now" or "Review document"
23  // this should always be a known docusign domain,
24  // even with branded docusign subdomains
25  and any(body.links,
26          // we've observed invisible characters in the display name
27          // such as U+034f(look carefully): "Revi͏ew Now"
28          (
29            strings.ilevenshtein(.display_text, "Review Now") <= 3
30            or (
31              strings.icontains(.display_text, "Review")
32              and not strings.icontains(.display_text, "Review Us")
33            )
34            or strings.icontains(.display_text, "Now")
35            or strings.contains(.display_text, "document")
36          )
37          and .href_url.domain.root_domain not in ("docusign.com", "docusign.net")
38  )
39  and (
40    sender.email.domain.root_domain not in ('docusign.net', 'docusign.com')
41    // check for DMARC fail for spoofs
42    or any(distinct(headers.hops, .authentication_results.dmarc is not null),
43           strings.ilike(.authentication_results.dmarc, "*fail")
44    )
45  )
46  // adding negation for messages originating from docusigns api
47  // and the sender.display.name contains "via"
48  and not (
49    any(headers.hops,
50        any(.fields, .name == "X-Api-Host" and strings.ends_with(.value, "docusign.net"))
51    )
52    and strings.contains(sender.display_name, "via")
53  )
54  // unsolicited
55  and (
56    (
57      sender.email.domain.root_domain in $free_email_providers
58      and sender.email.email not in $recipient_emails
59    )
60    or (
61      sender.email.domain.root_domain not in $free_email_providers
62      and sender.email.domain.domain not in $recipient_domains
63    )
64  )  
65attack_types:
66  - "Credential Phishing"
67tactics_and_techniques:
68  - "Impersonation: Brand"
69  - "Lookalike domain"
70  - "Social engineering"
71  - "Spoofing"
72detection_methods:
73  - "Header analysis"
74  - "Sender analysis"
75  - "URL analysis"
76id: "4d29235c-08b9-5f9b-950e-60b05c4691fb"
to-top