Detection rules › Sublime MQL

VIP impersonation with w2 request with reply-to mismatch

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

This rule detects emails attempting to impersonate a VIP requesting a W-2 with a reply-to mismatch.

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))
  or any(regex.extract(sender.display_name, '^(?<first>\S+)\s+(?<second>\S+)$'),
         any($org_vips,
             strings.contains(.display_name, ..named_groups["first"])
             and strings.contains(.display_name, ..named_groups["second"])
         )
  )
)
and not (
  sender.email.domain.domain in $org_domains
  and coalesce(headers.auth_summary.dmarc.pass, false)
)

// W-2 Language with a request
and (
  strings.contains(strings.replace_confusables(subject.base), 'W-2')
  or strings.icontains(subject.base, 'w2')
  or strings.icontains(subject.base, 'wage')
  or strings.icontains(subject.base, 'tax form')
  or strings.icontains(subject.base, 'irs')
)
and strings.contains(body.current_thread.text, 'W-2')
and any(ml.nlu_classifier(body.current_thread.text).entities,
        .name == "request"
)

// different reply-to address
and length(headers.reply_to) > 0
and sender.email.email not in map(headers.reply_to, .email.email)

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

Detection logic

Scope: inbound message.

This rule detects emails attempting to impersonate a VIP requesting a W-2 with a reply-to mismatch.

  1. inbound message
  2. any of:
    • any of $org_vips where:
      • strings.contains(sender.display_name)
    • any of regex.extract(sender.display_name) where:
      • any of $org_vips where all hold:
        • strings.contains(.display_name)
        • strings.contains(.display_name)
  3. not:
    • all of:
      • sender.email.domain.domain in $org_domains
      • coalesce(headers.auth_summary.dmarc.pass)
  4. any of:
    • strings.replace_confusables(subject.base) contains 'W-2'
    • subject.base contains 'w2'
    • subject.base contains 'wage'
    • subject.base contains 'tax form'
    • subject.base contains 'irs'
  5. body.current_thread.text contains 'W-2'
  6. any of ml.nlu_classifier(body.current_thread.text).entities where:
    • .name is 'request'
  7. length(headers.reply_to) > 0
  8. sender.email.email not in map(headers.reply_to, .email.email)
  9. not:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • coalesce(headers.auth_summary.dmarc.pass)

Inspects: body.current_thread.text, headers.auth_summary.dmarc.pass, headers.reply_to, headers.reply_to[].email.email, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.email, subject.base, type.inbound. Sensors: ml.nlu_classifier, regex.extract, strings.contains, strings.icontains, strings.replace_confusables. Reference lists: $high_trust_sender_root_domains, $org_domains, $org_vips.

Indicators matched (7)

FieldMatchValue
regex.extractregex^(?<first>\S+)\s+(?<second>\S+)$
strings.containssubstringW-2
strings.icontainssubstringw2
strings.icontainssubstringwage
strings.icontainssubstringtax form
strings.icontainssubstringirs
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsrequest