Detection rules › Sublime MQL

Service abuse: HelloSign from an unsolicited sender address

Severity
low
Type
rule
Source
github.com/sublime-security/sublime-rules

Detects messages from HelloSign in which the document originates from a newly observed email address. The email address is extracted from across multiple message components, including HTML body templates and email header fields.

Threat classification

Sublime's own taxonomy (not MITRE ATT&CK).

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering, Free file host, Evasion

Event coverage

Rule body MQL

type.inbound
and sender.email.domain.domain == "mail.hellosign.com"
and headers.auth_summary.spf.pass
and headers.auth_summary.dmarc.pass
and (
  // extract the sender out of the body html template
  (
    // if the sender_email is available in the body
    regex.icontains(body.html.raw,
                    '<th class="action-item--action[^\>]+\>\s*[^\<]*\((?P<sender_email>[^\)]+)\).*?</th>'
    )
    // check that the sender email has not been observed previously
    and all(regex.iextract(body.html.raw,
                           '<th class="action-item--action[^\>]+\>\s*[^\<]*\((?P<sender_email>[^\"]+@(?P<sender_domain>[^\"]+))\).*?</th>'
            ),
            .named_groups["sender_domain"] not in $org_domains
            and .named_groups["sender_email"] not in $recipient_emails
            and .named_groups["sender_email"] not in $sender_emails
            and not (
              .named_groups["sender_domain"] not in $free_email_providers
              and .named_groups["sender_domain"] in $recipient_domains
              and .named_groups["sender_domain"] in $sender_domains
            )
    )
  )

  // extract the sender out of header hops if it's there
  or any(headers.hops,
         any(.fields,
             .name == "X-Mailgun-Variables"
             and strings.icontains(.value, 'on_behalf_of_email')
             and all(regex.iextract(.value,
                                    '\"on_behalf_of_email": \"(?P<sender_email>[^\"]+@(?P<sender_domain>[^\"]+))\",'
                     ),
                     .named_groups["sender_domain"] not in $org_domains
                     and .named_groups["sender_email"] not in $recipient_emails
                     and .named_groups["sender_email"] not in $sender_emails
                     and not (
                       .named_groups["sender_domain"] not in $free_email_providers
                       and .named_groups["sender_domain"] in $recipient_domains
                       and .named_groups["sender_domain"] in $sender_domains
                     )
             )
         )
  )

  // extract the sender from the "reply to sender" element withn the body.html.raw
  or (
    regex.icontains(body.html.raw,
                    '<a href="mailto:[^\?]+\?[^\"]+\"[^\>]+\>(?:<img[^\>]+\>)?\s*Reply to sender<\/a>'
    )
    and all(regex.iextract(body.html.raw,
                           '<a href="mailto:(?P<sender_email>[^\?]+@(?P<sender_domain>[^\?]+))\?[^\"]+\"[^\>]+\>(?:<img[^\>]+\>)?\s*Reply to sender<\/a>'
            ),
            .named_groups["sender_domain"] not in $org_domains
            and .named_groups["sender_email"] not in $recipient_emails
            and .named_groups["sender_email"] not in $sender_emails
            and not (
              .named_groups["sender_domain"] not in $free_email_providers
              and .named_groups["sender_domain"] in $recipient_domains
              and .named_groups["sender_domain"] in $sender_domains
            )
    )
  )
)

Detection logic

Scope: inbound message.

Detects messages from HelloSign in which the document originates from a newly observed email address. The email address is extracted from across multiple message components, including HTML body templates and email header fields.

  1. inbound message
  2. sender.email.domain.domain is 'mail.hellosign.com'
  3. headers.auth_summary.spf.pass
  4. headers.auth_summary.dmarc.pass
  5. any of:
    • all of:
      • body.html.raw matches '<th class="action-item--action[^\\>]+\\>\\s*[^\\<]*\\((?P<sender_email>[^\\)]+)\\).*?</th>'
      • all of regex.iextract(body.html.raw) where all hold:
        • .named_groups['sender_domain'] not in $org_domains
        • .named_groups['sender_email'] not in $recipient_emails
        • .named_groups['sender_email'] not in $sender_emails
        • not:
          • all of:
            • .named_groups['sender_domain'] not in $free_email_providers
            • .named_groups['sender_domain'] in $recipient_domains
            • .named_groups['sender_domain'] in $sender_domains
    • any of headers.hops where:
      • any of .fields where all hold:
        • .name is 'X-Mailgun-Variables'
        • .value contains 'on_behalf_of_email'
        • all of regex.iextract(.value) where all hold:
          • .named_groups['sender_domain'] not in $org_domains
          • .named_groups['sender_email'] not in $recipient_emails
          • .named_groups['sender_email'] not in $sender_emails
          • not:
            • all of:
              • .named_groups['sender_domain'] not in $free_email_providers
              • .named_groups['sender_domain'] in $recipient_domains
              • .named_groups['sender_domain'] in $sender_domains
    • all of:
      • body.html.raw matches '<a href="mailto:[^\\?]+\\?[^\\"]+\\"[^\\>]+\\>(?:<img[^\\>]+\\>)?\\s*Reply to sender<\\/a>'
      • all of regex.iextract(body.html.raw) where all hold:
        • .named_groups['sender_domain'] not in $org_domains
        • .named_groups['sender_email'] not in $recipient_emails
        • .named_groups['sender_email'] not in $sender_emails
        • not:
          • all of:
            • .named_groups['sender_domain'] not in $free_email_providers
            • .named_groups['sender_domain'] in $recipient_domains
            • .named_groups['sender_domain'] in $sender_domains

Inspects: body.html.raw, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, sender.email.domain.domain, type.inbound. Sensors: regex.icontains, regex.iextract, strings.icontains. Reference lists: $free_email_providers, $org_domains, $recipient_domains, $recipient_emails, $sender_domains, $sender_emails.

Indicators matched (8)

FieldMatchValue
sender.email.domain.domainequalsmail.hellosign.com
regex.icontainsregex<th class="action-item--action[^\>]+\>\s*[^\<]*\((?P<sender_email>[^\)]+)\).*?</th>
regex.iextractregex<th class="action-item--action[^\>]+\>\s*[^\<]*\((?P<sender_email>[^\"]+@(?P<sender_domain>[^\"]+))\).*?</th>
headers.hops[].fields[].nameequalsX-Mailgun-Variables
strings.icontainssubstringon_behalf_of_email
regex.iextractregex\"on_behalf_of_email": \"(?P<sender_email>[^\"]+@(?P<sender_domain>[^\"]+))\",
regex.icontainsregex<a href="mailto:[^\?]+\?[^\"]+\"[^\>]+\>(?:<img[^\>]+\>)?\s*Reply to sender<\/a>
regex.iextractregex<a href="mailto:(?P<sender_email>[^\?]+@(?P<sender_domain>[^\?]+))\?[^\"]+\"[^\>]+\>(?:<img[^\>]+\>)?\s*Reply to sender<\/a>