Detection rules › Sublime MQL

VIP impersonation with invoicing request

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

This rule detects emails attempting to impersonate a VIP, it leverages NLU to determine if there is invoicing verbiage in the current thread, and requires request language.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesImpersonation: VIP

Event coverage

Rule body MQL

type.inbound
and any($org_vips, strings.contains(sender.display_name, .display_name))
and (
  (
    sender.email.domain.domain in $org_domains
    // X-headers indicate external sender
    and headers.x_authenticated_sender.email != sender.email.email
    and headers.x_authenticated_domain.domain not in $org_domains
  )
  or sender.email.domain.domain not in $org_domains
)

// Invoice Language with a request
and (
  any(ml.nlu_classifier(body.current_thread.text).tags,
      .name == "invoice"
      and .confidence in ("medium", "high")
      and any(ml.nlu_classifier(body.current_thread.text).entities,
              .name == "request"
      )
  )
)

// and the reply to email address has never been contacted  
and any(headers.reply_to, .email.email not in $recipient_emails)

// 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.

This rule detects emails attempting to impersonate a VIP, it leverages NLU to determine if there is invoicing verbiage in the current thread, and requires request language.

  1. inbound message
  2. any of $org_vips where:
    • strings.contains(sender.display_name)
  3. any of:
    • all of:
      • sender.email.domain.domain in $org_domains
      • headers.x_authenticated_sender.email is not sender.email.email
      • headers.x_authenticated_domain.domain not in $org_domains
    • sender.email.domain.domain not in $org_domains
  4. any of ml.nlu_classifier(body.current_thread.text).tags where all hold:
    • .name is 'invoice'
    • .confidence in ('medium', 'high')
    • any of ml.nlu_classifier(body.current_thread.text).entities where:
      • .name is 'request'
  5. any of headers.reply_to where:
    • .email.email not in $recipient_emails
  6. 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: body.current_thread.text, headers.auth_summary.dmarc.pass, headers.reply_to, headers.reply_to[].email.email, headers.x_authenticated_domain.domain, headers.x_authenticated_sender.email, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: ml.nlu_classifier, strings.contains. Reference lists: $high_trust_sender_root_domains, $org_domains, $org_vips, $recipient_emails.

Indicators matched (4)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).tags[].nameequalsinvoice
ml.nlu_classifier(body.current_thread.text).tags[].confidencemembermedium
ml.nlu_classifier(body.current_thread.text).tags[].confidencememberhigh
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsrequest