Detection rules › Sublime MQL

Credential phishing content and link (untrusted sender)

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

Message contains credential theft language and a link to a credential phishing page from an unknown sender. We use Link Analysis in aggressive mode to increase our chances of scanning.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering

Event coverage

Rule body MQL

type.inbound
and (
  any(ml.nlu_classifier(body.current_thread.text).intents,
      .name == "cred_theft" and .confidence in ("medium", "high")
  )
  // embedded in an image attachment
  // note: don't use message_screenshot() for now
  // because it's not limited to current_thread and may FP
  or any(attachments,
         .file_type in $file_types_images
         and any(file.explode(.),
                 any(ml.nlu_classifier(.scan.ocr.raw).intents,
                     .name == "cred_theft" and .confidence in ("medium", "high")
                 )
         )
  )
)
and any(body.links,
        .href_url.domain.root_domain not in ("outlook.com")
        and .href_url.domain.domain != "play.google.com"
        and ml.link_analysis(., mode="aggressive").effective_url.domain.domain != "play.google.com"
        and ml.link_analysis(., mode="aggressive").credphish.disposition == "phishing"
        and (
          ml.link_analysis(., mode="aggressive").credphish.confidence in (
            "medium",
            "high"
          )
          or ml.link_analysis(., mode="aggressive").credphish.contains_captcha
        )
        and not .href_url.domain.root_domain == "c3reservations.com"
)
and (
  (
    profile.by_sender_email().prevalence in ("new", "outlier")
    and not profile.by_sender_email().solicited
  )
  or (
    profile.by_sender_email().any_messages_malicious_or_spam
    and not profile.by_sender_email().any_messages_benign
  )
  // or there are no recipients
  or length(recipients.to) == 0
  // or the recipients are all invalid 
  or all(recipients.to, .email.domain.valid == false)

  // or the sender exhibits a "self sender" pattern
  or (
    length(recipients.to) == 1
    and recipients.to[0].email.email == sender.email.email
  )
)

// negate docusign 'via' messages
and not (
  any(headers.hops,
      any(.fields,
          .name == "X-Api-Host" and strings.ends_with(.value, "docusign.net")
      )
  )
  and strings.contains(sender.display_name, "via")
)

// negate docusign originated emails
and not any(headers.hops,
            regex.imatch(.received.server.raw, ".+.docusign.(net|com)")
)

// negate highly trusted sender domains unless they fail DMARC authentication
and (
  (
    sender.email.domain.root_domain in $high_trust_sender_root_domains
    and not headers.auth_summary.dmarc.pass
  )
  or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)

Detection logic

Scope: inbound message.

Message contains credential theft language and a link to a credential phishing page from an unknown sender. We use Link Analysis in aggressive mode to increase our chances of scanning.

  1. inbound message
  2. any of:
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'cred_theft'
      • .confidence in ('medium', 'high')
    • any of attachments where all hold:
      • .file_type in $file_types_images
      • any of file.explode(.) where:
        • any of ml.nlu_classifier(.scan.ocr.raw).intents where all hold:
          • .name is 'cred_theft'
          • .confidence in ('medium', 'high')
  3. any of body.links where all hold:
    • .href_url.domain.root_domain not in ('outlook.com')
    • .href_url.domain.domain is not 'play.google.com'
    • ml.link_analysis(.).effective_url.domain.domain is not 'play.google.com'
    • ml.link_analysis(.).credphish.disposition is 'phishing'
    • any of:
      • ml.link_analysis(.).credphish.confidence in ('medium', 'high')
      • ml.link_analysis(.).credphish.contains_captcha
    • not:
      • .href_url.domain.root_domain is 'c3reservations.com'
  4. any of:
    • all of:
      • profile.by_sender_email().prevalence in ('new', 'outlier')
      • not:
        • profile.by_sender_email().solicited
    • all of:
      • profile.by_sender_email().any_messages_malicious_or_spam
      • not:
        • profile.by_sender_email().any_messages_benign
    • length(recipients.to) is 0
    • all of recipients.to where:
      • .email.domain.valid is False
    • all of:
      • length(recipients.to) is 1
      • recipients.to[0].email.email is sender.email.email
  5. not:
    • all of:
      • any of headers.hops where:
        • any of .fields where all hold:
          • .name is 'X-Api-Host'
          • .value ends with 'docusign.net'
      • sender.display_name contains 'via'
  6. not:
    • any of headers.hops where:
      • .received.server.raw matches '.+.docusign.(net|com)'
  7. any of:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • not:
        • headers.auth_summary.dmarc.pass
    • sender.email.domain.root_domain not in $high_trust_sender_root_domains

Inspects: attachments[].file_type, body.current_thread.text, body.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, headers.auth_summary.dmarc.pass, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, headers.hops[].received.server.raw, recipients.to, recipients.to[0].email.email, recipients.to[].email.domain.valid, sender.display_name, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: file.explode, ml.link_analysis, ml.nlu_classifier, profile.by_sender_email, regex.imatch, strings.contains, strings.ends_with. Reference lists: $file_types_images, $high_trust_sender_root_domains.

Indicators matched (12)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).intents[].confidencemembermedium
ml.nlu_classifier(body.current_thread.text).intents[].confidencememberhigh
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].nameequalscred_theft
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidencemembermedium
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidencememberhigh
body.links[].href_url.domain.root_domainmemberoutlook.com
body.links[].href_url.domain.root_domainequalsc3reservations.com
headers.hops[].fields[].nameequalsX-Api-Host
strings.ends_withsuffixdocusign.net
strings.containssubstringvia
regex.imatchregex.+.docusign.(net|com)