Brand impersonation: Adobe Sign with suspicious indicators

Detects messages impersonating Adobe Sign that contain Adobe branding elements but are not sent from legitimate Adobe domains and lack proper Adobe Sign authentication headers.

Sublime rule (View on GitHub)

  1name: "Brand impersonation: Adobe Sign with suspicious indicators"
  2description: "Detects messages impersonating Adobe Sign that contain Adobe branding elements but are not sent from legitimate Adobe domains and lack proper Adobe Sign authentication headers."
  3type: "rule"
  4severity: "high"
  5source: |
  6  type.inbound
  7  and (
  8    (
  9      length(filter(attachments, .file_type == "pdf")) == 0
 10      and (
 11        regex.icontains(body.html.raw,
 12                        'alt="Adobe(?: Acrobat)? Sign"',
 13                        "adobe-sign-logo.{0,20}.png",
 14                        'alt="Powered by Adobe Acrobat Sign"'
 15        )
 16        or any(html.xpath(body.html, "//img/@src").nodes,
 17               strings.parse_url(.raw).domain.root_domain == "adobesign.com"
 18               and (
 19                 strings.istarts_with(strings.parse_url(.raw).path,
 20                                      "/cobrand_logo/"
 21                 )
 22                 or strings.icontains(strings.parse_url(.raw).path,
 23                                      "checkmarkCircle"
 24                 )
 25               )
 26        )
 27      )
 28    )
 29    or (
 30      any(attachments,
 31          .file_type == "pdf"
 32          and any(file.explode(.),
 33                  any(.scan.url.urls,
 34                      regex.icontains(.url,
 35                                      '(?:ad0be.{0,5}s[1i]gn|ad[0o]be.{0,5}s1gn)'
 36                      )
 37                  )
 38          )
 39      )
 40    )
 41  )
 42  and not (
 43    // inspect the "oldest" thread, negate where that thread is the original Adobe Sign email (based on link domains)
 44    (
 45      length(body.previous_threads[length(body.previous_threads) - 1].links) > 0
 46      and all(body.previous_threads[length(body.previous_threads) - 1].links,
 47              .href_url.domain.root_domain in (
 48                "aka.ms",
 49                "adobe.com",
 50                "adobesign.com",
 51                "echosign.com",
 52                "adobesignsandbox.com",
 53                "mimecastprotect.com",
 54                "mimecast.com"
 55              )
 56              or .href_url.domain.root_domain in $org_domains
 57              or .href_url.domain.root_domain == sender.email.domain.root_domain
 58              or any(recipients.to,
 59                     .email.domain.root_domain == ..href_url.domain.root_domain
 60              )
 61      )
 62    )
 63    // legit review button
 64    or any(body.links,
 65           .display_text in (
 66             "Review and sign",
 67             "the document",
 68             "Open agreement",
 69             "VIEW DOCUMENTS",
 70             "Click here to review and sign"
 71           )
 72           and (
 73             .href_url.domain.root_domain in (
 74               "adobe.com",
 75               "adobesign.com",
 76               "echosign.com",
 77               "adobesignsandbox.com",
 78             )
 79             // Mimecast link logic
 80             or (
 81               .href_url.domain.root_domain in (
 82                 "mimecastprotect.com",
 83                 "mimecast.com"
 84               )
 85               and any(.href_url.query_params_decoded['domain'],
 86                       strings.parse_domain(.).root_domain in (
 87                         "adobe.com",
 88                         "adobesign.com",
 89                         "echosign.com",
 90                         "adobesignsandbox.com",
 91                       )
 92               )
 93             )
 94           )
 95    )
 96    // accidental recipient
 97    or any(recipients.to, .email.email == "adobesign@adobesign.com")
 98    // known Adobe Sign messaage ID formats
 99    or (
100      (length(headers.references) > 1 or length(body.previous_threads) != 0)
101      and regex.imatch(headers.references[0],
102                       '[0-9]{9,10}\.[0-9]{4,6}\.[0-9]{13}@event-consumer-prod-[a-z]-[a-z0-9]{7,10}-[a-z0-9]{5}',
103                       '[0-9]{8,10}\.[0-9]{5,7}\.[0-9]{13}@(webapp|job)-prod-.*$',
104                       '[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}-APO-PRODHIPAA@apo-p-h'
105      )
106    )
107    // negate Adobe Sign messages from custom domains
108    or any(headers.hops,
109           any(.fields, .name in ("Adobesigneventid", "Agreementid"))
110    )
111  )
112  and not (
113    sender.email.domain.root_domain in (
114      "adobe.com",
115      "adobesign.com",
116      "adobesignsandbox.com",
117      "echosign.com",
118      // ticketing software that embeds emails
119      "helpscout.net"
120    )
121    and headers.auth_summary.dmarc.pass
122  )
123  and (
124    (
125      sender.email.domain.root_domain in $high_trust_sender_root_domains
126      and not headers.auth_summary.dmarc.pass
127    )
128    or sender.email.domain.root_domain not in $high_trust_sender_root_domains
129  )  
130attack_types:
131  - "Credential Phishing"
132tactics_and_techniques:
133  - "Impersonation: Brand"
134  - "Social engineering"
135detection_methods:
136  - "Content analysis"
137  - "Header analysis"
138  - "HTML analysis"
139  - "Sender analysis"
140id: "704d143a-7ef2-5601-9e38-e659f0f65c8c"
to-top