Detection rules › Sublime MQL

Sublime MQL rules: impersonation

RuleSeverity
BEC: Employee impersonation with subject manipulationhigh
Benefits enrollment impersonationhigh
Brand impersonation: Adobe with suspicious language and linkhigh
Brand impersonation: ADPmedium
Brand impersonation: Amazonlow
Brand impersonation: Amazon with suspicious attachmentmedium
Brand impersonation: American Express (AMEX)low
Brand impersonation: Anthropic/Claude with newly registered domainmedium
Brand impersonation: Applehigh
Brand impersonation: Aramcomedium
Brand impersonation: AuthentiSignmedium
Brand impersonation: Bank of Americahigh
Brand impersonation: Barracuda Networksmedium
Brand impersonation: Binancemedium
Brand impersonation: Blockchain.commedium
Brand impersonation: Box file sharing servicemedium
Brand impersonation: Capital Onehigh
Brand impersonation: Charles Schwabmedium
Brand impersonation: Chase Bankhigh
Brand impersonation: Chase bank with credential phishing indicatorsmedium
Brand impersonation: Coinbasehigh
Brand impersonation: Dashlanemedium
Brand impersonation: DHLlow
Brand impersonation: DigitalOceanhigh
Brand impersonation: DocuSignhigh
Brand impersonation: DoorDashmedium
Brand impersonation: Dotloopmedium
Brand impersonation: Dropboxmedium
Brand impersonation: Exoduslow
Brand impersonation: Fastwaymedium
Brand impersonation: FedExlow
Brand impersonation: FINRAmedium
Brand impersonation: Githubhigh
Brand impersonation: Google Drive fake file sharemedium
Brand impersonation: Google using Microsoft Formshigh
Brand impersonation: Google Workspace alert notificationmedium
Brand impersonation: Government / Tax Authority document luremedium
Brand impersonation: Gustomedium
Brand impersonation: LastPasshigh
Brand impersonation: Ledgerlow
Brand impersonation: LinkedInmedium
Brand impersonation: Mailgunmedium
Brand impersonation: Meta and subsidiariesmedium
Brand impersonation: Microsofthigh
Brand impersonation: Microsoft fake sign-in alertmedium
Brand impersonation: Microsoft logo in HTML with fake quarantine release notificationhigh
Brand impersonation: Microsoft quarantine release notification in bodyhigh
Brand impersonation: Microsoft quarantine release notification in image attachmenthigh
Brand impersonation: Microsoft Teamshigh
Brand impersonation: Microsoft Teams invitationhigh
Brand impersonation: Microsoft with embedded logo and credential theft languagehigh
Brand impersonation: Netflixlow
Brand impersonation: Nortonlow
Brand impersonation: Office 365 mail servicemedium
Brand impersonation: Oktamedium
Brand impersonation: OpenAI with payment issueshigh
Brand impersonation: Outlookhigh
Brand Impersonation: PayPalmedium
Brand impersonation: PNCmedium
Brand impersonation: Purdue ePlanroom with suspicious linksmedium
Brand impersonation: Quickbooksmedium
Brand impersonation: QuickBooks dispute notificationhigh
Brand impersonation: Ripplelow
Brand Impersonation: ShareFilemedium
Brand impersonation: Sharepointhigh
Brand impersonation: Sharepoint fake file sharemedium
Brand impersonation: Silicon Valley Bankmedium
Brand impersonation: Social Security Administrationmedium
Brand impersonation: Spotifylow
Brand impersonation: Stellar Development Foundation (SDF)low
Brand Impersonation: Stripehigh
Brand impersonation: Sublime Securityhigh
Brand impersonation: TurboTaxlow
Brand impersonation: Twittermedium
Brand impersonation: ukr[.]netmedium
Brand impersonation: United Healthcaremedium
Brand impersonation: UPSlow
Brand impersonation: USPShigh
Brand impersonation: Vantalow
Brand impersonation: Venmomedium
Brand impersonation: Wells Fargohigh
Brand impersonation: Wisehigh
Brand impersonation: Wixmedium
Brand impersonation: Zoom (strict)medium
Display name and subject impersonation using recipient SLD (new sender)medium
Display name impersonation using recipient SLDmedium
DocuSign impersonation via CloudHQ linksmedium
DocuSign impersonation via spoofed Intuit senderhigh
Domain impersonation: Freemail reply-to local lookalike with financial requestmedium
Employee impersonation with urgent request (untrusted sender)medium
Employee impersonation: Payroll fraudhigh
Fake message thread - Untrusted sender with a mismatched freemail reply-to addressmedium
Fake shipping notification with link to free file hostinglow
Impersonation using recipient domain (untrusted sender)medium
Impersonation: Australian Federal Police with criminal case languagehigh
Impersonation: Chrome Web Store policylow
Impersonation: Employee name in subject with suspicious sendermedium
Impersonation: Employee using fabricated identity in initial contacthigh
Impersonation: Executive using numbered local parthigh
Impersonation: Human Resources with link or attachment and engaging languagemedium
Impersonation: IT Department mailbox storage alertmedium
Impersonation: Legal firm with copyright infringement noticemedium
Impersonation: Recipient organization in sender display name with credential theft imagemedium
Impersonation: Salesforce fake campaign failure notificationmedium
Impersonation: SAM/SBA federal registrationhigh
Impersonation: SharePoint reply header anomalymedium
Impersonation: Suspected supplier impersonation with suspicious contenthigh
VIP Impersonation via Google Group relay with suspicious indicatorshigh
VIP impersonation with BEC language (near match, untrusted sender)medium
VIP impersonation with invoicing requesthigh
VIP impersonation with urgent request (strict match, untrusted sender)high
VIP impersonation with w2 request with reply-to mismatchhigh
X (Twitter) impersonation with credential phishing motivesmedium

BEC: Employee impersonation with subject manipulation

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

Subject matches the display name of someone in your organization, and the body resembles a BEC attack.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesImpersonation: Employee, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • subject
  • type

Rule body

type.inbound

// attacks have been observed where the impersonation is
// in the subject, and the display name contains what a
// subject typically would contain. this is an attempt to
// bypass impersonation detections
and subject.base in~ $org_display_names
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "bec" and .confidence in ("medium", "high")
)
and (
  not profile.by_sender().solicited
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)

Detection logic

Scope: inbound message.

Subject matches the display name of someone in your organization, and the body resembles a BEC attack.

  1. inbound message
  2. subject.base in $org_display_names
  3. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name is 'bec'
    • .confidence in ('medium', 'high')
  4. any of:
    • not:
      • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign

Inspects: body.current_thread.text, subject.base, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender. Reference lists: $org_display_names.

Indicators matched (3)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).intents[].nameequalsbec
ml.nlu_classifier(body.current_thread.text).intents[].confidencemembermedium
ml.nlu_classifier(body.current_thread.text).intents[].confidencememberhigh

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    not
      profile.by_sender func_call "profile.by_sender().solicited"
  any(ml.nlu_classifier(body.current_thread.text).intents)
    and
      ml.nlu_classifier(body.current_thread.text).intents.confidence in ["high", "medium"]
      ml.nlu_classifier(body.current_thread.text).intents.name eq "bec"
  type.inbound eq "true"
   macro "subject.base in org_display_names"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Benefits enrollment impersonation

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

Detects messages about benefit enrollment periods and healthcare selections from external senders that contain urgent language or requests for action. Excludes legitimate HR communications, marketing mailers, and trusted sender domains with valid authentication.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Impersonation: Employee, Out of band pivot, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • headers.hops
  • sender.email
  • subject
  • type

Rule body

type.inbound
and sender.email.domain.domain not in $org_domains
and (
  length(body.current_thread.text) < 5000 or body.current_thread.text is null
)
and (
  regex.icontains(subject.subject,
                  '(open|benefits?) enrol{1,2}ment', // catches both enrolment and enrollment
                  'benefit(s)?.{0,10}(?:plan|choice|selection|deadline|period|summary)',
                  'hr benefits',
                  'annual enrol{1,2}ment',
                  'healthcare (choice|selection|opt.?in)',
                  '(fsa|hsa|401k) (enrol{1,2}ment|selection)',
                  'dependent (coverage|verification)',
                  '(health|dental|vision|insurance|medical) enrol{1,2}ment'
  )
  or regex.icontains(body.current_thread.text,
                     'benefit(s)? (plan|choice|selection|deadline|period)',
                     'hr benefits',
                     'annual enrol{1,2}ment',
                     'healthcare (choice|selection|opt.?in)',
                     '(fsa|hsa|401k) (enrol{1,2}ment|selection)',
                     'dependent (coverage|verification)',
                     '(health|dental|vision|insurance|medical) enrol{1,2}ment',
                     '(urgent|immediate) action required.{0,20}(benefit|enrol{1,2}ment)',
                     'coverage.{0,20}(expire|terminate)',
                     'last (day|chance).{0,20}(enrol{1,2}|select)',
                     '(login|sign.?in).{0,20}(benefit portal|hr portal)',
                     '(verify|update|confirm).{0,20}(benefit.{0,20}selection)'
  )
  or any(attachments,
         regex.icontains(.file_name,
                         'fileDoc-Review',
                         '(open|benefits?) enrol{1,2}ment',
                         'annual enrol{1,2}ment',
                         '(fsa|hsa|401k) (enrol{1,2}ment|selection)',
                         '(urgent|immediate) action required.{0,20}(benefit|enrol{1,2}ment)',
         )
  )
)
and 2 of (
  any(ml.nlu_classifier(body.current_thread.text).entities,
      .name in ("urgency", "request")
  ),
  any(ml.nlu_classifier(body.current_thread.text).intents, .name != "benign"),
  (
    (length(body.current_thread.text) < 250 and length(attachments) == 1)
    or (body.current_thread.text is null and length(attachments) == 1)
  ),
  // lure in attachment
  (
    any(attachments,
        (
          .file_type in $file_types_images
          or .file_type in ("pdf", "docx", "doc")
          or .file_extension in $file_extensions_macros
        )
        and any(filter(file.explode(.), .scan.ocr.raw is not null),
                (
                  any(ml.nlu_classifier(.scan.ocr.raw).intents,
                      .name != "benign"
                  )
                  and any(ml.nlu_classifier(.scan.ocr.raw).entities,
                          .name in ("urgency", "request")
                  )
                )
        )
    )
  )
)
// negate replies
and (length(headers.references) == 0 or headers.in_reply_to is null)

// Negate common marketing mailers
and not regex.icontains(sender.display_name,
                        'HR (?:Events|Expert|Support Center|Studies|Knowledge Cloud|News Library|Crowd|Solutions|Interests)|HR and People Operations'
)
and not (
  // Constant Contact
  any(headers.hops,
      strings.icontains(.authentication_results.spf_details.designator,
                        "constantcontact.com"
      )
  )
  or any(headers.hops,
         strings.icontains(.received_spf.designator, "constantcontact.com")
  )
  or (
    (
      any(headers.hops,
          .index == 0
          and any(.authentication_results.dkim_details,
                  .domain == "auth.ccsend.com"
          )
      )
    )
    and headers.auth_summary.dmarc.pass
  )
  or any(headers.references, strings.iends_with(., "ccsend.com"))
  // Hubspot
  or any(headers.hops,
         strings.icontains(.authentication_results.spf_details.designator,
                           "hubspotemail.net"
         )
  )
)
and sender.email.domain.root_domain not in~ (
  'medicare.gov',
  'farmers.com',
  'uhc.com',
  'blueshieldca.com',
  'corestream.com'
)
and (
  profile.by_sender().prevalence in ("new", "outlier")
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)
// 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.

Detects messages about benefit enrollment periods and healthcare selections from external senders that contain urgent language or requests for action. Excludes legitimate HR communications, marketing mailers, and trusted sender domains with valid authentication.

  1. inbound message
  2. sender.email.domain.domain not in $org_domains
  3. any of:
    • length(body.current_thread.text) < 5000
    • body.current_thread.text is missing
  4. any of:
    • subject.subject matches any of 8 patterns
      • (open|benefits?) enrol{1,2}ment
      • benefit(s)?.{0,10}(?:plan|choice|selection|deadline|period|summary)
      • hr benefits
      • annual enrol{1,2}ment
      • healthcare (choice|selection|opt.?in)
      • (fsa|hsa|401k) (enrol{1,2}ment|selection)
      • dependent (coverage|verification)
      • (health|dental|vision|insurance|medical) enrol{1,2}ment
    • body.current_thread.text matches any of 12 patterns
      • benefit(s)? (plan|choice|selection|deadline|period)
      • hr benefits
      • annual enrol{1,2}ment
      • healthcare (choice|selection|opt.?in)
      • (fsa|hsa|401k) (enrol{1,2}ment|selection)
      • dependent (coverage|verification)
      • (health|dental|vision|insurance|medical) enrol{1,2}ment
      • (urgent|immediate) action required.{0,20}(benefit|enrol{1,2}ment)
      • coverage.{0,20}(expire|terminate)
      • last (day|chance).{0,20}(enrol{1,2}|select)
      • (login|sign.?in).{0,20}(benefit portal|hr portal)
      • (verify|update|confirm).{0,20}(benefit.{0,20}selection)
    • any of attachments where:
      • .file_name matches any of 5 patterns
        • fileDoc-Review
        • (open|benefits?) enrol{1,2}ment
        • annual enrol{1,2}ment
        • (fsa|hsa|401k) (enrol{1,2}ment|selection)
        • (urgent|immediate) action required.{0,20}(benefit|enrol{1,2}ment)
  5. at least 2 of:
    • any of ml.nlu_classifier(body.current_thread.text).entities where:
      • .name in ('urgency', 'request')
    • any of ml.nlu_classifier(body.current_thread.text).intents where:
      • .name is not 'benign'
    • any of:
      • all of:
        • length(body.current_thread.text) < 250
        • length(attachments) is 1
      • all of:
        • body.current_thread.text is missing
        • length(attachments) is 1
    • any of attachments where all hold:
      • any of:
        • .file_type in $file_types_images
        • .file_type in ('pdf', 'docx', 'doc')
        • .file_extension in $file_extensions_macros
      • any of filter(...) where all hold:
        • any of ml.nlu_classifier(.scan.ocr.raw).intents where:
          • .name is not 'benign'
        • any of ml.nlu_classifier(.scan.ocr.raw).entities where:
          • .name in ('urgency', 'request')
  6. any of:
    • length(headers.references) is 0
    • headers.in_reply_to is missing
  7. not:
    • sender.display_name matches 'HR (?:Events|Expert|Support Center|Studies|Knowledge Cloud|News Library|Crowd|Solutions|Interests)|HR and People Operations'
  8. none of:
    • any of headers.hops where:
      • .authentication_results.spf_details.designator contains 'constantcontact.com'
    • any of headers.hops where:
      • .received_spf.designator contains 'constantcontact.com'
    • all of:
      • any of headers.hops where all hold:
        • .index is 0
        • any of .authentication_results.dkim_details where:
          • .domain is 'auth.ccsend.com'
      • headers.auth_summary.dmarc.pass
    • any of headers.references where:
      • . ends with 'ccsend.com'
    • any of headers.hops where:
      • .authentication_results.spf_details.designator contains 'hubspotemail.net'
  9. sender.email.domain.root_domain not in ('medicare.gov', 'farmers.com', 'uhc.com', 'blueshieldca.com', 'corestream.com')
  10. any of:
    • profile.by_sender().prevalence in ('new', 'outlier')
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  11. 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_extension, attachments[].file_name, attachments[].file_type, body.current_thread.text, headers.auth_summary.dmarc.pass, headers.hops, headers.hops[].authentication_results.dkim_details, headers.hops[].authentication_results.dkim_details[].domain, headers.hops[].authentication_results.spf_details.designator, headers.hops[].index, headers.hops[].received_spf.designator, headers.in_reply_to, headers.references, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: file.explode, ml.nlu_classifier, profile.by_sender, regex.icontains, strings.icontains, strings.iends_with. Reference lists: $file_extensions_macros, $file_types_images, $high_trust_sender_root_domains, $org_domains.

Indicators matched (22)

FieldMatchValue
regex.icontainsregex(open|benefits?) enrol{1,2}ment
regex.icontainsregexbenefit(s)?.{0,10}(?:plan|choice|selection|deadline|period|summary)
regex.icontainsregexhr benefits
regex.icontainsregexannual enrol{1,2}ment
regex.icontainsregexhealthcare (choice|selection|opt.?in)
regex.icontainsregex(fsa|hsa|401k) (enrol{1,2}ment|selection)
regex.icontainsregexdependent (coverage|verification)
regex.icontainsregex(health|dental|vision|insurance|medical) enrol{1,2}ment
regex.icontainsregexbenefit(s)? (plan|choice|selection|deadline|period)
regex.icontainsregex(urgent|immediate) action required.{0,20}(benefit|enrol{1,2}ment)
regex.icontainsregexcoverage.{0,20}(expire|terminate)
regex.icontainsregexlast (day|chance).{0,20}(enrol{1,2}|select)
10 more
regex.icontainsregex(login|sign.?in).{0,20}(benefit portal|hr portal)
regex.icontainsregex(verify|update|confirm).{0,20}(benefit.{0,20}selection)
regex.icontainsregexfileDoc-Review
ml.nlu_classifier(body.current_thread.text).entities[].namememberurgency
ml.nlu_classifier(body.current_thread.text).entities[].namememberrequest
attachments[].file_typememberpdf
attachments[].file_typememberdocx
attachments[].file_typememberdoc
ml.nlu_classifier(filter(...)[].scan.ocr.raw).entities[].namememberurgency
ml.nlu_classifier(filter(...)[].scan.ocr.raw).entities[].namememberrequest

Stages and Predicates

Stage 1: mql_rule

and
  not
    or
      and
        any(headers.hops)
          and
            any(headers.hops.authentication_results.dkim_details)
              headers.hops.authentication_results.dkim_details.domain eq "auth.ccsend.com"
            headers.hops.index eq "0"
        headers.auth_summary.dmarc.pass eq "true"
      any(headers.hops)
        headers.hops.authentication_results.spf_details.designator contains "constantcontact.com"
      any(headers.hops)
        headers.hops.authentication_results.spf_details.designator contains "hubspotemail.net"
      any(headers.hops)
        headers.hops.received_spf.designator contains "constantcontact.com"
      any(headers.references)
        headers.references ends_with "ccsend.com"
  or
    any(attachments)
      and
        any(filter(...))
          and
            any(ml.nlu_classifier(filter(...).scan.ocr.raw).entities)
              ml.nlu_classifier(filter(...).scan.ocr.raw).entities.name in ["request", "urgency"]
            any(ml.nlu_classifier(filter(...).scan.ocr.raw).intents)
              ml.nlu_classifier(filter(...).scan.ocr.raw).intents.name ne "benign"
        or
          attachments.file_type in ["doc", "docx", "pdf"]
           macro "attachments[].file_extension in file_extensions_macros"
           macro "attachments[].file_type in file_types_images"
    and
      attachments length_compare "1"
      body.current_thread.text is_null
    and
      attachments length_compare "1"
      body.current_thread.text length_compare "250"
    any(ml.nlu_classifier(body.current_thread.text).entities)
      ml.nlu_classifier(body.current_thread.text).entities.name in ["request", "urgency"]
    any(ml.nlu_classifier(body.current_thread.text).intents)
      ml.nlu_classifier(body.current_thread.text).intents.name ne "benign"
  or
    any(attachments)
      or
        attachments.file_name regex_match "(fsa|hsa|401k) (enrol{1,2}ment|selection)"
        attachments.file_name regex_match "(open|benefits?) enrol{1,2}ment"
        attachments.file_name regex_match "(urgent|immediate) action required.{0,20}(benefit|enrol{1,2}ment)"
        attachments.file_name regex_match "annual enrol{1,2}ment"
        attachments.file_name regex_match "fileDoc-Review"
    body.current_thread.text regex_match "(fsa|hsa|401k) (enrol{1,2}ment|selection)"
    body.current_thread.text regex_match "(health|dental|vision|insurance|medical) enrol{1,2}ment"
    body.current_thread.text regex_match "(login|sign.?in).{0,20}(benefit portal|hr portal)"
    body.current_thread.text regex_match "(urgent|immediate) action required.{0,20}(benefit|enrol{1,2}ment)"
    body.current_thread.text regex_match "(verify|update|confirm).{0,20}(benefit.{0,20}selection)"
    body.current_thread.text regex_match "annual enrol{1,2}ment"
    body.current_thread.text regex_match "benefit(s)? (plan|choice|selection|deadline|period)"
    body.current_thread.text regex_match "coverage.{0,20}(expire|terminate)"
    body.current_thread.text regex_match "dependent (coverage|verification)"
    body.current_thread.text regex_match "healthcare (choice|selection|opt.?in)"
    body.current_thread.text regex_match "hr benefits"
    body.current_thread.text regex_match "last (day|chance).{0,20}(enrol{1,2}|select)"
    subject.subject regex_match "(fsa|hsa|401k) (enrol{1,2}ment|selection)"
    subject.subject regex_match "(health|dental|vision|insurance|medical) enrol{1,2}ment"
    subject.subject regex_match "(open|benefits?) enrol{1,2}ment"
    subject.subject regex_match "annual enrol{1,2}ment"
    subject.subject regex_match "benefit(s)?.{0,10}(?:plan|choice|selection|deadline|period|summary)"
    subject.subject regex_match "dependent (coverage|verification)"
    subject.subject regex_match "healthcare (choice|selection|opt.?in)"
    subject.subject regex_match "hr benefits"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    profile.by_sender func_call "profile.by_sender().prevalence in (new, outlier)"
  or
    body.current_thread.text is_null
    body.current_thread.text length_compare "5000"
  or
    headers.in_reply_to is_null
    headers.references length_compare "0"
  not
    sender.display_name regex_match "HR (?:Events|Expert|Support Center|Studies|Knowledge Cloud|News Library|Crowd|Solutions|Interests)|HR and People Operations"
  not
    sender.email.domain.root_domain in ["blueshieldca.com", "corestream.com", "farmers.com", "medicare.gov", "uhc.com"]
  type.inbound eq "true"
   macro "sender.email.domain.domain not in org_domains"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.hopsarray_any(no value, null check)excludes:headers.hops
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
headers.referencesarray_any(no value, null check)excludes:headers.references
sender.display_nameregex_matchHR (?:Events|Expert|Support Center|Studies|Knowledge Cloud|News Library|Crowd|Solutions|Interests), HR and People Operationsexcludes:sender.display_name field:"sender.display_name" value:"HR (?:Events|Expert|Support Center|Studies|Knowledge Cloud|News Library|Crowd|Solutions|Interests)" field:"sender.display_name" value:"HR and People Operations"
sender.email.domain.root_domaininblueshieldca.com, corestream.com, farmers.com, medicare.gov, uhc.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textis_null
  • (no value, null check)
field:"body.current_thread.text" kind:is_null
body.current_thread.textregex_match
  • (fsa|hsa|401k) (enrol{1,2}ment|selection)
  • (health|dental|vision|insurance|medical) enrol{1,2}ment
  • (login|sign.?in).{0,20}(benefit portal|hr portal)
  • (urgent|immediate) action required.{0,20}(benefit|enrol{1,2}ment)
  • (verify|update|confirm).{0,20}(benefit.{0,20}selection)
  • annual enrol{1,2}ment
  • benefit(s)? (plan|choice|selection|deadline|period)
  • coverage.{0,20}(expire|terminate)
  • dependent (coverage|verification)
  • healthcare (choice|selection|opt.?in)
  • hr benefits
  • last (day|chance).{0,20}(enrol{1,2}|select)
field:"body.current_thread.text" kind:regex_match
headers.in_reply_tois_null
  • (no value, null check)
field:"headers.in_reply_to" kind:is_null
subject.subjectregex_match
  • (fsa|hsa|401k) (enrol{1,2}ment|selection)
  • (health|dental|vision|insurance|medical) enrol{1,2}ment
  • (open|benefits?) enrol{1,2}ment
  • annual enrol{1,2}ment
  • benefit(s)?.{0,10}(?:plan|choice|selection|deadline|period|summary)
  • dependent (coverage|verification)
  • healthcare (choice|selection|opt.?in)
  • hr benefits
field:"subject.subject" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Adobe with suspicious language and link

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

Email contains an Adobe logo, at least one link, and suspicious link language from a new sender.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • body.links
  • headers
  • headers.auth_summary
  • headers.domains
  • sender.email
  • subject
  • type

Rule body

type.inbound
// All attachments are images or 0 attachments
and (
  (
    length(attachments) > 0
    and all(attachments, .file_type in $file_types_images)
  )
  or length(attachments) == 0
)
and length(filter(body.links, .href_url.scheme != 'mailto')) > 0
and (
  any(ml.logo_detect(file.message_screenshot()).brands,
      .name == "Adobe" and .confidence in ("high")
  )
  or (
    strings.icontains(body.current_thread.text, "adobe")
    and not strings.icontains(body.current_thread.text, "adobe marketplace")
    and not strings.icontains(body.current_thread.text, "adobe analytics")
    and (
      // Leverage topic analysis to pick up on themes
      (
        length(ml.nlu_classifier(body.current_thread.text).topics) == 1
        and all(ml.nlu_classifier(body.current_thread.text).topics,
                .name == "File Sharing and Cloud Services"
                and .confidence != "low"
        )
      )
      // Key phrases if topic anlayis doesn't match
      or strings.icontains(body.current_thread.text, 'review the document')
      or strings.icontains(body.current_thread.text, 'access file')
      or strings.icontains(body.current_thread.text, 'pending document')
      or any(body.links, strings.ilike(.display_text, 'review and sign'))
      or any(body.links, strings.ilike(.display_text, 'open document'))
    )
    and length(body.current_thread.text) < 2000
  )
)
and (
  (
    //
    // This rule makes use of a beta feature and is subject to change without notice
    // using the beta feature in custom rules is not suggested until it has been formally released
    //
    strings.ilike(beta.ocr(file.message_screenshot()).text,
                  "*review*",
                  "*sign*",
                  "*view*",
                  "open",
                  "*completed document*",
                  "*open agreement*",
                  "*open document*"
    )
    and not strings.ilike(beta.ocr(file.message_screenshot()).text,
                          "*view this email*",
                          "*view*browser*",
                          "*view online*",
                          "*business review*"
    )
  )
  or any(body.links,
         strings.ilike(.display_text,
                       "*review*",
                       "*sign*",
                       "*view*",
                       "open",
                       "*completed document*",
                       "*open agreement*",
                       "*open document*",
                       "*continue*"
         )
         and not strings.ilike(.display_text,
                               "*view this email*",
                               "*view*browser*",
                               "*view online*"
         )
  )
)
// Negate replies & forwards
and (
  (
    (length(headers.references) > 0 or headers.in_reply_to is null)
    and not (
      (
        strings.istarts_with(subject.subject, "RE:")
        or strings.istarts_with(subject.subject, "RES:")
        or strings.istarts_with(subject.subject, "R:")
        or strings.istarts_with(subject.subject, "ODG:")
        or strings.istarts_with(subject.subject, "答复:")
        or strings.istarts_with(subject.subject, "AW:")
        or strings.istarts_with(subject.subject, "TR:")
        or strings.istarts_with(subject.subject, "FWD:")
        or regex.imatch(subject.subject,
                        '^\[?/{0,2}(EXT|EXTERNAL)\]?/{0,2}[: ]\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*'
        )
      )
    )
  )
  or length(headers.references) == 0
)
// Negate certain common topics
and not any(ml.nlu_classifier(body.current_thread.text).topics,
            .name in (
              "Advertising and Promotions",
              "Events and Webinars",
              "Professional and Career Development",
              "Newsletters and Digests"
            )
            and .confidence != "low"
)
and (
  (
    headers.auth_summary.spf.pass
    and headers.auth_summary.dmarc.pass
    and (
      not profile.by_sender().solicited
      or profile.by_sender().any_messages_malicious_or_spam
      or profile.by_sender_email().days_since.last_contact > 14
    )
    and not profile.by_sender().any_messages_benign
    // Negate affiliates, sub-products & legitimate domains
    and not sender.email.domain.root_domain in (
      "adobe-events.com",
      "frame.io",
      "nudgesecurity.io",
      "adobesignsandbox.com",
      "magento.com",
      "workfront.com"
    )
    // Continued
    and not any(headers.domains, .root_domain == "zohomail.com")
    and not strings.iends_with(headers.message_id, 'omniture.com>')
  )
  or not headers.auth_summary.spf.pass
  or headers.auth_summary.spf.pass is null
  or not headers.auth_summary.dmarc.pass
  or headers.auth_summary.dmarc.pass is null
)
// 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.

Email contains an Adobe logo, at least one link, and suspicious link language from a new sender.

  1. inbound message
  2. any of:
    • all of:
      • length(attachments) > 0
      • all of attachments where:
        • .file_type in $file_types_images
    • length(attachments) is 0
  3. length(filter(body.links, .href_url.scheme != 'mailto')) > 0
  4. any of:
    • any of ml.logo_detect(file.message_screenshot()).brands where all hold:
      • .name is 'Adobe'
      • .confidence in ('high')
    • all of:
      • body.current_thread.text contains 'adobe'
      • not:
        • body.current_thread.text contains 'adobe marketplace'
      • not:
        • body.current_thread.text contains 'adobe analytics'
      • any of:
        • all of:
          • length(ml.nlu_classifier(body.current_thread.text).topics) is 1
          • all of ml.nlu_classifier(body.current_thread.text).topics where all hold:
            • .name is 'File Sharing and Cloud Services'
            • .confidence is not 'low'
        • body.current_thread.text contains 'review the document'
        • body.current_thread.text contains 'access file'
        • body.current_thread.text contains 'pending document'
        • any of body.links where:
          • .display_text matches 'review and sign'
        • any of body.links where:
          • .display_text matches 'open document'
      • length(body.current_thread.text) < 2000
  5. any of:
    • all of:
      • beta.ocr(file.message_screenshot()).text matches any of 7 patterns
        • *review*
        • *sign*
        • *view*
        • open
        • *completed document*
        • *open agreement*
        • *open document*
      • not:
        • beta.ocr(file.message_screenshot()).text matches any of 4 patterns
          • *view this email*
          • *view*browser*
          • *view online*
          • *business review*
    • any of body.links where all hold:
      • .display_text matches any of 8 patterns
        • *review*
        • *sign*
        • *view*
        • open
        • *completed document*
        • *open agreement*
        • *open document*
        • *continue*
      • not:
        • .display_text matches any of 3 patterns
          • *view this email*
          • *view*browser*
          • *view online*
  6. any of:
    • all of:
      • any of:
        • length(headers.references) > 0
        • headers.in_reply_to is missing
      • none of:
        • subject.subject starts with 'RE:'
        • subject.subject starts with 'RES:'
        • subject.subject starts with 'R:'
        • subject.subject starts with 'ODG:'
        • subject.subject starts with '答复:'
        • subject.subject starts with 'AW:'
        • subject.subject starts with 'TR:'
        • subject.subject starts with 'FWD:'
        • subject.subject matches '^\\[?/{0,2}(EXT|EXTERNAL)\\]?/{0,2}[: ]\\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*'
    • length(headers.references) is 0
  7. not:
    • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
      • .name in ('Advertising and Promotions', 'Events and Webinars', 'Professional and Career Development', 'Newsletters and Digests')
      • .confidence is not 'low'
  8. any of:
    • all of:
      • headers.auth_summary.spf.pass
      • headers.auth_summary.dmarc.pass
      • any of:
        • not:
          • profile.by_sender().solicited
        • profile.by_sender().any_messages_malicious_or_spam
        • profile.by_sender_email().days_since.last_contact > 14
      • not:
        • profile.by_sender().any_messages_benign
      • not:
        • sender.email.domain.root_domain in ('adobe-events.com', 'frame.io', 'nudgesecurity.io', 'adobesignsandbox.com', 'magento.com', 'workfront.com')
      • not:
        • any of headers.domains where:
          • .root_domain is 'zohomail.com'
      • not:
        • headers.message_id ends with 'omniture.com>'
    • not:
      • headers.auth_summary.spf.pass
    • headers.auth_summary.spf.pass is missing
    • not:
      • headers.auth_summary.dmarc.pass
    • headers.auth_summary.dmarc.pass is missing
  9. 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[].display_text, body.links[].href_url.scheme, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.domains, headers.domains[].root_domain, headers.in_reply_to, headers.message_id, headers.references, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: beta.ocr, file.message_screenshot, ml.logo_detect, ml.nlu_classifier, profile.by_sender, profile.by_sender_email, regex.imatch, strings.icontains, strings.iends_with, strings.ilike, strings.istarts_with. Reference lists: $file_types_images, $high_trust_sender_root_domains.

Indicators matched (17)

FieldMatchValue
ml.logo_detect(file.message_screenshot()).brands[].nameequalsAdobe
ml.logo_detect(file.message_screenshot()).brands[].confidencememberhigh
strings.icontainssubstringadobe
ml.nlu_classifier(body.current_thread.text).topics[].nameequalsFile Sharing and Cloud Services
strings.icontainssubstringreview the document
strings.icontainssubstringaccess file
strings.icontainssubstringpending document
strings.ilikesubstringreview and sign
strings.ilikesubstringopen document
strings.ilikesubstring*review*
strings.ilikesubstring*sign*
strings.ilikesubstring*view*
5 more
strings.ilikesubstringopen
strings.ilikesubstring*completed document*
strings.ilikesubstring*open agreement*
strings.ilikesubstring*open document*
strings.ilikesubstring*continue*

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(body.links)
      and
        not
          or
            body.links.display_text match "view online"
            body.links.display_text match "view this email"
            body.links.display_text wildcard "*view*browser*"
        or
          body.links.display_text eq "open"
          body.links.display_text match "completed document"
          body.links.display_text match "continue"
          body.links.display_text match "open agreement"
          body.links.display_text match "open document"
          body.links.display_text match "review"
          body.links.display_text match "sign"
          body.links.display_text match "view"
    and
      not
        or
          beta.ocr(file.message_screenshot()).text match "business review"
          beta.ocr(file.message_screenshot()).text match "view online"
          beta.ocr(file.message_screenshot()).text match "view this email"
          beta.ocr(file.message_screenshot()).text wildcard "*view*browser*"
      or
        beta.ocr(file.message_screenshot()).text eq "open"
        beta.ocr(file.message_screenshot()).text match "completed document"
        beta.ocr(file.message_screenshot()).text match "open agreement"
        beta.ocr(file.message_screenshot()).text match "open document"
        beta.ocr(file.message_screenshot()).text match "review"
        beta.ocr(file.message_screenshot()).text match "sign"
        beta.ocr(file.message_screenshot()).text match "view"
  or
    and
      or
        any(body.links)
          body.links.display_text eq "open document"
        any(body.links)
          body.links.display_text eq "review and sign"
        and
          ml.nlu_classifier(body.current_thread.text).topics length_compare "1"
           macro "all(ml.nlu_classifier(body.current_thread.text).topics)"
        body.current_thread.text contains "access file"
        body.current_thread.text contains "pending document"
        body.current_thread.text contains "review the document"
      not
        body.current_thread.text contains "adobe analytics"
      not
        body.current_thread.text contains "adobe marketplace"
      body.current_thread.text contains "adobe"
      body.current_thread.text length_compare "2000"
    any(ml.logo_detect(file.message_screenshot()).brands)
      and
        ml.logo_detect(file.message_screenshot()).brands.confidence eq "high"
        ml.logo_detect(file.message_screenshot()).brands.name eq "Adobe"
  or
    and
      not
        any(headers.domains)
          headers.domains.root_domain eq "zohomail.com"
      or
        not
          profile.by_sender func_call "profile.by_sender().solicited"
        profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
        profile.by_sender_email func_call "profile.by_sender_email().days_since.last_contact > 14"
      not
        headers.message_id ends_with "omniture.com>"
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      not
        sender.email.domain.root_domain in ["adobe-events.com", "adobesignsandbox.com", "frame.io", "magento.com", "nudgesecurity.io", "workfront.com"]
      headers.auth_summary.dmarc.pass eq "true"
      headers.auth_summary.spf.pass eq "true"
    not
      headers.auth_summary.dmarc.pass eq "true"
    not
      headers.auth_summary.spf.pass eq "true"
    headers.auth_summary.dmarc.pass is_null
    headers.auth_summary.spf.pass is_null
  or
    and
      not
        or
          subject.subject regex_match "^\\[?/{0,2}(EXT|EXTERNAL)\\]?/{0,2}[: ]\\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*"
          subject.subject starts_with "AW:"
          subject.subject starts_with "FWD:"
          subject.subject starts_with "ODG:"
          subject.subject starts_with "R:"
          subject.subject starts_with "RE:"
          subject.subject starts_with "RES:"
          subject.subject starts_with "TR:"
          subject.subject starts_with "答复:"
      or
        headers.in_reply_to is_null
        headers.references length_compare "0"
    headers.references length_compare "0"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    any(ml.nlu_classifier(body.current_thread.text).topics)
      and
        ml.nlu_classifier(body.current_thread.text).topics.confidence ne "low"
        ml.nlu_classifier(body.current_thread.text).topics.name in ["Advertising and Promotions", "Events and Webinars", "Newsletters and Digests", "Professional and Career Development"]
  or
    and
      attachments length_compare "0"
       macro "all(attachments)"
    attachments length_compare "0"
  filter(body.links, .href_url.scheme != 'mailto') length_compare "0"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
ml.nlu_classifier(body.current_thread.text).topicsarray_any(no value, null check)excludes:ml.nlu_classifier(body.current_thread.text).topics

Indicators

These rows show field, operator, and value matches.

Brand impersonation: ADP

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

Impersonation of the payroll provider ADP. Most commonly seen around US tax season (Q1)

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • sender.email
  • type

Rule body

type.inbound
and sender.display_name in~ (
  'RS-Plan-Admin@adp.com',
  'ADP',
  'SecurityServices_NoReply@adp.com'
)
and sender.email.domain.root_domain not in~ (
  'adp.com',
  'adpsurveys.com',
  'adp.com.br'
)
and sender.email.email not in $recipient_emails

Detection logic

Scope: inbound message.

Impersonation of the payroll provider ADP. Most commonly seen around US tax season (Q1)

  1. inbound message
  2. sender.display_name in ('RS-Plan-Admin@adp.com', 'ADP', 'SecurityServices_NoReply@adp.com')
  3. sender.email.domain.root_domain not in ('adp.com', 'adpsurveys.com', 'adp.com.br')
  4. sender.email.email not in $recipient_emails

Inspects: sender.display_name, sender.email.domain.root_domain, sender.email.email, type.inbound. Reference lists: $recipient_emails.

Indicators matched (3)

FieldMatchValue
sender.display_namememberRS-Plan-Admin@adp.com
sender.display_namememberADP
sender.display_namememberSecurityServices_NoReply@adp.com

Stages and Predicates

Stage 1: mql_rule

and
  not
    sender.email.domain.root_domain in ["adp.com", "adp.com.br", "adpsurveys.com"]
  sender.display_name in ["ADP", "RS-Plan-Admin@adp.com", "SecurityServices_NoReply@adp.com"]
  type.inbound eq "true"
   macro "sender.email.email not in recipient_emails"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
sender.display_namein
  • ADP
  • RS-Plan-Admin@adp.com
  • SecurityServices_NoReply@adp.com
field:"sender.display_name" kind:in
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Amazon

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

Impersonation of Amazon. These are most commonly fake shipping notifications. Amazon is the #2 most-impersonated brand (as of Q2 2020)

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • headers.hops
  • sender.email
  • subject
  • type

Rule body

type.inbound
and not any(headers.hops,
            any(.fields,
                .name == 'X-Amazon-Mail-Relay-Type' and .value == "notification"
            )
)
and (
  regex.icontains(sender.display_name,
                  '\b[aaa𝝰aa𝑎𝗮𝕒𝖆𝓪𝚊𝞪аɑα𝔞𝒂𝘢𝛂⍺𝒶𝙖𝜶𝛼𝐚𝖺]maz[o0]n\s?(pay|marketplace|\.com)|ᵃ⤻ᶻ'
  )
  or strings.ilevenshtein(sender.display_name, 'amazon.com') <= 1
  or strings.ilevenshtein(sender.display_name, 'amazon pay') <= 1
  or strings.ilevenshtein(sender.display_name, 'amazon marketplace') <= 1
  or strings.ilevenshtein(sender.display_name, 'amazon customer support') <= 1
  or regex.icontains(sender.display_name,
                     "prime (?:subscription|notification|support)"
  )
  or regex.imatch(sender.display_name,
                  '^(?:amazon\s)?prime (?:deals?|store)$',
                  'amazon'
  )
  or strings.ilike(subject.subject, "*prime membership*")
  // prime subscription id ##
  or (
    strings.icontains(subject.base, "prime")
    and regex.icontains(body.current_thread.text, 'subscription\s+id\s?.\s\w+')
  )
  or (
    strings.ilevenshtein(sender.display_name, 'amazon') <= 1
    and sender.email.domain.root_domain in $free_email_providers
  )
  or (
    any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft" and .confidence == "high"
    )
    and any(ml.nlu_classifier(body.current_thread.text).topics,
            .name in (
              "Security and Authentication",
              "Secure Message",
              "Reminders and Notifications",
              "Order Confirmations",
              "Customer Service and Support"
            )
    )
    and strings.icontains(body.current_thread.text, "amazon")
  )
)
// negate listservs
and not (
  any(headers.hops, any(.fields, .name == "List-Unsubscribe"))
  and strings.contains(sender.display_name, "via")
)
and sender.email.domain.root_domain not in~ (
  'amazon.com',
  'amazon.com.au',
  'amazon.de',
  'amazon.es',
  'amazon.fr',
  'amazon.it',
  'amazon.in',
  'amazon.lu',
  'amazon.nl',
  'amazonsellerservices.com',
  'amazon.ae',
  'amazon.sa',
  'amazon.com.sg',
  'amazon.co.uk',
  'amazon.co.jp',
  'amazon.com.mx',
  'amazon.com.br',
  'amazon.com.tr',
  'amazon.cn',
  'amazon.ca',
  'amazon.sg',
  'amazonaws.cn',
  'amazonpay.in',
  'amazonpay.com',
  'q4inc.com',
  'synchronybank.com',
  'opodo.com',
  'flynas.com',
  'amazonmusic.com',
  'blink.com',
  'affirm.com',
  'amazon.work',
  'amazon.jobs',
  'rocketmoney.com',
  'registrar.amazon',
  'amazonworkspaces.com',
  'awsapps.com',
  'aws.com',
  'awsevents.com',
  'amazon.se',
  'amazon.ie',
  'amazonconnect.com',
  'aws-experience.com',
  'proofpointessentials.com',
  'area1security.com',
  'marketplace.aws',
  'quicksight.aws'
)

// negate amazon.com.be explicitly, this cannot be part of the root_domain set above as it uses the PSL (Public suffix list) for parsing and com.be is owned by amazon directly.
and sender.email.domain.domain not in~ ('amazon.com.be')
and sender.email.email not in $recipient_emails
and sender.email.domain.domain not in $org_domains

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

Impersonation of Amazon. These are most commonly fake shipping notifications. Amazon is the #2 most-impersonated brand (as of Q2 2020)

  1. inbound message
  2. not:
    • any of headers.hops where:
      • any of .fields where all hold:
        • .name is 'X-Amazon-Mail-Relay-Type'
        • .value is 'notification'
  3. any of:
    • sender.display_name matches '\\b[aaa𝝰aa𝑎𝗮𝕒𝖆𝓪𝚊𝞪аɑα𝔞𝒂𝘢𝛂⍺𝒶𝙖𝜶𝛼𝐚𝖺]maz[o0]n\\s?(pay|marketplace|\\.com)|ᵃ⤻ᶻ'
    • sender.display_name is similar to 'amazon.com'
    • sender.display_name is similar to 'amazon pay'
    • sender.display_name is similar to 'amazon marketplace'
    • sender.display_name is similar to 'amazon customer support'
    • sender.display_name matches 'prime (?:subscription|notification|support)'
    • sender.display_name matches any of 2 patterns
      • ^(?:amazon\s)?prime (?:deals?|store)$
      • amazon
    • subject.subject matches '*prime membership*'
    • all of:
      • subject.base contains 'prime'
      • body.current_thread.text matches 'subscription\\s+id\\s?.\\s\\w+'
    • all of:
      • sender.display_name is similar to 'amazon'
      • sender.email.domain.root_domain in $free_email_providers
    • all of:
      • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
        • .name is 'cred_theft'
        • .confidence is 'high'
      • any of ml.nlu_classifier(body.current_thread.text).topics where:
        • .name in ('Security and Authentication', 'Secure Message', 'Reminders and Notifications', 'Order Confirmations', 'Customer Service and Support')
      • body.current_thread.text contains 'amazon'
  4. not:
    • all of:
      • any of headers.hops where:
        • any of .fields where:
          • .name is 'List-Unsubscribe'
      • sender.display_name contains 'via'
  5. sender.email.domain.root_domain not in ('amazon.com', 'amazon.com.au', 'amazon.de', 'amazon.es', 'amazon.fr', 'amazon.it', 'amazon.in', 'amazon.lu', 'amazon.nl', 'amazonsellerservices.com', 'amazon.ae', 'amazon.sa', 'amazon.com.sg', 'amazon.co.uk', 'amazon.co.jp', 'amazon.com.mx', 'amazon.com.br', 'amazon.com.tr', 'amazon.cn', 'amazon.ca', 'amazon.sg', 'amazonaws.cn', 'amazonpay.in', 'amazonpay.com', 'q4inc.com', 'synchronybank.com', 'opodo.com', 'flynas.com', 'amazonmusic.com', 'blink.com', 'affirm.com', 'amazon.work', 'amazon.jobs', 'rocketmoney.com', 'registrar.amazon', 'amazonworkspaces.com', 'awsapps.com', 'aws.com', 'awsevents.com', 'amazon.se', 'amazon.ie', 'amazonconnect.com', 'aws-experience.com', 'proofpointessentials.com', 'area1security.com', 'marketplace.aws', 'quicksight.aws')
  6. sender.email.domain.domain not in ('amazon.com.be')
  7. sender.email.email not in $recipient_emails
  8. sender.email.domain.domain not in $org_domains
  9. 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.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.email, subject.base, subject.subject, type.inbound. Sensors: ml.nlu_classifier, regex.icontains, regex.imatch, strings.contains, strings.icontains, strings.ilevenshtein, strings.ilike. Reference lists: $free_email_providers, $high_trust_sender_root_domains, $org_domains, $recipient_emails.

Indicators matched (20)

FieldMatchValue
regex.icontainsregex\b[aaa𝝰aa𝑎𝗮𝕒𝖆𝓪𝚊𝞪аɑα𝔞𝒂𝘢𝛂⍺𝒶𝙖𝜶𝛼𝐚𝖺]maz[o0]n\s?(pay|marketplace|\.com)|ᵃ⤻ᶻ
strings.ilevenshteinfuzzyamazon.com
strings.ilevenshteinfuzzyamazon pay
strings.ilevenshteinfuzzyamazon marketplace
strings.ilevenshteinfuzzyamazon customer support
regex.icontainsregexprime (?:subscription|notification|support)
regex.imatchregex^(?:amazon\s)?prime (?:deals?|store)$
regex.imatchregexamazon
strings.ilikesubstring*prime membership*
strings.icontainssubstringprime
regex.icontainsregexsubscription\s+id\s?.\s\w+
strings.ilevenshteinfuzzyamazon
8 more
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh
ml.nlu_classifier(body.current_thread.text).topics[].namememberSecurity and Authentication
ml.nlu_classifier(body.current_thread.text).topics[].namememberSecure Message
ml.nlu_classifier(body.current_thread.text).topics[].namememberReminders and Notifications
ml.nlu_classifier(body.current_thread.text).topics[].namememberOrder Confirmations
ml.nlu_classifier(body.current_thread.text).topics[].namememberCustomer Service and Support
strings.icontainssubstringamazon

Stages and Predicates

Stage 1: mql_rule

and
  not
    and
      any(headers.hops)
        any(headers.hops.fields)
          headers.hops.fields.name eq "List-Unsubscribe"
      sender.display_name contains "via"
  not
    any(headers.hops)
      any(headers.hops.fields)
        and
          headers.hops.fields[].name eq "X-Amazon-Mail-Relay-Type"
          headers.hops.fields[].value eq "notification"
  or
    and
      any(ml.nlu_classifier(body.current_thread.text).intents)
        and
          ml.nlu_classifier(body.current_thread.text).intents.confidence eq "high"
          ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
      any(ml.nlu_classifier(body.current_thread.text).topics)
        ml.nlu_classifier(body.current_thread.text).topics.name in ["Customer Service and Support", "Order Confirmations", "Reminders and Notifications", "Secure Message", "Security and Authentication"]
      body.current_thread.text contains "amazon"
    and
      body.current_thread.text regex_match "subscription\\s+id\\s?.\\s\\w+"
      subject.base contains "prime"
    and
      strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"amazon\") <= 1"
       macro "sender.email.domain.root_domain in free_email_providers"
    sender.display_name regex_match "\\b[aaa𝝰aa𝑎𝗮𝕒𝖆𝓪𝚊𝞪аɑα𝔞𝒂𝘢𝛂⍺𝒶𝙖𝜶𝛼𝐚𝖺]maz[o0]n\\s?(pay|marketplace|\\.com)|ᵃ⤻ᶻ"
    sender.display_name regex_match "^(?:amazon\\s)?prime (?:deals?|store)$"
    sender.display_name regex_match "amazon"
    sender.display_name regex_match "prime (?:subscription|notification|support)"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"amazon customer support\") <= 1"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"amazon marketplace\") <= 1"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"amazon pay\") <= 1"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"amazon.com\") <= 1"
    subject.subject match "prime membership"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    sender.email.domain.domain eq "amazon.com.be"
  not
    sender.email.domain.root_domain in ["affirm.com", "amazon.ae", "amazon.ca", "amazon.cn", "amazon.co.jp", "amazon.co.uk", "amazon.com", "amazon.com.au", "amazon.com.br", "amazon.com.mx", "amazon.com.sg", "amazon.com.tr", "amazon.de", "amazon.es", "amazon.fr", "amazon.ie", "amazon.in", "amazon.it", "amazon.jobs", "amazon.lu", "amazon.nl", "amazon.sa", "amazon.se", "amazon.sg", "amazon.work", "amazonaws.cn", "amazonconnect.com", "amazonmusic.com", "amazonpay.com", "amazonpay.in", "amazonsellerservices.com", "amazonworkspaces.com", "area1security.com", "aws-experience.com", "aws.com", "awsapps.com", "awsevents.com", "blink.com", "flynas.com", "marketplace.aws", "opodo.com", "proofpointessentials.com", "q4inc.com", "quicksight.aws", "registrar.amazon", "rocketmoney.com", "synchronybank.com"]
  type.inbound eq "true"
   macro "sender.email.domain.domain not in org_domains"
   macro "sender.email.email not in recipient_emails"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.hopsarray_any(no value, null check)excludes:headers.hops
sender.display_namecontainsviaexcludes:sender.display_name field:"sender.display_name" value:"via"
sender.email.domain.domaineqamazon.com.beexcludes:sender.email.domain.domain field:"sender.email.domain.domain" value:"amazon.com.be"
sender.email.domain.root_domaininaffirm.com, amazon.ae, amazon.ca, amazon.cn, amazon.co.jp, amazon.co.uk, amazon.com, amazon.com.au, amazon.com.br, amazon.com.mx, amazon.com.sg, amazon.com.tr, amazon.de, amazon.es, amazon.fr, amazon.ie, amazon.in, amazon.it, amazon.jobs, amazon.lu, amazon.nl, amazon.sa, amazon.se, amazon.sg, amazon.work, amazonaws.cn, amazonconnect.com, amazonmusic.com, amazonpay.com, amazonpay.in, amazonsellerservices.com, amazonworkspaces.com, area1security.com, aws-experience.com, aws.com, awsapps.com, awsevents.com, blink.com, flynas.com, marketplace.aws, opodo.com, proofpointessentials.com, q4inc.com, quicksight.aws, registrar.amazon, rocketmoney.com, synchronybank.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textcontains
  • amazon
field:"body.current_thread.text" kind:contains value:"amazon"
body.current_thread.textregex_match
  • subscription\s+id\s?.\s\w+
field:"body.current_thread.text" kind:regex_match value:"subscription\s+id\s?.\s\w+"
sender.display_nameregex_match
    • \b[aaa𝝰aa𝑎𝗮𝕒𝖆𝓪𝚊𝞪аɑα𝔞𝒂𝘢𝛂⍺𝒶𝙖𝜶𝛼𝐚𝖺]maz[o0]n\s?(pay|marketplace|.com)
    • ᵃ⤻ᶻ
  • ^(?:amazon\s)?prime (?:deals?|store)$
  • amazon
  • prime (?:subscription|notification|support)
field:"sender.display_name" kind:regex_match
subject.basecontains
  • prime
field:"subject.base" kind:contains value:"prime"
subject.subjectwildcard
  • *prime membership*
field:"subject.subject" kind:wildcard value:"*prime membership*"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Amazon with suspicious attachment

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

Impersonation of Amazon. These are most commonly fake shipping notifications. Amazon is the #2 most-impersonated brand (as of Q2 2020)

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • sender.email
  • type

Rule body

type.inbound
and (
  strings.ilike(sender.display_name, "amazon*")
  or any(attachments, strings.icontains(.file_name, "amazon"))
  or any(attachments,
         (.file_type in $file_types_images or .file_type == "pdf")
         and any(file.explode(.), strings.icontains(.scan.ocr.raw, "amazon"))
  )
)
and any(attachments,
        (.file_type in $file_types_images or .file_type == "pdf")
        and any(ml.logo_detect(.).brands,
                .name == "Amazon" and .confidence in~ ("medium", "high")
        )
        and (
          any(file.explode(.),
              any(ml.nlu_classifier(.scan.ocr.raw).intents,
                  .name != "benign" and .confidence == "high"
              )
          )
          or any(ml.nlu_classifier(body.current_thread.text).intents,
                 .name != "benign" and .confidence == "high"
          )
        )
)
and (
  not profile.by_sender().solicited
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)
and sender.email.domain.root_domain not in~ (
  'a2z.com',
  'amazon.com',
  'amazon.com.au',
  'amazon.co.uk',
  'amazon.de',
  'amazon.es',
  'amazon.fr',
  'amazon.it',
  'amazon.in',
  'amazon.lu',
  'amazon.com.au',
  'amazonsellerservices.com',
  'amazon.ae',
  'amazon.sa',
  'amazon.cn',
  'amazon.ca',
  'amazon.com.mx',
  'amazon.com.br',
  'amazon.ph',
  'amazon.sg',
  'amazon.com.tr',
  'amazonpay.in',
  'amazonpay.com',
  'synchronybank.com',
  'aws.com'
)

Detection logic

Scope: inbound message.

Impersonation of Amazon. These are most commonly fake shipping notifications. Amazon is the #2 most-impersonated brand (as of Q2 2020)

  1. inbound message
  2. any of:
    • sender.display_name matches 'amazon*'
    • any of attachments where:
      • .file_name contains 'amazon'
    • any of attachments where all hold:
      • any of:
        • .file_type in $file_types_images
        • .file_type is 'pdf'
      • any of file.explode(.) where:
        • .scan.ocr.raw contains 'amazon'
  3. any of attachments where all hold:
    • any of:
      • .file_type in $file_types_images
      • .file_type is 'pdf'
    • any of ml.logo_detect(.).brands where all hold:
      • .name is 'Amazon'
      • .confidence in ('medium', 'high')
    • any of:
      • any of file.explode(.) where:
        • any of ml.nlu_classifier(.scan.ocr.raw).intents where all hold:
          • .name is not 'benign'
          • .confidence is 'high'
      • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
        • .name is not 'benign'
        • .confidence is 'high'
  4. any of:
    • not:
      • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  5. sender.email.domain.root_domain not in ('a2z.com', 'amazon.com', 'amazon.com.au', 'amazon.co.uk', 'amazon.de', 'amazon.es', 'amazon.fr', 'amazon.it', 'amazon.in', 'amazon.lu', 'amazon.com.au', 'amazonsellerservices.com', 'amazon.ae', 'amazon.sa', 'amazon.cn', 'amazon.ca', 'amazon.com.mx', 'amazon.com.br', 'amazon.ph', 'amazon.sg', 'amazon.com.tr', 'amazonpay.in', 'amazonpay.com', 'synchronybank.com', 'aws.com')

Inspects: attachments[].file_name, attachments[].file_type, body.current_thread.text, sender.display_name, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, ml.logo_detect, ml.nlu_classifier, profile.by_sender, strings.icontains, strings.ilike. Reference lists: $file_types_images.

Indicators matched (8)

FieldMatchValue
strings.ilikesubstringamazon*
strings.icontainssubstringamazon
attachments[].file_typeequalspdf
ml.logo_detect(attachments[]).brands[].nameequalsAmazon
ml.logo_detect(attachments[]).brands[].confidencemembermedium
ml.logo_detect(attachments[]).brands[].confidencememberhigh
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidenceequalshigh
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh

Stages and Predicates

Stage 1: mql_rule

and
  any(attachments)
    and
      or
        any(file.explode(attachments))
          any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).intents)
            and
              ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidence eq "high"
              ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].name ne "benign"
        any(ml.nlu_classifier(body.current_thread.text).intents)
          and
            ml.nlu_classifier(body.current_thread.text).intents.confidence eq "high"
            ml.nlu_classifier(body.current_thread.text).intents.name ne "benign"
      any(ml.logo_detect(attachments).brands)
        and
          ml.logo_detect(attachments[]).brands[].confidence in ["high", "medium"]
          ml.logo_detect(attachments[]).brands[].name eq "Amazon"
      or
        attachments.file_type eq "pdf"
         macro "attachments[].file_type in file_types_images"
  or
    any(attachments)
      and
        or
          attachments.file_type eq "pdf"
           macro "attachments[].file_type in file_types_images"
        any(file.explode(attachments))
          file.explode(attachments).scan.ocr.raw contains "amazon"
    any(attachments)
      attachments.file_name contains "amazon"
    sender.display_name starts_with "amazon"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    not
      profile.by_sender func_call "profile.by_sender().solicited"
  not
    sender.email.domain.root_domain in ["a2z.com", "amazon.ae", "amazon.ca", "amazon.cn", "amazon.co.uk", "amazon.com", "amazon.com.au", "amazon.com.br", "amazon.com.mx", "amazon.com.tr", "amazon.de", "amazon.es", "amazon.fr", "amazon.in", "amazon.it", "amazon.lu", "amazon.ph", "amazon.sa", "amazon.sg", "amazonpay.com", "amazonpay.in", "amazonsellerservices.com", "aws.com", "synchronybank.com"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domainina2z.com, amazon.ae, amazon.ca, amazon.cn, amazon.co.uk, amazon.com, amazon.com.au, amazon.com.br, amazon.com.mx, amazon.com.tr, amazon.de, amazon.es, amazon.fr, amazon.in, amazon.it, amazon.lu, amazon.ph, amazon.sa, amazon.sg, amazonpay.com, amazonpay.in, amazonsellerservices.com, aws.com, synchronybank.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: American Express (AMEX)

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

Impersonation of the credit card provider American Express.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  regex.icontains(strings.replace_confusables(sender.display_name),
                  'american ?express'
  )
  or strings.ilike(sender.display_name, "*amer?can expres*")
  or strings.ilevenshtein(sender.display_name, 'american express') <= 2
  or strings.icontains(body.current_thread.text,
                       'american express customer service'
  )
  or strings.ilike(sender.email.domain.domain, '*americanexpress*')
)
and sender.email.domain.root_domain not in (
  'aexp.com',
  'americanexpress.ae',
  'americanexpress.com',
  'americanexpress.co.uk',
  'americanexpress.com.bh',
  'aexpfeedback.com',
  'amexnetwork.com',
  'accountonline.com',
  'transunion.com',
  'amexgiftcard.com',
  'amexgbt.com',
  'herrickstravelamex.com',
  'citi.com',
  'secure.com',
  'nectar.com',
  'accentinfomedia.com',
  'egencia.com'
)
and sender.email.domain.domain not in (
  'accountprotection.microsoft.com',
  'amex.membershipmail.net'
)
and not profile.by_sender().solicited

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

Impersonation of the credit card provider American Express.

  1. inbound message
  2. any of:
    • strings.replace_confusables(sender.display_name) matches 'american ?express'
    • sender.display_name matches '*amer?can expres*'
    • sender.display_name is similar to 'american express'
    • body.current_thread.text contains 'american express customer service'
    • sender.email.domain.domain matches '*americanexpress*'
  3. sender.email.domain.root_domain not in ('aexp.com', 'americanexpress.ae', 'americanexpress.com', 'americanexpress.co.uk', 'americanexpress.com.bh', 'aexpfeedback.com', 'amexnetwork.com', 'accountonline.com', 'transunion.com', 'amexgiftcard.com', 'amexgbt.com', 'herrickstravelamex.com', 'citi.com', 'secure.com', 'nectar.com', 'accentinfomedia.com', 'egencia.com')
  4. sender.email.domain.domain not in ('accountprotection.microsoft.com', 'amex.membershipmail.net')
  5. not:
    • profile.by_sender().solicited
  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, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender, regex.icontains, strings.icontains, strings.ilevenshtein, strings.ilike, strings.replace_confusables. Reference lists: $high_trust_sender_root_domains.

Indicators matched (5)

FieldMatchValue
regex.icontainsregexamerican ?express
strings.ilikesubstring*amer?can expres*
strings.ilevenshteinfuzzyamerican express
strings.icontainssubstringamerican express customer service
strings.ilikesubstring*americanexpress*

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    body.current_thread.text contains "american express customer service"
    sender.display_name match "amer?can expres"
    sender.email.domain.domain match "americanexpress"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"american express\") <= 2"
    strings.replace_confusables(sender.display_name) regex_match "american ?express"
  not
    profile.by_sender func_call "profile.by_sender().solicited"
  not
    sender.email.domain.domain in ["accountprotection.microsoft.com", "amex.membershipmail.net"]
  not
    sender.email.domain.root_domain in ["accentinfomedia.com", "accountonline.com", "aexp.com", "aexpfeedback.com", "americanexpress.ae", "americanexpress.co.uk", "americanexpress.com", "americanexpress.com.bh", "amexgbt.com", "amexgiftcard.com", "amexnetwork.com", "citi.com", "egencia.com", "herrickstravelamex.com", "nectar.com", "secure.com", "transunion.com"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.domaininaccountprotection.microsoft.com, amex.membershipmail.netexcludes:sender.email.domain.domain field:"sender.email.domain.domain" value:"accountprotection.microsoft.com" field:"sender.email.domain.domain" value:"amex.membershipmail.net"
sender.email.domain.root_domaininaccentinfomedia.com, accountonline.com, aexp.com, aexpfeedback.com, americanexpress.ae, americanexpress.co.uk, americanexpress.com, americanexpress.com.bh, amexgbt.com, amexgiftcard.com, amexnetwork.com, citi.com, egencia.com, herrickstravelamex.com, nectar.com, secure.com, transunion.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Anthropic/Claude with newly registered domain

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

Detects messages impersonating Anthropic or Claude using sender display names of 'Anthropic' or 'Claude' from domains not affiliated with the legitimate brands. The rule flags messages where the sending domain, reply-to domain, or return-path domain is newly registered (under 90 days old).

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Spam
Tactics and techniquesLookalike domain, Social engineering, Spoofing

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and regex.icontains(sender.display_name, '(?:claude|anthropic)')
// sender display name with claude, anthropic - created less than 90 days
and network.whois(sender.email.domain).days_old <= 90

// common theme for suspicious claude, anthropic
and 2 of (
  strings.icontains(body.current_thread.text, "ad account"),
  strings.icontains(body.current_thread.text, "claude ads"),
  strings.icontains(body.current_thread.text, "trial access"),
  strings.icontains(body.current_thread.text, "subscription"),
  strings.icontains(body.current_thread.text, "workspace"),
  strings.icontains(body.current_thread.text, 'ads team'),
  strings.icontains(body.current_thread.text, 'google ads'),
  regex.icontains(body.current_thread.text, "connect.{0,30}account"),
  regex.icontains(body.current_thread.text, '\banthropic\s+(?:team|pbc)\b'),
  2 of (
    strings.icontains(body.current_thread.text, '548 Market Street'),
    strings.icontains(body.current_thread.text, 'San Francisco'),
    strings.icontains(body.current_thread.text, 'CA 94104')
  ),
  any(ml.nlu_classifier(body.current_thread.text).entities,
      .name == "sender"
      and strings.icontains(.text, "Claude", "Anthropic")
      and strings.iends_with(.text, "Team")
  )
)

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

Detects messages impersonating Anthropic or Claude using sender display names of 'Anthropic' or 'Claude' from domains not affiliated with the legitimate brands. The rule flags messages where the sending domain, reply-to domain, or return-path domain is newly registered (under 90 days old).

  1. inbound message
  2. sender.display_name matches '(?:claude|anthropic)'
  3. network.whois(sender.email.domain).days_old ≤ 90
  4. at least 2 of:
    • body.current_thread.text contains 'ad account'
    • body.current_thread.text contains 'claude ads'
    • body.current_thread.text contains 'trial access'
    • body.current_thread.text contains 'subscription'
    • body.current_thread.text contains 'workspace'
    • body.current_thread.text contains 'ads team'
    • body.current_thread.text contains 'google ads'
    • body.current_thread.text matches 'connect.{0,30}account'
    • body.current_thread.text matches '\\banthropic\\s+(?:team|pbc)\\b'
    • at least 2 of:
      • body.current_thread.text contains '548 Market Street'
      • body.current_thread.text contains 'San Francisco'
      • body.current_thread.text contains 'CA 94104'
    • any of ml.nlu_classifier(body.current_thread.text).entities where all hold:
      • .name is 'sender'
      • .text contains any of 2 patterns
        • Claude
        • Anthropic
      • .text ends with 'Team'
  5. 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, sender.display_name, sender.email.domain, sender.email.domain.root_domain, type.inbound. Sensors: ml.nlu_classifier, network.whois, regex.icontains, strings.icontains, strings.iends_with. Reference lists: $high_trust_sender_root_domains.

Indicators matched (17)

FieldMatchValue
regex.icontainsregex(?:claude|anthropic)
strings.icontainssubstringad account
strings.icontainssubstringclaude ads
strings.icontainssubstringtrial access
strings.icontainssubstringsubscription
strings.icontainssubstringworkspace
strings.icontainssubstringads team
strings.icontainssubstringgoogle ads
regex.icontainsregexconnect.{0,30}account
regex.icontainsregex\banthropic\s+(?:team|pbc)\b
strings.icontainssubstring548 Market Street
strings.icontainssubstringSan Francisco
5 more
strings.icontainssubstringCA 94104
ml.nlu_classifier(body.current_thread.text).entities[].nameequalssender
strings.icontainssubstringClaude
strings.icontainssubstringAnthropic
strings.iends_withsuffixTeam

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(ml.nlu_classifier(body.current_thread.text).entities)
      and
        or
          ml.nlu_classifier(body.current_thread.text).entities.text contains "Anthropic"
          ml.nlu_classifier(body.current_thread.text).entities.text contains "Claude"
        ml.nlu_classifier(body.current_thread.text).entities.name eq "sender"
        ml.nlu_classifier(body.current_thread.text).entities.text ends_with "Team"
    body.current_thread.text contains "548 Market Street"
    body.current_thread.text contains "CA 94104"
    body.current_thread.text contains "San Francisco"
    body.current_thread.text contains "ad account"
    body.current_thread.text contains "ads team"
    body.current_thread.text contains "claude ads"
    body.current_thread.text contains "google ads"
    body.current_thread.text contains "subscription"
    body.current_thread.text contains "trial access"
    body.current_thread.text contains "workspace"
    body.current_thread.text regex_match "\\banthropic\\s+(?:team|pbc)\\b"
    body.current_thread.text regex_match "connect.{0,30}account"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
  network.whois func_call "network.whois(sender.email.domain).days_old <= 90"
  sender.display_name regex_match "(?:claude|anthropic)"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textcontains
  • 548 Market Street
  • CA 94104
  • San Francisco
  • ad account
  • ads team
  • claude ads
  • google ads
  • subscription
  • trial access
  • workspace
field:"body.current_thread.text" kind:contains
body.current_thread.textregex_match
  • \banthropic\s+(?:team|pbc)\b
  • connect.{0,30}account
field:"body.current_thread.text" kind:regex_match
sender.display_nameregex_match
  • (?:claude|anthropic)
field:"sender.display_name" kind:regex_match value:"(?:claude|anthropic)"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Apple

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

Impersonation of Apple.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • sender.email
  • type

Rule body

type.inbound
and (
  sender.display_name =~ 'apple developer'
  or strings.ilevenshtein(sender.display_name, 'apple developer') <= 2
)
and sender.email.domain.root_domain !~ 'apple.com'
and sender.email.email not in $recipient_emails

Detection logic

Scope: inbound message.

Impersonation of Apple.

  1. inbound message
  2. any of:
    • sender.display_name is 'apple developer'
    • sender.display_name is similar to 'apple developer'
  3. sender.email.domain.root_domain is not 'apple.com'
  4. sender.email.email not in $recipient_emails

Inspects: sender.display_name, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: strings.ilevenshtein. Reference lists: $recipient_emails.

Indicators matched (2)

FieldMatchValue
sender.display_nameequalsapple developer
strings.ilevenshteinfuzzyapple developer

Stages and Predicates

Stage 1: mql_rule

and
  or
    sender.display_name eq "apple developer"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"apple developer\") <= 2"
  sender.email.domain.root_domain ne "apple.com"
  type.inbound eq "true"
   macro "sender.email.email not in recipient_emails"

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Aramco

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

Impersonation of the petroleum and natural gas company Saudi Aramco.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.links
  • headers
  • headers.auth_summary
  • headers.reply_to
  • sender.email
  • subject
  • type

Rule body

type.inbound
and length(filter(body.links, .href_url.domain.valid)) < 25
and (
  strings.ilike(sender.display_name, '*aramco*')
  or strings.ilevenshtein(sender.display_name, 'aramco') <= 1
  or strings.ilike(sender.email.domain.domain, '*aramco*')
  or strings.ilike(subject.subject, '*aramco*')
)
and any(ml.nlu_classifier(body.current_thread.text).entities,
        .name == "financial" or .name == "request"
)
and (
  (
    any(ml.nlu_classifier(body.current_thread.text).entities,
        strings.ilike(.text, "*aramco*")
    )
    and any(ml.nlu_classifier(body.current_thread.text).entities,
            .name == "urgency"
    )
  )
  or regex.icount(body.current_thread.text, "vendor|supplier") > 3
  or any(headers.reply_to, .email.domain.root_domain in $free_email_providers)
  or network.whois(sender.email.domain).days_old <= 90
  or any(headers.reply_to, network.whois(.email.domain).days_old < 90)
)
// Aramco domain negations
and sender.email.domain.root_domain not in~ (
  'aramco.com',
  'aramcoamericas.com',
  'aramcoventures.com',
  'aramcoworld.com',
  'aramcodigital.com',
  'aramcoeurope.com'
)
// negate emails sent by the Aston Martin Aramco F1 Team
and sender.email.domain.root_domain != "astonmartinf1.com"
and not strings.icontains(subject.subject, 'Aston Martin')
and not regex.icontains(subject.subject, 'Formula (?:One|1)', '\bF1\b')

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

Impersonation of the petroleum and natural gas company Saudi Aramco.

  1. inbound message
  2. length(filter(body.links, .href_url.domain.valid)) < 25
  3. any of:
    • sender.display_name matches '*aramco*'
    • sender.display_name is similar to 'aramco'
    • sender.email.domain.domain matches '*aramco*'
    • subject.subject matches '*aramco*'
  4. any of ml.nlu_classifier(body.current_thread.text).entities where any holds:
    • .name is 'financial'
    • .name is 'request'
  5. any of:
    • all of:
      • any of ml.nlu_classifier(body.current_thread.text).entities where:
        • .text matches '*aramco*'
      • any of ml.nlu_classifier(body.current_thread.text).entities where:
        • .name is 'urgency'
    • regex.icount(body.current_thread.text, 'vendor|supplier') > 3
    • any of headers.reply_to where:
      • .email.domain.root_domain in $free_email_providers
    • network.whois(sender.email.domain).days_old ≤ 90
    • any of headers.reply_to where:
      • network.whois(.email.domain).days_old < 90
  6. sender.email.domain.root_domain not in ('aramco.com', 'aramcoamericas.com', 'aramcoventures.com', 'aramcoworld.com', 'aramcodigital.com', 'aramcoeurope.com')
  7. sender.email.domain.root_domain is not 'astonmartinf1.com'
  8. not:
    • subject.subject contains 'Aston Martin'
  9. not:
    • subject.subject matches any of 2 patterns
      • Formula (?:One|1)
      • \bF1\b
  10. 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, body.links, body.links[].href_url.domain.valid, headers.auth_summary.dmarc.pass, headers.reply_to, headers.reply_to[].email.domain, headers.reply_to[].email.domain.root_domain, sender.display_name, sender.email.domain, sender.email.domain.domain, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: ml.nlu_classifier, network.whois, regex.icontains, regex.icount, strings.icontains, strings.ilevenshtein, strings.ilike. Reference lists: $free_email_providers, $high_trust_sender_root_domains.

Indicators matched (6)

FieldMatchValue
strings.ilikesubstring*aramco*
strings.ilevenshteinfuzzyaramco
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsfinancial
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsrequest
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsurgency
regex.icountregexvendor|supplier

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    and
      any(ml.nlu_classifier(body.current_thread.text).entities)
        ml.nlu_classifier(body.current_thread.text).entities.name eq "urgency"
      any(ml.nlu_classifier(body.current_thread.text).entities)
        ml.nlu_classifier(body.current_thread.text).entities.text match "aramco"
    any(headers.reply_to)
      network.whois func_call "network.whois(headers.reply_to[].email.domain).days_old < 90"
    any(headers.reply_to)
       macro "headers.reply_to[].email.domain.root_domain in free_email_providers"
    network.whois func_call "network.whois(sender.email.domain).days_old <= 90"
    regex.icount func_call "regex.icount(body.current_thread.text, \"vendor|supplier\") > 3"
  any(ml.nlu_classifier(body.current_thread.text).entities)
    or
      ml.nlu_classifier(body.current_thread.text).entities.name eq "financial"
      ml.nlu_classifier(body.current_thread.text).entities.name eq "request"
  not
    or
      subject.subject regex_match "Formula (?:One|1)"
      subject.subject regex_match "\\bF1\\b"
  or
    sender.display_name match "aramco"
    sender.email.domain.domain match "aramco"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"aramco\") <= 1"
    subject.subject match "aramco"
  not
    sender.email.domain.root_domain in ["aramco.com", "aramcoamericas.com", "aramcodigital.com", "aramcoeurope.com", "aramcoventures.com", "aramcoworld.com"]
  not
    subject.subject contains "Aston Martin"
  filter(body.links, .href_url.domain.valid) length_compare "25"
  sender.email.domain.root_domain ne "astonmartinf1.com"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
subject.subjectregex_matchFormula (?:One|1)excludes:subject.subject field:"subject.subject" value:"Formula (?:One|1)"
subject.subjectregex_match\bF1\bexcludes:subject.subject field:"subject.subject" value:"\bF1\b"
sender.email.domain.root_domaininaramco.com, aramcoamericas.com, aramcodigital.com, aramcoeurope.com, aramcoventures.com, aramcoworld.comexcludes:sender.email.domain.root_domain
subject.subjectcontainsAston Martinexcludes:subject.subject field:"subject.subject" value:"Aston Martin"

Indicators

These rows show field, operator, and value matches.

Brand impersonation: AuthentiSign

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

Detects messages impersonating AuthentiSign through display name, domain, subject, or body content that either originate from non-AuthentiSign or spoofed domains.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, BEC/Fraud
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and strings.icontains(body.current_thread.text, "authentisign")
and (
  regex.icontains(body.current_thread.text, 'signing (?:name|party)')
  or strings.ilike(sender.display_name, '*authentisign*')
  or strings.ilevenshtein(sender.display_name, 'authentisign') <= 1
  or strings.ilike(sender.email.domain.domain, '*authentisign*')
)
and (
  sender.email.domain.root_domain != "authentisign.com"
  or (
    sender.email.domain.root_domain == "authentisign.com"
    and not (headers.auth_summary.spf.pass or headers.auth_summary.dmarc.pass)
  )
)

Detection logic

Scope: inbound message.

Detects messages impersonating AuthentiSign through display name, domain, subject, or body content that either originate from non-AuthentiSign or spoofed domains.

  1. inbound message
  2. body.current_thread.text contains 'authentisign'
  3. any of:
    • body.current_thread.text matches 'signing (?:name|party)'
    • sender.display_name matches '*authentisign*'
    • sender.display_name is similar to 'authentisign'
    • sender.email.domain.domain matches '*authentisign*'
  4. any of:
    • sender.email.domain.root_domain is not 'authentisign.com'
    • all of:
      • sender.email.domain.root_domain is 'authentisign.com'
      • none of:
        • headers.auth_summary.spf.pass
        • headers.auth_summary.dmarc.pass

Inspects: body.current_thread.text, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: regex.icontains, strings.icontains, strings.ilevenshtein, strings.ilike.

Indicators matched (5)

FieldMatchValue
strings.icontainssubstringauthentisign
regex.icontainsregexsigning (?:name|party)
strings.ilikesubstring*authentisign*
strings.ilevenshteinfuzzyauthentisign
sender.email.domain.root_domainequalsauthentisign.com

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        or
          headers.auth_summary.dmarc.pass eq "true"
          headers.auth_summary.spf.pass eq "true"
      sender.email.domain.root_domain eq "authentisign.com"
    sender.email.domain.root_domain ne "authentisign.com"
  or
    body.current_thread.text regex_match "signing (?:name|party)"
    sender.display_name match "authentisign"
    sender.email.domain.domain match "authentisign"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"authentisign\") <= 1"
  body.current_thread.text contains "authentisign"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Bank of America

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

Impersonation of Bank of America, usually for credential theft.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.auth_summary
  • recipients
  • recipients.to[0]
  • sender.email
  • type

Rule body

type.inbound
and (
  sender.display_name =~ 'bank of america'
  or strings.ilevenshtein(sender.display_name, 'bank of america') <= 2
  or strings.ilike(sender.email.domain.domain, '*bankofamerica*')
)
and sender.email.domain.root_domain not in~ (
  'bankofamerica.com',
  'transunion.com',
  'bofa.com',
  'bofamerchantservices.com'
)
and (
  sender.email.email not in $recipient_emails
  or (
    length(recipients.to) == 1
    and sender.email.email == recipients.to[0].email.email
  )
)

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

Impersonation of Bank of America, usually for credential theft.

  1. inbound message
  2. any of:
    • sender.display_name is 'bank of america'
    • sender.display_name is similar to 'bank of america'
    • sender.email.domain.domain matches '*bankofamerica*'
  3. sender.email.domain.root_domain not in ('bankofamerica.com', 'transunion.com', 'bofa.com', 'bofamerchantservices.com')
  4. any of:
    • sender.email.email not in $recipient_emails
    • all of:
      • length(recipients.to) is 1
      • sender.email.email is recipients.to[0].email.email
  5. 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: headers.auth_summary.dmarc.pass, recipients.to, recipients.to[0].email.email, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: strings.ilevenshtein, strings.ilike. Reference lists: $high_trust_sender_root_domains, $recipient_emails.

Indicators matched (3)

FieldMatchValue
sender.display_nameequalsbank of america
strings.ilevenshteinfuzzybank of america
strings.ilikesubstring*bankofamerica*

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    and
      recipients.to length_compare "1"
      sender.email.email cross_field_compare "recipients.to[0].email.email"
     macro "sender.email.email not in recipient_emails"
  or
    sender.display_name eq "bank of america"
    sender.email.domain.domain match "bankofamerica"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"bank of america\") <= 2"
  not
    sender.email.domain.root_domain in ["bankofamerica.com", "bofa.com", "bofamerchantservices.com", "transunion.com"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaininbankofamerica.com, bofa.com, bofamerchantservices.com, transunion.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Barracuda Networks

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

Impersonation of Barracuda Networks, an IT security company.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • sender.email
  • type

Rule body

type.inbound
and (
  strings.ilike(sender.display_name, '*barracuda*')
  or strings.ilevenshtein(sender.display_name, 'barracuda') <= 1
  or strings.ilike(sender.email.domain.domain, '*barracuda*')
)
and sender.email.domain.root_domain not in (
  'barracuda.com',
  'barracudamsp.com',
  'barracudanetworks.com',
  'netsuite.com',

  // hockey team
  'sharkssports.net',
  'sjbarracuda.com',

  // Barracuda Barcatering
  'barracuda-barcatering.de',

  // Barracuda Events Team
  'worldspan.co.uk',

  // Barracudas Day Camps
  'barracudas.co.uk',

  // BarracudaShoes
  'barracudashoes.it'
)
and (
  profile.by_sender().prevalence in ("new", "outlier")
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)

Detection logic

Scope: inbound message.

Impersonation of Barracuda Networks, an IT security company.

  1. inbound message
  2. any of:
    • sender.display_name matches '*barracuda*'
    • sender.display_name is similar to 'barracuda'
    • sender.email.domain.domain matches '*barracuda*'
  3. sender.email.domain.root_domain not in ('barracuda.com', 'barracudamsp.com', 'barracudanetworks.com', 'netsuite.com', 'sharkssports.net', 'sjbarracuda.com', 'barracuda-barcatering.de', 'worldspan.co.uk', 'barracudas.co.uk', 'barracudashoes.it')
  4. any of:
    • profile.by_sender().prevalence in ('new', 'outlier')
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign

Inspects: sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender, strings.ilevenshtein, strings.ilike.

Indicators matched (2)

FieldMatchValue
strings.ilikesubstring*barracuda*
strings.ilevenshteinfuzzybarracuda

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    profile.by_sender func_call "profile.by_sender().prevalence in (new, outlier)"
  or
    sender.display_name match "barracuda"
    sender.email.domain.domain match "barracuda"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"barracuda\") <= 1"
  not
    sender.email.domain.root_domain in ["barracuda-barcatering.de", "barracuda.com", "barracudamsp.com", "barracudanetworks.com", "barracudas.co.uk", "barracudashoes.it", "netsuite.com", "sharkssports.net", "sjbarracuda.com", "worldspan.co.uk"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaininbarracuda-barcatering.de, barracuda.com, barracudamsp.com, barracudanetworks.com, barracudas.co.uk, barracudashoes.it, netsuite.com, sharkssports.net, sjbarracuda.com, worldspan.co.ukexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Binance

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

Impersonation of the cryptocurrency exchange Binance.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  strings.ilike(sender.display_name, '*binance*')
  or strings.ilevenshtein(sender.display_name, 'binance') <= 1
  or strings.ilike(sender.email.domain.domain, '*binance*')
  or strings.ilike(subject.subject, '*binance*')
)
and sender.email.domain.root_domain not in~ (
  'binance.com',
  'binance.us',
  'trustwallet.com',
  'binance.charity'
)
and any(ml.nlu_classifier(body.current_thread.text).entities,
        .text == "Binance"
)
and any(ml.nlu_classifier(body.current_thread.text).entities,
        .name == "financial"
)
and (
  any(ml.nlu_classifier(body.current_thread.text).entities, .name == "urgency")
  or any(ml.nlu_classifier(body.current_thread.text).entities,
         .name == "request"
  )
)
and (
  any(ml.nlu_classifier(body.current_thread.text).entities,
      .text in~ ("withdrawal", "deposit")
  )
  or any(ml.nlu_classifier(body.current_thread.text).intents, .name != "benign")
)
and (
  // if this comes from a free email provider,
  // flag if org has never sent an email to sender's email before
  (
    sender.email.domain.root_domain in $free_email_providers
    and sender.email.email not in $recipient_emails
  )
  // if this comes from a custom domain,
  // flag if org has never sent an email to sender's domain before
  or (
    sender.email.domain.root_domain not in $free_email_providers
    and sender.email.domain.domain not in $recipient_domains
  )
)

Detection logic

Scope: inbound message.

Impersonation of the cryptocurrency exchange Binance.

  1. inbound message
  2. any of:
    • sender.display_name matches '*binance*'
    • sender.display_name is similar to 'binance'
    • sender.email.domain.domain matches '*binance*'
    • subject.subject matches '*binance*'
  3. sender.email.domain.root_domain not in ('binance.com', 'binance.us', 'trustwallet.com', 'binance.charity')
  4. any of ml.nlu_classifier(body.current_thread.text).entities where:
    • .text is 'Binance'
  5. any of ml.nlu_classifier(body.current_thread.text).entities where:
    • .name is 'financial'
  6. any of:
    • any of ml.nlu_classifier(body.current_thread.text).entities where:
      • .name is 'urgency'
    • any of ml.nlu_classifier(body.current_thread.text).entities where:
      • .name is 'request'
  7. any of:
    • any of ml.nlu_classifier(body.current_thread.text).entities where:
      • .text in ('withdrawal', 'deposit')
    • any of ml.nlu_classifier(body.current_thread.text).intents where:
      • .name is not 'benign'
  8. any of:
    • all of:
      • sender.email.domain.root_domain in $free_email_providers
      • sender.email.email not in $recipient_emails
    • all of:
      • sender.email.domain.root_domain not in $free_email_providers
      • sender.email.domain.domain not in $recipient_domains

Inspects: body.current_thread.text, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.email, subject.subject, type.inbound. Sensors: ml.nlu_classifier, strings.ilevenshtein, strings.ilike. Reference lists: $free_email_providers, $recipient_domains, $recipient_emails.

Indicators matched (8)

FieldMatchValue
strings.ilikesubstring*binance*
strings.ilevenshteinfuzzybinance
ml.nlu_classifier(body.current_thread.text).entities[].textequalsBinance
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsfinancial
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsurgency
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsrequest
ml.nlu_classifier(body.current_thread.text).entities[].textmemberwithdrawal
ml.nlu_classifier(body.current_thread.text).entities[].textmemberdeposit

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(ml.nlu_classifier(body.current_thread.text).entities)
      ml.nlu_classifier(body.current_thread.text).entities.name eq "request"
    any(ml.nlu_classifier(body.current_thread.text).entities)
      ml.nlu_classifier(body.current_thread.text).entities.name eq "urgency"
  or
    any(ml.nlu_classifier(body.current_thread.text).entities)
      ml.nlu_classifier(body.current_thread.text).entities.text in ["deposit", "withdrawal"]
    any(ml.nlu_classifier(body.current_thread.text).intents)
      ml.nlu_classifier(body.current_thread.text).intents.name ne "benign"
  or
    and
       macro "sender.email.domain.domain not in recipient_domains"
       macro "sender.email.domain.root_domain not in free_email_providers"
    and
       macro "sender.email.domain.root_domain in free_email_providers"
       macro "sender.email.email not in recipient_emails"
  any(ml.nlu_classifier(body.current_thread.text).entities)
    ml.nlu_classifier(body.current_thread.text).entities.name eq "financial"
  any(ml.nlu_classifier(body.current_thread.text).entities)
    ml.nlu_classifier(body.current_thread.text).entities.text eq "Binance"
  or
    sender.display_name match "binance"
    sender.email.domain.domain match "binance"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"binance\") <= 1"
    subject.subject match "binance"
  not
    sender.email.domain.root_domain in ["binance.charity", "binance.com", "binance.us", "trustwallet.com"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaininbinance.charity, binance.com, binance.us, trustwallet.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Blockchain.com

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

Impersonation of Blockchain.com, usually for credential theft.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.links
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  regex.imatch(sender.display_name, '\bblockchain\b')
  or strings.ilevenshtein(sender.display_name, 'blockchain') <= 1
  or strings.ilike(sender.email.domain.domain, '*blockchain.com*')
  or any(body.links,
         strings.ilevenshtein(.href_url.domain.root_domain, 'blockchain') == 1
  )
)
and not any(ml.nlu_classifier(body.current_thread.text).topics,
            .name in ("Educational and Research", "Advertising and Promotions")
            and .confidence == "high"
)
and not (
  sender.email.domain.root_domain in~ (
    'blockchain.com',
    'wxblockchain.com',
    'ai-blockchain.com',
    'envisionblockchain.com'
  )
  and coalesce(headers.auth_summary.dmarc.pass, false)
)
and not profile.by_sender_email().solicited

Detection logic

Scope: inbound message.

Impersonation of Blockchain.com, usually for credential theft.

  1. inbound message
  2. any of:
    • sender.display_name matches '\\bblockchain\\b'
    • sender.display_name is similar to 'blockchain'
    • sender.email.domain.domain matches '*blockchain.com*'
    • any of body.links where:
      • .href_url.domain.root_domain is similar to 'blockchain'
  3. not:
    • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
      • .name in ('Educational and Research', 'Advertising and Promotions')
      • .confidence is 'high'
  4. not:
    • all of:
      • sender.email.domain.root_domain in ('blockchain.com', 'wxblockchain.com', 'ai-blockchain.com', 'envisionblockchain.com')
      • coalesce(headers.auth_summary.dmarc.pass)
  5. not:
    • profile.by_sender_email().solicited

Inspects: body.current_thread.text, body.links, body.links[].href_url.domain.root_domain, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender_email, regex.imatch, strings.ilevenshtein, strings.ilike.

Indicators matched (3)

FieldMatchValue
regex.imatchregex\bblockchain\b
strings.ilevenshteinfuzzyblockchain
strings.ilikesubstring*blockchain.com*

Stages and Predicates

Stage 1: mql_rule

and
  not
    any(ml.nlu_classifier(body.current_thread.text).topics)
      and
        ml.nlu_classifier(body.current_thread.text).topics.confidence eq "high"
        ml.nlu_classifier(body.current_thread.text).topics.name in ["Advertising and Promotions", "Educational and Research"]
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
      sender.email.domain.root_domain in ["ai-blockchain.com", "blockchain.com", "envisionblockchain.com", "wxblockchain.com"]
  or
    any(body.links)
      strings.ilevenshtein func_call "strings.ilevenshtein(body.links[].href_url.domain.root_domain, \"blockchain\") == 1"
    sender.display_name regex_match "\\bblockchain\\b"
    sender.email.domain.domain match "blockchain.com"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"blockchain\") <= 1"
  not
    profile.by_sender_email func_call "profile.by_sender_email().solicited"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
ml.nlu_classifier(body.current_thread.text).topicsarray_any(no value, null check)excludes:ml.nlu_classifier(body.current_thread.text).topics
sender.email.domain.root_domaininai-blockchain.com, blockchain.com, envisionblockchain.com, wxblockchain.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Box file sharing service

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

Detects messages impersonating Box file sharing service by identifying Box logos, collaboration-related language, or Box company address information from senders not associated with the legitimate box.com domain.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • headers.domains
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  (
    any(ml.logo_detect(file.message_screenshot()).brands, .name == "Box")
    and any([body.current_thread.text, subject.subject],
            regex.icontains(.,
                            'invited you to.{0,10}(?:view|edit|work together|collaborate)',
                            'items were (?:deleted|added)'
            )
    )
  )
  // Box address from footer
  or 2 of (
    strings.icontains(body.current_thread.text, 'About Box'),
    strings.icontains(body.current_thread.text, '900 Jefferson Ave'),
    strings.icontains(body.current_thread.text, 'Redwood City, CA 94063')
  )
  or strings.icontains(body.current_thread.text,
                       "who is using SignRequest.com, an electronic signature tool"
  )
  or strings.icontains(body.current_thread.text, "sent by SignRequest BV")
)
and not (
  sender.email.domain.root_domain in (
    "box.com",
    "liftoff.io",
    "signrequest.com"
  )
  and coalesce(headers.auth_summary.dmarc.pass, false)
)
// 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)
)
// not a forward or reply
and (headers.in_reply_to is null or length(headers.references) == 0)
// negation for messages traversing box.com
// happens with custom sender domains
and not (
  any(headers.domains, .root_domain == "box.com")
  and headers.auth_summary.spf.pass
  and headers.auth_summary.dmarc.pass
)

Detection logic

Scope: inbound message.

Detects messages impersonating Box file sharing service by identifying Box logos, collaboration-related language, or Box company address information from senders not associated with the legitimate box.com domain.

  1. inbound message
  2. any of:
    • all of:
      • any of ml.logo_detect(file.message_screenshot()).brands where:
        • .name is 'Box'
      • any of [body.current_thread.text, subject.subject] where:
        • . matches any of 2 patterns
          • invited you to.{0,10}(?:view|edit|work together|collaborate)
          • items were (?:deleted|added)
    • at least 2 of:
      • body.current_thread.text contains 'About Box'
      • body.current_thread.text contains '900 Jefferson Ave'
      • body.current_thread.text contains 'Redwood City, CA 94063'
    • body.current_thread.text contains 'who is using SignRequest.com, an electronic signature tool'
    • body.current_thread.text contains 'sent by SignRequest BV'
  3. not:
    • all of:
      • sender.email.domain.root_domain in ('box.com', 'liftoff.io', 'signrequest.com')
      • coalesce(headers.auth_summary.dmarc.pass)
  4. not:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • coalesce(headers.auth_summary.dmarc.pass)
  5. any of:
    • headers.in_reply_to is missing
    • length(headers.references) is 0
  6. not:
    • all of:
      • any of headers.domains where:
        • .root_domain is 'box.com'
      • headers.auth_summary.spf.pass
      • headers.auth_summary.dmarc.pass

Inspects: body.current_thread.text, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.domains, headers.domains[].root_domain, headers.in_reply_to, headers.references, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: file.message_screenshot, ml.logo_detect, regex.icontains, strings.icontains. Reference lists: $high_trust_sender_root_domains.

Indicators matched (8)

FieldMatchValue
ml.logo_detect(file.message_screenshot()).brands[].nameequalsBox
regex.icontainsregexinvited you to.{0,10}(?:view|edit|work together|collaborate)
regex.icontainsregexitems were (?:deleted|added)
strings.icontainssubstringAbout Box
strings.icontainssubstring900 Jefferson Ave
strings.icontainssubstringRedwood City, CA 94063
strings.icontainssubstringwho is using SignRequest.com, an electronic signature tool
strings.icontainssubstringsent by SignRequest BV

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      any([body.current_thread.text, subject.subject])
        or
          [body.current_thread.text, subject.subject] regex_match "invited you to.{0,10}(?:view|edit|work together|collaborate)"
          [body.current_thread.text, subject.subject] regex_match "items were (?:deleted|added)"
      any(ml.logo_detect(file.message_screenshot()).brands)
        ml.logo_detect(file.message_screenshot()).brands.name eq "Box"
    body.current_thread.text contains "900 Jefferson Ave"
    body.current_thread.text contains "About Box"
    body.current_thread.text contains "Redwood City, CA 94063"
    body.current_thread.text contains "sent by SignRequest BV"
    body.current_thread.text contains "who is using SignRequest.com, an electronic signature tool"
  not
    and
      any(headers.domains)
        headers.domains.root_domain eq "box.com"
      headers.auth_summary.dmarc.pass eq "true"
      headers.auth_summary.spf.pass eq "true"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
      sender.email.domain.root_domain in ["box.com", "liftoff.io", "signrequest.com"]
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
  or
    headers.in_reply_to is_null
    headers.references length_compare "0"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textcontains
  • 900 Jefferson Ave
  • About Box
  • Redwood City, CA 94063
  • sent by SignRequest BV
  • who is using SignRequest.com, an electronic signature tool
field:"body.current_thread.text" kind:contains
headers.in_reply_tois_null
  • (no value, null check)
field:"headers.in_reply_to" kind:is_null
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Capital One

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

This detection rule identifies inbound messages containing Capital One branding indicators in display names, sender addresses, message content, or embedded logos, while excluding legitimate Capital One domains and authenticated communications from known trusted senders.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • body.html
  • body.links
  • headers
  • headers.auth_summary
  • headers.hops
  • sender.email
  • subject
  • type

Rule body

type.inbound
// limit evaluation of a regex heavy rule
and length(body.current_thread.text) < 2000000
and (
  any([
        strings.replace_confusables(sender.display_name),
        strings.replace_confusables(subject.subject),
        // domain parts of sender
        sender.email.local_part,
        sender.email.domain.sld
      ],
      // quick checks first
      strings.icontains(., 'Capital One')
      or strings.icontains(., 'CapitalOne')

      // slower checks next
      or regex.icontains(., 'Capital.?One')
      // levenshtein distince similar to captial one
      or strings.ilevenshtein(., 'Capital One') <= 2
  )
  or any(ml.logo_detect(file.message_screenshot()).brands,
         .name == "Capital One Bank" and .confidence != "low"
  )
)
and not (
  sender.email.domain.root_domain in (
    "capitalone.co.uk",
    "capitalone.com",
    "capitaloneshopping.com",
    "capitalonesoftware.com",
    "capitalonebooking.com",
    "capitalonetravel.com",
    "olbanking.com", // a fiserv.one domain
    "bynder.com", // Digital Assest Mgmt
    "gcs-web.com", // investor relations run by capital one
    "capitalonearena.com", // the arena
    "monumentalsports.com", // the company that owns a bunch of teams that play at the arena?
    "ticketmaster.com", // sell and advertises tickets at Capital One Arena
    "credible.com", // known loan marketplace
    "capitalonetradecredit.com" // domain associated with Capital One's trade credit platform
  )
  and headers.auth_summary.dmarc.pass
)
// and the sender is not from high trust sender root domains
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
)
// suspicious indicators here
and (
  // // password theme
  (
    strings.icontains(body.current_thread.text, "new password")
    or regex.icontains(body.current_thread.text,
                       '(?:credentials?|password)\s*(?:\w+\s+){0,3}\s*(?:compromise|reset|expir(?:ation|ed)|update|invalid|incorrect|changed|(?:mis)?match)',
                       '(?:compromise|reset|expir(?:ation|ed)|update|invalid|incorrect|changed|(?:mis)?match)\s*(?:\w+\s+){0,3}\s*(?:credentials?|password)',
                       '(?:short|weak|chang(?:e|ing)|reset)\s*(?:\w+\s+){0,3}\s*(?:credentials?|password)',
                       '(?:credentials?|password)\s*(?:\w+\s+){0,3}\s*(?:short|weak|chang(?:e|ing)|reset)',
    )
  )
  // // login failures
  or (
    strings.icontains(body.current_thread.text, "unusual number of")
    or strings.icontains(body.current_thread.text, "security breach")
    or (
      strings.icontains(body.current_thread.text, "security alert")
      // some capital one notiifcaitons include directions to
      // change notificaiton preferences to only security alerts
      and (
        strings.icount(body.current_thread.text, "security alert") > strings.icount(body.current_thread.text,
                                                                                    "sign in to your account and select Security Alerts."
        )
      )
    )
    or strings.icontains(body.current_thread.text, "account remains secure")
    or strings.icontains(body.current_thread.text, "please verify your account")
    or strings.icontains(body.current_thread.text,
                         "suspicious activity detected"
    )
    or strings.icontains(body.current_thread.text, "temporarily locked out")
    or regex.icontains(body.current_thread.text,
                       '(?:invalid|unrecognized|unauthorized|fail(?:ed|ure)?|suspicious|unusual|attempt(?:ed)?\b|tried to)\s*(?:\w+\s+){0,3}\s*(?:log(?:.?in)?|sign(?:.?in)?|account|access|activity)',
                       '(?:log(?:.?in)?|sign(?:.?in)?|account|access|activity)\s*(?:\w+\s+){0,3}\s*(?:invalid|unrecognized|fail(?:ed|ure)?|suspicious|unusual|attempt(?:ed)?\b)'
    )
  )
  // // account locked
  or (
    strings.icontains(body.current_thread.text, "been suspend")
    or strings.icontains(body.current_thread.text, "will be restored")
    or strings.icontains(body.current_thread.text, "security reasons")
    or strings.icontains(body.current_thread.text,
                         "temporarily restricted access"
    )
    or regex.icontains(body.current_thread.text,
                       'acc(?:ou)?n?t\s*(?:\w+\s+){0,3}\s*(?:authenticat(?:e|ion)|activity|\bho[li]d\b|terminat|[il1]{2}m[il1]t(?:s|ed|ation)|b?locked|de-?activat|suspen(?:ed|sion)|restrict(?:ed|ion)?|expir(?:ed?|ing)|v[il]o[li]at|verif(?:y|ication))',
                       '(?:authenticat(?:e|ion)|activity|\bho[li]d\b|terminat|[il1]{2}m[il1]t(?:s|ed|ation)|b?locked|de-?activat|suspen(?:ed|sion)|restrict(?:ed|ion)?|expir(?:ed?|ing)|v[il]o[li]at|verif(?:y|ication))\s*(?:\w+\s+){0,3}\s*acc(?:ou)?n?t\b'
    )
  )
  // // secure messages
  or (
    regex.icontains(body.current_thread.text,
                    '(?:encrypt(?:ion|ed)?|secur(?:ed?|ity)) (?:\w+\s+){0,3}\s*message'
    )
    or strings.icontains(body.current_thread.text, "document portal")
    or regex.icontains(body.current_thread.text,
                       "has been (?:encrypt|sent secure)"
    )
    or regex.icontains(body.current_thread.text,
                       'encryption (?:\w+\s+){0,3}\s*tech'
    )
  )
  // // documents to view
  or (
    // we can skip the regex if the diplay_text doesn't contain document
    // this might need to be removed if the regex is expanded
    strings.icontains(body.current_thread.text, 'document')
    and regex.icontains(body.current_thread.text,
                        'document\s*(?:\w+\s+){0,3}\s*(?:ready|posted|review|available|online)',
                        '(?:ready|posted|review|available|online)\s*(?:\w+\s+){0,3}\s*document'
    )
  )
  // // account/profile details
  or (
    strings.icontains(body.current_thread.text, "about your account")
    or strings.icontains(body.current_thread.text, "action required")
    or regex.icontains(body.current_thread.text,
                       '(update|\bedit\b|modify|revise|verif(?:y|ication)|discrepanc(?:y|ies)|mismatch(?:es)?|inconsistenc(?:y|ies)?|difference(?:s)?|anomal(?:y|ies)?|irregularit(?:y|ies)?)\s*(?:\w+\s+){0,4}\s*(?:account|ownership|detail|record|data|info(?:rmation)?)',
                       '(?:account|ownership|detail|record|data|info(?:rmation)?)\s*(?:\w+\s+){0,4}\s*(update|\bedit\b|modify|revise|verif(?:y|ication)|discrepanc(?:y|ies)|mismatch(?:es)?|inconsistenc(?:y|ies)?|difference(?:s)?|anomal(?:y|ies)?|irregularit(?:y|ies)?)'
    )
  )
  // // other calls to action that are unexpected
  or (strings.icontains(body.current_thread.text, "download the attachment"))

  // the links contain suspect wording
  or (
    0 < length(body.links) <= 50
    and any(body.links,
            (
              regex.icontains(.display_text, '(?:log|sign).?in')
              or strings.icontains(.display_text, 'confirm')
              or strings.icontains(.display_text, 'i recongize it')
              or strings.icontains(.display_text, "something\'s wrong")
              or regex.icontains(.display_text,
                                 '(?:(?:re)?view|see|read)\s*(?:\w+\s*){0,3}\s*(?:document|message|now|account)'
              )
              or regex.icontains(.display_text,
                                 'restore\s*(?:\w+\s*){0,3}\s*(?:account|access)'
              )
              or regex.icontains(.display_text,
                                 'review\s*(?:\w+\s*){0,3}\s*(?:payment)'
              )
            )
            and not regex.icontains(.display_text,
                                    'confirm\s*(?:\w+\s*){0,3}\s*this message'
            )
            and .href_url.domain.root_domain != "capitalone.com"
    )
  )
  // the message contains a disclaimer but isn't from capitalone
  or (
    regex.icontains(body.current_thread.text,
                    'To ensure delivery, add [^\@]+@[^\s]*capitalone.com to your address book.'
    )
    and sender.email.domain.root_domain != "capitalone.com"
  )
)
// negation of inbound org domains which path eamil auth
and not (
  type.inbound
  and sender.email.domain.domain in $org_domains
  and headers.auth_summary.spf.pass
  and headers.auth_summary.dmarc.pass
  and not 'fail' in~ distinct(map(headers.hops, .authentication_results.dkim))
)
and not any(beta.ml_topic(body.html.display_text).topics,
            (
              .name in (
                // lots of newsletters talk about capital one
                "Newsletters and Digests",
                // lots of recruiting mention oppurtunties at capital one, often including the logo
                "Professional and Career Development",
              )
              and .confidence == "high"
            )
            or (
              .name in (
                // Outage events are often news worthy
                "News and Current Events"
              )
              and .confidence != "low"
            )
)
// negating legit replies/forwards
// https://github.com/sublime-security/sublime-rules/blob/main/insights/authentication/org_inbound_auth_pass.yml
and not (
  (
    strings.istarts_with(subject.subject, "RE:")
    or strings.istarts_with(subject.subject, "FW:")
    or strings.istarts_with(subject.subject, "FWD:")
    or regex.imatch(subject.subject,
                    '(\[[^\]]+\]\s?){0,3}(re|fwd?|automat.*)\s?:.*'
    )
    or strings.istarts_with(subject.subject, "Réponse automatique")
  )
  and (length(headers.references) > 0 and headers.in_reply_to is not null)
)
// negate bounce backs
and not (
  strings.like(sender.email.local_part,
               "*postmaster*",
               "*mailer-daemon*",
               "*administrator*"
  )
  and any(attachments,
          .content_type in (
            "message/rfc822",
            "message/delivery-status",
            "text/calendar"
          )
  )
)

Detection logic

Scope: inbound message.

This detection rule identifies inbound messages containing Capital One branding indicators in display names, sender addresses, message content, or embedded logos, while excluding legitimate Capital One domains and authenticated communications from known trusted senders.

  1. inbound message
  2. length(body.current_thread.text) < 2000000
  3. any of:
    • any of [strings.replace_confusables(sender.display_name), strings.replace_confusables(subject.subject), sender.email.local_part, sender.email.domain.sld] where any holds:
      • . contains 'Capital One'
      • . contains 'CapitalOne'
      • . matches 'Capital.?One'
      • . is similar to 'Capital One'
    • any of ml.logo_detect(file.message_screenshot()).brands where all hold:
      • .name is 'Capital One Bank'
      • .confidence is not 'low'
  4. not:
    • all of:
      • sender.email.domain.root_domain in ('capitalone.co.uk', 'capitalone.com', 'capitaloneshopping.com', 'capitalonesoftware.com', 'capitalonebooking.com', 'capitalonetravel.com', 'olbanking.com', 'bynder.com', 'gcs-web.com', 'capitalonearena.com', 'monumentalsports.com', 'ticketmaster.com', 'credible.com', 'capitalonetradecredit.com')
      • headers.auth_summary.dmarc.pass
  5. 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
  6. any of:
    • any of:
      • body.current_thread.text contains 'new password'
      • body.current_thread.text matches any of 4 patterns
        • (?:credentials?|password)\s*(?:\w+\s+){0,3}\s*(?:compromise|reset|expir(?:ation|ed)|update|invalid|incorrect|changed|(?:mis)?match)
        • (?:compromise|reset|expir(?:ation|ed)|update|invalid|incorrect|changed|(?:mis)?match)\s*(?:\w+\s+){0,3}\s*(?:credentials?|password)
        • (?:short|weak|chang(?:e|ing)|reset)\s*(?:\w+\s+){0,3}\s*(?:credentials?|password)
        • (?:credentials?|password)\s*(?:\w+\s+){0,3}\s*(?:short|weak|chang(?:e|ing)|reset)
    • any of:
      • body.current_thread.text contains 'unusual number of'
      • body.current_thread.text contains 'security breach'
      • all of:
        • body.current_thread.text contains 'security alert'
        • strings.icount(body.current_thread.text, 'security alert') > strings.icount(body.current_thread.text, 'sign in to your account and select Security Alerts.')
      • body.current_thread.text contains 'account remains secure'
      • body.current_thread.text contains 'please verify your account'
      • body.current_thread.text contains 'suspicious activity detected'
      • body.current_thread.text contains 'temporarily locked out'
      • body.current_thread.text matches any of 2 patterns
        • (?:invalid|unrecognized|unauthorized|fail(?:ed|ure)?|suspicious|unusual|attempt(?:ed)?\b|tried to)\s*(?:\w+\s+){0,3}\s*(?:log(?:.?in)?|sign(?:.?in)?|account|access|activity)
        • (?:log(?:.?in)?|sign(?:.?in)?|account|access|activity)\s*(?:\w+\s+){0,3}\s*(?:invalid|unrecognized|fail(?:ed|ure)?|suspicious|unusual|attempt(?:ed)?\b)
    • any of:
      • body.current_thread.text contains 'been suspend'
      • body.current_thread.text contains 'will be restored'
      • body.current_thread.text contains 'security reasons'
      • body.current_thread.text contains 'temporarily restricted access'
      • body.current_thread.text matches any of 2 patterns
        • acc(?:ou)?n?t\s*(?:\w+\s+){0,3}\s*(?:authenticat(?:e|ion)|activity|\bho[li]d\b|terminat|[il1]{2}m[il1]t(?:s|ed|ation)|b?locked|de-?activat|suspen(?:ed|sion)|restrict(?:ed|ion)?|expir(?:ed?|ing)|v[il]o[li]at|verif(?:y|ication))
        • (?:authenticat(?:e|ion)|activity|\bho[li]d\b|terminat|[il1]{2}m[il1]t(?:s|ed|ation)|b?locked|de-?activat|suspen(?:ed|sion)|restrict(?:ed|ion)?|expir(?:ed?|ing)|v[il]o[li]at|verif(?:y|ication))\s*(?:\w+\s+){0,3}\s*acc(?:ou)?n?t\b
    • any of:
      • body.current_thread.text matches '(?:encrypt(?:ion|ed)?|secur(?:ed?|ity)) (?:\\w+\\s+){0,3}\\s*message'
      • body.current_thread.text contains 'document portal'
      • body.current_thread.text matches 'has been (?:encrypt|sent secure)'
      • body.current_thread.text matches 'encryption (?:\\w+\\s+){0,3}\\s*tech'
    • all of:
      • body.current_thread.text contains 'document'
      • body.current_thread.text matches any of 2 patterns
        • document\s*(?:\w+\s+){0,3}\s*(?:ready|posted|review|available|online)
        • (?:ready|posted|review|available|online)\s*(?:\w+\s+){0,3}\s*document
    • any of:
      • body.current_thread.text contains 'about your account'
      • body.current_thread.text contains 'action required'
      • body.current_thread.text matches any of 2 patterns
        • (update|\bedit\b|modify|revise|verif(?:y|ication)|discrepanc(?:y|ies)|mismatch(?:es)?|inconsistenc(?:y|ies)?|difference(?:s)?|anomal(?:y|ies)?|irregularit(?:y|ies)?)\s*(?:\w+\s+){0,4}\s*(?:account|ownership|detail|record|data|info(?:rmation)?)
        • (?:account|ownership|detail|record|data|info(?:rmation)?)\s*(?:\w+\s+){0,4}\s*(update|\bedit\b|modify|revise|verif(?:y|ication)|discrepanc(?:y|ies)|mismatch(?:es)?|inconsistenc(?:y|ies)?|difference(?:s)?|anomal(?:y|ies)?|irregularit(?:y|ies)?)
    • body.current_thread.text contains 'download the attachment'
    • all of:
      • all of:
        • length(body.links) > 0
        • length(body.links) ≤ 50
      • any of body.links where all hold:
        • any of:
          • .display_text matches '(?:log|sign).?in'
          • .display_text contains 'confirm'
          • .display_text contains 'i recongize it'
          • .display_text contains "something\\'s wrong"
          • .display_text matches '(?:(?:re)?view|see|read)\\s*(?:\\w+\\s*){0,3}\\s*(?:document|message|now|account)'
          • .display_text matches 'restore\\s*(?:\\w+\\s*){0,3}\\s*(?:account|access)'
          • .display_text matches 'review\\s*(?:\\w+\\s*){0,3}\\s*(?:payment)'
        • not:
          • .display_text matches 'confirm\\s*(?:\\w+\\s*){0,3}\\s*this message'
        • .href_url.domain.root_domain is not 'capitalone.com'
    • all of:
      • body.current_thread.text matches 'To ensure delivery, add [^\\@]+@[^\\s]*capitalone.com to your address book.'
      • sender.email.domain.root_domain is not 'capitalone.com'
  7. not:
    • all of:
      • inbound message
      • sender.email.domain.domain in $org_domains
      • headers.auth_summary.spf.pass
      • headers.auth_summary.dmarc.pass
      • not:
        • distinct(...) contains 'fail'
  8. not:
    • any of beta.ml_topic(body.html.display_text).topics where any holds:
      • all of:
        • .name in ('Newsletters and Digests', 'Professional and Career Development')
        • .confidence is 'high'
      • all of:
        • .name in ('News and Current Events')
        • .confidence is not 'low'
  9. not:
    • all of:
      • any of:
        • subject.subject starts with 'RE:'
        • subject.subject starts with 'FW:'
        • subject.subject starts with 'FWD:'
        • subject.subject matches '(\\[[^\\]]+\\]\\s?){0,3}(re|fwd?|automat.*)\\s?:.*'
        • subject.subject starts with 'Réponse automatique'
      • all of:
        • length(headers.references) > 0
        • headers.in_reply_to is set
  10. not:
    • all of:
      • sender.email.local_part matches any of 3 patterns
        • *postmaster*
        • *mailer-daemon*
        • *administrator*
      • any of attachments where:
        • .content_type in ('message/rfc822', 'message/delivery-status', 'text/calendar')

Inspects: attachments[].content_type, body.current_thread.text, body.html.display_text, body.links, body.links[].display_text, body.links[].href_url.domain.root_domain, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.hops, headers.hops[].authentication_results.dkim, headers.in_reply_to, headers.references, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.domain.sld, sender.email.local_part, subject.subject, type.inbound. Sensors: beta.ml_topic, file.message_screenshot, ml.logo_detect, regex.icontains, regex.imatch, strings.icontains, strings.icount, strings.ilevenshtein, strings.istarts_with, strings.like, strings.replace_confusables. Reference lists: $high_trust_sender_root_domains, $org_domains.

Indicators matched (46)

FieldMatchValue
strings.icontainssubstringCapital One
strings.icontainssubstringCapitalOne
regex.icontainsregexCapital.?One
strings.ilevenshteinfuzzyCapital One
ml.logo_detect(file.message_screenshot()).brands[].nameequalsCapital One Bank
strings.icontainssubstringnew password
regex.icontainsregex(?:credentials?|password)\s*(?:\w+\s+){0,3}\s*(?:compromise|reset|expir(?:ation|ed)|update|invalid|incorrect|changed|(?:mis)?match)
regex.icontainsregex(?:compromise|reset|expir(?:ation|ed)|update|invalid|incorrect|changed|(?:mis)?match)\s*(?:\w+\s+){0,3}\s*(?:credentials?|password)
regex.icontainsregex(?:short|weak|chang(?:e|ing)|reset)\s*(?:\w+\s+){0,3}\s*(?:credentials?|password)
regex.icontainsregex(?:credentials?|password)\s*(?:\w+\s+){0,3}\s*(?:short|weak|chang(?:e|ing)|reset)
strings.icontainssubstringunusual number of
strings.icontainssubstringsecurity breach
34 more
strings.icontainssubstringsecurity alert
strings.icontainssubstringaccount remains secure
strings.icontainssubstringplease verify your account
strings.icontainssubstringsuspicious activity detected
strings.icontainssubstringtemporarily locked out
regex.icontainsregex(?:invalid|unrecognized|unauthorized|fail(?:ed|ure)?|suspicious|unusual|attempt(?:ed)?\b|tried to)\s*(?:\w+\s+){0,3}\s*(?:log(?:.?in)?|sign(?:.?in)?|account|access|activity)
regex.icontainsregex(?:log(?:.?in)?|sign(?:.?in)?|account|access|activity)\s*(?:\w+\s+){0,3}\s*(?:invalid|unrecognized|fail(?:ed|ure)?|suspicious|unusual|attempt(?:ed)?\b)
strings.icontainssubstringbeen suspend
strings.icontainssubstringwill be restored
strings.icontainssubstringsecurity reasons
strings.icontainssubstringtemporarily restricted access
regex.icontainsregexacc(?:ou)?n?t\s*(?:\w+\s+){0,3}\s*(?:authenticat(?:e|ion)|activity|\bho[li]d\b|terminat|[il1]{2}m[il1]t(?:s|ed|ation)|b?locked|de-?activat|suspen(?:ed|sion)|restrict(?:ed|ion)?|expir(?:ed?|ing)|v[il]o[li]at|verif(?:y|ication))
regex.icontainsregex(?:authenticat(?:e|ion)|activity|\bho[li]d\b|terminat|[il1]{2}m[il1]t(?:s|ed|ation)|b?locked|de-?activat|suspen(?:ed|sion)|restrict(?:ed|ion)?|expir(?:ed?|ing)|v[il]o[li]at|verif(?:y|ication))\s*(?:\w+\s+){0,3}\s*acc(?:ou)?n?t\b
regex.icontainsregex(?:encrypt(?:ion|ed)?|secur(?:ed?|ity)) (?:\w+\s+){0,3}\s*message
strings.icontainssubstringdocument portal
regex.icontainsregexhas been (?:encrypt|sent secure)
regex.icontainsregexencryption (?:\w+\s+){0,3}\s*tech
strings.icontainssubstringdocument
regex.icontainsregexdocument\s*(?:\w+\s+){0,3}\s*(?:ready|posted|review|available|online)
regex.icontainsregex(?:ready|posted|review|available|online)\s*(?:\w+\s+){0,3}\s*document
strings.icontainssubstringabout your account
strings.icontainssubstringaction required
regex.icontainsregex(update|\bedit\b|modify|revise|verif(?:y|ication)|discrepanc(?:y|ies)|mismatch(?:es)?|inconsistenc(?:y|ies)?|difference(?:s)?|anomal(?:y|ies)?|irregularit(?:y|ies)?)\s*(?:\w+\s+){0,4}\s*(?:account|ownership|detail|record|data|info(?:rmation)?)
regex.icontainsregex(?:account|ownership|detail|record|data|info(?:rmation)?)\s*(?:\w+\s+){0,4}\s*(update|\bedit\b|modify|revise|verif(?:y|ication)|discrepanc(?:y|ies)|mismatch(?:es)?|inconsistenc(?:y|ies)?|difference(?:s)?|anomal(?:y|ies)?|irregularit(?:y|ies)?)
strings.icontainssubstringdownload the attachment
regex.icontainsregex(?:log|sign).?in
strings.icontainssubstringconfirm
strings.icontainssubstringi recongize it
strings.icontainssubstringsomething\'s wrong
regex.icontainsregex(?:(?:re)?view|see|read)\s*(?:\w+\s*){0,3}\s*(?:document|message|now|account)
regex.icontainsregexrestore\s*(?:\w+\s*){0,3}\s*(?:account|access)
regex.icontainsregexreview\s*(?:\w+\s*){0,3}\s*(?:payment)
regex.icontainsregexTo ensure delivery, add [^\@]+@[^\s]*capitalone.com to your address book.
distinct(map(headers.hops, .authentication_results.dkim))containsfail

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      any(body.links)
        and
          or
            body.links.display_text contains "confirm"
            body.links.display_text contains "i recongize it"
            body.links.display_text contains "something\\'s wrong"
            body.links.display_text regex_match "(?:(?:re)?view|see|read)\\s*(?:\\w+\\s*){0,3}\\s*(?:document|message|now|account)"
            body.links.display_text regex_match "(?:log|sign).?in"
            body.links.display_text regex_match "restore\\s*(?:\\w+\\s*){0,3}\\s*(?:account|access)"
            body.links.display_text regex_match "review\\s*(?:\\w+\\s*){0,3}\\s*(?:payment)"
          not
            body.links.display_text regex_match "confirm\\s*(?:\\w+\\s*){0,3}\\s*this message"
          body.links.href_url.domain.root_domain ne "capitalone.com"
      body.links length_compare "0"
      body.links length_compare "50"
    and
      or
        body.current_thread.text regex_match "(?:ready|posted|review|available|online)\\s*(?:\\w+\\s+){0,3}\\s*document"
        body.current_thread.text regex_match "document\\s*(?:\\w+\\s+){0,3}\\s*(?:ready|posted|review|available|online)"
      body.current_thread.text contains "document"
    and
      body.current_thread.text contains "security alert"
      strings.icount func_call "strings.icount(body.current_thread.text, \"security alert\") > strings.icount(body.current_thread.text, 'sign in to your account and select Security Alerts.')"
    and
      body.current_thread.text regex_match "To ensure delivery, add [^\\@]+@[^\\s]*capitalone.com to your address book."
      sender.email.domain.root_domain ne "capitalone.com"
    body.current_thread.text contains "about your account"
    body.current_thread.text contains "account remains secure"
    body.current_thread.text contains "action required"
    body.current_thread.text contains "been suspend"
    body.current_thread.text contains "document portal"
    body.current_thread.text contains "download the attachment"
    body.current_thread.text contains "new password"
    body.current_thread.text contains "please verify your account"
    body.current_thread.text contains "security breach"
    body.current_thread.text contains "security reasons"
    body.current_thread.text contains "suspicious activity detected"
    body.current_thread.text contains "temporarily locked out"
    body.current_thread.text contains "temporarily restricted access"
    body.current_thread.text contains "unusual number of"
    body.current_thread.text contains "will be restored"
    body.current_thread.text regex_match "(?:account|ownership|detail|record|data|info(?:rmation)?)\\s*(?:\\w+\\s+){0,4}\\s*(update|\\bedit\\b|modify|revise|verif(?:y|ication)|discrepanc(?:y|ies)|mismatch(?:es)?|inconsistenc(?:y|ies)?|difference(?:s)?|anomal(?:y|ies)?|irregularit(?:y|ies)?)"
    body.current_thread.text regex_match "(?:authenticat(?:e|ion)|activity|\\bho[li]d\\b|terminat|[il1]{2}m[il1]t(?:s|ed|ation)|b?locked|de-?activat|suspen(?:ed|sion)|restrict(?:ed|ion)?|expir(?:ed?|ing)|v[il]o[li]at|verif(?:y|ication))\\s*(?:\\w+\\s+){0,3}\\s*acc(?:ou)?n?t\\b"
    body.current_thread.text regex_match "(?:compromise|reset|expir(?:ation|ed)|update|invalid|incorrect|changed|(?:mis)?match)\\s*(?:\\w+\\s+){0,3}\\s*(?:credentials?|password)"
    body.current_thread.text regex_match "(?:credentials?|password)\\s*(?:\\w+\\s+){0,3}\\s*(?:compromise|reset|expir(?:ation|ed)|update|invalid|incorrect|changed|(?:mis)?match)"
    body.current_thread.text regex_match "(?:credentials?|password)\\s*(?:\\w+\\s+){0,3}\\s*(?:short|weak|chang(?:e|ing)|reset)"
    body.current_thread.text regex_match "(?:encrypt(?:ion|ed)?|secur(?:ed?|ity)) (?:\\w+\\s+){0,3}\\s*message"
    body.current_thread.text regex_match "(?:invalid|unrecognized|unauthorized|fail(?:ed|ure)?|suspicious|unusual|attempt(?:ed)?\\b|tried to)\\s*(?:\\w+\\s+){0,3}\\s*(?:log(?:.?in)?|sign(?:.?in)?|account|access|activity)"
    body.current_thread.text regex_match "(?:log(?:.?in)?|sign(?:.?in)?|account|access|activity)\\s*(?:\\w+\\s+){0,3}\\s*(?:invalid|unrecognized|fail(?:ed|ure)?|suspicious|unusual|attempt(?:ed)?\\b)"
    body.current_thread.text regex_match "(?:short|weak|chang(?:e|ing)|reset)\\s*(?:\\w+\\s+){0,3}\\s*(?:credentials?|password)"
    body.current_thread.text regex_match "(update|\\bedit\\b|modify|revise|verif(?:y|ication)|discrepanc(?:y|ies)|mismatch(?:es)?|inconsistenc(?:y|ies)?|difference(?:s)?|anomal(?:y|ies)?|irregularit(?:y|ies)?)\\s*(?:\\w+\\s+){0,4}\\s*(?:account|ownership|detail|record|data|info(?:rmation)?)"
    body.current_thread.text regex_match "acc(?:ou)?n?t\\s*(?:\\w+\\s+){0,3}\\s*(?:authenticat(?:e|ion)|activity|\\bho[li]d\\b|terminat|[il1]{2}m[il1]t(?:s|ed|ation)|b?locked|de-?activat|suspen(?:ed|sion)|restrict(?:ed|ion)?|expir(?:ed?|ing)|v[il]o[li]at|verif(?:y|ication))"
    body.current_thread.text regex_match "encryption (?:\\w+\\s+){0,3}\\s*tech"
    body.current_thread.text regex_match "has been (?:encrypt|sent secure)"
  not
    any(beta.ml_topic(body.html.display_text).topics)
      or
        and
          beta.ml_topic(body.html.display_text).topics.confidence eq "high"
          beta.ml_topic(body.html.display_text).topics.name in ["Newsletters and Digests", "Professional and Career Development"]
        and
          beta.ml_topic(body.html.display_text).topics.confidence ne "low"
          beta.ml_topic(body.html.display_text).topics.name eq "News and Current Events"
  or
    any([strings.replace_confusables(sender.display_name), strings.replace_confusables(subject.subject), sender.email.local_part, sender.email.domain.sld])
      or
        [strings.replace_confusables(sender.display_name), strings.replace_confusables(subject.subject), sender.email.local_part, sender.email.domain.sld] contains "Capital One"
        [strings.replace_confusables(sender.display_name), strings.replace_confusables(subject.subject), sender.email.local_part, sender.email.domain.sld] contains "CapitalOne"
        [strings.replace_confusables(sender.display_name), strings.replace_confusables(subject.subject), sender.email.local_part, sender.email.domain.sld] regex_match "Capital.?One"
        strings.ilevenshtein func_call "strings.ilevenshtein([strings.replace_confusables(sender.display_name), strings.replace_confusables(subject.subject), sender.email.local_part, sender.email.domain.sld][], \"Capital One\") <= 2"
    any(ml.logo_detect(file.message_screenshot()).brands)
      and
        ml.logo_detect(file.message_screenshot()).brands.confidence ne "low"
        ml.logo_detect(file.message_screenshot()).brands.name eq "Capital One Bank"
  not
    and
      any(attachments)
        attachments.content_type in ["message/delivery-status", "message/rfc822", "text/calendar"]
      or
        sender.email.local_part match "administrator"
        sender.email.local_part match "mailer-daemon"
        sender.email.local_part match "postmaster"
  not
    and
      not
        distinct(...) contains "fail"
      headers.auth_summary.dmarc.pass eq "true"
      headers.auth_summary.spf.pass eq "true"
      type.inbound eq "true"
       macro "sender.email.domain.domain in org_domains"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    and
      or
        subject.subject regex_match "(\\[[^\\]]+\\]\\s?){0,3}(re|fwd?|automat.*)\\s?:.*"
        subject.subject starts_with "FW:"
        subject.subject starts_with "FWD:"
        subject.subject starts_with "RE:"
        subject.subject starts_with "Réponse automatique"
      headers.in_reply_to is_not_null
      headers.references length_compare "0"
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.root_domain in ["bynder.com", "capitalone.co.uk", "capitalone.com", "capitalonearena.com", "capitalonebooking.com", "capitaloneshopping.com", "capitalonesoftware.com", "capitalonetradecredit.com", "capitalonetravel.com", "credible.com", "gcs-web.com", "monumentalsports.com", "olbanking.com", "ticketmaster.com"]
  body.current_thread.text length_compare "2000000"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
beta.ml_topic(body.html.display_text).topicsarray_any(no value, null check)excludes:beta.ml_topic(body.html.display_text).topics
attachmentsarray_any(no value, null check)excludes:attachments
sender.email.local_partmatchadministratorexcludes:sender.email.local_part field:"sender.email.local_part" value:"administrator"
sender.email.local_partmatchmailer-daemonexcludes:sender.email.local_part field:"sender.email.local_part" value:"mailer-daemon"
sender.email.local_partmatchpostmasterexcludes:sender.email.local_part field:"sender.email.local_part" value:"postmaster"
distinct(...)containsfailexcludes:distinct(...) field:"distinct(...)" value:"fail"
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
headers.auth_summary.spf.passeqtrueexcludes:headers.auth_summary.spf.pass field:"headers.auth_summary.spf.pass" value:"true"
type.inboundeqtrueexcludes:type.inbound field:"type.inbound" value:"true"
subject.subjectregex_match([[^]]+]\s?){0,3}(re|fwd?|automat.*)\s?:.*excludes:subject.subject field:"subject.subject" value:"([[^]]+]\s?){0,3}(re|fwd?|automat.*)\s?:.*"
subject.subjectstarts_withFW:excludes:subject.subject field:"subject.subject" value:"FW:"
subject.subjectstarts_withFWD:excludes:subject.subject field:"subject.subject" value:"FWD:"
subject.subjectstarts_withRE:excludes:subject.subject field:"subject.subject" value:"RE:"
subject.subjectstarts_withRéponse automatiqueexcludes:subject.subject field:"subject.subject" value:"Réponse automatique"
headers.in_reply_tois_not_null(no value, null check)excludes:headers.in_reply_to
headers.referenceslength_compare0excludes:headers.references field:"headers.references" value:"0"
sender.email.domain.root_domaininbynder.com, capitalone.co.uk, capitalone.com, capitalonearena.com, capitalonebooking.com, capitaloneshopping.com, capitalonesoftware.com, capitalonetradecredit.com, capitalonetravel.com, credible.com, gcs-web.com, monumentalsports.com, olbanking.com, ticketmaster.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textcontains
  • about your account
  • account remains secure
  • action required
  • been suspend
  • document
  • document portal
  • download the attachment
  • new password
  • please verify your account
  • security alert
  • security breach
  • security reasons
  • suspicious activity detected
  • temporarily locked out
  • temporarily restricted access
  • unusual number of
  • will be restored
field:"body.current_thread.text" kind:contains
body.current_thread.textregex_match
  • (?:account|ownership|detail|record|data|info(?:rmation)?)\s*(?:\w+\s+){0,4}\s*(update|\bedit\b|modify|revise|verif(?:y|ication)|discrepanc(?:y|ies)|mismatch(?:es)?|inconsistenc(?:y|ies)?|difference(?:s)?|anomal(?:y|ies)?|irregularit(?:y|ies)?)
  • (?:authenticat(?:e|ion)|activity|\bho[li]d\b|terminat|[il1]{2}m[il1]t(?:s|ed|ation)|b?locked|de-?activat|suspen(?:ed|sion)|restrict(?:ed|ion)?|expir(?:ed?|ing)|v[il]o[li]at|verif(?:y|ication))\s*(?:\w+\s+){0,3}\s*acc(?:ou)?n?t\b
  • (?:compromise|reset|expir(?:ation|ed)|update|invalid|incorrect|changed|(?:mis)?match)\s*(?:\w+\s+){0,3}\s*(?:credentials?|password)
  • (?:credentials?|password)\s*(?:\w+\s+){0,3}\s*(?:compromise|reset|expir(?:ation|ed)|update|invalid|incorrect|changed|(?:mis)?match)
  • (?:credentials?|password)\s*(?:\w+\s+){0,3}\s*(?:short|weak|chang(?:e|ing)|reset)
  • (?:encrypt(?:ion|ed)?|secur(?:ed?|ity)) (?:\w+\s+){0,3}\s*message
  • (?:invalid|unrecognized|unauthorized|fail(?:ed|ure)?|suspicious|unusual|attempt(?:ed)?\b|tried to)\s*(?:\w+\s+){0,3}\s*(?:log(?:.?in)?|sign(?:.?in)?|account|access|activity)
  • (?:log(?:.?in)?|sign(?:.?in)?|account|access|activity)\s*(?:\w+\s+){0,3}\s*(?:invalid|unrecognized|fail(?:ed|ure)?|suspicious|unusual|attempt(?:ed)?\b)
  • (?:ready|posted|review|available|online)\s*(?:\w+\s+){0,3}\s*document
  • (?:short|weak|chang(?:e|ing)|reset)\s*(?:\w+\s+){0,3}\s*(?:credentials?|password)
  • (update|\bedit\b|modify|revise|verif(?:y|ication)|discrepanc(?:y|ies)|mismatch(?:es)?|inconsistenc(?:y|ies)?|difference(?:s)?|anomal(?:y|ies)?|irregularit(?:y|ies)?)\s*(?:\w+\s+){0,4}\s*(?:account|ownership|detail|record|data|info(?:rmation)?)
  • To ensure delivery, add [^\@]+@[^\s]*capitalone.com to your address book.
  • acc(?:ou)?n?t\s*(?:\w+\s+){0,3}\s*(?:authenticat(?:e|ion)|activity|\bho[li]d\b|terminat|[il1]{2}m[il1]t(?:s|ed|ation)|b?locked|de-?activat|suspen(?:ed|sion)|restrict(?:ed|ion)?|expir(?:ed?|ing)|v[il]o[li]at|verif(?:y|ication))
  • document\s*(?:\w+\s+){0,3}\s*(?:ready|posted|review|available|online)
  • encryption (?:\w+\s+){0,3}\s*tech
  • has been (?:encrypt|sent secure)
field:"body.current_thread.text" kind:regex_match
distinct(...)contains
  • fail
field:"distinct(...)" kind:contains value:"fail"
sender.email.domain.root_domainne
  • capitalone.com
field:"sender.email.domain.root_domain" kind:ne value:"capitalone.com"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Charles Schwab

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

Impersonation of Charles Schwab & Co

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  // display name contains charles schwab
  (
    strings.ilike(strings.replace_confusables(sender.display_name),
                  '*charles schwab*'
    )
    // no spaces
    or strings.ilike(strings.replace_confusables(sender.display_name),
                     '*charlesschwab*'
    )
    // levenshtein distince similar to schwab
    or strings.ilevenshtein(strings.replace_confusables(sender.display_name),
                            'charles schwab'
    ) <= 1
    // sender domain contains schwab
    or strings.ilike(strings.replace_confusables(sender.email.domain.domain),
                     '*schwab*'
    )
  )
)

// and the sender is not in org_domains or from charles shwab domains and passes auth
and not (
  sender.email.domain.root_domain in $org_domains
  or (
    (
      sender.email.domain.root_domain in (
        "schwab.com",
        "aboutschwab.com.",
        "schwabcorrentesettlement.com", // Schawb v. Corrente, et al. Settlement domain
        "schwabmoneywise.com",
        "schwabe.com", // law firm with name
        "proxyvote.com", // sends shareholder voting information with subject of company name
        "boheme-schwabing.de", // steakhouse
        "lesschwab.com", // tire sales
        "schwab-marketing.com", // German Marketing Agency
        "schwaben.ca" // unrelated but similar domain
      )
      or sender.email.domain.domain in ("schwabebooks.ccsend.com")
    )
    and headers.auth_summary.dmarc.pass
  )
)
// and the sender is not from high trust sender root domains
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
)
and not profile.by_sender().solicited

Detection logic

Scope: inbound message.

Impersonation of Charles Schwab & Co

  1. inbound message
  2. any of:
    • strings.replace_confusables(sender.display_name) matches '*charles schwab*'
    • strings.replace_confusables(sender.display_name) matches '*charlesschwab*'
    • strings.replace_confusables(sender.display_name) is similar to 'charles schwab'
    • strings.replace_confusables(sender.email.domain.domain) matches '*schwab*'
  3. none of:
    • sender.email.domain.root_domain in $org_domains
    • all of:
      • any of:
        • sender.email.domain.root_domain in ('schwab.com', 'aboutschwab.com.', 'schwabcorrentesettlement.com', 'schwabmoneywise.com', 'schwabe.com', 'proxyvote.com', 'boheme-schwabing.de', 'lesschwab.com', 'schwab-marketing.com', 'schwaben.ca')
        • sender.email.domain.domain in ('schwabebooks.ccsend.com')
      • headers.auth_summary.dmarc.pass
  4. 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
  5. not:
    • profile.by_sender().solicited

Inspects: headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender, strings.ilevenshtein, strings.ilike, strings.replace_confusables. Reference lists: $high_trust_sender_root_domains, $org_domains.

Indicators matched (4)

FieldMatchValue
strings.ilikesubstring*charles schwab*
strings.ilikesubstring*charlesschwab*
strings.ilevenshteinfuzzycharles schwab
strings.ilikesubstring*schwab*

Stages and Predicates

Stage 1: mql_rule

and
  not
    or
      and
        or
          sender.email.domain.domain eq "schwabebooks.ccsend.com"
          sender.email.domain.root_domain in ["aboutschwab.com.", "boheme-schwabing.de", "lesschwab.com", "proxyvote.com", "schwab-marketing.com", "schwab.com", "schwabcorrentesettlement.com", "schwabe.com", "schwaben.ca", "schwabmoneywise.com"]
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in org_domains"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    profile.by_sender func_call "profile.by_sender().solicited"
  or
    strings.ilevenshtein func_call "strings.ilevenshtein(strings.replace_confusables(sender.display_name), \"charles schwab\") <= 1"
    strings.replace_confusables(sender.display_name) match "charles schwab"
    strings.replace_confusables(sender.display_name) match "charlesschwab"
    strings.replace_confusables(sender.email.domain.domain) match "schwab"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.domaineqschwabebooks.ccsend.comexcludes:sender.email.domain.domain field:"sender.email.domain.domain" value:"schwabebooks.ccsend.com"
sender.email.domain.root_domaininaboutschwab.com., boheme-schwabing.de, lesschwab.com, proxyvote.com, schwab-marketing.com, schwab.com, schwabcorrentesettlement.com, schwabe.com, schwaben.ca, schwabmoneywise.comexcludes:sender.email.domain.root_domain
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Chase Bank

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

Impersonation of Chase Bank and related services to harvest credentials or related information such as dates of birth, phone numbers, social security numbers, ATM pin numbers, drivers license numbers, selfies, and ID card photos.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  strings.ilike(sender.display_name,
                '*chase sapphire*',
                '*chase card services*',
                '*united mileageplus*',
                "echase*",
                "*freedom unlimited*"
  )
  or strings.ilevenshtein(sender.display_name, 'chase sapphire') <= 2
  or strings.ilevenshtein(sender.display_name, 'chase card services') <= 2
  or strings.ilevenshtein(sender.display_name, 'united mileageplus') <= 2
  or (
    (
      strings.ilevenshtein(sender.display_name, 'echase') <= 1
      or (
        strings.icontains(sender.display_name, "bank")
        and strings.icontains(subject.base, "chase bank")
      )
    )
    // Negate Chase sender display name if cred theft, callback phishing, and a Chase logo isn't detected
    and not (
      strings.icontains(sender.display_name, 'chase')
      and not (
        any(ml.nlu_classifier(body.current_thread.text).intents,
            .name == "cred_theft" and .confidence in ("medium", "high")
        )
        or any(ml.nlu_classifier(body.current_thread.text).intents,
               .name == "callback_scam" and .confidence in ("medium", "high")
        )
        or any(ml.logo_detect(file.message_screenshot()).brands,
               strings.starts_with(.name, "Chase")
        )
      )
    )
  )
  or regex.icontains(body.current_thread.text,
                     '(Chase|J\.?\s?P\.?\sMorgan)\s(Privacy|Treasury)\sOperations|(Privacy|Treasury)\sOperations\s(Chase|J\.?\s?P\.?\sMorgan)'
  )
)
and not (
  sender.display_name is not null and sender.display_name in~ ("chaser", "case")
)
and sender.email.domain.root_domain not in~ (
  'chase.com',
  'united.com',
  'transunion.com',
  'shopping-chase.com',
  'chasetravel.com',
  'chaseoffers.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.

Impersonation of Chase Bank and related services to harvest credentials or related information such as dates of birth, phone numbers, social security numbers, ATM pin numbers, drivers license numbers, selfies, and ID card photos.

  1. inbound message
  2. any of:
    • sender.display_name matches any of 5 patterns
      • *chase sapphire*
      • *chase card services*
      • *united mileageplus*
      • echase*
      • *freedom unlimited*
    • sender.display_name is similar to 'chase sapphire'
    • sender.display_name is similar to 'chase card services'
    • sender.display_name is similar to 'united mileageplus'
    • all of:
      • any of:
        • sender.display_name is similar to 'echase'
        • all of:
          • sender.display_name contains 'bank'
          • subject.base contains 'chase bank'
      • not:
        • all of:
          • sender.display_name contains 'chase'
          • none of:
            • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
              • .name is 'cred_theft'
              • .confidence in ('medium', 'high')
            • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
              • .name is 'callback_scam'
              • .confidence in ('medium', 'high')
            • any of ml.logo_detect(file.message_screenshot()).brands where:
              • .name starts with 'Chase'
    • body.current_thread.text matches '(Chase|J\\.?\\s?P\\.?\\sMorgan)\\s(Privacy|Treasury)\\sOperations|(Privacy|Treasury)\\sOperations\\s(Chase|J\\.?\\s?P\\.?\\sMorgan)'
  3. not:
    • all of:
      • sender.display_name is set
      • sender.display_name in ('chaser', 'case')
  4. sender.email.domain.root_domain not in ('chase.com', 'united.com', 'transunion.com', 'shopping-chase.com', 'chasetravel.com', 'chaseoffers.com')
  5. 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, sender.display_name, sender.email.domain.root_domain, subject.base, type.inbound. Sensors: file.message_screenshot, ml.logo_detect, ml.nlu_classifier, regex.icontains, strings.icontains, strings.ilevenshtein, strings.ilike, strings.starts_with. Reference lists: $high_trust_sender_root_domains.

Indicators matched (17)

FieldMatchValue
strings.ilikesubstring*chase sapphire*
strings.ilikesubstring*chase card services*
strings.ilikesubstring*united mileageplus*
strings.ilikesubstringechase*
strings.ilikesubstring*freedom unlimited*
strings.ilevenshteinfuzzychase sapphire
strings.ilevenshteinfuzzychase card services
strings.ilevenshteinfuzzyunited mileageplus
strings.ilevenshteinfuzzyechase
strings.icontainssubstringbank
strings.icontainssubstringchase bank
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
5 more
ml.nlu_classifier(body.current_thread.text).intents[].confidencemembermedium
ml.nlu_classifier(body.current_thread.text).intents[].confidencememberhigh
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscallback_scam
strings.starts_withprefixChase
regex.icontainsregex(Chase|J\.?\s?P\.?\sMorgan)\s(Privacy|Treasury)\sOperations|(Privacy|Treasury)\sOperations\s(Chase|J\.?\s?P\.?\sMorgan)

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        and
          not
            or
              any(ml.nlu_classifier(body.current_thread.text).intents)
                and
                  ml.nlu_classifier(body.current_thread.text).intents.confidence in ["high", "medium"]
                  ml.nlu_classifier(body.current_thread.text).intents.name eq "callback_scam"
              any(ml.nlu_classifier(body.current_thread.text).intents)
                and
                  ml.nlu_classifier(body.current_thread.text).intents.confidence in ["high", "medium"]
                  ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
              any(ml.logo_detect(file.message_screenshot()).brands)
                ml.logo_detect(file.message_screenshot()).brands.name starts_with "Chase"
          sender.display_name contains "chase"
      or
        and
          sender.display_name contains "bank"
          subject.base contains "chase bank"
        strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"echase\") <= 1"
    body.current_thread.text regex_match "(Chase|J\\.?\\s?P\\.?\\sMorgan)\\s(Privacy|Treasury)\\sOperations|(Privacy|Treasury)\\sOperations\\s(Chase|J\\.?\\s?P\\.?\\sMorgan)"
    sender.display_name match "chase card services"
    sender.display_name match "chase sapphire"
    sender.display_name match "freedom unlimited"
    sender.display_name match "united mileageplus"
    sender.display_name starts_with "echase"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"chase card services\") <= 2"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"chase sapphire\") <= 2"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"united mileageplus\") <= 2"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    and
      sender.display_name in ["case", "chaser"]
      sender.display_name is_not_null
  not
    sender.email.domain.root_domain in ["chase.com", "chaseoffers.com", "chasetravel.com", "shopping-chase.com", "transunion.com", "united.com"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.display_nameincase, chaserexcludes:sender.display_name field:"sender.display_name" value:"case" field:"sender.display_name" value:"chaser"
sender.display_nameis_not_null(no value, null check)excludes:sender.display_name
sender.email.domain.root_domaininchase.com, chaseoffers.com, chasetravel.com, shopping-chase.com, transunion.com, united.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textregex_match
    • (Chase|J.?\s?P.?\sMorgan)\s(Privacy|Treasury)\sOperations
    • (Privacy|Treasury)\sOperations\s(Chase|J.?\s?P.?\sMorgan)
field:"body.current_thread.text" kind:regex_match
sender.display_namecontains
  • bank
field:"sender.display_name" kind:contains value:"bank"
sender.display_namewildcard
  • *chase card services*
  • *chase sapphire*
  • *freedom unlimited*
  • *united mileageplus*
  • echase*
field:"sender.display_name" kind:wildcard
subject.basecontains
  • chase bank
field:"subject.base" kind:contains value:"chase bank"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Chase bank with credential phishing indicators

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

This rule checks for messages with or without attachments leveraging the Chase logo, and LinkAnalysis or Natural Language Understanding(NLU) has flagged credential phishing with medium to high confidence. The rule also excludes messages where all links are Chase affiliates, in addition to negating high trust sender root domains.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • body.links
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  (
    length(attachments) <= 3
    and any(attachments,
            .file_type in $file_types_images
            and any(ml.logo_detect(.).brands, .name == "Chase")
    )
  )
  or (
    length(attachments) == 0
    and any(ml.logo_detect(file.message_screenshot()).brands, .name == "Chase")
  )
)
and 0 < length(body.links) < 10
and (
  any(body.links,
      any([ml.link_analysis(.)],
          .credphish.disposition == "phishing"
          and .credphish.brand.confidence in ("medium", "high")
      )
  )
  or any(ml.nlu_classifier(body.current_thread.text).intents,
         .name in ("cred_theft") and .confidence in ("medium", "high")
  )
)
and not all(body.links,
            .href_url.domain.root_domain in (
              "chasecdn.com",
              "chase.com",
              "chase.co.uk",
              "gslbjpmchase.com",
              "jpmorganchase.com",
              "jpmorgan.com",
              "jpmorganfunds.com",
              "jpmprivatebank.com",
              "paymentech.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
)
and (
  not profile.by_sender().solicited
  or profile.by_sender().any_messages_malicious_or_spam
)

Detection logic

Scope: inbound message.

This rule checks for messages with or without attachments leveraging the Chase logo, and LinkAnalysis or Natural Language Understanding(NLU) has flagged credential phishing with medium to high confidence. The rule also excludes messages where all links are Chase affiliates, in addition to negating high trust sender root domains.

  1. inbound message
  2. any of:
    • all of:
      • length(attachments) ≤ 3
      • any of attachments where all hold:
        • .file_type in $file_types_images
        • any of ml.logo_detect(.).brands where:
          • .name is 'Chase'
    • all of:
      • length(attachments) is 0
      • any of ml.logo_detect(file.message_screenshot()).brands where:
        • .name is 'Chase'
  3. all of:
    • length(body.links) > 0
    • length(body.links) < 10
  4. any of:
    • any of body.links where:
      • any of [ml.link_analysis(.)] where all hold:
        • .credphish.disposition is 'phishing'
        • .credphish.brand.confidence in ('medium', 'high')
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name in ('cred_theft')
      • .confidence in ('medium', 'high')
  5. not:
    • all of body.links where:
      • .href_url.domain.root_domain in ('chasecdn.com', 'chase.com', 'chase.co.uk', 'gslbjpmchase.com', 'jpmorganchase.com', 'jpmorgan.com', 'jpmorganfunds.com', 'jpmprivatebank.com', 'paymentech.com')
  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
  7. any of:
    • not:
      • profile.by_sender().solicited
    • profile.by_sender().any_messages_malicious_or_spam

Inspects: attachments[].file_type, body.current_thread.text, body.links, body.links[].href_url.domain.root_domain, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: file.message_screenshot, ml.link_analysis, ml.logo_detect, ml.nlu_classifier, profile.by_sender. Reference lists: $file_types_images, $high_trust_sender_root_domains.

Indicators matched (8)

FieldMatchValue
ml.logo_detect(attachments[]).brands[].nameequalsChase
ml.logo_detect(file.message_screenshot()).brands[].nameequalsChase
[ml.link_analysis(body.links[])][].credphish.dispositionequalsphishing
[ml.link_analysis(body.links[])][].credphish.brand.confidencemembermedium
[ml.link_analysis(body.links[])][].credphish.brand.confidencememberhigh
ml.nlu_classifier(body.current_thread.text).intents[].namemembercred_theft
ml.nlu_classifier(body.current_thread.text).intents[].confidencemembermedium
ml.nlu_classifier(body.current_thread.text).intents[].confidencememberhigh

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      any(attachments)
        and
          any(ml.logo_detect(attachments).brands)
            ml.logo_detect(attachments).brands.name eq "Chase"
           macro "attachments[].file_type in file_types_images"
      attachments length_compare "3"
    and
      any(ml.logo_detect(file.message_screenshot()).brands)
        ml.logo_detect(file.message_screenshot()).brands.name eq "Chase"
      attachments length_compare "0"
  or
    any(body.links)
      any([ml.link_analysis(body.links)])
        and
          [ml.link_analysis(body.links[])][].credphish.brand.confidence in ["high", "medium"]
          [ml.link_analysis(body.links[])][].credphish.disposition eq "phishing"
    any(ml.nlu_classifier(body.current_thread.text).intents)
      and
        ml.nlu_classifier(body.current_thread.text).intents.confidence in ["high", "medium"]
        ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    not
      profile.by_sender func_call "profile.by_sender().solicited"
    profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
  not
     macro "all(body.links)"
  body.links length_compare "0"
  body.links length_compare "10"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Coinbase

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

Impersonation of the cryptocurrency exchange Coinbase to harvest Coinbase credentials or related information.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  strings.ilike(strings.replace_confusables(sender.display_name), '*coinbase*')
  or strings.ilevenshtein(strings.replace_confusables(sender.display_name),
                          'coinbase'
  ) <= 1
  or strings.ilike(sender.email.domain.domain, '*coinbase*')
)
and not (
  sender.email.domain.root_domain in (
    'coinbase.com',
    'q4inc.com',
    'sendsafely.com' // used by Coinbase for verification codes
  )
  and headers.auth_summary.dmarc.pass
)
and (
  // if this comes from a free email provider,
  // flag if org has never sent an email to sender's email before
  (
    sender.email.domain.root_domain in $free_email_providers
    and sender.email.email not in $recipient_emails
  )
  // if this comes from a custom domain,
  // flag if org has never sent an email to sender's domain before
  or (
    sender.email.domain.root_domain not in $free_email_providers
    and sender.email.domain.domain not in $recipient_domains
  )
)

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

Impersonation of the cryptocurrency exchange Coinbase to harvest Coinbase credentials or related information.

  1. inbound message
  2. any of:
    • strings.replace_confusables(sender.display_name) matches '*coinbase*'
    • strings.replace_confusables(sender.display_name) is similar to 'coinbase'
    • sender.email.domain.domain matches '*coinbase*'
  3. not:
    • all of:
      • sender.email.domain.root_domain in ('coinbase.com', 'q4inc.com', 'sendsafely.com')
      • headers.auth_summary.dmarc.pass
  4. any of:
    • all of:
      • sender.email.domain.root_domain in $free_email_providers
      • sender.email.email not in $recipient_emails
    • all of:
      • sender.email.domain.root_domain not in $free_email_providers
      • sender.email.domain.domain not in $recipient_domains
  5. 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: headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: strings.ilevenshtein, strings.ilike, strings.replace_confusables. Reference lists: $free_email_providers, $high_trust_sender_root_domains, $recipient_domains, $recipient_emails.

Indicators matched (2)

FieldMatchValue
strings.ilikesubstring*coinbase*
strings.ilevenshteinfuzzycoinbase

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.root_domain in ["coinbase.com", "q4inc.com", "sendsafely.com"]
  or
    and
       macro "sender.email.domain.domain not in recipient_domains"
       macro "sender.email.domain.root_domain not in free_email_providers"
    and
       macro "sender.email.domain.root_domain in free_email_providers"
       macro "sender.email.email not in recipient_emails"
  or
    sender.email.domain.domain match "coinbase"
    strings.ilevenshtein func_call "strings.ilevenshtein(strings.replace_confusables(sender.display_name), \"coinbase\") <= 1"
    strings.replace_confusables(sender.display_name) match "coinbase"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Dashlane

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

Impersonation of the password management software Dashlane.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  regex.icontains(sender.display_name, '\bDashlane\b')
  or strings.ilike(sender.email.domain.domain, '*Dashlane*')
)
and sender.email.domain.root_domain not in~ ('dashlane.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.

Impersonation of the password management software Dashlane.

  1. inbound message
  2. any of:
    • sender.display_name matches '\\bDashlane\\b'
    • sender.email.domain.domain matches '*Dashlane*'
  3. sender.email.domain.root_domain not in ('dashlane.com')
  4. 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: headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: regex.icontains, strings.ilike. Reference lists: $high_trust_sender_root_domains.

Indicators matched (2)

FieldMatchValue
regex.icontainsregex\bDashlane\b
strings.ilikesubstring*Dashlane*

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    sender.display_name regex_match "\\bDashlane\\b"
    sender.email.domain.domain match "Dashlane"
  not
    sender.email.domain.root_domain eq "dashlane.com"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaineqdashlane.comexcludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"dashlane.com"

Indicators

These rows show field, operator, and value matches.

Brand impersonation: DHL

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

Impersonation of the shipping provider DHL.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  regex.icontains(sender.display_name, '\bDHL\b')
  or (
    strings.ilike(sender.email.domain.domain, '*DHL*')
    and length(sender.email.domain.domain) < 15
  )
  or strings.ilike(subject.subject, '*DHL notification*')
  or regex.icontains(subject.subject, 'dhl? express')
  or regex.contains(subject.subject, '\bD.{0,2}H.{0,2}L.{0,2}\b')
  or (
    any(ml.nlu_classifier(body.current_thread.text).topics,
        .name == "Shipping and Package" and .confidence == "high"
    )
    and strings.contains(body.current_thread.text, 'DHL ')
  )
)
and (
  any(ml.nlu_classifier(body.current_thread.text).entities, .name == "urgency")
  or any(ml.nlu_classifier(body.current_thread.text).entities,
         .name == "org"
         and (
           .text =~ "DHL"
           or .text =~ "DHL Express"
           or strings.istarts_with(.text, "DHL International")
         )
  )
  or any(ml.logo_detect(file.message_screenshot()).brands,
         .name == "DHL" and .confidence in ("medium", "high")
  )
  or regex.icontains(body.current_thread.text, '\bDHL\b')
  // it contains a QR code
  or (
    //
    // This rule makes use of a beta feature and is subject to change without notice
    // using the beta feature in custom rules is not suggested until it has been formally released
    //
    beta.scan_qr(file.message_screenshot()).found
    and any(beta.scan_qr(file.message_screenshot()).items, .type == "url")
  )
  //
  // This rule makes use of a beta feature and is subject to change without notice
  // using the beta feature in custom rules is not suggested until it has been formally released
  //
  or strings.ilike(beta.ocr(file.message_screenshot()).text,
                   "*package*",
                   "*parcel*",
                   "*shipping*",
                   "*delivery*",
                   "*track*"
  )
  or strings.ilike(body.current_thread.text,
                   "*package*",
                   "*parcel*",
                   "*shipping*",
                   "*delivery*",
                   "*track*"
  )
)
and (
  (
    (length(headers.references) > 0 or headers.in_reply_to is null)
    and not (
      (
        strings.istarts_with(subject.subject, "RE:")
        or strings.istarts_with(subject.subject, "RES:")
        or strings.istarts_with(subject.subject, "R:")
        or strings.istarts_with(subject.subject, "ODG:")
        or strings.istarts_with(subject.subject, "答复:")
        or strings.istarts_with(subject.subject, "AW:")
        or strings.istarts_with(subject.subject, "TR:")
        or strings.istarts_with(subject.subject, "FWD:")
        or regex.imatch(subject.subject, '(\[[^\]]+\]\s?){0,3}(re|fwd?)\s?:')
      )
    )
  )
  or length(headers.references) == 0
)
and sender.email.domain.root_domain not in~ (
  'dhl.com',
  'dhl-news.com',
  'bdhllp.com',
  'dhlecommerce.co.uk',
  'dhlparcel.co.uk',
  'dhlecs.com',
  'dhl.co.uk',
  'dhl.co.tz',
  'dpdhl.com',
  'dhl.de',
  'dhl.fr',
  'dhl.pl',
  'dhlexpress.fr', // legit dhl site
  'dhlending.com',
  'inmotion.dhl',
  'dhlparcel.nl',
  'dhltariff.co.uk',
  'dhlindia-kyc.com',
  'dpogroup.com',
  '4flow-service.com', // shipping service
  'leaders-in-logistics.com', // legit sight for leadership webinar events
  'deutschepost.de', // German postal service
  'dhlecommerce.nl',
  'dhl.nl',
  'adhlawfirm.com', // similar name but unrelated
  'attendhlth.com', // dhl in domain but unrelated
  'tdhlaw.com', // dhl in domain but unrelated
  'hapibenefits.com', // DHL rewards program
  'dhlgpi.com', // DHL Australia
  'dhlfreight-news.com'
)
and not (
  sender.email.domain.tld in ('dhl')
  and coalesce(headers.auth_summary.dmarc.pass, false)
)
and (
  profile.by_sender().prevalence in ("new", "outlier")
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)

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

Impersonation of the shipping provider DHL.

  1. inbound message
  2. any of:
    • sender.display_name matches '\\bDHL\\b'
    • all of:
      • sender.email.domain.domain matches '*DHL*'
      • length(sender.email.domain.domain) < 15
    • subject.subject matches '*DHL notification*'
    • subject.subject matches 'dhl? express'
    • subject.subject matches '\\bD.{0,2}H.{0,2}L.{0,2}\\b'
    • all of:
      • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
        • .name is 'Shipping and Package'
        • .confidence is 'high'
      • body.current_thread.text contains 'DHL '
  3. any of:
    • any of ml.nlu_classifier(body.current_thread.text).entities where:
      • .name is 'urgency'
    • any of ml.nlu_classifier(body.current_thread.text).entities where all hold:
      • .name is 'org'
      • any of:
        • .text is 'DHL'
        • .text is 'DHL Express'
        • .text starts with 'DHL International'
    • any of ml.logo_detect(file.message_screenshot()).brands where all hold:
      • .name is 'DHL'
      • .confidence in ('medium', 'high')
    • body.current_thread.text matches '\\bDHL\\b'
    • all of:
      • beta.scan_qr(file.message_screenshot()).found
      • any of beta.scan_qr(file.message_screenshot()).items where:
        • .type is 'url'
    • beta.ocr(file.message_screenshot()).text matches any of 5 patterns
      • *package*
      • *parcel*
      • *shipping*
      • *delivery*
      • *track*
    • body.current_thread.text matches any of 5 patterns
      • *package*
      • *parcel*
      • *shipping*
      • *delivery*
      • *track*
  4. any of:
    • all of:
      • any of:
        • length(headers.references) > 0
        • headers.in_reply_to is missing
      • none of:
        • subject.subject starts with 'RE:'
        • subject.subject starts with 'RES:'
        • subject.subject starts with 'R:'
        • subject.subject starts with 'ODG:'
        • subject.subject starts with '答复:'
        • subject.subject starts with 'AW:'
        • subject.subject starts with 'TR:'
        • subject.subject starts with 'FWD:'
        • subject.subject matches '(\\[[^\\]]+\\]\\s?){0,3}(re|fwd?)\\s?:'
    • length(headers.references) is 0
  5. sender.email.domain.root_domain not in ('dhl.com', 'dhl-news.com', 'bdhllp.com', 'dhlecommerce.co.uk', 'dhlparcel.co.uk', 'dhlecs.com', 'dhl.co.uk', 'dhl.co.tz', 'dpdhl.com', 'dhl.de', 'dhl.fr', 'dhl.pl', 'dhlexpress.fr', 'dhlending.com', 'inmotion.dhl', 'dhlparcel.nl', 'dhltariff.co.uk', 'dhlindia-kyc.com', 'dpogroup.com', '4flow-service.com', 'leaders-in-logistics.com', 'deutschepost.de', 'dhlecommerce.nl', 'dhl.nl', 'adhlawfirm.com', 'attendhlth.com', 'tdhlaw.com', 'hapibenefits.com', 'dhlgpi.com', 'dhlfreight-news.com')
  6. not:
    • all of:
      • sender.email.domain.tld in ('dhl')
      • coalesce(headers.auth_summary.dmarc.pass)
  7. any of:
    • profile.by_sender().prevalence in ('new', 'outlier')
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  8. 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.in_reply_to, headers.references, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.domain.tld, subject.subject, type.inbound. Sensors: beta.ocr, beta.scan_qr, file.message_screenshot, ml.logo_detect, ml.nlu_classifier, profile.by_sender, regex.contains, regex.icontains, regex.imatch, strings.contains, strings.ilike, strings.istarts_with. Reference lists: $high_trust_sender_root_domains.

Indicators matched (22)

FieldMatchValue
regex.icontainsregex\bDHL\b
strings.ilikesubstring*DHL*
strings.ilikesubstring*DHL notification*
regex.icontainsregexdhl? express
regex.containsregex\bD.{0,2}H.{0,2}L.{0,2}\b
ml.nlu_classifier(body.current_thread.text).topics[].nameequalsShipping and Package
ml.nlu_classifier(body.current_thread.text).topics[].confidenceequalshigh
strings.containssubstringDHL
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsurgency
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsorg
ml.nlu_classifier(body.current_thread.text).entities[].textequalsDHL
ml.nlu_classifier(body.current_thread.text).entities[].textequalsDHL Express
10 more
strings.istarts_withprefixDHL International
ml.logo_detect(file.message_screenshot()).brands[].nameequalsDHL
ml.logo_detect(file.message_screenshot()).brands[].confidencemembermedium
ml.logo_detect(file.message_screenshot()).brands[].confidencememberhigh
beta.scan_qr(file.message_screenshot()).items[].typeequalsurl
strings.ilikesubstring*package*
strings.ilikesubstring*parcel*
strings.ilikesubstring*shipping*
strings.ilikesubstring*delivery*
strings.ilikesubstring*track*

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(ml.nlu_classifier(body.current_thread.text).entities)
      and
        or
          ml.nlu_classifier(body.current_thread.text).entities.text eq "DHL Express"
          ml.nlu_classifier(body.current_thread.text).entities.text eq "DHL"
          ml.nlu_classifier(body.current_thread.text).entities.text starts_with "DHL International"
        ml.nlu_classifier(body.current_thread.text).entities.name eq "org"
    and
      any(beta.scan_qr(file.message_screenshot()).items)
        beta.scan_qr(file.message_screenshot()).items.type eq "url"
      beta.scan_qr func_call "beta.scan_qr(file.message_screenshot()).found"
    any(ml.logo_detect(file.message_screenshot()).brands)
      and
        ml.logo_detect(file.message_screenshot()).brands.confidence in ["high", "medium"]
        ml.logo_detect(file.message_screenshot()).brands.name eq "DHL"
    any(ml.nlu_classifier(body.current_thread.text).entities)
      ml.nlu_classifier(body.current_thread.text).entities.name eq "urgency"
    beta.ocr(file.message_screenshot()).text match "delivery"
    beta.ocr(file.message_screenshot()).text match "package"
    beta.ocr(file.message_screenshot()).text match "parcel"
    beta.ocr(file.message_screenshot()).text match "shipping"
    beta.ocr(file.message_screenshot()).text match "track"
    body.current_thread.text match "delivery"
    body.current_thread.text match "package"
    body.current_thread.text match "parcel"
    body.current_thread.text match "shipping"
    body.current_thread.text match "track"
    body.current_thread.text regex_match "\\bDHL\\b"
  or
    and
      any(ml.nlu_classifier(body.current_thread.text).topics)
        and
          ml.nlu_classifier(body.current_thread.text).topics.confidence eq "high"
          ml.nlu_classifier(body.current_thread.text).topics.name eq "Shipping and Package"
      body.current_thread.text contains "DHL "
    and
      sender.email.domain.domain length_compare "15"
      sender.email.domain.domain match "DHL"
    sender.display_name regex_match "\\bDHL\\b"
    subject.subject match "DHL notification"
    subject.subject regex_match "\\bD.{0,2}H.{0,2}L.{0,2}\\b"
    subject.subject regex_match "dhl? express"
  or
    and
      not
        or
          subject.subject regex_match "(\\[[^\\]]+\\]\\s?){0,3}(re|fwd?)\\s?:"
          subject.subject starts_with "AW:"
          subject.subject starts_with "FWD:"
          subject.subject starts_with "ODG:"
          subject.subject starts_with "R:"
          subject.subject starts_with "RE:"
          subject.subject starts_with "RES:"
          subject.subject starts_with "TR:"
          subject.subject starts_with "答复:"
      or
        headers.in_reply_to is_null
        headers.references length_compare "0"
    headers.references length_compare "0"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    profile.by_sender func_call "profile.by_sender().prevalence in (new, outlier)"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
      sender.email.domain.tld eq "dhl"
  not
    sender.email.domain.root_domain in ["4flow-service.com", "adhlawfirm.com", "attendhlth.com", "bdhllp.com", "deutschepost.de", "dhl-news.com", "dhl.co.tz", "dhl.co.uk", "dhl.com", "dhl.de", "dhl.fr", "dhl.nl", "dhl.pl", "dhlecommerce.co.uk", "dhlecommerce.nl", "dhlecs.com", "dhlending.com", "dhlexpress.fr", "dhlfreight-news.com", "dhlgpi.com", "dhlindia-kyc.com", "dhlparcel.co.uk", "dhlparcel.nl", "dhltariff.co.uk", "dpdhl.com", "dpogroup.com", "hapibenefits.com", "inmotion.dhl", "leaders-in-logistics.com", "tdhlaw.com"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.tldeqdhlexcludes:sender.email.domain.tld field:"sender.email.domain.tld" value:"dhl"
sender.email.domain.root_domainin4flow-service.com, adhlawfirm.com, attendhlth.com, bdhllp.com, deutschepost.de, dhl-news.com, dhl.co.tz, dhl.co.uk, dhl.com, dhl.de, dhl.fr, dhl.nl, dhl.pl, dhlecommerce.co.uk, dhlecommerce.nl, dhlecs.com, dhlending.com, dhlexpress.fr, dhlfreight-news.com, dhlgpi.com, dhlindia-kyc.com, dhlparcel.co.uk, dhlparcel.nl, dhltariff.co.uk, dpdhl.com, dpogroup.com, hapibenefits.com, inmotion.dhl, leaders-in-logistics.com, tdhlaw.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: DigitalOcean

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

Impersonation of the cloud provider DigitalOcean.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • sender.email
  • type

Rule body

type.inbound
and (
  sender.display_name =~ 'digitalocean'
  or strings.ilevenshtein(sender.display_name, 'digitalocean') <= 2
  or strings.ilike(sender.email.domain.domain, '*digitalocean*')
)
and sender.email.domain.root_domain not in (
  'digitalocean.com',
  'paperspace.com',
  'coupahost.com' // third party supplier used by DigitalOcean 
)
and (
  not profile.by_sender().solicited
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

Impersonation of the cloud provider DigitalOcean.

  1. inbound message
  2. any of:
    • sender.display_name is 'digitalocean'
    • sender.display_name is similar to 'digitalocean'
    • sender.email.domain.domain matches '*digitalocean*'
  3. sender.email.domain.root_domain not in ('digitalocean.com', 'paperspace.com', 'coupahost.com')
  4. any of:
    • not:
      • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  5. not:
    • profile.by_sender().any_messages_benign

Inspects: sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender, strings.ilevenshtein, strings.ilike.

Indicators matched (3)

FieldMatchValue
sender.display_nameequalsdigitalocean
strings.ilevenshteinfuzzydigitalocean
strings.ilikesubstring*digitalocean*

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    not
      profile.by_sender func_call "profile.by_sender().solicited"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  or
    sender.display_name eq "digitalocean"
    sender.email.domain.domain match "digitalocean"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"digitalocean\") <= 2"
  not
    sender.email.domain.root_domain in ["coupahost.com", "digitalocean.com", "paperspace.com"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

Brand impersonation: DocuSign

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

Attack impersonating a DocuSign request for signature.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering, Spoofing

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • body.html
  • body.links
  • headers
  • headers.auth_summary
  • headers.domains
  • headers.hops
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  // orgs can have docusign.company.com
  strings.ilike(sender.email.email, '*docusign.net*', '*docusign.com*')

  // if the above is true, you'll see a "via Docusign"
  or strings.ilike(sender.display_name, '*docusign*')

  // detects 1 character variations,
  // such as DocuSlgn (with an "L" instead of an "I")
  or strings.ilevenshtein(sender.display_name, "docusign") == 1
  or strings.ilike(sender.display_name, "*docuonline*", "*via *signature*")
  or (
    strings.istarts_with(body.html.inner_text, "docusign")
    and not strings.istarts_with(body.current_thread.text, "docusign")
  )
  // docusign is found in current thread AND contains docusign wording within current_thread or subject
  or (
    regex.icontains(body.current_thread.text, '\bdocu.?sign\b')
    and (
      // additional context from body.current_thread.text
      strings.istarts_with(body.current_thread.text, "DOCUSIGN\n", )
      or regex.icontains(body.current_thread.text,
                         "You(?:'ve| have) received a ([^\\s]+\\s)?document"
      )
      or strings.icontains(body.current_thread.text,
                           'a document to review and sign',
      )
      or strings.icontains(body.current_thread.text,
                           'A document is available for you',
      )
      or strings.icontains(body.current_thread.text,
                           'a document ready for you',
      )
      or strings.icontains(body.current_thread.text,
                           'This email contains a secure link to DocuSign'
      )
      or strings.icontains(body.current_thread.text,
                           'All parties have completed with Docusign'
      )
      or strings.icontains(body.current_thread.text,
                           'the signing of this document has been completed'
      )
      or strings.icontains(body.current_thread.text,
                           'Please use the link above to Docusign'
      )
      or strings.icontains(body.current_thread.text, 'Review on Docusign')
      or strings.icontains(body.current_thread.text, 'Completed with Docusign')
      or strings.icontains(body.current_thread.text, 'Completed on Docusign')
      or strings.icontains(body.current_thread.text, 'Complete with Docusign')
      or strings.icontains(body.current_thread.text,
                           'please review and complete with DocuSign'
      )
      or strings.icontains(body.current_thread.text,
                           'We appreciate you choosing DocuSign'
      )
      or strings.icontains(body.current_thread.text,
                           'A document has been sent to you for'
      )
      or strings.icontains(body.current_thread.text, 'Please Sign docusign')
      or strings.icontains(body.current_thread.text,
                           'This email was sent via DocuSign'
      )
      or strings.icontains(body.current_thread.text,
                           'This email was sent to you via DocuSign'
      )
      or strings.icontains(body.current_thread.text,
                           'This message was sent via DocuSign'
      )
      or strings.icontains(body.current_thread.text,
                           'This message was sent to you via DocuSign'
      )
      or strings.icontains(body.current_thread.text,
                           'review via DocuSign Electronic Signature'
      )
      or strings.icontains(body.current_thread.text, 'sent to you by DocuSign')
      or strings.icontains(body.current_thread.text, 'Processed by DocuSign')
      or strings.icontains(body.current_thread.text,
                           'Please read and sign the document'
      )
      or strings.icontains(body.current_thread.text,
                           'Please kindly review and sign the '
      )
      or strings.icontains(body.current_thread.text,
                           'Your document is pending review and signature'
      )
      or strings.icontains(body.current_thread.text,
                           'pending document for your signature'
      )
      or strings.icontains(body.current_thread.text,
                           'your review and signature'
      )
      or strings.icontains(body.current_thread.text, 'a pending document for')
      or strings.icontains(body.current_thread.text, 'Your document is ready')
      or strings.icontains(body.current_thread.text,
                           'This email is automatically generated by DocuSign'
      )
      or strings.icontains(body.current_thread.text,
                           'Your document has been completed'
      )
      // docusign is "near" review and sign or sign and return
      or regex.icontains(body.current_thread.text,
                         'Review\s*(?:and\s*|&\s*)Sign.{0,40}docusign',
                         'docusign.{0,40}Review\s*(?:and\s*|&\s*)Sign',
                         'Sign\s*(?:and\s*|&\s*)Return.{0,40}docusign',
                         'Sign\s*(?:and\s*|&\s*)Return.docusign.{0,40}'
      )

      // additional context from subject.subject
      or strings.icontains(subject.subject, 'complete with docusign')
      or strings.icontains(subject.subject, 'signature request')
      or regex.icontains(subject.subject, 'Review\s*(?:and\s*|&\s*)Sign')
      or regex.icontains(subject.subject, 'Sign\s*(?:and\s*|&\s*)Return')
      or strings.icontains(subject.subject, 'Please Docusign')
      or strings.icontains(subject.subject, 'Docusign has sent')
    )
  )
  or (
    // negate replies/forwards which involve a legit docusign message-id format
    not any(headers.references,
            strings.iends_with(., 'docusign.net')
            and regex.imatch(., '[0-9a-f]{32}@(?:[^\.]+\.)?docusign.net')
    )
    and (
      (
        sender.display_name is not null
        and regex.icontains(sender.display_name, '\bdocu\b')
        and strings.icontains(sender.display_name, 'sign')
      )
      or (
        subject.subject is not null
        and regex.icontains(subject.subject, '\bdocu\b')
        and strings.icontains(subject.subject, 'sign')
      )
      or (
        (
          regex.icontains(body.html.raw,
                          'Powered by.{0,6}(?:\s*<\/?[^\>]+\>\s*)+<img[^\>]+(?:src="https:\/\/docucdn-a\.akamaihd\.net\/[^\"]+email-logo.png"|alt="DocuSign")'
          )
          or regex.icontains(body.current_thread.text, 'Powered by\s*DocuSign')
        )
        // limit it to where the powered by is within the current thread
        and strings.icontains(body.current_thread.text, 'Powered by')
      )
      // footer disclaimers
      or strings.icontains(body.current_thread.text,
                           'using the Docusign Electronic Signature Service'
      )
      or strings.icontains(body.current_thread.text,
                           'who uses the DocuSign Electronic Signature Service'
      )
      or strings.icontains(body.current_thread.text,
                           'Thank you for choosing DocuSign'
      )
      or (
        (
          strings.icontains(body.current_thread.text,
                            'Alternate Signing Method'
          )
          or strings.icontains(body.current_thread.text, 'Alternative Access')
        )
        and regex.icontains(body.current_thread.text,
                            '(?:Click|Select) ''Access Documents'', and enter '
        )
      )
      or (
        strings.icontains(body.current_thread.text,
                          'Please do not share this email, link, or access code with others'
        )
        and not sender.email.domain.root_domain in (
          "insuresign.com",
          "clixsign.com",
          "esignlive.com",
          "clickcontracts.com",
          "sadq.sa",
          "vasion.com",
          "chubb.com", // insurance company
        )
      )
      or (
        strings.icontains(body.current_thread.text, 'Docusign provides a ')
        and strings.icontains(body.current_thread.text,
                              'solution for Digital Transaction Management'
        )
      )
      or strings.icontains(body.current_thread.text,
                           'a secure link to DocuSign'
      )

      // footer links
      or (
        length(filter(body.links,
                      (
                        .href_url.domain.domain == "support.docusign.com"
                        and strings.contains(.href_url.path, '/articles/')
                      )
                      or .href_url.domain.domain == "community.docusign.com"
                      or .href_url.domain.domain == "protect.docusign.com"
                      or .href_url.domain.domain == "app.esign.docusign.com"
               )
        ) >= 2
        // and the display_text for these links are within the current thread
        and (
          strings.icontains(body.current_thread.text, 'Declining to sign')
          or strings.icontains(body.current_thread.text,
                               'Managing notifications'
          )
          or strings.icontains(body.current_thread.text,
                               'How to Sign a Document'
          )
          or strings.icontains(body.current_thread.text,
                               'Docusign Support Center'
          )
          or strings.icontains(body.current_thread.text, 'Report this email')
          or strings.icontains(body.current_thread.text, 'Docusign Community')
          or strings.icontains(body.current_thread.text,
                               'Connect with our support team'
          )
          or strings.icontains(body.current_thread.text, 'Unsubscribe')
          or strings.icontains(body.current_thread.text, 'Manage Preferences')
        )
      )
    )
  )
  or (
    (
      regex.icontains(body.html.raw,
                      '<font size="?[0-9]"?[^\>]*>DocuSign</font>'
      )
      or regex.icontains(body.html.raw, '\nDocu(?:<[^\>]+>\s*)+Sign<')
      or regex.icontains(body.html.raw,
                         '<span[^>]*style="[^"]*">Docu.?Sign<\/span>'
      )
      or any(html.xpath(body.html, '//h1').nodes,
             regex.icontains(.display_text, 'Docu.?Sign')
      )
      or regex.icontains(body.html.raw,
                         '<span[^>]*style="[^"]*">(Docu|D(?:ocu?)?)<\/span>(?:<[^\>]+\>){0,2}<span[^>]*style="[^"]*">(Sign|S(?:ign?)?)<\/span>'
      )
      // any bold text contains docusign
      or any(html.xpath(body.html, '//strong').nodes,
             regex.imatch(.display_text, 'Docu.?Sign')
      )
      // title starts with Docusign
      or any(html.xpath(body.html, '//title').nodes,
             regex.icontains(.display_text, '^docu.?sign')
      )
      // a div with a class of logo contains the display text of docusign
      or any(html.xpath(body.html, '//div[@class="logo"]').nodes,
             strings.icontains(.display_text, 'Docusign')
      )
      // image contains an alt text of docusign
      or any(html.xpath(body.html, '//img/@alt').nodes, .raw =~ "docusign")

      // Basic variations with HTML encoding
      // use of regex extract allows
      or any(regex.iextract(body.html.raw,
                            '(?:D|&#68;|&#x44;)(?:&#?[0-9a-fA-F]{2,6};|\s|o|о|&#1086;|&#x43e;)(?:&#?[0-9a-fA-F]{2,6};|\s|c|с|&#1089;|&#x441;)u(?:&#?[0-9a-fA-F]{2,6};|\s)?S(?:&#?[0-9a-fA-F]{2,6};|\s|i|і|&#1110;|&#x456;)(?:&#?[0-9a-fA-F]{2,6};|\s|g|ɡ|&#609;|&#x261;)(?:n|&#110;|&#x6e;)'
             ),
             .full_match !~ "docusign"
      )
      //  Common homograph patterns
      or any(regex.iextract(body.html.raw,
                            '(?:[DⅮᎠᗞᗡ𝐃𝐷𝑫𝒟𝓓𝔇𝔻𝕯𝖣])\s*(?:[oοоօ0Ооʘ◯])\s*(?:[cсçҫ¢ϲС])\s*u\s*(?:[sѕЅ5$])\s*(?:[iіІ1l!|])\s*(?:[gǵġģ9ɡ])\s*(?:[nոռℼη𝐧𝑛𝒏𝓃𝓷𝔫𝕟𝖓])'
             ),
             .full_match !~ "docusign"
      )

      // Look for HTML entities for each letter in sequence
      or any(regex.iextract(body.html.raw,
                            '(?:D|&#68;|&#x44;)(?:o|о|&#111;|&#x6f;|&#1086;|&#x43e;|&#959;|&#x3bf;)(?:c|с|&#99;|&#x63;|&#1089;|&#x441;|&#1010;|&#231;|&#x67;|&#265;|&#x109;)(?:u|&#117;|&#x75;|&#1091;|&#x443;|&#965;|&#x3c5;)(?:s|&#115;|&#x73;|&#1109;|&#x455;)(?:i|і|&#105;|&#x69;|&#1110;|&#x456;|&#305;|&#x131;)(?:g|&#103;|&#x67;|&#609;|&#x261;|&#287;|&#x11f;)(?:n|&#110;|&#x6e;|&#1085;|&#x43d;|&#951;|&#x3b7;)'
             ),
             .full_match !~ "docusign"
      )

      // Handle repeated HTML entities and variation selectors (using Unicode class)
      or any(regex.iextract(body.html.raw,
                            'D(?:&#[0-9]{1,7};)*\p{Mn}*o(?:&#[0-9]{1,7};)*\p{Mn}*c(?:&#[0-9]{1,7};)*\p{Mn}*u(?:&#[0-9]{1,7};)*\p{Mn}*[Ss](?:&#[0-9]{1,7};)*\p{Mn}*i(?:&#[0-9]{1,7};)*\p{Mn}*g(?:&#[0-9]{1,7};)*\p{Mn}*n'
             ),
             .full_match !~ "docusign"
      )
    )
    and (
      regex.icontains(body.html.raw,
                      'b(?:ackground(?:-color)?|g?color):\s*rgb\(30,\s*76,\s*161\)',
                      'b(?:ackground(?:-color)?|g?color):\s*rgb\(61,\s*170,\s*73\)'
      )
      or regex.icontains(body.html.raw,
                         '<(?:div|td|table)[^>]*b(?:ackground(?:-color)?|g?color)(?::|=)\s*\"?#1e4ca1[^>]*>',
      )
      or regex.icontains(body.html.raw,
                         'b(?:ackground(?:-color)?|g?color)(?::|=)\s*\"?#(?:214e9f|3260a7|0056b3|1e4ca1|214395|325bb8|3c60ad)'
      )
    )
  )
  or (
    strings.icontains(body.current_thread.text, 'Docusign')
    and (
      regex.icontains(body.html.raw, '<title>[^<]*Easearch[^<]*</title>')
      or regex.icontains(body.html.raw, '<spacing>[^<]*(?:Docusign|Document)')
      or regex.icontains(body.html.raw, '{(?:domain|randomNumber\d?)}')
    )
  )
)

// identifies the main CTA in the email, eg "Review now" or "Review document"
// this should always be a known docusign domain,
// even with branded docusign subdomains
and (
  any(
      // filter links that match docusign wording
      filter(body.links,
             // we've observed invisible characters in the display name
             // such as U+034F: "Revi\x{034F}ew Now"
             (
               strings.ilevenshtein(.display_text, "Review Now") <= 3
               or strings.ilevenshtein(.display_text, "Review and Sign") <= 3
               or (
                 strings.icontains(.display_text, "Review")
                 // negate benign uses of the "review" term
                 and not (
                   strings.icontains(.display_text, "Review Us")
                   or strings.icontains(.display_text, "leave us a review")
                   or regex.icontains(.display_text, '\bReviews\b')
                   // don't match microsoft quarantine messages
                   or (
                     strings.icontains(.display_text, "Review Message")
                     and (
                       .href_url.domain.domain == "security.microsoft.com"
                       and .href_url.path == "/quarantine"
                     )
                   )
                 )
               )
               or strings.icontains(.display_text, "document")
               or strings.icontains(.display_text, "docusign")
               or strings.icontains(.display_text, "Review on Docusign")
               or strings.icontains(.display_text, "view form")
               or (
                 strings.icontains(.display_text, "Sign")
                 and regex.icontains(.display_text, '(?:in\b|now)')
               )
               or (
                 strings.icontains(.display_text, "Download")
                 and (
                   strings.icontains(.display_text, "File")
                   or strings.icontains(.display_text, "Document")
                 )
               )
               or strings.icontains(.display_text, "complete tasks")
               or strings.icontains(.display_text, "View and complete")
             )
      ),
      // ensure those links aren't legit
      not .href_url.domain.root_domain in (
        "docusign.com",
        "docusign.net",
        'docusign.co.uk',
        'docusign.com.br',
        'docusign.fr',
        // other e-signature companies which use simliar wording
        "insuresign.com",
        "clixsign.com",
        "esignlive.com",
        "clickcontracts.com",
        "adobesign.com",
        "hellosign.com",
      )
      and not (
        .href_url.domain.root_domain == "mimecastprotect.com"
        and (
          .href_url.query_params is not null
          and regex.icontains(.href_url.query_params,
                              'domain=(?:\w+\.)?docusign.(?:net|com|co\.uk|com\.br|fr)',
                              // other e-signature companies
                              'domain=(?:\w+\.)?(?:insuresign\.com|clixsign\.com|esignlive\.com|clickcontracts\.com|adobesign\.com|hellosign\.com)'
          )
        )
      )
  )
  // Suspicious attachment
  or any(attachments,
         (
           .file_extension in~ ("html", "htm", "shtml", "dhtml")
           or .file_extension in~ $file_extensions_common_archives
           or .file_type == "html"
           or .content_type == "text/html"
         )
         and 1 of (
           (
             regex.icontains(file.parse_html(.).raw, '\s{0,}<script.*')
             and regex.icontains(file.parse_html(.).raw, "</script>")
           ),
           strings.ilike(file.parse_html(.).raw,
                         "*createElement*",
                         "*appendChild*",
                         "*createObjectURL*"
           ),
           strings.icount(file.parse_html(.).raw, "/*") > 10,
           any($free_subdomain_hosts, strings.icontains(..file_name, .))
         )
  )
)

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

// negation for messages traversing docusign.net
// happens with custom sender domains
and not (
  any(headers.domains, .root_domain == "docusign.net")
  and headers.auth_summary.spf.pass
  and headers.auth_summary.dmarc.pass
)

// adding negation for messages originating from docusigns api
// and the sender.display.name contains "via"
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")
)

Detection logic

Scope: inbound message.

Attack impersonating a DocuSign request for signature.

  1. inbound message
  2. any of:
    • sender.email.email matches any of 2 patterns
      • *docusign.net*
      • *docusign.com*
    • sender.display_name matches '*docusign*'
    • sender.display_name is similar to 'docusign'
    • sender.display_name matches any of 2 patterns
      • *docuonline*
      • *via *signature*
    • all of:
      • body.html.inner_text starts with 'docusign'
      • not:
        • body.current_thread.text starts with 'docusign'
    • all of:
      • body.current_thread.text matches '\\bdocu.?sign\\b'
      • any of:
        • body.current_thread.text starts with 'DOCUSIGN\\n'
        • body.current_thread.text matches "You(?:'ve| have) received a ([^\\\\s]+\\\\s)?document"
        • body.current_thread.text contains 'a document to review and sign'
        • body.current_thread.text contains 'A document is available for you'
        • body.current_thread.text contains 'a document ready for you'
        • body.current_thread.text contains 'This email contains a secure link to DocuSign'
        • body.current_thread.text contains 'All parties have completed with Docusign'
        • body.current_thread.text contains 'the signing of this document has been completed'
        • body.current_thread.text contains 'Please use the link above to Docusign'
        • body.current_thread.text contains 'Review on Docusign'
        • body.current_thread.text contains 'Completed with Docusign'
        • body.current_thread.text contains 'Completed on Docusign'
        • body.current_thread.text contains 'Complete with Docusign'
        • body.current_thread.text contains 'please review and complete with DocuSign'
        • body.current_thread.text contains 'We appreciate you choosing DocuSign'
        • body.current_thread.text contains 'A document has been sent to you for'
        • body.current_thread.text contains 'Please Sign docusign'
        • body.current_thread.text contains 'This email was sent via DocuSign'
        • body.current_thread.text contains 'This email was sent to you via DocuSign'
        • body.current_thread.text contains 'This message was sent via DocuSign'
        • body.current_thread.text contains 'This message was sent to you via DocuSign'
        • body.current_thread.text contains 'review via DocuSign Electronic Signature'
        • body.current_thread.text contains 'sent to you by DocuSign'
        • body.current_thread.text contains 'Processed by DocuSign'
        • body.current_thread.text contains 'Please read and sign the document'
        • body.current_thread.text contains 'Please kindly review and sign the '
        • body.current_thread.text contains 'Your document is pending review and signature'
        • body.current_thread.text contains 'pending document for your signature'
        • body.current_thread.text contains 'your review and signature'
        • body.current_thread.text contains 'a pending document for'
        • body.current_thread.text contains 'Your document is ready'
        • body.current_thread.text contains 'This email is automatically generated by DocuSign'
        • body.current_thread.text contains 'Your document has been completed'
        • body.current_thread.text matches any of 4 patterns
          • Review\s*(?:and\s*|&\s*)Sign.{0,40}docusign
          • docusign.{0,40}Review\s*(?:and\s*|&\s*)Sign
          • Sign\s*(?:and\s*|&\s*)Return.{0,40}docusign
          • Sign\s*(?:and\s*|&\s*)Return.docusign.{0,40}
        • subject.subject contains 'complete with docusign'
        • subject.subject contains 'signature request'
        • subject.subject matches 'Review\\s*(?:and\\s*|&\\s*)Sign'
        • subject.subject matches 'Sign\\s*(?:and\\s*|&\\s*)Return'
        • subject.subject contains 'Please Docusign'
        • subject.subject contains 'Docusign has sent'
    • all of:
      • not:
        • any of headers.references where all hold:
          • . ends with 'docusign.net'
          • . matches '[0-9a-f]{32}@(?:[^\\.]+\\.)?docusign.net'
      • any of:
        • all of:
          • sender.display_name is set
          • sender.display_name matches '\\bdocu\\b'
          • sender.display_name contains 'sign'
        • all of:
          • subject.subject is set
          • subject.subject matches '\\bdocu\\b'
          • subject.subject contains 'sign'
        • all of:
          • any of:
            • body.html.raw matches 'Powered by.{0,6}(?:\\s*<\\/?[^\\>]+\\>\\s*)+<img[^\\>]+(?:src="https:\\/\\/docucdn-a\\.akamaihd\\.net\\/[^\\"]+email-logo.png"|alt="DocuSign")'
            • body.current_thread.text matches 'Powered by\\s*DocuSign'
          • body.current_thread.text contains 'Powered by'
        • body.current_thread.text contains 'using the Docusign Electronic Signature Service'
        • body.current_thread.text contains 'who uses the DocuSign Electronic Signature Service'
        • body.current_thread.text contains 'Thank you for choosing DocuSign'
        • all of:
          • any of:
            • body.current_thread.text contains 'Alternate Signing Method'
            • body.current_thread.text contains 'Alternative Access'
          • body.current_thread.text matches "(?:Click|Select) 'Access Documents', and enter "
        • all of:
          • body.current_thread.text contains 'Please do not share this email, link, or access code with others'
          • not:
            • sender.email.domain.root_domain in ('insuresign.com', 'clixsign.com', 'esignlive.com', 'clickcontracts.com', 'sadq.sa', 'vasion.com', 'chubb.com')
        • all of:
          • body.current_thread.text contains 'Docusign provides a '
          • body.current_thread.text contains 'solution for Digital Transaction Management'
        • body.current_thread.text contains 'a secure link to DocuSign'
        • all of:
          • length(filter(body.links, .href_url.domain.domain == 'support.docusign.com' and strings.contains(.href_url.path, '/articles/') or .href_url.domain.domain == 'community.docusign.com' or .href_url.domain.domain == 'protect.docusign.com' or .href_url.domain.domain == 'app.esign.docusign.com')) ≥ 2
          • body.current_thread.text contains any of 9 patterns
            • Declining to sign
            • Managing notifications
            • How to Sign a Document
            • Docusign Support Center
            • Report this email
            • Docusign Community
            • Connect with our support team
            • Unsubscribe
            • Manage Preferences
    • all of:
      • any of:
        • body.html.raw matches '<font size="?[0-9]"?[^\\>]*>DocuSign</font>'
        • body.html.raw matches '\\nDocu(?:<[^\\>]+>\\s*)+Sign<'
        • body.html.raw matches '<span[^>]*style="[^"]*">Docu.?Sign<\\/span>'
        • any of html.xpath(body.html, '//h1').nodes where:
          • .display_text matches 'Docu.?Sign'
        • body.html.raw matches '<span[^>]*style="[^"]*">(Docu|D(?:ocu?)?)<\\/span>(?:<[^\\>]+\\>){0,2}<span[^>]*style="[^"]*">(Sign|S(?:ign?)?)<\\/span>'
        • any of html.xpath(body.html, '//strong').nodes where:
          • .display_text matches 'Docu.?Sign'
        • any of html.xpath(body.html, '//title').nodes where:
          • .display_text matches '^docu.?sign'
        • any of html.xpath(body.html, '//div[@class="logo"]').nodes where:
          • .display_text contains 'Docusign'
        • any of html.xpath(body.html, '//img/@alt').nodes where:
          • .raw is 'docusign'
        • any of regex.iextract(body.html.raw) where:
          • .full_match is not 'docusign'
        • any of regex.iextract(body.html.raw) where:
          • .full_match is not 'docusign'
        • any of regex.iextract(body.html.raw) where:
          • .full_match is not 'docusign'
        • any of regex.iextract(body.html.raw) where:
          • .full_match is not 'docusign'
      • any of:
        • body.html.raw matches any of 2 patterns
          • b(?:ackground(?:-color)?|g?color):\s*rgb\(30,\s*76,\s*161\)
          • b(?:ackground(?:-color)?|g?color):\s*rgb\(61,\s*170,\s*73\)
        • body.html.raw matches '<(?:div|td|table)[^>]*b(?:ackground(?:-color)?|g?color)(?::|=)\\s*\\"?#1e4ca1[^>]*>'
        • body.html.raw matches 'b(?:ackground(?:-color)?|g?color)(?::|=)\\s*\\"?#(?:214e9f|3260a7|0056b3|1e4ca1|214395|325bb8|3c60ad)'
    • all of:
      • body.current_thread.text contains 'Docusign'
      • any of:
        • body.html.raw matches '<title>[^<]*Easearch[^<]*</title>'
        • body.html.raw matches '<spacing>[^<]*(?:Docusign|Document)'
        • body.html.raw matches '{(?:domain|randomNumber\\d?)}'
  3. any of:
    • any of filter(body.links) where all hold:
      • not:
        • .href_url.domain.root_domain in ('docusign.com', 'docusign.net', 'docusign.co.uk', 'docusign.com.br', 'docusign.fr', 'insuresign.com', 'clixsign.com', 'esignlive.com', 'clickcontracts.com', 'adobesign.com', 'hellosign.com')
      • not:
        • all of:
          • .href_url.domain.root_domain is 'mimecastprotect.com'
          • all of:
            • .href_url.query_params is set
            • .href_url.query_params matches any of 2 patterns
              • domain=(?:\w+\.)?docusign.(?:net|com|co\.uk|com\.br|fr)
              • domain=(?:\w+\.)?(?:insuresign\.com|clixsign\.com|esignlive\.com|clickcontracts\.com|adobesign\.com|hellosign\.com)
    • any of attachments where all hold:
      • any of:
        • .file_extension in ('html', 'htm', 'shtml', 'dhtml')
        • .file_extension in $file_extensions_common_archives
        • .file_type is 'html'
        • .content_type is 'text/html'
      • at least 1 of:
        • all of:
          • file.parse_html(.).raw matches '\\s{0,}<script.*'
          • file.parse_html(.).raw matches '</script>'
        • file.parse_html(.).raw matches any of 3 patterns
          • *createElement*
          • *appendChild*
          • *createObjectURL*
        • strings.icount(file.parse_html(.).raw, '/*') > 10
        • any of $free_subdomain_hosts where:
          • strings.icontains(.file_name)
  4. not:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • coalesce(headers.auth_summary.dmarc.pass)
  5. not:
    • all of:
      • any of headers.domains where:
        • .root_domain is 'docusign.net'
      • headers.auth_summary.spf.pass
      • headers.auth_summary.dmarc.pass
  6. 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'

Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_name, attachments[].file_type, body.current_thread.text, body.html, body.html.inner_text, body.html.raw, body.links, body.links[].display_text, body.links[].href_url.domain.domain, body.links[].href_url.path, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.domains, headers.domains[].root_domain, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, headers.references, sender.display_name, sender.email.domain.root_domain, sender.email.email, subject.subject, type.inbound. Sensors: file.parse_html, html.xpath, regex.icontains, regex.iextract, regex.imatch, strings.contains, strings.ends_with, strings.icontains, strings.icount, strings.iends_with, strings.ilevenshtein, strings.ilike, strings.istarts_with. Reference lists: $file_extensions_common_archives, $free_subdomain_hosts, $high_trust_sender_root_domains.

Indicators matched (124)

FieldMatchValue
strings.ilikesubstring*docusign.net*
strings.ilikesubstring*docusign.com*
strings.ilikesubstring*docusign*
strings.ilevenshteinfuzzydocusign
strings.ilikesubstring*docuonline*
strings.ilikesubstring*via *signature*
strings.istarts_withprefixdocusign
regex.icontainsregex\bdocu.?sign\b
strings.istarts_withprefixDOCUSIGN\n
regex.icontainsregexYou(?:'ve| have) received a ([^\\s]+\\s)?document
strings.icontainssubstringa document to review and sign
strings.icontainssubstringA document is available for you
112 more
strings.icontainssubstringa document ready for you
strings.icontainssubstringThis email contains a secure link to DocuSign
strings.icontainssubstringAll parties have completed with Docusign
strings.icontainssubstringthe signing of this document has been completed
strings.icontainssubstringPlease use the link above to Docusign
strings.icontainssubstringReview on Docusign
strings.icontainssubstringCompleted with Docusign
strings.icontainssubstringCompleted on Docusign
strings.icontainssubstringComplete with Docusign
strings.icontainssubstringplease review and complete with DocuSign
strings.icontainssubstringWe appreciate you choosing DocuSign
strings.icontainssubstringA document has been sent to you for
strings.icontainssubstringPlease Sign docusign
strings.icontainssubstringThis email was sent via DocuSign
strings.icontainssubstringThis email was sent to you via DocuSign
strings.icontainssubstringThis message was sent via DocuSign
strings.icontainssubstringThis message was sent to you via DocuSign
strings.icontainssubstringreview via DocuSign Electronic Signature
strings.icontainssubstringsent to you by DocuSign
strings.icontainssubstringProcessed by DocuSign
strings.icontainssubstringPlease read and sign the document
strings.icontainssubstringPlease kindly review and sign the
strings.icontainssubstringYour document is pending review and signature
strings.icontainssubstringpending document for your signature
strings.icontainssubstringyour review and signature
strings.icontainssubstringa pending document for
strings.icontainssubstringYour document is ready
strings.icontainssubstringThis email is automatically generated by DocuSign
strings.icontainssubstringYour document has been completed
regex.icontainsregexReview\s*(?:and\s*|&\s*)Sign.{0,40}docusign
regex.icontainsregexdocusign.{0,40}Review\s*(?:and\s*|&\s*)Sign
regex.icontainsregexSign\s*(?:and\s*|&\s*)Return.{0,40}docusign
regex.icontainsregexSign\s*(?:and\s*|&\s*)Return.docusign.{0,40}
strings.icontainssubstringcomplete with docusign
strings.icontainssubstringsignature request
regex.icontainsregexReview\s*(?:and\s*|&\s*)Sign
regex.icontainsregexSign\s*(?:and\s*|&\s*)Return
strings.icontainssubstringPlease Docusign
strings.icontainssubstringDocusign has sent
regex.icontainsregex\bdocu\b
strings.icontainssubstringsign
regex.icontainsregexPowered by.{0,6}(?:\s*<\/?[^\>]+\>\s*)+<img[^\>]+(?:src="https:\/\/docucdn-a\.akamaihd\.net\/[^\"]+email-logo.png"|alt="DocuSign")
regex.icontainsregexPowered by\s*DocuSign
strings.icontainssubstringPowered by
strings.icontainssubstringusing the Docusign Electronic Signature Service
strings.icontainssubstringwho uses the DocuSign Electronic Signature Service
strings.icontainssubstringThank you for choosing DocuSign
strings.icontainssubstringAlternate Signing Method
strings.icontainssubstringAlternative Access
regex.icontainsregex(?:Click|Select) 'Access Documents', and enter
strings.icontainssubstringPlease do not share this email, link, or access code with others
strings.icontainssubstringDocusign provides a
strings.icontainssubstringsolution for Digital Transaction Management
strings.icontainssubstringa secure link to DocuSign
body.links[].href_url.domain.domainequalssupport.docusign.com
strings.containssubstring/articles/
body.links[].href_url.domain.domainequalscommunity.docusign.com
body.links[].href_url.domain.domainequalsprotect.docusign.com
body.links[].href_url.domain.domainequalsapp.esign.docusign.com
strings.icontainssubstringDeclining to sign
strings.icontainssubstringManaging notifications
strings.icontainssubstringHow to Sign a Document
strings.icontainssubstringDocusign Support Center
strings.icontainssubstringReport this email
strings.icontainssubstringDocusign Community
strings.icontainssubstringConnect with our support team
strings.icontainssubstringUnsubscribe
strings.icontainssubstringManage Preferences
regex.icontainsregex<font size="?[0-9]"?[^\>]*>DocuSign</font>
regex.icontainsregex\nDocu(?:<[^\>]+>\s*)+Sign<
regex.icontainsregex<span[^>]*style="[^"]*">Docu.?Sign<\/span>
regex.icontainsregexDocu.?Sign
regex.icontainsregex<span[^>]*style="[^"]*">(Docu|D(?:ocu?)?)<\/span>(?:<[^\>]+\>){0,2}<span[^>]*style="[^"]*">(Sign|S(?:ign?)?)<\/span>
regex.imatchregexDocu.?Sign
regex.icontainsregex^docu.?sign
strings.icontainssubstringDocusign
html.xpath(body.html, '//img/@alt').nodes[].rawequalsdocusign
regex.iextractregex(?:D|&#68;|&#x44;)(?:&#?[0-9a-fA-F]{2,6};|\s|o|о|&#1086;|&#x43e;)(?:&#?[0-9a-fA-F]{2,6};|\s|c|с|&#1089;|&#x441;)u(?:&#?[0-9a-fA-F]{2,6};|\s)?S(?:&#?[0-9a-fA-F]{2,6};|\s|i|і|&#1110;|&#x456;)(?:&#?[0-9a-fA-F]{2,6};|\s|g|ɡ|&#609;|&#x261;)(?:n|&#110;|&#x6e;)
regex.iextractregex(?:[DⅮᎠᗞᗡ𝐃𝐷𝑫𝒟𝓓𝔇𝔻𝕯𝖣])\s*(?:[oοоօ0Ооʘ◯])\s*(?:[cсçҫ¢ϲС])\s*u\s*(?:[sѕЅ5$])\s*(?:[iіІ1l!|])\s*(?:[gǵġģ9ɡ])\s*(?:[nոռℼη𝐧𝑛𝒏𝓃𝓷𝔫𝕟𝖓])
regex.iextractregex(?:D|&#68;|&#x44;)(?:o|о|&#111;|&#x6f;|&#1086;|&#x43e;|&#959;|&#x3bf;)(?:c|с|&#99;|&#x63;|&#1089;|&#x441;|&#1010;|&#231;|&#x67;|&#265;|&#x109;)(?:u|&#117;|&#x75;|&#1091;|&#x443;|&#965;|&#x3c5;)(?:s|&#115;|&#x73;|&#1109;|&#x455;)(?:i|і|&#105;|&#x69;|&#1110;|&#x456;|&#305;|&#x131;)(?:g|&#103;|&#x67;|&#609;|&#x261;|&#287;|&#x11f;)(?:n|&#110;|&#x6e;|&#1085;|&#x43d;|&#951;|&#x3b7;)
regex.iextractregexD(?:&#[0-9]{1,7};)*\p{Mn}*o(?:&#[0-9]{1,7};)*\p{Mn}*c(?:&#[0-9]{1,7};)*\p{Mn}*u(?:&#[0-9]{1,7};)*\p{Mn}*[Ss](?:&#[0-9]{1,7};)*\p{Mn}*i(?:&#[0-9]{1,7};)*\p{Mn}*g(?:&#[0-9]{1,7};)*\p{Mn}*n
regex.icontainsregexb(?:ackground(?:-color)?|g?color):\s*rgb\(30,\s*76,\s*161\)
regex.icontainsregexb(?:ackground(?:-color)?|g?color):\s*rgb\(61,\s*170,\s*73\)
regex.icontainsregex<(?:div|td|table)[^>]*b(?:ackground(?:-color)?|g?color)(?::|=)\s*\"?#1e4ca1[^>]*>
regex.icontainsregexb(?:ackground(?:-color)?|g?color)(?::|=)\s*\"?#(?:214e9f|3260a7|0056b3|1e4ca1|214395|325bb8|3c60ad)
regex.icontainsregex<title>[^<]*Easearch[^<]*</title>
regex.icontainsregex<spacing>[^<]*(?:Docusign|Document)
regex.icontainsregex{(?:domain|randomNumber\d?)}
strings.ilevenshteinfuzzyReview Now
strings.ilevenshteinfuzzyReview and Sign
strings.icontainssubstringReview
strings.icontainssubstringdocument
strings.icontainssubstringdocusign
strings.icontainssubstringview form
strings.icontainssubstringSign
regex.icontainsregex(?:in\b|now)
strings.icontainssubstringDownload
strings.icontainssubstringFile
strings.icontainssubstringDocument
strings.icontainssubstringcomplete tasks
strings.icontainssubstringView and complete
attachments[].file_extensionmemberhtml
attachments[].file_extensionmemberhtm
attachments[].file_extensionmembershtml
attachments[].file_extensionmemberdhtml
attachments[].file_typeequalshtml
attachments[].content_typeequalstext/html
regex.icontainsregex\s{0,}<script.*
regex.icontainsregex</script>
strings.ilikesubstring*createElement*
strings.ilikesubstring*appendChild*
strings.ilikesubstring*createObjectURL*

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(filter(body.links))
      and
        not
          and
            or
              filter(body.links).href_url.query_params regex_match "domain=(?:\\w+\\.)?(?:insuresign\\.com|clixsign\\.com|esignlive\\.com|clickcontracts\\.com|adobesign\\.com|hellosign\\.com)"
              filter(body.links).href_url.query_params regex_match "domain=(?:\\w+\\.)?docusign.(?:net|com|co\\.uk|com\\.br|fr)"
            filter(body.links).href_url.domain.root_domain eq "mimecastprotect.com"
            filter(body.links).href_url.query_params is_not_null
        not
          filter(body.links).href_url.domain.root_domain in ["adobesign.com", "clickcontracts.com", "clixsign.com", "docusign.co.uk", "docusign.com", "docusign.com.br", "docusign.fr", "docusign.net", "esignlive.com", "hellosign.com", "insuresign.com"]
    any(attachments)
      and
        or
          and
            file.parse_html(attachments[]).raw regex_match "</script>"
            file.parse_html(attachments[]).raw regex_match "\\s{0,}<script.*"
          any($free_subdomain_hosts)
            strings.icontains func_call "strings.icontains(attachments[].file_name)"
          file.parse_html(attachments[]).raw match "appendChild"
          file.parse_html(attachments[]).raw match "createElement"
          file.parse_html(attachments[]).raw match "createObjectURL"
          strings.icount func_call "strings.icount(file.parse_html(attachments[]).raw, \"/*\") > 10"
        or
          attachments.content_type eq "text/html"
          attachments.file_extension in ["dhtml", "htm", "html", "shtml"]
          attachments.file_type eq "html"
           macro "attachments[].file_extension in file_extensions_common_archives"
  or
    and
      or
        and
          or
            body.current_thread.text contains "Alternate Signing Method"
            body.current_thread.text contains "Alternative Access"
          body.current_thread.text regex_match "(?:Click|Select) 'Access Documents', and enter "
        and
          or
            body.current_thread.text contains "Connect with our support team"
            body.current_thread.text contains "Declining to sign"
            body.current_thread.text contains "Docusign Community"
            body.current_thread.text contains "Docusign Support Center"
            body.current_thread.text contains "How to Sign a Document"
            body.current_thread.text contains "Manage Preferences"
            body.current_thread.text contains "Managing notifications"
            body.current_thread.text contains "Report this email"
            body.current_thread.text contains "Unsubscribe"
          filter(body.links, .href_url.domain.domain == 'support.docusign.com' and strings.contains(.href_url.path, '/articles/') or .href_url.domain.domain == 'community.docusign.com' or .href_url.domain.domain == 'protect.docusign.com' or .href_url.domain.domain == 'app.esign.docusign.com') length_compare "2"
        and
          or
            body.current_thread.text regex_match "Powered by\\s*DocuSign"
            body.html.raw regex_match "Powered by.{0,6}(?:\\s*<\\/?[^\\>]+\\>\\s*)+<img[^\\>]+(?:src=\"https:\\/\\/docucdn-a\\.akamaihd\\.net\\/[^\\\"]+email-logo.png\"|alt=\"DocuSign\")"
          body.current_thread.text contains "Powered by"
        and
          not
            sender.email.domain.root_domain in ["chubb.com", "clickcontracts.com", "clixsign.com", "esignlive.com", "insuresign.com", "sadq.sa", "vasion.com"]
          body.current_thread.text contains "Please do not share this email, link, or access code with others"
        and
          body.current_thread.text contains "Docusign provides a "
          body.current_thread.text contains "solution for Digital Transaction Management"
        and
          sender.display_name contains "sign"
          sender.display_name is_not_null
          sender.display_name regex_match "\\bdocu\\b"
        and
          subject.subject contains "sign"
          subject.subject is_not_null
          subject.subject regex_match "\\bdocu\\b"
        body.current_thread.text contains "Thank you for choosing DocuSign"
        body.current_thread.text contains "a secure link to DocuSign"
        body.current_thread.text contains "using the Docusign Electronic Signature Service"
        body.current_thread.text contains "who uses the DocuSign Electronic Signature Service"
      not
        any(headers.references)
          and
            headers.references ends_with "docusign.net"
            headers.references regex_match "[0-9a-f]{32}@(?:[^\\.]+\\.)?docusign.net"
    and
      or
        any(html.xpath(body.html, '//div[@class="logo"]').nodes)
          html.xpath(body.html, '//div[@class="logo"]').nodes.display_text contains "Docusign"
        any(html.xpath(body.html, '//h1').nodes)
          html.xpath(body.html, '//h1').nodes.display_text regex_match "Docu.?Sign"
        any(html.xpath(body.html, '//img/@alt').nodes)
          html.xpath(body.html, '//img/@alt').nodes.raw eq "docusign"
        any(html.xpath(body.html, '//strong').nodes)
          html.xpath(body.html, '//strong').nodes.display_text regex_match "Docu.?Sign"
        any(html.xpath(body.html, '//title').nodes)
          html.xpath(body.html, '//title').nodes.display_text regex_match "^docu.?sign"
        any(regex.iextract(body.html.raw))
          regex.iextract(body.html.raw).full_match ne "docusign"
        body.html.raw regex_match "<font size=\"?[0-9]\"?[^\\>]*>DocuSign</font>"
        body.html.raw regex_match "<span[^>]*style=\"[^\"]*\">(Docu|D(?:ocu?)?)<\\/span>(?:<[^\\>]+\\>){0,2}<span[^>]*style=\"[^\"]*\">(Sign|S(?:ign?)?)<\\/span>"
        body.html.raw regex_match "<span[^>]*style=\"[^\"]*\">Docu.?Sign<\\/span>"
        body.html.raw regex_match "\\nDocu(?:<[^\\>]+>\\s*)+Sign<"
      or
        body.html.raw regex_match "<(?:div|td|table)[^>]*b(?:ackground(?:-color)?|g?color)(?::|=)\\s*\\\"?#1e4ca1[^>]*>"
        body.html.raw regex_match "b(?:ackground(?:-color)?|g?color)(?::|=)\\s*\\\"?#(?:214e9f|3260a7|0056b3|1e4ca1|214395|325bb8|3c60ad)"
        body.html.raw regex_match "b(?:ackground(?:-color)?|g?color):\\s*rgb\\(30,\\s*76,\\s*161\\)"
        body.html.raw regex_match "b(?:ackground(?:-color)?|g?color):\\s*rgb\\(61,\\s*170,\\s*73\\)"
    and
      or
        body.current_thread.text contains "A document has been sent to you for"
        body.current_thread.text contains "A document is available for you"
        body.current_thread.text contains "All parties have completed with Docusign"
        body.current_thread.text contains "Complete with Docusign"
        body.current_thread.text contains "Completed on Docusign"
        body.current_thread.text contains "Completed with Docusign"
        body.current_thread.text contains "Please Sign docusign"
        body.current_thread.text contains "Please kindly review and sign the "
        body.current_thread.text contains "Please read and sign the document"
        body.current_thread.text contains "Please use the link above to Docusign"
        body.current_thread.text contains "Processed by DocuSign"
        body.current_thread.text contains "Review on Docusign"
        body.current_thread.text contains "This email contains a secure link to DocuSign"
        body.current_thread.text contains "This email is automatically generated by DocuSign"
        body.current_thread.text contains "This email was sent to you via DocuSign"
        body.current_thread.text contains "This email was sent via DocuSign"
        body.current_thread.text contains "This message was sent to you via DocuSign"
        body.current_thread.text contains "This message was sent via DocuSign"
        body.current_thread.text contains "We appreciate you choosing DocuSign"
        body.current_thread.text contains "Your document has been completed"
        body.current_thread.text contains "Your document is pending review and signature"
        body.current_thread.text contains "Your document is ready"
        body.current_thread.text contains "a document ready for you"
        body.current_thread.text contains "a document to review and sign"
        body.current_thread.text contains "a pending document for"
        body.current_thread.text contains "pending document for your signature"
        body.current_thread.text contains "please review and complete with DocuSign"
        body.current_thread.text contains "review via DocuSign Electronic Signature"
        body.current_thread.text contains "sent to you by DocuSign"
        body.current_thread.text contains "the signing of this document has been completed"
        body.current_thread.text contains "your review and signature"
        body.current_thread.text regex_match "Review\\s*(?:and\\s*|&\\s*)Sign.{0,40}docusign"
        body.current_thread.text regex_match "Sign\\s*(?:and\\s*|&\\s*)Return.docusign.{0,40}"
        body.current_thread.text regex_match "Sign\\s*(?:and\\s*|&\\s*)Return.{0,40}docusign"
        body.current_thread.text regex_match "You(?:'ve| have) received a ([^\\\\s]+\\\\s)?document"
        body.current_thread.text regex_match "docusign.{0,40}Review\\s*(?:and\\s*|&\\s*)Sign"
        body.current_thread.text starts_with "DOCUSIGN\\n"
        subject.subject contains "Docusign has sent"
        subject.subject contains "Please Docusign"
        subject.subject contains "complete with docusign"
        subject.subject contains "signature request"
        subject.subject regex_match "Review\\s*(?:and\\s*|&\\s*)Sign"
        subject.subject regex_match "Sign\\s*(?:and\\s*|&\\s*)Return"
      body.current_thread.text regex_match "\\bdocu.?sign\\b"
    and
      not
        body.current_thread.text starts_with "docusign"
      body.html.inner_text starts_with "docusign"
    and
      or
        body.html.raw regex_match "<spacing>[^<]*(?:Docusign|Document)"
        body.html.raw regex_match "<title>[^<]*Easearch[^<]*</title>"
        body.html.raw regex_match "{(?:domain|randomNumber\\d?)}"
      body.current_thread.text contains "Docusign"
    sender.display_name match "docuonline"
    sender.display_name match "docusign"
    sender.display_name wildcard "*via *signature*"
    sender.email.email match "docusign.com"
    sender.email.email match "docusign.net"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"docusign\") == 1"
  not
    and
      any(headers.hops)
        any(headers.hops.fields)
          and
            headers.hops.fields[].name eq "X-Api-Host"
            headers.hops.fields[].value ends_with "docusign.net"
      sender.display_name contains "via"
  not
    and
      any(headers.domains)
        headers.domains.root_domain eq "docusign.net"
      headers.auth_summary.dmarc.pass eq "true"
      headers.auth_summary.spf.pass eq "true"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.hopsarray_any(no value, null check)excludes:headers.hops
sender.display_namecontainsviaexcludes:sender.display_name field:"sender.display_name" value:"via"
headers.domainsarray_any(no value, null check)excludes:headers.domains
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
headers.auth_summary.spf.passeqtrueexcludes:headers.auth_summary.spf.pass field:"headers.auth_summary.spf.pass" value:"true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textcontains
  • A document has been sent to you for
  • A document is available for you
  • All parties have completed with Docusign
  • Alternate Signing Method
  • Alternative Access
  • Complete with Docusign
  • Completed on Docusign
  • Completed with Docusign
  • Connect with our support team
  • Declining to sign
  • Docusign
  • Docusign Community
  • Docusign Support Center
  • Docusign provides a
  • How to Sign a Document
  • Manage Preferences
  • Managing notifications
  • Please Sign docusign
  • Please do not share this email, link, or access code with others
  • Please kindly review and sign the
  • Please read and sign the document
  • Please use the link above to Docusign
  • Powered by
  • Processed by DocuSign
  • Report this email
  • Review on Docusign
  • Thank you for choosing DocuSign
  • This email contains a secure link to DocuSign
  • This email is automatically generated by DocuSign
  • This email was sent to you via DocuSign
  • This email was sent via DocuSign
  • This message was sent to you via DocuSign
  • This message was sent via DocuSign
  • Unsubscribe
  • We appreciate you choosing DocuSign
  • Your document has been completed
  • Your document is pending review and signature
  • Your document is ready
  • a document ready for you
  • a document to review and sign
  • a pending document for
  • a secure link to DocuSign
  • pending document for your signature
  • please review and complete with DocuSign
  • review via DocuSign Electronic Signature
  • sent to you by DocuSign
  • solution for Digital Transaction Management
  • the signing of this document has been completed
  • using the Docusign Electronic Signature Service
  • who uses the DocuSign Electronic Signature Service
  • your review and signature
field:"body.current_thread.text" kind:contains
body.current_thread.textregex_match
  • (?:Click|Select) 'Access Documents', and enter
  • Powered by\s*DocuSign
  • Review\s*(?:and\s*|&\s*)Sign.{0,40}docusign
  • Sign\s*(?:and\s*|&\s*)Return.docusign.{0,40}
  • Sign\s*(?:and\s*|&\s*)Return.{0,40}docusign
  • You(?:'ve| have) received a ([^\s]+\s)?document
  • \bdocu.?sign\b
  • docusign.{0,40}Review\s*(?:and\s*|&\s*)Sign
field:"body.current_thread.text" kind:regex_match
body.current_thread.textstarts_with
  • DOCUSIGN\n
field:"body.current_thread.text" kind:starts_with value:"DOCUSIGN\n"
body.html.inner_textstarts_with
  • docusign
field:"body.html.inner_text" kind:starts_with value:"docusign"
body.html.rawregex_match
  • <(?:div|td|table)[^>]*b(?:ackground(?:-color)?|g?color)(?::|=)\s*\"?#1e4ca1[^>]*>
  • <font size="?[0-9]"?[^\>]*>DocuSign</font>
  • <spacing>[^<]*(?:Docusign|Document)
  • <span[^>]*style="[^"]*">(Docu|D(?:ocu?)?)<\/span>(?:<[^\>]+\>){0,2}<span[^>]*style="[^"]*">(Sign|S(?:ign?)?)<\/span>
  • <span[^>]*style="[^"]*">Docu.?Sign<\/span>
  • <title>[^<]*Easearch[^<]*</title>
  • Powered by.{0,6}(?:\s*<\/?[^\>]+\>\s*)+<img[^\>]+(?:src="https:\/\/docucdn-a.akamaihd.net\/[^\"]+email-logo.png"|alt="DocuSign")
  • \nDocu(?:<[^\>]+>\s*)+Sign<
  • b(?:ackground(?:-color)?|g?color)(?::|=)\s*\"?#(?:214e9f|3260a7|0056b3|1e4ca1|214395|325bb8|3c60ad)
  • b(?:ackground(?:-color)?|g?color):\s*rgb(30,\s*76,\s*161)
  • b(?:ackground(?:-color)?|g?color):\s*rgb(61,\s*170,\s*73)
  • {(?:domain|randomNumber\d?)}
field:"body.html.raw" kind:regex_match
sender.display_namecontains
  • sign
field:"sender.display_name" kind:contains value:"sign"
sender.display_nameis_not_null
  • (no value, null check)
field:"sender.display_name" kind:is_not_null
sender.display_nameregex_match
  • \bdocu\b
field:"sender.display_name" kind:regex_match value:"\bdocu\b"
sender.display_namewildcard
  • *docuonline*
  • *docusign*
  • *via *signature*
field:"sender.display_name" kind:wildcard
sender.email.emailwildcard
  • *docusign.com*
  • *docusign.net*
field:"sender.email.email" kind:wildcard
subject.subjectcontains
  • Docusign has sent
  • Please Docusign
  • complete with docusign
  • sign
  • signature request
field:"subject.subject" kind:contains
subject.subjectis_not_null
  • (no value, null check)
field:"subject.subject" kind:is_not_null
subject.subjectregex_match
  • Review\s*(?:and\s*|&\s*)Sign
  • Sign\s*(?:and\s*|&\s*)Return
  • \bdocu\b
field:"subject.subject" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: DoorDash

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

Impersonation of the online food ordering and food delivery platform, DoorDash

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  strings.ilike(sender.display_name, '*doordash*')
  or strings.ilevenshtein(sender.display_name, 'doordash') <= 1
  or strings.ilike(sender.email.domain.domain, '*doordash*')
)
and (
  sender.email.domain.root_domain not in~ (
    'doordash.com',
    'cdn4dd.com',
    'doordash.team'
  )
  and sender.email.domain.domain not in~ (
    'ws-doordash.sendbird.com',
    'qemailserver.com',
    'sent-via.netsuite.com'
  )
)
and 0 < length(body.links) < 10
and not all(body.links,
            .href_url.domain.root_domain in (
              'doordash.com',
              'cdn4dd.com',
              'doordash.team'
            )
)
and (
  not profile.by_sender().solicited
  or profile.by_sender().any_messages_malicious_or_spam
)
and not profile.by_sender().any_messages_benign

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

Impersonation of the online food ordering and food delivery platform, DoorDash

  1. inbound message
  2. any of:
    • sender.display_name matches '*doordash*'
    • sender.display_name is similar to 'doordash'
    • sender.email.domain.domain matches '*doordash*'
  3. all of:
    • sender.email.domain.root_domain not in ('doordash.com', 'cdn4dd.com', 'doordash.team')
    • sender.email.domain.domain not in ('ws-doordash.sendbird.com', 'qemailserver.com', 'sent-via.netsuite.com')
  4. all of:
    • length(body.links) > 0
    • length(body.links) < 10
  5. not:
    • all of body.links where:
      • .href_url.domain.root_domain in ('doordash.com', 'cdn4dd.com', 'doordash.team')
  6. any of:
    • not:
      • profile.by_sender().solicited
    • profile.by_sender().any_messages_malicious_or_spam
  7. not:
    • profile.by_sender().any_messages_benign
  8. 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.links, body.links[].href_url.domain.root_domain, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender, strings.ilevenshtein, strings.ilike. Reference lists: $high_trust_sender_root_domains.

Indicators matched (2)

FieldMatchValue
strings.ilikesubstring*doordash*
strings.ilevenshteinfuzzydoordash

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    not
      profile.by_sender func_call "profile.by_sender().solicited"
    profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  or
    sender.display_name match "doordash"
    sender.email.domain.domain match "doordash"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"doordash\") <= 1"
  not
    sender.email.domain.domain in ["qemailserver.com", "sent-via.netsuite.com", "ws-doordash.sendbird.com"]
  not
    sender.email.domain.root_domain in ["cdn4dd.com", "doordash.com", "doordash.team"]
  not
     macro "all(body.links)"
  body.links length_compare "0"
  body.links length_compare "10"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Dotloop

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

Impersonation of Dotloop, a real estate transaction management platform.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  strings.ilike(sender.display_name, '*dotloop*')
  or strings.ilike(sender.email.domain.domain, '*dotloop*')
  or (
    // dotloop logo
    any(html.xpath(body.html, '//img').nodes,
        strings.icontains(.inner_text, 'dotloop')
    )
    and strings.contains(strings.replace_confusables(body.current_thread.text),
                         '(888)-DOTLOOP'
    )
    and 3 of (
      strings.contains(strings.replace_confusables(body.current_thread.text),
                       'DOTLOOP',
      ),
      strings.contains(strings.replace_confusables(body.current_thread.text),
                       '1301 Second Avenue',
      ),
      strings.contains(strings.replace_confusables(body.current_thread.text),
                       'Floor 36',
      ),
      strings.contains(strings.replace_confusables(body.current_thread.text),
                       'Seattle, WA 98101'
      )
    )
  )
)
and sender.email.domain.root_domain not in~ ('dotloop.com', 'showingtime.com')
and (
  (
    profile.by_sender().prevalence in ("new", "outlier")
    and not profile.by_sender().solicited
  )
  or profile.by_sender().any_messages_malicious_or_spam
)
and not profile.by_sender().any_messages_benign

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

Impersonation of Dotloop, a real estate transaction management platform.

  1. inbound message
  2. any of:
    • sender.display_name matches '*dotloop*'
    • sender.email.domain.domain matches '*dotloop*'
    • all of:
      • any of html.xpath(body.html, '//img').nodes where:
        • .inner_text contains 'dotloop'
      • strings.replace_confusables(body.current_thread.text) contains '(888)-DOTLOOP'
      • at least 3 of 4: strings.replace_confusables(body.current_thread.text) contains any of 4 patterns
        • DOTLOOP
        • 1301 Second Avenue
        • Floor 36
        • Seattle, WA 98101
  3. sender.email.domain.root_domain not in ('dotloop.com', 'showingtime.com')
  4. any of:
    • all of:
      • profile.by_sender().prevalence in ('new', 'outlier')
      • not:
        • profile.by_sender().solicited
    • profile.by_sender().any_messages_malicious_or_spam
  5. not:
    • profile.by_sender().any_messages_benign
  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, body.html, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: html.xpath, profile.by_sender, strings.contains, strings.icontains, strings.ilike, strings.replace_confusables. Reference lists: $high_trust_sender_root_domains.

Indicators matched (7)

FieldMatchValue
strings.ilikesubstring*dotloop*
strings.icontainssubstringdotloop
strings.containssubstring(888)-DOTLOOP
strings.containssubstringDOTLOOP
strings.containssubstring1301 Second Avenue
strings.containssubstringFloor 36
strings.containssubstringSeattle, WA 98101

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    and
      any(html.xpath(body.html, '//img').nodes)
        html.xpath(body.html, '//img').nodes.inner_text contains "dotloop"
      or
        strings.replace_confusables(body.current_thread.text) contains "1301 Second Avenue"
        strings.replace_confusables(body.current_thread.text) contains "DOTLOOP"
        strings.replace_confusables(body.current_thread.text) contains "Floor 36"
        strings.replace_confusables(body.current_thread.text) contains "Seattle, WA 98101"
      strings.replace_confusables(body.current_thread.text) contains "(888)-DOTLOOP"
    sender.display_name match "dotloop"
    sender.email.domain.domain match "dotloop"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().solicited"
      profile.by_sender func_call "profile.by_sender().prevalence in (new, outlier)"
    profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  not
    sender.email.domain.root_domain in ["dotloop.com", "showingtime.com"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Dropbox

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

Impersonation of Dropbox, a file sharing service.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • body.links
  • headers
  • headers.auth_summary
  • headers.hops
  • sender.email
  • type

Rule body

type.inbound
and (
  strings.ilike(sender.display_name, '*dropbox*')
  or strings.ilevenshtein(sender.display_name, 'dropbox') <= 1
  or strings.ilike(sender.email.domain.domain, '*dropbox*')
  or any(body.links,
         .display_url.domain.root_domain == "dropbox.com"
         and .mismatched
         and not .href_url.domain.root_domain in (
           "mimecast.com",
           "mimecastprotect.com"
         )
  )
  or regex.icontains(body.current_thread.text,
                     'invited you to view the file ".*" on Dropbox',
                     'dr[o0]pb[o0]x.{0,20}share.{0,20}f[i1|][i1|l]es?',
                     'dropbox sign (?:account|team)'
  )
  // dropbox style button
  or length(html.xpath(body.html,
                       "//a[contains(@style, 'background-color: #0070e0') and contains(@style, 'color: white') and contains(@style, 'width: 210px')  and contains(@style, 'max-width: 210px') and contains(@style, 'border-radius: 4px') and contains(@style, 'text-align: center') and contains(@style, 'font-size: 15px')]"
            ).nodes
  ) == 1
  or any(attachments,
         .file_type not in $file_types_images
         and regex.icontains(.file_name, 'dr[o0]pb[o0]x')
  )
)
and sender.email.domain.root_domain not in~ (
  'dropbox.com',
  'dropboxforum.com',
  'dropboxsign.com'
)
and (
  any(attachments,
      .file_type in $file_types_images
      and any(file.explode(.), strings.ilike(.scan.ocr.raw, "*dropbox*"))
  )
  or any(body.links,
         (
           (
             strings.ilike(.display_text,
                           "*review*",
                           "*sign*",
                           "*view*",
                           "*completed document*",
                           "*open agreement*",
                           "*open document*",
                           "*open file*"
             )
             and not strings.ilike(.display_text, "*view this email in*")
           )
           or (
             .display_text is null
             and .href_url.domain.root_domain in $free_file_hosts
           )
         )
         and (
           .href_url.domain.root_domain != "dropbox.com"
           and any(ml.nlu_classifier(body.current_thread.text).intents,
                   .name == "cred_theft" and .confidence in ("medium", "high")
           )
         )
  )
  or (
    length(ml.logo_detect(file.message_screenshot()).brands) != 0
    and all(ml.logo_detect(file.message_screenshot()).brands,
            .name == "Dropbox"
    )
  )
  or (
    any(attachments,
        .file_type not in $file_types_images
        and regex.icontains(.file_name, 'dr[o0]pb[o0]x')
    )
    and any(ml.nlu_classifier(body.current_thread.text).intents,
            .name == "cred_theft" and .confidence != "low"
    )
  )
)
and sender.email.email not in $recipient_emails

// negate dropbox fax (aka hellofax)
and not sender.email.domain.root_domain == 'hellofax.com'

// negate iCloud Private Message Relay
and not (
  sender.email.domain.domain == "privaterelay.appleid.com"
  or any(headers.hops, any(.fields, .name == "X-ICLOUD-HME"))
)

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

Impersonation of Dropbox, a file sharing service.

  1. inbound message
  2. any of:
    • sender.display_name matches '*dropbox*'
    • sender.display_name is similar to 'dropbox'
    • sender.email.domain.domain matches '*dropbox*'
    • any of body.links where all hold:
      • .display_url.domain.root_domain is 'dropbox.com'
      • .mismatched
      • not:
        • .href_url.domain.root_domain in ('mimecast.com', 'mimecastprotect.com')
    • body.current_thread.text matches any of 3 patterns
      • invited you to view the file ".*" on Dropbox
      • dr[o0]pb[o0]x.{0,20}share.{0,20}f[i1|][i1|l]es?
      • dropbox sign (?:account|team)
    • length(html.xpath(body.html, "//a[contains(@style, 'background-color: #0070e0') and contains(@style, 'color: white') and contains(@style, 'width: 210px') and contains(@style, 'max-width: 210px') and contains(@style, 'border-radius: 4px') and contains(@style, 'text-align: center') and contains(@style, 'font-size: 15px')]").nodes) is 1
    • any of attachments where all hold:
      • .file_type not in $file_types_images
      • .file_name matches 'dr[o0]pb[o0]x'
  3. sender.email.domain.root_domain not in ('dropbox.com', 'dropboxforum.com', 'dropboxsign.com')
  4. any of:
    • any of attachments where all hold:
      • .file_type in $file_types_images
      • any of file.explode(.) where:
        • .scan.ocr.raw matches '*dropbox*'
    • any of body.links where all hold:
      • any of:
        • all of:
          • .display_text matches any of 7 patterns
            • *review*
            • *sign*
            • *view*
            • *completed document*
            • *open agreement*
            • *open document*
            • *open file*
          • not:
            • .display_text matches '*view this email in*'
        • all of:
          • .display_text is missing
          • .href_url.domain.root_domain in $free_file_hosts
      • all of:
        • .href_url.domain.root_domain is not 'dropbox.com'
        • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
          • .name is 'cred_theft'
          • .confidence in ('medium', 'high')
    • all of:
      • length(ml.logo_detect(file.message_screenshot()).brands) is not 0
      • all of ml.logo_detect(file.message_screenshot()).brands where:
        • .name is 'Dropbox'
    • all of:
      • any of attachments where all hold:
        • .file_type not in $file_types_images
        • .file_name matches 'dr[o0]pb[o0]x'
      • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
        • .name is 'cred_theft'
        • .confidence is not 'low'
  5. sender.email.email not in $recipient_emails
  6. not:
    • sender.email.domain.root_domain is 'hellofax.com'
  7. none of:
    • sender.email.domain.domain is 'privaterelay.appleid.com'
    • any of headers.hops where:
      • any of .fields where:
        • .name is 'X-ICLOUD-HME'
  8. 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_name, attachments[].file_type, body.current_thread.text, body.html, body.links, body.links[].display_text, body.links[].display_url.domain.root_domain, body.links[].href_url.domain.root_domain, body.links[].mismatched, headers.auth_summary.dmarc.pass, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: file.explode, file.message_screenshot, html.xpath, ml.logo_detect, ml.nlu_classifier, regex.icontains, strings.ilevenshtein, strings.ilike. Reference lists: $file_types_images, $free_file_hosts, $high_trust_sender_root_domains, $recipient_emails.

Indicators matched (18)

FieldMatchValue
strings.ilikesubstring*dropbox*
strings.ilevenshteinfuzzydropbox
body.links[].display_url.domain.root_domainequalsdropbox.com
regex.icontainsregexinvited you to view the file ".*" on Dropbox
regex.icontainsregexdr[o0]pb[o0]x.{0,20}share.{0,20}f[i1|][i1|l]es?
regex.icontainsregexdropbox sign (?:account|team)
regex.icontainsregexdr[o0]pb[o0]x
strings.ilikesubstring*review*
strings.ilikesubstring*sign*
strings.ilikesubstring*view*
strings.ilikesubstring*completed document*
strings.ilikesubstring*open agreement*
6 more
strings.ilikesubstring*open document*
strings.ilikesubstring*open file*
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.logo_detect(file.message_screenshot()).brands[].nameequalsDropbox

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(body.links)
      and
        or
          and
            or
              body.links.display_text match "completed document"
              body.links.display_text match "open agreement"
              body.links.display_text match "open document"
              body.links.display_text match "open file"
              body.links.display_text match "review"
              body.links.display_text match "sign"
              body.links.display_text match "view"
            not
              body.links.display_text match "view this email in"
          and
            body.links.display_text is_null
             macro "body.links[].href_url.domain.root_domain in free_file_hosts"
        any(ml.nlu_classifier(body.current_thread.text).intents)
          and
            ml.nlu_classifier(body.current_thread.text).intents.confidence in ["high", "medium"]
            ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
        body.links.href_url.domain.root_domain ne "dropbox.com"
    and
      any(attachments)
        and
          attachments.file_name regex_match "dr[o0]pb[o0]x"
           macro "attachments[].file_type not in file_types_images"
      any(ml.nlu_classifier(body.current_thread.text).intents)
        and
          ml.nlu_classifier(body.current_thread.text).intents.confidence ne "low"
          ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
    any(attachments)
      and
        any(file.explode(attachments))
          file.explode(attachments).scan.ocr.raw match "dropbox"
         macro "attachments[].file_type in file_types_images"
    and
      ml.logo_detect(file.message_screenshot()).brands length_compare "0"
       macro "all(ml.logo_detect(file.message_screenshot()).brands)"
  or
    any(body.links)
      and
        not
          body.links.href_url.domain.root_domain in ["mimecast.com", "mimecastprotect.com"]
        body.links.display_url.domain.root_domain eq "dropbox.com"
        body.links.mismatched eq "true"
    any(attachments)
      and
        attachments.file_name regex_match "dr[o0]pb[o0]x"
         macro "attachments[].file_type not in file_types_images"
    body.current_thread.text regex_match "dr[o0]pb[o0]x.{0,20}share.{0,20}f[i1|][i1|l]es?"
    body.current_thread.text regex_match "dropbox sign (?:account|team)"
    body.current_thread.text regex_match "invited you to view the file \".*\" on Dropbox"
    html.xpath(body.html, "//a[contains(@style, 'background-color: #0070e0') and contains(@style, 'color: white') and contains(@style, 'width: 210px')  and contains(@style, 'max-width: 210px') and contains(@style, 'border-radius: 4px') and contains(@style, 'text-align: center') and contains(@style, 'font-size: 15px')]").nodes length_compare "1"
    sender.display_name match "dropbox"
    sender.email.domain.domain match "dropbox"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"dropbox\") <= 1"
  not
    or
      any(headers.hops)
        any(headers.hops.fields)
          headers.hops.fields.name eq "X-ICLOUD-HME"
      sender.email.domain.domain eq "privaterelay.appleid.com"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    sender.email.domain.root_domain eq "hellofax.com"
  not
    sender.email.domain.root_domain in ["dropbox.com", "dropboxforum.com", "dropboxsign.com"]
  type.inbound eq "true"
   macro "sender.email.email not in recipient_emails"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textregex_match
  • dr[o0]pb[o0]x.{0,20}share.{0,20}f[i1|][i1|l]es?
  • dropbox sign (?:account|team)
  • invited you to view the file ".*" on Dropbox
field:"body.current_thread.text" kind:regex_match
sender.display_namewildcard
  • *dropbox*
field:"sender.display_name" kind:wildcard value:"*dropbox*"
sender.email.domain.domainwildcard
  • *dropbox*
field:"sender.email.domain.domain" kind:wildcard value:"*dropbox*"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Exodus

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

Attack impersonating Exodus Wallet.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • sender.email
  • type

Rule body

type.inbound
and (
  strings.ilike(sender.display_name, "*exodus*")
  or (
    strings.ilike(sender.email.domain.root_domain, "*exodus*")
    and network.whois(sender.email.domain).days_old <= 30
  )
)
and sender.email.domain.root_domain not in (
  "exodus.com",
  "exodus.io",
  "exodusescaperoom.com"
)
and sender.email.email not in $recipient_emails
and (
  any(ml.nlu_classifier(body.current_thread.text).intents, .name != "benign")
  or any(ml.nlu_classifier(body.current_thread.text).entities,
         .text == "wallet"
  )
)

Detection logic

Scope: inbound message.

Attack impersonating Exodus Wallet.

  1. inbound message
  2. any of:
    • sender.display_name matches '*exodus*'
    • all of:
      • sender.email.domain.root_domain matches '*exodus*'
      • network.whois(sender.email.domain).days_old ≤ 30
  3. sender.email.domain.root_domain not in ('exodus.com', 'exodus.io', 'exodusescaperoom.com')
  4. sender.email.email not in $recipient_emails
  5. any of:
    • any of ml.nlu_classifier(body.current_thread.text).intents where:
      • .name is not 'benign'
    • any of ml.nlu_classifier(body.current_thread.text).entities where:
      • .text is 'wallet'

Inspects: body.current_thread.text, sender.display_name, sender.email.domain, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: ml.nlu_classifier, network.whois, strings.ilike. Reference lists: $recipient_emails.

Indicators matched (2)

FieldMatchValue
strings.ilikesubstring*exodus*
ml.nlu_classifier(body.current_thread.text).entities[].textequalswallet

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(ml.nlu_classifier(body.current_thread.text).entities)
      ml.nlu_classifier(body.current_thread.text).entities.text eq "wallet"
    any(ml.nlu_classifier(body.current_thread.text).intents)
      ml.nlu_classifier(body.current_thread.text).intents.name ne "benign"
  or
    and
      network.whois func_call "network.whois(sender.email.domain).days_old <= 30"
      sender.email.domain.root_domain match "exodus"
    sender.display_name match "exodus"
  not
    sender.email.domain.root_domain in ["exodus.com", "exodus.io", "exodusescaperoom.com"]
  type.inbound eq "true"
   macro "sender.email.email not in recipient_emails"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Fastway

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

Impersonation of Fastway Couriers, a delivery services company in Ireland and South Africa.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  strings.ilike(sender.display_name, '*fastway*')
  or strings.ilevenshtein(sender.display_name, 'fastway couriers') <= 1
)
and sender.email.domain.root_domain not in~ (
  'fastway.co.za',
  'fastway.com.au',
  'fastway.ie'
)

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

// and no false positives and not solicited
and (
  not profile.by_sender().any_messages_benign
  and not profile.by_sender().solicited
)

Detection logic

Scope: inbound message.

Impersonation of Fastway Couriers, a delivery services company in Ireland and South Africa.

  1. inbound message
  2. any of:
    • sender.display_name matches '*fastway*'
    • sender.display_name is similar to 'fastway couriers'
  3. sender.email.domain.root_domain not in ('fastway.co.za', 'fastway.com.au', 'fastway.ie')
  4. 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
  5. all of:
    • not:
      • profile.by_sender().any_messages_benign
    • not:
      • profile.by_sender().solicited

Inspects: headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender, strings.ilevenshtein, strings.ilike. Reference lists: $high_trust_sender_root_domains.

Indicators matched (2)

FieldMatchValue
strings.ilikesubstring*fastway*
strings.ilevenshteinfuzzyfastway couriers

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  not
    profile.by_sender func_call "profile.by_sender().solicited"
  or
    sender.display_name match "fastway"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"fastway couriers\") <= 1"
  not
    sender.email.domain.root_domain in ["fastway.co.za", "fastway.com.au", "fastway.ie"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

Brand impersonation: FedEx

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

Impersonation of the shipping provider FedEx.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  sender.display_name in~ ('fedex', 'fedex shipment', 'fedex tracking updates')
  or strings.ilevenshtein(sender.display_name, 'fedex') <= 1
  or regex.icontains(sender.display_name, '^Fed-?ex')
  or strings.ilike(sender.email.domain.domain, '*fedex*')
  or (
    any(ml.logo_detect(file.message_screenshot()).brands, .name == "FedEx")
    and (
      any(ml.nlu_classifier(body.current_thread.text).entities,
          .name == "request" and strings.icontains(.text, "signature")
      )
      or strings.istarts_with(body.current_thread.text, 'FedEx')
    )
  )
  or 2 of (
    strings.icontains(body.current_thread.text, "FedEx"),
    strings.icontains(body.current_thread.text, "942 South Shady Grove Road"),
    strings.icontains(body.current_thread.text, "3620 Hacks Cross Road"),
    strings.icontains(body.current_thread.text, "Memphis, TN")
  )
)
and not (
  sender.email.domain.root_domain in~ (
    'fedex.com',
    'fedexfreight.com', // added 2026-05-08
    'cj.com', // CJ is a global affiliate marketing network
    'sedex.com', // sedex.com is not affiliated with FedEx, but is an apparent FP
    'myworkday.com',
    'billtrust.com',
    'flying-cargo.rs', // Serbian arm of Fedex (https://www.fedex.com/en-rs/customer-support.html)
    'confirmit.com', // survey/market research company
    'centercode.com' // survey company
  )
  and coalesce(headers.auth_summary.dmarc.pass, false)
)
and (
  not profile.by_sender().any_messages_benign
  and not profile.by_sender().solicited
)

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

Impersonation of the shipping provider FedEx.

  1. inbound message
  2. any of:
    • sender.display_name in ('fedex', 'fedex shipment', 'fedex tracking updates')
    • sender.display_name is similar to 'fedex'
    • sender.display_name matches '^Fed-?ex'
    • sender.email.domain.domain matches '*fedex*'
    • all of:
      • any of ml.logo_detect(file.message_screenshot()).brands where:
        • .name is 'FedEx'
      • any of:
        • any of ml.nlu_classifier(body.current_thread.text).entities where all hold:
          • .name is 'request'
          • .text contains 'signature'
        • body.current_thread.text starts with 'FedEx'
    • at least 2 of 4: body.current_thread.text contains any of 4 patterns
      • FedEx
      • 942 South Shady Grove Road
      • 3620 Hacks Cross Road
      • Memphis, TN
  3. not:
    • all of:
      • sender.email.domain.root_domain in ('fedex.com', 'fedexfreight.com', 'cj.com', 'sedex.com', 'myworkday.com', 'billtrust.com', 'flying-cargo.rs', 'confirmit.com', 'centercode.com')
      • coalesce(headers.auth_summary.dmarc.pass)
  4. all of:
    • not:
      • profile.by_sender().any_messages_benign
    • not:
      • profile.by_sender().solicited
  5. 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, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: file.message_screenshot, ml.logo_detect, ml.nlu_classifier, profile.by_sender, regex.icontains, strings.icontains, strings.ilevenshtein, strings.ilike, strings.istarts_with. Reference lists: $high_trust_sender_root_domains.

Indicators matched (14)

FieldMatchValue
sender.display_namememberfedex
sender.display_namememberfedex shipment
sender.display_namememberfedex tracking updates
strings.ilevenshteinfuzzyfedex
regex.icontainsregex^Fed-?ex
strings.ilikesubstring*fedex*
ml.logo_detect(file.message_screenshot()).brands[].nameequalsFedEx
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsrequest
strings.icontainssubstringsignature
strings.istarts_withprefixFedEx
strings.icontainssubstringFedEx
strings.icontainssubstring942 South Shady Grove Road
2 more
strings.icontainssubstring3620 Hacks Cross Road
strings.icontainssubstringMemphis, TN

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      or
        any(ml.nlu_classifier(body.current_thread.text).entities)
          and
            ml.nlu_classifier(body.current_thread.text).entities.name eq "request"
            ml.nlu_classifier(body.current_thread.text).entities.text contains "signature"
        body.current_thread.text starts_with "FedEx"
      any(ml.logo_detect(file.message_screenshot()).brands)
        ml.logo_detect(file.message_screenshot()).brands.name eq "FedEx"
    body.current_thread.text contains "3620 Hacks Cross Road"
    body.current_thread.text contains "942 South Shady Grove Road"
    body.current_thread.text contains "FedEx"
    body.current_thread.text contains "Memphis, TN"
    sender.display_name in ["fedex", "fedex shipment", "fedex tracking updates"]
    sender.display_name regex_match "^Fed-?ex"
    sender.email.domain.domain match "fedex"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"fedex\") <= 1"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
      sender.email.domain.root_domain in ["billtrust.com", "centercode.com", "cj.com", "confirmit.com", "fedex.com", "fedexfreight.com", "flying-cargo.rs", "myworkday.com", "sedex.com"]
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  not
    profile.by_sender func_call "profile.by_sender().solicited"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaininbilltrust.com, centercode.com, cj.com, confirmit.com, fedex.com, fedexfreight.com, flying-cargo.rs, myworkday.com, sedex.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: FINRA

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

Impersonation of the Financial Industry Regulatory Authority (FINRA)

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • sender.email
  • type

Rule body

type.inbound
and (
  strings.ilevenshtein(sender.display_name, 'finra') <= 1
  or strings.ilevenshtein(sender.email.domain.sld, 'finra') <= 1
)
and any(ml.nlu_classifier(body.current_thread.text).entities,
        .name == "financial"
)
and length(ml.nlu_classifier(body.current_thread.text).intents) > 0
and sender.email.domain.root_domain not in~ (
  'finra.org',
  'finrax.com',
  'finca.wine', // a wine company
  'finta.com' // unrelated domain caught by levenshtein 
)
and (
  (
    profile.by_sender().prevalence in ("new", "outlier")
    and not profile.by_sender().solicited
  )
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)

Detection logic

Scope: inbound message.

Impersonation of the Financial Industry Regulatory Authority (FINRA)

  1. inbound message
  2. any of:
    • sender.display_name is similar to 'finra'
    • sender.email.domain.sld is similar to 'finra'
  3. any of ml.nlu_classifier(body.current_thread.text).entities where:
    • .name is 'financial'
  4. length(ml.nlu_classifier(body.current_thread.text).intents) > 0
  5. sender.email.domain.root_domain not in ('finra.org', 'finrax.com', 'finca.wine', 'finta.com')
  6. any of:
    • all of:
      • profile.by_sender().prevalence in ('new', 'outlier')
      • not:
        • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign

Inspects: body.current_thread.text, sender.display_name, sender.email.domain.root_domain, sender.email.domain.sld, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender, strings.ilevenshtein.

Indicators matched (2)

FieldMatchValue
strings.ilevenshteinfuzzyfinra
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsfinancial

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    and
      not
        profile.by_sender func_call "profile.by_sender().solicited"
      profile.by_sender func_call "profile.by_sender().prevalence in (new, outlier)"
  any(ml.nlu_classifier(body.current_thread.text).entities)
    ml.nlu_classifier(body.current_thread.text).entities.name eq "financial"
  not
    sender.email.domain.root_domain in ["finca.wine", "finra.org", "finrax.com", "finta.com"]
  or
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"finra\") <= 1"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.email.domain.sld, \"finra\") <= 1"
  ml.nlu_classifier(body.current_thread.text).intents length_compare "0"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaininfinca.wine, finra.org, finrax.com, finta.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Github

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

Impersonation of Github.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.auth_summary
  • headers.hops
  • sender.email
  • subject
  • type

Rule body

type.inbound
and not strings.ilike(sender.display_name,
                      '*course*',
                      '*bootcamp*',
                      '*training*'
)
and (
  strings.ilike(sender.display_name, '*github*')
  or strings.ilike(sender.email.email, '*github*')
  or strings.ilevenshtein(sender.email.domain.sld, 'github') <= 1
)
// negating listservs
and not (
  any(headers.hops, any(.fields, .name == "List-Unsubscribe"))
  and (
    strings.contains(sender.display_name, "via")
    or strings.icontains(subject.subject, "monitor")
  )
)
and not (
  any(headers.hops, any(.fields, .name == "X-GitHub-Reason"))
  and headers.auth_summary.dmarc.pass
)
and sender.email.domain.root_domain not in (
  'github.com',
  'thegithubshop.com',
  'gitlab.com',
  'itthub.net',
  'githubsupport.com',
  'gtmhub.com',
  'githubstatus.com',
  'githubnext.com',
  'lithub.com',
  'icims.com',
  'bithub.email',
  'goldcast.io',
  'luma-mail.com', // GitHub's event invitation software
  'github.events' // GitHub event newsletters
)

// 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
)
and (
  not profile.by_sender().solicited
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

Impersonation of Github.

  1. inbound message
  2. not:
    • sender.display_name matches any of 3 patterns
      • *course*
      • *bootcamp*
      • *training*
  3. any of:
    • sender.display_name matches '*github*'
    • sender.email.email matches '*github*'
    • sender.email.domain.sld is similar to 'github'
  4. not:
    • all of:
      • any of headers.hops where:
        • any of .fields where:
          • .name is 'List-Unsubscribe'
      • any of:
        • sender.display_name contains 'via'
        • subject.subject contains 'monitor'
  5. not:
    • all of:
      • any of headers.hops where:
        • any of .fields where:
          • .name is 'X-GitHub-Reason'
      • headers.auth_summary.dmarc.pass
  6. sender.email.domain.root_domain not in ('github.com', 'thegithubshop.com', 'gitlab.com', 'itthub.net', 'githubsupport.com', 'gtmhub.com', 'githubstatus.com', 'githubnext.com', 'lithub.com', 'icims.com', 'bithub.email', 'goldcast.io', 'luma-mail.com', 'github.events')
  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
  8. any of:
    • not:
      • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  9. not:
    • profile.by_sender().any_messages_benign

Inspects: headers.auth_summary.dmarc.pass, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, sender.display_name, sender.email.domain.root_domain, sender.email.domain.sld, sender.email.email, subject.subject, type.inbound. Sensors: profile.by_sender, strings.contains, strings.icontains, strings.ilevenshtein, strings.ilike. Reference lists: $high_trust_sender_root_domains.

Indicators matched (2)

FieldMatchValue
strings.ilikesubstring*github*
strings.ilevenshteinfuzzygithub

Stages and Predicates

Stage 1: mql_rule

and
  not
    and
      any(headers.hops)
        any(headers.hops.fields)
          headers.hops.fields.name eq "List-Unsubscribe"
      or
        sender.display_name contains "via"
        subject.subject contains "monitor"
  not
    and
      any(headers.hops)
        any(headers.hops.fields)
          headers.hops.fields.name eq "X-GitHub-Reason"
      headers.auth_summary.dmarc.pass eq "true"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    not
      profile.by_sender func_call "profile.by_sender().solicited"
  not
    or
      sender.display_name match "bootcamp"
      sender.display_name match "course"
      sender.display_name match "training"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  or
    sender.display_name match "github"
    sender.email.email match "github"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.email.domain.sld, \"github\") <= 1"
  not
    sender.email.domain.root_domain in ["bithub.email", "github.com", "github.events", "githubnext.com", "githubstatus.com", "githubsupport.com", "gitlab.com", "goldcast.io", "gtmhub.com", "icims.com", "itthub.net", "lithub.com", "luma-mail.com", "thegithubshop.com"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.hopsarray_any(no value, null check)excludes:headers.hops
sender.display_namecontainsviaexcludes:sender.display_name field:"sender.display_name" value:"via"
subject.subjectcontainsmonitorexcludes:subject.subject field:"subject.subject" value:"monitor"
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
sender.display_namematchbootcampexcludes:sender.display_name field:"sender.display_name" value:"bootcamp"
sender.display_namematchcourseexcludes:sender.display_name field:"sender.display_name" value:"course"
sender.display_namematchtrainingexcludes:sender.display_name field:"sender.display_name" value:"training"
sender.email.domain.root_domaininbithub.email, github.com, github.events, githubnext.com, githubstatus.com, githubsupport.com, gitlab.com, goldcast.io, gtmhub.com, icims.com, itthub.net, lithub.com, luma-mail.com, thegithubshop.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Google Drive fake file share

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

This rule detects messages impersonating a Google Drive file sharing email where no links point to known Google domains.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • body.html
  • body.links
  • body.plain
  • body.previous_threads
  • headers
  • headers.auth_summary
  • headers.return_path
  • recipients
  • recipients.cc
  • recipients.to
  • sender.email
  • subject
  • type

Rule body

type.inbound

// Google Drive body content looks like this
and (
  (
    (
      any([body.current_thread.text, body.plain.raw],
          strings.ilike(.,
                        "*shared a file with you*",
                        "*shared with you*",
                        "*invited you to review*",
                        "*received a document*",
                        "*shared a document*",
                        "*shared a spreadsheet*",
                        "*shared this document*",
                        "*shared an item*",
                        "*received this email because you*",
                        "*shared a*with you*",
                        "*automated *mail from google*drive*",
                        "*added as an editor*",
                        "*invited you to edit*"
          )
      )
      //
      // This rule makes use of a beta feature and is subject to change without notice
      // using the beta feature in custom rules is not suggested until it has been formally released
      //
      or strings.ilike(beta.ocr(file.message_screenshot()).text,
                       "*shared a file with you*",
                       "*shared with you*",
                       "*invited you to review*",
                       "*received a document*",
                       "*shared a document*",
                       "*shared a spreadsheet*",
                       "*shared this document*",
                       "*shared an item*",
                       "*received this email because you*",
                       "*shared a*with you*",
                       "*automated *mail from google*drive*",
                       "*added as an editor*",
                       "*invited you to edit*"
      )
      // suspicious subjects
      or (
        (
          regex.icontains(subject.subject, 'shared \".*\" with you')
          and sender.email.domain.root_domain != "dropbox.com"
        )
        // with Google Drive terminology in body content
        and any([body.current_thread.text, body.plain.raw],
                strings.ilike(.,
                              "*Google Drive*",
                              "*Google Doc*",
                              "*Google Sheet*",
                              "*Google Slide*"
                )
        )
      )
    )
    and (
      strings.ilike(subject.subject,
                    "*shared*",
                    "*updated*",
                    "*sign*",
                    "*review*"
      )
      or (
        any(recipients.to,
            strings.icontains(subject.subject, .email.domain.sld)
            or (
              (.email.domain.valid == false)
              and all(recipients.cc, .email.domain.valid == false)
            )
        )
        or length(recipients.to) == 0
      )
      or strings.ilike(subject.subject, "*Docs*", "*Sheets*", "*Slides*")
      or any(body.links,
             strings.icontains(.display_text, "open document")
             or strings.iends_with(.display_text, ".pdf")
             or (
               .display_text =~ "Open"
               and network.whois(.href_url.domain).days_old < 365
             )
             or any(recipients.to,
                    strings.icontains(..display_text, .email.email)
                    or strings.icontains(..display_text, .email.local_part)
             )
      )
      or strings.ilike(sender.display_name, "*Google Drive*")
      or subject.subject is null
      or subject.subject == ""
      or regex.icontains(body.current_thread.text, '^g.o.o.g.l.e')
    )
  )
  or any([
           "Contigo", // Spanish
           "Avec vous", // French
           "Mit Ihnen", // German
           "Con te", // Italian
           "Com você", // Portuguese
           "Met u", // Dutch
           "С вами", // Russian
           "与你", // Chinese (Simplified)
           "與您", // Chinese (Traditional)
           "あなたと", // Japanese
           "당신과", // Korean
           "معك", // Arabic
           "آپ کے ساتھ", // Urdu
           "আপনার সাথে", // Bengali
           "आपके साथ", // Hindi
           "Sizinle", // Turkish // Azerbaijani
           "Med dig", // Swedish
           "Z tobą", // Polish
           "З вами", // Ukrainian
           "Önnel", // Hungarian
           "Μαζί σας", // Greek
           "איתך", // Hebrew
           "กับคุณ", // Thai
           "Với bạn", // Vietnamese
           "Dengan Anda", // Indonesian // Malay
           "Nawe", // Swahili
           "Cu dumneavoastră", // Romanian
           "S vámi", // Czech
           "Med deg", // Norwegian
           "S vami", // Slovak
           "Med dig", // Danish
           "Amb vostè", // Catalan
           "Teiega", // Estonian
           "S vama", // Serbian
         ],
         strings.icontains(subject.subject, .)
  )
)

// contains logic that impersonates Google
and (
  any(ml.logo_detect(file.message_screenshot()).brands,
      strings.starts_with(.name, "Google")
  )
  // Google Drive share box formatting
  or strings.icontains(body.html.raw,
                       '<table style="width:100%; border:1px solid #dadce0; border-radius:6px; border-spacing:0; border-collapse:separate; table-layout:fixed" role="presentation">'
  )
  or any(attachments,
         .file_type in $file_types_images
         and (
           any(ml.logo_detect(.).brands, strings.starts_with(.name, "Google"))
           or strings.icontains(beta.ocr(.).text,
                                strings.concat("You have received this email because ",
                                               sender.email.email,
                                               " shared a document with you"
                                )
           )
           or strings.icontains(beta.ocr(.).text,
                                strings.concat("You have received this email because ",
                                               sender.email.email,
                                               " received a file or folder"
                                )
           )
           or any(recipients.to,
                  strings.icontains(beta.ocr(..).text,
                                    strings.concat("You have received this email because ",
                                                   .email.email,
                                                   " shared a document with you"
                                    )
                  )
           )
           or any(recipients.to,
                  strings.icontains(beta.ocr(..).text,
                                    strings.concat("You have received this email because ",
                                                   .email.email,
                                                   " received a file or folder"
                                    )
                  )
           )
           or strings.icontains(beta.ocr(.).text,
                                strings.concat(sender.display_name,
                                               " (",
                                               sender.email.email,
                                               ") ",
                                               "shared"
                                )
           )
         )
  )
  or strings.icontains(body.current_thread.text,
                       strings.concat("You have received this email because ",
                                      sender.email.email,
                                      " shared a document with you"
                       )
  )
  or strings.icontains(body.current_thread.text,
                       strings.concat("You have received this email because ",
                                      sender.email.email,
                                      " received a file or folder"
                       )
  )
  or any(recipients.to,
         strings.icontains(body.current_thread.text,
                           strings.concat("You have received this email because ",
                                          .email.email,
                                          " shared a document with you"
                           )
         )
  )
  or any(recipients.to,
         strings.icontains(body.current_thread.text,
                           strings.concat("You have received this email because ",
                                          .email.email,
                                          " received a file or folder"
                           )
         )
  )
  or strings.icontains(body.current_thread.text,
                       strings.concat(sender.display_name,
                                      " (",
                                      sender.email.email,
                                      ") ",
                                      "shared"
                       )
  )
  // Google address from footer
  or 2 of (
    strings.icontains(body.current_thread.text, 'Google LLC'),
    strings.icontains(body.current_thread.text, '1600 Amphitheatre Parkway'),
    strings.icontains(body.current_thread.text, 'Mountain View, CA 94043'),
  )
)
and not (
  // Google Sites has been observed abused
  all(body.links,
      .href_url.domain.root_domain in ("google.com")
      // allow for matches against sites.google.com, which has been observed being abused
      and .href_url.domain.domain != "sites.google.com"
  )
)
and sender.email.domain.root_domain not in $org_domains
and sender.email.domain.root_domain not in ("google.com")
and not (
  all(headers.references, strings.ends_with(., '@docs-share.google.com'))
  and headers.return_path.domain.domain == "doclist.bounces.google.com"
)
// negate first threads that are a legitimate Google Drive share
and not (
  length(body.previous_threads) != 0
  and length(body.previous_threads[length(body.previous_threads) - 1].links) != 0
  and all(body.previous_threads[length(body.previous_threads) - 1].links,
          .href_url.domain.root_domain == "google.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
)
and (
  profile.by_sender().solicited == false
  or profile.by_sender_email().prevalence == "new"
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

This rule detects messages impersonating a Google Drive file sharing email where no links point to known Google domains.

  1. inbound message
  2. any of:
    • all of:
      • any of:
        • any of [body.current_thread.text, body.plain.raw] where:
          • . matches any of 13 patterns
            • *shared a file with you*
            • *shared with you*
            • *invited you to review*
            • *received a document*
            • *shared a document*
            • *shared a spreadsheet*
            • *shared this document*
            • *shared an item*
            • *received this email because you*
            • *shared a*with you*
            • *automated *mail from google*drive*
            • *added as an editor*
            • *invited you to edit*
        • beta.ocr(file.message_screenshot()).text matches any of 13 patterns
          • *shared a file with you*
          • *shared with you*
          • *invited you to review*
          • *received a document*
          • *shared a document*
          • *shared a spreadsheet*
          • *shared this document*
          • *shared an item*
          • *received this email because you*
          • *shared a*with you*
          • *automated *mail from google*drive*
          • *added as an editor*
          • *invited you to edit*
        • all of:
          • all of:
            • subject.subject matches 'shared \\".*\\" with you'
            • sender.email.domain.root_domain is not 'dropbox.com'
          • any of [body.current_thread.text, body.plain.raw] where:
            • . matches any of 4 patterns
              • *Google Drive*
              • *Google Doc*
              • *Google Sheet*
              • *Google Slide*
      • any of:
        • subject.subject matches any of 4 patterns
          • *shared*
          • *updated*
          • *sign*
          • *review*
        • any of:
          • any of recipients.to where any holds:
            • strings.icontains(subject.subject)
            • all of:
              • .email.domain.valid is False
              • all of recipients.cc where:
                • .email.domain.valid is False
          • length(recipients.to) is 0
        • subject.subject matches any of 3 patterns
          • *Docs*
          • *Sheets*
          • *Slides*
        • any of body.links where any holds:
          • .display_text contains 'open document'
          • .display_text ends with '.pdf'
          • all of:
            • .display_text is 'Open'
            • network.whois(.href_url.domain).days_old < 365
          • any of recipients.to where any holds:
            • strings.icontains(.display_text)
            • strings.icontains(.display_text)
        • sender.display_name matches '*Google Drive*'
        • subject.subject is missing
        • subject.subject is ''
        • body.current_thread.text matches '^g.o.o.g.l.e'
    • any of ['Contigo', 'Avec vous', 'Mit Ihnen', 'Con te', 'Com você', 'Met u', 'С вами', '与你', '與您', 'あなたと', '당신과', 'معك', 'آپ کے ساتھ', 'আপনার সাথে', 'आपके साथ', 'Sizinle', 'Med dig', 'Z tobą', 'З вами', 'Önnel', 'Μαζί σας', 'איתך', 'กับคุณ', 'Với bạn', 'Dengan Anda', 'Nawe', 'Cu dumneavoastră', 'S vámi', 'Med deg', 'S vami', 'Med dig', 'Amb vostè', 'Teiega', 'S vama'] where:
      • strings.icontains(subject.subject)
  3. any of:
    • any of ml.logo_detect(file.message_screenshot()).brands where:
      • .name starts with 'Google'
    • body.html.raw contains '<table style="width:100%; border:1px solid #dadce0; border-radius:6px; border-spacing:0; border-collapse:separate; table-layout:fixed" role="presentation">'
    • any of attachments where all hold:
      • .file_type in $file_types_images
      • any of:
        • any of ml.logo_detect(.).brands where:
          • .name starts with 'Google'
        • strings.icontains(beta.ocr(.).text)
        • strings.icontains(beta.ocr(.).text)
        • any of recipients.to where:
          • strings.icontains(beta.ocr(.).text)
        • any of recipients.to where:
          • strings.icontains(beta.ocr(.).text)
        • strings.icontains(beta.ocr(.).text)
    • strings.icontains(body.current_thread.text)
    • strings.icontains(body.current_thread.text)
    • any of recipients.to where:
      • strings.icontains(body.current_thread.text)
    • any of recipients.to where:
      • strings.icontains(body.current_thread.text)
    • strings.icontains(body.current_thread.text)
    • at least 2 of:
      • body.current_thread.text contains 'Google LLC'
      • body.current_thread.text contains '1600 Amphitheatre Parkway'
      • body.current_thread.text contains 'Mountain View, CA 94043'
  4. not:
    • all of body.links where all hold:
      • .href_url.domain.root_domain in ('google.com')
      • .href_url.domain.domain is not 'sites.google.com'
  5. sender.email.domain.root_domain not in $org_domains
  6. sender.email.domain.root_domain not in ('google.com')
  7. not:
    • all of:
      • all of headers.references where:
        • . ends with '@docs-share.google.com'
      • headers.return_path.domain.domain is 'doclist.bounces.google.com'
  8. not:
    • all of:
      • length(body.previous_threads) is not 0
      • length(body.previous_threads[].links) is not 0
      • all of body.previous_threads[].links where:
        • .href_url.domain.root_domain is 'google.com'
  9. 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
  10. any of:
    • profile.by_sender().solicited is False
    • profile.by_sender_email().prevalence is 'new'
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  11. not:
    • profile.by_sender().any_messages_benign

Inspects: attachments[].file_type, body.current_thread.text, body.html.raw, body.links, body.links[].display_text, body.links[].href_url.domain, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.plain.raw, body.previous_threads, body.previous_threads[].links, body.previous_threads[].links[].href_url.domain.root_domain, headers.auth_summary.dmarc.pass, headers.references, headers.return_path.domain.domain, recipients.cc, recipients.cc[].email.domain.valid, recipients.to, recipients.to[].email.domain.sld, recipients.to[].email.domain.valid, recipients.to[].email.email, recipients.to[].email.local_part, sender.display_name, sender.email.domain.root_domain, sender.email.email, subject.subject, type.inbound. Sensors: beta.ocr, file.message_screenshot, ml.logo_detect, network.whois, profile.by_sender, profile.by_sender_email, regex.icontains, strings.concat, strings.ends_with, strings.icontains, strings.iends_with, strings.ilike, strings.starts_with. Reference lists: $file_types_images, $high_trust_sender_root_domains, $org_domains.

Indicators matched (35)

FieldMatchValue
strings.ilikesubstring*shared a file with you*
strings.ilikesubstring*shared with you*
strings.ilikesubstring*invited you to review*
strings.ilikesubstring*received a document*
strings.ilikesubstring*shared a document*
strings.ilikesubstring*shared a spreadsheet*
strings.ilikesubstring*shared this document*
strings.ilikesubstring*shared an item*
strings.ilikesubstring*received this email because you*
strings.ilikesubstring*shared a*with you*
strings.ilikesubstring*automated *mail from google*drive*
strings.ilikesubstring*added as an editor*
23 more
strings.ilikesubstring*invited you to edit*
regex.icontainsregexshared \".*\" with you
strings.ilikesubstring*Google Drive*
strings.ilikesubstring*Google Doc*
strings.ilikesubstring*Google Sheet*
strings.ilikesubstring*Google Slide*
strings.ilikesubstring*shared*
strings.ilikesubstring*updated*
strings.ilikesubstring*sign*
strings.ilikesubstring*review*
strings.ilikesubstring*Docs*
strings.ilikesubstring*Sheets*
strings.ilikesubstring*Slides*
strings.icontainssubstringopen document
strings.iends_withsuffix.pdf
body.links[].display_textequalsOpen
subject.subjectequals
regex.icontainsregex^g.o.o.g.l.e
strings.starts_withprefixGoogle
strings.icontainssubstring<table style="width:100%; border:1px solid #dadce0; border-radius:6px; border-spacing:0; border-collapse:separate; table-layout:fixed" role="presentation">
strings.icontainssubstringGoogle LLC
strings.icontainssubstring1600 Amphitheatre Parkway
strings.icontainssubstringMountain View, CA 94043

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      or
        and
          any([body.current_thread.text, body.plain.raw])
            or
              [body.current_thread.text, body.plain.raw] match "Google Doc"
              [body.current_thread.text, body.plain.raw] match "Google Drive"
              [body.current_thread.text, body.plain.raw] match "Google Sheet"
              [body.current_thread.text, body.plain.raw] match "Google Slide"
          sender.email.domain.root_domain ne "dropbox.com"
          subject.subject regex_match "shared \\\".*\\\" with you"
        any([body.current_thread.text, body.plain.raw])
          or
            [body.current_thread.text, body.plain.raw] match "added as an editor"
            [body.current_thread.text, body.plain.raw] match "invited you to edit"
            [body.current_thread.text, body.plain.raw] match "invited you to review"
            [body.current_thread.text, body.plain.raw] match "received a document"
            [body.current_thread.text, body.plain.raw] match "received this email because you"
            [body.current_thread.text, body.plain.raw] match "shared a document"
            [body.current_thread.text, body.plain.raw] match "shared a file with you"
            [body.current_thread.text, body.plain.raw] match "shared a spreadsheet"
            [body.current_thread.text, body.plain.raw] match "shared an item"
            [body.current_thread.text, body.plain.raw] match "shared this document"
            [body.current_thread.text, body.plain.raw] match "shared with you"
            [body.current_thread.text, body.plain.raw] wildcard "*automated *mail from google*drive*"
            [body.current_thread.text, body.plain.raw] wildcard "*shared a*with you*"
        beta.ocr(file.message_screenshot()).text match "added as an editor"
        beta.ocr(file.message_screenshot()).text match "invited you to edit"
        beta.ocr(file.message_screenshot()).text match "invited you to review"
        beta.ocr(file.message_screenshot()).text match "received a document"
        beta.ocr(file.message_screenshot()).text match "received this email because you"
        beta.ocr(file.message_screenshot()).text match "shared a document"
        beta.ocr(file.message_screenshot()).text match "shared a file with you"
        beta.ocr(file.message_screenshot()).text match "shared a spreadsheet"
        beta.ocr(file.message_screenshot()).text match "shared an item"
        beta.ocr(file.message_screenshot()).text match "shared this document"
        beta.ocr(file.message_screenshot()).text match "shared with you"
        beta.ocr(file.message_screenshot()).text wildcard "*automated *mail from google*drive*"
        beta.ocr(file.message_screenshot()).text wildcard "*shared a*with you*"
      or
        any(body.links)
          or
            and
              body.links.display_text eq "Open"
              network.whois func_call "network.whois(body.links[].href_url.domain).days_old < 365"
            any(recipients.to)
              strings.icontains func_call "strings.icontains(body.links[].display_text)"
            body.links.display_text contains "open document"
            body.links.display_text ends_with ".pdf"
        any(recipients.to)
          or
            and
              recipients.to.email.domain.valid eq "false"
               macro "all(recipients.cc)"
            strings.icontains func_call "strings.icontains(subject.subject)"
        body.current_thread.text regex_match "^g.o.o.g.l.e"
        recipients.to length_compare "0"
        sender.display_name match "Google Drive"
        subject.subject eq ""
        subject.subject is_null
        subject.subject match "Docs"
        subject.subject match "Sheets"
        subject.subject match "Slides"
        subject.subject match "review"
        subject.subject match "shared"
        subject.subject match "sign"
        subject.subject match "updated"
    any(['Contigo', 'Avec vous', 'Mit Ihnen', 'Con te', 'Com você', 'Met u', 'С вами', '与你', '與您', 'あなたと', '당신과', 'معك', 'آپ کے ساتھ', 'আপনার সাথে', 'आपके साथ', 'Sizinle', 'Med dig', 'Z tobą', 'З вами', 'Önnel', 'Μαζί σας', 'איתך', 'กับคุณ', 'Với bạn', 'Dengan Anda', 'Nawe', 'Cu dumneavoastră', 'S vámi', 'Med deg', 'S vami', 'Med dig', 'Amb vostè', 'Teiega', 'S vama'])
      strings.icontains func_call "strings.icontains(subject.subject)"
  or
    any(attachments)
      and
        or
          any(ml.logo_detect(attachments).brands)
            ml.logo_detect(attachments).brands.name starts_with "Google"
          any(recipients.to)
            strings.icontains func_call "strings.icontains(beta.ocr(attachments[]).text)"
          strings.icontains func_call "strings.icontains(beta.ocr(attachments[]).text)"
         macro "attachments[].file_type in file_types_images"
    any(ml.logo_detect(file.message_screenshot()).brands)
      ml.logo_detect(file.message_screenshot()).brands.name starts_with "Google"
    any(recipients.to)
      strings.icontains func_call "strings.icontains(body.current_thread.text)"
    body.current_thread.text contains "1600 Amphitheatre Parkway"
    body.current_thread.text contains "Google LLC"
    body.current_thread.text contains "Mountain View, CA 94043"
    body.html.raw contains "<table style=\"width:100%; border:1px solid #dadce0; border-radius:6px; border-spacing:0; border-collapse:separate; table-layout:fixed\" role=\"presentation\">"
    strings.icontains func_call "strings.icontains(body.current_thread.text)"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    profile.by_sender func_call "profile.by_sender().solicited == false"
    profile.by_sender_email func_call "profile.by_sender_email().prevalence == new"
  not
    and
      body.previous_threads length_compare "0"
      body.previous_threads[].links length_compare "0"
       macro "all(body.previous_threads[].links)"
  not
    and
      headers.return_path.domain.domain eq "doclist.bounces.google.com"
       macro "all(headers.references)"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  not
    sender.email.domain.root_domain eq "google.com"
  not
     macro "all(body.links)"
  type.inbound eq "true"
   macro "sender.email.domain.root_domain not in org_domains"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
beta.ocr(file.message_screenshot()).textwildcard
  • *added as an editor*
  • *automated *mail from google*drive*
  • *invited you to edit*
  • *invited you to review*
  • *received a document*
  • *received this email because you*
  • *shared a document*
  • *shared a file with you*
  • *shared a spreadsheet*
  • *shared a*with you*
  • *shared an item*
  • *shared this document*
  • *shared with you*
field:"beta.ocr(file.message_screenshot()).text" kind:wildcard
body.current_thread.textcontains
  • 1600 Amphitheatre Parkway
  • Google LLC
  • Mountain View, CA 94043
field:"body.current_thread.text" kind:contains
body.current_thread.textregex_match
  • ^g.o.o.g.l.e
field:"body.current_thread.text" kind:regex_match value:"^g.o.o.g.l.e"
body.html.rawcontains
  • <table style="width:100%; border:1px solid #dadce0; border-radius:6px; border-spacing:0; border-collapse:separate; table-layout:fixed" role="presentation">
field:"body.html.raw" kind:contains
sender.display_namewildcard
  • *Google Drive*
field:"sender.display_name" kind:wildcard value:"*Google Drive*"
sender.email.domain.root_domainne
  • dropbox.com
field:"sender.email.domain.root_domain" kind:ne value:"dropbox.com"
subject.subjectis_null
  • (no value, null check)
field:"subject.subject" kind:is_null
subject.subjectregex_match
  • shared \".*\" with you
field:"subject.subject" kind:regex_match
subject.subjectwildcard
  • *Docs*
  • *Sheets*
  • *Slides*
  • *review*
  • *shared*
  • *sign*
  • *updated*
field:"subject.subject" kind:wildcard
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Google using Microsoft Forms

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

Abuses Microsoft Forms to impersonate Google.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.html
  • body.links
  • headers
  • sender.email
  • type

Rule body

type.inbound
and sender.email.domain.domain == 'email.formspro.microsoft.com'
and regex.icontains(sender.display_name, '(google|gmail)')
and regex.icontains(sender.display_name, '(alert|warning|notification)')
// MsgID does not contain Google|Gmail|GoogleMail
and not regex.icontains(headers.message_id,
                        '(mail|mx)?\.?(google(mail)?|gmail.com)'
)
and (
  any(body.links, .href_url.domain.root_domain not in $tranco_1m)
  or strings.ilike(body.html.display_text,
                   "*suspicious activities*",
                   "*failure to secure*",
                   "*loose your*",
                   "*suspended*"
  )
)

Detection logic

Scope: inbound message.

Abuses Microsoft Forms to impersonate Google.

  1. inbound message
  2. sender.email.domain.domain is 'email.formspro.microsoft.com'
  3. sender.display_name matches '(google|gmail)'
  4. sender.display_name matches '(alert|warning|notification)'
  5. not:
    • headers.message_id matches '(mail|mx)?\\.?(google(mail)?|gmail.com)'
  6. any of:
    • any of body.links where:
      • .href_url.domain.root_domain not in $tranco_1m
    • body.html.display_text matches any of 4 patterns
      • *suspicious activities*
      • *failure to secure*
      • *loose your*
      • *suspended*

Inspects: body.html.display_text, body.links, body.links[].href_url.domain.root_domain, headers.message_id, sender.display_name, sender.email.domain.domain, type.inbound. Sensors: regex.icontains, strings.ilike. Reference lists: $tranco_1m.

Indicators matched (7)

FieldMatchValue
sender.email.domain.domainequalsemail.formspro.microsoft.com
regex.icontainsregex(google|gmail)
regex.icontainsregex(alert|warning|notification)
strings.ilikesubstring*suspicious activities*
strings.ilikesubstring*failure to secure*
strings.ilikesubstring*loose your*
strings.ilikesubstring*suspended*

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(body.links)
       macro "body.links[].href_url.domain.root_domain not in tranco_1m"
    body.html.display_text match "failure to secure"
    body.html.display_text match "loose your"
    body.html.display_text match "suspended"
    body.html.display_text match "suspicious activities"
  not
    headers.message_id regex_match "(mail|mx)?\\.?(google(mail)?|gmail.com)"
  sender.display_name regex_match "(alert|warning|notification)"
  sender.display_name regex_match "(google|gmail)"
  sender.email.domain.domain eq "email.formspro.microsoft.com"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.message_idregex_match(mail|mx)?.?(google(mail)?|gmail.com)excludes:headers.message_id field:"headers.message_id" value:"(mail|mx)?.?(google(mail)?|gmail.com)"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.html.display_textwildcard
  • *failure to secure*
  • *loose your*
  • *suspended*
  • *suspicious activities*
field:"body.html.display_text" kind:wildcard
sender.display_nameregex_match
  • (alert|warning|notification)
  • (google|gmail)
field:"sender.display_name" kind:regex_match
sender.email.domain.domaineq
  • email.formspro.microsoft.com
field:"sender.email.domain.domain" kind:eq value:"email.formspro.microsoft.com"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Google Workspace alert notification

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

Detects messages impersonating Google Workspace alert notifications that use Google branding elements, workspace-specific terminology, and admin console references, but originate from non-Google domains and contain suspicious links.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering, Lookalike domain

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.html
  • body.links
  • headers
  • headers.auth_summary
  • headers.hops
  • headers.reply_to
  • sender.email
  • subject
  • type

Rule body

type.inbound

// Sender impersonates Google Workspace alerts but not from Google
and (
  regex.icontains(sender.display_name,
                  '(?:workspace|google\s*workspace).*(?:alert|notification)'
  )
  or regex.icontains(sender.display_name,
                     '(?:alert|notification).*(?:workspace|google\s*workspace)'
  )
  or regex.icontains(sender.email.local_part,
                     'workspace.*(?:alert|notification)'
  )
  or regex.icontains(sender.email.local_part, 'google.*workspace')
)
and not (
  sender.email.domain.root_domain in~ (
    'google.com',
    'google.co.uk',
    'google.ca'
  )
  and headers.auth_summary.dmarc.pass
)

// Negate legitimate Atlassian/Jira notifications that may contain Google Workspace content
and not (
  sender.email.domain.root_domain in~ ('atlassian.net', 'atlassian.com')
  and headers.auth_summary.dmarc.pass
)

// Negate legitimate Google alerts forwarded through mailing lists
and not (
  any(headers.hops,
      any(.fields,
          .name in ('X-Original-Sender', 'X-Original-From')
          and strings.ends_with(.value, '@google.com')
      )
  )
)

// Exclude Google Voice/phone call notifications
and not (
  regex.icontains(subject.subject,
                  '(?:phone\s*call|voice\s*mail|missed\s*call)'
  )
  or regex.icontains(body.current_thread.text, 'Google\s*Voice')
)

// Exclude forwarded messages
and not subject.is_forward

// Body contains Google Workspace impersonation patterns
and (
  // Alert center call to action with various phishing subjects
  (
    regex.icontains(body.current_thread.text, 'alert\s*cent(?:er|re)')
    and (
      regex.icontains(subject.subject,
                      'spike\s+in\s+(?:user[- ]?reported\s+)?spam'
      )
      or regex.icontains(subject.subject,
                         '(?:security|admin|workspace)\s+alert'
      )
      or regex.icontains(subject.subject,
                         'suspicious\s+(?:activity|login|access)'
      )
    )
  )
  // Reply-to address spoofs Google Workspace alerts
  or any(headers.reply_to,
         .email.email == 'google-workspace-alerts-noreply@google.com'
  )
  // Google Workspace logo hotlinked from gstatic
  or (
    strings.icontains(body.html.raw,
                      'gstatic.com/apps/signup/resources/google-workspace-lockup.png'
    )
    or strings.icontains(body.html.raw,
                         'gstatic.com/apps/signup/resources/google-workspace-lockup.svg'
    )
    or strings.icontains(body.html.raw,
                         'gstatic.com/apps/signup/resources/google-workspace-lockup.jpg'
    )
  )
  // Google corporate address
  or (
    strings.icontains(body.current_thread.text, '1600 Amphitheatre Parkway')
    and strings.icontains(body.current_thread.text, 'Mountain View, CA')
  )
  // Admin recipient messaging patterns
  or regex.icontains(body.current_thread.text, 'designated\s+admin\s+recipient')
  or (
    regex.icontains(body.current_thread.text,
                    'Google\s+Workspace(?:\s*account)?'
    )
    and regex.icontains(body.current_thread.text,
                        '(?:admin|administrator)\s+(?:console|recipient|account)'
    )
  )
  // Alert details structure common in these phishing attempts
  or (
    regex.icontains(body.current_thread.text, 'alert\s+details\s+include')
    and regex.icontains(body.current_thread.text,
                        '(?:activity\s+date|total\s+(?:user\s+)?reports|severity)'
    )
  )
)

// Contains links that are not to Google
and any(body.links,
        not .href_url.domain.root_domain in~ (
          'google.com',
          'google.co.uk',
          'google.ca',
          'gstatic.com',
          'googleusercontent.com',
          'sendgrid.net'
        )
)

Detection logic

Scope: inbound message.

Detects messages impersonating Google Workspace alert notifications that use Google branding elements, workspace-specific terminology, and admin console references, but originate from non-Google domains and contain suspicious links.

  1. inbound message
  2. any of:
    • sender.display_name matches '(?:workspace|google\\s*workspace).*(?:alert|notification)'
    • sender.display_name matches '(?:alert|notification).*(?:workspace|google\\s*workspace)'
    • sender.email.local_part matches 'workspace.*(?:alert|notification)'
    • sender.email.local_part matches 'google.*workspace'
  3. not:
    • all of:
      • sender.email.domain.root_domain in ('google.com', 'google.co.uk', 'google.ca')
      • headers.auth_summary.dmarc.pass
  4. not:
    • all of:
      • sender.email.domain.root_domain in ('atlassian.net', 'atlassian.com')
      • headers.auth_summary.dmarc.pass
  5. not:
    • any of headers.hops where:
      • any of .fields where all hold:
        • .name in ('X-Original-Sender', 'X-Original-From')
        • .value ends with '@google.com'
  6. none of:
    • subject.subject matches '(?:phone\\s*call|voice\\s*mail|missed\\s*call)'
    • body.current_thread.text matches 'Google\\s*Voice'
  7. not:
    • subject.is_forward
  8. any of:
    • all of:
      • body.current_thread.text matches 'alert\\s*cent(?:er|re)'
      • any of:
        • subject.subject matches 'spike\\s+in\\s+(?:user[- ]?reported\\s+)?spam'
        • subject.subject matches '(?:security|admin|workspace)\\s+alert'
        • subject.subject matches 'suspicious\\s+(?:activity|login|access)'
    • any of headers.reply_to where:
      • .email.email is 'google-workspace-alerts-noreply@google.com'
    • any of:
      • body.html.raw contains 'gstatic.com/apps/signup/resources/google-workspace-lockup.png'
      • body.html.raw contains 'gstatic.com/apps/signup/resources/google-workspace-lockup.svg'
      • body.html.raw contains 'gstatic.com/apps/signup/resources/google-workspace-lockup.jpg'
    • all of:
      • body.current_thread.text contains '1600 Amphitheatre Parkway'
      • body.current_thread.text contains 'Mountain View, CA'
    • body.current_thread.text matches 'designated\\s+admin\\s+recipient'
    • all of:
      • body.current_thread.text matches 'Google\\s+Workspace(?:\\s*account)?'
      • body.current_thread.text matches '(?:admin|administrator)\\s+(?:console|recipient|account)'
    • all of:
      • body.current_thread.text matches 'alert\\s+details\\s+include'
      • body.current_thread.text matches '(?:activity\\s+date|total\\s+(?:user\\s+)?reports|severity)'
  9. any of body.links where:
    • not:
      • .href_url.domain.root_domain in ('google.com', 'google.co.uk', 'google.ca', 'gstatic.com', 'googleusercontent.com', 'sendgrid.net')

Inspects: body.current_thread.text, body.html.raw, body.links, 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.reply_to, headers.reply_to[].email.email, sender.display_name, sender.email.domain.root_domain, sender.email.local_part, subject.is_forward, subject.subject, type.inbound. Sensors: regex.icontains, strings.ends_with, strings.icontains.

Indicators matched (19)

FieldMatchValue
regex.icontainsregex(?:workspace|google\s*workspace).*(?:alert|notification)
regex.icontainsregex(?:alert|notification).*(?:workspace|google\s*workspace)
regex.icontainsregexworkspace.*(?:alert|notification)
regex.icontainsregexgoogle.*workspace
regex.icontainsregexalert\s*cent(?:er|re)
regex.icontainsregexspike\s+in\s+(?:user[- ]?reported\s+)?spam
regex.icontainsregex(?:security|admin|workspace)\s+alert
regex.icontainsregexsuspicious\s+(?:activity|login|access)
headers.reply_to[].email.emailequalsgoogle-workspace-alerts-noreply@google.com
strings.icontainssubstringgstatic.com/apps/signup/resources/google-workspace-lockup.png
strings.icontainssubstringgstatic.com/apps/signup/resources/google-workspace-lockup.svg
strings.icontainssubstringgstatic.com/apps/signup/resources/google-workspace-lockup.jpg
7 more
strings.icontainssubstring1600 Amphitheatre Parkway
strings.icontainssubstringMountain View, CA
regex.icontainsregexdesignated\s+admin\s+recipient
regex.icontainsregexGoogle\s+Workspace(?:\s*account)?
regex.icontainsregex(?:admin|administrator)\s+(?:console|recipient|account)
regex.icontainsregexalert\s+details\s+include
regex.icontainsregex(?:activity\s+date|total\s+(?:user\s+)?reports|severity)

Stages and Predicates

Stage 1: mql_rule

and
  not
    any(headers.hops)
      any(headers.hops.fields)
        and
          headers.hops.fields[].name in ["X-Original-From", "X-Original-Sender"]
          headers.hops.fields[].value ends_with "@google.com"
  or
    and
      or
        subject.subject regex_match "(?:security|admin|workspace)\\s+alert"
        subject.subject regex_match "spike\\s+in\\s+(?:user[- ]?reported\\s+)?spam"
        subject.subject regex_match "suspicious\\s+(?:activity|login|access)"
      body.current_thread.text regex_match "alert\\s*cent(?:er|re)"
    and
      body.current_thread.text contains "1600 Amphitheatre Parkway"
      body.current_thread.text contains "Mountain View, CA"
    and
      body.current_thread.text regex_match "(?:activity\\s+date|total\\s+(?:user\\s+)?reports|severity)"
      body.current_thread.text regex_match "alert\\s+details\\s+include"
    and
      body.current_thread.text regex_match "(?:admin|administrator)\\s+(?:console|recipient|account)"
      body.current_thread.text regex_match "Google\\s+Workspace(?:\\s*account)?"
    any(headers.reply_to)
      headers.reply_to.email.email eq "google-workspace-alerts-noreply@google.com"
    body.current_thread.text regex_match "designated\\s+admin\\s+recipient"
    body.html.raw contains "gstatic.com/apps/signup/resources/google-workspace-lockup.jpg"
    body.html.raw contains "gstatic.com/apps/signup/resources/google-workspace-lockup.png"
    body.html.raw contains "gstatic.com/apps/signup/resources/google-workspace-lockup.svg"
  not
    or
      body.current_thread.text regex_match "Google\\s*Voice"
      subject.subject regex_match "(?:phone\\s*call|voice\\s*mail|missed\\s*call)"
  any(body.links)
    not
      body.links.href_url.domain.root_domain in ["google.ca", "google.co.uk", "google.com", "googleusercontent.com", "gstatic.com", "sendgrid.net"]
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.root_domain in ["atlassian.com", "atlassian.net"]
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.root_domain in ["google.ca", "google.co.uk", "google.com"]
  or
    sender.display_name regex_match "(?:alert|notification).*(?:workspace|google\\s*workspace)"
    sender.display_name regex_match "(?:workspace|google\\s*workspace).*(?:alert|notification)"
    sender.email.local_part regex_match "google.*workspace"
    sender.email.local_part regex_match "workspace.*(?:alert|notification)"
  not
    subject.is_forward eq "true"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textcontains
  • 1600 Amphitheatre Parkway
  • Mountain View, CA
field:"body.current_thread.text" kind:contains
body.current_thread.textregex_match
  • (?:activity\s+date|total\s+(?:user\s+)?reports|severity)
  • (?:admin|administrator)\s+(?:console|recipient|account)
  • Google\s+Workspace(?:\s*account)?
  • alert\s*cent(?:er|re)
  • alert\s+details\s+include
  • designated\s+admin\s+recipient
field:"body.current_thread.text" kind:regex_match
body.html.rawcontains
  • gstatic.com/apps/signup/resources/google-workspace-lockup.jpg
  • gstatic.com/apps/signup/resources/google-workspace-lockup.png
  • gstatic.com/apps/signup/resources/google-workspace-lockup.svg
field:"body.html.raw" kind:contains
sender.display_nameregex_match
  • (?:alert|notification).*(?:workspace|google\s*workspace)
  • (?:workspace|google\s*workspace).*(?:alert|notification)
field:"sender.display_name" kind:regex_match
sender.email.local_partregex_match
  • google.*workspace
  • workspace.*(?:alert|notification)
field:"sender.email.local_part" kind:regex_match
subject.subjectregex_match
  • (?:security|admin|workspace)\s+alert
  • spike\s+in\s+(?:user[- ]?reported\s+)?spam
  • suspicious\s+(?:activity|login|access)
field:"subject.subject" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Government / Tax Authority document lure

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

Detects messages impersonating government and tax authorities (such as the IRS, SSA, Department of Treasury, and similar agencies) that contain suspicious document-related links. The rule identifies either download calls-to-action pointing to low-reputation or free subdomain hosts, or phishing-kit URLs that embed the impersonated organization's name in the path. Credential theft intent is confirmed via NLP analysis, and trusted sender domains are only flagged when DMARC authentication fails.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Free subdomain host, Social engineering, Lookalike domain

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
// impersonates a named government / tax / benefits authority in the sender display name
and regex.icontains(strings.replace_confusables(sender.display_name),
                    'internal revenue|\bIRS\b|social security|\bSSA\b|medicaid|medicare|department of (?:health|revenue|treasur|state|labor|justice|homeland)|ministry of finance|income tax (?:department|dept)|department of the treasury|u\.?s\.? treasury'
)
// a document lure link that is either a download cta to a low-rep host
and any(body.current_thread.links,
        regex.icontains(.display_text,
                        'download|response form|review document|official document|statement'
        )
        and (
          .href_url.domain.root_domain not in $tranco_1m
          or .href_url.domain.root_domain in $url_shorteners
          or (
            .href_url.domain.subdomain is not null
            and .href_url.domain.subdomain != "www"
            and .href_url.domain.root_domain in $free_subdomain_hosts
          )
        )
)
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft" and .confidence in ("medium", "high")
)
// 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.

Detects messages impersonating government and tax authorities (such as the IRS, SSA, Department of Treasury, and similar agencies) that contain suspicious document-related links. The rule identifies either download calls-to-action pointing to low-reputation or free subdomain hosts, or phishing-kit URLs that embed the impersonated organization's name in the path. Credential theft intent is confirmed via NLP analysis, and trusted sender domains are only flagged when DMARC authentication fails.

  1. inbound message
  2. strings.replace_confusables(sender.display_name) matches 'internal revenue|\\bIRS\\b|social security|\\bSSA\\b|medicaid|medicare|department of (?:health|revenue|treasur|state|labor|justice|homeland)|ministry of finance|income tax (?:department|dept)|department of the treasury|u\\.?s\\.? treasury'
  3. any of body.current_thread.links where all hold:
    • .display_text matches 'download|response form|review document|official document|statement'
    • any of:
      • .href_url.domain.root_domain not in $tranco_1m
      • .href_url.domain.root_domain in $url_shorteners
      • all of:
        • .href_url.domain.subdomain is set
        • .href_url.domain.subdomain is not 'www'
        • .href_url.domain.root_domain in $free_subdomain_hosts
  4. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name is 'cred_theft'
    • .confidence in ('medium', 'high')
  5. not:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • coalesce(headers.auth_summary.dmarc.pass)

Inspects: body.current_thread.links, body.current_thread.links[].display_text, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.links[].href_url.domain.subdomain, body.current_thread.text, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.root_domain, type.inbound. Sensors: ml.nlu_classifier, regex.icontains, strings.replace_confusables. Reference lists: $free_subdomain_hosts, $high_trust_sender_root_domains, $tranco_1m, $url_shorteners.

Indicators matched (5)

FieldMatchValue
regex.icontainsregexinternal revenue|\bIRS\b|social security|\bSSA\b|medicaid|medicare|department of (?:health|revenue|treasur|state|labor|justice|homeland)|ministry of finance|income tax (?:department|dept)|department of the treasury|u\.?s\.? treasury
regex.icontainsregexdownload|response form|review document|official document|statement
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

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    and
      or
        and
          body.current_thread.links.href_url.domain.subdomain is_not_null
          body.current_thread.links.href_url.domain.subdomain ne "www"
           macro "body.current_thread.links[].href_url.domain.root_domain in free_subdomain_hosts"
         macro "body.current_thread.links[].href_url.domain.root_domain in url_shorteners"
         macro "body.current_thread.links[].href_url.domain.root_domain not in tranco_1m"
      body.current_thread.links.display_text regex_match "download|response form|review document|official document|statement"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
  any(ml.nlu_classifier(body.current_thread.text).intents)
    and
      ml.nlu_classifier(body.current_thread.text).intents.confidence in ["high", "medium"]
      ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
  strings.replace_confusables(sender.display_name) regex_match "internal revenue|\\bIRS\\b|social security|\\bSSA\\b|medicaid|medicare|department of (?:health|revenue|treasur|state|labor|justice|homeland)|ministry of finance|income tax (?:department|dept)|department of the treasury|u\\.?s\\.? treasury"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
strings.replace_confusables(sender.display_name)regex_match
    • internal revenue
    • \bIRS\b
    • social security
    • \bSSA\b
    • medicaid
    • medicare
    • department of (?:health|revenue|treasur|state|labor|justice|homeland)
    • ministry of finance
    • income tax (?:department|dept)
    • department of the treasury
    • u.?s.? treasury
field:"strings.replace_confusables(sender.display_name)" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Gusto

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

Impersonation of Gusto, a cloud-based payroll management company.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  strings.ilike(sender.display_name, '*gusto*')
  or strings.ilevenshtein(sender.display_name, 'gusto') <= 1
  or strings.ilike(sender.email.domain.domain, '*gusto*')
)
and any(ml.logo_detect(file.message_screenshot()).brands,
        .name == "Gusto" and .confidence in ("medium", "high")
)
and sender.email.domain.root_domain !~ 'gusto.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.

Impersonation of Gusto, a cloud-based payroll management company.

  1. inbound message
  2. any of:
    • sender.display_name matches '*gusto*'
    • sender.display_name is similar to 'gusto'
    • sender.email.domain.domain matches '*gusto*'
  3. any of ml.logo_detect(file.message_screenshot()).brands where all hold:
    • .name is 'Gusto'
    • .confidence in ('medium', 'high')
  4. sender.email.domain.root_domain is not 'gusto.com'
  5. 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: headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: file.message_screenshot, ml.logo_detect, strings.ilevenshtein, strings.ilike. Reference lists: $high_trust_sender_root_domains.

Indicators matched (5)

FieldMatchValue
strings.ilikesubstring*gusto*
strings.ilevenshteinfuzzygusto
ml.logo_detect(file.message_screenshot()).brands[].nameequalsGusto
ml.logo_detect(file.message_screenshot()).brands[].confidencemembermedium
ml.logo_detect(file.message_screenshot()).brands[].confidencememberhigh

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  any(ml.logo_detect(file.message_screenshot()).brands)
    and
      ml.logo_detect(file.message_screenshot()).brands.confidence in ["high", "medium"]
      ml.logo_detect(file.message_screenshot()).brands.name eq "Gusto"
  or
    sender.display_name match "gusto"
    sender.email.domain.domain match "gusto"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"gusto\") <= 1"
  sender.email.domain.root_domain ne "gusto.com"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Brand impersonation: LastPass

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

Detects messages impersonating the password manager LastPass that contain suspicious language about maintenance, vault exports, or master passwords.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.links
  • headers
  • headers.auth_summary
  • recipients
  • recipients.to
  • sender.email
  • type

Rule body

type.inbound
and length(body.links) > 0
and any([sender.display_name, sender.email.domain.domain],
        strings.ilike(strings.replace_confusables(.), "*LastPass*", "Last?Pass")
)
and (
  strings.ilike(body.current_thread.text,
                "*back*up*",
                "*maintenance*",
                "*master*password*",
                "*export*vault*",
                "*support@lastpass.com*" // real LastPass support address
  )
  or any(body.links,
         // links directly to a S3 bucket
         (
           .href_url.domain.root_domain == "amazonaws.com"
           and strings.icontains(.href_url.domain.subdomain, "s3")
         )
         // recipient email as a URL param
         or any(.href_url.query_params_decoded["email"],
                strings.parse_email(.).email in map(recipients.to, .email.email)
         )
  )
  or any(ml.nlu_classifier(body.current_thread.text).topics,
         .name in ("Security and Authentication", "Reminders and Notifications")
         and .confidence != "low"
  )
  // invalid sender address
  or not sender.email.domain.valid
)
// negate newsletters
and not any(ml.nlu_classifier(body.current_thread.text).topics,
            .name in ("Newsletters and Digests") and .confidence != "low"
)
and not (
  sender.email.domain.root_domain in~ ("lastpass.com")
  and headers.auth_summary.dmarc.pass
)

Detection logic

Scope: inbound message.

Detects messages impersonating the password manager LastPass that contain suspicious language about maintenance, vault exports, or master passwords.

  1. inbound message
  2. length(body.links) > 0
  3. any of [sender.display_name, sender.email.domain.domain] where:
    • strings.replace_confusables(.) matches any of 2 patterns
      • *LastPass*
      • Last?Pass
  4. any of:
    • body.current_thread.text matches any of 5 patterns
      • *back*up*
      • *maintenance*
      • *master*password*
      • *export*vault*
      • *support@lastpass.com*
    • any of body.links where any holds:
      • all of:
        • .href_url.domain.root_domain is 'amazonaws.com'
        • .href_url.domain.subdomain contains 's3'
      • any of .href_url.query_params_decoded['email'] where:
        • strings.parse_email(.).email in map(recipients.to, .email.email)
    • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
      • .name in ('Security and Authentication', 'Reminders and Notifications')
      • .confidence is not 'low'
    • not:
      • sender.email.domain.valid
  5. not:
    • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
      • .name in ('Newsletters and Digests')
      • .confidence is not 'low'
  6. not:
    • all of:
      • sender.email.domain.root_domain in ('lastpass.com')
      • headers.auth_summary.dmarc.pass

Inspects: body.current_thread.text, body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.subdomain, body.links[].href_url.query_params_decoded['email'], headers.auth_summary.dmarc.pass, recipients.to, recipients.to[].email.email, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.domain.valid, type.inbound. Sensors: ml.nlu_classifier, strings.icontains, strings.ilike, strings.parse_email, strings.replace_confusables.

Indicators matched (11)

FieldMatchValue
strings.ilikesubstring*LastPass*
strings.ilikesubstringLast?Pass
strings.ilikesubstring*back*up*
strings.ilikesubstring*maintenance*
strings.ilikesubstring*master*password*
strings.ilikesubstring*export*vault*
strings.ilikesubstring*support@lastpass.com*
body.links[].href_url.domain.root_domainequalsamazonaws.com
strings.icontainssubstrings3
ml.nlu_classifier(body.current_thread.text).topics[].namememberSecurity and Authentication
ml.nlu_classifier(body.current_thread.text).topics[].namememberReminders and Notifications

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(body.links)
      or
        and
          body.links.href_url.domain.root_domain eq "amazonaws.com"
          body.links.href_url.domain.subdomain contains "s3"
        any(body.links.href_url.query_params_decoded['email'])
          strings.parse_email func_call "strings.parse_email(body.links[].href_url.query_params_decoded['email'][]).email in map(recipients.to, body.links[].href_url.query_params_decoded['email'][].email.email)"
    any(ml.nlu_classifier(body.current_thread.text).topics)
      and
        ml.nlu_classifier(body.current_thread.text).topics.confidence ne "low"
        ml.nlu_classifier(body.current_thread.text).topics.name in ["Reminders and Notifications", "Security and Authentication"]
    not
      sender.email.domain.valid eq "true"
    body.current_thread.text match "maintenance"
    body.current_thread.text match "support@lastpass.com"
    body.current_thread.text wildcard "*back*up*"
    body.current_thread.text wildcard "*export*vault*"
    body.current_thread.text wildcard "*master*password*"
  not
    any(ml.nlu_classifier(body.current_thread.text).topics)
      and
        ml.nlu_classifier(body.current_thread.text).topics.confidence ne "low"
        ml.nlu_classifier(body.current_thread.text).topics.name eq "Newsletters and Digests"
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.root_domain eq "lastpass.com"
  any([sender.display_name, sender.email.domain.domain])
    or
      strings.replace_confusables([sender.display_name, sender.email.domain.domain][]) eq "Last?Pass"
      strings.replace_confusables([sender.display_name, sender.email.domain.domain][]) match "LastPass"
  body.links length_compare "0"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
ml.nlu_classifier(body.current_thread.text).topicsarray_any(no value, null check)excludes:ml.nlu_classifier(body.current_thread.text).topics
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
sender.email.domain.root_domaineqlastpass.comexcludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"lastpass.com"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textwildcard
  • *back*up*
  • *export*vault*
  • *maintenance*
  • *master*password*
  • *support@lastpass.com*
field:"body.current_thread.text" kind:wildcard
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Ledger

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

Attack impersonating hardware cryptocurrency wallet ledger.com's brand.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.auth_summary
  • headers.return_path
  • sender.email
  • type

Rule body

type.inbound
and (
  (
    sender.email.domain.root_domain == 'ledger.com'
    and headers.return_path.domain.root_domain not in (
      'ledger.com',
      'amazonses.com',
      'ledger.fr',
      'hubspotemail.net'
    )
  )
  or (
    (
      // only match ledger actual domains if dmarc fails
      not (
        sender.email.domain.root_domain in~ ('ledger.com', 'ledger.fr')
        and headers.auth_summary.dmarc.pass
      )
      or not sender.email.domain.root_domain in~ ('ledger.com', 'ledger.fr')
    )
    and (
      strings.ilike(sender.email.email, '*-ledger.com*')
      or sender.display_name =~ "ledger"
      or strings.istarts_with(sender.display_name, "ledger")
      or strings.ilevenshtein(sender.email.domain.sld, "ledger") <= 1
    )
    and (
      // if this comes from a free email provider,
      // flag if org has never sent an email to sender's email before
      (
        sender.email.domain.root_domain in $free_email_providers
        and sender.email.email not in $recipient_emails
      )
      // if this comes from a custom domain,
      // flag if org has never sent an email to sender's domain before
      or (
        sender.email.domain.root_domain not in $free_email_providers
        and sender.email.domain.domain not in $recipient_domains
      )
    )
  )
)
and sender.email.domain.root_domain not in (
  // Fortune has a newsletter called "The Ledger"
  'fortune.com',
  'velocityledger.com',
  'lever.co',
  'queensledger.com',
  'libertyledger.com',
  'uledger.io',
  'ledgers.org.uk',
  'leger.co.uk',
  'xledger.net'
)

Detection logic

Scope: inbound message.

Attack impersonating hardware cryptocurrency wallet ledger.com's brand.

  1. inbound message
  2. any of:
    • all of:
      • sender.email.domain.root_domain is 'ledger.com'
      • headers.return_path.domain.root_domain not in ('ledger.com', 'amazonses.com', 'ledger.fr', 'hubspotemail.net')
    • all of:
      • any of:
        • not:
          • all of:
            • sender.email.domain.root_domain in ('ledger.com', 'ledger.fr')
            • headers.auth_summary.dmarc.pass
        • not:
          • sender.email.domain.root_domain in ('ledger.com', 'ledger.fr')
      • any of:
        • sender.email.email matches '*-ledger.com*'
        • sender.display_name is 'ledger'
        • sender.display_name starts with 'ledger'
        • sender.email.domain.sld is similar to 'ledger'
      • any of:
        • all of:
          • sender.email.domain.root_domain in $free_email_providers
          • sender.email.email not in $recipient_emails
        • all of:
          • sender.email.domain.root_domain not in $free_email_providers
          • sender.email.domain.domain not in $recipient_domains
  3. sender.email.domain.root_domain not in ('fortune.com', 'velocityledger.com', 'lever.co', 'queensledger.com', 'libertyledger.com', 'uledger.io', 'ledgers.org.uk', 'leger.co.uk', 'xledger.net')

Inspects: headers.auth_summary.dmarc.pass, headers.return_path.domain.root_domain, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.domain.sld, sender.email.email, type.inbound. Sensors: strings.ilevenshtein, strings.ilike, strings.istarts_with. Reference lists: $free_email_providers, $recipient_domains, $recipient_emails.

Indicators matched (5)

FieldMatchValue
sender.email.domain.root_domainequalsledger.com
strings.ilikesubstring*-ledger.com*
sender.display_nameequalsledger
strings.istarts_withprefixledger
strings.ilevenshteinfuzzyledger

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      or
        not
          and
            headers.auth_summary.dmarc.pass eq "true"
            sender.email.domain.root_domain in ["ledger.com", "ledger.fr"]
        not
          sender.email.domain.root_domain in ["ledger.com", "ledger.fr"]
      or
        and
           macro "sender.email.domain.domain not in recipient_domains"
           macro "sender.email.domain.root_domain not in free_email_providers"
        and
           macro "sender.email.domain.root_domain in free_email_providers"
           macro "sender.email.email not in recipient_emails"
      or
        sender.display_name eq "ledger"
        sender.display_name starts_with "ledger"
        sender.email.email match "-ledger.com"
        strings.ilevenshtein func_call "strings.ilevenshtein(sender.email.domain.sld, \"ledger\") <= 1"
    and
      not
        headers.return_path.domain.root_domain in ["amazonses.com", "hubspotemail.net", "ledger.com", "ledger.fr"]
      sender.email.domain.root_domain eq "ledger.com"
  not
    sender.email.domain.root_domain in ["fortune.com", "ledgers.org.uk", "leger.co.uk", "lever.co", "libertyledger.com", "queensledger.com", "uledger.io", "velocityledger.com", "xledger.net"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaininfortune.com, ledgers.org.uk, leger.co.uk, lever.co, libertyledger.com, queensledger.com, uledger.io, velocityledger.com, xledger.netexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: LinkedIn

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

Impersonation of LinkedIn.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.reply_to
  • headers.return_path
  • sender.email
  • type

Rule body

type.inbound
and (
  sender.display_name =~ 'linkedin'
  or strings.ilevenshtein(sender.display_name, 'linkedin') <= 2
  or strings.ilevenshtein(sender.email.domain.root_domain, 'linkedin.com') <= 2
  or strings.ilike(sender.email.domain.root_domain, "*linkedin.com")
  or regex.icontains(body.current_thread.text, '©\s*(?:\d+)\s*linkedin')
  or (
    strings.icontains(body.current_thread.text, "linkedin")
    and regex.icontains(body.current_thread.text, 'due\s+invoice\(s\)\s+\d+')
  )
  or strings.icontains(body.current_thread.text, 'linkedin subscription order')
  or (
    strings.ilike(sender.display_name, "*linkedin*")
    and 1 of (
      any(ml.nlu_classifier(body.current_thread.text).intents,
          .name in ("cred_theft", "steal_pii") and .confidence == "high"
      ),
      network.whois(sender.email.domain).days_old <= 30
      and strings.ilike(sender.email.email, "*linkedin*"),
      (
        length(headers.reply_to) > 0
        and all(headers.reply_to,
                .email.domain.root_domain != sender.email.domain.root_domain
        )
        and all(headers.reply_to,
                .email.domain.root_domain != headers.return_path.domain.root_domain
        )
        and sender.email.domain.root_domain != headers.return_path.domain.root_domain
      )
    )
  )
)
and sender.email.domain.root_domain not in (
  'linkedin.com',
  'smartrecruiters.com',
  'teams-events.com',
  'linkeen.com'
)
and sender.email.domain.domain not in ('linkedin.coupahost.com')
and sender.email.email not in $recipient_emails
and not regex.icontains(headers.message_id, '[^-]linkedin.com>$')

// LinkedIn corporate uses DocuSign
and not (
  sender.email.domain.root_domain in~ ('docusign.net', 'docusign.com')
  and all(headers.reply_to, .email.domain.root_domain == 'linkedin.com')
)

Detection logic

Scope: inbound message.

Impersonation of LinkedIn.

  1. inbound message
  2. any of:
    • sender.display_name is 'linkedin'
    • sender.display_name is similar to 'linkedin'
    • sender.email.domain.root_domain is similar to 'linkedin.com'
    • sender.email.domain.root_domain matches '*linkedin.com'
    • body.current_thread.text matches '©\\s*(?:\\d+)\\s*linkedin'
    • all of:
      • body.current_thread.text contains 'linkedin'
      • body.current_thread.text matches 'due\\s+invoice\\(s\\)\\s+\\d+'
    • body.current_thread.text contains 'linkedin subscription order'
    • all of:
      • sender.display_name matches '*linkedin*'
      • at least 1 of:
        • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
          • .name in ('cred_theft', 'steal_pii')
          • .confidence is 'high'
        • all of:
          • network.whois(sender.email.domain).days_old ≤ 30
          • sender.email.email matches '*linkedin*'
        • all of:
          • length(headers.reply_to) > 0
          • all of headers.reply_to where:
            • .email.domain.root_domain is not sender.email.domain.root_domain
          • all of headers.reply_to where:
            • .email.domain.root_domain is not headers.return_path.domain.root_domain
          • sender.email.domain.root_domain is not headers.return_path.domain.root_domain
  3. sender.email.domain.root_domain not in ('linkedin.com', 'smartrecruiters.com', 'teams-events.com', 'linkeen.com')
  4. sender.email.domain.domain not in ('linkedin.coupahost.com')
  5. sender.email.email not in $recipient_emails
  6. not:
    • headers.message_id matches '[^-]linkedin.com>$'
  7. not:
    • all of:
      • sender.email.domain.root_domain in ('docusign.net', 'docusign.com')
      • all of headers.reply_to where:
        • .email.domain.root_domain is 'linkedin.com'

Inspects: body.current_thread.text, headers.message_id, headers.reply_to, headers.reply_to[].email.domain.root_domain, headers.return_path.domain.root_domain, sender.display_name, sender.email.domain, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: ml.nlu_classifier, network.whois, regex.icontains, strings.icontains, strings.ilevenshtein, strings.ilike. Reference lists: $recipient_emails.

Indicators matched (12)

FieldMatchValue
sender.display_nameequalslinkedin
strings.ilevenshteinfuzzylinkedin
strings.ilevenshteinfuzzylinkedin.com
strings.ilikesubstring*linkedin.com
regex.icontainsregex©\s*(?:\d+)\s*linkedin
strings.icontainssubstringlinkedin
regex.icontainsregexdue\s+invoice\(s\)\s+\d+
strings.icontainssubstringlinkedin subscription order
strings.ilikesubstring*linkedin*
ml.nlu_classifier(body.current_thread.text).intents[].namemembercred_theft
ml.nlu_classifier(body.current_thread.text).intents[].namemembersteal_pii
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      or
        any(ml.nlu_classifier(body.current_thread.text).intents)
          and
            ml.nlu_classifier(body.current_thread.text).intents.confidence eq "high"
            ml.nlu_classifier(body.current_thread.text).intents.name in ["cred_theft", "steal_pii"]
        and
          headers.reply_to length_compare "0"
          sender.email.domain.root_domain cross_field_compare "headers.return_path.domain.root_domain"
           macro "all(headers.reply_to)"
        and
          network.whois func_call "network.whois(sender.email.domain).days_old <= 30"
          sender.email.email match "linkedin"
      sender.display_name match "linkedin"
    and
      body.current_thread.text contains "linkedin"
      body.current_thread.text regex_match "due\\s+invoice\\(s\\)\\s+\\d+"
    body.current_thread.text contains "linkedin subscription order"
    body.current_thread.text regex_match "©\\s*(?:\\d+)\\s*linkedin"
    sender.display_name eq "linkedin"
    sender.email.domain.root_domain ends_with "linkedin.com"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"linkedin\") <= 2"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.email.domain.root_domain, \"linkedin.com\") <= 2"
  not
    and
      sender.email.domain.root_domain in ["docusign.com", "docusign.net"]
       macro "all(headers.reply_to)"
  not
    headers.message_id regex_match "[^-]linkedin.com>$"
  not
    sender.email.domain.domain eq "linkedin.coupahost.com"
  not
    sender.email.domain.root_domain in ["linkedin.com", "linkeen.com", "smartrecruiters.com", "teams-events.com"]
  type.inbound eq "true"
   macro "sender.email.email not in recipient_emails"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domainindocusign.com, docusign.netexcludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"docusign.com" field:"sender.email.domain.root_domain" value:"docusign.net"
headers.message_idregex_match[^-]linkedin.com>$excludes:headers.message_id field:"headers.message_id" value:"[^-]linkedin.com>$"
sender.email.domain.domaineqlinkedin.coupahost.comexcludes:sender.email.domain.domain field:"sender.email.domain.domain" value:"linkedin.coupahost.com"
sender.email.domain.root_domaininlinkedin.com, linkeen.com, smartrecruiters.com, teams-events.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Mailgun

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

Impersonation of the Mailgun Email delivery platform.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, BEC/Fraud
Tactics and techniquesImpersonation: Brand

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.html
  • headers
  • headers.auth_summary
  • headers.domains
  • headers.hops
  • recipients
  • recipients.to
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  any([
        sender.display_name,
        sender.email.domain.domain,
        sender.email.local_part,
        subject.subject
      ],
      regex.icontains(strings.replace_confusables(.), "ma[il][il]gun")
  )
  or regex.icontains(body.html.raw,
                     '<title>.*mailgun.*</title>',
                     'alt\s*=\s*"\s*Mailgun\s*Logo\s*"'
  )
  or regex.icontains(body.current_thread.text,
                     '[©®]\s*(20\d\d\s*)?Mailgun',
                     'mailgun\s*[©®]'
  )
  or any(ml.logo_detect(file.message_screenshot()).brands,
         .name == "Mailgun" and .confidence in ("medium", "high")
  )
)
and not (
  // sent from mailgun actual
  (
    sender.email.domain.root_domain in (
      'mailgun.com',
      'mailgun.net', // official mailgun domains
      'sinch.com', // parent company of Mailgun
      'mailgunwarmup.com', // an unrelated b2b firm
      'emailonacid.com', // another sinch email product 
      'elior-na.com', // a domain with a simliar logo that catches on logo_detect
      'brembo.com' // a domain with a simliar logo that catches on logo_detect
    )
    and headers.auth_summary.dmarc.pass
  )
  // and not where the recipient include the domain with a simliar logo
  // and where that recipient shows up in a previous thread
  or (
    any(recipients.to,
        .email.domain.root_domain in ("elior-na.com", "brembo.com")
    )
    and any(filter(recipients.to,
                   .email.domain.root_domain in ("elior-na.com", "brembo.com")
            ),
            (
              strings.icontains(body.html.display_text,
                                strings.concat("From: ", .email.email)
              )
              or strings.icontains(body.html.display_text,
                                   strings.concat("From: ", .display_name)
              )
            )
    )
  )
  or 
  // some domains have "mailgun" as a subdomain and are sent via mailgun
  // these are unlikely to be impersonations
  (
    (
      strings.icontains(sender.email.domain.domain, "mailgun")
      or strings.icontains(sender.email.local_part, "mailgun")
    )
    and (
      // if mailgun action was in the header.hops very likely not impersonation
      any(headers.domains, .root_domain in ('mailgun.com', 'mailgun.net'))
      // but if not and there are 4 or more X-Mailgun headers, likely not impersonation
      or sum(map(filter(headers.hops, .index < 2),
                 length(filter(.fields,
                               strings.starts_with(.name, "X-Mailgun-")
                        )
                 )
             )
      ) >= 3
    )
  )
)
// 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.

Impersonation of the Mailgun Email delivery platform.

  1. inbound message
  2. any of:
    • any of [sender.display_name, sender.email.domain.domain, sender.email.local_part, subject.subject] where:
      • strings.replace_confusables(.) matches 'ma[il][il]gun'
    • body.html.raw matches any of 2 patterns
      • <title>.*mailgun.*</title>
      • alt\s*=\s*"\s*Mailgun\s*Logo\s*"
    • body.current_thread.text matches any of 2 patterns
      • [©®]\s*(20\d\d\s*)?Mailgun
      • mailgun\s*[©®]
    • any of ml.logo_detect(file.message_screenshot()).brands where all hold:
      • .name is 'Mailgun'
      • .confidence in ('medium', 'high')
  3. none of:
    • all of:
      • sender.email.domain.root_domain in ('mailgun.com', 'mailgun.net', 'sinch.com', 'mailgunwarmup.com', 'emailonacid.com', 'elior-na.com', 'brembo.com')
      • headers.auth_summary.dmarc.pass
    • all of:
      • any of recipients.to where:
        • .email.domain.root_domain in ('elior-na.com', 'brembo.com')
      • any of filter(recipients.to) where any holds:
        • strings.icontains(body.html.display_text)
        • strings.icontains(body.html.display_text)
    • all of:
      • any of:
        • sender.email.domain.domain contains 'mailgun'
        • sender.email.local_part contains 'mailgun'
      • any of:
        • any of headers.domains where:
          • .root_domain in ('mailgun.com', 'mailgun.net')
        • sum(map(filter(headers.hops, .index < 2), length(filter(.fields, strings.starts_with(.name, 'X-Mailgun-'))))) ≥ 3
  4. 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, body.html.display_text, body.html.raw, headers.auth_summary.dmarc.pass, headers.domains, headers.domains[].root_domain, headers.hops, headers.hops[].index, recipients.to, recipients.to[].email.domain.root_domain, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.local_part, subject.subject, type.inbound. Sensors: file.message_screenshot, ml.logo_detect, regex.icontains, strings.concat, strings.icontains, strings.replace_confusables, strings.starts_with. Reference lists: $high_trust_sender_root_domains.

Indicators matched (8)

FieldMatchValue
regex.icontainsregexma[il][il]gun
regex.icontainsregex<title>.*mailgun.*</title>
regex.icontainsregexalt\s*=\s*"\s*Mailgun\s*Logo\s*"
regex.icontainsregex[©®]\s*(20\d\d\s*)?Mailgun
regex.icontainsregexmailgun\s*[©®]
ml.logo_detect(file.message_screenshot()).brands[].nameequalsMailgun
ml.logo_detect(file.message_screenshot()).brands[].confidencemembermedium
ml.logo_detect(file.message_screenshot()).brands[].confidencememberhigh

Stages and Predicates

Stage 1: mql_rule

and
  not
    or
      and
        or
          any(headers.domains)
            headers.domains.root_domain in ["mailgun.com", "mailgun.net"]
          sum func_call "sum(map(filter(headers.hops, .index < 2), length(filter(.fields, strings.starts_with(.name, 'X-Mailgun-'))))) >= 3"
        or
          sender.email.domain.domain contains "mailgun"
          sender.email.local_part contains "mailgun"
      and
        any(recipients.to)
          recipients.to.email.domain.root_domain in ["brembo.com", "elior-na.com"]
        any(filter(recipients.to))
          strings.icontains func_call "strings.icontains(body.html.display_text)"
      and
        headers.auth_summary.dmarc.pass eq "true"
        sender.email.domain.root_domain in ["brembo.com", "elior-na.com", "emailonacid.com", "mailgun.com", "mailgun.net", "mailgunwarmup.com", "sinch.com"]
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    any(ml.logo_detect(file.message_screenshot()).brands)
      and
        ml.logo_detect(file.message_screenshot()).brands.confidence in ["high", "medium"]
        ml.logo_detect(file.message_screenshot()).brands.name eq "Mailgun"
    any([sender.display_name, sender.email.domain.domain, sender.email.local_part, subject.subject])
      strings.replace_confusables([sender.display_name, sender.email.domain.domain, sender.email.local_part, subject.subject][]) regex_match "ma[il][il]gun"
    body.current_thread.text regex_match "[©®]\\s*(20\\d\\d\\s*)?Mailgun"
    body.current_thread.text regex_match "mailgun\\s*[©®]"
    body.html.raw regex_match "<title>.*mailgun.*</title>"
    body.html.raw regex_match "alt\\s*=\\s*\"\\s*Mailgun\\s*Logo\\s*\""
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.domainsarray_any(no value, null check)excludes:headers.domains
sender.email.domain.domaincontainsmailgunexcludes:sender.email.domain.domain field:"sender.email.domain.domain" value:"mailgun"
sender.email.local_partcontainsmailgunexcludes:sender.email.local_part field:"sender.email.local_part" value:"mailgun"
recipients.toarray_any(no value, null check)excludes:recipients.to
filter(recipients.to)array_any(no value, null check)excludes:filter(recipients.to)
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
sender.email.domain.root_domaininbrembo.com, elior-na.com, emailonacid.com, mailgun.com, mailgun.net, mailgunwarmup.com, sinch.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textregex_match
  • [©®]\s*(20\d\d\s*)?Mailgun
  • mailgun\s*[©®]
field:"body.current_thread.text" kind:regex_match
body.html.rawregex_match
  • <title>.*mailgun.*</title>
  • alt\s*=\s*"\s*Mailgun\s*Logo\s*"
field:"body.html.raw" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Meta and subsidiaries

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

Impersonation of Meta or Meta's subsidiaries Facebook and Instagram.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.links
  • headers
  • headers.auth_summary
  • headers.reply_to
  • recipients
  • recipients.to
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  // sender display name is a strong enough indicator
  // that it can be used without any other impersonation logic
  (
    regex.icontains(sender.display_name,

                    // this regex looks for a commonly abused phrase starting with 'meta', potentially containing a version of the word 'verified', followed by phrases that have been observed in campaigns.
                    '\bm.?e.?t.?a\b.*(?:verif(?:y|i(?:cado|ed)))?.*\b(?:recruiting|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|account|help|support|service|business|policy|Vérifié|certify|inc|help[ -]?desk)\b',

                    // this regex also looks for a commonly abused phrase starting with 'meta', followed by a phrase, then 'team' with no separating spaces.
                    '\bm.?e.?t.?a(?:recruiting|pro|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|service|account|help|support|business|policy|ads)team',

                    // this regex is similar to the first in this section, but starts with facebook instead of meta
                    '\bf.?a.?c.?e.?b.?o.?o.?k\b.*(?:verif(?:y|i(?:cado|ed)))?.*\b(?:recruiting|ads[ -]?team|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|service|account|help|support|business|policy|Vérifié|certify|inc|help[ -]?desk)\b',
                    '^[a-z]+ from \bmeta$',
                    'page ?ads ?support',
                    'Instagram\s*(?:Not|Policies|Report|Helpdesk|Support)',
                    '\bMeta & Coursera',
                    'Compliance & Security',
                    'social.?media.?\b(?:master|expert|pro|guru)\b',
                    '\bmeta\b.?(?:social|skill|ads).?(?:star|set|expert)',
                    'noreply-(?:meta|fb).+',
                    '(?:meta|facebook|fb|instagram|ig)[-\s]verif'
    )
    or (
      regex.icontains(sender.display_name,
                      "f\u{200a}?a\u{200a}?c\u{200a}?e\u{200a}?b\u{200a}?o\u{200a}?o\u{200a}?k"
      )
      and not strings.icontains(sender.display_name, 'facebook')
    )
    or strings.contains(sender.display_name, "\u{24C2}")
    or strings.ilevenshtein(sender.display_name, 'facebook ads') <= 2
    or strings.ilevenshtein(sender.display_name, 'facebook business') <= 2
    or strings.ilike(sender.email.domain.domain, '*facebook*', "ig-support*")
    or strings.ilike(sender.email.local_part,
                     "*instagramlive*",
                     "*facebooksupport*"
    )
    or strings.icontains(sender.email.domain.subdomain, 'meta-')
    or (
      regex.icontains(body.current_thread.text, '©\s*(?:\d+)\s*meta\b')
      and strings.count(body.current_thread.text, '©') == 1
    )
  )
  // the use of these keywords (facebook, instagram)
  // or the levenshtein distance to facebook
  // are less strong and thus need to be combined with logo detection or nlu
  or (
    (
      regex.icontains(sender.display_name,
                      '\bf[\p{Mn}\p{Cf}]*a[\p{Mn}\p{Cf}]*c[\p{Mn}\p{Cf}]*e[\p{Mn}\p{Cf}]*b[\p{Mn}\p{Cf}]*o[\p{Mn}\p{Cf}]*o[\p{Mn}\p{Cf}]*k[\p{Mn}\p{Cf}]*\b',
                      '\binstagr(am)?\b',
                      '\bm[\p{Mn}\p{Cf}]*e[\p{Mn}\p{Cf}]*t[\p{Mn}\p{Cf}]*a\b'
      )
      or strings.ilevenshtein(sender.display_name, 'facebook') <= 2
      or sender.email.email == 'noreply@appsheet.com'
    )
    and 2 of (
      any(ml.logo_detect(file.message_screenshot()).brands,
          .name in ("Facebook", "Meta", "Instagram", "Threads")
      ),
      any(ml.nlu_classifier(body.current_thread.text).intents,
          .name in ("cred_theft", "callback_scam", "steal_pii")
          and .confidence in ("medium", "high")
      ),
      (
        length(body.current_thread.text) < 2000
        and regex.icontains(body.current_thread.text, "(?:violation|infringe)")
      ),
      regex.icontains(subject.base,
                      '\b(?:recruiting|permanently|locked|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|account|help|support|business|policy|verif(?:y|i(?:cado|ed))|Vérifié|Trademark|Misuse|Review|Violation|Warning|Restriction|Inappropriate|service|Content|multiple reports)\b'
      ),
      any(body.links,
          .href_url.domain.root_domain in $self_service_creation_platform_domains
          or .href_url.domain.root_domain in $free_file_hosts
          or .href_url.domain.root_domain in $free_subdomain_hosts
          or .href_url.domain.root_domain in $url_shorteners
      ),
      sender.email.domain.root_domain in $free_email_providers
    )
  )
  // salesforce sender combined with logo detection and nlu is enough
  or (
    sender.email.domain.root_domain == "salesforce.com"
    and any(ml.logo_detect(file.message_screenshot()).brands,
            .name in ("Facebook", "Meta", "Instagram", "Threads")
    )
    and any(ml.nlu_classifier(body.current_thread.text).intents,
            .name in ("cred_theft", "callback_scam", "steal_pii")
            and .confidence in ("medium", "high")
    )
  )
  or 
  // or the body contains a facebook/meta footer with the address citing "community support"
  (
    (
      regex.icontains(body.current_thread.text,
                      '(?:1\s+(?:Facebook|Hacker|Meta)?\s*Way|1601\s+Willow\s+Rd?).*Menlo\s+Park.*CA.*94025'
      )
      or (
        regex.icontains(body.current_thread.text,
                        '(?:Security Team © Meta|Meta Support Team)'
        )
      )
    )
    // and it contains a link to spawn a chat with facebook - this is not the way support operates
    and (
      any(body.links,
          strings.ends_with(.href_url.domain.domain, 'facebook.com')
          and strings.starts_with(.href_url.path, '/msg/')
      )
      or (
        any(ml.nlu_classifier(body.current_thread.text).intents,
            .name in ("cred_theft", "callback_scam", "steal_pii")
            and .confidence in ("high")
        )
      )
      or any(recipients.to,
             .email.domain.valid
             and any(body.links,
                     strings.icontains(.href_url.url, ..email.email)
                     or any(strings.scan_base64(.href_url.url,
                                                format="url",
                                                ignore_padding=true
                            ),
                            strings.icontains(., ...email.email)
                     )
                     or any(strings.scan_base64(.href_url.fragment,
                                                ignore_padding=true
                            ),
                            strings.icontains(., ...email.email)
                     )
             )
      )
    )
  )
  // we've seen advertising "advice/recommendations"
  or (
    all(ml.nlu_classifier(body.current_thread.text).topics,
        .name in ("Advertising and Promotions", "Reminders and Notifications")
    )
    // Meta mention
    and (
      any(ml.nlu_classifier(body.current_thread.text).entities,
          .name == "org" and strings.icontains(.text, 'Community Guidelines')
      )
      or regex.icontains(body.current_thread.text,
                         '(1\s+(Facebook|Hacker|\bMeta\b)?\s*Way|1601\s+Willow\s+Rd?).*Menlo\s+Park.*CA.*94025'
      )
    )
    and any(ml.nlu_classifier(body.current_thread.text).entities,
            .name == "urgency"
    )
  )
  or (
    strings.icontains(body.current_thread.text, "Meta Professional Certificate")
    and strings.icontains(body.current_thread.text, "Meta & Coursera Team")
    // Add link validation
    and any(body.links,
            strings.icontains(.display_text, "coursera")
            and .href_url.domain.root_domain != "coursera.org"
    )
  )
  or 2 of (
    strings.icontains(body.current_thread.text, 'Meta '),
    strings.icontains(body.current_thread.text, '1602 Willow Road'),
    strings.icontains(body.current_thread.text, 'Menlo Park, CA 91024'),
  )
)
and sender.email.domain.root_domain not in~ (
  'facebook.com',
  'facebookmail.com',
  'eventsatfacebook.com',
  'facebookenterprise.com',
  'meta.com',
  'metamail.com',
  'instagram.com',
  'medallia.com',
  'fbworkmail.com',
  'workplace.com',
  'capterra.com', // they mention "Community Guidelines"
  'facebookblueprint.com',
  'metaenterprisemail.com',
  'pigfacebookstore.com.au', // unrelated domain but hitting on facebook
  'metacompliance.com',
  'metaprop.com', // unrelated domain but hitting on meta pro
  'oakley.com', // meta intelligence glasses
  'facebookuserprivacysettlement.com', // fb settlement website
  'perceptyx.com', // ai employee engagement
  'unroll.me', // unroll contains instagram logo
  'har.com' // facebook ads management
)
// negate metaenterprise links
and not any(headers.reply_to, .email.email == "noreply@facebookmail.com")

// meta wiki renamer
and not (
  sender.display_name == 'Meta-Wiki'
  and sender.email.domain.root_domain == 'wikimedia.org'
)

// we dont want emails where all the links go to meta domains
and not (
  (
    length(body.links) > 1
    and all(body.links,
            .href_url.domain.root_domain in (
              'facebook.com',
              'instagram.com',
              'meta.com'
            )
            and not strings.istarts_with(.href_url.path, '/share/')
    )
  )
  // too many links
  or length(body.links) > 20
)

// no previous threads
and length(body.previous_threads) == 0

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

  // salesforce has been abused for meta phishing campaigns repeatedly
  or sender.email.domain.root_domain == "salesforce.com"
)

Detection logic

Scope: inbound message.

Impersonation of Meta or Meta's subsidiaries Facebook and Instagram.

  1. inbound message
  2. any of:
    • any of:
      • sender.display_name matches any of 12 patterns
        • \bm.?e.?t.?a\b.*(?:verif(?:y|i(?:cado|ed)))?.*\b(?:recruiting|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|account|help|support|service|business|policy|Vérifié|certify|inc|help[ -]?desk)\b
        • \bm.?e.?t.?a(?:recruiting|pro|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|service|account|help|support|business|policy|ads)team
        • \bf.?a.?c.?e.?b.?o.?o.?k\b.*(?:verif(?:y|i(?:cado|ed)))?.*\b(?:recruiting|ads[ -]?team|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|service|account|help|support|business|policy|Vérifié|certify|inc|help[ -]?desk)\b
        • ^[a-z]+ from \bmeta$
        • page ?ads ?support
        • Instagram\s*(?:Not|Policies|Report|Helpdesk|Support)
        • \bMeta & Coursera
        • Compliance & Security
        • social.?media.?\b(?:master|expert|pro|guru)\b
        • \bmeta\b.?(?:social|skill|ads).?(?:star|set|expert)
        • noreply-(?:meta|fb).+
        • (?:meta|facebook|fb|instagram|ig)[-\s]verif
      • all of:
        • sender.display_name matches 'f\\u{200a}?a\\u{200a}?c\\u{200a}?e\\u{200a}?b\\u{200a}?o\\u{200a}?o\\u{200a}?k'
        • not:
          • sender.display_name contains 'facebook'
      • sender.display_name contains '\\u{24C2}'
      • sender.display_name is similar to 'facebook ads'
      • sender.display_name is similar to 'facebook business'
      • sender.email.domain.domain matches any of 2 patterns
        • *facebook*
        • ig-support*
      • sender.email.local_part matches any of 2 patterns
        • *instagramlive*
        • *facebooksupport*
      • sender.email.domain.subdomain contains 'meta-'
      • all of:
        • body.current_thread.text matches '©\\s*(?:\\d+)\\s*meta\\b'
        • strings.count(body.current_thread.text, '©') is 1
    • all of:
      • any of:
        • sender.display_name matches any of 3 patterns
          • \bf[\p{Mn}\p{Cf}]*a[\p{Mn}\p{Cf}]*c[\p{Mn}\p{Cf}]*e[\p{Mn}\p{Cf}]*b[\p{Mn}\p{Cf}]*o[\p{Mn}\p{Cf}]*o[\p{Mn}\p{Cf}]*k[\p{Mn}\p{Cf}]*\b
          • \binstagr(am)?\b
          • \bm[\p{Mn}\p{Cf}]*e[\p{Mn}\p{Cf}]*t[\p{Mn}\p{Cf}]*a\b
        • sender.display_name is similar to 'facebook'
        • sender.email.email is 'noreply@appsheet.com'
      • at least 2 of:
        • any of ml.logo_detect(file.message_screenshot()).brands where:
          • .name in ('Facebook', 'Meta', 'Instagram', 'Threads')
        • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
          • .name in ('cred_theft', 'callback_scam', 'steal_pii')
          • .confidence in ('medium', 'high')
        • all of:
          • length(body.current_thread.text) < 2000
          • body.current_thread.text matches '(?:violation|infringe)'
        • subject.base matches '\\b(?:recruiting|permanently|locked|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|account|help|support|business|policy|verif(?:y|i(?:cado|ed))|Vérifié|Trademark|Misuse|Review|Violation|Warning|Restriction|Inappropriate|service|Content|multiple reports)\\b'
        • any of body.links where any holds:
          • .href_url.domain.root_domain in $self_service_creation_platform_domains
          • .href_url.domain.root_domain in $free_file_hosts
          • .href_url.domain.root_domain in $free_subdomain_hosts
          • .href_url.domain.root_domain in $url_shorteners
        • sender.email.domain.root_domain in $free_email_providers
    • all of:
      • sender.email.domain.root_domain is 'salesforce.com'
      • any of ml.logo_detect(file.message_screenshot()).brands where:
        • .name in ('Facebook', 'Meta', 'Instagram', 'Threads')
      • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
        • .name in ('cred_theft', 'callback_scam', 'steal_pii')
        • .confidence in ('medium', 'high')
    • all of:
      • any of:
        • body.current_thread.text matches '(?:1\\s+(?:Facebook|Hacker|Meta)?\\s*Way|1601\\s+Willow\\s+Rd?).*Menlo\\s+Park.*CA.*94025'
        • body.current_thread.text matches '(?:Security Team © Meta|Meta Support Team)'
      • any of:
        • any of body.links where all hold:
          • .href_url.domain.domain ends with 'facebook.com'
          • .href_url.path starts with '/msg/'
        • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
          • .name in ('cred_theft', 'callback_scam', 'steal_pii')
          • .confidence in ('high')
        • any of recipients.to where all hold:
          • .email.domain.valid
          • any of body.links where any holds:
            • strings.icontains(.href_url.url)
            • any of strings.scan_base64(.href_url.url) where:
              • strings.icontains(.)
            • any of strings.scan_base64(.href_url.fragment) where:
              • strings.icontains(.)
    • all of:
      • all of ml.nlu_classifier(body.current_thread.text).topics where:
        • .name in ('Advertising and Promotions', 'Reminders and Notifications')
      • any of:
        • any of ml.nlu_classifier(body.current_thread.text).entities where all hold:
          • .name is 'org'
          • .text contains 'Community Guidelines'
        • body.current_thread.text matches '(1\\s+(Facebook|Hacker|\\bMeta\\b)?\\s*Way|1601\\s+Willow\\s+Rd?).*Menlo\\s+Park.*CA.*94025'
      • any of ml.nlu_classifier(body.current_thread.text).entities where:
        • .name is 'urgency'
    • all of:
      • body.current_thread.text contains 'Meta Professional Certificate'
      • body.current_thread.text contains 'Meta & Coursera Team'
      • any of body.links where all hold:
        • .display_text contains 'coursera'
        • .href_url.domain.root_domain is not 'coursera.org'
    • at least 2 of:
      • body.current_thread.text contains 'Meta '
      • body.current_thread.text contains '1602 Willow Road'
      • body.current_thread.text contains 'Menlo Park, CA 91024'
  3. sender.email.domain.root_domain not in ('facebook.com', 'facebookmail.com', 'eventsatfacebook.com', 'facebookenterprise.com', 'meta.com', 'metamail.com', 'instagram.com', 'medallia.com', 'fbworkmail.com', 'workplace.com', 'capterra.com', 'facebookblueprint.com', 'metaenterprisemail.com', 'pigfacebookstore.com.au', 'metacompliance.com', 'metaprop.com', 'oakley.com', 'facebookuserprivacysettlement.com', 'perceptyx.com', 'unroll.me', 'har.com')
  4. not:
    • any of headers.reply_to where:
      • .email.email is 'noreply@facebookmail.com'
  5. not:
    • all of:
      • sender.display_name is 'Meta-Wiki'
      • sender.email.domain.root_domain is 'wikimedia.org'
  6. none of:
    • all of:
      • length(body.links) > 1
      • all of body.links where all hold:
        • .href_url.domain.root_domain in ('facebook.com', 'instagram.com', 'meta.com')
        • not:
          • .href_url.path starts with '/share/'
    • length(body.links) > 20
  7. length(body.previous_threads) is 0
  8. 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
    • sender.email.domain.root_domain is 'salesforce.com'

Inspects: body.current_thread.text, body.links, body.links[].display_text, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.fragment, body.links[].href_url.path, body.links[].href_url.url, body.previous_threads, headers.auth_summary.dmarc.pass, headers.reply_to, headers.reply_to[].email.email, recipients.to, recipients.to[].email.domain.valid, recipients.to[].email.email, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.domain.subdomain, sender.email.email, sender.email.local_part, subject.base, type.inbound. Sensors: file.message_screenshot, ml.logo_detect, ml.nlu_classifier, regex.icontains, strings.contains, strings.count, strings.ends_with, strings.icontains, strings.ilevenshtein, strings.ilike, strings.istarts_with, strings.scan_base64, strings.starts_with. Reference lists: $free_email_providers, $free_file_hosts, $free_subdomain_hosts, $high_trust_sender_root_domains, $self_service_creation_platform_domains, $url_shorteners.

Indicators matched (56)

FieldMatchValue
regex.icontainsregex\bm.?e.?t.?a\b.*(?:verif(?:y|i(?:cado|ed)))?.*\b(?:recruiting|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|account|help|support|service|business|policy|Vérifié|certify|inc|help[ -]?desk)\b
regex.icontainsregex\bm.?e.?t.?a(?:recruiting|pro|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|service|account|help|support|business|policy|ads)team
regex.icontainsregex\bf.?a.?c.?e.?b.?o.?o.?k\b.*(?:verif(?:y|i(?:cado|ed)))?.*\b(?:recruiting|ads[ -]?team|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|service|account|help|support|business|policy|Vérifié|certify|inc|help[ -]?desk)\b
regex.icontainsregex^[a-z]+ from \bmeta$
regex.icontainsregexpage ?ads ?support
regex.icontainsregexInstagram\s*(?:Not|Policies|Report|Helpdesk|Support)
regex.icontainsregex\bMeta & Coursera
regex.icontainsregexCompliance & Security
regex.icontainsregexsocial.?media.?\b(?:master|expert|pro|guru)\b
regex.icontainsregex\bmeta\b.?(?:social|skill|ads).?(?:star|set|expert)
regex.icontainsregexnoreply-(?:meta|fb).+
regex.icontainsregex(?:meta|facebook|fb|instagram|ig)[-\s]verif
44 more
regex.icontainsregexf\u{200a}?a\u{200a}?c\u{200a}?e\u{200a}?b\u{200a}?o\u{200a}?o\u{200a}?k
strings.containssubstring\u{24C2}
strings.ilevenshteinfuzzyfacebook ads
strings.ilevenshteinfuzzyfacebook business
strings.ilikesubstring*facebook*
strings.ilikesubstringig-support*
strings.ilikesubstring*instagramlive*
strings.ilikesubstring*facebooksupport*
strings.icontainssubstringmeta-
regex.icontainsregex©\s*(?:\d+)\s*meta\b
regex.icontainsregex\bf[\p{Mn}\p{Cf}]*a[\p{Mn}\p{Cf}]*c[\p{Mn}\p{Cf}]*e[\p{Mn}\p{Cf}]*b[\p{Mn}\p{Cf}]*o[\p{Mn}\p{Cf}]*o[\p{Mn}\p{Cf}]*k[\p{Mn}\p{Cf}]*\b
regex.icontainsregex\binstagr(am)?\b
regex.icontainsregex\bm[\p{Mn}\p{Cf}]*e[\p{Mn}\p{Cf}]*t[\p{Mn}\p{Cf}]*a\b
strings.ilevenshteinfuzzyfacebook
sender.email.emailequalsnoreply@appsheet.com
ml.logo_detect(file.message_screenshot()).brands[].namememberFacebook
ml.logo_detect(file.message_screenshot()).brands[].namememberMeta
ml.logo_detect(file.message_screenshot()).brands[].namememberInstagram
ml.logo_detect(file.message_screenshot()).brands[].namememberThreads
ml.nlu_classifier(body.current_thread.text).intents[].namemembercred_theft
ml.nlu_classifier(body.current_thread.text).intents[].namemembercallback_scam
ml.nlu_classifier(body.current_thread.text).intents[].namemembersteal_pii
ml.nlu_classifier(body.current_thread.text).intents[].confidencemembermedium
ml.nlu_classifier(body.current_thread.text).intents[].confidencememberhigh
regex.icontainsregex(?:violation|infringe)
regex.icontainsregex\b(?:recruiting|permanently|locked|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|account|help|support|business|policy|verif(?:y|i(?:cado|ed))|Vérifié|Trademark|Misuse|Review|Violation|Warning|Restriction|Inappropriate|service|Content|multiple reports)\b
sender.email.domain.root_domainequalssalesforce.com
regex.icontainsregex(?:1\s+(?:Facebook|Hacker|Meta)?\s*Way|1601\s+Willow\s+Rd?).*Menlo\s+Park.*CA.*94025
regex.icontainsregex(?:Security Team © Meta|Meta Support Team)
strings.ends_withsuffixfacebook.com
strings.starts_withprefix/msg/
ml.nlu_classifier(body.current_thread.text).topics[].namememberAdvertising and Promotions
ml.nlu_classifier(body.current_thread.text).topics[].namememberReminders and Notifications
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsorg
strings.icontainssubstringCommunity Guidelines
regex.icontainsregex(1\s+(Facebook|Hacker|\bMeta\b)?\s*Way|1601\s+Willow\s+Rd?).*Menlo\s+Park.*CA.*94025
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsurgency
strings.icontainssubstringMeta Professional Certificate
strings.icontainssubstringMeta & Coursera Team
strings.icontainssubstringcoursera
strings.icontainssubstringMeta
strings.icontainssubstring1602 Willow Road
strings.icontainssubstringMenlo Park, CA 91024
strings.istarts_withprefix/share/

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      or
        any(recipients.to)
          and
            any(body.links)
              or
                any(strings.scan_base64(body.links.href_url.fragment))
                  strings.icontains func_call "strings.icontains(strings.scan_base64(body.links[].href_url.fragment)[])"
                any(strings.scan_base64(body.links.href_url.url))
                  strings.icontains func_call "strings.icontains(strings.scan_base64(body.links[].href_url.url)[])"
                strings.icontains func_call "strings.icontains(body.links[].href_url.url)"
            recipients.to.email.domain.valid eq "true"
        any(body.links)
          and
            body.links.href_url.domain.domain ends_with "facebook.com"
            body.links.href_url.path starts_with "/msg/"
        any(ml.nlu_classifier(body.current_thread.text).intents)
          and
            ml.nlu_classifier(body.current_thread.text).intents.confidence eq "high"
            ml.nlu_classifier(body.current_thread.text).intents.name in ["callback_scam", "cred_theft", "steal_pii"]
      or
        body.current_thread.text regex_match "(?:1\\s+(?:Facebook|Hacker|Meta)?\\s*Way|1601\\s+Willow\\s+Rd?).*Menlo\\s+Park.*CA.*94025"
        body.current_thread.text regex_match "(?:Security Team © Meta|Meta Support Team)"
    and
      or
        any(ml.nlu_classifier(body.current_thread.text).entities)
          and
            ml.nlu_classifier(body.current_thread.text).entities.name eq "org"
            ml.nlu_classifier(body.current_thread.text).entities.text contains "Community Guidelines"
        body.current_thread.text regex_match "(1\\s+(Facebook|Hacker|\\bMeta\\b)?\\s*Way|1601\\s+Willow\\s+Rd?).*Menlo\\s+Park.*CA.*94025"
      any(ml.nlu_classifier(body.current_thread.text).entities)
        ml.nlu_classifier(body.current_thread.text).entities.name eq "urgency"
       macro "all(ml.nlu_classifier(body.current_thread.text).topics)"
    and
      or
        any(ml.nlu_classifier(body.current_thread.text).intents)
          and
            ml.nlu_classifier(body.current_thread.text).intents.confidence in ["high", "medium"]
            ml.nlu_classifier(body.current_thread.text).intents.name in ["callback_scam", "cred_theft", "steal_pii"]
        any(body.links)
          or
             macro "body.links[].href_url.domain.root_domain in free_file_hosts"
             macro "body.links[].href_url.domain.root_domain in free_subdomain_hosts"
             macro "body.links[].href_url.domain.root_domain in self_service_creation_platform_domains"
             macro "body.links[].href_url.domain.root_domain in url_shorteners"
        and
          body.current_thread.text length_compare "2000"
          body.current_thread.text regex_match "(?:violation|infringe)"
        any(ml.logo_detect(file.message_screenshot()).brands)
          ml.logo_detect(file.message_screenshot()).brands.name in ["Facebook", "Instagram", "Meta", "Threads"]
        subject.base regex_match "\\b(?:recruiting|permanently|locked|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|account|help|support|business|policy|verif(?:y|i(?:cado|ed))|Vérifié|Trademark|Misuse|Review|Violation|Warning|Restriction|Inappropriate|service|Content|multiple reports)\\b"
         macro "sender.email.domain.root_domain in free_email_providers"
      or
        sender.display_name regex_match "\\bf[\\p{Mn}\\p{Cf}]*a[\\p{Mn}\\p{Cf}]*c[\\p{Mn}\\p{Cf}]*e[\\p{Mn}\\p{Cf}]*b[\\p{Mn}\\p{Cf}]*o[\\p{Mn}\\p{Cf}]*o[\\p{Mn}\\p{Cf}]*k[\\p{Mn}\\p{Cf}]*\\b"
        sender.display_name regex_match "\\binstagr(am)?\\b"
        sender.display_name regex_match "\\bm[\\p{Mn}\\p{Cf}]*e[\\p{Mn}\\p{Cf}]*t[\\p{Mn}\\p{Cf}]*a\\b"
        sender.email.email eq "noreply@appsheet.com"
        strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"facebook\") <= 2"
    and
      any(body.links)
        and
          body.links.display_text contains "coursera"
          body.links.href_url.domain.root_domain ne "coursera.org"
      body.current_thread.text contains "Meta & Coursera Team"
      body.current_thread.text contains "Meta Professional Certificate"
    and
      any(ml.nlu_classifier(body.current_thread.text).intents)
        and
          ml.nlu_classifier(body.current_thread.text).intents.confidence in ["high", "medium"]
          ml.nlu_classifier(body.current_thread.text).intents.name in ["callback_scam", "cred_theft", "steal_pii"]
      any(ml.logo_detect(file.message_screenshot()).brands)
        ml.logo_detect(file.message_screenshot()).brands.name in ["Facebook", "Instagram", "Meta", "Threads"]
      sender.email.domain.root_domain eq "salesforce.com"
    and
      not
        sender.display_name contains "facebook"
      sender.display_name regex_match "f\\u{200a}?a\\u{200a}?c\\u{200a}?e\\u{200a}?b\\u{200a}?o\\u{200a}?o\\u{200a}?k"
    and
      body.current_thread.text regex_match "©\\s*(?:\\d+)\\s*meta\\b"
      strings.count func_call "strings.count(body.current_thread.text, \"©\") == 1"
    body.current_thread.text contains "1602 Willow Road"
    body.current_thread.text contains "Menlo Park, CA 91024"
    body.current_thread.text contains "Meta "
    sender.display_name contains "\\u{24C2}"
    sender.display_name regex_match "(?:meta|facebook|fb|instagram|ig)[-\\s]verif"
    sender.display_name regex_match "Compliance & Security"
    sender.display_name regex_match "Instagram\\s*(?:Not|Policies|Report|Helpdesk|Support)"
    sender.display_name regex_match "\\bMeta & Coursera"
    sender.display_name regex_match "\\bf.?a.?c.?e.?b.?o.?o.?k\\b.*(?:verif(?:y|i(?:cado|ed)))?.*\\b(?:recruiting|ads[ -]?team|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|service|account|help|support|business|policy|Vérifié|certify|inc|help[ -]?desk)\\b"
    sender.display_name regex_match "\\bm.?e.?t.?a(?:recruiting|pro|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|service|account|help|support|business|policy|ads)team"
    sender.display_name regex_match "\\bm.?e.?t.?a\\b.*(?:verif(?:y|i(?:cado|ed)))?.*\\b(?:recruiting|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|account|help|support|service|business|policy|Vérifié|certify|inc|help[ -]?desk)\\b"
    sender.display_name regex_match "\\bmeta\\b.?(?:social|skill|ads).?(?:star|set|expert)"
    sender.display_name regex_match "^[a-z]+ from \\bmeta$"
    sender.display_name regex_match "noreply-(?:meta|fb).+"
    sender.display_name regex_match "page ?ads ?support"
    sender.display_name regex_match "social.?media.?\\b(?:master|expert|pro|guru)\\b"
    sender.email.domain.domain match "facebook"
    sender.email.domain.domain starts_with "ig-support"
    sender.email.domain.subdomain contains "meta-"
    sender.email.local_part match "facebooksupport"
    sender.email.local_part match "instagramlive"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"facebook ads\") <= 2"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"facebook business\") <= 2"
  not
    or
      and
        body.links length_compare "1"
         macro "all(body.links)"
      body.links length_compare "20"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
    sender.email.domain.root_domain eq "salesforce.com"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    any(headers.reply_to)
      headers.reply_to.email.email eq "noreply@facebookmail.com"
  not
    and
      sender.display_name eq "Meta-Wiki"
      sender.email.domain.root_domain eq "wikimedia.org"
  not
    sender.email.domain.root_domain in ["capterra.com", "eventsatfacebook.com", "facebook.com", "facebookblueprint.com", "facebookenterprise.com", "facebookmail.com", "facebookuserprivacysettlement.com", "fbworkmail.com", "har.com", "instagram.com", "medallia.com", "meta.com", "metacompliance.com", "metaenterprisemail.com", "metamail.com", "metaprop.com", "oakley.com", "perceptyx.com", "pigfacebookstore.com.au", "unroll.me", "workplace.com"]
  body.previous_threads length_compare "0"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
body.linkslength_compare1excludes:body.links field:"body.links" value:"1"
body.linkslength_compare20excludes:body.links field:"body.links" value:"20"
headers.reply_toarray_any(no value, null check)excludes:headers.reply_to
sender.display_nameeqMeta-Wikiexcludes:sender.display_name field:"sender.display_name" value:"Meta-Wiki"
sender.email.domain.root_domaineqwikimedia.orgexcludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"wikimedia.org"
sender.email.domain.root_domainincapterra.com, eventsatfacebook.com, facebook.com, facebookblueprint.com, facebookenterprise.com, facebookmail.com, facebookuserprivacysettlement.com, fbworkmail.com, har.com, instagram.com, medallia.com, meta.com, metacompliance.com, metaenterprisemail.com, metamail.com, metaprop.com, oakley.com, perceptyx.com, pigfacebookstore.com.au, unroll.me, workplace.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textcontains
  • 1602 Willow Road
  • Menlo Park, CA 91024
  • Meta
  • Meta & Coursera Team
  • Meta Professional Certificate
field:"body.current_thread.text" kind:contains
body.current_thread.textregex_match
  • (1\s+(Facebook|Hacker|\bMeta\b)?\s*Way|1601\s+Willow\s+Rd?).*Menlo\s+Park.*CA.*94025
  • (?:1\s+(?:Facebook|Hacker|Meta)?\s*Way|1601\s+Willow\s+Rd?).*Menlo\s+Park.*CA.*94025
  • (?:Security Team © Meta|Meta Support Team)
  • (?:violation|infringe)
  • ©\s*(?:\d+)\s*meta\b
field:"body.current_thread.text" kind:regex_match
sender.display_namecontains
  • \u{24C2}
field:"sender.display_name" kind:contains value:"\u{24C2}"
sender.display_nameregex_match
  • (?:meta|facebook|fb|instagram|ig)[-\s]verif
  • Compliance & Security
  • Instagram\s*(?:Not|Policies|Report|Helpdesk|Support)
  • \bMeta & Coursera
  • \bf.?a.?c.?e.?b.?o.?o.?k\b.*(?:verif(?:y|i(?:cado|ed)))?.*\b(?:recruiting|ads[ -]?team|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|service|account|help|support|business|policy|Vérifié|certify|inc|help[ -]?desk)\b
  • \bf[\p{Mn}\p{Cf}]*a[\p{Mn}\p{Cf}]*c[\p{Mn}\p{Cf}]*e[\p{Mn}\p{Cf}]*b[\p{Mn}\p{Cf}]*o[\p{Mn}\p{Cf}]*o[\p{Mn}\p{Cf}]*k[\p{Mn}\p{Cf}]*\b
  • \binstagr(am)?\b
  • \bm.?e.?t.?a(?:recruiting|pro|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|service|account|help|support|business|policy|ads)team
  • \bm.?e.?t.?a\b.*(?:verif(?:y|i(?:cado|ed)))?.*\b(?:recruiting|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|account|help|support|service|business|policy|Vérifié|certify|inc|help[ -]?desk)\b
  • \bm[\p{Mn}\p{Cf}]*e[\p{Mn}\p{Cf}]*t[\p{Mn}\p{Cf}]*a\b
  • \bmeta\b.?(?:social|skill|ads).?(?:star|set|expert)
  • ^[a-z]+ from \bmeta$
  • f\u{200a}?a\u{200a}?c\u{200a}?e\u{200a}?b\u{200a}?o\u{200a}?o\u{200a}?k
  • noreply-(?:meta|fb).+
  • page ?ads ?support
  • social.?media.?\b(?:master|expert|pro|guru)\b
field:"sender.display_name" kind:regex_match
sender.email.domain.domainwildcard
  • *facebook*
  • ig-support*
field:"sender.email.domain.domain" kind:wildcard
sender.email.domain.root_domaineq
  • salesforce.com
field:"sender.email.domain.root_domain" kind:eq value:"salesforce.com"
sender.email.domain.subdomaincontains
  • meta-
field:"sender.email.domain.subdomain" kind:contains value:"meta-"
sender.email.emaileq
  • noreply@appsheet.com
field:"sender.email.email" kind:eq value:"noreply@appsheet.com"
sender.email.local_partwildcard
  • *facebooksupport*
  • *instagramlive*
field:"sender.email.local_part" kind:wildcard
subject.baseregex_match
  • \b(?:recruiting|permanently|locked|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|account|help|support|business|policy|verif(?:y|i(?:cado|ed))|Vérifié|Trademark|Misuse|Review|Violation|Warning|Restriction|Inappropriate|service|Content|multiple reports)\b
field:"subject.base" kind:regex_match value:"\b(?:recruiting|permanently|locked|certification|trust|safety|badge|alert|advertising|compliance|copyright|enforcement|intellectual|rights|account|help|support|business|policy|verif(?:y|i(?:cado|ed))|Vérifié|Trademark|Misuse|Review|Violation|Warning|Restriction|Inappropriate|service|Content|multiple reports)\b"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Microsoft

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

Impersonation of the Microsoft brand.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • body.links
  • headers
  • headers.auth_summary
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  length(body.links) < 30
  or sender.email.local_part == "newsletter" and length(body.links) < 5
)
and (
  (
    strings.ilike(subject.subject, '*Microsoft 365*')
    and strings.ilike(subject.subject, '*is expired*')
  )
  or (
    // should catch any instance of the word "expired"
    strings.ilike(body.current_thread.text, "*expir*")
    and strings.ilike(body.current_thread.text, "*password*")
    and strings.ilike(body.current_thread.text, "*microsoft*")
  )
  or regex.icontains(body.current_thread.text,
                     ".*reach you.{0,20}Microsoft Teams",
                     "microsoft account\n2fa"
  )
  or strings.icontains(body.current_thread.text, "microsoft account team")
  or strings.ilike(sender.display_name, '*new activity in Teams*')
  or strings.icontains(strings.replace_confusables(sender.display_name),
                       'microsoft advertising support'
  )
  or subject.subject =~ 'Offline Message in Teams'
  or strings.ilike(subject.subject, '*Teams Sent A Message')
  or sender.display_name in~ (
    'Microsoft Partner Network',
    'Microsoft Advertising',
    'Microsoft',
    'Microsoft Feedback',
    'Microsoft account team',
    'Microsoft Support',
    'Microsoft 365 Message center',
    'Microsoft Azure'
  )
  or regex.icontains(sender.display_name,
                     "[MḾṀṂⱮМḿṁṃᵯⱮ𝐌𝑀][iíìîïīĭĩįıɪɨᵢⁱ𝐢𝑖][cćĉċčçƈȼ𝐜𝑐][rŕŗřȑȓɾᵣⁿʳ𝐫𝑟][oóòôõöøōŏőɵₒᵒº𝐨𝑜][sśŝšșşʂᵴˢˢ𝐬𝑠][oóòôõöøōŏőɵₒᵒº𝐨𝑜][fḟƒᵮᶠ𝐟𝑓][tťțţᵵₜᵗᵗ𝐭𝑡]"
  )
  or regex.icontains(sender.display_name,
                     "[MḾṀṂⱮМḿṁṃᵯⱮ𝐌𝑀][iíìîïīĭĩįıɪɨᵢⁱ𝐢𝑖][rŕŗřȑȓɾᵣⁿʳ𝐫𝑟][cćĉċčçƈȼ𝐜𝑐][oóòôõöøōŏőɵₒᵒº𝐨𝑜][sśŝšșşʂᵴˢˢ𝐬𝑠][oóòôõöøōŏőɵₒᵒº𝐨𝑜][fḟƒᵮᶠ𝐟𝑓][tťțţᵵₜᵗᵗ𝐭𝑡]" // [sic]
  )
  or any(attachments,
         .file_extension == "pdf"
         and beta.parse_exif(.).page_count == 1
         and any(ml.logo_detect(.).brands, .name == "Microsoft")
         and any(file.explode(.),
                 regex.icontains(.scan.ocr.raw, '[©@]\s*(?:\d+)?\s*Microsoft')
         )
  )
)
and not (
  sender.email.domain.root_domain in~ (
    'microsoft.com',
    'microsoftstoreemail.com',
    'microsoftsupport.com',
    'office.com',
    'teams-events.com',
    'qualtrics-research.com',
    'skype.com',
    'azureadnotifications.us',
    'microsoftonline.us',
    'mail.microsoft',
    'office365.com',
    'microsoftadvertising.com'
  )
  and headers.auth_summary.dmarc.pass
)
and not (
  sender.email.domain.domain in~ (
    'microsoft.regsvc.com',
    'microsoft.onmicrosoft.com'
  )
  and headers.auth_summary.dmarc.pass
)
and (
  profile.by_sender().prevalence in ("new", "outlier")
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)

// negate legitimate Office 365 bouncebacks
and not (
  all(attachments,
      .content_type in ("message/delivery-status", "message/rfc822")
  )
  and (
    sender.email.local_part in ('postmaster', 'mailer-daemon')
    or strings.starts_with(sender.email.local_part, 'microsoftexchange')
  )
  and (
    strings.contains(subject.subject, 'Undeliverable:')
    or strings.contains(subject.subject, 'Blocked:')
    or strings.contains(subject.subject, 'Não é possível entregar:')
    or strings.contains(subject.subject, 'Nie można dostarczyć:')
    or strings.contains(subject.subject, 'Non remis :')
    or strings.contains(subject.subject, 'Teslim edilmez:')
    or strings.contains(subject.subject, 'No se puede entregar:')
  )
)

// negate other legitimate MS notifications
and not (
  length(body.links) > 0
  and (
    (
      all(body.links,
          .href_url.domain.root_domain in (
            "aka.ms",
            "microsoftonline.com",
            "microsoft.com"
          )
          or .href_url.domain.tld == "microsoft"
      )
      and headers.auth_summary.dmarc.pass
    )

    // microsoft b2b applications invitations - no auth checks
    or (
      sender.email.local_part == "invites"
      and sender.email.domain.root_domain == "onmicrosoft.com"
      // infra validated message id
      and strings.icontains(headers.message_id, "pepf")
    )
  )
)

// 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)
)
// not a newsletter or advertisement
and not (
  any(ml.nlu_classifier(body.current_thread.text).topics,
      .name in ("Newsletters and Digests") and .confidence == "high"
  )
  and (
    any(body.links,
        strings.icontains(.display_text, "unsubscribe")
        and (strings.icontains(.href_url.path, "unsubscribe"))
    )
  )
)

Detection logic

Scope: inbound message.

Impersonation of the Microsoft brand.

  1. inbound message
  2. any of:
    • length(body.links) < 30
    • all of:
      • sender.email.local_part is 'newsletter'
      • length(body.links) < 5
  3. any of:
    • all of:
      • subject.subject matches '*Microsoft 365*'
      • subject.subject matches '*is expired*'
    • all of:
      • body.current_thread.text matches '*expir*'
      • body.current_thread.text matches '*password*'
      • body.current_thread.text matches '*microsoft*'
    • body.current_thread.text matches any of 2 patterns
      • .*reach you.{0,20}Microsoft Teams
      • microsoft account\n2fa
    • body.current_thread.text contains 'microsoft account team'
    • sender.display_name matches '*new activity in Teams*'
    • strings.replace_confusables(sender.display_name) contains 'microsoft advertising support'
    • subject.subject is 'Offline Message in Teams'
    • subject.subject matches '*Teams Sent A Message'
    • sender.display_name in ('Microsoft Partner Network', 'Microsoft Advertising', 'Microsoft', 'Microsoft Feedback', 'Microsoft account team', 'Microsoft Support', 'Microsoft 365 Message center', 'Microsoft Azure')
    • sender.display_name matches '[MḾṀṂⱮМḿṁṃᵯⱮ𝐌𝑀][iíìîïīĭĩįıɪɨᵢⁱ𝐢𝑖][cćĉċčçƈȼ𝐜𝑐][rŕŗřȑȓɾᵣⁿʳ𝐫𝑟][oóòôõöøōŏőɵₒᵒº𝐨𝑜][sśŝšșşʂᵴˢˢ𝐬𝑠][oóòôõöøōŏőɵₒᵒº𝐨𝑜][fḟƒᵮᶠ𝐟𝑓][tťțţᵵₜᵗᵗ𝐭𝑡]'
    • sender.display_name matches '[MḾṀṂⱮМḿṁṃᵯⱮ𝐌𝑀][iíìîïīĭĩįıɪɨᵢⁱ𝐢𝑖][rŕŗřȑȓɾᵣⁿʳ𝐫𝑟][cćĉċčçƈȼ𝐜𝑐][oóòôõöøōŏőɵₒᵒº𝐨𝑜][sśŝšșşʂᵴˢˢ𝐬𝑠][oóòôõöøōŏőɵₒᵒº𝐨𝑜][fḟƒᵮᶠ𝐟𝑓][tťțţᵵₜᵗᵗ𝐭𝑡]'
    • any of attachments where all hold:
      • .file_extension is 'pdf'
      • beta.parse_exif(.).page_count is 1
      • any of ml.logo_detect(.).brands where:
        • .name is 'Microsoft'
      • any of file.explode(.) where:
        • .scan.ocr.raw matches '[©@]\\s*(?:\\d+)?\\s*Microsoft'
  4. not:
    • all of:
      • sender.email.domain.root_domain in ('microsoft.com', 'microsoftstoreemail.com', 'microsoftsupport.com', 'office.com', 'teams-events.com', 'qualtrics-research.com', 'skype.com', 'azureadnotifications.us', 'microsoftonline.us', 'mail.microsoft', 'office365.com', 'microsoftadvertising.com')
      • headers.auth_summary.dmarc.pass
  5. not:
    • all of:
      • sender.email.domain.domain in ('microsoft.regsvc.com', 'microsoft.onmicrosoft.com')
      • headers.auth_summary.dmarc.pass
  6. any of:
    • profile.by_sender().prevalence in ('new', 'outlier')
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  7. not:
    • all of:
      • all of attachments where:
        • .content_type in ('message/delivery-status', 'message/rfc822')
      • any of:
        • sender.email.local_part in ('postmaster', 'mailer-daemon')
        • sender.email.local_part starts with 'microsoftexchange'
      • subject.subject contains any of 7 patterns
        • Undeliverable:
        • Blocked:
        • Não é possível entregar:
        • Nie można dostarczyć:
        • Non remis :
        • Teslim edilmez:
        • No se puede entregar:
  8. not:
    • all of:
      • length(body.links) > 0
      • any of:
        • all of:
          • all of body.links where any holds:
            • .href_url.domain.root_domain in ('aka.ms', 'microsoftonline.com', 'microsoft.com')
            • .href_url.domain.tld is 'microsoft'
          • headers.auth_summary.dmarc.pass
        • all of:
          • sender.email.local_part is 'invites'
          • sender.email.domain.root_domain is 'onmicrosoft.com'
          • headers.message_id contains 'pepf'
  9. not:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • coalesce(headers.auth_summary.dmarc.pass)
  10. not:
    • all of:
      • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
        • .name in ('Newsletters and Digests')
        • .confidence is 'high'
      • any of body.links where all hold:
        • .display_text contains 'unsubscribe'
        • .href_url.path contains 'unsubscribe'

Inspects: attachments[].content_type, attachments[].file_extension, body.current_thread.text, body.links, body.links[].display_text, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.tld, body.links[].href_url.path, headers.auth_summary.dmarc.pass, headers.message_id, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.local_part, subject.subject, type.inbound. Sensors: beta.parse_exif, file.explode, ml.logo_detect, ml.nlu_classifier, profile.by_sender, regex.icontains, strings.contains, strings.icontains, strings.ilike, strings.replace_confusables, strings.starts_with. Reference lists: $high_trust_sender_root_domains.

Indicators matched (26)

FieldMatchValue
sender.email.local_partequalsnewsletter
strings.ilikesubstring*Microsoft 365*
strings.ilikesubstring*is expired*
strings.ilikesubstring*expir*
strings.ilikesubstring*password*
strings.ilikesubstring*microsoft*
regex.icontainsregex.*reach you.{0,20}Microsoft Teams
regex.icontainsregexmicrosoft account\n2fa
strings.icontainssubstringmicrosoft account team
strings.ilikesubstring*new activity in Teams*
strings.icontainssubstringmicrosoft advertising support
subject.subjectequalsOffline Message in Teams
14 more
strings.ilikesubstring*Teams Sent A Message
sender.display_namememberMicrosoft Partner Network
sender.display_namememberMicrosoft Advertising
sender.display_namememberMicrosoft
sender.display_namememberMicrosoft Feedback
sender.display_namememberMicrosoft account team
sender.display_namememberMicrosoft Support
sender.display_namememberMicrosoft 365 Message center
sender.display_namememberMicrosoft Azure
regex.icontainsregex[MḾṀṂⱮМḿṁṃᵯⱮ𝐌𝑀][iíìîïīĭĩįıɪɨᵢⁱ𝐢𝑖][cćĉċčçƈȼ𝐜𝑐][rŕŗřȑȓɾᵣⁿʳ𝐫𝑟][oóòôõöøōŏőɵₒᵒº𝐨𝑜][sśŝšșşʂᵴˢˢ𝐬𝑠][oóòôõöøōŏőɵₒᵒº𝐨𝑜][fḟƒᵮᶠ𝐟𝑓][tťțţᵵₜᵗᵗ𝐭𝑡]
regex.icontainsregex[MḾṀṂⱮМḿṁṃᵯⱮ𝐌𝑀][iíìîïīĭĩįıɪɨᵢⁱ𝐢𝑖][rŕŗřȑȓɾᵣⁿʳ𝐫𝑟][cćĉċčçƈȼ𝐜𝑐][oóòôõöøōŏőɵₒᵒº𝐨𝑜][sśŝšșşʂᵴˢˢ𝐬𝑠][oóòôõöøōŏőɵₒᵒº𝐨𝑜][fḟƒᵮᶠ𝐟𝑓][tťțţᵵₜᵗᵗ𝐭𝑡]
attachments[].file_extensionequalspdf
ml.logo_detect(attachments[]).brands[].nameequalsMicrosoft
regex.icontainsregex[©@]\s*(?:\d+)?\s*Microsoft

Stages and Predicates

Stage 1: mql_rule

and
  not
    and
      any(body.links)
        and
          body.links.display_text contains "unsubscribe"
          body.links.href_url.path contains "unsubscribe"
      any(ml.nlu_classifier(body.current_thread.text).topics)
        and
          ml.nlu_classifier(body.current_thread.text).topics.confidence eq "high"
          ml.nlu_classifier(body.current_thread.text).topics.name eq "Newsletters and Digests"
  or
    any(attachments)
      and
        any(file.explode(attachments))
          file.explode(attachments).scan.ocr.raw regex_match "[©@]\\s*(?:\\d+)?\\s*Microsoft"
        any(ml.logo_detect(attachments).brands)
          ml.logo_detect(attachments).brands.name eq "Microsoft"
        attachments.file_extension eq "pdf"
        beta.parse_exif func_call "beta.parse_exif(attachments[]).page_count == 1"
    and
      body.current_thread.text match "expir"
      body.current_thread.text match "microsoft"
      body.current_thread.text match "password"
    and
      subject.subject match "Microsoft 365"
      subject.subject match "is expired"
    body.current_thread.text contains "microsoft account team"
    body.current_thread.text regex_match ".*reach you.{0,20}Microsoft Teams"
    body.current_thread.text regex_match "microsoft account\\n2fa"
    sender.display_name in ["Microsoft", "Microsoft 365 Message center", "Microsoft Advertising", "Microsoft Azure", "Microsoft Feedback", "Microsoft Partner Network", "Microsoft Support", "Microsoft account team"]
    sender.display_name match "new activity in Teams"
    sender.display_name regex_match "[MḾṀṂⱮМḿṁṃᵯⱮ𝐌𝑀][iíìîïīĭĩįıɪɨᵢⁱ𝐢𝑖][cćĉċčçƈȼ𝐜𝑐][rŕŗřȑȓɾᵣⁿʳ𝐫𝑟][oóòôõöøōŏőɵₒᵒº𝐨𝑜][sśŝšșşʂᵴˢˢ𝐬𝑠][oóòôõöøōŏőɵₒᵒº𝐨𝑜][fḟƒᵮᶠ𝐟𝑓][tťțţᵵₜᵗᵗ𝐭𝑡]"
    sender.display_name regex_match "[MḾṀṂⱮМḿṁṃᵯⱮ𝐌𝑀][iíìîïīĭĩįıɪɨᵢⁱ𝐢𝑖][rŕŗřȑȓɾᵣⁿʳ𝐫𝑟][cćĉċčçƈȼ𝐜𝑐][oóòôõöøōŏőɵₒᵒº𝐨𝑜][sśŝšșşʂᵴˢˢ𝐬𝑠][oóòôõöøōŏőɵₒᵒº𝐨𝑜][fḟƒᵮᶠ𝐟𝑓][tťțţᵵₜᵗᵗ𝐭𝑡]"
    strings.replace_confusables(sender.display_name) contains "microsoft advertising support"
    subject.subject ends_with "Teams Sent A Message"
    subject.subject eq "Offline Message in Teams"
  not
    and
      or
        and
          headers.auth_summary.dmarc.pass eq "true"
           macro "all(body.links)"
        and
          headers.message_id contains "pepf"
          sender.email.domain.root_domain eq "onmicrosoft.com"
          sender.email.local_part eq "invites"
      body.links length_compare "0"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    profile.by_sender func_call "profile.by_sender().prevalence in (new, outlier)"
  not
    and
      or
        sender.email.local_part in ["mailer-daemon", "postmaster"]
        sender.email.local_part starts_with "microsoftexchange"
      or
        subject.subject contains "Blocked:"
        subject.subject contains "Nie można dostarczyć:"
        subject.subject contains "No se puede entregar:"
        subject.subject contains "Non remis :"
        subject.subject contains "Não é possível entregar:"
        subject.subject contains "Teslim edilmez:"
        subject.subject contains "Undeliverable:"
       macro "all(attachments)"
  or
    and
      body.links length_compare "5"
      sender.email.local_part eq "newsletter"
    body.links length_compare "30"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.domain in ["microsoft.onmicrosoft.com", "microsoft.regsvc.com"]
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.root_domain in ["azureadnotifications.us", "mail.microsoft", "microsoft.com", "microsoftadvertising.com", "microsoftonline.us", "microsoftstoreemail.com", "microsoftsupport.com", "office.com", "office365.com", "qualtrics-research.com", "skype.com", "teams-events.com"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
body.linksarray_any(no value, null check)excludes:body.links
ml.nlu_classifier(body.current_thread.text).topicsarray_any(no value, null check)excludes:ml.nlu_classifier(body.current_thread.text).topics
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
headers.message_idcontainspepfexcludes:headers.message_id field:"headers.message_id" value:"pepf"
sender.email.domain.root_domaineqonmicrosoft.comexcludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"onmicrosoft.com"
sender.email.local_parteqinvitesexcludes:sender.email.local_part field:"sender.email.local_part" value:"invites"
body.linkslength_compare0excludes:body.links field:"body.links" value:"0"
sender.email.local_partinmailer-daemon, postmasterexcludes:sender.email.local_part field:"sender.email.local_part" value:"mailer-daemon" field:"sender.email.local_part" value:"postmaster"
sender.email.local_partstarts_withmicrosoftexchangeexcludes:sender.email.local_part field:"sender.email.local_part" value:"microsoftexchange"
subject.subjectcontainsBlocked:excludes:subject.subject field:"subject.subject" value:"Blocked:"
subject.subjectcontainsNie można dostarczyć:excludes:subject.subject field:"subject.subject" value:"Nie można dostarczyć:"
subject.subjectcontainsNo se puede entregar:excludes:subject.subject field:"subject.subject" value:"No se puede entregar:"
subject.subjectcontainsNon remis :excludes:subject.subject field:"subject.subject" value:"Non remis :"
subject.subjectcontainsNão é possível entregar:excludes:subject.subject field:"subject.subject" value:"Não é possível entregar:"
subject.subjectcontainsTeslim edilmez:excludes:subject.subject field:"subject.subject" value:"Teslim edilmez:"
subject.subjectcontainsUndeliverable:excludes:subject.subject field:"subject.subject" value:"Undeliverable:"
sender.email.domain.domaininmicrosoft.onmicrosoft.com, microsoft.regsvc.comexcludes:sender.email.domain.domain field:"sender.email.domain.domain" value:"microsoft.onmicrosoft.com" field:"sender.email.domain.domain" value:"microsoft.regsvc.com"
sender.email.domain.root_domaininazureadnotifications.us, mail.microsoft, microsoft.com, microsoftadvertising.com, microsoftonline.us, microsoftstoreemail.com, microsoftsupport.com, office.com, office365.com, qualtrics-research.com, skype.com, teams-events.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textcontains
  • microsoft account team
field:"body.current_thread.text" kind:contains value:"microsoft account team"
body.current_thread.textregex_match
  • .*reach you.{0,20}Microsoft Teams
  • microsoft account\n2fa
field:"body.current_thread.text" kind:regex_match
body.current_thread.textwildcard
  • *expir*
  • *microsoft*
  • *password*
field:"body.current_thread.text" kind:wildcard
sender.display_namein
  • Microsoft
  • Microsoft 365 Message center
  • Microsoft Advertising
  • Microsoft Azure
  • Microsoft Feedback
  • Microsoft Partner Network
  • Microsoft Support
  • Microsoft account team
field:"sender.display_name" kind:in
sender.display_nameregex_match
  • [MḾṀṂⱮМḿṁṃᵯⱮ𝐌𝑀][iíìîïīĭĩįıɪɨᵢⁱ𝐢𝑖][cćĉċčçƈȼ𝐜𝑐][rŕŗřȑȓɾᵣⁿʳ𝐫𝑟][oóòôõöøōŏőɵₒᵒº𝐨𝑜][sśŝšșşʂᵴˢˢ𝐬𝑠][oóòôõöøōŏőɵₒᵒº𝐨𝑜][fḟƒᵮᶠ𝐟𝑓][tťțţᵵₜᵗᵗ𝐭𝑡]
  • [MḾṀṂⱮМḿṁṃᵯⱮ𝐌𝑀][iíìîïīĭĩįıɪɨᵢⁱ𝐢𝑖][rŕŗřȑȓɾᵣⁿʳ𝐫𝑟][cćĉċčçƈȼ𝐜𝑐][oóòôõöøōŏőɵₒᵒº𝐨𝑜][sśŝšșşʂᵴˢˢ𝐬𝑠][oóòôõöøōŏőɵₒᵒº𝐨𝑜][fḟƒᵮᶠ𝐟𝑓][tťțţᵵₜᵗᵗ𝐭𝑡]
field:"sender.display_name" kind:regex_match
sender.display_namewildcard
  • *new activity in Teams*
field:"sender.display_name" kind:wildcard value:"*new activity in Teams*"
sender.email.local_parteq
  • newsletter
field:"sender.email.local_part" kind:eq value:"newsletter"
strings.replace_confusables(sender.display_name)contains
  • microsoft advertising support
field:"strings.replace_confusables(sender.display_name)" kind:contains value:"microsoft advertising support"
subject.subjecteq
  • Offline Message in Teams
field:"subject.subject" kind:eq value:"Offline Message in Teams"
subject.subjectwildcard
  • *Microsoft 365*
  • *Teams Sent A Message
  • *is expired*
field:"subject.subject" kind:wildcard
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Microsoft fake sign-in alert

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

Detects messages impersonating Microsoft that mimic sign-in security alerts and attempt to solicit a response.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • headers
  • headers.hops
  • headers.reply_to
  • headers.return_path
  • sender.email
  • subject
  • type

Rule body

type.inbound
// no links found in body
and length(body.links) == 0
// Microsoft strings
and (
  strings.contains(subject.subject, "Microsoft")
  or strings.contains(sender.display_name, "Microsoft")
  or strings.contains(body.current_thread.text, "Microsoft")
  or (

    // or Microsoft Brand logo
    any(attachments,
        .file_type in $file_types_images
        and any(ml.logo_detect(.).brands,
                strings.starts_with(.name, "Microsoft")
        )
    )
  )
)

// Body contains Indicators of fake sign in notification
and (
  regex.contains(body.current_thread.text,
                 '(Country.region:.{0,20}IP address:|Platform:.{0,20}Browser:)'
  )
  or regex.contains(body.current_thread.text, "Unusual.{0,10}activity")
)
and (

  // If the sender is freemail
  sender.email.domain.domain in $free_email_providers
  or (

    // sender is not freemail, but the return path email or reply to email is
    sender.email.domain.domain not in $free_email_providers
    and (
      headers.return_path.domain.root_domain in $free_email_providers
      or (
        length(headers.reply_to) > 0
        and (
          all(headers.reply_to,
              .email.domain.root_domain in $free_email_providers
          )
        )
      )
      or (

        // if all replyto domain, return_path domain, sender domain mismatch
        length(headers.reply_to) > 0
        and (
          all(headers.reply_to,
              .email.domain.domain != headers.return_path.domain.domain
          )
          and headers.return_path.domain.domain != sender.email.domain.domain
        )
      )

      // or the domain is less than 90 days old
      or network.whois(sender.email.domain).days_old <= 90
      or (

        // or Compauth verdict is not pass/softpass
        any(headers.hops,
            .authentication_results.compauth.verdict is not null
            and .authentication_results.compauth.verdict not in (
              "pass",
              "softpass"
            )
        )
      )
    )
  )
)
and sender.email.domain.root_domain not in (
  "bing.com",
  "microsoft.com",
  "microsoftonline.com",
  "microsoftsupport.com",
  "microsoft365.com",
  "office.com",
  "onedrive.com",
  "sharepointonline.com",
  "yammer.com",
)

Detection logic

Scope: inbound message.

Detects messages impersonating Microsoft that mimic sign-in security alerts and attempt to solicit a response.

  1. inbound message
  2. length(body.links) is 0
  3. any of:
    • subject.subject contains 'Microsoft'
    • sender.display_name contains 'Microsoft'
    • body.current_thread.text contains 'Microsoft'
    • any of attachments where all hold:
      • .file_type in $file_types_images
      • any of ml.logo_detect(.).brands where:
        • .name starts with 'Microsoft'
  4. any of:
    • body.current_thread.text matches '(Country.region:.{0,20}IP address:|Platform:.{0,20}Browser:)'
    • body.current_thread.text matches 'Unusual.{0,10}activity'
  5. any of:
    • sender.email.domain.domain in $free_email_providers
    • all of:
      • sender.email.domain.domain not in $free_email_providers
      • any of:
        • headers.return_path.domain.root_domain in $free_email_providers
        • all of:
          • length(headers.reply_to) > 0
          • all of headers.reply_to where:
            • .email.domain.root_domain in $free_email_providers
        • all of:
          • length(headers.reply_to) > 0
          • all of:
            • all of headers.reply_to where:
              • .email.domain.domain is not headers.return_path.domain.domain
            • headers.return_path.domain.domain is not sender.email.domain.domain
        • network.whois(sender.email.domain).days_old ≤ 90
        • any of headers.hops where all hold:
          • .authentication_results.compauth.verdict is set
          • .authentication_results.compauth.verdict not in ('pass', 'softpass')
  6. sender.email.domain.root_domain not in ('bing.com', 'microsoft.com', 'microsoftonline.com', 'microsoftsupport.com', 'microsoft365.com', 'office.com', 'onedrive.com', 'sharepointonline.com', 'yammer.com')

Inspects: attachments[].file_type, body.current_thread.text, body.links, headers.hops, headers.hops[].authentication_results.compauth.verdict, headers.reply_to, headers.reply_to[].email.domain.domain, headers.reply_to[].email.domain.root_domain, headers.return_path.domain.domain, headers.return_path.domain.root_domain, sender.display_name, sender.email.domain, sender.email.domain.domain, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: ml.logo_detect, network.whois, regex.contains, strings.contains, strings.starts_with. Reference lists: $file_types_images, $free_email_providers.

Indicators matched (4)

FieldMatchValue
strings.containssubstringMicrosoft
strings.starts_withprefixMicrosoft
regex.containsregex(Country.region:.{0,20}IP address:|Platform:.{0,20}Browser:)
regex.containsregexUnusual.{0,10}activity

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      or
        any(headers.hops)
          and
            not
              headers.hops.authentication_results.compauth.verdict in ["pass", "softpass"]
            headers.hops.authentication_results.compauth.verdict is_not_null
        and
          headers.reply_to length_compare "0"
          headers.return_path.domain.domain cross_field_compare "sender.email.domain.domain"
           macro "all(headers.reply_to)"
        and
          headers.reply_to length_compare "0"
           macro "all(headers.reply_to)"
        network.whois func_call "network.whois(sender.email.domain).days_old <= 90"
         macro "headers.return_path.domain.root_domain in free_email_providers"
       macro "sender.email.domain.domain not in free_email_providers"
     macro "sender.email.domain.domain in free_email_providers"
  or
    any(attachments)
      and
        any(ml.logo_detect(attachments).brands)
          ml.logo_detect(attachments).brands.name starts_with "Microsoft"
         macro "attachments[].file_type in file_types_images"
    body.current_thread.text contains "Microsoft"
    sender.display_name contains "Microsoft"
    subject.subject contains "Microsoft"
  or
    body.current_thread.text regex_match "(Country.region:.{0,20}IP address:|Platform:.{0,20}Browser:)"
    body.current_thread.text regex_match "Unusual.{0,10}activity"
  not
    sender.email.domain.root_domain in ["bing.com", "microsoft.com", "microsoft365.com", "microsoftonline.com", "microsoftsupport.com", "office.com", "onedrive.com", "sharepointonline.com", "yammer.com"]
  body.links length_compare "0"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaininbing.com, microsoft.com, microsoft365.com, microsoftonline.com, microsoftsupport.com, office.com, onedrive.com, sharepointonline.com, yammer.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Microsoft logo in HTML with fake quarantine release notification

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

A message containing a Microsoft logo generated using HTML tables and references to the Microsoft Exchange quarantine, but did not come from Microsoft.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Impersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.html
  • headers
  • headers.hops
  • sender.email
  • type

Rule body

type.inbound
and 0 < length(body.links) < 10
// Microsoft logo via HTML table composition
and (
  regex.icontains(body.html.raw,
                  '<table[^>]*>\s*<tbody[^>]*>\s*<tr[^>]*>\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\s*&nbsp;\s*</td>\s*){2}\s*</tr>\s*<tr[^>]*>\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\s*&nbsp;\s*</td>\s*){2}'
  )
  or regex.icontains(body.html.raw,
                     '<td style="background:\s*rgb\(246,\s*93,\s*53\);\s*height:\d+px;">.*?<td style="background:\s*rgb\(129,\s*187,\s*5\);\s*height:\d+px;">.*?<td style="background:\s*rgb\(4,\s*165,\s*240\);\s*height:\d+px;">.*?<td style="background:\s*rgb\(255,\s*186,\s*7\);\s*height:\d+px;">'
  )
  or 4 of (
    regex.icontains(body.html.raw,
                    '<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(245, 189, 67\);">.{0,10}</td>'
    ),
    regex.icontains(body.html.raw,
                    '<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(137, 184, 57\);">.{0,10}</td>'
    ),
    regex.icontains(body.html.raw,
                    '<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(217, 83, 51\);">.{0,10}</td>'
    ),
    regex.icontains(body.html.raw,
                    '<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(71, 160, 218\);">.{0,10}</td>'
    )
  )
  or regex.icontains(body.html.raw,
                     '<DIV[^>]*><SPAN style="[^"]*BACKGROUND-COLOR: #ff1940"></SPAN><SPAN style="[^"]*BACKGROUND-COLOR: #3eb55d"></SPAN><SPAN style="[^"]*BACKGROUND-COLOR: #04b5f0"></SPAN><SPAN style="[^"]*BACKGROUND-COLOR: #ffca07"></SPAN></DIV>'
  )
  or regex.icontains(body.html.raw,
                     '<span style="[^"]*background-color:\s*#FF1941;[^"]*"></span>\s*<span style="[^"]*background-color:\s*#36ba58;[^"]*"></span>\s*<span style="[^"]*background-color:\s*#04a1d6;[^"]*"></span>\s*<span style="[^"]*background-color:\s*#FFCA08;[^"]*"></span>'
  )
  or regex.icontains(body.html.raw,
                     '<td[^>]+background:#f25022[^>]+>.*?<td[^>]+background:#7fba00[^>]+>.*?<td[^>]+background:#01a4ef[^>]+>.*?<td[^>]+background:#ffb901[^>]+>'
  )
  or regex.icontains(body.html.raw,
                     '<td bgcolor="red".*?<td bgcolor="green".*?<td bgcolor="#04a5f0".*?<td bgcolor="#ffba07"'
  )
  or 4 of (
    regex.icontains(body.html.raw,
                    '<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(73, 161, 232\);">.{0,10}</td>'
    ),
    regex.icontains(body.html.raw,
                    '<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(224, 92, 53\);">.{0,10}</td>'
    ),
    regex.icontains(body.html.raw,
                    '<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(139, 183, 55\);">.{0,10}</td>'
    ),
    regex.icontains(body.html.raw,
                    '<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(244, 188, 65\);">.{0,10}</td>'
    )
  )
  or regex.icontains(body.html.raw,
                     '<td style="BACKGROUND-COLOR: red".*?<td style="BACKGROUND-COLOR: rgb\(19,186,132\)".*?<td style="BACKGROUND-COLOR: rgb\(4,166,240\)".*?<td style="BACKGROUND-COLOR: rgb\(255,186,8\)"'
  )
  or 4 of (
    regex.icontains(body.html.raw, 'background-color:rgb\(213,56,62\)'),
    regex.icontains(body.html.raw, 'background-color:rgb\(0,114,30\)'),
    regex.icontains(body.html.raw, 'background-color:rgb\(0,110,173\)'),
    regex.icontains(body.html.raw, 'background-color:rgb\(227,209,43\)'),
  )
  or 4 of (
    regex.icontains(body.html.raw, '<td[^>]*bgcolor="#F25022">&nbsp;</td>'),
    regex.icontains(body.html.raw, '<td[^>]*bgcolor="#7FBA00">&nbsp;</td>'),
    regex.icontains(body.html.raw,
                    '<td[^>]*(bgcolor="#00A4EF"|height="\d+")[^>]*(bgcolor="#00A4EF"|height="\d+")[^>]*>&nbsp;</td>'
    ),
    regex.icontains(body.html.raw,
                    '<td[^>]*(bgcolor="#FFB900"|height="\d+")[^>]*(bgcolor="#FFB900"|height="\d+")[^>]*>&nbsp;</td>'
    )
  )
  or regex.icontains(body.html.raw,
                     '<DIV[^>]*><SPAN[^>]*background-color:\s*#FF1940;[^>]*><\/SPAN><SPAN[^>]*background-color:\s*#36ba57;[^>]*><\/SPAN><SPAN[^>]*background-color:\s*#04a1d6;[^>]*><\/SPAN><SPAN[^>]*background-color:\s*#FFCA07;[^>]*><\/SPAN><\/DIV>'
  )
  or 3 of (
    regex.icontains(body.html.raw, '.password-expiration'),
    regex.icontains(body.html.raw, 'color: #2672ec;'),
    regex.icontains(body.html.raw, 'M\x{00AD}ic\x{00AD}ro\x{00AD}so\x{00AD}ft')
  )
  or 4 of (
    regex.icontains(body.html.raw, 'background-color:#FF1940;'),
    regex.icontains(body.html.raw, 'background-color:#3eb55d;'),
    regex.icontains(body.html.raw, 'background-color:#04B5F0;'),
    regex.icontains(body.html.raw, 'background-color:#FFCA07;'),
  )
  or 4 of (
    regex.icontains(body.html.raw, 'bgcolor="#eb5024"'),
    regex.icontains(body.html.raw, 'bgcolor="#7db606"'),
    regex.icontains(body.html.raw, 'bgcolor="#05a1e8"'),
    regex.icontains(body.html.raw, 'bgcolor="#f7b408"'),
  )
  or 4 of (
    regex.icontains(body.html.raw, '<td style="background: #E74F23;'),
    regex.icontains(body.html.raw, '<td style="background: #7AB206;'),
    regex.icontains(body.html.raw, '<td style="background: #059EE4;'),
    regex.icontains(body.html.raw, '<td style="background: #F2B108;'),
  )
  or 4 of (
    regex.icontains(body.html.raw, 'background-color:rgb\(246,93,53\)'),
    regex.icontains(body.html.raw, 'background-color:rgb\(129,187,5\)'),
    regex.icontains(body.html.raw, 'background-color:rgb\(4,165,240\)'),
    regex.icontains(body.html.raw, 'background-color:rgb\(255,186,7\)')
  )
  and 3 of (
    strings.icontains(body.current_thread.text, "review"),
    strings.icontains(body.current_thread.text, "release"),
    strings.icontains(body.current_thread.text, "quarantine"),
    strings.icontains(body.current_thread.text, "messages"),
    strings.icontains(body.current_thread.text, "recover"),
    strings.icontains(body.current_thread.text, "server error")
  )
  and sender.email.domain.root_domain not in (
    "bing.com",
    "microsoft.com",
    "microsoftonline.com",
    "microsoftsupport.com",
    "microsoft365.com",
    "office.com",
    "onedrive.com",
    "sharepointonline.com",
    "yammer.com",
  )
)

// negate highly trusted sender domains unless they fail DMARC authentication
and (
  (
    sender.email.domain.root_domain in $high_trust_sender_root_domains
    and (
      any(distinct(headers.hops, .authentication_results.dmarc is not null),
          strings.ilike(.authentication_results.dmarc, "*fail")
      )
    )
  )
  or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)
and not profile.by_sender().solicited
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

A message containing a Microsoft logo generated using HTML tables and references to the Microsoft Exchange quarantine, but did not come from Microsoft.

  1. inbound message
  2. all of:
    • length(body.links) > 0
    • length(body.links) < 10
  3. any of:
    • body.html.raw matches '<table[^>]*>\\s*<tbody[^>]*>\\s*<tr[^>]*>\\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\\s*&nbsp;\\s*</td>\\s*){2}\\s*</tr>\\s*<tr[^>]*>\\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\\s*&nbsp;\\s*</td>\\s*){2}'
    • body.html.raw matches '<td style="background:\\s*rgb\\(246,\\s*93,\\s*53\\);\\s*height:\\d+px;">.*?<td style="background:\\s*rgb\\(129,\\s*187,\\s*5\\);\\s*height:\\d+px;">.*?<td style="background:\\s*rgb\\(4,\\s*165,\\s*240\\);\\s*height:\\d+px;">.*?<td style="background:\\s*rgb\\(255,\\s*186,\\s*7\\);\\s*height:\\d+px;">'
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • <td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(245, 189, 67\);">.{0,10}</td>
      • <td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(137, 184, 57\);">.{0,10}</td>
      • <td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(217, 83, 51\);">.{0,10}</td>
      • <td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(71, 160, 218\);">.{0,10}</td>
    • body.html.raw matches '<DIV[^>]*><SPAN style="[^"]*BACKGROUND-COLOR: #ff1940"></SPAN><SPAN style="[^"]*BACKGROUND-COLOR: #3eb55d"></SPAN><SPAN style="[^"]*BACKGROUND-COLOR: #04b5f0"></SPAN><SPAN style="[^"]*BACKGROUND-COLOR: #ffca07"></SPAN></DIV>'
    • body.html.raw matches '<span style="[^"]*background-color:\\s*#FF1941;[^"]*"></span>\\s*<span style="[^"]*background-color:\\s*#36ba58;[^"]*"></span>\\s*<span style="[^"]*background-color:\\s*#04a1d6;[^"]*"></span>\\s*<span style="[^"]*background-color:\\s*#FFCA08;[^"]*"></span>'
    • body.html.raw matches '<td[^>]+background:#f25022[^>]+>.*?<td[^>]+background:#7fba00[^>]+>.*?<td[^>]+background:#01a4ef[^>]+>.*?<td[^>]+background:#ffb901[^>]+>'
    • body.html.raw matches '<td bgcolor="red".*?<td bgcolor="green".*?<td bgcolor="#04a5f0".*?<td bgcolor="#ffba07"'
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • <td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(73, 161, 232\);">.{0,10}</td>
      • <td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(224, 92, 53\);">.{0,10}</td>
      • <td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(139, 183, 55\);">.{0,10}</td>
      • <td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(244, 188, 65\);">.{0,10}</td>
    • body.html.raw matches '<td style="BACKGROUND-COLOR: red".*?<td style="BACKGROUND-COLOR: rgb\\(19,186,132\\)".*?<td style="BACKGROUND-COLOR: rgb\\(4,166,240\\)".*?<td style="BACKGROUND-COLOR: rgb\\(255,186,8\\)"'
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • background-color:rgb\(213,56,62\)
      • background-color:rgb\(0,114,30\)
      • background-color:rgb\(0,110,173\)
      • background-color:rgb\(227,209,43\)
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • <td[^>]*bgcolor="#F25022">&nbsp;</td>
      • <td[^>]*bgcolor="#7FBA00">&nbsp;</td>
      • <td[^>]*(bgcolor="#00A4EF"|height="\d+")[^>]*(bgcolor="#00A4EF"|height="\d+")[^>]*>&nbsp;</td>
      • <td[^>]*(bgcolor="#FFB900"|height="\d+")[^>]*(bgcolor="#FFB900"|height="\d+")[^>]*>&nbsp;</td>
    • body.html.raw matches '<DIV[^>]*><SPAN[^>]*background-color:\\s*#FF1940;[^>]*><\\/SPAN><SPAN[^>]*background-color:\\s*#36ba57;[^>]*><\\/SPAN><SPAN[^>]*background-color:\\s*#04a1d6;[^>]*><\\/SPAN><SPAN[^>]*background-color:\\s*#FFCA07;[^>]*><\\/SPAN><\\/DIV>'
    • at least 3 of:
      • body.html.raw matches '.password-expiration'
      • body.html.raw matches 'color: #2672ec;'
      • body.html.raw matches 'M\\x{00AD}ic\\x{00AD}ro\\x{00AD}so\\x{00AD}ft'
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • background-color:#FF1940;
      • background-color:#3eb55d;
      • background-color:#04B5F0;
      • background-color:#FFCA07;
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • bgcolor="#eb5024"
      • bgcolor="#7db606"
      • bgcolor="#05a1e8"
      • bgcolor="#f7b408"
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • <td style="background: #E74F23;
      • <td style="background: #7AB206;
      • <td style="background: #059EE4;
      • <td style="background: #F2B108;
    • all of:
      • at least 4 of 4: body.html.raw matches any of 4 patterns
        • background-color:rgb\(246,93,53\)
        • background-color:rgb\(129,187,5\)
        • background-color:rgb\(4,165,240\)
        • background-color:rgb\(255,186,7\)
      • at least 3 of 6: body.current_thread.text contains any of 6 patterns
        • review
        • release
        • quarantine
        • messages
        • recover
        • server error
      • sender.email.domain.root_domain not in ('bing.com', 'microsoft.com', 'microsoftonline.com', 'microsoftsupport.com', 'microsoft365.com', 'office.com', 'onedrive.com', 'sharepointonline.com', 'yammer.com')
  4. any of:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • any of distinct(headers.hops) where:
        • .authentication_results.dmarc matches '*fail'
    • sender.email.domain.root_domain not in $high_trust_sender_root_domains
  5. not:
    • profile.by_sender().solicited
  6. not:
    • profile.by_sender().any_messages_benign

Inspects: body.current_thread.text, body.html.raw, body.links, headers.hops, headers.hops[].authentication_results.dmarc, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender, regex.icontains, strings.icontains, strings.ilike. Reference lists: $high_trust_sender_root_domains.

Indicators matched (50)

FieldMatchValue
regex.icontainsregex<table[^>]*>\s*<tbody[^>]*>\s*<tr[^>]*>\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\s*&nbsp;\s*</td>\s*){2}\s*</tr>\s*<tr[^>]*>\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\s*&nbsp;\s*</td>\s*){2}
regex.icontainsregex<td style="background:\s*rgb\(246,\s*93,\s*53\);\s*height:\d+px;">.*?<td style="background:\s*rgb\(129,\s*187,\s*5\);\s*height:\d+px;">.*?<td style="background:\s*rgb\(4,\s*165,\s*240\);\s*height:\d+px;">.*?<td style="background:\s*rgb\(255,\s*186,\s*7\);\s*height:\d+px;">
regex.icontainsregex<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(245, 189, 67\);">.{0,10}</td>
regex.icontainsregex<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(137, 184, 57\);">.{0,10}</td>
regex.icontainsregex<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(217, 83, 51\);">.{0,10}</td>
regex.icontainsregex<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(71, 160, 218\);">.{0,10}</td>
regex.icontainsregex<DIV[^>]*><SPAN style="[^"]*BACKGROUND-COLOR: #ff1940"></SPAN><SPAN style="[^"]*BACKGROUND-COLOR: #3eb55d"></SPAN><SPAN style="[^"]*BACKGROUND-COLOR: #04b5f0"></SPAN><SPAN style="[^"]*BACKGROUND-COLOR: #ffca07"></SPAN></DIV>
regex.icontainsregex<span style="[^"]*background-color:\s*#FF1941;[^"]*"></span>\s*<span style="[^"]*background-color:\s*#36ba58;[^"]*"></span>\s*<span style="[^"]*background-color:\s*#04a1d6;[^"]*"></span>\s*<span style="[^"]*background-color:\s*#FFCA08;[^"]*"></span>
regex.icontainsregex<td[^>]+background:#f25022[^>]+>.*?<td[^>]+background:#7fba00[^>]+>.*?<td[^>]+background:#01a4ef[^>]+>.*?<td[^>]+background:#ffb901[^>]+>
regex.icontainsregex<td bgcolor="red".*?<td bgcolor="green".*?<td bgcolor="#04a5f0".*?<td bgcolor="#ffba07"
regex.icontainsregex<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(73, 161, 232\);">.{0,10}</td>
regex.icontainsregex<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(224, 92, 53\);">.{0,10}</td>
38 more
regex.icontainsregex<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(139, 183, 55\);">.{0,10}</td>
regex.icontainsregex<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(244, 188, 65\);">.{0,10}</td>
regex.icontainsregex<td style="BACKGROUND-COLOR: red".*?<td style="BACKGROUND-COLOR: rgb\(19,186,132\)".*?<td style="BACKGROUND-COLOR: rgb\(4,166,240\)".*?<td style="BACKGROUND-COLOR: rgb\(255,186,8\)"
regex.icontainsregexbackground-color:rgb\(213,56,62\)
regex.icontainsregexbackground-color:rgb\(0,114,30\)
regex.icontainsregexbackground-color:rgb\(0,110,173\)
regex.icontainsregexbackground-color:rgb\(227,209,43\)
regex.icontainsregex<td[^>]*bgcolor="#F25022">&nbsp;</td>
regex.icontainsregex<td[^>]*bgcolor="#7FBA00">&nbsp;</td>
regex.icontainsregex<td[^>]*(bgcolor="#00A4EF"|height="\d+")[^>]*(bgcolor="#00A4EF"|height="\d+")[^>]*>&nbsp;</td>
regex.icontainsregex<td[^>]*(bgcolor="#FFB900"|height="\d+")[^>]*(bgcolor="#FFB900"|height="\d+")[^>]*>&nbsp;</td>
regex.icontainsregex<DIV[^>]*><SPAN[^>]*background-color:\s*#FF1940;[^>]*><\/SPAN><SPAN[^>]*background-color:\s*#36ba57;[^>]*><\/SPAN><SPAN[^>]*background-color:\s*#04a1d6;[^>]*><\/SPAN><SPAN[^>]*background-color:\s*#FFCA07;[^>]*><\/SPAN><\/DIV>
regex.icontainsregex.password-expiration
regex.icontainsregexcolor: #2672ec;
regex.icontainsregexM\x{00AD}ic\x{00AD}ro\x{00AD}so\x{00AD}ft
regex.icontainsregexbackground-color:#FF1940;
regex.icontainsregexbackground-color:#3eb55d;
regex.icontainsregexbackground-color:#04B5F0;
regex.icontainsregexbackground-color:#FFCA07;
regex.icontainsregexbgcolor="#eb5024"
regex.icontainsregexbgcolor="#7db606"
regex.icontainsregexbgcolor="#05a1e8"
regex.icontainsregexbgcolor="#f7b408"
regex.icontainsregex<td style="background: #E74F23;
regex.icontainsregex<td style="background: #7AB206;
regex.icontainsregex<td style="background: #059EE4;
regex.icontainsregex<td style="background: #F2B108;
regex.icontainsregexbackground-color:rgb\(246,93,53\)
regex.icontainsregexbackground-color:rgb\(129,187,5\)
regex.icontainsregexbackground-color:rgb\(4,165,240\)
regex.icontainsregexbackground-color:rgb\(255,186,7\)
strings.icontainssubstringreview
strings.icontainssubstringrelease
strings.icontainssubstringquarantine
strings.icontainssubstringmessages
strings.icontainssubstringrecover
strings.icontainssubstringserver error
strings.ilikesubstring*fail

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      or
        body.current_thread.text contains "messages"
        body.current_thread.text contains "quarantine"
        body.current_thread.text contains "recover"
        body.current_thread.text contains "release"
        body.current_thread.text contains "review"
        body.current_thread.text contains "server error"
      not
        sender.email.domain.root_domain in ["bing.com", "microsoft.com", "microsoft365.com", "microsoftonline.com", "microsoftsupport.com", "office.com", "onedrive.com", "sharepointonline.com", "yammer.com"]
      body.html.raw regex_match "background-color:rgb\\(129,187,5\\)"
      body.html.raw regex_match "background-color:rgb\\(246,93,53\\)"
      body.html.raw regex_match "background-color:rgb\\(255,186,7\\)"
      body.html.raw regex_match "background-color:rgb\\(4,165,240\\)"
    and
      body.html.raw regex_match ".password-expiration"
      body.html.raw regex_match "M\\x{00AD}ic\\x{00AD}ro\\x{00AD}so\\x{00AD}ft"
      body.html.raw regex_match "color: #2672ec;"
    and
      body.html.raw regex_match "<td style=\"background: #059EE4;"
      body.html.raw regex_match "<td style=\"background: #7AB206;"
      body.html.raw regex_match "<td style=\"background: #E74F23;"
      body.html.raw regex_match "<td style=\"background: #F2B108;"
    and
      body.html.raw regex_match "<td style=\"width:.\\d.px;.height:.\\d.px;.background-color:.rgb\\(137, 184, 57\\);\">.{0,10}</td>"
      body.html.raw regex_match "<td style=\"width:.\\d.px;.height:.\\d.px;.background-color:.rgb\\(217, 83, 51\\);\">.{0,10}</td>"
      body.html.raw regex_match "<td style=\"width:.\\d.px;.height:.\\d.px;.background-color:.rgb\\(245, 189, 67\\);\">.{0,10}</td>"
      body.html.raw regex_match "<td style=\"width:.\\d.px;.height:.\\d.px;.background-color:.rgb\\(71, 160, 218\\);\">.{0,10}</td>"
    and
      body.html.raw regex_match "<td style=\"width:.\\d.px;.height:.\\d.px;.background-color:.rgb\\(139, 183, 55\\);\">.{0,10}</td>"
      body.html.raw regex_match "<td style=\"width:.\\d.px;.height:.\\d.px;.background-color:.rgb\\(224, 92, 53\\);\">.{0,10}</td>"
      body.html.raw regex_match "<td style=\"width:.\\d.px;.height:.\\d.px;.background-color:.rgb\\(244, 188, 65\\);\">.{0,10}</td>"
      body.html.raw regex_match "<td style=\"width:.\\d.px;.height:.\\d.px;.background-color:.rgb\\(73, 161, 232\\);\">.{0,10}</td>"
    and
      body.html.raw regex_match "<td[^>]*(bgcolor=\"#00A4EF\"|height=\"\\d+\")[^>]*(bgcolor=\"#00A4EF\"|height=\"\\d+\")[^>]*>&nbsp;</td>"
      body.html.raw regex_match "<td[^>]*(bgcolor=\"#FFB900\"|height=\"\\d+\")[^>]*(bgcolor=\"#FFB900\"|height=\"\\d+\")[^>]*>&nbsp;</td>"
      body.html.raw regex_match "<td[^>]*bgcolor=\"#7FBA00\">&nbsp;</td>"
      body.html.raw regex_match "<td[^>]*bgcolor=\"#F25022\">&nbsp;</td>"
    and
      body.html.raw regex_match "background-color:#04B5F0;"
      body.html.raw regex_match "background-color:#3eb55d;"
      body.html.raw regex_match "background-color:#FF1940;"
      body.html.raw regex_match "background-color:#FFCA07;"
    and
      body.html.raw regex_match "background-color:rgb\\(0,110,173\\)"
      body.html.raw regex_match "background-color:rgb\\(0,114,30\\)"
      body.html.raw regex_match "background-color:rgb\\(213,56,62\\)"
      body.html.raw regex_match "background-color:rgb\\(227,209,43\\)"
    and
      body.html.raw regex_match "bgcolor=\"#05a1e8\""
      body.html.raw regex_match "bgcolor=\"#7db606\""
      body.html.raw regex_match "bgcolor=\"#eb5024\""
      body.html.raw regex_match "bgcolor=\"#f7b408\""
    body.html.raw regex_match "<DIV[^>]*><SPAN style=\"[^\"]*BACKGROUND-COLOR: #ff1940\"></SPAN><SPAN style=\"[^\"]*BACKGROUND-COLOR: #3eb55d\"></SPAN><SPAN style=\"[^\"]*BACKGROUND-COLOR: #04b5f0\"></SPAN><SPAN style=\"[^\"]*BACKGROUND-COLOR: #ffca07\"></SPAN></DIV>"
    body.html.raw regex_match "<DIV[^>]*><SPAN[^>]*background-color:\\s*#FF1940;[^>]*><\\/SPAN><SPAN[^>]*background-color:\\s*#36ba57;[^>]*><\\/SPAN><SPAN[^>]*background-color:\\s*#04a1d6;[^>]*><\\/SPAN><SPAN[^>]*background-color:\\s*#FFCA07;[^>]*><\\/SPAN><\\/DIV>"
    body.html.raw regex_match "<span style=\"[^\"]*background-color:\\s*#FF1941;[^\"]*\"></span>\\s*<span style=\"[^\"]*background-color:\\s*#36ba58;[^\"]*\"></span>\\s*<span style=\"[^\"]*background-color:\\s*#04a1d6;[^\"]*\"></span>\\s*<span style=\"[^\"]*background-color:\\s*#FFCA08;[^\"]*\"></span>"
    body.html.raw regex_match "<table[^>]*>\\s*<tbody[^>]*>\\s*<tr[^>]*>\\s*(<td[^>]*bgcolor=\"#[0-9A-Fa-f]{6}\"[^>]*>\\s*&nbsp;\\s*</td>\\s*){2}\\s*</tr>\\s*<tr[^>]*>\\s*(<td[^>]*bgcolor=\"#[0-9A-Fa-f]{6}\"[^>]*>\\s*&nbsp;\\s*</td>\\s*){2}"
    body.html.raw regex_match "<td bgcolor=\"red\".*?<td bgcolor=\"green\".*?<td bgcolor=\"#04a5f0\".*?<td bgcolor=\"#ffba07\""
    body.html.raw regex_match "<td style=\"BACKGROUND-COLOR: red\".*?<td style=\"BACKGROUND-COLOR: rgb\\(19,186,132\\)\".*?<td style=\"BACKGROUND-COLOR: rgb\\(4,166,240\\)\".*?<td style=\"BACKGROUND-COLOR: rgb\\(255,186,8\\)\""
    body.html.raw regex_match "<td style=\"background:\\s*rgb\\(246,\\s*93,\\s*53\\);\\s*height:\\d+px;\">.*?<td style=\"background:\\s*rgb\\(129,\\s*187,\\s*5\\);\\s*height:\\d+px;\">.*?<td style=\"background:\\s*rgb\\(4,\\s*165,\\s*240\\);\\s*height:\\d+px;\">.*?<td style=\"background:\\s*rgb\\(255,\\s*186,\\s*7\\);\\s*height:\\d+px;\">"
    body.html.raw regex_match "<td[^>]+background:#f25022[^>]+>.*?<td[^>]+background:#7fba00[^>]+>.*?<td[^>]+background:#01a4ef[^>]+>.*?<td[^>]+background:#ffb901[^>]+>"
  or
    and
      any(distinct(headers.hops))
        distinct(headers.hops).authentication_results.dmarc ends_with "fail"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  not
    profile.by_sender func_call "profile.by_sender().solicited"
  body.links length_compare "0"
  body.links length_compare "10"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textcontains
  • messages
  • quarantine
  • recover
  • release
  • review
  • server error
field:"body.current_thread.text" kind:contains
body.html.rawregex_match
  • .password-expiration
  • <DIV[^>]*><SPAN style="[^"]*BACKGROUND-COLOR: #ff1940"></SPAN><SPAN style="[^"]*BACKGROUND-COLOR: #3eb55d"></SPAN><SPAN style="[^"]*BACKGROUND-COLOR: #04b5f0"></SPAN><SPAN style="[^"]*BACKGROUND-COLOR: #ffca07"></SPAN></DIV>
  • <DIV[^>]*><SPAN[^>]*background-color:\s*#FF1940;[^>]*><\/SPAN><SPAN[^>]*background-color:\s*#36ba57;[^>]*><\/SPAN><SPAN[^>]*background-color:\s*#04a1d6;[^>]*><\/SPAN><SPAN[^>]*background-color:\s*#FFCA07;[^>]*><\/SPAN><\/DIV>
  • <span style="[^"]*background-color:\s*#FF1941;[^"]*"></span>\s*<span style="[^"]*background-color:\s*#36ba58;[^"]*"></span>\s*<span style="[^"]*background-color:\s*#04a1d6;[^"]*"></span>\s*<span style="[^"]*background-color:\s*#FFCA08;[^"]*"></span>
  • <table[^>]*>\s*<tbody[^>]*>\s*<tr[^>]*>\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\s* \s*</td>\s*){2}\s*</tr>\s*<tr[^>]*>\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\s* \s*</td>\s*){2}
  • <td bgcolor="red".*?<td bgcolor="green".*?<td bgcolor="#04a5f0".*?<td bgcolor="#ffba07"
  • <td style="BACKGROUND-COLOR: red".*?<td style="BACKGROUND-COLOR: rgb(19,186,132)".*?<td style="BACKGROUND-COLOR: rgb(4,166,240)".*?<td style="BACKGROUND-COLOR: rgb(255,186,8)"
  • <td style="background: #059EE4;
  • <td style="background: #7AB206;
  • <td style="background: #E74F23;
  • <td style="background: #F2B108;
  • <td style="background:\s*rgb(246,\s*93,\s*53);\s*height:\d+px;">.*?<td style="background:\s*rgb(129,\s*187,\s*5);\s*height:\d+px;">.*?<td style="background:\s*rgb(4,\s*165,\s*240);\s*height:\d+px;">.*?<td style="background:\s*rgb(255,\s*186,\s*7);\s*height:\d+px;">
  • <td style="width:.\d.px;.height:.\d.px;.background-color:.rgb(137, 184, 57);">.{0,10}</td>
  • <td style="width:.\d.px;.height:.\d.px;.background-color:.rgb(139, 183, 55);">.{0,10}</td>
  • <td style="width:.\d.px;.height:.\d.px;.background-color:.rgb(217, 83, 51);">.{0,10}</td>
  • <td style="width:.\d.px;.height:.\d.px;.background-color:.rgb(224, 92, 53);">.{0,10}</td>
  • <td style="width:.\d.px;.height:.\d.px;.background-color:.rgb(244, 188, 65);">.{0,10}</td>
  • <td style="width:.\d.px;.height:.\d.px;.background-color:.rgb(245, 189, 67);">.{0,10}</td>
  • <td style="width:.\d.px;.height:.\d.px;.background-color:.rgb(71, 160, 218);">.{0,10}</td>
  • <td style="width:.\d.px;.height:.\d.px;.background-color:.rgb(73, 161, 232);">.{0,10}</td>
  • <td[^>]*(bgcolor="#00A4EF"|height="\d+")[^>]*(bgcolor="#00A4EF"|height="\d+")[^>]*> </td>
  • <td[^>]*(bgcolor="#FFB900"|height="\d+")[^>]*(bgcolor="#FFB900"|height="\d+")[^>]*> </td>
  • <td[^>]*bgcolor="#7FBA00"> </td>
  • <td[^>]*bgcolor="#F25022"> </td>
  • <td[^>]+background:#f25022[^>]+>.*?<td[^>]+background:#7fba00[^>]+>.*?<td[^>]+background:#01a4ef[^>]+>.*?<td[^>]+background:#ffb901[^>]+>
  • M\x{00AD}ic\x{00AD}ro\x{00AD}so\x{00AD}ft
  • background-color:#04B5F0;
  • background-color:#3eb55d;
  • background-color:#FF1940;
  • background-color:#FFCA07;
  • background-color:rgb(0,110,173)
  • background-color:rgb(0,114,30)
  • background-color:rgb(129,187,5)
  • background-color:rgb(213,56,62)
  • background-color:rgb(227,209,43)
  • background-color:rgb(246,93,53)
  • background-color:rgb(255,186,7)
  • background-color:rgb(4,165,240)
  • bgcolor="#05a1e8"
  • bgcolor="#7db606"
  • bgcolor="#eb5024"
  • bgcolor="#f7b408"
  • color: #2672ec;
field:"body.html.raw" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Microsoft quarantine release notification in body

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

Message containing suspicious quarantine release language in the body, and a Microsoft logo attachment but did not come from Microsoft.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and length(filter(attachments, .file_type not in $file_types_images)) == 0
and any(attachments,
        any(file.explode(.),
            (
              // attachment is most likely only a logo 
              (
                length(.scan.ocr.raw) < 15 or .scan.ocr.raw is null
              )
              and any(ml.logo_detect(..).brands,
                      strings.starts_with(.name, "Microsoft")
              )
            )
        )
        and (
          3 of (
            strings.ilike(body.current_thread.text, "*review*"),
            strings.ilike(body.current_thread.text, "*release*"),
            strings.ilike(body.current_thread.text, "*quarantine*"),
            strings.ilike(body.current_thread.text, "*messages*"),
            strings.ilike(body.current_thread.text, "*blocked*"),
            strings.ilike(body.current_thread.text, "*notification*"),
            strings.ilike(body.current_thread.text, "*kindly*")
          )
        )
)
and sender.email.domain.root_domain not in (
  "bing.com",
  "microsoft.com",
  "microsoftonline.com",
  "microsoftsupport.com",
  "microsoft365.com",
  "office.com",
  "office365.com",
  "onedrive.com",
  "sharepointonline.com",
  "yammer.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
)
and not profile.by_sender().solicited
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

Message containing suspicious quarantine release language in the body, and a Microsoft logo attachment but did not come from Microsoft.

  1. inbound message
  2. length(filter(attachments, .file_type not in $file_types_images)) is 0
  3. any of attachments where all hold:
    • any of file.explode(.) where all hold:
      • any of:
        • length(.scan.ocr.raw) < 15
        • .scan.ocr.raw is missing
      • any of ml.logo_detect(.).brands where:
        • .name starts with 'Microsoft'
    • at least 3 of 7: body.current_thread.text matches any of 7 patterns
      • *review*
      • *release*
      • *quarantine*
      • *messages*
      • *blocked*
      • *notification*
      • *kindly*
  4. sender.email.domain.root_domain not in ('bing.com', 'microsoft.com', 'microsoftonline.com', 'microsoftsupport.com', 'microsoft365.com', 'office.com', 'office365.com', 'onedrive.com', 'sharepointonline.com', 'yammer.com')
  5. 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
  6. not:
    • profile.by_sender().solicited
  7. not:
    • profile.by_sender().any_messages_benign

Inspects: attachments[].file_type, body.current_thread.text, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, ml.logo_detect, profile.by_sender, strings.ilike, strings.starts_with. Reference lists: $file_types_images, $high_trust_sender_root_domains.

Indicators matched (8)

FieldMatchValue
strings.starts_withprefixMicrosoft
strings.ilikesubstring*review*
strings.ilikesubstring*release*
strings.ilikesubstring*quarantine*
strings.ilikesubstring*messages*
strings.ilikesubstring*blocked*
strings.ilikesubstring*notification*
strings.ilikesubstring*kindly*

Stages and Predicates

Stage 1: mql_rule

and
  any(attachments)
    and
      any(file.explode(attachments))
        and
          or
            file.explode(attachments[])[].scan.ocr.raw is_null
            file.explode(attachments[])[].scan.ocr.raw length_compare "15"
          any(ml.logo_detect(attachments).brands)
            ml.logo_detect(attachments).brands.name starts_with "Microsoft"
      or
        body.current_thread.text match "blocked"
        body.current_thread.text match "kindly"
        body.current_thread.text match "messages"
        body.current_thread.text match "notification"
        body.current_thread.text match "quarantine"
        body.current_thread.text match "release"
        body.current_thread.text match "review"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  not
    profile.by_sender func_call "profile.by_sender().solicited"
  not
    sender.email.domain.root_domain in ["bing.com", "microsoft.com", "microsoft365.com", "microsoftonline.com", "microsoftsupport.com", "office.com", "office365.com", "onedrive.com", "sharepointonline.com", "yammer.com"]
  filter(attachments, .file_type not in $file_types_images) length_compare "0"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaininbing.com, microsoft.com, microsoft365.com, microsoftonline.com, microsoftsupport.com, office.com, office365.com, onedrive.com, sharepointonline.com, yammer.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Microsoft quarantine release notification in image attachment

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

Message with an image attachment containing credential theft language and references to the Microsoft Exchange quarantine, but did not come from Microsoft.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesFree file host, Impersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and length(filter(attachments, .file_type not in $file_types_images)) == 0
and any(attachments,
        any(file.explode(.),
            (
              any(ml.nlu_classifier(.scan.ocr.raw).intents,
                  .name == "cred_theft" and .confidence != "low"
              )
              or (
                length(ml.nlu_classifier(.scan.ocr.raw).intents) == 0
                and length(ml.nlu_classifier(.scan.ocr.raw).entities) > 2
              )
            )
            and (
              (
                any(ml.nlu_classifier(.scan.ocr.raw).entities,
                    .name == "urgency"
                )
              )
              or any(ml.nlu_classifier(.scan.ocr.raw).entities,
                     .name == "sender" and strings.icontains(.text, "Microsoft")
              )
            )
        )
        and any(file.explode(.),
                3 of (
                  strings.icontains(.scan.ocr.raw, "review"),
                  strings.icontains(.scan.ocr.raw, "release"),
                  strings.icontains(.scan.ocr.raw, "quarantine"),
                  strings.icontains(.scan.ocr.raw, "messages"),
                  strings.icontains(.scan.ocr.raw, "blocked"),
                  strings.icontains(.scan.ocr.raw, "notification"),
                  any(ml.logo_detect(..).brands,
                      strings.starts_with(.name, "Microsoft")
                  )
                )
        )
)
and sender.email.domain.root_domain not in (
  "bing.com",
  "microsoft.com",
  "microsoftonline.com",
  "microsoftsupport.com",
  "microsoft365.com",
  "office.com",
  "onedrive.com",
  "sharepointonline.com",
  "yammer.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
)
and not profile.by_sender().solicited
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

Message with an image attachment containing credential theft language and references to the Microsoft Exchange quarantine, but did not come from Microsoft.

  1. inbound message
  2. length(filter(attachments, .file_type not in $file_types_images)) is 0
  3. any of attachments where all hold:
    • any of file.explode(.) where all hold:
      • any of:
        • any of ml.nlu_classifier(.scan.ocr.raw).intents where all hold:
          • .name is 'cred_theft'
          • .confidence is not 'low'
        • all of:
          • length(ml.nlu_classifier(.scan.ocr.raw).intents) is 0
          • length(ml.nlu_classifier(.scan.ocr.raw).entities) > 2
      • any of:
        • any of ml.nlu_classifier(.scan.ocr.raw).entities where:
          • .name is 'urgency'
        • any of ml.nlu_classifier(.scan.ocr.raw).entities where all hold:
          • .name is 'sender'
          • .text contains 'Microsoft'
    • any of file.explode(.) where:
      • at least 3 of:
        • .scan.ocr.raw contains 'review'
        • .scan.ocr.raw contains 'release'
        • .scan.ocr.raw contains 'quarantine'
        • .scan.ocr.raw contains 'messages'
        • .scan.ocr.raw contains 'blocked'
        • .scan.ocr.raw contains 'notification'
        • any of ml.logo_detect(.).brands where:
          • .name starts with 'Microsoft'
  4. sender.email.domain.root_domain not in ('bing.com', 'microsoft.com', 'microsoftonline.com', 'microsoftsupport.com', 'microsoft365.com', 'office.com', 'onedrive.com', 'sharepointonline.com', 'yammer.com')
  5. 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
  6. not:
    • profile.by_sender().solicited
  7. not:
    • profile.by_sender().any_messages_benign

Inspects: attachments[].file_type, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, ml.logo_detect, ml.nlu_classifier, profile.by_sender, strings.icontains, strings.starts_with. Reference lists: $file_types_images, $high_trust_sender_root_domains.

Indicators matched (11)

FieldMatchValue
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].nameequalscred_theft
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).entities[].nameequalsurgency
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).entities[].nameequalssender
strings.icontainssubstringMicrosoft
strings.icontainssubstringreview
strings.icontainssubstringrelease
strings.icontainssubstringquarantine
strings.icontainssubstringmessages
strings.icontainssubstringblocked
strings.icontainssubstringnotification
strings.starts_withprefixMicrosoft

Stages and Predicates

Stage 1: mql_rule

and
  any(attachments)
    and
      any(file.explode(attachments))
        and
          or
            any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).entities)
              and
                ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).entities[].name eq "sender"
                ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).entities[].text contains "Microsoft"
            any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).entities)
              ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).entities.name eq "urgency"
          or
            any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).intents)
              and
                ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidence ne "low"
                ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].name eq "cred_theft"
            and
              ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).entities length_compare "2"
              ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents length_compare "0"
      any(file.explode(attachments))
        or
          any(ml.logo_detect(attachments).brands)
            ml.logo_detect(attachments).brands.name starts_with "Microsoft"
          file.explode(attachments[])[].scan.ocr.raw contains "blocked"
          file.explode(attachments[])[].scan.ocr.raw contains "messages"
          file.explode(attachments[])[].scan.ocr.raw contains "notification"
          file.explode(attachments[])[].scan.ocr.raw contains "quarantine"
          file.explode(attachments[])[].scan.ocr.raw contains "release"
          file.explode(attachments[])[].scan.ocr.raw contains "review"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  not
    profile.by_sender func_call "profile.by_sender().solicited"
  not
    sender.email.domain.root_domain in ["bing.com", "microsoft.com", "microsoft365.com", "microsoftonline.com", "microsoftsupport.com", "office.com", "onedrive.com", "sharepointonline.com", "yammer.com"]
  filter(attachments, .file_type not in $file_types_images) length_compare "0"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaininbing.com, microsoft.com, microsoft365.com, microsoftonline.com, microsoftsupport.com, office.com, onedrive.com, sharepointonline.com, yammer.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Microsoft Teams

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

Impersonation of a Microsoft Teams message.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • sender.email
  • type

Rule body

type.inbound
and length(filter(attachments,
                  .file_type in $file_types_images or .file_type == "pdf"
           )
) < 10
and any(attachments,
        (.file_type in $file_types_images or .file_type == "pdf")
        and any(file.explode(.),
                regex.icontains(.scan.ocr.raw,
                                "trying to reach you.*microsoft teams"
                )
        )
)
and sender.email.domain.root_domain not in (
  "microsoft.com",
  "microsoftsupport.com",
  "office.com"
)

Detection logic

Scope: inbound message.

Impersonation of a Microsoft Teams message.

  1. inbound message
  2. length(filter(attachments, .file_type in $file_types_images or .file_type == 'pdf')) < 10
  3. any of attachments where all hold:
    • any of:
      • .file_type in $file_types_images
      • .file_type is 'pdf'
    • any of file.explode(.) where:
      • .scan.ocr.raw matches 'trying to reach you.*microsoft teams'
  4. sender.email.domain.root_domain not in ('microsoft.com', 'microsoftsupport.com', 'office.com')

Inspects: attachments[].file_type, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, regex.icontains. Reference lists: $file_types_images.

Indicators matched (2)

FieldMatchValue
attachments[].file_typeequalspdf
regex.icontainsregextrying to reach you.*microsoft teams

Stages and Predicates

Stage 1: mql_rule

and
  any(attachments)
    and
      or
        attachments.file_type eq "pdf"
         macro "attachments[].file_type in file_types_images"
      any(file.explode(attachments))
        file.explode(attachments).scan.ocr.raw regex_match "trying to reach you.*microsoft teams"
  not
    sender.email.domain.root_domain in ["microsoft.com", "microsoftsupport.com", "office.com"]
  filter(attachments, .file_type in $file_types_images or .file_type == 'pdf') length_compare "10"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Microsoft Teams invitation

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

Detects messages impersonating a Microsoft Teams invites by matching known invite text patterns while containing join links that do not resolve to Microsoft domains. Additional verification includes checking for absent phone dial-in options and missing standard Teams help text or HTML meeting components.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.html
  • body.links
  • headers
  • headers.auth_summary
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  (
    strings.icontains(body.current_thread.text, 'Microsoft Teams')
    and strings.icontains(body.current_thread.text,
                          'join the meeting',
                          'confirm your attendance',
                          'confirm attendance'
    )
    and strings.contains(body.current_thread.text, 'Meeting ID:')
    and strings.contains(body.current_thread.text, 'Passcode:')
  )
  or (
    strings.icontains(body.current_thread.text, "teams")
    // strings that give us confidence it's teams
    and 2 of (
      strings.icontains(body.current_thread.text, "internal"),
      strings.icontains(body.current_thread.text, "message"),
      strings.icontains(body.current_thread.text, "meeting"),
      strings.icontains(body.current_thread.text, "Download Teams")
    )
  )
  // either the subject or sender.display name containt Microsoft Teams and Meeting
  or (
    any([subject.base, sender.display_name],
        strings.icontains(., 'Microsoft Teams')
        and strings.icontains(., 'meeting')
    )
  )
)
// not a reply
and length(headers.references) == 0
and headers.in_reply_to is null
// few links
and length(distinct(body.links, .href_url.url)) < 10
// short body
and length(body.current_thread.text) < 600
// no unsubscribe links
// common in newsletters which link to a webinar style event
and not any(body.links, strings.icontains(.display_text, "unsub"))

// one of the links contains is a CTA that doesn't link to MS
and any(body.current_thread.links,
        (
          .display_text =~ "join the meeting"
          or strings.icontains(.display_text, "join the meeting")
          or strings.icontains(.display_text, "play recording")
          // is a mismatched domain via .display_url
          or (
            .display_url.domain.root_domain in (
              "microsoft.com",
              "microsoft.us",
              "microsoft.cn",
              "live.com"
            )
            and .mismatched
          )
        )
        and .href_url.domain.root_domain not in (
          "microsoft.com",
          "microsoft.us",
          "microsoft.cn",
          "live.com"
        )
        and not (
          .href_url.domain.root_domain == "mimecastprotect.com"
          and (
            strings.parse_domain(.href_url.query_params_decoded["domain"][0]).root_domain in (
              "microsoft.com",
              "microsoft.us",
              "microsoft.cn",
              "live.com"
            )
            or strings.parse_domain(.href_url.query_params_decoded["domain"][0]).root_domain in $bulk_mailer_url_root_domains
          )
        )
        // rewriters often abstract the link
        and .href_url.domain.root_domain not in $bulk_mailer_url_root_domains
)
// missing the dial by phone element
and not strings.icontains(body.current_thread.text, 'Dial in by phone')

// any of these suspicious elements from the body
and (
  // malicious samples leveraged recipient domain branding here
  not strings.icontains(body.current_thread.text, 'Microsoft Teams Need help?')
  // malicious samples contained unique html elements not present in legit ones
  or strings.icontains(body.html.raw, '<div class="meeting-title">')
  or strings.icontains(body.html.raw, '<div class="meeting-time">')
  or strings.icontains(body.html.raw, '<div class="meeting-location">')
  or strings.icontains(body.html.raw, '<span class="conflict-badge">')
  or strings.icontains(body.html.raw, 'class="join-button"')
)

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

Detects messages impersonating a Microsoft Teams invites by matching known invite text patterns while containing join links that do not resolve to Microsoft domains. Additional verification includes checking for absent phone dial-in options and missing standard Teams help text or HTML meeting components.

  1. inbound message
  2. any of:
    • body.current_thread.text contains all of 6 patterns
      • Microsoft Teams
      • join the meeting
      • confirm your attendance
      • confirm attendance
      • Meeting ID:
      • Passcode:
    • all of:
      • body.current_thread.text contains 'teams'
      • at least 2 of 4: body.current_thread.text contains any of 4 patterns
        • internal
        • message
        • meeting
        • Download Teams
    • any of [subject.base, sender.display_name] where all hold:
      • . contains 'Microsoft Teams'
      • . contains 'meeting'
  3. length(headers.references) is 0
  4. headers.in_reply_to is missing
  5. length(distinct(body.links, .href_url.url)) < 10
  6. length(body.current_thread.text) < 600
  7. not:
    • any of body.links where:
      • .display_text contains 'unsub'
  8. any of body.current_thread.links where all hold:
    • any of:
      • .display_text is 'join the meeting'
      • .display_text contains 'join the meeting'
      • .display_text contains 'play recording'
      • all of:
        • .display_url.domain.root_domain in ('microsoft.com', 'microsoft.us', 'microsoft.cn', 'live.com')
        • .mismatched
    • .href_url.domain.root_domain not in ('microsoft.com', 'microsoft.us', 'microsoft.cn', 'live.com')
    • not:
      • all of:
        • .href_url.domain.root_domain is 'mimecastprotect.com'
        • any of:
          • strings.parse_domain(.href_url.query_params_decoded['domain'][0]).root_domain in ('microsoft.com', 'microsoft.us', 'microsoft.cn', 'live.com')
          • strings.parse_domain(.href_url.query_params_decoded['domain'][0]).root_domain in $bulk_mailer_url_root_domains
    • .href_url.domain.root_domain not in $bulk_mailer_url_root_domains
  9. not:
    • body.current_thread.text contains 'Dial in by phone'
  10. any of:
    • not:
      • body.current_thread.text contains 'Microsoft Teams Need help?'
    • body.html.raw contains '<div class="meeting-title">'
    • body.html.raw contains '<div class="meeting-time">'
    • body.html.raw contains '<div class="meeting-location">'
    • body.html.raw contains '<span class="conflict-badge">'
    • body.html.raw contains 'class="join-button"'
  11. 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.links, body.current_thread.links[].display_text, body.current_thread.links[].display_url.domain.root_domain, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.links[].href_url.query_params_decoded['domain'][0], body.current_thread.links[].mismatched, body.current_thread.text, body.html.raw, body.links, body.links[].display_text, body.links[].href_url.url, headers.auth_summary.dmarc.pass, headers.in_reply_to, headers.references, sender.display_name, sender.email.domain.root_domain, subject.base, type.inbound. Sensors: strings.contains, strings.icontains, strings.parse_domain. Reference lists: $bulk_mailer_url_root_domains, $high_trust_sender_root_domains.

Indicators matched (22)

FieldMatchValue
strings.icontainssubstringMicrosoft Teams
strings.icontainssubstringjoin the meeting
strings.icontainssubstringconfirm your attendance
strings.icontainssubstringconfirm attendance
strings.containssubstringMeeting ID:
strings.containssubstringPasscode:
strings.icontainssubstringteams
strings.icontainssubstringinternal
strings.icontainssubstringmessage
strings.icontainssubstringmeeting
strings.icontainssubstringDownload Teams
body.current_thread.links[].display_textequalsjoin the meeting
10 more
strings.icontainssubstringplay recording
body.current_thread.links[].display_url.domain.root_domainmembermicrosoft.com
body.current_thread.links[].display_url.domain.root_domainmembermicrosoft.us
body.current_thread.links[].display_url.domain.root_domainmembermicrosoft.cn
body.current_thread.links[].display_url.domain.root_domainmemberlive.com
strings.icontainssubstring<div class="meeting-title">
strings.icontainssubstring<div class="meeting-time">
strings.icontainssubstring<div class="meeting-location">
strings.icontainssubstring<span class="conflict-badge">
strings.icontainssubstringclass="join-button"

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    and
      not
        and
          or
            strings.parse_domain func_call "strings.parse_domain(body.current_thread.links[].href_url.query_params_decoded['domain'][0]).root_domain in (microsoft.com, microsoft.us, microsoft.cn, live.com)"
            strings.parse_domain func_call "strings.parse_domain(body.current_thread.links[].href_url.query_params_decoded['domain'][0]).root_domain in bulk_mailer_url_root_domains"
          body.current_thread.links.href_url.domain.root_domain eq "mimecastprotect.com"
      or
        and
          body.current_thread.links.display_url.domain.root_domain in ["live.com", "microsoft.cn", "microsoft.com", "microsoft.us"]
          body.current_thread.links.mismatched eq "true"
        body.current_thread.links.display_text contains "join the meeting"
        body.current_thread.links.display_text contains "play recording"
        body.current_thread.links.display_text eq "join the meeting"
      not
        body.current_thread.links.href_url.domain.root_domain in ["live.com", "microsoft.cn", "microsoft.com", "microsoft.us"]
       macro "body.current_thread.links[].href_url.domain.root_domain not in bulk_mailer_url_root_domains"
  or
    any([subject.base, sender.display_name])
      and
        [subject.base, sender.display_name] contains "Microsoft Teams"
        [subject.base, sender.display_name] contains "meeting"
    and
      or
        body.current_thread.text contains "Download Teams"
        body.current_thread.text contains "internal"
        body.current_thread.text contains "meeting"
        body.current_thread.text contains "message"
      body.current_thread.text contains "teams"
    and
      or
        body.current_thread.text contains "confirm attendance"
        body.current_thread.text contains "confirm your attendance"
        body.current_thread.text contains "join the meeting"
      body.current_thread.text contains "Meeting ID:"
      body.current_thread.text contains "Microsoft Teams"
      body.current_thread.text contains "Passcode:"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    not
      body.current_thread.text contains "Microsoft Teams Need help?"
    body.html.raw contains "<div class=\"meeting-location\">"
    body.html.raw contains "<div class=\"meeting-time\">"
    body.html.raw contains "<div class=\"meeting-title\">"
    body.html.raw contains "<span class=\"conflict-badge\">"
    body.html.raw contains "class=\"join-button\""
  not
    any(body.links)
      body.links.display_text contains "unsub"
  not
    body.current_thread.text contains "Dial in by phone"
  body.current_thread.text length_compare "600"
  distinct(body.links, .href_url.url) length_compare "10"
  headers.in_reply_to is_null
  headers.references length_compare "0"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
body.linksarray_any(no value, null check)excludes:body.links
body.current_thread.textcontainsDial in by phoneexcludes:body.current_thread.text field:"body.current_thread.text" value:"Dial in by phone"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textcontains
  • Download Teams
  • Meeting ID:
  • Microsoft Teams
  • Passcode:
  • confirm attendance
  • confirm your attendance
  • internal
  • join the meeting
  • meeting
  • message
  • teams
field:"body.current_thread.text" kind:contains
body.html.rawcontains
  • <div class="meeting-location">
  • <div class="meeting-time">
  • <div class="meeting-title">
  • <span class="conflict-badge">
  • class="join-button"
field:"body.html.raw" kind:contains
headers.in_reply_tois_null
  • (no value, null check)
field:"headers.in_reply_to" kind:is_null
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Microsoft with embedded logo and credential theft language

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

This rule detects messages impersonating Microsoft via a logo and contains credential theft language. From a new and unsolicited sender.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • body.links
  • headers
  • headers.auth_summary
  • headers.domains
  • headers.hops
  • headers.return_path
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  (
    length(attachments) > 0
    and all(attachments,
            .file_type in $file_types_images or .file_type == "pdf"
    )
  )
  or length(attachments) == 0
)
and any(ml.logo_detect(file.message_screenshot()).brands,
        strings.starts_with(.name, "Microsoft")
)
and (
  any(ml.nlu_classifier(body.current_thread.text).intents,
      .name == "cred_theft" and .confidence in ("medium", "high")
  )
  or (
    length(body.current_thread.text) == 0
    //
    // This rule makes use of a beta feature and is subject to change without notice
    // using the beta feature in custom rules is not suggested until it has been formally released
    //
    and any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents,
            .name == "cred_theft" and .confidence in ("medium", "high")
    )
  )
)
and (
  not (
    headers.auth_summary.dmarc.pass
    and headers.auth_summary.dmarc.details.from.domain in (
      "azureadnotifications.us",
      "microsoft.com",
      "sharepointonline.com",
      "cloudappsecurity.com",
      "microsoftsupport.com",
      "microsoft.onmicrosoft.com",
      "yammer.com"
    )
  )
  or headers.auth_summary.dmarc.pass is null
  or headers.auth_summary.dmarc.details.from.domain is null
)
and not (
  sender.email.domain.domain == "planner.office365.com"
  and headers.return_path.email == "noreply@planner.office365.com"
  and headers.auth_summary.dmarc.details.from.root_domain == "office365.com"
)

// Microsoft has some legit onmicrosoft domains...
and not (
  sender.email.domain.domain == "microsoft.onmicrosoft.com"
  and headers.auth_summary.spf.pass
  and all(body.links, .href_url.domain.root_domain == "microsoft.com")
)

// message is not from sharepoint actual (additional check in case DMARC check above fails to bail out)
and not (
  (
    strings.ilike(headers.message_id,
                  '<Share-*',
                  '<MassDelete-*',
                  '<FileDeleteAfterExpiration-*',
                  '<NotifyOwnerSharedWithExternalUsers*',
                  '<OneTimePasscode*'
    )
    and strings.ends_with(headers.message_id, '@odspnotify>')
  )
  or (
    any(headers.hops,
        any(.fields,
            .name == "X-Google-Original-Message-ID"
            and strings.ilike(.value,
                              '<Share-*',
                              '<MassDelete-*',
                              '<FileDeleteAfterExpiration-*',
                              '<NotifyOwnerSharedWithExternalUsers*',
                              '<OneTimePasscode*'
            )
            and strings.ends_with(.value, '@odspnotify>')
        )
    )
  )
)

// negate legitimate microsoft b2b applications invitations
and not (
  length(body.links) > 0
  and (
    sender.email.local_part == "invites"
    and sender.email.domain.root_domain == "onmicrosoft.com"
    // infra validated message id
    and strings.icontains(headers.message_id, "pepf")
  )
)

// sender profiles
and (
  not profile.by_sender().solicited
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)

// negate org domains unless they fail DMARC authentication
and (
  (
    sender.email.domain.root_domain in $org_domains
    and (
      not headers.auth_summary.dmarc.pass
      // MS quarantine digest emails from an org domain are router "internally" to MS, therefore, there is no authentication information
      or not (
        headers.auth_summary.dmarc.pass is null
        and all(headers.domains,
                .root_domain in ("outlook.com", "office365.com")
        )
        // typical emails from freemail Outlook accounts are from prod.outlook.com
        and strings.ends_with(headers.message_id, "protection.outlook.com>")
      )
    )
  )
  or sender.email.domain.root_domain not in $org_domains
)

// negate sharepoint file shares with mimecast rewrites
and not (
  // rewritten message ID
  strings.iends_with(headers.message_id, 'mimecast.lan>')
  and all(filter(body.links,
                 strings.icontains(subject.subject, .display_text)
                 or .display_text == "Open"
          ),
          .href_url.domain.root_domain in (
            "mimecastprotect.com",
            "mimecast.com"
          )
          and any(.href_url.query_params_decoded["domain"],
                  strings.parse_domain(.).tld == "ms"
                  or strings.parse_domain(.).root_domain == "sharepoint.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
)
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

This rule detects messages impersonating Microsoft via a logo and contains credential theft language. From a new and unsolicited sender.

  1. inbound message
  2. any of:
    • all of:
      • length(attachments) > 0
      • all of attachments where any holds:
        • .file_type in $file_types_images
        • .file_type is 'pdf'
    • length(attachments) is 0
  3. any of ml.logo_detect(file.message_screenshot()).brands where:
    • .name starts with 'Microsoft'
  4. any of:
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'cred_theft'
      • .confidence in ('medium', 'high')
    • all of:
      • length(body.current_thread.text) is 0
      • any of ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents where all hold:
        • .name is 'cred_theft'
        • .confidence in ('medium', 'high')
  5. any of:
    • not:
      • all of:
        • headers.auth_summary.dmarc.pass
        • headers.auth_summary.dmarc.details.from.domain in ('azureadnotifications.us', 'microsoft.com', 'sharepointonline.com', 'cloudappsecurity.com', 'microsoftsupport.com', 'microsoft.onmicrosoft.com', 'yammer.com')
    • headers.auth_summary.dmarc.pass is missing
    • headers.auth_summary.dmarc.details.from.domain is missing
  6. not:
    • all of:
      • sender.email.domain.domain is 'planner.office365.com'
      • headers.return_path.email is 'noreply@planner.office365.com'
      • headers.auth_summary.dmarc.details.from.root_domain is 'office365.com'
  7. not:
    • all of:
      • sender.email.domain.domain is 'microsoft.onmicrosoft.com'
      • headers.auth_summary.spf.pass
      • all of body.links where:
        • .href_url.domain.root_domain is 'microsoft.com'
  8. none of:
    • all of:
      • headers.message_id matches any of 5 patterns
        • <Share-*
        • <MassDelete-*
        • <FileDeleteAfterExpiration-*
        • <NotifyOwnerSharedWithExternalUsers*
        • <OneTimePasscode*
      • headers.message_id ends with '@odspnotify>'
    • any of headers.hops where:
      • any of .fields where all hold:
        • .name is 'X-Google-Original-Message-ID'
        • .value matches any of 5 patterns
          • <Share-*
          • <MassDelete-*
          • <FileDeleteAfterExpiration-*
          • <NotifyOwnerSharedWithExternalUsers*
          • <OneTimePasscode*
        • .value ends with '@odspnotify>'
  9. not:
    • all of:
      • length(body.links) > 0
      • all of:
        • sender.email.local_part is 'invites'
        • sender.email.domain.root_domain is 'onmicrosoft.com'
        • headers.message_id contains 'pepf'
  10. any of:
    • not:
      • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  11. any of:
    • all of:
      • sender.email.domain.root_domain in $org_domains
      • any of:
        • not:
          • headers.auth_summary.dmarc.pass
        • not:
          • all of:
            • headers.auth_summary.dmarc.pass is missing
            • all of headers.domains where:
              • .root_domain in ('outlook.com', 'office365.com')
            • headers.message_id ends with 'protection.outlook.com>'
    • sender.email.domain.root_domain not in $org_domains
  12. not:
    • all of:
      • headers.message_id ends with 'mimecast.lan>'
      • all of filter(body.links) where all hold:
        • .href_url.domain.root_domain in ('mimecastprotect.com', 'mimecast.com')
        • any of .href_url.query_params_decoded['domain'] where any holds:
          • strings.parse_domain(.).tld is 'ms'
          • strings.parse_domain(.).root_domain is 'sharepoint.com'
  13. 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
  14. not:
    • profile.by_sender().any_messages_benign

Inspects: attachments[].file_type, body.current_thread.text, body.links, body.links[].display_text, body.links[].href_url.domain.root_domain, headers.auth_summary.dmarc.details.from.domain, headers.auth_summary.dmarc.details.from.root_domain, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.domains, headers.domains[].root_domain, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, headers.message_id, headers.return_path.email, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.local_part, subject.subject, type.inbound. Sensors: beta.ocr, file.message_screenshot, ml.logo_detect, ml.nlu_classifier, profile.by_sender, strings.ends_with, strings.icontains, strings.iends_with, strings.ilike, strings.parse_domain, strings.starts_with. Reference lists: $file_types_images, $high_trust_sender_root_domains, $org_domains.

Indicators matched (8)

FieldMatchValue
attachments[].file_typeequalspdf
strings.starts_withprefixMicrosoft
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(beta.ocr(file.message_screenshot()).text).intents[].nameequalscred_theft
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents[].confidencemembermedium
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents[].confidencememberhigh

Stages and Predicates

Stage 1: mql_rule

and
  not
    or
      any(headers.hops)
        any(headers.hops.fields)
          and
            or
              headers.hops.fields[].value starts_with "<FileDeleteAfterExpiration-"
              headers.hops.fields[].value starts_with "<MassDelete-"
              headers.hops.fields[].value starts_with "<NotifyOwnerSharedWithExternalUsers"
              headers.hops.fields[].value starts_with "<OneTimePasscode"
              headers.hops.fields[].value starts_with "<Share-"
            headers.hops.fields[].name eq "X-Google-Original-Message-ID"
            headers.hops.fields[].value ends_with "@odspnotify>"
      and
        or
          headers.message_id starts_with "<FileDeleteAfterExpiration-"
          headers.message_id starts_with "<MassDelete-"
          headers.message_id starts_with "<NotifyOwnerSharedWithExternalUsers"
          headers.message_id starts_with "<OneTimePasscode"
          headers.message_id starts_with "<Share-"
        headers.message_id ends_with "@odspnotify>"
  or
    and
      or
        not
          and
            headers.auth_summary.dmarc.pass is_null
            headers.message_id ends_with "protection.outlook.com>"
             macro "all(headers.domains)"
        not
          headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in org_domains"
     macro "sender.email.domain.root_domain not in org_domains"
  or
    and
      any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents)
        and
          ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents.confidence in ["high", "medium"]
          ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents.name eq "cred_theft"
      body.current_thread.text length_compare "0"
    any(ml.nlu_classifier(body.current_thread.text).intents)
      and
        ml.nlu_classifier(body.current_thread.text).intents.confidence in ["high", "medium"]
        ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
  or
    not
      and
        headers.auth_summary.dmarc.details.from.domain in ["azureadnotifications.us", "cloudappsecurity.com", "microsoft.com", "microsoft.onmicrosoft.com", "microsoftsupport.com", "sharepointonline.com", "yammer.com"]
        headers.auth_summary.dmarc.pass eq "true"
    headers.auth_summary.dmarc.details.from.domain is_null
    headers.auth_summary.dmarc.pass is_null
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    not
      profile.by_sender func_call "profile.by_sender().solicited"
  or
    and
      attachments length_compare "0"
       macro "all(attachments)"
    attachments length_compare "0"
  not
    and
      body.links length_compare "0"
      headers.message_id contains "pepf"
      sender.email.domain.root_domain eq "onmicrosoft.com"
      sender.email.local_part eq "invites"
  not
    and
      headers.auth_summary.dmarc.details.from.root_domain eq "office365.com"
      headers.return_path.email eq "noreply@planner.office365.com"
      sender.email.domain.domain eq "planner.office365.com"
  not
    and
      headers.auth_summary.spf.pass eq "true"
      sender.email.domain.domain eq "microsoft.onmicrosoft.com"
       macro "all(body.links)"
  not
    and
      headers.message_id ends_with "mimecast.lan>"
       macro "all(filter(body.links))"
  any(ml.logo_detect(file.message_screenshot()).brands)
    ml.logo_detect(file.message_screenshot()).brands.name starts_with "Microsoft"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.hopsarray_any(no value, null check)excludes:headers.hops
headers.message_idstarts_with<FileDeleteAfterExpiration-excludes:headers.message_id field:"headers.message_id" value:"<FileDeleteAfterExpiration-"
headers.message_idstarts_with<MassDelete-excludes:headers.message_id field:"headers.message_id" value:"<MassDelete-"
headers.message_idstarts_with<NotifyOwnerSharedWithExternalUsersexcludes:headers.message_id field:"headers.message_id" value:"<NotifyOwnerSharedWithExternalUsers"
headers.message_idstarts_with<OneTimePasscodeexcludes:headers.message_id field:"headers.message_id" value:"<OneTimePasscode"
headers.message_idstarts_with<Share-excludes:headers.message_id field:"headers.message_id" value:"<Share-"
headers.message_idends_with@odspnotify>excludes:headers.message_id field:"headers.message_id" value:"@odspnotify>"
body.linkslength_compare0excludes:body.links field:"body.links" value:"0"
headers.message_idcontainspepfexcludes:headers.message_id field:"headers.message_id" value:"pepf"
sender.email.domain.root_domaineqonmicrosoft.comexcludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"onmicrosoft.com"
sender.email.local_parteqinvitesexcludes:sender.email.local_part field:"sender.email.local_part" value:"invites"
headers.auth_summary.dmarc.details.from.root_domaineqoffice365.comexcludes:headers.auth_summary.dmarc.details.from.root_domain field:"headers.auth_summary.dmarc.details.from.root_domain" value:"office365.com"
headers.return_path.emaileqnoreply@planner.office365.comexcludes:headers.return_path.email field:"headers.return_path.email" value:"noreply@planner.office365.com"
sender.email.domain.domaineqplanner.office365.comexcludes:sender.email.domain.domain field:"sender.email.domain.domain" value:"planner.office365.com"
headers.auth_summary.spf.passeqtrueexcludes:headers.auth_summary.spf.pass field:"headers.auth_summary.spf.pass" value:"true"
sender.email.domain.domaineqmicrosoft.onmicrosoft.comexcludes:sender.email.domain.domain field:"sender.email.domain.domain" value:"microsoft.onmicrosoft.com"
headers.message_idends_withmimecast.lan>excludes:headers.message_id field:"headers.message_id" value:"mimecast.lan>"

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Netflix

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

Impersonation of Netflix.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • recipients
  • recipients.cc
  • recipients.to
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  // obfuscated sender display name
  (
    sender.display_name is not null
    and (
      regex.icontains(strings.replace_confusables(sender.display_name),
                      '[nm]etf[li][il]x'
      )
      or strings.ilevenshtein(strings.replace_confusables(sender.display_name),
                              'netflix'
      ) <= 1
      or regex.icontains(strings.replace_confusables(sender.display_name),
                         'n.{0,3}e.{0,3}t.{0,3}f.{0,3}l.{0,3}i.{0,3}x.{0,3}'
      )
    )
  )
  // Netflix reactivate subscription
  or (
    strings.icontains(subject.base, "netflix")
    and regex.icontains(body.current_thread.text,
                        'reactivate\s+(your\s+)?subscription'
    )
  )
  or (
    strings.icontains(strings.replace_confusables(body.current_thread.text),
                      'netplusflix'
    )
    and strings.count(body.current_thread.text, '©') == 1
  )
  // obfuscated sender email domain
  or regex.icontains(strings.replace_confusables(sender.email.domain.domain),
                     '[nm]etf[li][il]x'
  )
  // logo detection on message screenshot (no link analysis)
  or (
    any(ml.logo_detect(file.message_screenshot()).brands,
        .name == "Netflix" and .confidence in ("medium", "high")
    )
    and (
      // non NLU based keywords on the screenshot
      regex.icontains(beta.ocr(file.message_screenshot()).text,
                      'suspen(?:ded|sion)'
      )
      or 
      // combo of NLU cred_theft + financial + Customer Service and Support
      (
        any(ml.nlu_classifier(body.current_thread.text).intents,
            .name == "cred_theft"
        )
        and any(ml.nlu_classifier(body.current_thread.text).entities,
                .name == "financial"
        )
        and any(ml.nlu_classifier(body.current_thread.text).topics,
                .name == "Customer Service and Support"
        )
      )
    )
  )
  // Address Detection
  or 2 of (
    strings.icontains(body.current_thread.text, 'Netflix, Inc'),
    strings.icontains(body.current_thread.text, '100 Winchester Circle'),
    strings.icontains(body.current_thread.text, 'Los Gatos, CA 95032')
  )
  // unusual recipient pattern + logo detect + credphish dispoistion
  or (
    (
      length(recipients.to) == 0
      or (
        all(recipients.to, .email.domain.valid == false)
        and all(recipients.cc, .email.domain.valid == false)
      )
    )
    and any(ml.logo_detect(file.message_screenshot()).brands,
            .name == "Netflix" and .confidence in ("medium", "high")
    )
    and (
      any(body.links,
          ml.link_analysis(.).credphish.disposition == "phishing"
          and ml.link_analysis(.).credphish.confidence in ("medium", "high")
      )
    )
  )
)
// negation of legit domains
and not (
  sender.email.domain.root_domain in (
    'netflix.com',
    'dvd.com',
    'netflixfamily.com',
    'netflixpreviewclub.com',
    'netflixanimation.com',
    'envoy.com',
    'lexisnexis.com',
    'netflix.shop',
    'netflixcontractors.com', // owned by netflix
    'netflixevents.com', // owned by netflix
    'netelixir.com', // unrelated marketing
    'netflixhouse.com', // owned by netflix
    'instagram.com',
    'netflix.net',
    'netflixshopsupport.com', // owned by netflix
    'netflixpartner.com', // owned by netflix
  )
  and coalesce(headers.auth_summary.dmarc.pass, false)
)
and not (
  sender.email.domain.domain in (
    'netflix.zendesk.com' // netflix actual support
  )
  and coalesce(headers.auth_summary.dmarc.pass, false)
)
and not profile.by_sender_email().solicited

Detection logic

Scope: inbound message.

Impersonation of Netflix.

  1. inbound message
  2. any of:
    • all of:
      • sender.display_name is set
      • any of:
        • strings.replace_confusables(sender.display_name) matches '[nm]etf[li][il]x'
        • strings.replace_confusables(sender.display_name) is similar to 'netflix'
        • strings.replace_confusables(sender.display_name) matches 'n.{0,3}e.{0,3}t.{0,3}f.{0,3}l.{0,3}i.{0,3}x.{0,3}'
    • all of:
      • subject.base contains 'netflix'
      • body.current_thread.text matches 'reactivate\\s+(your\\s+)?subscription'
    • all of:
      • strings.replace_confusables(body.current_thread.text) contains 'netplusflix'
      • strings.count(body.current_thread.text, '©') is 1
    • strings.replace_confusables(sender.email.domain.domain) matches '[nm]etf[li][il]x'
    • all of:
      • any of ml.logo_detect(file.message_screenshot()).brands where all hold:
        • .name is 'Netflix'
        • .confidence in ('medium', 'high')
      • any of:
        • beta.ocr(file.message_screenshot()).text matches 'suspen(?:ded|sion)'
        • all of:
          • any of ml.nlu_classifier(body.current_thread.text).intents where:
            • .name is 'cred_theft'
          • any of ml.nlu_classifier(body.current_thread.text).entities where:
            • .name is 'financial'
          • any of ml.nlu_classifier(body.current_thread.text).topics where:
            • .name is 'Customer Service and Support'
    • at least 2 of:
      • body.current_thread.text contains 'Netflix, Inc'
      • body.current_thread.text contains '100 Winchester Circle'
      • body.current_thread.text contains 'Los Gatos, CA 95032'
    • all of:
      • any of:
        • length(recipients.to) is 0
        • all of:
          • all of recipients.to where:
            • .email.domain.valid is False
          • all of recipients.cc where:
            • .email.domain.valid is False
      • any of ml.logo_detect(file.message_screenshot()).brands where all hold:
        • .name is 'Netflix'
        • .confidence in ('medium', 'high')
      • any of body.links where all hold:
        • ml.link_analysis(.).credphish.disposition is 'phishing'
        • ml.link_analysis(.).credphish.confidence in ('medium', 'high')
  3. not:
    • all of:
      • sender.email.domain.root_domain in ('netflix.com', 'dvd.com', 'netflixfamily.com', 'netflixpreviewclub.com', 'netflixanimation.com', 'envoy.com', 'lexisnexis.com', 'netflix.shop', 'netflixcontractors.com', 'netflixevents.com', 'netelixir.com', 'netflixhouse.com', 'instagram.com', 'netflix.net', 'netflixshopsupport.com', 'netflixpartner.com')
      • coalesce(headers.auth_summary.dmarc.pass)
  4. not:
    • all of:
      • sender.email.domain.domain in ('netflix.zendesk.com')
      • coalesce(headers.auth_summary.dmarc.pass)
  5. not:
    • profile.by_sender_email().solicited

Inspects: body.current_thread.text, body.links, headers.auth_summary.dmarc.pass, recipients.cc, recipients.cc[].email.domain.valid, recipients.to, recipients.to[].email.domain.valid, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, subject.base, type.inbound. Sensors: beta.ocr, file.message_screenshot, ml.link_analysis, ml.logo_detect, ml.nlu_classifier, profile.by_sender_email, regex.icontains, strings.count, strings.icontains, strings.ilevenshtein, strings.replace_confusables.

Indicators matched (16)

FieldMatchValue
regex.icontainsregex[nm]etf[li][il]x
strings.ilevenshteinfuzzynetflix
regex.icontainsregexn.{0,3}e.{0,3}t.{0,3}f.{0,3}l.{0,3}i.{0,3}x.{0,3}
strings.icontainssubstringnetflix
regex.icontainsregexreactivate\s+(your\s+)?subscription
strings.icontainssubstringnetplusflix
ml.logo_detect(file.message_screenshot()).brands[].nameequalsNetflix
ml.logo_detect(file.message_screenshot()).brands[].confidencemembermedium
ml.logo_detect(file.message_screenshot()).brands[].confidencememberhigh
regex.icontainsregexsuspen(?:ded|sion)
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsfinancial
4 more
ml.nlu_classifier(body.current_thread.text).topics[].nameequalsCustomer Service and Support
strings.icontainssubstringNetflix, Inc
strings.icontainssubstring100 Winchester Circle
strings.icontainssubstringLos Gatos, CA 95032

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      or
        and
          any(ml.nlu_classifier(body.current_thread.text).entities)
            ml.nlu_classifier(body.current_thread.text).entities.name eq "financial"
          any(ml.nlu_classifier(body.current_thread.text).intents)
            ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
          any(ml.nlu_classifier(body.current_thread.text).topics)
            ml.nlu_classifier(body.current_thread.text).topics.name eq "Customer Service and Support"
        beta.ocr(file.message_screenshot()).text regex_match "suspen(?:ded|sion)"
      any(ml.logo_detect(file.message_screenshot()).brands)
        and
          ml.logo_detect(file.message_screenshot()).brands.confidence in ["high", "medium"]
          ml.logo_detect(file.message_screenshot()).brands.name eq "Netflix"
    and
      any(body.links)
        and
          ml.link_analysis func_call "ml.link_analysis(body.links[]).credphish.confidence in (medium, high)"
          ml.link_analysis func_call "ml.link_analysis(body.links[]).credphish.disposition == phishing"
      any(ml.logo_detect(file.message_screenshot()).brands)
        and
          ml.logo_detect(file.message_screenshot()).brands.confidence in ["high", "medium"]
          ml.logo_detect(file.message_screenshot()).brands.name eq "Netflix"
      or
        and
           macro "all(recipients.cc)"
           macro "all(recipients.to)"
        recipients.to length_compare "0"
    and
      or
        strings.ilevenshtein func_call "strings.ilevenshtein(strings.replace_confusables(sender.display_name), \"netflix\") <= 1"
        strings.replace_confusables(sender.display_name) regex_match "[nm]etf[li][il]x"
        strings.replace_confusables(sender.display_name) regex_match "n.{0,3}e.{0,3}t.{0,3}f.{0,3}l.{0,3}i.{0,3}x.{0,3}"
      sender.display_name is_not_null
    and
      body.current_thread.text regex_match "reactivate\\s+(your\\s+)?subscription"
      subject.base contains "netflix"
    and
      strings.count func_call "strings.count(body.current_thread.text, \"©\") == 1"
      strings.replace_confusables(body.current_thread.text) contains "netplusflix"
    body.current_thread.text contains "100 Winchester Circle"
    body.current_thread.text contains "Los Gatos, CA 95032"
    body.current_thread.text contains "Netflix, Inc"
    strings.replace_confusables(sender.email.domain.domain) regex_match "[nm]etf[li][il]x"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
      sender.email.domain.domain eq "netflix.zendesk.com"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
      sender.email.domain.root_domain in ["dvd.com", "envoy.com", "instagram.com", "lexisnexis.com", "netelixir.com", "netflix.com", "netflix.net", "netflix.shop", "netflixanimation.com", "netflixcontractors.com", "netflixevents.com", "netflixfamily.com", "netflixhouse.com", "netflixpartner.com", "netflixpreviewclub.com", "netflixshopsupport.com"]
  not
    profile.by_sender_email func_call "profile.by_sender_email().solicited"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.domaineqnetflix.zendesk.comexcludes:sender.email.domain.domain field:"sender.email.domain.domain" value:"netflix.zendesk.com"
sender.email.domain.root_domainindvd.com, envoy.com, instagram.com, lexisnexis.com, netelixir.com, netflix.com, netflix.net, netflix.shop, netflixanimation.com, netflixcontractors.com, netflixevents.com, netflixfamily.com, netflixhouse.com, netflixpartner.com, netflixpreviewclub.com, netflixshopsupport.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Norton

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

Scans files to detect Norton (Lifelock|360|Security) impersonation.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesFree email provider, Impersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • headers
  • headers.reply_to
  • recipients
  • recipients.to
  • sender.email
  • type

Rule body

type.inbound
and sender.email.domain.domain != "norton.com"
and any(attachments,
        (.file_type in $file_types_images or .file_type == "pdf")
        and (
          (
            strings.ilike(.file_name, "*norton*")
            and not (
              any(recipients.to, strings.iends_with(.display_name, "Norton"))
            )
          )
          or any(file.explode(.),
                 regex.icontains(.scan.ocr.raw,
                                 ".*norton.?60.*",
                                 ".*lifelock.*",
                                 ".*norton.?security.*",
                                 ".*norton.?anti.?virus.*",
                                 ".*Norton.{2,3}subscription.*"
                 )
          )
        )
)
and (
  (
    // if freemail, flag if it's a first-time sender
    sender.email.domain.root_domain in $free_email_providers
    and sender.email.email not in $sender_emails
  )
  or (
    // if custom domain, we want to avoid flagging
    // on the real Norton invoices
    // so we flag if it's not a first-time sender
    // and if it's not in the tranco 1M w/ a reply-to mismatch
    // for example we've observed:
    // Sender: Norton <quickbooks@notification.intuit.com>
    // Reply-to: foo@outlook.com
    sender.email.domain.root_domain not in $free_email_providers
    and sender.email.domain.domain not in $sender_domains
    and (
      sender.email.domain.root_domain not in $tranco_1m
      or any(headers.reply_to,
             .email.domain.domain != sender.email.domain.domain
      )
    )
  )
  or (
    (
      length(recipients.to) == 0
      or all(recipients.to, .display_name == "Undisclosed recipients")
    )
    and length(recipients.cc) == 0
    and length(recipients.bcc) == 0
  )
)

Detection logic

Scope: inbound message.

Scans files to detect Norton (Lifelock|360|Security) impersonation.

  1. inbound message
  2. sender.email.domain.domain is not 'norton.com'
  3. any of attachments where all hold:
    • any of:
      • .file_type in $file_types_images
      • .file_type is 'pdf'
    • any of:
      • all of:
        • .file_name matches '*norton*'
        • not:
          • any of recipients.to where:
            • .display_name ends with 'Norton'
      • any of file.explode(.) where:
        • .scan.ocr.raw matches any of 5 patterns
          • .*norton.?60.*
          • .*lifelock.*
          • .*norton.?security.*
          • .*norton.?anti.?virus.*
          • .*Norton.{2,3}subscription.*
  4. any of:
    • all of:
      • sender.email.domain.root_domain in $free_email_providers
      • sender.email.email not in $sender_emails
    • all of:
      • sender.email.domain.root_domain not in $free_email_providers
      • sender.email.domain.domain not in $sender_domains
      • any of:
        • sender.email.domain.root_domain not in $tranco_1m
        • any of headers.reply_to where:
          • .email.domain.domain is not sender.email.domain.domain
    • all of:
      • any of:
        • length(recipients.to) is 0
        • all of recipients.to where:
          • .display_name is 'Undisclosed recipients'
      • length(recipients.cc) is 0
      • length(recipients.bcc) is 0

Inspects: attachments[].file_name, attachments[].file_type, headers.reply_to, headers.reply_to[].email.domain.domain, recipients.bcc, recipients.cc, recipients.to, recipients.to[].display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: file.explode, regex.icontains, strings.iends_with, strings.ilike. Reference lists: $file_types_images, $free_email_providers, $sender_domains, $sender_emails, $tranco_1m.

Indicators matched (8)

FieldMatchValue
attachments[].file_typeequalspdf
strings.ilikesubstring*norton*
regex.icontainsregex.*norton.?60.*
regex.icontainsregex.*lifelock.*
regex.icontainsregex.*norton.?security.*
regex.icontainsregex.*norton.?anti.?virus.*
regex.icontainsregex.*Norton.{2,3}subscription.*
recipients.to[].display_nameequalsUndisclosed recipients

Stages and Predicates

Stage 1: mql_rule

and
  any(attachments)
    and
      or
        and
          not
            any(recipients.to)
              recipients.to.display_name ends_with "Norton"
          attachments.file_name match "norton"
        any(file.explode(attachments))
          or
            file.explode(attachments[])[].scan.ocr.raw regex_match ".*Norton.{2,3}subscription.*"
            file.explode(attachments[])[].scan.ocr.raw regex_match ".*lifelock.*"
            file.explode(attachments[])[].scan.ocr.raw regex_match ".*norton.?60.*"
            file.explode(attachments[])[].scan.ocr.raw regex_match ".*norton.?anti.?virus.*"
            file.explode(attachments[])[].scan.ocr.raw regex_match ".*norton.?security.*"
      or
        attachments.file_type eq "pdf"
         macro "attachments[].file_type in file_types_images"
  or
    and
      or
        any(headers.reply_to)
          headers.reply_to.email.domain.domain cross_field_compare "sender.email.domain.domain"
         macro "sender.email.domain.root_domain not in tranco_1m"
       macro "sender.email.domain.domain not in sender_domains"
       macro "sender.email.domain.root_domain not in free_email_providers"
    and
      or
        recipients.to length_compare "0"
         macro "all(recipients.to)"
      recipients.bcc length_compare "0"
      recipients.cc length_compare "0"
    and
       macro "sender.email.domain.root_domain in free_email_providers"
       macro "sender.email.email not in sender_emails"
  sender.email.domain.domain ne "norton.com"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Office 365 mail service

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

Detects messages from domains containing both 'o365' and 'mail' in the second-level domain, commonly used to impersonate legitimate Microsoft Office 365 mail services.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  strings.icontains(sender.email.domain.sld, 'o365')
  or strings.icontains(sender.email.domain.sld, 'outlook')
  or strings.icontains(sender.email.domain.sld, 'office')
)
and strings.icontains(sender.email.domain.sld, 'mail')
// not benign use cases
and not (
  sender.email.domain.root_domain in (
    "agentofficemail.com", // mandrill app addon
    "mdofficemail.com", // doctor office
    "medofficemail.com", // doctor office
    "officemailbox.fr", // bulk mail provider
    "mail-office.fr", // bulk mail provider
    "officedepot-mail.co.kr", // office depot in kr
    "emailmarketdataoutlook.com", // email mrkting 
    "officelabsmail.co.uk" // company in the uk
  )
  and headers.auth_summary.dmarc.pass
)

Detection logic

Scope: inbound message.

Detects messages from domains containing both 'o365' and 'mail' in the second-level domain, commonly used to impersonate legitimate Microsoft Office 365 mail services.

  1. inbound message
  2. any of:
    • sender.email.domain.sld contains 'o365'
    • sender.email.domain.sld contains 'outlook'
    • sender.email.domain.sld contains 'office'
  3. sender.email.domain.sld contains 'mail'
  4. not:
    • all of:
      • sender.email.domain.root_domain in ('agentofficemail.com', 'mdofficemail.com', 'medofficemail.com', 'officemailbox.fr', 'mail-office.fr', 'officedepot-mail.co.kr', 'emailmarketdataoutlook.com', 'officelabsmail.co.uk')
      • headers.auth_summary.dmarc.pass

Inspects: headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, sender.email.domain.sld, type.inbound. Sensors: strings.icontains.

Indicators matched (4)

FieldMatchValue
strings.icontainssubstringo365
strings.icontainssubstringoutlook
strings.icontainssubstringoffice
strings.icontainssubstringmail

Stages and Predicates

Stage 1: mql_rule

and
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.root_domain in ["agentofficemail.com", "emailmarketdataoutlook.com", "mail-office.fr", "mdofficemail.com", "medofficemail.com", "officedepot-mail.co.kr", "officelabsmail.co.uk", "officemailbox.fr"]
  or
    sender.email.domain.sld contains "o365"
    sender.email.domain.sld contains "office"
    sender.email.domain.sld contains "outlook"
  sender.email.domain.sld contains "mail"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
sender.email.domain.root_domaininagentofficemail.com, emailmarketdataoutlook.com, mail-office.fr, mdofficemail.com, medofficemail.com, officedepot-mail.co.kr, officelabsmail.co.uk, officemailbox.frexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Okta

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

Impersonation of Okta, an identity and access management company.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.auth_summary
  • headers.domains
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  regex.icontains(sender.display_name, '\bOkta\b')
  or strings.ilike(sender.email.domain.domain, '*Okta*')
  or strings.ilike(subject.subject, '*Okta*')
)
and not (length(headers.references) > 0 or headers.in_reply_to is not null)
and not (
  sender.email.domain.root_domain in~ (
    'oktacdn.com',
    'okta.com',
    'okta-emea.com',
    'okta-gov.com',
    'oktapreview.com',
    'polaris.me',
    'examity.com', // exam service used by okta
    'discoursemail.com' // used by okta's dev community
  )
  and headers.auth_summary.dmarc.pass
)
and any(ml.logo_detect(file.message_screenshot()).brands,
        .name == "Okta" and .confidence in ("medium", "high")
)
and (
  profile.by_sender().prevalence != "common"
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)
// negate okta relay
and not any(distinct(headers.domains, .domain is not null),
            .domain == "mailrelay.okta.com"
)
// 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.

Impersonation of Okta, an identity and access management company.

  1. inbound message
  2. any of:
    • sender.display_name matches '\\bOkta\\b'
    • sender.email.domain.domain matches '*Okta*'
    • subject.subject matches '*Okta*'
  3. none of:
    • length(headers.references) > 0
    • headers.in_reply_to is set
  4. not:
    • all of:
      • sender.email.domain.root_domain in ('oktacdn.com', 'okta.com', 'okta-emea.com', 'okta-gov.com', 'oktapreview.com', 'polaris.me', 'examity.com', 'discoursemail.com')
      • headers.auth_summary.dmarc.pass
  5. any of ml.logo_detect(file.message_screenshot()).brands where all hold:
    • .name is 'Okta'
    • .confidence in ('medium', 'high')
  6. any of:
    • profile.by_sender().prevalence is not 'common'
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  7. not:
    • any of distinct(headers.domains) where:
      • .domain is 'mailrelay.okta.com'
  8. not:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • coalesce(headers.auth_summary.dmarc.pass)

Inspects: headers.auth_summary.dmarc.pass, headers.domains, headers.domains[].domain, headers.in_reply_to, headers.references, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: file.message_screenshot, ml.logo_detect, profile.by_sender, regex.icontains, strings.ilike. Reference lists: $high_trust_sender_root_domains.

Indicators matched (5)

FieldMatchValue
regex.icontainsregex\bOkta\b
strings.ilikesubstring*Okta*
ml.logo_detect(file.message_screenshot()).brands[].nameequalsOkta
ml.logo_detect(file.message_screenshot()).brands[].confidencemembermedium
ml.logo_detect(file.message_screenshot()).brands[].confidencememberhigh

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    profile.by_sender func_call "profile.by_sender().prevalence != common"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
  not
    any(distinct(headers.domains))
      distinct(headers.domains).domain eq "mailrelay.okta.com"
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.root_domain in ["discoursemail.com", "examity.com", "okta-emea.com", "okta-gov.com", "okta.com", "oktacdn.com", "oktapreview.com", "polaris.me"]
  not
    or
      headers.in_reply_to is_not_null
      headers.references length_compare "0"
  any(ml.logo_detect(file.message_screenshot()).brands)
    and
      ml.logo_detect(file.message_screenshot()).brands.confidence in ["high", "medium"]
      ml.logo_detect(file.message_screenshot()).brands.name eq "Okta"
  or
    sender.display_name regex_match "\\bOkta\\b"
    sender.email.domain.domain match "Okta"
    subject.subject match "Okta"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
distinct(headers.domains)array_any(no value, null check)excludes:distinct(headers.domains)
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
sender.email.domain.root_domainindiscoursemail.com, examity.com, okta-emea.com, okta-gov.com, okta.com, oktacdn.com, oktapreview.com, polaris.meexcludes:sender.email.domain.root_domain
headers.in_reply_tois_not_null(no value, null check)excludes:headers.in_reply_to
headers.referenceslength_compare0excludes:headers.references field:"headers.references" value:"0"

Indicators

These rows show field, operator, and value matches.

Brand impersonation: OpenAI with payment issues

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

Detects messages impersonating OpenAI or ChatGPT with payment-related content such as subscription cancellation, payment failures, or billing updates from non-OpenAI domains.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  // sender or subject contains openai or chatgpt
  regex.icontains(sender.display_name, '\bchat\s*gpt\b')
  or regex.icontains(sender.display_name, '\bopen\s*a[li]\b')
  or regex.icontains(subject.subject, '\bchat\s*gpt\b')
  or regex.icontains(subject.subject, '\bopen\s*a[li]\b')
  or regex.icontains(body.current_thread.text,
                     '(?:regarding\s*your\s*Open\s*A[lI]\s*account|Open\s*A[lI]\s*\.\s*All\s*rights\s*reserved|the\s*open\s*ai\s*team)'
  )
)
and 2 of (
  // payment phrase
  regex.icontains(strings.replace_confusables(body.current_thread.text),
                  'update (?:payment method|your (?:billing|payment))'
  ),
  regex.icontains(strings.replace_confusables(body.current_thread.text),
                  'Subscription (?:has expired|(?:will be)?Cancel+ed)'
  ),
  regex.icontains(strings.replace_confusables(body.current_thread.text),
                  'issue with (?:the transaction|(?:your\s)?payment)'
  ),
  regex.icontains(strings.replace_confusables(body.current_thread.text),
                  "you(?:'ll| will) lose access"
  ),
  regex.icontains(strings.replace_confusables(body.current_thread.text),
                  'payment (?:is not successful|error|was declined)'
  ),
  regex.icontains(strings.replace_confusables(body.current_thread.text),
                  'unable to (?:process|automatically charge)'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'bank or card issuer'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'issue with the transaction'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'could not be processed'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'settle the outstanding'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'account will be downgraded'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'Renew Subscription'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'balance is settled'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'will renew automatically'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'process your payment'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'keep your subscription active'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'avoid any interruption'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'charge attempt was unsuccessful'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'scheduled for cancellation'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'authorizing your payment'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'Declining Payment'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'Insufficient funds'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'Card has expired'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'exceeds your credit limit'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'plan features have been paused'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'saved payment method'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'active without interruption'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'interruption to your access'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'review your account status'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'access confirmation'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'review allowance'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'access may be suspended'
  ),
  strings.icontains(strings.replace_confusables(body.current_thread.text),
                    'next allowance cycle'
  )
)
// not from openai
and not (
  sender.email.domain.root_domain == 'openai.com'
  and coalesce(headers.auth_summary.dmarc.pass, false)
)
// 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.

Detects messages impersonating OpenAI or ChatGPT with payment-related content such as subscription cancellation, payment failures, or billing updates from non-OpenAI domains.

  1. inbound message
  2. any of:
    • sender.display_name matches '\\bchat\\s*gpt\\b'
    • sender.display_name matches '\\bopen\\s*a[li]\\b'
    • subject.subject matches '\\bchat\\s*gpt\\b'
    • subject.subject matches '\\bopen\\s*a[li]\\b'
    • body.current_thread.text matches '(?:regarding\\s*your\\s*Open\\s*A[lI]\\s*account|Open\\s*A[lI]\\s*\\.\\s*All\\s*rights\\s*reserved|the\\s*open\\s*ai\\s*team)'
  3. at least 2 of:
    • strings.replace_confusables(body.current_thread.text) matches 'update (?:payment method|your (?:billing|payment))'
    • strings.replace_confusables(body.current_thread.text) matches 'Subscription (?:has expired|(?:will be)?Cancel+ed)'
    • strings.replace_confusables(body.current_thread.text) matches 'issue with (?:the transaction|(?:your\\s)?payment)'
    • strings.replace_confusables(body.current_thread.text) matches "you(?:'ll| will) lose access"
    • strings.replace_confusables(body.current_thread.text) matches 'payment (?:is not successful|error|was declined)'
    • strings.replace_confusables(body.current_thread.text) matches 'unable to (?:process|automatically charge)'
    • strings.replace_confusables(body.current_thread.text) contains 'bank or card issuer'
    • strings.replace_confusables(body.current_thread.text) contains 'issue with the transaction'
    • strings.replace_confusables(body.current_thread.text) contains 'could not be processed'
    • strings.replace_confusables(body.current_thread.text) contains 'settle the outstanding'
    • strings.replace_confusables(body.current_thread.text) contains 'account will be downgraded'
    • strings.replace_confusables(body.current_thread.text) contains 'Renew Subscription'
    • strings.replace_confusables(body.current_thread.text) contains 'balance is settled'
    • strings.replace_confusables(body.current_thread.text) contains 'will renew automatically'
    • strings.replace_confusables(body.current_thread.text) contains 'process your payment'
    • strings.replace_confusables(body.current_thread.text) contains 'keep your subscription active'
    • strings.replace_confusables(body.current_thread.text) contains 'avoid any interruption'
    • strings.replace_confusables(body.current_thread.text) contains 'charge attempt was unsuccessful'
    • strings.replace_confusables(body.current_thread.text) contains 'scheduled for cancellation'
    • strings.replace_confusables(body.current_thread.text) contains 'authorizing your payment'
    • strings.replace_confusables(body.current_thread.text) contains 'Declining Payment'
    • strings.replace_confusables(body.current_thread.text) contains 'Insufficient funds'
    • strings.replace_confusables(body.current_thread.text) contains 'Card has expired'
    • strings.replace_confusables(body.current_thread.text) contains 'exceeds your credit limit'
    • strings.replace_confusables(body.current_thread.text) contains 'plan features have been paused'
    • strings.replace_confusables(body.current_thread.text) contains 'saved payment method'
    • strings.replace_confusables(body.current_thread.text) contains 'active without interruption'
    • strings.replace_confusables(body.current_thread.text) contains 'interruption to your access'
    • strings.replace_confusables(body.current_thread.text) contains 'review your account status'
    • strings.replace_confusables(body.current_thread.text) contains 'access confirmation'
    • strings.replace_confusables(body.current_thread.text) contains 'review allowance'
    • strings.replace_confusables(body.current_thread.text) contains 'access may be suspended'
    • strings.replace_confusables(body.current_thread.text) contains 'next allowance cycle'
  4. not:
    • all of:
      • sender.email.domain.root_domain is 'openai.com'
      • coalesce(headers.auth_summary.dmarc.pass)
  5. 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, sender.display_name, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: regex.icontains, strings.icontains, strings.replace_confusables. Reference lists: $high_trust_sender_root_domains.

Indicators matched (36)

FieldMatchValue
regex.icontainsregex\bchat\s*gpt\b
regex.icontainsregex\bopen\s*a[li]\b
regex.icontainsregex(?:regarding\s*your\s*Open\s*A[lI]\s*account|Open\s*A[lI]\s*\.\s*All\s*rights\s*reserved|the\s*open\s*ai\s*team)
regex.icontainsregexupdate (?:payment method|your (?:billing|payment))
regex.icontainsregexSubscription (?:has expired|(?:will be)?Cancel+ed)
regex.icontainsregexissue with (?:the transaction|(?:your\s)?payment)
regex.icontainsregexyou(?:'ll| will) lose access
regex.icontainsregexpayment (?:is not successful|error|was declined)
regex.icontainsregexunable to (?:process|automatically charge)
strings.icontainssubstringbank or card issuer
strings.icontainssubstringissue with the transaction
strings.icontainssubstringcould not be processed
24 more
strings.icontainssubstringsettle the outstanding
strings.icontainssubstringaccount will be downgraded
strings.icontainssubstringRenew Subscription
strings.icontainssubstringbalance is settled
strings.icontainssubstringwill renew automatically
strings.icontainssubstringprocess your payment
strings.icontainssubstringkeep your subscription active
strings.icontainssubstringavoid any interruption
strings.icontainssubstringcharge attempt was unsuccessful
strings.icontainssubstringscheduled for cancellation
strings.icontainssubstringauthorizing your payment
strings.icontainssubstringDeclining Payment
strings.icontainssubstringInsufficient funds
strings.icontainssubstringCard has expired
strings.icontainssubstringexceeds your credit limit
strings.icontainssubstringplan features have been paused
strings.icontainssubstringsaved payment method
strings.icontainssubstringactive without interruption
strings.icontainssubstringinterruption to your access
strings.icontainssubstringreview your account status
strings.icontainssubstringaccess confirmation
strings.icontainssubstringreview allowance
strings.icontainssubstringaccess may be suspended
strings.icontainssubstringnext allowance cycle

Stages and Predicates

Stage 1: mql_rule

and
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
      sender.email.domain.root_domain eq "openai.com"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
  or
    body.current_thread.text regex_match "(?:regarding\\s*your\\s*Open\\s*A[lI]\\s*account|Open\\s*A[lI]\\s*\\.\\s*All\\s*rights\\s*reserved|the\\s*open\\s*ai\\s*team)"
    sender.display_name regex_match "\\bchat\\s*gpt\\b"
    sender.display_name regex_match "\\bopen\\s*a[li]\\b"
    subject.subject regex_match "\\bchat\\s*gpt\\b"
    subject.subject regex_match "\\bopen\\s*a[li]\\b"
  or
    strings.replace_confusables(body.current_thread.text) contains "Card has expired"
    strings.replace_confusables(body.current_thread.text) contains "Declining Payment"
    strings.replace_confusables(body.current_thread.text) contains "Insufficient funds"
    strings.replace_confusables(body.current_thread.text) contains "Renew Subscription"
    strings.replace_confusables(body.current_thread.text) contains "access confirmation"
    strings.replace_confusables(body.current_thread.text) contains "access may be suspended"
    strings.replace_confusables(body.current_thread.text) contains "account will be downgraded"
    strings.replace_confusables(body.current_thread.text) contains "active without interruption"
    strings.replace_confusables(body.current_thread.text) contains "authorizing your payment"
    strings.replace_confusables(body.current_thread.text) contains "avoid any interruption"
    strings.replace_confusables(body.current_thread.text) contains "balance is settled"
    strings.replace_confusables(body.current_thread.text) contains "bank or card issuer"
    strings.replace_confusables(body.current_thread.text) contains "charge attempt was unsuccessful"
    strings.replace_confusables(body.current_thread.text) contains "could not be processed"
    strings.replace_confusables(body.current_thread.text) contains "exceeds your credit limit"
    strings.replace_confusables(body.current_thread.text) contains "interruption to your access"
    strings.replace_confusables(body.current_thread.text) contains "issue with the transaction"
    strings.replace_confusables(body.current_thread.text) contains "keep your subscription active"
    strings.replace_confusables(body.current_thread.text) contains "next allowance cycle"
    strings.replace_confusables(body.current_thread.text) contains "plan features have been paused"
    strings.replace_confusables(body.current_thread.text) contains "process your payment"
    strings.replace_confusables(body.current_thread.text) contains "review allowance"
    strings.replace_confusables(body.current_thread.text) contains "review your account status"
    strings.replace_confusables(body.current_thread.text) contains "saved payment method"
    strings.replace_confusables(body.current_thread.text) contains "scheduled for cancellation"
    strings.replace_confusables(body.current_thread.text) contains "settle the outstanding"
    strings.replace_confusables(body.current_thread.text) contains "will renew automatically"
    strings.replace_confusables(body.current_thread.text) regex_match "Subscription (?:has expired|(?:will be)?Cancel+ed)"
    strings.replace_confusables(body.current_thread.text) regex_match "issue with (?:the transaction|(?:your\\s)?payment)"
    strings.replace_confusables(body.current_thread.text) regex_match "payment (?:is not successful|error|was declined)"
    strings.replace_confusables(body.current_thread.text) regex_match "unable to (?:process|automatically charge)"
    strings.replace_confusables(body.current_thread.text) regex_match "update (?:payment method|your (?:billing|payment))"
    strings.replace_confusables(body.current_thread.text) regex_match "you(?:'ll| will) lose access"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaineqopenai.comexcludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"openai.com"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textregex_match
  • (?:regarding\s*your\s*Open\s*A[lI]\s*account|Open\s*A[lI]\s*.\s*All\s*rights\s*reserved|the\s*open\s*ai\s*team)
field:"body.current_thread.text" kind:regex_match value:"(?:regarding\s*your\s*Open\s*A[lI]\s*account|Open\s*A[lI]\s*.\s*All\s*rights\s*reserved|the\s*open\s*ai\s*team)"
sender.display_nameregex_match
  • \bchat\s*gpt\b
  • \bopen\s*a[li]\b
field:"sender.display_name" kind:regex_match
strings.replace_confusables(body.current_thread.text)contains
  • Card has expired
  • Declining Payment
  • Insufficient funds
  • Renew Subscription
  • access confirmation
  • access may be suspended
  • account will be downgraded
  • active without interruption
  • authorizing your payment
  • avoid any interruption
  • balance is settled
  • bank or card issuer
  • charge attempt was unsuccessful
  • could not be processed
  • exceeds your credit limit
  • interruption to your access
  • issue with the transaction
  • keep your subscription active
  • next allowance cycle
  • plan features have been paused
  • process your payment
  • review allowance
  • review your account status
  • saved payment method
  • scheduled for cancellation
  • settle the outstanding
  • will renew automatically
field:"strings.replace_confusables(body.current_thread.text)" kind:contains
strings.replace_confusables(body.current_thread.text)regex_match
  • Subscription (?:has expired|(?:will be)?Cancel+ed)
  • issue with (?:the transaction|(?:your\s)?payment)
  • payment (?:is not successful|error|was declined)
  • unable to (?:process|automatically charge)
  • update (?:payment method|your (?:billing|payment))
  • you(?:'ll| will) lose access
field:"strings.replace_confusables(body.current_thread.text)" kind:regex_match
subject.subjectregex_match
  • \bchat\s*gpt\b
  • \bopen\s*a[li]\b
field:"subject.subject" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Outlook

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

Impersonation of Outlook.com. Senders with "outlook.com" in the subdomain have been observed sending fake account notifications.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • sender.email
  • type

Rule body

type.inbound
and regex.icontains(sender.email.domain.domain, '.*outlook.com.+')
// Negate legitimate outlook root domains
and sender.email.domain.root_domain not in (
  'outlook.com.au',
  'outlook.com.br',
  'outlook.com.ar',
  'outlook.at',
  'outlook.be',
  'outlook.cl',
  'outlook.cz',
  'outlook.dk',
  'outlook.fr',
  'outlook.de',
  'outlook.com.gr',
  'outlook.co.il',
  'outlook.in',
  'outlook.co.id',
  'outlook.ie',
  'outlook.it',
  'outlook.hu',
  'outlook.jp',
  'outlook.kr',
  'outlook.lv',
  'outlook.my',
  'outlook.co.nz',
  'outlook.com.pe',
  'outlook.ph',
  'outlook.pt',
  'outlook.sa',
  'outlook.sg',
  'outlook.sk',
  'outlook.es',
  'outlook.co.th',
  'outlook.com.tr',
  'outlook.com.vn'
)
and sender.email.email not in $recipient_emails

Detection logic

Scope: inbound message.

Impersonation of Outlook.com. Senders with "outlook.com" in the subdomain have been observed sending fake account notifications.

  1. inbound message
  2. sender.email.domain.domain matches '.*outlook.com.+'
  3. sender.email.domain.root_domain not in ('outlook.com.au', 'outlook.com.br', 'outlook.com.ar', 'outlook.at', 'outlook.be', 'outlook.cl', 'outlook.cz', 'outlook.dk', 'outlook.fr', 'outlook.de', 'outlook.com.gr', 'outlook.co.il', 'outlook.in', 'outlook.co.id', 'outlook.ie', 'outlook.it', 'outlook.hu', 'outlook.jp', 'outlook.kr', 'outlook.lv', 'outlook.my', 'outlook.co.nz', 'outlook.com.pe', 'outlook.ph', 'outlook.pt', 'outlook.sa', 'outlook.sg', 'outlook.sk', 'outlook.es', 'outlook.co.th', 'outlook.com.tr', 'outlook.com.vn')
  4. sender.email.email not in $recipient_emails

Inspects: sender.email.domain.domain, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: regex.icontains. Reference lists: $recipient_emails.

Indicators matched (1)

FieldMatchValue
regex.icontainsregex.*outlook.com.+

Stages and Predicates

Stage 1: mql_rule

and
  not
    sender.email.domain.root_domain in ["outlook.at", "outlook.be", "outlook.cl", "outlook.co.id", "outlook.co.il", "outlook.co.nz", "outlook.co.th", "outlook.com.ar", "outlook.com.au", "outlook.com.br", "outlook.com.gr", "outlook.com.pe", "outlook.com.tr", "outlook.com.vn", "outlook.cz", "outlook.de", "outlook.dk", "outlook.es", "outlook.fr", "outlook.hu", "outlook.ie", "outlook.in", "outlook.it", "outlook.jp", "outlook.kr", "outlook.lv", "outlook.my", "outlook.ph", "outlook.pt", "outlook.sa", "outlook.sg", "outlook.sk"]
  sender.email.domain.domain regex_match ".*outlook.com.+"
  type.inbound eq "true"
   macro "sender.email.email not in recipient_emails"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaininoutlook.at, outlook.be, outlook.cl, outlook.co.id, outlook.co.il, outlook.co.nz, outlook.co.th, outlook.com.ar, outlook.com.au, outlook.com.br, outlook.com.gr, outlook.com.pe, outlook.com.tr, outlook.com.vn, outlook.cz, outlook.de, outlook.dk, outlook.es, outlook.fr, outlook.hu, outlook.ie, outlook.in, outlook.it, outlook.jp, outlook.kr, outlook.lv, outlook.my, outlook.ph, outlook.pt, outlook.sa, outlook.sg, outlook.skexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand Impersonation: PayPal

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

Impersonation of PayPal.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  strings.replace_confusables(sender.display_name) =~ "paypal"
  or strings.ilevenshtein(strings.replace_confusables(sender.display_name),
                          'paypal'
  ) <= 1
  or strings.ilike(strings.replace_confusables(sender.display_name), '*paypal*')
  or strings.icontains(body.current_thread.text, "paypal billing team")
  or strings.icontains(body.current_thread.text, "paypal account services")
  or regex.icontains(body.current_thread.text, 'secure[-\._]?pay[-\._]?pal')
  or regex.icontains(body.current_thread.text,
                     '(?:pay[-\._\s]*pa[i1]\b|paypa[|!]|p@y\.?p@l)'
  )
  or (
    strings.istarts_with(body.current_thread.text, 'paypal')
    and length(body.previous_threads) == 0
    and any(ml.nlu_classifier(body.current_thread.text).intents,
            .name == "callback_scam"
    )
  )
  or any(attachments,
         (.file_type in $file_types_images or .file_type == "pdf")
         and any(ml.logo_detect(.).brands, .name == "PayPal")
         and any(file.explode(.),
                 // exclude images taken with mobile cameras and screenshots from android
                 not any(.scan.exiftool.fields,
                         .key == "Model"
                         or (
                           .key == "Software"
                           and strings.starts_with(.value, "Android")
                         )
                 )
                 // exclude images taken with mobile cameras and screenshots from Apple
                 and not any(.scan.exiftool.fields,
                             .key == "DeviceManufacturer"
                             and .value == "Apple Computer Inc."
                 )
                 and strings.ilike(.scan.ocr.raw, "*PayPal*")
                 and strings.ilike(.scan.ocr.raw,
                                   "*invoice*",
                                   "*transaction*",
                                   "*bitcoin*",
                                   "*dear customer*",
                                   "*suspicious activity*",
                                   "*contact support*",
                                   "*helpdesk*"
                 )
         )
  )
  or (
    any(ml.logo_detect(file.message_screenshot()).brands, .name == "PayPal")
    and strings.ilike(body.current_thread.text, "*PayPal*")
    and strings.ilike(body.current_thread.text,
                      "*invoice*",
                      "*transaction*",
                      "*bitcoin*",
                      "*dear customer*",
                      "*suspicious activity*",
                      "*contact support*",
                      "*helpdesk*"
    )
  )
)
and not any(ml.nlu_classifier(body.current_thread.text).topics,
            .name in~ (
              "Professional and Career Development",
              "Government Services"
            )
)
and sender.email.domain.root_domain not in (
  'google.com',
  'paypal-brandsfeedback.com',
  'paypal-creditsurvey.com',
  'paypal-customerfeedback.com',
  'paypal-experience.com',
  'paypal-prepaid.com',
  'paypal.at',
  'paypal.be',
  'paypal.ca',
  'paypal.ch',
  'paypal.co.il',
  'paypal.co.uk',
  'paypal.com',
  'paypal.com.au',
  'paypal.com.mx',
  'paypal.com.sg',
  'paypal.de',
  'paypal.dk',
  'paypal.es',
  'paypal.fr',
  'paypal.hk',
  'paypal.it',
  'paypal.nl',
  'paypal.pl',
  'paypal.se',
  'paypalcorp.com',
  'q4inc.com',
  'synchrony.com',
  'synchronybank.com',
  'synchronyfinancial.com',
  'xoom.com',
  'zettle.com'
)
// negate paypal.co.br explicitly, this cannot be part of the root_domain set above as it uses the PSL (Public suffix list) for parsing and co.br is not a recognized public suffix.
and sender.email.domain.domain not in~ ('paypal.co.br')

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

Impersonation of PayPal.

  1. inbound message
  2. any of:
    • strings.replace_confusables(sender.display_name) is 'paypal'
    • strings.replace_confusables(sender.display_name) is similar to 'paypal'
    • strings.replace_confusables(sender.display_name) matches '*paypal*'
    • body.current_thread.text contains 'paypal billing team'
    • body.current_thread.text contains 'paypal account services'
    • body.current_thread.text matches 'secure[-\\._]?pay[-\\._]?pal'
    • body.current_thread.text matches '(?:pay[-\\._\\s]*pa[i1]\\b|paypa[|!]|p@y\\.?p@l)'
    • all of:
      • body.current_thread.text starts with 'paypal'
      • length(body.previous_threads) is 0
      • any of ml.nlu_classifier(body.current_thread.text).intents where:
        • .name is 'callback_scam'
    • any of attachments where all hold:
      • any of:
        • .file_type in $file_types_images
        • .file_type is 'pdf'
      • any of ml.logo_detect(.).brands where:
        • .name is 'PayPal'
      • any of file.explode(.) where all hold:
        • not:
          • any of .scan.exiftool.fields where any holds:
            • .key is 'Model'
            • all of:
              • .key is 'Software'
              • .value starts with 'Android'
        • not:
          • any of .scan.exiftool.fields where all hold:
            • .key is 'DeviceManufacturer'
            • .value is 'Apple Computer Inc.'
        • .scan.ocr.raw matches '*PayPal*'
        • .scan.ocr.raw matches any of 7 patterns
          • *invoice*
          • *transaction*
          • *bitcoin*
          • *dear customer*
          • *suspicious activity*
          • *contact support*
          • *helpdesk*
    • all of:
      • any of ml.logo_detect(file.message_screenshot()).brands where:
        • .name is 'PayPal'
      • body.current_thread.text matches '*PayPal*'
      • body.current_thread.text matches any of 7 patterns
        • *invoice*
        • *transaction*
        • *bitcoin*
        • *dear customer*
        • *suspicious activity*
        • *contact support*
        • *helpdesk*
  3. not:
    • any of ml.nlu_classifier(body.current_thread.text).topics where:
      • .name in ('Professional and Career Development', 'Government Services')
  4. sender.email.domain.root_domain not in ('google.com', 'paypal-brandsfeedback.com', 'paypal-creditsurvey.com', 'paypal-customerfeedback.com', 'paypal-experience.com', 'paypal-prepaid.com', 'paypal.at', 'paypal.be', 'paypal.ca', 'paypal.ch', 'paypal.co.il', 'paypal.co.uk', 'paypal.com', 'paypal.com.au', 'paypal.com.mx', 'paypal.com.sg', 'paypal.de', 'paypal.dk', 'paypal.es', 'paypal.fr', 'paypal.hk', 'paypal.it', 'paypal.nl', 'paypal.pl', 'paypal.se', 'paypalcorp.com', 'q4inc.com', 'synchrony.com', 'synchronybank.com', 'synchronyfinancial.com', 'xoom.com', 'zettle.com')
  5. sender.email.domain.domain not in ('paypal.co.br')
  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: attachments[].file_type, body.current_thread.text, body.previous_threads, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, file.message_screenshot, ml.logo_detect, ml.nlu_classifier, regex.icontains, strings.icontains, strings.ilevenshtein, strings.ilike, strings.istarts_with, strings.replace_confusables, strings.starts_with. Reference lists: $file_types_images, $high_trust_sender_root_domains.

Indicators matched (19)

FieldMatchValue
strings.ilevenshteinfuzzypaypal
strings.ilikesubstring*paypal*
strings.icontainssubstringpaypal billing team
strings.icontainssubstringpaypal account services
regex.icontainsregexsecure[-\._]?pay[-\._]?pal
regex.icontainsregex(?:pay[-\._\s]*pa[i1]\b|paypa[|!]|p@y\.?p@l)
strings.istarts_withprefixpaypal
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscallback_scam
attachments[].file_typeequalspdf
ml.logo_detect(attachments[]).brands[].nameequalsPayPal
strings.ilikesubstring*PayPal*
strings.ilikesubstring*invoice*
7 more
strings.ilikesubstring*transaction*
strings.ilikesubstring*bitcoin*
strings.ilikesubstring*dear customer*
strings.ilikesubstring*suspicious activity*
strings.ilikesubstring*contact support*
strings.ilikesubstring*helpdesk*
ml.logo_detect(file.message_screenshot()).brands[].nameequalsPayPal

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(attachments)
      and
        any(file.explode(attachments))
          and
            not
              any(file.explode(attachments).scan.exiftool.fields)
                or
                  and
                    file.explode(attachments[])[].scan.exiftool.fields[].key eq "Software"
                    file.explode(attachments[])[].scan.exiftool.fields[].value starts_with "Android"
                  file.explode(attachments[])[].scan.exiftool.fields[].key eq "Model"
            not
              any(file.explode(attachments).scan.exiftool.fields)
                and
                  file.explode(attachments[])[].scan.exiftool.fields[].key eq "DeviceManufacturer"
                  file.explode(attachments[])[].scan.exiftool.fields[].value eq "Apple Computer Inc."
            or
              file.explode(attachments[])[].scan.ocr.raw match "bitcoin"
              file.explode(attachments[])[].scan.ocr.raw match "contact support"
              file.explode(attachments[])[].scan.ocr.raw match "dear customer"
              file.explode(attachments[])[].scan.ocr.raw match "helpdesk"
              file.explode(attachments[])[].scan.ocr.raw match "invoice"
              file.explode(attachments[])[].scan.ocr.raw match "suspicious activity"
              file.explode(attachments[])[].scan.ocr.raw match "transaction"
            file.explode(attachments[])[].scan.ocr.raw match "PayPal"
        or
          attachments.file_type eq "pdf"
           macro "attachments[].file_type in file_types_images"
        any(ml.logo_detect(attachments).brands)
          ml.logo_detect(attachments).brands.name eq "PayPal"
    and
      or
        body.current_thread.text match "bitcoin"
        body.current_thread.text match "contact support"
        body.current_thread.text match "dear customer"
        body.current_thread.text match "helpdesk"
        body.current_thread.text match "invoice"
        body.current_thread.text match "suspicious activity"
        body.current_thread.text match "transaction"
      any(ml.logo_detect(file.message_screenshot()).brands)
        ml.logo_detect(file.message_screenshot()).brands.name eq "PayPal"
      body.current_thread.text match "PayPal"
    and
      any(ml.nlu_classifier(body.current_thread.text).intents)
        ml.nlu_classifier(body.current_thread.text).intents.name eq "callback_scam"
      body.current_thread.text starts_with "paypal"
      body.previous_threads length_compare "0"
    body.current_thread.text contains "paypal account services"
    body.current_thread.text contains "paypal billing team"
    body.current_thread.text regex_match "(?:pay[-\\._\\s]*pa[i1]\\b|paypa[|!]|p@y\\.?p@l)"
    body.current_thread.text regex_match "secure[-\\._]?pay[-\\._]?pal"
    strings.ilevenshtein func_call "strings.ilevenshtein(strings.replace_confusables(sender.display_name), \"paypal\") <= 1"
    strings.replace_confusables func_call "strings.replace_confusables(sender.display_name) =~ paypal"
    strings.replace_confusables(sender.display_name) match "paypal"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    any(ml.nlu_classifier(body.current_thread.text).topics)
      ml.nlu_classifier(body.current_thread.text).topics.name in ["Government Services", "Professional and Career Development"]
  not
    sender.email.domain.domain eq "paypal.co.br"
  not
    sender.email.domain.root_domain in ["google.com", "paypal-brandsfeedback.com", "paypal-creditsurvey.com", "paypal-customerfeedback.com", "paypal-experience.com", "paypal-prepaid.com", "paypal.at", "paypal.be", "paypal.ca", "paypal.ch", "paypal.co.il", "paypal.co.uk", "paypal.com", "paypal.com.au", "paypal.com.mx", "paypal.com.sg", "paypal.de", "paypal.dk", "paypal.es", "paypal.fr", "paypal.hk", "paypal.it", "paypal.nl", "paypal.pl", "paypal.se", "paypalcorp.com", "q4inc.com", "synchrony.com", "synchronybank.com", "synchronyfinancial.com", "xoom.com", "zettle.com"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
ml.nlu_classifier(body.current_thread.text).topicsarray_any(no value, null check)excludes:ml.nlu_classifier(body.current_thread.text).topics
sender.email.domain.domaineqpaypal.co.brexcludes:sender.email.domain.domain field:"sender.email.domain.domain" value:"paypal.co.br"
sender.email.domain.root_domainingoogle.com, paypal-brandsfeedback.com, paypal-creditsurvey.com, paypal-customerfeedback.com, paypal-experience.com, paypal-prepaid.com, paypal.at, paypal.be, paypal.ca, paypal.ch, paypal.co.il, paypal.co.uk, paypal.com, paypal.com.au, paypal.com.mx, paypal.com.sg, paypal.de, paypal.dk, paypal.es, paypal.fr, paypal.hk, paypal.it, paypal.nl, paypal.pl, paypal.se, paypalcorp.com, q4inc.com, synchrony.com, synchronybank.com, synchronyfinancial.com, xoom.com, zettle.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: PNC

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

Impersonation of PNC Financial Services

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • headers
  • headers.auth_summary
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  regex.icontains(sender.display_name, '\PNC\b')
  or strings.ilike(sender.email.domain.domain, '*PNC*')
  or strings.ilike(subject.subject, '*PNC*')
)
and sender.email.domain.root_domain not in~ ('pnc.com', 'pncbank.com')
and sender.email.domain.tld != "pnc"
and any(ml.logo_detect(file.message_screenshot()).brands,
        .name == "PNC" and .confidence in ("medium", "high")
)
and (
  profile.by_sender().prevalence in ("new", "outlier")
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)
// not forwards/replies
and not (
  (length(headers.references) > 0 or headers.in_reply_to is not null)
  and (subject.is_forward or subject.is_reply)
  and length(body.previous_threads) >= 1
)
// 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.

Impersonation of PNC Financial Services

  1. inbound message
  2. any of:
    • sender.display_name matches '\\PNC\\b'
    • sender.email.domain.domain matches '*PNC*'
    • subject.subject matches '*PNC*'
  3. sender.email.domain.root_domain not in ('pnc.com', 'pncbank.com')
  4. sender.email.domain.tld is not 'pnc'
  5. any of ml.logo_detect(file.message_screenshot()).brands where all hold:
    • .name is 'PNC'
    • .confidence in ('medium', 'high')
  6. any of:
    • profile.by_sender().prevalence in ('new', 'outlier')
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  7. not:
    • all of:
      • any of:
        • length(headers.references) > 0
        • headers.in_reply_to is set
      • any of:
        • subject.is_forward
        • subject.is_reply
      • length(body.previous_threads) ≥ 1
  8. 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.previous_threads, headers.auth_summary.dmarc.pass, headers.in_reply_to, headers.references, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.domain.tld, subject.is_forward, subject.is_reply, subject.subject, type.inbound. Sensors: file.message_screenshot, ml.logo_detect, profile.by_sender, regex.icontains, strings.ilike. Reference lists: $high_trust_sender_root_domains.

Indicators matched (5)

FieldMatchValue
regex.icontainsregex\PNC\b
strings.ilikesubstring*PNC*
ml.logo_detect(file.message_screenshot()).brands[].nameequalsPNC
ml.logo_detect(file.message_screenshot()).brands[].confidencemembermedium
ml.logo_detect(file.message_screenshot()).brands[].confidencememberhigh

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    and
      or
        headers.in_reply_to is_not_null
        headers.references length_compare "0"
      or
        subject.is_forward eq "true"
        subject.is_reply eq "true"
      body.previous_threads length_compare "1"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    profile.by_sender func_call "profile.by_sender().prevalence in (new, outlier)"
  any(ml.logo_detect(file.message_screenshot()).brands)
    and
      ml.logo_detect(file.message_screenshot()).brands.confidence in ["high", "medium"]
      ml.logo_detect(file.message_screenshot()).brands.name eq "PNC"
  or
    sender.display_name regex_match "\\PNC\\b"
    sender.email.domain.domain match "PNC"
    subject.subject match "PNC"
  not
    sender.email.domain.root_domain in ["pnc.com", "pncbank.com"]
  sender.email.domain.tld ne "pnc"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Purdue ePlanroom with suspicious links

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

Detects messages impersonating Purdue ePlanroom with links that either not from the legitimate reprographix.com domain or contain suspicious credential theft indicators.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, BEC/Fraud
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.links
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and strings.icontains(body.current_thread.text, "Purdue ePlanroom")
and (
  any(filter(body.links, strings.contains(.display_text, "Review This Project")),
      .href_url.domain.root_domain != "reprographix.com"
  )
  or any(body.links, ml.link_analysis(.).credphish.disposition == "phishing")
)
and not (
  sender.email.domain.root_domain == "reprographix.com"
  and headers.auth_summary.dmarc.pass
)

Detection logic

Scope: inbound message.

Detects messages impersonating Purdue ePlanroom with links that either not from the legitimate reprographix.com domain or contain suspicious credential theft indicators.

  1. inbound message
  2. body.current_thread.text contains 'Purdue ePlanroom'
  3. any of:
    • any of filter(body.links) where:
      • .href_url.domain.root_domain is not 'reprographix.com'
    • any of body.links where:
      • ml.link_analysis(.).credphish.disposition is 'phishing'
  4. not:
    • all of:
      • sender.email.domain.root_domain is 'reprographix.com'
      • headers.auth_summary.dmarc.pass

Inspects: body.current_thread.text, body.links, body.links[].display_text, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: ml.link_analysis, strings.contains, strings.icontains.

Indicators matched (2)

FieldMatchValue
strings.icontainssubstringPurdue ePlanroom
strings.containssubstringReview This Project

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(filter(body.links))
      filter(body.links).href_url.domain.root_domain ne "reprographix.com"
    any(body.links)
      ml.link_analysis func_call "ml.link_analysis(body.links[]).credphish.disposition == phishing"
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.root_domain eq "reprographix.com"
  body.current_thread.text contains "Purdue ePlanroom"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Quickbooks

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

Impersonation of the Quickbooks service from Intuit.

Threat classification

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

CategoryValues
Attack typesCallback Phishing, Credential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.links
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  (
    strings.ilike(sender.display_name,
                  'quickboo*',
                  'QuickB*',
                  'QBook*',
                  'intuit*'
    )
    or strings.like(sender.display_name, "QB-*", "QB *")
    or strings.ilevenshtein(sender.display_name, 'quickbooks') <= 1
    or strings.ilike(sender.email.domain.domain, '*quickbook*')
    or (
      length(filter(ml.nlu_classifier(body.current_thread.text).entities,
                    strings.icontains(.text, "quickbooks")
             )
      ) >= 2
      and any(ml.nlu_classifier(body.current_thread.text).intents,
              .name in ("cred_theft", "callback_scam")
      )
    )
  )
  or strings.ilike(body.current_thread.text, "*invoice*")
)
and (
  any(ml.logo_detect(file.message_screenshot()).brands,
      .name == "Quickbooks" and .confidence in ("medium", "high")
  )
  // contains the address and copyright
  or (
    strings.icontains(body.current_thread.text,
                      '2800 E. Commerce Center Place, Tucson, AZ 85706',
                      '2700 Coast Ave, Mountain View, CA 94043'
    )
    and regex.icontains(body.current_thread.text, '©\s*(?:\d+)\s*Intuit')
  )
  or strings.icontains(body.current_thread.text,
                       'Powered by QuickBooks',
                       'QuickBooks and Intuit are trademarks of Intuit Inc.',
                       "QuickBooks Cloud Services",
                       "QuickBooks Support Center",
                       "QuickBooks subscription"
  )
  or regex.icontains(body.current_thread.text,
                     '(?:Secured by )?QuickBooks Payments'
  )

  // phone number and update language
  or (
    regex.icontains(body.current_thread.text,
                    '\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}',
                    '\+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}'
    )
    and any(ml.nlu_classifier(body.current_thread.text).topics,
            .name in ("Software and App Updates", "Security and Authentication")
    )

    // we need to re-check for QB indicators, otherwise we can have "*invoice*"
    // and this block, which is much more than just QB impersonation
    and (
      strings.ilike(sender.display_name,
                    'quickbook*',
                    'QuickB*',
                    'QBook*',
                    'intuit*'
      )
      or strings.like(sender.display_name, "QB-*", "QB *")
      or strings.ilevenshtein(sender.display_name, 'quickbooks') <= 1
      or strings.ilike(sender.email.domain.domain, '*quickbook*')
      or (
        length(filter(ml.nlu_classifier(body.current_thread.text).entities,
                      strings.icontains(.text, "quickbooks")
               )
        ) > 2
        and any(ml.nlu_classifier(body.current_thread.text).intents,
                .name == "cred_theft"
        )
      )
    )
  )
  or any(body.links,
         (
           regex.icontains(.display_url.url, '(?:quickbooks|intuit)')
           and .mismatched
           and not .href_url.domain.root_domain in (
             "mimecast.com",
             "mimecastprotect.com"
           )
         )
         or (
           regex.icontains(.href_url.path, '(?:quickbooks|intuit)')
           and not strings.icontains(.href_url.domain.root_domain,
                                     "quickbooks",
                                     "intuit"
           )
           and not any(ml.nlu_classifier(body.current_thread.text).topics,
                       .name == "Advertising and Promotions"
           )
         )
  )
  or (
    any(ml.nlu_classifier(body.current_thread.text).entities,
        .name == "sender" and regex.icontains(.text, 'quickbooks?')
    )
    and any(ml.nlu_classifier(body.current_thread.text).intents,
            .name == "cred_theft" and .confidence == "high"
    )
  )
)
and not (
  sender.email.domain.root_domain in~ (
    'intuit.com',
    'turbotax.com',
    'intuit.ca',
    'meliopayments.com',
    'qemailserver.com',
    'intuit.co.uk',
    'quickbooksonline.com',
    'tsheets.com'
  )
  and coalesce(headers.auth_summary.dmarc.pass, false)
)
and (
  not profile.by_sender().any_messages_benign
  and not profile.by_sender().solicited
)
// links in body are not known QB domains or the senders root website (both indicative of a legitimate QuickBooks invoice message)
and (
  length(filter(body.links,
                .href_url.domain.root_domain in~ (
                  'intuit.com',
                  'turbotax.com',
                  'intuit.ca',
                  'meliopayments.com',
                  'qemailserver.com',
                  'intuit.co.uk',
                  'quickbooksonline.com'
                )
                or (
                  .href_url.domain.root_domain == sender.email.domain.root_domain
                  and (.href_url.path is null or .href_url.path == "/")
                )
                // handle links to the root website when the sender uses a freemail address to send invoices
                or (
                  .href_url.domain.sld == sender.email.local_part
                  and (.href_url.path is null or .href_url.path == "/")
                  and sender.email.domain.root_domain in $free_email_providers
                )
         )
  ) != length(body.links)
  // or no valid links
  or length(filter(body.links, .href_url.domain.domain is not null)) == 0
)
// the call to action link does not lead to inuit
and not (
  // filter down to observed call to action display text
  any(filter(body.links,
             .display_text in~ (
               "view and pay",
               "review and pay",
               "view details"
             )
      ),
      // benign/legit href_url details for those links
      (
        // sendgrid rewritten links
        .href_url.domain.domain == "links.notification.intuit.com"
        // CTA link
        or (
          .href_url.domain.domain == "connect.intuit.com"
          and strings.icontains(.href_url.query_params, 'cta=viewinvoicenow')
        )
        // Mimecast links
        or (
          .href_url.domain.root_domain == "mimecastprotect.com"
          and (
            strings.icontains(.href_url.query_params,
                              'domain=links.notification.intuit.com'
            )
            or strings.icontains(.href_url.query_params,
                                 'domain=connect.intuit.com'
            )
          )
        )
      )
  )
)
// negate common sender of quickbooks reseller
and not strings.icontains(body.current_thread.text, 'Purchasing Reviews, Inc')
// 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.

Impersonation of the Quickbooks service from Intuit.

  1. inbound message
  2. any of:
    • any of:
      • sender.display_name matches any of 4 patterns
        • quickboo*
        • QuickB*
        • QBook*
        • intuit*
      • sender.display_name matches any of 2 patterns
        • QB-*
        • QB *
      • sender.display_name is similar to 'quickbooks'
      • sender.email.domain.domain matches '*quickbook*'
      • all of:
        • length(filter(ml.nlu_classifier(body.current_thread.text).entities, strings.icontains(.text, 'quickbooks'))) ≥ 2
        • any of ml.nlu_classifier(body.current_thread.text).intents where:
          • .name in ('cred_theft', 'callback_scam')
    • body.current_thread.text matches '*invoice*'
  3. any of:
    • any of ml.logo_detect(file.message_screenshot()).brands where all hold:
      • .name is 'Quickbooks'
      • .confidence in ('medium', 'high')
    • all of:
      • body.current_thread.text contains any of 2 patterns
        • 2800 E. Commerce Center Place, Tucson, AZ 85706
        • 2700 Coast Ave, Mountain View, CA 94043
      • body.current_thread.text matches '©\\s*(?:\\d+)\\s*Intuit'
    • body.current_thread.text contains any of 5 patterns
      • Powered by QuickBooks
      • QuickBooks and Intuit are trademarks of Intuit Inc.
      • QuickBooks Cloud Services
      • QuickBooks Support Center
      • QuickBooks subscription
    • body.current_thread.text matches '(?:Secured by )?QuickBooks Payments'
    • all of:
      • body.current_thread.text matches any of 2 patterns
        • \+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}
        • \+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}
      • any of ml.nlu_classifier(body.current_thread.text).topics where:
        • .name in ('Software and App Updates', 'Security and Authentication')
      • any of:
        • sender.display_name matches any of 4 patterns
          • quickbook*
          • QuickB*
          • QBook*
          • intuit*
        • sender.display_name matches any of 2 patterns
          • QB-*
          • QB *
        • sender.display_name is similar to 'quickbooks'
        • sender.email.domain.domain matches '*quickbook*'
        • all of:
          • length(filter(ml.nlu_classifier(body.current_thread.text).entities, strings.icontains(.text, 'quickbooks'))) > 2
          • any of ml.nlu_classifier(body.current_thread.text).intents where:
            • .name is 'cred_theft'
    • any of body.links where any holds:
      • all of:
        • .display_url.url matches '(?:quickbooks|intuit)'
        • .mismatched
        • not:
          • .href_url.domain.root_domain in ('mimecast.com', 'mimecastprotect.com')
      • all of:
        • .href_url.path matches '(?:quickbooks|intuit)'
        • not:
          • .href_url.domain.root_domain contains any of 2 patterns
            • quickbooks
            • intuit
        • not:
          • any of ml.nlu_classifier(body.current_thread.text).topics where:
            • .name is 'Advertising and Promotions'
    • all of:
      • any of ml.nlu_classifier(body.current_thread.text).entities where all hold:
        • .name is 'sender'
        • .text matches 'quickbooks?'
      • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
        • .name is 'cred_theft'
        • .confidence is 'high'
  4. not:
    • all of:
      • sender.email.domain.root_domain in ('intuit.com', 'turbotax.com', 'intuit.ca', 'meliopayments.com', 'qemailserver.com', 'intuit.co.uk', 'quickbooksonline.com', 'tsheets.com')
      • coalesce(headers.auth_summary.dmarc.pass)
  5. all of:
    • not:
      • profile.by_sender().any_messages_benign
    • not:
      • profile.by_sender().solicited
  6. any of:
    • length(filter(body.links, .href_url.domain.root_domain in~ ('intuit.com', 'turbotax.com', 'intuit.ca', 'meliopayments.com', 'qemailserver.com', 'intuit.co.uk', 'quickbooksonline.com') or .href_url.domain.root_domain == sender.email.domain.root_domain and .href_url.path is null or .href_url.path == '/' or .href_url.domain.sld == sender.email.local_part and .href_url.path is null or .href_url.path == '/' and sender.email.domain.root_domain in $free_email_providers)) is not length(body.links)
    • length(filter(body.links, .href_url.domain.domain is not null)) is 0
  7. not:
    • any of filter(body.links) where any holds:
      • .href_url.domain.domain is 'links.notification.intuit.com'
      • all of:
        • .href_url.domain.domain is 'connect.intuit.com'
        • .href_url.query_params contains 'cta=viewinvoicenow'
      • all of:
        • .href_url.domain.root_domain is 'mimecastprotect.com'
        • any of:
          • .href_url.query_params contains 'domain=links.notification.intuit.com'
          • .href_url.query_params contains 'domain=connect.intuit.com'
  8. not:
    • body.current_thread.text contains 'Purchasing Reviews, Inc'
  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, body.links, body.links[].display_text, body.links[].display_url.url, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.sld, body.links[].href_url.path, body.links[].mismatched, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.local_part, type.inbound. Sensors: file.message_screenshot, ml.logo_detect, ml.nlu_classifier, profile.by_sender, regex.icontains, strings.icontains, strings.ilevenshtein, strings.ilike, strings.like. Reference lists: $free_email_providers, $high_trust_sender_root_domains.

Indicators matched (42)

FieldMatchValue
strings.ilikesubstringquickboo*
strings.ilikesubstringQuickB*
strings.ilikesubstringQBook*
strings.ilikesubstringintuit*
strings.likesubstringQB-*
strings.likesubstringQB *
strings.ilevenshteinfuzzyquickbooks
strings.ilikesubstring*quickbook*
strings.icontainssubstringquickbooks
ml.nlu_classifier(body.current_thread.text).intents[].namemembercred_theft
ml.nlu_classifier(body.current_thread.text).intents[].namemembercallback_scam
strings.ilikesubstring*invoice*
30 more
ml.logo_detect(file.message_screenshot()).brands[].nameequalsQuickbooks
ml.logo_detect(file.message_screenshot()).brands[].confidencemembermedium
ml.logo_detect(file.message_screenshot()).brands[].confidencememberhigh
strings.icontainssubstring2800 E. Commerce Center Place, Tucson, AZ 85706
strings.icontainssubstring2700 Coast Ave, Mountain View, CA 94043
regex.icontainsregex©\s*(?:\d+)\s*Intuit
strings.icontainssubstringPowered by QuickBooks
strings.icontainssubstringQuickBooks and Intuit are trademarks of Intuit Inc.
strings.icontainssubstringQuickBooks Cloud Services
strings.icontainssubstringQuickBooks Support Center
strings.icontainssubstringQuickBooks subscription
regex.icontainsregex(?:Secured by )?QuickBooks Payments
regex.icontainsregex\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}
regex.icontainsregex\+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}
ml.nlu_classifier(body.current_thread.text).topics[].namememberSoftware and App Updates
ml.nlu_classifier(body.current_thread.text).topics[].namememberSecurity and Authentication
strings.ilikesubstringquickbook*
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
regex.icontainsregex(?:quickbooks|intuit)
ml.nlu_classifier(body.current_thread.text).entities[].nameequalssender
regex.icontainsregexquickbooks?
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh
body.links[].href_url.domain.root_domainmemberintuit.com
body.links[].href_url.domain.root_domainmemberturbotax.com
body.links[].href_url.domain.root_domainmemberintuit.ca
body.links[].href_url.domain.root_domainmembermeliopayments.com
body.links[].href_url.domain.root_domainmemberqemailserver.com
body.links[].href_url.domain.root_domainmemberintuit.co.uk
body.links[].href_url.domain.root_domainmemberquickbooksonline.com
body.links[].href_url.pathequals/

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(body.links)
      or
        and
          not
            or
              body.links.href_url.domain.root_domain contains "intuit"
              body.links.href_url.domain.root_domain contains "quickbooks"
          not
            any(ml.nlu_classifier(body.current_thread.text).topics)
              ml.nlu_classifier(body.current_thread.text).topics.name eq "Advertising and Promotions"
          body.links.href_url.path regex_match "(?:quickbooks|intuit)"
        and
          not
            body.links.href_url.domain.root_domain in ["mimecast.com", "mimecastprotect.com"]
          body.links.display_url.url regex_match "(?:quickbooks|intuit)"
          body.links.mismatched eq "true"
    and
      or
        and
          any(ml.nlu_classifier(body.current_thread.text).intents)
            ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
          filter(ml.nlu_classifier(body.current_thread.text).entities, strings.icontains(.text, 'quickbooks')) length_compare "2"
        sender.display_name starts_with "QB "
        sender.display_name starts_with "QB-"
        sender.display_name starts_with "QBook"
        sender.display_name starts_with "QuickB"
        sender.display_name starts_with "intuit"
        sender.display_name starts_with "quickbook"
        sender.email.domain.domain match "quickbook"
        strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"quickbooks\") <= 1"
      or
        body.current_thread.text regex_match "\\+?([ilo0-9]{1,2})?\\s?\\(?\\d{3}\\)?[\\s\\.\\-⋅]{0,5}[ilo0-9]{3}[\\s\\.\\-⋅]{0,5}[ilo0-9]{4}"
        body.current_thread.text regex_match "\\+?([ilo0-9]{1}.)?\\(?[ilo0-9]{3}?\\)?.[ilo0-9]{3}.?[ilo0-9]{4}"
      any(ml.nlu_classifier(body.current_thread.text).topics)
        ml.nlu_classifier(body.current_thread.text).topics.name in ["Security and Authentication", "Software and App Updates"]
    and
      any(ml.nlu_classifier(body.current_thread.text).entities)
        and
          ml.nlu_classifier(body.current_thread.text).entities.name eq "sender"
          ml.nlu_classifier(body.current_thread.text).entities.text regex_match "quickbooks?"
      any(ml.nlu_classifier(body.current_thread.text).intents)
        and
          ml.nlu_classifier(body.current_thread.text).intents.confidence eq "high"
          ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
    and
      or
        body.current_thread.text contains "2700 Coast Ave, Mountain View, CA 94043"
        body.current_thread.text contains "2800 E. Commerce Center Place, Tucson, AZ 85706"
      body.current_thread.text regex_match "©\\s*(?:\\d+)\\s*Intuit"
    any(ml.logo_detect(file.message_screenshot()).brands)
      and
        ml.logo_detect(file.message_screenshot()).brands.confidence in ["high", "medium"]
        ml.logo_detect(file.message_screenshot()).brands.name eq "Quickbooks"
    body.current_thread.text contains "Powered by QuickBooks"
    body.current_thread.text contains "QuickBooks Cloud Services"
    body.current_thread.text contains "QuickBooks Support Center"
    body.current_thread.text contains "QuickBooks and Intuit are trademarks of Intuit Inc."
    body.current_thread.text contains "QuickBooks subscription"
    body.current_thread.text regex_match "(?:Secured by )?QuickBooks Payments"
  not
    any(filter(body.links))
      or
        and
          or
            filter(body.links).href_url.query_params contains "domain=connect.intuit.com"
            filter(body.links).href_url.query_params contains "domain=links.notification.intuit.com"
          filter(body.links).href_url.domain.root_domain eq "mimecastprotect.com"
        and
          filter(body.links).href_url.domain.domain eq "connect.intuit.com"
          filter(body.links).href_url.query_params contains "cta=viewinvoicenow"
        filter(body.links).href_url.domain.domain eq "links.notification.intuit.com"
  or
    and
      any(ml.nlu_classifier(body.current_thread.text).intents)
        ml.nlu_classifier(body.current_thread.text).intents.name in ["callback_scam", "cred_theft"]
      filter(ml.nlu_classifier(body.current_thread.text).entities, strings.icontains(.text, 'quickbooks')) length_compare "2"
    body.current_thread.text match "invoice"
    sender.display_name starts_with "QB "
    sender.display_name starts_with "QB-"
    sender.display_name starts_with "QBook"
    sender.display_name starts_with "QuickB"
    sender.display_name starts_with "intuit"
    sender.display_name starts_with "quickboo"
    sender.email.domain.domain match "quickbook"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"quickbooks\") <= 1"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
      sender.email.domain.root_domain in ["intuit.ca", "intuit.co.uk", "intuit.com", "meliopayments.com", "qemailserver.com", "quickbooksonline.com", "tsheets.com", "turbotax.com"]
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
  not
    body.current_thread.text contains "Purchasing Reviews, Inc"
  or
    filter(body.links, .href_url.domain.domain is not null) length_compare "0"
    length func_call "length(filter(body.links, .href_url.domain.root_domain in~ ('intuit.com', 'turbotax.com', 'intuit.ca', 'meliopayments.com', 'qemailserver.com', 'intuit.co.uk', 'quickbooksonline.com') or .href_url.domain.root_domain == sender.email.domain.root_domain and .href_url.path is null or .href_url.path == '/' or .href_url.domain.sld == sender.email.local_part and .href_url.path is null or .href_url.path == '/' and sender.email.domain.root_domain in $free_email_providers)) != length(body.links)"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  not
    profile.by_sender func_call "profile.by_sender().solicited"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
filter(body.links)array_any(no value, null check)excludes:filter(body.links)
sender.email.domain.root_domaininintuit.ca, intuit.co.uk, intuit.com, meliopayments.com, qemailserver.com, quickbooksonline.com, tsheets.com, turbotax.comexcludes:sender.email.domain.root_domain
body.current_thread.textcontainsPurchasing Reviews, Incexcludes:body.current_thread.text field:"body.current_thread.text" value:"Purchasing Reviews, Inc"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textcontains
  • 2700 Coast Ave, Mountain View, CA 94043
  • 2800 E. Commerce Center Place, Tucson, AZ 85706
  • Powered by QuickBooks
  • QuickBooks Cloud Services
  • QuickBooks Support Center
  • QuickBooks and Intuit are trademarks of Intuit Inc.
  • QuickBooks subscription
field:"body.current_thread.text" kind:contains
body.current_thread.textregex_match
  • (?:Secured by )?QuickBooks Payments
  • +?([ilo0-9]{1,2})?\s?(?\d{3})?[\s.\-⋅]{0,5}[ilo0-9]{3}[\s.\-⋅]{0,5}[ilo0-9]{4}
  • +?([ilo0-9]{1}.)?(?[ilo0-9]{3}?)?.[ilo0-9]{3}.?[ilo0-9]{4}
  • ©\s*(?:\d+)\s*Intuit
field:"body.current_thread.text" kind:regex_match
body.current_thread.textwildcard
  • *invoice*
field:"body.current_thread.text" kind:wildcard value:"*invoice*"
sender.display_namewildcard
  • QB *
  • QB-*
  • QBook*
  • QuickB*
  • intuit*
  • quickboo*
  • quickbook*
field:"sender.display_name" kind:wildcard
sender.email.domain.domainwildcard
  • *quickbook*
field:"sender.email.domain.domain" kind:wildcard value:"*quickbook*"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: QuickBooks dispute notification

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

Detects messages impersonating QuickBooks or Intuit that reference dispute notifications or resolutions, but originate from unauthorized domains that fail DMARC authentication.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesImpersonation: Brand

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • sender.email
  • subject
  • type

Rule body

type.inbound
and any([subject.base, sender.display_name],
        strings.icontains(., 'Quickbooks', 'Intuit')
)
and any([subject.base, sender.display_name, body.current_thread.text],
        regex.icontains(., 'Dispute\s+(?:Notification|Resolution)')
)
and not (
  sender.email.domain.root_domain in~ (
    'intuit.com',
    'turbotax.com',
    'intuit.ca',
    'meliopayments.com',
    'qemailserver.com',
    'intuit.co.uk',
    'quickbooksonline.com',
    'tsheets.com'
  )
  and coalesce(headers.auth_summary.dmarc.pass, false)
)

Detection logic

Scope: inbound message.

Detects messages impersonating QuickBooks or Intuit that reference dispute notifications or resolutions, but originate from unauthorized domains that fail DMARC authentication.

  1. inbound message
  2. any of [subject.base, sender.display_name] where:
    • . contains any of 2 patterns
      • Quickbooks
      • Intuit
  3. any of [subject.base, sender.display_name, body.current_thread.text] where:
    • . matches 'Dispute\\s+(?:Notification|Resolution)'
  4. not:
    • all of:
      • sender.email.domain.root_domain in ('intuit.com', 'turbotax.com', 'intuit.ca', 'meliopayments.com', 'qemailserver.com', 'intuit.co.uk', 'quickbooksonline.com', 'tsheets.com')
      • coalesce(headers.auth_summary.dmarc.pass)

Inspects: body.current_thread.text, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.root_domain, subject.base, type.inbound. Sensors: regex.icontains, strings.icontains.

Indicators matched (3)

FieldMatchValue
strings.icontainssubstringQuickbooks
strings.icontainssubstringIntuit
regex.icontainsregexDispute\s+(?:Notification|Resolution)

Stages and Predicates

Stage 1: mql_rule

and
  any([subject.base, sender.display_name])
    or
      [subject.base, sender.display_name] contains "Intuit"
      [subject.base, sender.display_name] contains "Quickbooks"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
      sender.email.domain.root_domain in ["intuit.ca", "intuit.co.uk", "intuit.com", "meliopayments.com", "qemailserver.com", "quickbooksonline.com", "tsheets.com", "turbotax.com"]
  any([subject.base, sender.display_name, body.current_thread.text])
    [subject.base, sender.display_name, body.current_thread.text] regex_match "Dispute\\s+(?:Notification|Resolution)"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaininintuit.ca, intuit.co.uk, intuit.com, meliopayments.com, qemailserver.com, quickbooksonline.com, tsheets.com, turbotax.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Ripple

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

Attack impersonating Ripple cryptocurrency, potentially in the form of a giveaway scam.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • sender.email
  • type

Rule body

type.inbound
and regex.imatch(sender.display_name, '\bripple\b')
and sender.email.domain.root_domain not in ("ripple.com", "ripplejobs.co.uk")

Detection logic

Scope: inbound message.

Attack impersonating Ripple cryptocurrency, potentially in the form of a giveaway scam.

  1. inbound message
  2. sender.display_name matches '\\bripple\\b'
  3. sender.email.domain.root_domain not in ('ripple.com', 'ripplejobs.co.uk')

Inspects: sender.display_name, sender.email.domain.root_domain, type.inbound. Sensors: regex.imatch.

Indicators matched (1)

FieldMatchValue
regex.imatchregex\bripple\b

Stages and Predicates

Stage 1: mql_rule

and
  not
    sender.email.domain.root_domain in ["ripple.com", "ripplejobs.co.uk"]
  sender.display_name regex_match "\\bripple\\b"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

Brand Impersonation: ShareFile

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

This detection rule matches on the impersonation of the file sharing site ShareFile. Threat actors have been observed abusing this brand to deliver messages with links to crediential phishing pages.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Evasion, Lookalike domain

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • headers.hops
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  0 < length(body.links) < 100
  or 0 < length(filter(attachments, .file_type in $file_types_images)) <= 5
  or length(filter(attachments, .file_type == "pdf")) == 1
)
and (
  strings.icontains(sender.display_name, 'ShareFile')
  or strings.icontains(subject.subject, 'ShareFile Attachments')
  or strings.ilevenshtein(sender.display_name, 'ShareFile') <= 2
  or strings.icontains(sender.email.domain.domain, 'sharefile')
  // message body
  or strings.icontains(body.current_thread.text, 'ShareFile Attachments')
  or strings.icontains(body.current_thread.text,
                       'Click here to change how often ShareFile sends emails'
  )
  or strings.icontains(body.current_thread.text,
                       'uses ShareFile to share documents securely'
  )
  or strings.icontains(body.current_thread.text,
                       'ShareFile is a tool for sending, receiving, and organizing your business files online'
  )
  or regex.icontains(body.current_thread.text,
                     'shared a (?:file|document)\s*(?:\w+\s+){0,3}\s*via sharefile'
  )
  or strings.icontains(body.current_thread.text, 'Powered By Citrix ShareFile')
  or regex.icontains(body.current_thread.text, '© 20\d\d ShareFile')

  // any of the attached images contain the same message body wording
  or (
    0 < length(attachments) <= 5
    and (
      all(attachments, .file_type in $file_types_images)
      or (length(filter(attachments, .file_type == "pdf")) == 1)
    )
    and (
      any(attachments,
          any(file.explode(.),
              strings.icontains(.scan.ocr.raw, 'ShareFile Attachments')
              or strings.icontains(.scan.ocr.raw,
                                   'Click here to change how often ShareFile sends emails'
              )
              or strings.icontains(.scan.ocr.raw,
                                   'uses ShareFile to share documents securely'
              )
              or strings.icontains(.scan.ocr.raw,
                                   'ShareFile is a tool for sending, receiving, and organizing your business files online'
              )
              or strings.icontains(.scan.ocr.raw, 'Powered By Citrix ShareFile')
          )
      )
      or regex.icontains(body.current_thread.text, '© 20\d\d ShareFile')
    )
  )
)
and not (
  sender.email.domain.root_domain in (
    'sf-notifications.com',
    'sharefile.com',
    'cloud.com', // previous parent org of ShareFile
    'progress.com' // progress.com is the parent org of ShareFile
  )
  and headers.auth_summary.dmarc.pass
)
// ShareFile also allows you customers to send from customer domains/mail servers
// https://docs.sharefile.com/en-us/sharefile/configure/admin-settings/advanced-preferences.html#smtp-server
// when this happens, we cannot depend on the sender.email.domain.root_domain
// there does appear to be a custom header value added though. 
and not (
  any(headers.hops,
      .index == 0
      and any(.fields,
              (
                .name =~ "X-SMTPAPI"
                and strings.icontains(.value, 'sf_event_id')
              )
              or .name in~ ("x-sf-messageclass", "x-sf-uri")
      )
  )
)
// 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 detection rule matches on the impersonation of the file sharing site ShareFile. Threat actors have been observed abusing this brand to deliver messages with links to crediential phishing pages.

  1. inbound message
  2. any of:
    • all of:
      • length(body.links) > 0
      • length(body.links) < 100
    • all of:
      • length(filter(attachments, .file_type in $file_types_images)) > 0
      • length(filter(attachments, .file_type in $file_types_images)) ≤ 5
    • length(filter(attachments, .file_type == 'pdf')) is 1
  3. any of:
    • sender.display_name contains 'ShareFile'
    • subject.subject contains 'ShareFile Attachments'
    • sender.display_name is similar to 'ShareFile'
    • sender.email.domain.domain contains 'sharefile'
    • body.current_thread.text contains 'ShareFile Attachments'
    • body.current_thread.text contains 'Click here to change how often ShareFile sends emails'
    • body.current_thread.text contains 'uses ShareFile to share documents securely'
    • body.current_thread.text contains 'ShareFile is a tool for sending, receiving, and organizing your business files online'
    • body.current_thread.text matches 'shared a (?:file|document)\\s*(?:\\w+\\s+){0,3}\\s*via sharefile'
    • body.current_thread.text contains 'Powered By Citrix ShareFile'
    • body.current_thread.text matches '© 20\\d\\d ShareFile'
    • all of:
      • all of:
        • length(attachments) > 0
        • length(attachments) ≤ 5
      • any of:
        • all of attachments where:
          • .file_type in $file_types_images
        • length(filter(attachments, .file_type == 'pdf')) is 1
      • any of:
        • any of attachments where:
          • any of file.explode(.) where any holds:
            • .scan.ocr.raw contains 'ShareFile Attachments'
            • .scan.ocr.raw contains 'Click here to change how often ShareFile sends emails'
            • .scan.ocr.raw contains 'uses ShareFile to share documents securely'
            • .scan.ocr.raw contains 'ShareFile is a tool for sending, receiving, and organizing your business files online'
            • .scan.ocr.raw contains 'Powered By Citrix ShareFile'
        • body.current_thread.text matches '© 20\\d\\d ShareFile'
  4. not:
    • all of:
      • sender.email.domain.root_domain in ('sf-notifications.com', 'sharefile.com', 'cloud.com', 'progress.com')
      • headers.auth_summary.dmarc.pass
  5. not:
    • any of headers.hops where all hold:
      • .index is 0
      • any of .fields where any holds:
        • all of:
          • .name is 'X-SMTPAPI'
          • .value contains 'sf_event_id'
        • .name in ('x-sf-messageclass', 'x-sf-uri')
  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: attachments[].file_type, body.current_thread.text, body.links, headers.auth_summary.dmarc.pass, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, headers.hops[].index, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: file.explode, regex.icontains, strings.icontains, strings.ilevenshtein. Reference lists: $file_types_images, $high_trust_sender_root_domains.

Indicators matched (11)

FieldMatchValue
attachments[].file_typeequalspdf
strings.icontainssubstringShareFile
strings.icontainssubstringShareFile Attachments
strings.ilevenshteinfuzzyShareFile
strings.icontainssubstringsharefile
strings.icontainssubstringClick here to change how often ShareFile sends emails
strings.icontainssubstringuses ShareFile to share documents securely
strings.icontainssubstringShareFile is a tool for sending, receiving, and organizing your business files online
regex.icontainsregexshared a (?:file|document)\s*(?:\w+\s+){0,3}\s*via sharefile
strings.icontainssubstringPowered By Citrix ShareFile
regex.icontainsregex© 20\d\d ShareFile

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      or
        any(attachments)
          any(file.explode(attachments))
            or
              file.explode(attachments[])[].scan.ocr.raw contains "Click here to change how often ShareFile sends emails"
              file.explode(attachments[])[].scan.ocr.raw contains "Powered By Citrix ShareFile"
              file.explode(attachments[])[].scan.ocr.raw contains "ShareFile Attachments"
              file.explode(attachments[])[].scan.ocr.raw contains "ShareFile is a tool for sending, receiving, and organizing your business files online"
              file.explode(attachments[])[].scan.ocr.raw contains "uses ShareFile to share documents securely"
        body.current_thread.text regex_match "© 20\\d\\d ShareFile"
      or
        filter(attachments, .file_type == 'pdf') length_compare "1"
         macro "all(attachments)"
      attachments length_compare "0"
      attachments length_compare "5"
    body.current_thread.text contains "Click here to change how often ShareFile sends emails"
    body.current_thread.text contains "Powered By Citrix ShareFile"
    body.current_thread.text contains "ShareFile Attachments"
    body.current_thread.text contains "ShareFile is a tool for sending, receiving, and organizing your business files online"
    body.current_thread.text contains "uses ShareFile to share documents securely"
    body.current_thread.text regex_match "shared a (?:file|document)\\s*(?:\\w+\\s+){0,3}\\s*via sharefile"
    body.current_thread.text regex_match "© 20\\d\\d ShareFile"
    sender.display_name contains "ShareFile"
    sender.email.domain.domain contains "sharefile"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"ShareFile\") <= 2"
    subject.subject contains "ShareFile Attachments"
  not
    any(headers.hops)
      and
        any(headers.hops.fields)
          or
            and
              headers.hops.fields[].name eq "X-SMTPAPI"
              headers.hops.fields[].value contains "sf_event_id"
            headers.hops.fields[].name in ["x-sf-messageclass", "x-sf-uri"]
        headers.hops.index eq "0"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    and
      body.links length_compare "0"
      body.links length_compare "100"
    and
      filter(attachments, .file_type in $file_types_images) length_compare "0"
      filter(attachments, .file_type in $file_types_images) length_compare "5"
    filter(attachments, .file_type == 'pdf') length_compare "1"
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.root_domain in ["cloud.com", "progress.com", "sf-notifications.com", "sharefile.com"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.hopsarray_any(no value, null check)excludes:headers.hops
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
sender.email.domain.root_domainincloud.com, progress.com, sf-notifications.com, sharefile.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textcontains
  • Click here to change how often ShareFile sends emails
  • Powered By Citrix ShareFile
  • ShareFile Attachments
  • ShareFile is a tool for sending, receiving, and organizing your business files online
  • uses ShareFile to share documents securely
field:"body.current_thread.text" kind:contains
body.current_thread.textregex_match
  • shared a (?:file|document)\s*(?:\w+\s+){0,3}\s*via sharefile
  • © 20\d\d ShareFile
field:"body.current_thread.text" kind:regex_match
sender.display_namecontains
  • ShareFile
field:"sender.display_name" kind:contains value:"ShareFile"
sender.email.domain.domaincontains
  • sharefile
field:"sender.email.domain.domain" kind:contains value:"sharefile"
subject.subjectcontains
  • ShareFile Attachments
field:"subject.subject" kind:contains value:"ShareFile Attachments"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Sharepoint

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

Body, attached images or pdf contains a Sharepoint logo. The message contains a link and credential theft language.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • body.html
  • body.links
  • body.plain
  • headers
  • headers.auth_summary
  • headers.hops
  • sender.email
  • subject
  • type

Rule body

type.inbound
and length(body.links) > 0
and (
  any(attachments,
      (.file_type in $file_types_images or .file_type == "pdf")
      and any(ml.logo_detect(.).brands, .name == "Microsoft SharePoint")
  )
  or any(ml.logo_detect(file.message_screenshot()).brands,
         .name == "Microsoft SharePoint"
  )
  or strings.istarts_with(strings.replace_confusables(body.current_thread.text),
                          "Sharepoint"
  )
  or regex.icontains(body.html.raw,
                     '<img.*(title=|alt=).share.*src=""'
  ) // broken Sharepoint logo
  or (
    strings.icontains(strings.replace_confusables(body.plain.raw), "SharePoint")
    // message body references file deletion
    and regex.icontains(body.plain.raw,
                        '(expired )?file\s(was|has been|will be|scheduled (for|to be))\s?delet(ed|ion)'
    )
  )
  or (
    strings.icontains(body.current_thread.text, 'Sharepoint')
    and (
      regex.icontains(body.html.raw, '{(?:domain|randomNumber\d?)}')
      or any(body.links,
             regex.icontains(.href_url.url, 'mailto:[^@]+@{domain}')
      )
      or regex.icontains(body.html.raw, '<title>[^<]*Easearch[^<]*</title>')
    )
  )
)
and (
  (
    any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft" and .confidence == "high"
    )
    //
    // This rule makes use of a beta feature and is subject to change without notice
    // using the beta feature in custom rules is not suggested until it has been formally released
    //
    or any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents,
           .name == "cred_theft" and .confidence == "high"
    )
    or any(attachments,
           .file_type == "pdf"
           and beta.parse_exif(.).page_count == 1
           and any(file.explode(.),
                   any(ml.nlu_classifier(.scan.ocr.raw).intents,
                       .name == "cred_theft" and .confidence == "high"
                   )
           )
    )
  )
  or any(ml.nlu_classifier(body.current_thread.text).entities,
         .name == "urgency" and strings.ilike(.text, "*encrypted*")
  )
  or any(body.links,
         regex.imatch(.display_text,
                      '(?:re)?view (?:(?:&|and) (?:e([[:punct:]]|\s)?)?sign )?(?:complete )?(?:document|file)'
         )
  )
)
and not (
  (
    (
      strings.istarts_with(subject.subject, "RE:")
      or strings.istarts_with(subject.subject, "R:")
      or strings.istarts_with(subject.subject, "ODG:")
      or strings.istarts_with(subject.subject, "答复:")
      or strings.istarts_with(subject.subject, "AW:")
      or strings.istarts_with(subject.subject, "TR:")
      or strings.istarts_with(subject.subject, "FWD:")
      or regex.imatch(subject.subject, '(\[[^\]]+\]\s?){0,3}(re|fwd?)\s?:')
      or regex.imatch(subject.subject,
                      '^\[?(EXT|EXTERNAL)\]?[: ]\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*'
      )
    )
    and (
      (length(headers.references) > 0 or headers.in_reply_to is not null)
      // ensure that there are actual threads
      and (
        length(body.previous_threads) > 0
        or (length(body.html.display_text) - length(body.current_thread.text)) > 200
      )
    )
  )
)
and (
  profile.by_sender_email().prevalence != 'common'
  or not profile.by_sender_email().solicited
  or profile.by_sender().any_messages_malicious_or_spam
)
and not profile.by_sender().any_messages_benign

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

// negate sharepoint file share
and not (
  // based on the message id format
  (
    (
      strings.starts_with(headers.message_id, '<Share-')
      and strings.ends_with(headers.message_id, '@odspnotify>')
    )
    // negate legitimate access request to file
    or (
      strings.starts_with(headers.message_id, '<Sharing')
      and strings.ends_with(headers.message_id, '@odspnotify>')
    )
    // deal with Google thinking the message ID is "broke"
    or (
      strings.icontains(headers.message_id, 'SMTPIN_ADDED_BROKEN')
      and any(headers.hops,
              any(.fields,
                  .name == "X-Google-Original-Message-ID"
                  and strings.starts_with(.value, '<Share-')
                  and strings.ends_with(.value, '@odspnotify>')
              )
      )
    )
  )
  // all of the "action" links are sharepoint/ms
  and all(filter(body.links,
                 strings.icontains(subject.subject, .display_text)
                 or .display_text == "Open"
          ),
          .href_url.domain.root_domain in ("sharepoint.com", "1drv.ms")
          or (
            .href_url.domain.tld == "ms"
            // Microsoft does not own the .ms TLD, this checks to ensure it is one of their domains
            and (
              network.whois(.href_url.domain).registrant_company == "Microsoft Corporation"
              or strings.ilike(network.whois(.href_url.domain).registrar_name,
                               "*MarkMonitor*",
                               "*CSC Corporate*",
                               "*com laude*"
              )
            )
          )
  )
)
// negate sharepoint file shares with mimecast rewrites
and not (
  // rewritten message ID
  strings.iends_with(headers.message_id, 'mimecast.lan>')
  and all(filter(body.links,
                 strings.icontains(subject.subject, .display_text)
                 or .display_text == "Open"
          ),
          .href_url.domain.root_domain in (
            "mimecastprotect.com",
            "mimecast.com"
          )
          and any(.href_url.query_params_decoded["domain"],
                  strings.parse_domain(.).tld == "ms"
                  or strings.parse_domain(.).root_domain == "sharepoint.com"
          )
  )
)

Detection logic

Scope: inbound message.

Body, attached images or pdf contains a Sharepoint logo. The message contains a link and credential theft language.

  1. inbound message
  2. length(body.links) > 0
  3. any of:
    • any of attachments where all hold:
      • any of:
        • .file_type in $file_types_images
        • .file_type is 'pdf'
      • any of ml.logo_detect(.).brands where:
        • .name is 'Microsoft SharePoint'
    • any of ml.logo_detect(file.message_screenshot()).brands where:
      • .name is 'Microsoft SharePoint'
    • strings.replace_confusables(body.current_thread.text) starts with 'Sharepoint'
    • body.html.raw matches '<img.*(title=|alt=).share.*src=""'
    • all of:
      • strings.replace_confusables(body.plain.raw) contains 'SharePoint'
      • body.plain.raw matches '(expired )?file\\s(was|has been|will be|scheduled (for|to be))\\s?delet(ed|ion)'
    • all of:
      • body.current_thread.text contains 'Sharepoint'
      • any of:
        • body.html.raw matches '{(?:domain|randomNumber\\d?)}'
        • any of body.links where:
          • .href_url.url matches 'mailto:[^@]+@{domain}'
        • body.html.raw matches '<title>[^<]*Easearch[^<]*</title>'
  4. any of:
    • any of:
      • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
        • .name is 'cred_theft'
        • .confidence is 'high'
      • any of ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents where all hold:
        • .name is 'cred_theft'
        • .confidence is 'high'
      • any of attachments where all hold:
        • .file_type is 'pdf'
        • beta.parse_exif(.).page_count is 1
        • any of file.explode(.) where:
          • any of ml.nlu_classifier(.scan.ocr.raw).intents where all hold:
            • .name is 'cred_theft'
            • .confidence is 'high'
    • any of ml.nlu_classifier(body.current_thread.text).entities where all hold:
      • .name is 'urgency'
      • .text matches '*encrypted*'
    • any of body.links where:
      • .display_text matches '(?:re)?view (?:(?:&|and) (?:e([[:punct:]]|\\s)?)?sign )?(?:complete )?(?:document|file)'
  5. not:
    • all of:
      • any of:
        • subject.subject starts with 'RE:'
        • subject.subject starts with 'R:'
        • subject.subject starts with 'ODG:'
        • subject.subject starts with '答复:'
        • subject.subject starts with 'AW:'
        • subject.subject starts with 'TR:'
        • subject.subject starts with 'FWD:'
        • subject.subject matches '(\\[[^\\]]+\\]\\s?){0,3}(re|fwd?)\\s?:'
        • subject.subject matches '^\\[?(EXT|EXTERNAL)\\]?[: ]\\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*'
      • all of:
        • any of:
          • length(headers.references) > 0
          • headers.in_reply_to is set
        • any of:
          • length(body.previous_threads) > 0
          • length(body.html.display_text) - length(body.current_thread.text) > 200
  6. any of:
    • profile.by_sender_email().prevalence is not 'common'
    • not:
      • profile.by_sender_email().solicited
    • profile.by_sender().any_messages_malicious_or_spam
  7. not:
    • profile.by_sender().any_messages_benign
  8. 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
  9. not:
    • all of:
      • any of:
        • all of:
          • headers.message_id starts with '<Share-'
          • headers.message_id ends with '@odspnotify>'
        • all of:
          • headers.message_id starts with '<Sharing'
          • headers.message_id ends with '@odspnotify>'
        • all of:
          • headers.message_id contains 'SMTPIN_ADDED_BROKEN'
          • any of headers.hops where:
            • any of .fields where all hold:
              • .name is 'X-Google-Original-Message-ID'
              • .value starts with '<Share-'
              • .value ends with '@odspnotify>'
      • all of filter(body.links) where any holds:
        • .href_url.domain.root_domain in ('sharepoint.com', '1drv.ms')
        • all of:
          • .href_url.domain.tld is 'ms'
          • any of:
            • network.whois(.href_url.domain).registrant_company is 'Microsoft Corporation'
            • network.whois(.href_url.domain).registrar_name matches any of 3 patterns
              • *MarkMonitor*
              • *CSC Corporate*
              • *com laude*
  10. not:
    • all of:
      • headers.message_id ends with 'mimecast.lan>'
      • all of filter(body.links) where all hold:
        • .href_url.domain.root_domain in ('mimecastprotect.com', 'mimecast.com')
        • any of .href_url.query_params_decoded['domain'] where any holds:
          • strings.parse_domain(.).tld is 'ms'
          • strings.parse_domain(.).root_domain is 'sharepoint.com'

Inspects: attachments[].file_type, body.current_thread.text, body.html.raw, body.links, body.links[].display_text, body.links[].href_url.url, body.plain.raw, body.previous_threads, headers.auth_summary.dmarc.pass, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, headers.in_reply_to, headers.message_id, headers.references, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: beta.ocr, beta.parse_exif, file.explode, file.message_screenshot, ml.logo_detect, ml.nlu_classifier, network.whois, profile.by_sender, profile.by_sender_email, regex.icontains, regex.imatch, strings.ends_with, strings.icontains, strings.iends_with, strings.ilike, strings.istarts_with, strings.parse_domain, strings.replace_confusables, strings.starts_with. Reference lists: $file_types_images, $high_trust_sender_root_domains.

Indicators matched (20)

FieldMatchValue
attachments[].file_typeequalspdf
ml.logo_detect(attachments[]).brands[].nameequalsMicrosoft SharePoint
ml.logo_detect(file.message_screenshot()).brands[].nameequalsMicrosoft SharePoint
strings.istarts_withprefixSharepoint
regex.icontainsregex<img.*(title=|alt=).share.*src=""
strings.icontainssubstringSharePoint
regex.icontainsregex(expired )?file\s(was|has been|will be|scheduled (for|to be))\s?delet(ed|ion)
strings.icontainssubstringSharepoint
regex.icontainsregex{(?:domain|randomNumber\d?)}
regex.icontainsregexmailto:[^@]+@{domain}
regex.icontainsregex<title>[^<]*Easearch[^<]*</title>
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
8 more
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents[].nameequalscred_theft
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents[].confidenceequalshigh
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].nameequalscred_theft
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidenceequalshigh
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsurgency
strings.ilikesubstring*encrypted*
regex.imatchregex(?:re)?view (?:(?:&|and) (?:e([[:punct:]]|\s)?)?sign )?(?:complete )?(?:document|file)

Stages and Predicates

Stage 1: mql_rule

and
  not
    and
      or
        and
          any(headers.hops)
            any(headers.hops.fields)
              and
                headers.hops.fields[].name eq "X-Google-Original-Message-ID"
                headers.hops.fields[].value ends_with "@odspnotify>"
                headers.hops.fields[].value starts_with "<Share-"
          headers.message_id contains "SMTPIN_ADDED_BROKEN"
        and
          headers.message_id ends_with "@odspnotify>"
          headers.message_id starts_with "<Share-"
        and
          headers.message_id ends_with "@odspnotify>"
          headers.message_id starts_with "<Sharing"
       macro "all(filter(body.links))"
  or
    any(attachments)
      and
        any(file.explode(attachments))
          any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).intents)
            and
              ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidence eq "high"
              ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].name eq "cred_theft"
        attachments.file_type eq "pdf"
        beta.parse_exif func_call "beta.parse_exif(attachments[]).page_count == 1"
    any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents)
      and
        ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents.confidence eq "high"
        ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents.name eq "cred_theft"
    any(ml.nlu_classifier(body.current_thread.text).entities)
      and
        ml.nlu_classifier(body.current_thread.text).entities.name eq "urgency"
        ml.nlu_classifier(body.current_thread.text).entities.text match "encrypted"
    any(ml.nlu_classifier(body.current_thread.text).intents)
      and
        ml.nlu_classifier(body.current_thread.text).intents.confidence eq "high"
        ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
    any(body.links)
      body.links.display_text regex_match "(?:re)?view (?:(?:&|and) (?:e([[:punct:]]|\\s)?)?sign )?(?:complete )?(?:document|file)"
  or
    any(attachments)
      and
        or
          attachments.file_type eq "pdf"
           macro "attachments[].file_type in file_types_images"
        any(ml.logo_detect(attachments).brands)
          ml.logo_detect(attachments).brands.name eq "Microsoft SharePoint"
    and
      or
        any(body.links)
          body.links.href_url.url regex_match "mailto:[^@]+@{domain}"
        body.html.raw regex_match "<title>[^<]*Easearch[^<]*</title>"
        body.html.raw regex_match "{(?:domain|randomNumber\\d?)}"
      body.current_thread.text contains "Sharepoint"
    and
      body.plain.raw regex_match "(expired )?file\\s(was|has been|will be|scheduled (for|to be))\\s?delet(ed|ion)"
      strings.replace_confusables(body.plain.raw) contains "SharePoint"
    any(ml.logo_detect(file.message_screenshot()).brands)
      ml.logo_detect(file.message_screenshot()).brands.name eq "Microsoft SharePoint"
    body.html.raw regex_match "<img.*(title=|alt=).share.*src=\"\""
    strings.replace_confusables(body.current_thread.text) starts_with "Sharepoint"
  not
    and
      or
        body.previous_threads length_compare "0"
         macro "(length(body.html.display_text) - length(body.current_thread.text)) > 200"
      or
        headers.in_reply_to is_not_null
        headers.references length_compare "0"
      or
        subject.subject regex_match "(\\[[^\\]]+\\]\\s?){0,3}(re|fwd?)\\s?:"
        subject.subject regex_match "^\\[?(EXT|EXTERNAL)\\]?[: ]\\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*"
        subject.subject starts_with "AW:"
        subject.subject starts_with "FWD:"
        subject.subject starts_with "ODG:"
        subject.subject starts_with "R:"
        subject.subject starts_with "RE:"
        subject.subject starts_with "TR:"
        subject.subject starts_with "答复:"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    and
      headers.message_id ends_with "mimecast.lan>"
       macro "all(filter(body.links))"
  or
    not
      profile.by_sender_email func_call "profile.by_sender_email().solicited"
    profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    profile.by_sender_email func_call "profile.by_sender_email().prevalence != common"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  body.links length_compare "0"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.hopsarray_any(no value, null check)excludes:headers.hops
headers.message_idcontainsSMTPIN_ADDED_BROKENexcludes:headers.message_id field:"headers.message_id" value:"SMTPIN_ADDED_BROKEN"
headers.message_idends_with@odspnotify>excludes:headers.message_id field:"headers.message_id" value:"@odspnotify>"
headers.message_idstarts_with<Share-excludes:headers.message_id field:"headers.message_id" value:"<Share-"
headers.message_idstarts_with<Sharingexcludes:headers.message_id field:"headers.message_id" value:"<Sharing"
body.previous_threadslength_compare0excludes:body.previous_threads field:"body.previous_threads" value:"0"
headers.in_reply_tois_not_null(no value, null check)excludes:headers.in_reply_to
headers.referenceslength_compare0excludes:headers.references field:"headers.references" value:"0"
subject.subjectregex_match([[^]]+]\s?){0,3}(re|fwd?)\s?:excludes:subject.subject field:"subject.subject" value:"([[^]]+]\s?){0,3}(re|fwd?)\s?:"
subject.subjectregex_match^[?(EXT|EXTERNAL)]?[: ]\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*excludes:subject.subject field:"subject.subject" value:"^[?(EXT|EXTERNAL)]?[: ]\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*"
subject.subjectstarts_withAW:excludes:subject.subject field:"subject.subject" value:"AW:"
subject.subjectstarts_withFWD:excludes:subject.subject field:"subject.subject" value:"FWD:"
subject.subjectstarts_withODG:excludes:subject.subject field:"subject.subject" value:"ODG:"
subject.subjectstarts_withR:excludes:subject.subject field:"subject.subject" value:"R:"
subject.subjectstarts_withRE:excludes:subject.subject field:"subject.subject" value:"RE:"
subject.subjectstarts_withTR:excludes:subject.subject field:"subject.subject" value:"TR:"
subject.subjectstarts_with答复:excludes:subject.subject field:"subject.subject" value:"答复:"
headers.message_idends_withmimecast.lan>excludes:headers.message_id field:"headers.message_id" value:"mimecast.lan>"

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Sharepoint fake file share

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

This rule detects messages impersonating a Sharepoint file sharing email where no links point to known Microsoft domains.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • body.html
  • body.links
  • body.plain
  • headers
  • headers.auth_summary
  • recipients
  • recipients.to
  • sender.email
  • subject
  • type

Rule body

type.inbound

// Sharepoint body content looks like this
and (
  (
    (
      any([body.current_thread.text, body.plain.raw],
          strings.ilike(.,
                        "*shared a file with you*",
                        "*shared with you*",
                        "*invited you to access a file*",
                        "*received a document*",
                        "*shared a document*",
                        "*shared a new document*",
                        "*shared this document*"
          )
      )
      or any(ml.nlu_classifier(body.current_thread.text).topics,
             .name == "File Sharing and Cloud Services"
             and .confidence == "high"
      )
      //
      // This rule makes use of a beta feature and is subject to change without notice
      // using the beta feature in custom rules is not suggested until it has been formally released
      //
      or strings.ilike(beta.ocr(file.message_screenshot()).text,
                       "*shared a file with you*",
                       "*shared with you*",
                       "*invited you to access a file*",
                       "*received a document*",
                       "*shared a document*",
                       "*shared a new document*",
                       "*shared this document*"
      )
      //
      // This rule makes use of a beta feature and is subject to change without notice
      // using the beta feature in custom rules is not suggested until it has been formally released
      //
      or any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).topics,
             .name == "File Sharing and Cloud Services"
             and .confidence == "high"
      )
    )
    and (
      strings.ilike(subject.subject,
                    "*shared*",
                    "*updated*",
                    "*sign*",
                    "*review*",
                    "*scanned*"
      )
      or strings.ilike(subject.subject,
                       "*Excel*",
                       "*SharePoint*",
                       "*PowerPoint*",
                       "*OneNote*"
      )
      or strings.ilike(sender.display_name,
                       "*Excel*",
                       "*SharePoint*",
                       "*PowerPoint*",
                       "*OneNote*"
      )
      or any(body.links, strings.icontains(.display_text, "OPEN DOCUMENT"))
      or subject.subject is null
      or subject.subject == ""
      // the org as determined by NLU is in the subject
      or any(ml.nlu_classifier(body.current_thread.text).entities,
             .name == "org" and strings.icontains(subject.subject, .text)
      )
    )
  )
  or any([
           "Contigo", // Spanish
           "Avec vous", // French
           "Mit Ihnen", // German
           "Con te", // Italian
           "Com você", // Portuguese
           "Met u", // Dutch
           "С вами", // Russian
           "与你", // Chinese (Simplified)
           "與您", // Chinese (Traditional)
           "あなたと", // Japanese
           "당신과", // Korean
           "معك", // Arabic
           "آپ کے ساتھ", // Urdu
           "আপনার সাথে", // Bengali
           "आपके साथ", // Hindi
           "Sizinle", // Turkish // Azerbaijani
           "Med dig", // Swedish
           "Z tobą", // Polish
           "З вами", // Ukrainian
           "Önnel", // Hungarian
           "Μαζί σας", // Greek
           "איתך", // Hebrew
           "กับคุณ", // Thai
           "Với bạn", // Vietnamese
           "Dengan Anda", // Indonesian // Malay
           "Nawe", // Swahili
           "Cu dumneavoastră", // Romanian
           "S vámi", // Czech
           "Med deg", // Norwegian
           "S vami", // Slovak
           "Med dig", // Danish
           "Amb vostè", // Catalan
           "Teiega", // Estonian
           "S vama", // Serbian
         ],
         strings.icontains(subject.subject, .)
  )
)

// contains logic that impersonates Microsoft
and (
  any(ml.logo_detect(file.message_screenshot()).brands,
      strings.starts_with(.name, "Microsoft")
  )
  or any(attachments,
         .file_type in $file_types_images
         and any(ml.logo_detect(.).brands,
                 strings.starts_with(.name, "Microsoft")
         )
  )
  or regex.icontains(body.html.raw,
                     '<table[^>]*>\s*<tbody[^>]*>\s*<tr[^>]*>\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\s*&nbsp;\s*</td>\s*){2}\s*</tr>\s*<tr[^>]*>\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\s*&nbsp;\s*</td>\s*){2}'
  )
  or 3 of (
    regex.icontains(body.html.raw, '.password-expiration'),
    regex.icontains(body.html.raw, 'color: #2672ec;'),
    regex.icontains(body.html.raw, 'M\x{00AD}ic\x{00AD}ro\x{00AD}so\x{00AD}ft')
  )
  or 4 of (
    regex.icontains(body.html.raw, 'rgb\(246,\s?93,\s?53\)'),
    regex.icontains(body.html.raw, 'rgb\(129,\s?187,\s?5\)'),
    regex.icontains(body.html.raw, 'rgb\(4,\s?165,\s?240\)'),
    regex.icontains(body.html.raw, 'rgb\(255,\s?186,\s?7\)'),
  )
  or 4 of (
    regex.icontains(body.html.raw,
                    '(background-color:|background:|bgcolor=)(.)red'
    ),
    regex.icontains(body.html.raw, 'rgb\(19,\s?186,\s?132\)'),
    regex.icontains(body.html.raw, 'rgb\(4,\s?166,\s?240\)'),
    regex.icontains(body.html.raw, 'rgb\(255,\s?186,\s?8\)'),
  )
  or 4 of (
    regex.icontains(body.html.raw, 'rgb\(245,\s?189,\s?67\)'),
    regex.icontains(body.html.raw, 'rgb\(137,\s?184,\s?57\)'),
    regex.icontains(body.html.raw, 'rgb\(217,\s?83,\s?51\)'),
    regex.icontains(body.html.raw, 'rgb\(71,\s?160,\s?218\)')
  )
  or 4 of (
    regex.icontains(body.html.raw, 'rgb\(73,\s?161,\s?232\)'),
    regex.icontains(body.html.raw, 'rgb\(224,\s?92,\s?53\)'),
    regex.icontains(body.html.raw, 'rgb\(139,\s?183,\s?55\)'),
    regex.icontains(body.html.raw, 'rgb\(244,\s?188,\s?65\)')
  )
  or 4 of (
    regex.icontains(body.html.raw, 'rgb\(213,\s?56,\s?62\)'),
    regex.icontains(body.html.raw, 'rgb\(0,\s?114,\s?30\)'),
    regex.icontains(body.html.raw, 'rgb\(0,\s?110,\s?173\)'),
    regex.icontains(body.html.raw, 'rgb\(227,\s?209,\s?43\)'),
  )
  or 4 of (
    regex.icontains(body.html.raw, 'rgb\(246,\s?93,\s?53\)'),
    regex.icontains(body.html.raw, 'rgb\(129,\s?187,\s?5\)'),
    regex.icontains(body.html.raw, 'rgb\(4,\s?165,\s?240\)'),
    regex.icontains(body.html.raw, 'rgb\(255,\s?186,\s?7\)')
  )
  or 4 of (
    regex.icontains(body.html.raw, 'rgb\(242,\s?80,\s?34\)'),
    regex.icontains(body.html.raw, 'rgb\(127,\s?186,\s?0\)'),
    regex.icontains(body.html.raw, 'rgb\(0,\s?164,\s?239\)'),
    regex.icontains(body.html.raw, 'rgb\(255,\s?185,\s?0\)'),
  )
  or 4 of (
    regex.icontains(body.html.raw, 'rgb\(243,\s?83,\s?37\)'),
    regex.icontains(body.html.raw, 'rgb\(129,\s?188,\s?6\)'),
    regex.icontains(body.html.raw, 'rgb\(5,\s?166,\s?240\)'),
    regex.icontains(body.html.raw, 'rgb\(255,\s?186,\s?8\)')
  )
  or 4 of (
    regex.icontains(body.html.raw, 'rgb\(243,\s?80,\s?34\)'),
    regex.icontains(body.html.raw, 'rgb\(128,\s?187,\s?3\)'),
    regex.icontains(body.html.raw, 'rgb\(3,\s?165,\s?240\)'),
    regex.icontains(body.html.raw, 'rgb\(255,\s?185,\s?3\)')
  )
  or 4 of (
    regex.icontains(body.html.raw,
                    '(background-color:|background:|bgcolor=)(.)?(#)?(FF1940|eb5024|F25022|FF1941|red)'
    ),
    regex.icontains(body.html.raw,
                    '(background-color:|background:|bgcolor=)(.)?(#)?(36ba57|3eb55d|7db606|7FBA00|36ba58|green)'
    ),
    regex.icontains(body.html.raw,
                    '(background-color:|background:|bgcolor=)(.)?#(04a1d6|04B5F0|05a1e8|00A4EF|01a4ef|04a5f0)'
    ),
    regex.icontains(body.html.raw,
                    '(background-color:|background:|bgcolor=)(.)?#(FFCA07|f7b408|FFB900|FFCA08|ffb901|ffba07)'
    ),
  )
  or 4 of (
    regex.icontains(body.html.raw,
                    '(background-color:|background:|bgcolor=)(.)?#(f65314|f65d35|49a1e8|E74F23|F35325)'
    ),
    regex.icontains(body.html.raw,
                    '(background-color:|background:|bgcolor=)(.)?#(7cbf42|81bb05|e05c35|7AB206|81BC06)'
    ),
    regex.icontains(body.html.raw,
                    '(background-color:|background:|bgcolor=)(.)?#(00a4ef|0078d7|8bb737|04a5f0|059EE4|05A6F0)'
    ),
    regex.icontains(body.html.raw,
                    '(background-color:|background:|bgcolor=)(.)?#(ffb900|ffba07|f4bc41|F2B108|FFBA08)'
    ),
  )
  // fuzzy approach
  or 4 of (
    regex.icontains(body.html.raw,
                    'rgb\((2[1-4][0-9]|250),\s?(7[0-9]|8[0-9]|9[0-3]),\s?(3[0-9]|4[0-9]|5[0-3])\)'
    ),
    regex.icontains(body.html.raw,
                    'rgb\((12[0-9]|13[0-9]),\s?(18[0-9]|190),\s?([0-9]|10)\)'
    ),
    regex.icontains(body.html.raw,
                    'rgb\(([0-9]|1[0-5]),\s?(16[0-5]|166),\s?(23[0-9]|240)\)'
    ),
    regex.icontains(body.html.raw,
                    'rgb\((25[0-5]),\s?(18[5-9]|19[0-9]),\s?([0-9]|10)\)'
    )
  )
  or 4 of (
    regex.icontains(body.html.raw, 'rgb\((25[0-5]),\s?(2[0-5]),\s?(6[0-4])\)'),
    regex.icontains(body.html.raw, 'rgb\((6[0-2]),\s?(18[0-1]),\s?(9[0-3])\)'),
    regex.icontains(body.html.raw, 'rgb\(([0-4]),\s?(18[0-1]),\s?(24[0])\)'),
    regex.icontains(body.html.raw, 'rgb\((25[0-5]),\s?(20[0-2]),\s?([0-7])\)')
  )
  or (
    any(recipients.to,
        strings.icontains(body.current_thread.text,
                          strings.concat(.email.domain.sld,
                                         " shared a file with you"
                          )
        )
    )
  )
  or (
    any(recipients.to,
        strings.icontains(body.current_thread.text,
                          strings.concat("This link will work for ",
                                         .email.email
                          )
        )
    )
  )
  // contains HTML and wording from the sharepoint template
  or (
    (
      // 
      // This rule makes use of a beta feature and is subject to change without notice
      // using the beta feature in custom rules is not suggested until it has been formally released
      // 

      // alt text for the global icon
      length(html.xpath(body.html, '//img[@alt="permission globe icon"]').nodes) > 0
      // reference to the global icon id
      or length(html.xpath(body.html, '//img[@id="Picture_x0020_1"]').nodes) > 0
      // a comment reference the globe icon
      or strings.icontains(body.html.raw,
                           ' <!-- Permission globe icon placeholder -->'
      )
    )
    // the wording from the sharepoint share
    and strings.contains(body.current_thread.text,
                         'This invite will only work for you and people with existing access'
    )
  )
  or any(html.xpath(body.html,
                    "//*[contains(translate(@style, 'ABCDEF', 'abcdef'), 'color:#605e5c')]"
         ).nodes,
         .display_text =~ "Privacy Statement"
  )
  or 2 of (
    strings.icontains(body.current_thread.text,
                      'Microsoft respects your privacy'
    ),
    strings.icontains(body.current_thread.text,
                      'please read our Privacy Statement'
    ),
    strings.icontains(body.current_thread.text,
                      'Microsoft Corporation, One Microsoft Way, Redmond, WA 98052'
    ),
  )
)

// Negate messages when the message-id indciates the message is from MS actual. DKIM/SPF domains can be custom and therefore are unpredictable.
and not (
  strings.starts_with(headers.message_id, '<Share-')
  and strings.ends_with(headers.message_id, '@odspnotify>')
)

// fake Sharepoint shares are easy to identify if there are any links
// that don't point to microsoft[.]com or *.sharepoint[.]com
and not all(body.links,
            .href_url.domain.root_domain in (
              "1drv.ms",
              "aka.ms",
              "microsoft.com",
              "sharepoint.com"
            )
)
// if there is a Sharepoint link, ensure the link doesn't match any org SLDs
and not any(body.links,
            (
              .href_url.domain.root_domain == "sharepoint.com"
              and any($org_slds, . == ..href_url.domain.subdomain)
            )
            or .href_url.domain.domain in $tenant_domains
            or any(.href_url.query_params_decoded["domain"],
                   strings.parse_url(strings.concat("https://", .)).domain.root_domain == "sharepoint.com"
            )
)
and sender.email.domain.root_domain not in $org_domains
and sender.email.domain.root_domain not in (
  "bing.com",
  "microsoft.com",
  "microsoftonline.com",
  "microsoftsupport.com",
  "microsoft365.com",
  "office.com",
  "onedrive.com",
  "sharepointonline.com",
  "yammer.com",
  // ignore microsoft privacy statement links
  "aka.ms"
)
and not (
  (
    (
      strings.istarts_with(subject.subject, "RE:")
      or strings.istarts_with(subject.subject, "R:")
      or strings.istarts_with(subject.subject, "ODG:")
      or strings.istarts_with(subject.subject, "答复:")
      or strings.istarts_with(subject.subject, "AW:")
      or strings.istarts_with(subject.subject, "TR:")
      or strings.istarts_with(subject.subject, "FWD:")
      or regex.imatch(subject.subject, '(\[[^\]]+\]\s?){0,3}(re|fwd?)\s?:')
      or regex.imatch(subject.subject,
                      '^\[?(EXT|EXTERNAL)\]?[: ]\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*'
      )
    )
    and (
      (length(headers.references) > 0 or headers.in_reply_to is not null)
      // ensure that there are actual threads
      and (
        length(body.previous_threads) > 0
        or (length(body.html.display_text) - length(body.current_thread.text)) > 200
      )
    )
  )
)

// 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
)
and (
  profile.by_sender().solicited == false
  or profile.by_sender_email().prevalence == "new"
  or profile.by_sender_email().days_since.last_contact > 30
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
  // or it's a spoof of the org_domain
  or (
    sender.email.domain.domain in $org_domains
    and not (
      headers.auth_summary.spf.pass
      or coalesce(headers.auth_summary.dmarc.pass, false)
    )
  )
)
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

This rule detects messages impersonating a Sharepoint file sharing email where no links point to known Microsoft domains.

  1. inbound message
  2. any of:
    • all of:
      • any of:
        • any of [body.current_thread.text, body.plain.raw] where:
          • . matches any of 7 patterns
            • *shared a file with you*
            • *shared with you*
            • *invited you to access a file*
            • *received a document*
            • *shared a document*
            • *shared a new document*
            • *shared this document*
        • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
          • .name is 'File Sharing and Cloud Services'
          • .confidence is 'high'
        • beta.ocr(file.message_screenshot()).text matches any of 7 patterns
          • *shared a file with you*
          • *shared with you*
          • *invited you to access a file*
          • *received a document*
          • *shared a document*
          • *shared a new document*
          • *shared this document*
        • any of ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).topics where all hold:
          • .name is 'File Sharing and Cloud Services'
          • .confidence is 'high'
      • any of:
        • subject.subject matches any of 5 patterns
          • *shared*
          • *updated*
          • *sign*
          • *review*
          • *scanned*
        • subject.subject matches any of 4 patterns
          • *Excel*
          • *SharePoint*
          • *PowerPoint*
          • *OneNote*
        • sender.display_name matches any of 4 patterns
          • *Excel*
          • *SharePoint*
          • *PowerPoint*
          • *OneNote*
        • any of body.links where:
          • .display_text contains 'OPEN DOCUMENT'
        • subject.subject is missing
        • subject.subject is ''
        • any of ml.nlu_classifier(body.current_thread.text).entities where all hold:
          • .name is 'org'
          • strings.icontains(subject.subject)
    • any of ['Contigo', 'Avec vous', 'Mit Ihnen', 'Con te', 'Com você', 'Met u', 'С вами', '与你', '與您', 'あなたと', '당신과', 'معك', 'آپ کے ساتھ', 'আপনার সাথে', 'आपके साथ', 'Sizinle', 'Med dig', 'Z tobą', 'З вами', 'Önnel', 'Μαζί σας', 'איתך', 'กับคุณ', 'Với bạn', 'Dengan Anda', 'Nawe', 'Cu dumneavoastră', 'S vámi', 'Med deg', 'S vami', 'Med dig', 'Amb vostè', 'Teiega', 'S vama'] where:
      • strings.icontains(subject.subject)
  3. any of:
    • any of ml.logo_detect(file.message_screenshot()).brands where:
      • .name starts with 'Microsoft'
    • any of attachments where all hold:
      • .file_type in $file_types_images
      • any of ml.logo_detect(.).brands where:
        • .name starts with 'Microsoft'
    • body.html.raw matches '<table[^>]*>\\s*<tbody[^>]*>\\s*<tr[^>]*>\\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\\s*&nbsp;\\s*</td>\\s*){2}\\s*</tr>\\s*<tr[^>]*>\\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\\s*&nbsp;\\s*</td>\\s*){2}'
    • at least 3 of:
      • body.html.raw matches '.password-expiration'
      • body.html.raw matches 'color: #2672ec;'
      • body.html.raw matches 'M\\x{00AD}ic\\x{00AD}ro\\x{00AD}so\\x{00AD}ft'
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • rgb\(246,\s?93,\s?53\)
      • rgb\(129,\s?187,\s?5\)
      • rgb\(4,\s?165,\s?240\)
      • rgb\(255,\s?186,\s?7\)
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • (background-color:|background:|bgcolor=)(.)red
      • rgb\(19,\s?186,\s?132\)
      • rgb\(4,\s?166,\s?240\)
      • rgb\(255,\s?186,\s?8\)
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • rgb\(245,\s?189,\s?67\)
      • rgb\(137,\s?184,\s?57\)
      • rgb\(217,\s?83,\s?51\)
      • rgb\(71,\s?160,\s?218\)
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • rgb\(73,\s?161,\s?232\)
      • rgb\(224,\s?92,\s?53\)
      • rgb\(139,\s?183,\s?55\)
      • rgb\(244,\s?188,\s?65\)
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • rgb\(213,\s?56,\s?62\)
      • rgb\(0,\s?114,\s?30\)
      • rgb\(0,\s?110,\s?173\)
      • rgb\(227,\s?209,\s?43\)
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • rgb\(246,\s?93,\s?53\)
      • rgb\(129,\s?187,\s?5\)
      • rgb\(4,\s?165,\s?240\)
      • rgb\(255,\s?186,\s?7\)
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • rgb\(242,\s?80,\s?34\)
      • rgb\(127,\s?186,\s?0\)
      • rgb\(0,\s?164,\s?239\)
      • rgb\(255,\s?185,\s?0\)
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • rgb\(243,\s?83,\s?37\)
      • rgb\(129,\s?188,\s?6\)
      • rgb\(5,\s?166,\s?240\)
      • rgb\(255,\s?186,\s?8\)
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • rgb\(243,\s?80,\s?34\)
      • rgb\(128,\s?187,\s?3\)
      • rgb\(3,\s?165,\s?240\)
      • rgb\(255,\s?185,\s?3\)
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • (background-color:|background:|bgcolor=)(.)?(#)?(FF1940|eb5024|F25022|FF1941|red)
      • (background-color:|background:|bgcolor=)(.)?(#)?(36ba57|3eb55d|7db606|7FBA00|36ba58|green)
      • (background-color:|background:|bgcolor=)(.)?#(04a1d6|04B5F0|05a1e8|00A4EF|01a4ef|04a5f0)
      • (background-color:|background:|bgcolor=)(.)?#(FFCA07|f7b408|FFB900|FFCA08|ffb901|ffba07)
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • (background-color:|background:|bgcolor=)(.)?#(f65314|f65d35|49a1e8|E74F23|F35325)
      • (background-color:|background:|bgcolor=)(.)?#(7cbf42|81bb05|e05c35|7AB206|81BC06)
      • (background-color:|background:|bgcolor=)(.)?#(00a4ef|0078d7|8bb737|04a5f0|059EE4|05A6F0)
      • (background-color:|background:|bgcolor=)(.)?#(ffb900|ffba07|f4bc41|F2B108|FFBA08)
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • rgb\((2[1-4][0-9]|250),\s?(7[0-9]|8[0-9]|9[0-3]),\s?(3[0-9]|4[0-9]|5[0-3])\)
      • rgb\((12[0-9]|13[0-9]),\s?(18[0-9]|190),\s?([0-9]|10)\)
      • rgb\(([0-9]|1[0-5]),\s?(16[0-5]|166),\s?(23[0-9]|240)\)
      • rgb\((25[0-5]),\s?(18[5-9]|19[0-9]),\s?([0-9]|10)\)
    • at least 4 of 4: body.html.raw matches any of 4 patterns
      • rgb\((25[0-5]),\s?(2[0-5]),\s?(6[0-4])\)
      • rgb\((6[0-2]),\s?(18[0-1]),\s?(9[0-3])\)
      • rgb\(([0-4]),\s?(18[0-1]),\s?(24[0])\)
      • rgb\((25[0-5]),\s?(20[0-2]),\s?([0-7])\)
    • any of recipients.to where:
      • strings.icontains(body.current_thread.text)
    • any of recipients.to where:
      • strings.icontains(body.current_thread.text)
    • all of:
      • any of:
        • length(html.xpath(body.html, '//img[@alt="permission globe icon"]').nodes) > 0
        • length(html.xpath(body.html, '//img[@id="Picture_x0020_1"]').nodes) > 0
        • body.html.raw contains ' <!-- Permission globe icon placeholder -->'
      • body.current_thread.text contains 'This invite will only work for you and people with existing access'
    • any of html.xpath(body.html, "//*[contains(translate(@style, 'ABCDEF', 'abcdef'), 'color:#605e5c')]").nodes where:
      • .display_text is 'Privacy Statement'
    • at least 2 of:
      • body.current_thread.text contains 'Microsoft respects your privacy'
      • body.current_thread.text contains 'please read our Privacy Statement'
      • body.current_thread.text contains 'Microsoft Corporation, One Microsoft Way, Redmond, WA 98052'
  4. not:
    • all of:
      • headers.message_id starts with '<Share-'
      • headers.message_id ends with '@odspnotify>'
  5. not:
    • all of body.links where:
      • .href_url.domain.root_domain in ('1drv.ms', 'aka.ms', 'microsoft.com', 'sharepoint.com')
  6. not:
    • any of body.links where any holds:
      • all of:
        • .href_url.domain.root_domain is 'sharepoint.com'
        • any of $org_slds where:
          • . is .href_url.domain.subdomain
      • .href_url.domain.domain in $tenant_domains
      • any of .href_url.query_params_decoded['domain'] where:
        • strings.parse_url(strings.concat('https://', .)).domain.root_domain is 'sharepoint.com'
  7. sender.email.domain.root_domain not in $org_domains
  8. sender.email.domain.root_domain not in ('bing.com', 'microsoft.com', 'microsoftonline.com', 'microsoftsupport.com', 'microsoft365.com', 'office.com', 'onedrive.com', 'sharepointonline.com', 'yammer.com', 'aka.ms')
  9. not:
    • all of:
      • any of:
        • subject.subject starts with 'RE:'
        • subject.subject starts with 'R:'
        • subject.subject starts with 'ODG:'
        • subject.subject starts with '答复:'
        • subject.subject starts with 'AW:'
        • subject.subject starts with 'TR:'
        • subject.subject starts with 'FWD:'
        • subject.subject matches '(\\[[^\\]]+\\]\\s?){0,3}(re|fwd?)\\s?:'
        • subject.subject matches '^\\[?(EXT|EXTERNAL)\\]?[: ]\\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*'
      • all of:
        • any of:
          • length(headers.references) > 0
          • headers.in_reply_to is set
        • any of:
          • length(body.previous_threads) > 0
          • length(body.html.display_text) - length(body.current_thread.text) > 200
  10. 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
  11. any of:
    • profile.by_sender().solicited is False
    • profile.by_sender_email().prevalence is 'new'
    • profile.by_sender_email().days_since.last_contact > 30
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
    • all of:
      • sender.email.domain.domain in $org_domains
      • none of:
        • headers.auth_summary.spf.pass
        • coalesce(headers.auth_summary.dmarc.pass)
  12. not:
    • profile.by_sender().any_messages_benign

Inspects: attachments[].file_type, body.current_thread.text, body.html, body.html.raw, body.links, body.links[].display_text, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.subdomain, body.links[].href_url.query_params_decoded['domain'], body.plain.raw, body.previous_threads, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.in_reply_to, headers.message_id, headers.references, recipients.to, recipients.to[].email.domain.sld, recipients.to[].email.email, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: beta.ocr, file.message_screenshot, html.xpath, ml.logo_detect, ml.nlu_classifier, profile.by_sender, profile.by_sender_email, regex.icontains, regex.imatch, strings.concat, strings.contains, strings.ends_with, strings.icontains, strings.ilike, strings.istarts_with, strings.parse_url, strings.starts_with. Reference lists: $file_types_images, $high_trust_sender_root_domains, $org_domains, $org_slds, $tenant_domains.

Indicators matched (81)

FieldMatchValue
strings.ilikesubstring*shared a file with you*
strings.ilikesubstring*shared with you*
strings.ilikesubstring*invited you to access a file*
strings.ilikesubstring*received a document*
strings.ilikesubstring*shared a document*
strings.ilikesubstring*shared a new document*
strings.ilikesubstring*shared this document*
ml.nlu_classifier(body.current_thread.text).topics[].nameequalsFile Sharing and Cloud Services
ml.nlu_classifier(body.current_thread.text).topics[].confidenceequalshigh
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).topics[].nameequalsFile Sharing and Cloud Services
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).topics[].confidenceequalshigh
strings.ilikesubstring*shared*
69 more
strings.ilikesubstring*updated*
strings.ilikesubstring*sign*
strings.ilikesubstring*review*
strings.ilikesubstring*scanned*
strings.ilikesubstring*Excel*
strings.ilikesubstring*SharePoint*
strings.ilikesubstring*PowerPoint*
strings.ilikesubstring*OneNote*
strings.icontainssubstringOPEN DOCUMENT
subject.subjectequals
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsorg
strings.starts_withprefixMicrosoft
regex.icontainsregex<table[^>]*>\s*<tbody[^>]*>\s*<tr[^>]*>\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\s*&nbsp;\s*</td>\s*){2}\s*</tr>\s*<tr[^>]*>\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\s*&nbsp;\s*</td>\s*){2}
regex.icontainsregex.password-expiration
regex.icontainsregexcolor: #2672ec;
regex.icontainsregexM\x{00AD}ic\x{00AD}ro\x{00AD}so\x{00AD}ft
regex.icontainsregexrgb\(246,\s?93,\s?53\)
regex.icontainsregexrgb\(129,\s?187,\s?5\)
regex.icontainsregexrgb\(4,\s?165,\s?240\)
regex.icontainsregexrgb\(255,\s?186,\s?7\)
regex.icontainsregex(background-color:|background:|bgcolor=)(.)red
regex.icontainsregexrgb\(19,\s?186,\s?132\)
regex.icontainsregexrgb\(4,\s?166,\s?240\)
regex.icontainsregexrgb\(255,\s?186,\s?8\)
regex.icontainsregexrgb\(245,\s?189,\s?67\)
regex.icontainsregexrgb\(137,\s?184,\s?57\)
regex.icontainsregexrgb\(217,\s?83,\s?51\)
regex.icontainsregexrgb\(71,\s?160,\s?218\)
regex.icontainsregexrgb\(73,\s?161,\s?232\)
regex.icontainsregexrgb\(224,\s?92,\s?53\)
regex.icontainsregexrgb\(139,\s?183,\s?55\)
regex.icontainsregexrgb\(244,\s?188,\s?65\)
regex.icontainsregexrgb\(213,\s?56,\s?62\)
regex.icontainsregexrgb\(0,\s?114,\s?30\)
regex.icontainsregexrgb\(0,\s?110,\s?173\)
regex.icontainsregexrgb\(227,\s?209,\s?43\)
regex.icontainsregexrgb\(242,\s?80,\s?34\)
regex.icontainsregexrgb\(127,\s?186,\s?0\)
regex.icontainsregexrgb\(0,\s?164,\s?239\)
regex.icontainsregexrgb\(255,\s?185,\s?0\)
regex.icontainsregexrgb\(243,\s?83,\s?37\)
regex.icontainsregexrgb\(129,\s?188,\s?6\)
regex.icontainsregexrgb\(5,\s?166,\s?240\)
regex.icontainsregexrgb\(243,\s?80,\s?34\)
regex.icontainsregexrgb\(128,\s?187,\s?3\)
regex.icontainsregexrgb\(3,\s?165,\s?240\)
regex.icontainsregexrgb\(255,\s?185,\s?3\)
regex.icontainsregex(background-color:|background:|bgcolor=)(.)?(#)?(FF1940|eb5024|F25022|FF1941|red)
regex.icontainsregex(background-color:|background:|bgcolor=)(.)?(#)?(36ba57|3eb55d|7db606|7FBA00|36ba58|green)
regex.icontainsregex(background-color:|background:|bgcolor=)(.)?#(04a1d6|04B5F0|05a1e8|00A4EF|01a4ef|04a5f0)
regex.icontainsregex(background-color:|background:|bgcolor=)(.)?#(FFCA07|f7b408|FFB900|FFCA08|ffb901|ffba07)
regex.icontainsregex(background-color:|background:|bgcolor=)(.)?#(f65314|f65d35|49a1e8|E74F23|F35325)
regex.icontainsregex(background-color:|background:|bgcolor=)(.)?#(7cbf42|81bb05|e05c35|7AB206|81BC06)
regex.icontainsregex(background-color:|background:|bgcolor=)(.)?#(00a4ef|0078d7|8bb737|04a5f0|059EE4|05A6F0)
regex.icontainsregex(background-color:|background:|bgcolor=)(.)?#(ffb900|ffba07|f4bc41|F2B108|FFBA08)
regex.icontainsregexrgb\((2[1-4][0-9]|250),\s?(7[0-9]|8[0-9]|9[0-3]),\s?(3[0-9]|4[0-9]|5[0-3])\)
regex.icontainsregexrgb\((12[0-9]|13[0-9]),\s?(18[0-9]|190),\s?([0-9]|10)\)
regex.icontainsregexrgb\(([0-9]|1[0-5]),\s?(16[0-5]|166),\s?(23[0-9]|240)\)
regex.icontainsregexrgb\((25[0-5]),\s?(18[5-9]|19[0-9]),\s?([0-9]|10)\)
regex.icontainsregexrgb\((25[0-5]),\s?(2[0-5]),\s?(6[0-4])\)
regex.icontainsregexrgb\((6[0-2]),\s?(18[0-1]),\s?(9[0-3])\)
regex.icontainsregexrgb\(([0-4]),\s?(18[0-1]),\s?(24[0])\)
regex.icontainsregexrgb\((25[0-5]),\s?(20[0-2]),\s?([0-7])\)
strings.icontainssubstring <!-- Permission globe icon placeholder -->
strings.containssubstringThis invite will only work for you and people with existing access
html.xpath(body.html, "//*[contains(translate(@style, 'ABCDEF', 'abcdef'), 'color:#605e5c')]").nodes[].display_textequalsPrivacy Statement
strings.icontainssubstringMicrosoft respects your privacy
strings.icontainssubstringplease read our Privacy Statement
strings.icontainssubstringMicrosoft Corporation, One Microsoft Way, Redmond, WA 98052

Stages and Predicates

Stage 1: mql_rule

and
  not
    any(body.links)
      or
        and
          any($org_slds)
            $org_slds cross_field_compare "body.links.href_url.domain.subdomain"
          body.links.href_url.domain.root_domain eq "sharepoint.com"
        any(body.links.href_url.query_params_decoded['domain'])
          strings.parse_url func_call "strings.parse_url(strings.concat('https://', body.links[].href_url.query_params_decoded['domain'][])).domain.root_domain == sharepoint.com"
         macro "body.links[].href_url.domain.domain in tenant_domains"
  or
    and
      or
        any([body.current_thread.text, body.plain.raw])
          or
            [body.current_thread.text, body.plain.raw] match "invited you to access a file"
            [body.current_thread.text, body.plain.raw] match "received a document"
            [body.current_thread.text, body.plain.raw] match "shared a document"
            [body.current_thread.text, body.plain.raw] match "shared a file with you"
            [body.current_thread.text, body.plain.raw] match "shared a new document"
            [body.current_thread.text, body.plain.raw] match "shared this document"
            [body.current_thread.text, body.plain.raw] match "shared with you"
        any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).topics)
          and
            ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).topics.confidence eq "high"
            ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).topics.name eq "File Sharing and Cloud Services"
        any(ml.nlu_classifier(body.current_thread.text).topics)
          and
            ml.nlu_classifier(body.current_thread.text).topics.confidence eq "high"
            ml.nlu_classifier(body.current_thread.text).topics.name eq "File Sharing and Cloud Services"
        beta.ocr(file.message_screenshot()).text match "invited you to access a file"
        beta.ocr(file.message_screenshot()).text match "received a document"
        beta.ocr(file.message_screenshot()).text match "shared a document"
        beta.ocr(file.message_screenshot()).text match "shared a file with you"
        beta.ocr(file.message_screenshot()).text match "shared a new document"
        beta.ocr(file.message_screenshot()).text match "shared this document"
        beta.ocr(file.message_screenshot()).text match "shared with you"
      or
        any(ml.nlu_classifier(body.current_thread.text).entities)
          and
            ml.nlu_classifier(body.current_thread.text).entities.name eq "org"
            strings.icontains func_call "strings.icontains(subject.subject)"
        any(body.links)
          body.links.display_text contains "OPEN DOCUMENT"
        sender.display_name match "Excel"
        sender.display_name match "OneNote"
        sender.display_name match "PowerPoint"
        sender.display_name match "SharePoint"
        subject.subject eq ""
        subject.subject is_null
        subject.subject match "Excel"
        subject.subject match "OneNote"
        subject.subject match "PowerPoint"
        subject.subject match "SharePoint"
        subject.subject match "review"
        subject.subject match "scanned"
        subject.subject match "shared"
        subject.subject match "sign"
        subject.subject match "updated"
    any(['Contigo', 'Avec vous', 'Mit Ihnen', 'Con te', 'Com você', 'Met u', 'С вами', '与你', '與您', 'あなたと', '당신과', 'معك', 'آپ کے ساتھ', 'আপনার সাথে', 'आपके साथ', 'Sizinle', 'Med dig', 'Z tobą', 'З вами', 'Önnel', 'Μαζί σας', 'איתך', 'กับคุณ', 'Với bạn', 'Dengan Anda', 'Nawe', 'Cu dumneavoastră', 'S vámi', 'Med deg', 'S vami', 'Med dig', 'Amb vostè', 'Teiega', 'S vama'])
      strings.icontains func_call "strings.icontains(subject.subject)"
  or
    and
      not
        or
          coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
          headers.auth_summary.spf.pass eq "true"
       macro "sender.email.domain.domain in org_domains"
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    profile.by_sender func_call "profile.by_sender().solicited == false"
    profile.by_sender_email func_call "profile.by_sender_email().days_since.last_contact > 30"
    profile.by_sender_email func_call "profile.by_sender_email().prevalence == new"
  or
    any(attachments)
      and
        any(ml.logo_detect(attachments).brands)
          ml.logo_detect(attachments).brands.name starts_with "Microsoft"
         macro "attachments[].file_type in file_types_images"
    and
      or
        body.html.raw contains " <!-- Permission globe icon placeholder -->"
        html.xpath(body.html, '//img[@alt="permission globe icon"]').nodes length_compare "0"
        html.xpath(body.html, '//img[@id="Picture_x0020_1"]').nodes length_compare "0"
      body.current_thread.text contains "This invite will only work for you and people with existing access"
    and
      body.html.raw regex_match "(background-color:|background:|bgcolor=)(.)?#(00a4ef|0078d7|8bb737|04a5f0|059EE4|05A6F0)"
      body.html.raw regex_match "(background-color:|background:|bgcolor=)(.)?#(7cbf42|81bb05|e05c35|7AB206|81BC06)"
      body.html.raw regex_match "(background-color:|background:|bgcolor=)(.)?#(f65314|f65d35|49a1e8|E74F23|F35325)"
      body.html.raw regex_match "(background-color:|background:|bgcolor=)(.)?#(ffb900|ffba07|f4bc41|F2B108|FFBA08)"
    and
      body.html.raw regex_match "(background-color:|background:|bgcolor=)(.)?#(04a1d6|04B5F0|05a1e8|00A4EF|01a4ef|04a5f0)"
      body.html.raw regex_match "(background-color:|background:|bgcolor=)(.)?#(FFCA07|f7b408|FFB900|FFCA08|ffb901|ffba07)"
      body.html.raw regex_match "(background-color:|background:|bgcolor=)(.)?(#)?(36ba57|3eb55d|7db606|7FBA00|36ba58|green)"
      body.html.raw regex_match "(background-color:|background:|bgcolor=)(.)?(#)?(FF1940|eb5024|F25022|FF1941|red)"
    and
      body.html.raw regex_match "(background-color:|background:|bgcolor=)(.)red"
      body.html.raw regex_match "rgb\\(19,\\s?186,\\s?132\\)"
      body.html.raw regex_match "rgb\\(255,\\s?186,\\s?8\\)"
      body.html.raw regex_match "rgb\\(4,\\s?166,\\s?240\\)"
    and
      body.html.raw regex_match ".password-expiration"
      body.html.raw regex_match "M\\x{00AD}ic\\x{00AD}ro\\x{00AD}so\\x{00AD}ft"
      body.html.raw regex_match "color: #2672ec;"
    and
      body.html.raw regex_match "rgb\\((12[0-9]|13[0-9]),\\s?(18[0-9]|190),\\s?([0-9]|10)\\)"
      body.html.raw regex_match "rgb\\((25[0-5]),\\s?(18[5-9]|19[0-9]),\\s?([0-9]|10)\\)"
      body.html.raw regex_match "rgb\\((2[1-4][0-9]|250),\\s?(7[0-9]|8[0-9]|9[0-3]),\\s?(3[0-9]|4[0-9]|5[0-3])\\)"
      body.html.raw regex_match "rgb\\(([0-9]|1[0-5]),\\s?(16[0-5]|166),\\s?(23[0-9]|240)\\)"
    and
      body.html.raw regex_match "rgb\\((25[0-5]),\\s?(20[0-2]),\\s?([0-7])\\)"
      body.html.raw regex_match "rgb\\((25[0-5]),\\s?(2[0-5]),\\s?(6[0-4])\\)"
      body.html.raw regex_match "rgb\\((6[0-2]),\\s?(18[0-1]),\\s?(9[0-3])\\)"
      body.html.raw regex_match "rgb\\(([0-4]),\\s?(18[0-1]),\\s?(24[0])\\)"
    and
      body.html.raw regex_match "rgb\\(0,\\s?110,\\s?173\\)"
      body.html.raw regex_match "rgb\\(0,\\s?114,\\s?30\\)"
      body.html.raw regex_match "rgb\\(213,\\s?56,\\s?62\\)"
      body.html.raw regex_match "rgb\\(227,\\s?209,\\s?43\\)"
    and
      body.html.raw regex_match "rgb\\(0,\\s?164,\\s?239\\)"
      body.html.raw regex_match "rgb\\(127,\\s?186,\\s?0\\)"
      body.html.raw regex_match "rgb\\(242,\\s?80,\\s?34\\)"
      body.html.raw regex_match "rgb\\(255,\\s?185,\\s?0\\)"
    and
      body.html.raw regex_match "rgb\\(128,\\s?187,\\s?3\\)"
      body.html.raw regex_match "rgb\\(243,\\s?80,\\s?34\\)"
      body.html.raw regex_match "rgb\\(255,\\s?185,\\s?3\\)"
      body.html.raw regex_match "rgb\\(3,\\s?165,\\s?240\\)"
    and
      body.html.raw regex_match "rgb\\(129,\\s?187,\\s?5\\)"
      body.html.raw regex_match "rgb\\(246,\\s?93,\\s?53\\)"
      body.html.raw regex_match "rgb\\(255,\\s?186,\\s?7\\)"
      body.html.raw regex_match "rgb\\(4,\\s?165,\\s?240\\)"
    and
      body.html.raw regex_match "rgb\\(129,\\s?188,\\s?6\\)"
      body.html.raw regex_match "rgb\\(243,\\s?83,\\s?37\\)"
      body.html.raw regex_match "rgb\\(255,\\s?186,\\s?8\\)"
      body.html.raw regex_match "rgb\\(5,\\s?166,\\s?240\\)"
    and
      body.html.raw regex_match "rgb\\(137,\\s?184,\\s?57\\)"
      body.html.raw regex_match "rgb\\(217,\\s?83,\\s?51\\)"
      body.html.raw regex_match "rgb\\(245,\\s?189,\\s?67\\)"
      body.html.raw regex_match "rgb\\(71,\\s?160,\\s?218\\)"
    and
      body.html.raw regex_match "rgb\\(139,\\s?183,\\s?55\\)"
      body.html.raw regex_match "rgb\\(224,\\s?92,\\s?53\\)"
      body.html.raw regex_match "rgb\\(244,\\s?188,\\s?65\\)"
      body.html.raw regex_match "rgb\\(73,\\s?161,\\s?232\\)"
    any(html.xpath(body.html, "//*[contains(translate(@style, 'ABCDEF', 'abcdef'), 'color:#605e5c')]").nodes)
      html.xpath(body.html, "//*[contains(translate(@style, 'ABCDEF', 'abcdef'), 'color:#605e5c')]").nodes.display_text eq "Privacy Statement"
    any(ml.logo_detect(file.message_screenshot()).brands)
      ml.logo_detect(file.message_screenshot()).brands.name starts_with "Microsoft"
    any(recipients.to)
      strings.icontains func_call "strings.icontains(body.current_thread.text)"
    body.current_thread.text contains "Microsoft Corporation, One Microsoft Way, Redmond, WA 98052"
    body.current_thread.text contains "Microsoft respects your privacy"
    body.current_thread.text contains "please read our Privacy Statement"
    body.html.raw regex_match "<table[^>]*>\\s*<tbody[^>]*>\\s*<tr[^>]*>\\s*(<td[^>]*bgcolor=\"#[0-9A-Fa-f]{6}\"[^>]*>\\s*&nbsp;\\s*</td>\\s*){2}\\s*</tr>\\s*<tr[^>]*>\\s*(<td[^>]*bgcolor=\"#[0-9A-Fa-f]{6}\"[^>]*>\\s*&nbsp;\\s*</td>\\s*){2}"
  not
    and
      or
        body.previous_threads length_compare "0"
         macro "(length(body.html.display_text) - length(body.current_thread.text)) > 200"
      or
        headers.in_reply_to is_not_null
        headers.references length_compare "0"
      or
        subject.subject regex_match "(\\[[^\\]]+\\]\\s?){0,3}(re|fwd?)\\s?:"
        subject.subject regex_match "^\\[?(EXT|EXTERNAL)\\]?[: ]\\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*"
        subject.subject starts_with "AW:"
        subject.subject starts_with "FWD:"
        subject.subject starts_with "ODG:"
        subject.subject starts_with "R:"
        subject.subject starts_with "RE:"
        subject.subject starts_with "TR:"
        subject.subject starts_with "答复:"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    and
      headers.message_id ends_with "@odspnotify>"
      headers.message_id starts_with "<Share-"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  not
    sender.email.domain.root_domain in ["aka.ms", "bing.com", "microsoft.com", "microsoft365.com", "microsoftonline.com", "microsoftsupport.com", "office.com", "onedrive.com", "sharepointonline.com", "yammer.com"]
  not
     macro "all(body.links)"
  type.inbound eq "true"
   macro "sender.email.domain.root_domain not in org_domains"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
body.linksarray_any(no value, null check)excludes:body.links
body.previous_threadslength_compare0excludes:body.previous_threads field:"body.previous_threads" value:"0"
headers.in_reply_tois_not_null(no value, null check)excludes:headers.in_reply_to
headers.referenceslength_compare0excludes:headers.references field:"headers.references" value:"0"
subject.subjectregex_match([[^]]+]\s?){0,3}(re|fwd?)\s?:excludes:subject.subject field:"subject.subject" value:"([[^]]+]\s?){0,3}(re|fwd?)\s?:"
subject.subjectregex_match^[?(EXT|EXTERNAL)]?[: ]\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*excludes:subject.subject field:"subject.subject" value:"^[?(EXT|EXTERNAL)]?[: ]\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*"
subject.subjectstarts_withAW:excludes:subject.subject field:"subject.subject" value:"AW:"
subject.subjectstarts_withFWD:excludes:subject.subject field:"subject.subject" value:"FWD:"
subject.subjectstarts_withODG:excludes:subject.subject field:"subject.subject" value:"ODG:"
subject.subjectstarts_withR:excludes:subject.subject field:"subject.subject" value:"R:"
subject.subjectstarts_withRE:excludes:subject.subject field:"subject.subject" value:"RE:"
subject.subjectstarts_withTR:excludes:subject.subject field:"subject.subject" value:"TR:"
subject.subjectstarts_with答复:excludes:subject.subject field:"subject.subject" value:"答复:"
headers.message_idends_with@odspnotify>excludes:headers.message_id field:"headers.message_id" value:"@odspnotify>"
headers.message_idstarts_with<Share-excludes:headers.message_id field:"headers.message_id" value:"<Share-"
sender.email.domain.root_domaininaka.ms, bing.com, microsoft.com, microsoft365.com, microsoftonline.com, microsoftsupport.com, office.com, onedrive.com, sharepointonline.com, yammer.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
beta.ocr(file.message_screenshot()).textwildcard
  • *invited you to access a file*
  • *received a document*
  • *shared a document*
  • *shared a file with you*
  • *shared a new document*
  • *shared this document*
  • *shared with you*
field:"beta.ocr(file.message_screenshot()).text" kind:wildcard
body.current_thread.textcontains
  • Microsoft Corporation, One Microsoft Way, Redmond, WA 98052
  • Microsoft respects your privacy
  • This invite will only work for you and people with existing access
  • please read our Privacy Statement
field:"body.current_thread.text" kind:contains
body.html.rawcontains
  • <!-- Permission globe icon placeholder -->
field:"body.html.raw" kind:contains value:" <!-- Permission globe icon placeholder -->"
body.html.rawregex_match
  • (background-color:|background:|bgcolor=)(.)?#(00a4ef|0078d7|8bb737|04a5f0|059EE4|05A6F0)
  • (background-color:|background:|bgcolor=)(.)?#(04a1d6|04B5F0|05a1e8|00A4EF|01a4ef|04a5f0)
  • (background-color:|background:|bgcolor=)(.)?#(7cbf42|81bb05|e05c35|7AB206|81BC06)
  • (background-color:|background:|bgcolor=)(.)?#(FFCA07|f7b408|FFB900|FFCA08|ffb901|ffba07)
  • (background-color:|background:|bgcolor=)(.)?#(f65314|f65d35|49a1e8|E74F23|F35325)
  • (background-color:|background:|bgcolor=)(.)?#(ffb900|ffba07|f4bc41|F2B108|FFBA08)
  • (background-color:|background:|bgcolor=)(.)?(#)?(36ba57|3eb55d|7db606|7FBA00|36ba58|green)
  • (background-color:|background:|bgcolor=)(.)?(#)?(FF1940|eb5024|F25022|FF1941|red)
  • (background-color:|background:|bgcolor=)(.)red
  • .password-expiration
  • <table[^>]*>\s*<tbody[^>]*>\s*<tr[^>]*>\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\s* \s*</td>\s*){2}\s*</tr>\s*<tr[^>]*>\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\s* \s*</td>\s*){2}
  • M\x{00AD}ic\x{00AD}ro\x{00AD}so\x{00AD}ft
  • color: #2672ec;
  • rgb((12[0-9]|13[0-9]),\s?(18[0-9]|190),\s?([0-9]|10))
  • rgb((25[0-5]),\s?(18[5-9]|19[0-9]),\s?([0-9]|10))
  • rgb((25[0-5]),\s?(20[0-2]),\s?([0-7]))
  • rgb((25[0-5]),\s?(2[0-5]),\s?(6[0-4]))
  • rgb((2[1-4][0-9]|250),\s?(7[0-9]|8[0-9]|9[0-3]),\s?(3[0-9]|4[0-9]|5[0-3]))
  • rgb((6[0-2]),\s?(18[0-1]),\s?(9[0-3]))
  • rgb(([0-4]),\s?(18[0-1]),\s?(24[0]))
  • rgb(([0-9]|1[0-5]),\s?(16[0-5]|166),\s?(23[0-9]|240))
  • rgb(0,\s?110,\s?173)
  • rgb(0,\s?114,\s?30)
  • rgb(0,\s?164,\s?239)
  • rgb(127,\s?186,\s?0)
  • rgb(128,\s?187,\s?3)
  • rgb(129,\s?187,\s?5)
  • rgb(129,\s?188,\s?6)
  • rgb(137,\s?184,\s?57)
  • rgb(139,\s?183,\s?55)
  • rgb(19,\s?186,\s?132)
  • rgb(213,\s?56,\s?62)
  • rgb(217,\s?83,\s?51)
  • rgb(224,\s?92,\s?53)
  • rgb(227,\s?209,\s?43)
  • rgb(242,\s?80,\s?34)
  • rgb(243,\s?80,\s?34)
  • rgb(243,\s?83,\s?37)
  • rgb(244,\s?188,\s?65)
  • rgb(245,\s?189,\s?67)
  • rgb(246,\s?93,\s?53)
  • rgb(255,\s?185,\s?0)
  • rgb(255,\s?185,\s?3)
  • rgb(255,\s?186,\s?7)
  • rgb(255,\s?186,\s?8)
  • rgb(3,\s?165,\s?240)
  • rgb(4,\s?165,\s?240)
  • rgb(4,\s?166,\s?240)
  • rgb(5,\s?166,\s?240)
  • rgb(71,\s?160,\s?218)
  • rgb(73,\s?161,\s?232)
field:"body.html.raw" kind:regex_match
sender.display_namewildcard
  • *Excel*
  • *OneNote*
  • *PowerPoint*
  • *SharePoint*
field:"sender.display_name" kind:wildcard
subject.subjectis_null
  • (no value, null check)
field:"subject.subject" kind:is_null
subject.subjectwildcard
  • *Excel*
  • *OneNote*
  • *PowerPoint*
  • *SharePoint*
  • *review*
  • *scanned*
  • *shared*
  • *sign*
  • *updated*
field:"subject.subject" kind:wildcard
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Silicon Valley Bank

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

Detects emails that impersonate Silicon Valley Bank

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • sender.email
  • type

Rule body

type.inbound
and (
  regex.icontains(sender.email.domain.domain,
                  "(silicon(e)?.{0,10}(valley|bank)|svb)"
  )
  or strings.ilevenshtein(sender.display_name, 'svb') <= 1
)
and network.whois(sender.email.domain).days_old <= 30

Detection logic

Scope: inbound message.

Detects emails that impersonate Silicon Valley Bank

  1. inbound message
  2. any of:
    • sender.email.domain.domain matches '(silicon(e)?.{0,10}(valley|bank)|svb)'
    • sender.display_name is similar to 'svb'
  3. network.whois(sender.email.domain).days_old ≤ 30

Inspects: sender.display_name, sender.email.domain, sender.email.domain.domain, type.inbound. Sensors: network.whois, regex.icontains, strings.ilevenshtein.

Indicators matched (2)

FieldMatchValue
regex.icontainsregex(silicon(e)?.{0,10}(valley|bank)|svb)
strings.ilevenshteinfuzzysvb

Stages and Predicates

Stage 1: mql_rule

and
  or
    sender.email.domain.domain regex_match "(silicon(e)?.{0,10}(valley|bank)|svb)"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"svb\") <= 1"
  network.whois func_call "network.whois(sender.email.domain).days_old <= 30"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Social Security Administration

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

Detects messages impersonating the Social Security Administration (SSA) through various indicators including display names, subjects, body content, attachments, and HTML titles. The rule identifies SSA references, confusable characters, statement notifications, and credential theft language while excluding legitimate government communications.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Credential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • body.links
  • headers
  • headers.auth_summary
  • sender.email
  • subject
  • type

Rule body

type.inbound
// Identifies as SSA without catching strings such as "Alyssa"
and (
  regex.contains(sender.display_name, '^SSA\b')
  or strings.icontains(sender.display_name, "Social Security Administration")
  // there are confusables in the display name
  or (
    strings.replace_confusables(sender.display_name) != sender.display_name
    and strings.contains(strings.replace_confusables(sender.display_name),
                         "SSA"
    )
  )
  or any([sender.display_name, subject.subject],
         regex.icontains(strings.replace_confusables(.),
                         'Social (?:benefits|security|s.a\b)',
         )
  )
  or (
    strings.ilike(subject.base, "*statement*")
    and (
      strings.icontains(body.current_thread.text, "ssa.gov")
      or regex.icontains(body.current_thread.text,
                         '1[\s\-\.]?\(?\s*800\s*\)?[\s\-\.]?772[\s\-\.]?1213'
      )
    )
  )
  or (
    any(attachments,
        .file_type in ("doc", "docx")
        and any(file.explode(.),
                strings.icontains(.scan.strings.raw,
                                  "Social Security Administration"
                )
        )
    )
  )
  // display name or subject references a statement
  or (
    any([sender.display_name, subject.subject],
        regex.icontains(strings.replace_confusables(.),
                        '(Digital|(e[[:punct:]]?))\s?Statements?.{0,10}(Generated|Created|Issued|Ready)'
        )
    )
    // with SSA impersonation in the body
    and strings.icontains(body.current_thread.text,
                          'Social Security Administration'
    )
  )
  or any(html.xpath(body.html, '//title').nodes,
         (
           strings.icontains(.inner_text, 'Social Security')
           and (
             strings.icontains(.inner_text, 'Statement')
             or strings.icontains(.inner_text, 'Notification')
             or strings.icontains(.inner_text, 'Document')
             or strings.icontains(.inner_text, 'Message')
             or strings.icontains(.inner_text, 'Important Update')
             or strings.icontains(.inner_text, 'Benefit Amount')
             or strings.icontains(.inner_text, 'Account')
             or strings.icontains(.inner_text, 'Authorization')
           )
         )
         or .inner_text =~ "Social Security Administration"
         or .inner_text =~ "Social Security"
  )
  or (
    any(body.links,
        (
          strings.contains(.href_url.url, 'ssa.gov')
          or (.display_url.domain.root_domain == "ssa.gov" and .mismatched)
        )
    )
    and strings.icontains(body.current_thread.text,
                          'download monthly statement'
    )
    and strings.icontains(body.current_thread.text, 'stay connected')
  )
  or (
    any(ml.nlu_classifier(body.current_thread.text).entities,
        .name == "sender" and .text == "Social Security Administration"
    )
    and any(ml.nlu_classifier(body.current_thread.text).intents,
            .name == "cred_theft" and .confidence != "low"
    )
  )
)

// Not from a .gov domain
and not (sender.email.domain.tld == "gov" and headers.auth_summary.dmarc.pass)

// Additional suspicious indicator
and (
  any(ml.nlu_classifier(body.current_thread.text).topics,
      .name in ("Security and Authentication", "Secure Message")
      and .confidence == "high"
  )
  or any(ml.nlu_classifier(body.current_thread.text).entities,
         .name == "org" and .text == "SSA"
  )
  or length(body.current_thread.text) == 0
  or body.current_thread.text is null
  or strings.icontains(body.current_thread.text, "SSA Statement Viewer")
  or strings.icontains(strings.replace_confusables(body.current_thread.text),
                       "Social Security Statement"
  )
  or regex.icontains(body.current_thread.text,
                     "(?:view|open) (?:your|the).{0,8} (statement|document)"
  )
  or regex.icontains(body.current_thread.text,
                     "(?:view|open|assess|evaluate|review|conduct|read|scan)"
  )
  // real SSA phone number
  or strings.icontains(body.current_thread.text, "1-800-772-1213")
  or any(body.links,
         any(regex.extract(.href_url.path, '\.(?P<ext>[^./?#]+)(?:[?#]|$)'),
             .named_groups["ext"] in $file_extensions_executables
         )
  )
  or any(ml.logo_detect(file.message_screenshot()).brands,
         .name == "SSA" and .confidence == "high"
  )
  or (
    any(attachments,
        .file_type in ("doc", "docx")
        and any(file.explode(.),
                strings.icontains(.scan.strings.raw, "suspended")
                or strings.icontains(.scan.strings.raw, "fraudulent")
                or strings.icontains(.scan.strings.raw, "violated")
                or strings.icontains(.scan.strings.raw, "false identity")
                or regex.icontains(.scan.strings.raw,
                                   '\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}',
                                   '\+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}'
                )
        )
    )
  )
)
and not (
  any(ml.nlu_classifier(body.current_thread.text).topics,
      .name in (
        "Newsletters and Digests",
        "Advertising and Promotions",
        "Events and Webinars",
        "Charity and Non-Profit",
        "Political Mail"
      )
      and .confidence == "high"
  )
  or any(ml.nlu_classifier(body.current_thread.text).intents,
         .name == "benign" and .confidence == "high"
  )
)
and not (
  sender.email.email in ("email@email.monarch.com", "contact@govplus.com")
  and coalesce(headers.auth_summary.dmarc.pass, false)
)

// not a forward or reply
and (headers.in_reply_to is null or length(headers.references) == 0)
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.

Detects messages impersonating the Social Security Administration (SSA) through various indicators including display names, subjects, body content, attachments, and HTML titles. The rule identifies SSA references, confusable characters, statement notifications, and credential theft language while excluding legitimate government communications.

  1. inbound message
  2. any of:
    • sender.display_name matches '^SSA\\b'
    • sender.display_name contains 'Social Security Administration'
    • all of:
      • strings.replace_confusables(sender.display_name) is not sender.display_name
      • strings.replace_confusables(sender.display_name) contains 'SSA'
    • any of [sender.display_name, subject.subject] where:
      • strings.replace_confusables(.) matches 'Social (?:benefits|security|s.a\\b)'
    • all of:
      • subject.base matches '*statement*'
      • any of:
        • body.current_thread.text contains 'ssa.gov'
        • body.current_thread.text matches '1[\\s\\-\\.]?\\(?\\s*800\\s*\\)?[\\s\\-\\.]?772[\\s\\-\\.]?1213'
    • any of attachments where all hold:
      • .file_type in ('doc', 'docx')
      • any of file.explode(.) where:
        • .scan.strings.raw contains 'Social Security Administration'
    • all of:
      • any of [sender.display_name, subject.subject] where:
        • strings.replace_confusables(.) matches '(Digital|(e[[:punct:]]?))\\s?Statements?.{0,10}(Generated|Created|Issued|Ready)'
      • body.current_thread.text contains 'Social Security Administration'
    • any of html.xpath(body.html, '//title').nodes where any holds:
      • all of:
        • .inner_text contains 'Social Security'
        • .inner_text contains any of 8 patterns
          • Statement
          • Notification
          • Document
          • Message
          • Important Update
          • Benefit Amount
          • Account
          • Authorization
      • .inner_text is 'Social Security Administration'
      • .inner_text is 'Social Security'
    • all of:
      • any of body.links where any holds:
        • .href_url.url contains 'ssa.gov'
        • all of:
          • .display_url.domain.root_domain is 'ssa.gov'
          • .mismatched
      • body.current_thread.text contains 'download monthly statement'
      • body.current_thread.text contains 'stay connected'
    • all of:
      • any of ml.nlu_classifier(body.current_thread.text).entities where all hold:
        • .name is 'sender'
        • .text is 'Social Security Administration'
      • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
        • .name is 'cred_theft'
        • .confidence is not 'low'
  3. not:
    • all of:
      • sender.email.domain.tld is 'gov'
      • headers.auth_summary.dmarc.pass
  4. any of:
    • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
      • .name in ('Security and Authentication', 'Secure Message')
      • .confidence is 'high'
    • any of ml.nlu_classifier(body.current_thread.text).entities where all hold:
      • .name is 'org'
      • .text is 'SSA'
    • length(body.current_thread.text) is 0
    • body.current_thread.text is missing
    • body.current_thread.text contains 'SSA Statement Viewer'
    • strings.replace_confusables(body.current_thread.text) contains 'Social Security Statement'
    • body.current_thread.text matches '(?:view|open) (?:your|the).{0,8} (statement|document)'
    • body.current_thread.text matches '(?:view|open|assess|evaluate|review|conduct|read|scan)'
    • body.current_thread.text contains '1-800-772-1213'
    • any of body.links where:
      • any of regex.extract(.href_url.path) where:
        • .named_groups['ext'] in $file_extensions_executables
    • any of ml.logo_detect(file.message_screenshot()).brands where all hold:
      • .name is 'SSA'
      • .confidence is 'high'
    • any of attachments where all hold:
      • .file_type in ('doc', 'docx')
      • any of file.explode(.) where any holds:
        • .scan.strings.raw contains 'suspended'
        • .scan.strings.raw contains 'fraudulent'
        • .scan.strings.raw contains 'violated'
        • .scan.strings.raw contains 'false identity'
        • .scan.strings.raw matches any of 2 patterns
          • \+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}
          • \+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}
  5. none of:
    • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
      • .name in ('Newsletters and Digests', 'Advertising and Promotions', 'Events and Webinars', 'Charity and Non-Profit', 'Political Mail')
      • .confidence is 'high'
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'benign'
      • .confidence is 'high'
  6. not:
    • all of:
      • sender.email.email in ('email@email.monarch.com', 'contact@govplus.com')
      • coalesce(headers.auth_summary.dmarc.pass)
  7. any of:
    • headers.in_reply_to is missing
    • length(headers.references) is 0
  8. not:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • coalesce(headers.auth_summary.dmarc.pass)

Inspects: attachments[].file_type, body.current_thread.text, body.html, body.links, body.links[].display_url.domain.root_domain, body.links[].href_url.path, body.links[].href_url.url, body.links[].mismatched, headers.auth_summary.dmarc.pass, headers.in_reply_to, headers.references, sender.display_name, sender.email.domain.root_domain, sender.email.domain.tld, sender.email.email, subject.base, subject.subject, type.inbound. Sensors: file.explode, file.message_screenshot, html.xpath, ml.logo_detect, ml.nlu_classifier, regex.contains, regex.extract, regex.icontains, strings.contains, strings.icontains, strings.ilike, strings.replace_confusables. Reference lists: $file_extensions_executables, $high_trust_sender_root_domains.

Indicators matched (47)

FieldMatchValue
regex.containsregex^SSA\b
strings.icontainssubstringSocial Security Administration
strings.containssubstringSSA
regex.icontainsregexSocial (?:benefits|security|s.a\b)
strings.ilikesubstring*statement*
strings.icontainssubstringssa.gov
regex.icontainsregex1[\s\-\.]?\(?\s*800\s*\)?[\s\-\.]?772[\s\-\.]?1213
attachments[].file_typememberdoc
attachments[].file_typememberdocx
regex.icontainsregex(Digital|(e[[:punct:]]?))\s?Statements?.{0,10}(Generated|Created|Issued|Ready)
strings.icontainssubstringSocial Security
strings.icontainssubstringStatement
35 more
strings.icontainssubstringNotification
strings.icontainssubstringDocument
strings.icontainssubstringMessage
strings.icontainssubstringImportant Update
strings.icontainssubstringBenefit Amount
strings.icontainssubstringAccount
strings.icontainssubstringAuthorization
html.xpath(body.html, '//title').nodes[].inner_textequalsSocial Security Administration
html.xpath(body.html, '//title').nodes[].inner_textequalsSocial Security
strings.containssubstringssa.gov
body.links[].display_url.domain.root_domainequalsssa.gov
strings.icontainssubstringdownload monthly statement
strings.icontainssubstringstay connected
ml.nlu_classifier(body.current_thread.text).entities[].nameequalssender
ml.nlu_classifier(body.current_thread.text).entities[].textequalsSocial Security Administration
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).topics[].namememberSecurity and Authentication
ml.nlu_classifier(body.current_thread.text).topics[].namememberSecure Message
ml.nlu_classifier(body.current_thread.text).topics[].confidenceequalshigh
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsorg
ml.nlu_classifier(body.current_thread.text).entities[].textequalsSSA
strings.icontainssubstringSSA Statement Viewer
strings.icontainssubstringSocial Security Statement
regex.icontainsregex(?:view|open) (?:your|the).{0,8} (statement|document)
regex.icontainsregex(?:view|open|assess|evaluate|review|conduct|read|scan)
strings.icontainssubstring1-800-772-1213
regex.extractregex\.(?P<ext>[^./?#]+)(?:[?#]|$)
ml.logo_detect(file.message_screenshot()).brands[].nameequalsSSA
ml.logo_detect(file.message_screenshot()).brands[].confidenceequalshigh
strings.icontainssubstringsuspended
strings.icontainssubstringfraudulent
strings.icontainssubstringviolated
strings.icontainssubstringfalse identity
regex.icontainsregex\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}
regex.icontainsregex\+?([ilo0-9]{1,2})?\s?\(?\d{3}\)?[\s\.\-⋅]{0,5}[ilo0-9]{3}[\s\.\-⋅]{0,5}[ilo0-9]{4}

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      any(body.links)
        or
          and
            body.links.display_url.domain.root_domain eq "ssa.gov"
            body.links.mismatched eq "true"
          body.links.href_url.url contains "ssa.gov"
      body.current_thread.text contains "download monthly statement"
      body.current_thread.text contains "stay connected"
    any(html.xpath(body.html, '//title').nodes)
      or
        and
          or
            html.xpath(body.html, '//title').nodes.inner_text contains "Account"
            html.xpath(body.html, '//title').nodes.inner_text contains "Authorization"
            html.xpath(body.html, '//title').nodes.inner_text contains "Benefit Amount"
            html.xpath(body.html, '//title').nodes.inner_text contains "Document"
            html.xpath(body.html, '//title').nodes.inner_text contains "Important Update"
            html.xpath(body.html, '//title').nodes.inner_text contains "Message"
            html.xpath(body.html, '//title').nodes.inner_text contains "Notification"
            html.xpath(body.html, '//title').nodes.inner_text contains "Statement"
          html.xpath(body.html, '//title').nodes.inner_text contains "Social Security"
        html.xpath(body.html, '//title').nodes.inner_text eq "Social Security Administration"
        html.xpath(body.html, '//title').nodes.inner_text eq "Social Security"
    any(attachments)
      and
        any(file.explode(attachments))
          file.explode(attachments).scan.strings.raw contains "Social Security Administration"
        attachments.file_type in ["doc", "docx"]
    and
      any(ml.nlu_classifier(body.current_thread.text).entities)
        and
          ml.nlu_classifier(body.current_thread.text).entities.name eq "sender"
          ml.nlu_classifier(body.current_thread.text).entities.text eq "Social Security Administration"
      any(ml.nlu_classifier(body.current_thread.text).intents)
        and
          ml.nlu_classifier(body.current_thread.text).intents.confidence ne "low"
          ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
    and
      or
        body.current_thread.text contains "ssa.gov"
        body.current_thread.text regex_match "1[\\s\\-\\.]?\\(?\\s*800\\s*\\)?[\\s\\-\\.]?772[\\s\\-\\.]?1213"
      subject.base match "statement"
    and
      any([sender.display_name, subject.subject])
        strings.replace_confusables([sender.display_name, subject.subject][]) regex_match "(Digital|(e[[:punct:]]?))\\s?Statements?.{0,10}(Generated|Created|Issued|Ready)"
      body.current_thread.text contains "Social Security Administration"
    and
      strings.replace_confusables func_call "strings.replace_confusables(sender.display_name) != sender.display_name"
      strings.replace_confusables(sender.display_name) contains "SSA"
    any([sender.display_name, subject.subject])
      strings.replace_confusables([sender.display_name, subject.subject][]) regex_match "Social (?:benefits|security|s.a\\b)"
    sender.display_name contains "Social Security Administration"
    sender.display_name regex_match "^SSA\\b"
  or
    any(attachments)
      and
        any(file.explode(attachments))
          or
            file.explode(attachments[])[].scan.strings.raw contains "false identity"
            file.explode(attachments[])[].scan.strings.raw contains "fraudulent"
            file.explode(attachments[])[].scan.strings.raw contains "suspended"
            file.explode(attachments[])[].scan.strings.raw contains "violated"
            file.explode(attachments[])[].scan.strings.raw regex_match "\\+?([ilo0-9]{1,2})?\\s?\\(?\\d{3}\\)?[\\s\\.\\-⋅]{0,5}[ilo0-9]{3}[\\s\\.\\-⋅]{0,5}[ilo0-9]{4}"
            file.explode(attachments[])[].scan.strings.raw regex_match "\\+?([ilo0-9]{1}.)?\\(?[ilo0-9]{3}?\\)?.[ilo0-9]{3}.?[ilo0-9]{4}"
        attachments.file_type in ["doc", "docx"]
    any(ml.logo_detect(file.message_screenshot()).brands)
      and
        ml.logo_detect(file.message_screenshot()).brands.confidence eq "high"
        ml.logo_detect(file.message_screenshot()).brands.name eq "SSA"
    any(ml.nlu_classifier(body.current_thread.text).entities)
      and
        ml.nlu_classifier(body.current_thread.text).entities.name eq "org"
        ml.nlu_classifier(body.current_thread.text).entities.text eq "SSA"
    any(ml.nlu_classifier(body.current_thread.text).topics)
      and
        ml.nlu_classifier(body.current_thread.text).topics.confidence eq "high"
        ml.nlu_classifier(body.current_thread.text).topics.name in ["Secure Message", "Security and Authentication"]
    any(body.links)
      any(regex.extract(body.links.href_url.path))
         macro "regex.extract(body.links[].href_url.path)[].named_groups['ext'] in file_extensions_executables"
    body.current_thread.text contains "1-800-772-1213"
    body.current_thread.text contains "SSA Statement Viewer"
    body.current_thread.text is_null
    body.current_thread.text length_compare "0"
    body.current_thread.text regex_match "(?:view|open) (?:your|the).{0,8} (statement|document)"
    body.current_thread.text regex_match "(?:view|open|assess|evaluate|review|conduct|read|scan)"
    strings.replace_confusables(body.current_thread.text) contains "Social Security Statement"
  not
    or
      any(ml.nlu_classifier(body.current_thread.text).intents)
        and
          ml.nlu_classifier(body.current_thread.text).intents.confidence eq "high"
          ml.nlu_classifier(body.current_thread.text).intents.name eq "benign"
      any(ml.nlu_classifier(body.current_thread.text).topics)
        and
          ml.nlu_classifier(body.current_thread.text).topics.confidence eq "high"
          ml.nlu_classifier(body.current_thread.text).topics.name in ["Advertising and Promotions", "Charity and Non-Profit", "Events and Webinars", "Newsletters and Digests", "Political Mail"]
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
      sender.email.email in ["contact@govplus.com", "email@email.monarch.com"]
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.tld eq "gov"
  or
    headers.in_reply_to is_null
    headers.references length_compare "0"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
ml.nlu_classifier(body.current_thread.text).intentsarray_any(no value, null check)excludes:ml.nlu_classifier(body.current_thread.text).intents
ml.nlu_classifier(body.current_thread.text).topicsarray_any(no value, null check)excludes:ml.nlu_classifier(body.current_thread.text).topics
sender.email.emailincontact@govplus.com, email@email.monarch.comexcludes:sender.email.email field:"sender.email.email" value:"contact@govplus.com" field:"sender.email.email" value:"email@email.monarch.com"
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
sender.email.domain.tldeqgovexcludes:sender.email.domain.tld field:"sender.email.domain.tld" value:"gov"

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Spotify

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

Impersonation of Spotify.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  strings.ilike(sender.display_name, '*spotify*')
  or strings.ilevenshtein(sender.display_name, 'spotify') <= 1
  or strings.ilike(sender.email.domain.domain, '*spotify*')
  or (
    regex.icontains(body.current_thread.text, 'Spotify AB\b')
    and any(ml.logo_detect(file.message_screenshot()).brands,
            .name == "Spotify" and .confidence != "low"
    )
  )
)
and sender.email.domain.root_domain not in~ (
  'spotify.com',
  'byspotify.com',
  'echosign.com',
  'fromspotify.com',
  'anchor.fm'
)
and sender.email.domain.domain not in~ ('privaterelay.appleid.com')
and (
  profile.by_sender().prevalence in ("new", "outlier")
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)

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

Impersonation of Spotify.

  1. inbound message
  2. any of:
    • sender.display_name matches '*spotify*'
    • sender.display_name is similar to 'spotify'
    • sender.email.domain.domain matches '*spotify*'
    • all of:
      • body.current_thread.text matches 'Spotify AB\\b'
      • any of ml.logo_detect(file.message_screenshot()).brands where all hold:
        • .name is 'Spotify'
        • .confidence is not 'low'
  3. sender.email.domain.root_domain not in ('spotify.com', 'byspotify.com', 'echosign.com', 'fromspotify.com', 'anchor.fm')
  4. sender.email.domain.domain not in ('privaterelay.appleid.com')
  5. any of:
    • profile.by_sender().prevalence in ('new', 'outlier')
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  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, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: file.message_screenshot, ml.logo_detect, profile.by_sender, regex.icontains, strings.ilevenshtein, strings.ilike. Reference lists: $high_trust_sender_root_domains.

Indicators matched (4)

FieldMatchValue
strings.ilikesubstring*spotify*
strings.ilevenshteinfuzzyspotify
regex.icontainsregexSpotify AB\b
ml.logo_detect(file.message_screenshot()).brands[].nameequalsSpotify

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      any(ml.logo_detect(file.message_screenshot()).brands)
        and
          ml.logo_detect(file.message_screenshot()).brands.confidence ne "low"
          ml.logo_detect(file.message_screenshot()).brands.name eq "Spotify"
      body.current_thread.text regex_match "Spotify AB\\b"
    sender.display_name match "spotify"
    sender.email.domain.domain match "spotify"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"spotify\") <= 1"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    profile.by_sender func_call "profile.by_sender().prevalence in (new, outlier)"
  not
    sender.email.domain.domain eq "privaterelay.appleid.com"
  not
    sender.email.domain.root_domain in ["anchor.fm", "byspotify.com", "echosign.com", "fromspotify.com", "spotify.com"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.domaineqprivaterelay.appleid.comexcludes:sender.email.domain.domain field:"sender.email.domain.domain" value:"privaterelay.appleid.com"
sender.email.domain.root_domaininanchor.fm, byspotify.com, echosign.com, fromspotify.com, spotify.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Stellar Development Foundation (SDF)

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

Attack impersonating Stellar Development Foundation (SDF).

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • sender.email
  • type

Rule body

type.inbound
and regex.imatch(sender.display_name, '\bstellar\b')
and sender.email.domain.root_domain != "stellar.org"
and (
  not profile.by_sender().solicited
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)

Detection logic

Scope: inbound message.

Attack impersonating Stellar Development Foundation (SDF).

  1. inbound message
  2. sender.display_name matches '\\bstellar\\b'
  3. sender.email.domain.root_domain is not 'stellar.org'
  4. any of:
    • not:
      • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign

Inspects: sender.display_name, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender, regex.imatch.

Indicators matched (1)

FieldMatchValue
regex.imatchregex\bstellar\b

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    not
      profile.by_sender func_call "profile.by_sender().solicited"
  sender.display_name regex_match "\\bstellar\\b"
  sender.email.domain.root_domain ne "stellar.org"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Brand Impersonation: Stripe

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

Impersonation of Stripe, usually for credential theft.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • headers
  • headers.auth_summary
  • headers.hops
  • sender.email
  • type

Rule body

type.inbound
and (
  // Display name after replacing unicode confusables is stripe
  (
    sender.display_name =~ 'stripe'
    or (
      strings.istarts_with(sender.display_name, 'stripe ')
      and not sender.display_name in~ (
        'Stripe & Stare',
        'Stripe and Stare',
        'Stripe Events'
      )
    )
    or strings.replace_confusables(sender.display_name) =~ 'stripe'
    // fake stripe invoice in attached picture
    or (
      any(attachments,
          .file_type in $file_types_images
          and any(file.explode(.),
                  strings.ilike(.scan.ocr.raw, "*stripe*")
                  and any(ml.nlu_classifier(.scan.ocr.raw).intents,
                          .name in ("callback_scam")
                          and .confidence in ("medium", "high")
                  )
          )
      )
    )
  )
  or (
    // the edit distance is 1 or 2
    strings.ilevenshtein(strings.replace_confusables(sender.display_name),
                         'stripe'
    ) <= 2
    // the length is the same as "stripe"
    and length(sender.display_name) == 6
    // and not one of these english words that matches the edit distance
    and not sender.display_name in~ (
      "strive",
      "stride",
      "strife",
      "strike",
      "strobe",
      "stroke",
      "streps",
      "string",
      "scribe",
      "straye", // a shoe company?
      "storie", // storiesbystorie.com
      "stryke", // a cybersecurity and compliance company
      "stryve", // a food/snack company stryve.com
      "shrine", // common word
      "s.ride", // cab/taxi company
      "striim", // ai/data company
      "striim.com", // same as above
      "skribe" // ai/legal company
    )
  )
)
and not (
  sender.email.domain.root_domain in~ (
    'stripe.com',
    'stripetour.com',
    'stripepress.com'
  )
  and coalesce(headers.auth_summary.dmarc.pass, false)
)
and sender.email.email not in $recipient_emails

// Stripe adds a custom header
// don't match messages with the header
and not any(headers.hops, any(.fields, .name == "X-Stripe-EID"))

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

Impersonation of Stripe, usually for credential theft.

  1. inbound message
  2. any of:
    • any of:
      • sender.display_name is 'stripe'
      • all of:
        • sender.display_name starts with 'stripe '
        • not:
          • sender.display_name in ('Stripe & Stare', 'Stripe and Stare', 'Stripe Events')
      • strings.replace_confusables(sender.display_name) is 'stripe'
      • any of attachments where all hold:
        • .file_type in $file_types_images
        • any of file.explode(.) where all hold:
          • .scan.ocr.raw matches '*stripe*'
          • any of ml.nlu_classifier(.scan.ocr.raw).intents where all hold:
            • .name in ('callback_scam')
            • .confidence in ('medium', 'high')
    • all of:
      • strings.replace_confusables(sender.display_name) is similar to 'stripe'
      • length(sender.display_name) is 6
      • not:
        • sender.display_name in ('strive', 'stride', 'strife', 'strike', 'strobe', 'stroke', 'streps', 'string', 'scribe', 'straye', 'storie', 'stryke', 'stryve', 'shrine', 's.ride', 'striim', 'striim.com', 'skribe')
  3. not:
    • all of:
      • sender.email.domain.root_domain in ('stripe.com', 'stripetour.com', 'stripepress.com')
      • coalesce(headers.auth_summary.dmarc.pass)
  4. sender.email.email not in $recipient_emails
  5. not:
    • any of headers.hops where:
      • any of .fields where:
        • .name is 'X-Stripe-EID'
  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: attachments[].file_type, headers.auth_summary.dmarc.pass, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, sender.display_name, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: file.explode, ml.nlu_classifier, strings.ilevenshtein, strings.ilike, strings.istarts_with, strings.replace_confusables. Reference lists: $file_types_images, $high_trust_sender_root_domains, $recipient_emails.

Indicators matched (7)

FieldMatchValue
sender.display_nameequalsstripe
strings.istarts_withprefixstripe
strings.ilikesubstring*stripe*
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].namemembercallback_scam
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidencemembermedium
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidencememberhigh
strings.ilevenshteinfuzzystripe

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(attachments)
      and
        any(file.explode(attachments))
          and
            any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).intents)
              and
                ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidence in ["high", "medium"]
                ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].name eq "callback_scam"
            file.explode(attachments[])[].scan.ocr.raw match "stripe"
         macro "attachments[].file_type in file_types_images"
    and
      not
        sender.display_name in ["Stripe & Stare", "Stripe Events", "Stripe and Stare"]
      sender.display_name starts_with "stripe "
    and
      not
        sender.display_name in ["s.ride", "scribe", "shrine", "skribe", "storie", "straye", "streps", "stride", "strife", "striim", "striim.com", "strike", "string", "strive", "strobe", "stroke", "stryke", "stryve"]
      sender.display_name length_compare "6"
      strings.ilevenshtein func_call "strings.ilevenshtein(strings.replace_confusables(sender.display_name), \"stripe\") <= 2"
    sender.display_name eq "stripe"
    strings.replace_confusables func_call "strings.replace_confusables(sender.display_name) =~ stripe"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    any(headers.hops)
      any(headers.hops.fields)
        headers.hops.fields.name eq "X-Stripe-EID"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
      sender.email.domain.root_domain in ["stripe.com", "stripepress.com", "stripetour.com"]
  type.inbound eq "true"
   macro "sender.email.email not in recipient_emails"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Sublime Security

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

Possible attempt to impersonate Sublime Security executives.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  sender.display_name in~ (
    'Sublime Security',
    'Josh Kamdjou',
    'Joshua Kamdjou',
    'Ian Thiel'
  )
  or strings.ilevenshtein(sender.email.domain.domain, 'sublimesecurity.com') <= 2
)
and sender.email.domain.root_domain not in (
  'sublimesecurity.com',
  'luma-mail.com',
  'modernloop.io',
  'tabsplatform.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.

Possible attempt to impersonate Sublime Security executives.

  1. inbound message
  2. any of:
    • sender.display_name in ('Sublime Security', 'Josh Kamdjou', 'Joshua Kamdjou', 'Ian Thiel')
    • sender.email.domain.domain is similar to 'sublimesecurity.com'
  3. sender.email.domain.root_domain not in ('sublimesecurity.com', 'luma-mail.com', 'modernloop.io', 'tabsplatform.com')
  4. 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: headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: strings.ilevenshtein. Reference lists: $high_trust_sender_root_domains.

Indicators matched (5)

FieldMatchValue
sender.display_namememberSublime Security
sender.display_namememberJosh Kamdjou
sender.display_namememberJoshua Kamdjou
sender.display_namememberIan Thiel
strings.ilevenshteinfuzzysublimesecurity.com

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    sender.display_name in ["Ian Thiel", "Josh Kamdjou", "Joshua Kamdjou", "Sublime Security"]
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.email.domain.domain, \"sublimesecurity.com\") <= 2"
  not
    sender.email.domain.root_domain in ["luma-mail.com", "modernloop.io", "sublimesecurity.com", "tabsplatform.com"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaininluma-mail.com, modernloop.io, sublimesecurity.com, tabsplatform.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
sender.display_namein
  • Ian Thiel
  • Josh Kamdjou
  • Joshua Kamdjou
  • Sublime Security
field:"sender.display_name" kind:in
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: TurboTax

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

Impersonation of the TurboTax service from Intuit. Most commonly seen around US tax season (Q1).

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  strings.ilike(sender.display_name, '*turbotax*')
  or (
    strings.ilevenshtein(sender.display_name, 'turbotax') <= 1
    // negates FP for company called TurboTan
    and not (
      sender.display_name == "TurboTan"
      and sender.email.domain.root_domain == "brevosend.com"
      and headers.auth_summary.spf.pass
    )
  )
  or strings.ilike(sender.email.domain.domain, '*turbotax*')
)
and sender.email.domain.root_domain not in (
  'intuit.com',
  'turbotax.com',
  'intuit.ca',
  'truist.com' // Truist partners with Intuit to provide discounts
)
and sender.email.email not in $recipient_emails

// negates survery service used by TurboTax
and not (
  sender.email.domain.root_domain in ('qemailserver.com')
  and headers.auth_summary.spf.pass
  and any(body.links,
          .href_url.domain.root_domain in ("qualtrics.com", "intuit.com")
  )
)

Detection logic

Scope: inbound message.

Impersonation of the TurboTax service from Intuit. Most commonly seen around US tax season (Q1).

  1. inbound message
  2. any of:
    • sender.display_name matches '*turbotax*'
    • all of:
      • sender.display_name is similar to 'turbotax'
      • not:
        • all of:
          • sender.display_name is 'TurboTan'
          • sender.email.domain.root_domain is 'brevosend.com'
          • headers.auth_summary.spf.pass
    • sender.email.domain.domain matches '*turbotax*'
  3. sender.email.domain.root_domain not in ('intuit.com', 'turbotax.com', 'intuit.ca', 'truist.com')
  4. sender.email.email not in $recipient_emails
  5. not:
    • all of:
      • sender.email.domain.root_domain in ('qemailserver.com')
      • headers.auth_summary.spf.pass
      • any of body.links where:
        • .href_url.domain.root_domain in ('qualtrics.com', 'intuit.com')

Inspects: body.links, body.links[].href_url.domain.root_domain, headers.auth_summary.spf.pass, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: strings.ilevenshtein, strings.ilike. Reference lists: $recipient_emails.

Indicators matched (2)

FieldMatchValue
strings.ilikesubstring*turbotax*
strings.ilevenshteinfuzzyturbotax

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        and
          headers.auth_summary.spf.pass eq "true"
          sender.display_name eq "TurboTan"
          sender.email.domain.root_domain eq "brevosend.com"
      strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"turbotax\") <= 1"
    sender.display_name match "turbotax"
    sender.email.domain.domain match "turbotax"
  not
    and
      any(body.links)
        body.links.href_url.domain.root_domain in ["intuit.com", "qualtrics.com"]
      headers.auth_summary.spf.pass eq "true"
      sender.email.domain.root_domain eq "qemailserver.com"
  not
    sender.email.domain.root_domain in ["intuit.ca", "intuit.com", "truist.com", "turbotax.com"]
  type.inbound eq "true"
   macro "sender.email.email not in recipient_emails"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
body.linksarray_any(no value, null check)excludes:body.links
headers.auth_summary.spf.passeqtrueexcludes:headers.auth_summary.spf.pass field:"headers.auth_summary.spf.pass" value:"true"
sender.email.domain.root_domaineqqemailserver.comexcludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"qemailserver.com"
sender.email.domain.root_domaininintuit.ca, intuit.com, truist.com, turbotax.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Twitter

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

Impersonation of Twitter.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.links
  • headers
  • sender.email
  • type

Rule body

type.inbound
and (
  // Twitter logic
  (
    sender.display_name =~ "twitter"
    or strings.ilevenshtein(sender.display_name, 'twitter') <= 1
    or strings.ilike(sender.email.domain.domain, '*twitter*')
  )
  // "X" logic
  or (
    (
      3 of (
        strings.iends_with(sender.email.domain.root_domain, "-x.com"),
        strings.icontains(sender.email.local_part, "x-corp"),
        any(body.links,
            strings.iends_with(.href_url.domain.root_domain, "-x.com")
            or strings.istarts_with(.href_url.domain.subdomain, "x-corp")
        ),
        strings.ilike(body.current_thread.text,
                      "*content dispute*",
                      "*copyright*",
                      "*appeal*"
        ),
        strings.contains(body.current_thread.text, '1355 Market Street'),
        strings.contains(body.current_thread.text, 'San Francisco, CA 94103'),
        strings.contains(body.current_thread.text, 'X Corp'),
        strings.ilike(body.current_thread.text, '*865 FM 1209*bastrop*')
      )
      or (
        length(ml.logo_detect(file.message_screenshot()).brands) == 1
        and any(ml.logo_detect(file.message_screenshot()).brands,
                .name == "X" and .confidence == "high"
        )
        and (
          any(ml.nlu_classifier(body.current_thread.text).intents,
              .name == "cred_theft" and .confidence == "high"
          )
          or any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents,
                 .name == "cred_theft" and .confidence == "high"
          )
        )
      )
    )
    and any(beta.ml_topic(body.current_thread.text).topics,
            .name in (
              "Reminders and Notifications",
              "Security and Authentication",
              "Legal and Compliance",
              "Customer Service and Support"
            )
    )
  )
)
and sender.email.domain.domain not in~ (
  'twitter.com',
  'privaterelay.appleid.com',
  'stripe.com',
  'x.com',
  'twitter.discoursemail.com',
  'slack.com'
)
// negate Hearsay Systems which sends notifications from sender domain ending in twitter.com
and not (
  strings.ends_with(sender.email.domain.domain, '.hearsay.twitter.com')
  and strings.ends_with(headers.message_id, '@hearsaysystems.com>')
)
and sender.email.email not in $recipient_emails

Detection logic

Scope: inbound message.

Impersonation of Twitter.

  1. inbound message
  2. any of:
    • any of:
      • sender.display_name is 'twitter'
      • sender.display_name is similar to 'twitter'
      • sender.email.domain.domain matches '*twitter*'
    • all of:
      • any of:
        • at least 3 of:
          • sender.email.domain.root_domain ends with '-x.com'
          • sender.email.local_part contains 'x-corp'
          • any of body.links where any holds:
            • .href_url.domain.root_domain ends with '-x.com'
            • .href_url.domain.subdomain starts with 'x-corp'
          • body.current_thread.text matches any of 3 patterns
            • *content dispute*
            • *copyright*
            • *appeal*
          • body.current_thread.text contains '1355 Market Street'
          • body.current_thread.text contains 'San Francisco, CA 94103'
          • body.current_thread.text contains 'X Corp'
          • body.current_thread.text matches '*865 FM 1209*bastrop*'
        • all of:
          • length(ml.logo_detect(file.message_screenshot()).brands) is 1
          • any of ml.logo_detect(file.message_screenshot()).brands where all hold:
            • .name is 'X'
            • .confidence is 'high'
          • any of:
            • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
              • .name is 'cred_theft'
              • .confidence is 'high'
            • any of ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents where all hold:
              • .name is 'cred_theft'
              • .confidence is 'high'
      • any of beta.ml_topic(body.current_thread.text).topics where:
        • .name in ('Reminders and Notifications', 'Security and Authentication', 'Legal and Compliance', 'Customer Service and Support')
  3. sender.email.domain.domain not in ('twitter.com', 'privaterelay.appleid.com', 'stripe.com', 'x.com', 'twitter.discoursemail.com', 'slack.com')
  4. not:
    • all of:
      • sender.email.domain.domain ends with '.hearsay.twitter.com'
      • headers.message_id ends with '@hearsaysystems.com>'
  5. sender.email.email not in $recipient_emails

Inspects: body.current_thread.text, body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.subdomain, headers.message_id, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.email, sender.email.local_part, type.inbound. Sensors: beta.ml_topic, beta.ocr, file.message_screenshot, ml.logo_detect, ml.nlu_classifier, strings.contains, strings.ends_with, strings.icontains, strings.iends_with, strings.ilevenshtein, strings.ilike, strings.istarts_with. Reference lists: $recipient_emails.

Indicators matched (23)

FieldMatchValue
sender.display_nameequalstwitter
strings.ilevenshteinfuzzytwitter
strings.ilikesubstring*twitter*
strings.iends_withsuffix-x.com
strings.icontainssubstringx-corp
strings.istarts_withprefixx-corp
strings.ilikesubstring*content dispute*
strings.ilikesubstring*copyright*
strings.ilikesubstring*appeal*
strings.containssubstring1355 Market Street
strings.containssubstringSan Francisco, CA 94103
strings.containssubstringX Corp
11 more
strings.ilikesubstring*865 FM 1209*bastrop*
ml.logo_detect(file.message_screenshot()).brands[].nameequalsX
ml.logo_detect(file.message_screenshot()).brands[].confidenceequalshigh
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents[].nameequalscred_theft
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents[].confidenceequalshigh
beta.ml_topic(body.current_thread.text).topics[].namememberReminders and Notifications
beta.ml_topic(body.current_thread.text).topics[].namememberSecurity and Authentication
beta.ml_topic(body.current_thread.text).topics[].namememberLegal and Compliance
beta.ml_topic(body.current_thread.text).topics[].namememberCustomer Service and Support

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      or
        and
          or
            any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents)
              and
                ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents.confidence eq "high"
                ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents.name eq "cred_theft"
            any(ml.nlu_classifier(body.current_thread.text).intents)
              and
                ml.nlu_classifier(body.current_thread.text).intents.confidence eq "high"
                ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
          any(ml.logo_detect(file.message_screenshot()).brands)
            and
              ml.logo_detect(file.message_screenshot()).brands.confidence eq "high"
              ml.logo_detect(file.message_screenshot()).brands.name eq "X"
          ml.logo_detect(file.message_screenshot()).brands length_compare "1"
        any(body.links)
          or
            body.links.href_url.domain.root_domain ends_with "-x.com"
            body.links.href_url.domain.subdomain starts_with "x-corp"
        body.current_thread.text contains "1355 Market Street"
        body.current_thread.text contains "San Francisco, CA 94103"
        body.current_thread.text contains "X Corp"
        body.current_thread.text match "appeal"
        body.current_thread.text match "content dispute"
        body.current_thread.text match "copyright"
        body.current_thread.text wildcard "*865 FM 1209*bastrop*"
        sender.email.domain.root_domain ends_with "-x.com"
        sender.email.local_part contains "x-corp"
      any(beta.ml_topic(body.current_thread.text).topics)
        beta.ml_topic(body.current_thread.text).topics.name in ["Customer Service and Support", "Legal and Compliance", "Reminders and Notifications", "Security and Authentication"]
    sender.display_name eq "twitter"
    sender.email.domain.domain match "twitter"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"twitter\") <= 1"
  not
    and
      headers.message_id ends_with "@hearsaysystems.com>"
      sender.email.domain.domain ends_with ".hearsay.twitter.com"
  not
    sender.email.domain.domain in ["privaterelay.appleid.com", "slack.com", "stripe.com", "twitter.com", "twitter.discoursemail.com", "x.com"]
  type.inbound eq "true"
   macro "sender.email.email not in recipient_emails"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.message_idends_with@hearsaysystems.com>excludes:headers.message_id field:"headers.message_id" value:"@hearsaysystems.com>"
sender.email.domain.domainends_with.hearsay.twitter.comexcludes:sender.email.domain.domain field:"sender.email.domain.domain" value:".hearsay.twitter.com"
sender.email.domain.domaininprivaterelay.appleid.com, slack.com, stripe.com, twitter.com, twitter.discoursemail.com, x.comexcludes:sender.email.domain.domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: ukr[.]net

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

Impersonation of ukr[.]net. Originally reported by CERT-UA on 07 March, 2022, phishing emails impersonate ukr[.]net to steal user credentials. "Compromised mailboxes are used by the Russian Federation's special services to conduct cyber attacks on citizens of Ukraine."

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  (
    // technique
    strings.ilike(sender.display_name, "ukr*net")
    and sender.email.domain.root_domain != "ukr.net"
  )
  or (
    // IOCs
    subject.subject == "Увага"
    and (
      sender.email.email in (
        "muthuprakash.b@tvsrubber.com",
        "rakesh.ict@msruas.ac.in",
        "omars@salecharter.net",
        "citi.in.pm@xerago.com",
        "qs@gsengint.com",
        "sec.ls@msruas.ac.in",
        "vaishnavi.kj@tvsrubber.com",
        "nshcorp@nshcorp.in",
        "purchase2@hitechelastomers.com",
        "productionbelgavi@hodekindia.com",
        "narayanababu.py.ph@msruas.ac.in",
        "roopa.tsld@msruas.ac.in",
        "in-nonciti.basupport@xerago.com",
        "info@empiink.com",
        "pooja.fa@msruas.ac.in",
        "babu.d@tvsrubber.com",
        "systeam@xerago.com",
        "dean.ds@msruas.ac.in",
      )
      or any(body.links, .href_url.domain.domain == "consumerspanel.frge.io")
    )
  )
)

Detection logic

Scope: inbound message.

Impersonation of ukr[.]net. Originally reported by CERT-UA on 07 March, 2022, phishing emails impersonate ukr[.]net to steal user credentials. "Compromised mailboxes are used by the Russian Federation's special services to conduct cyber attacks on citizens of Ukraine."

  1. inbound message
  2. any of:
    • all of:
      • sender.display_name matches 'ukr*net'
      • sender.email.domain.root_domain is not 'ukr.net'
    • all of:
      • subject.subject is 'Увага'
      • any of:
        • sender.email.email in ('muthuprakash.b@tvsrubber.com', 'rakesh.ict@msruas.ac.in', 'omars@salecharter.net', 'citi.in.pm@xerago.com', 'qs@gsengint.com', 'sec.ls@msruas.ac.in', 'vaishnavi.kj@tvsrubber.com', 'nshcorp@nshcorp.in', 'purchase2@hitechelastomers.com', 'productionbelgavi@hodekindia.com', 'narayanababu.py.ph@msruas.ac.in', 'roopa.tsld@msruas.ac.in', 'in-nonciti.basupport@xerago.com', 'info@empiink.com', 'pooja.fa@msruas.ac.in', 'babu.d@tvsrubber.com', 'systeam@xerago.com', 'dean.ds@msruas.ac.in')
        • any of body.links where:
          • .href_url.domain.domain is 'consumerspanel.frge.io'

Inspects: body.links, body.links[].href_url.domain.domain, sender.display_name, sender.email.domain.root_domain, sender.email.email, subject.subject, type.inbound. Sensors: strings.ilike.

Indicators matched (21)

FieldMatchValue
strings.ilikesubstringukr*net
subject.subjectequalsУвага
sender.email.emailmembermuthuprakash.b@tvsrubber.com
sender.email.emailmemberrakesh.ict@msruas.ac.in
sender.email.emailmemberomars@salecharter.net
sender.email.emailmemberciti.in.pm@xerago.com
sender.email.emailmemberqs@gsengint.com
sender.email.emailmembersec.ls@msruas.ac.in
sender.email.emailmembervaishnavi.kj@tvsrubber.com
sender.email.emailmembernshcorp@nshcorp.in
sender.email.emailmemberpurchase2@hitechelastomers.com
sender.email.emailmemberproductionbelgavi@hodekindia.com
9 more
sender.email.emailmembernarayanababu.py.ph@msruas.ac.in
sender.email.emailmemberroopa.tsld@msruas.ac.in
sender.email.emailmemberin-nonciti.basupport@xerago.com
sender.email.emailmemberinfo@empiink.com
sender.email.emailmemberpooja.fa@msruas.ac.in
sender.email.emailmemberbabu.d@tvsrubber.com
sender.email.emailmembersysteam@xerago.com
sender.email.emailmemberdean.ds@msruas.ac.in
body.links[].href_url.domain.domainequalsconsumerspanel.frge.io

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      or
        any(body.links)
          body.links.href_url.domain.domain eq "consumerspanel.frge.io"
        sender.email.email in ["babu.d@tvsrubber.com", "citi.in.pm@xerago.com", "dean.ds@msruas.ac.in", "in-nonciti.basupport@xerago.com", "info@empiink.com", "muthuprakash.b@tvsrubber.com", "narayanababu.py.ph@msruas.ac.in", "nshcorp@nshcorp.in", "omars@salecharter.net", "pooja.fa@msruas.ac.in", "productionbelgavi@hodekindia.com", "purchase2@hitechelastomers.com", "qs@gsengint.com", "rakesh.ict@msruas.ac.in", "roopa.tsld@msruas.ac.in", "sec.ls@msruas.ac.in", "systeam@xerago.com", "vaishnavi.kj@tvsrubber.com"]
      subject.subject eq "Увага"
    and
      sender.display_name wildcard "ukr*net"
      sender.email.domain.root_domain ne "ukr.net"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
sender.display_namewildcard
  • ukr*net
field:"sender.display_name" kind:wildcard value:"ukr*net"
sender.email.domain.root_domainne
  • ukr.net
field:"sender.email.domain.root_domain" kind:ne value:"ukr.net"
sender.email.emailin
  • babu.d@tvsrubber.com
  • citi.in.pm@xerago.com
  • dean.ds@msruas.ac.in
  • in-nonciti.basupport@xerago.com
  • info@empiink.com
  • muthuprakash.b@tvsrubber.com
  • narayanababu.py.ph@msruas.ac.in
  • nshcorp@nshcorp.in
  • omars@salecharter.net
  • pooja.fa@msruas.ac.in
  • productionbelgavi@hodekindia.com
  • purchase2@hitechelastomers.com
  • qs@gsengint.com
  • rakesh.ict@msruas.ac.in
  • roopa.tsld@msruas.ac.in
  • sec.ls@msruas.ac.in
  • systeam@xerago.com
  • vaishnavi.kj@tvsrubber.com
field:"sender.email.email" kind:in
subject.subjecteq
  • Увага
field:"subject.subject" kind:eq value:"Увага"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: United Healthcare

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

Detects messages impersonating United Healthcare (UHC) by analyzing display names that contain variations of 'United Healthcare' or 'UHC', including those with character substitutions. The rule excludes legitimate messages from verified UHC domains that pass DMARC authentication and handles high-trust sender domains appropriately.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  // display name contains UHC
  (
    strings.ilike(strings.replace_confusables(sender.display_name),
                  '*united healthcare*'
    )
    or strings.ilike(strings.replace_confusables(sender.display_name), 'UHC*')
    or regex.icontains(sender.display_name, 'united ?health ?care')
  )
  // levenshtein distance similar to UHC
  or strings.ilevenshtein(strings.replace_confusables(sender.display_name),
                          'united healthcare'
  ) <= 1
  or (
    regex.icontains(body.current_thread.text, 'united ?health ?care')
    and (
      regex.icontains(body.current_thread.text, 'quick .{0,10}survey')
      // Free benefits/items lure commonly used in UHC impersonation
      or regex.icontains(body.current_thread.text,
                         'dental (benefits?|coverage).{0,50}(free|eligible|no.{0,10}cost)'
      )
      or regex.icontains(body.current_thread.text,
                         'free.{0,30}(toothbrush|dental|benefit)'
      )
    )
  )
  // Brand name in sender local part from non-UHC domain
  or (
    strings.icontains(sender.email.local_part, "unitedhealthcare")
    and sender.email.domain.root_domain not in (
      "uhc.com",
      "unitedhealthcare.com",
      "uhcmedicaresolutions.com",
      "unitedhealthcareupdate.com",
      "yourhealth-wellnessteam.com",
      "uhc-customer.com",
      "leavesource.com"
    )
  )
)
// and the sender is not in org_domains or from UHC domains and passes auth
and not (
  sender.email.domain.root_domain in $org_domains
  or (
    (
      sender.email.domain.root_domain in (
        "uhc.com",
        "unitedhealthcare.com",
        "uhcmedicaresolutions.com",
        "unitedhealthcareupdate.com",
        "yourhealth-wellnessteam.com",
        "uhc-customer.com",
        "leavesource.com"
      )
      or sender.display_name in (
        "UHCOM Faculty Affairs",
        "UHC Construction Services"
      )
    )
    and headers.auth_summary.dmarc.pass
  )
)
// negate UHC job related posting
and not any(ml.nlu_classifier(body.current_thread.text).topics,
            .name == "Professional and Career Development"
            and .confidence == "high"
)
// and the sender is not from high trust sender root domains
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.

Detects messages impersonating United Healthcare (UHC) by analyzing display names that contain variations of 'United Healthcare' or 'UHC', including those with character substitutions. The rule excludes legitimate messages from verified UHC domains that pass DMARC authentication and handles high-trust sender domains appropriately.

  1. inbound message
  2. any of:
    • any of:
      • strings.replace_confusables(sender.display_name) matches '*united healthcare*'
      • strings.replace_confusables(sender.display_name) matches 'UHC*'
      • sender.display_name matches 'united ?health ?care'
    • strings.replace_confusables(sender.display_name) is similar to 'united healthcare'
    • all of:
      • body.current_thread.text matches 'united ?health ?care'
      • any of:
        • body.current_thread.text matches 'quick .{0,10}survey'
        • body.current_thread.text matches 'dental (benefits?|coverage).{0,50}(free|eligible|no.{0,10}cost)'
        • body.current_thread.text matches 'free.{0,30}(toothbrush|dental|benefit)'
    • all of:
      • sender.email.local_part contains 'unitedhealthcare'
      • sender.email.domain.root_domain not in ('uhc.com', 'unitedhealthcare.com', 'uhcmedicaresolutions.com', 'unitedhealthcareupdate.com', 'yourhealth-wellnessteam.com', 'uhc-customer.com', 'leavesource.com')
  3. none of:
    • sender.email.domain.root_domain in $org_domains
    • all of:
      • any of:
        • sender.email.domain.root_domain in ('uhc.com', 'unitedhealthcare.com', 'uhcmedicaresolutions.com', 'unitedhealthcareupdate.com', 'yourhealth-wellnessteam.com', 'uhc-customer.com', 'leavesource.com')
        • sender.display_name in ('UHCOM Faculty Affairs', 'UHC Construction Services')
      • headers.auth_summary.dmarc.pass
  4. not:
    • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
      • .name is 'Professional and Career Development'
      • .confidence is 'high'
  5. 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, sender.display_name, sender.email.domain.root_domain, sender.email.local_part, type.inbound. Sensors: ml.nlu_classifier, regex.icontains, strings.icontains, strings.ilevenshtein, strings.ilike, strings.replace_confusables. Reference lists: $high_trust_sender_root_domains, $org_domains.

Indicators matched (8)

FieldMatchValue
strings.ilikesubstring*united healthcare*
strings.ilikesubstringUHC*
regex.icontainsregexunited ?health ?care
strings.ilevenshteinfuzzyunited healthcare
regex.icontainsregexquick .{0,10}survey
regex.icontainsregexdental (benefits?|coverage).{0,50}(free|eligible|no.{0,10}cost)
regex.icontainsregexfree.{0,30}(toothbrush|dental|benefit)
strings.icontainssubstringunitedhealthcare

Stages and Predicates

Stage 1: mql_rule

and
  not
    or
      and
        or
          sender.display_name in ["UHC Construction Services", "UHCOM Faculty Affairs"]
          sender.email.domain.root_domain in ["leavesource.com", "uhc-customer.com", "uhc.com", "uhcmedicaresolutions.com", "unitedhealthcare.com", "unitedhealthcareupdate.com", "yourhealth-wellnessteam.com"]
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in org_domains"
  or
    and
      or
        body.current_thread.text regex_match "dental (benefits?|coverage).{0,50}(free|eligible|no.{0,10}cost)"
        body.current_thread.text regex_match "free.{0,30}(toothbrush|dental|benefit)"
        body.current_thread.text regex_match "quick .{0,10}survey"
      body.current_thread.text regex_match "united ?health ?care"
    and
      not
        sender.email.domain.root_domain in ["leavesource.com", "uhc-customer.com", "uhc.com", "uhcmedicaresolutions.com", "unitedhealthcare.com", "unitedhealthcareupdate.com", "yourhealth-wellnessteam.com"]
      sender.email.local_part contains "unitedhealthcare"
    sender.display_name regex_match "united ?health ?care"
    strings.ilevenshtein func_call "strings.ilevenshtein(strings.replace_confusables(sender.display_name), \"united healthcare\") <= 1"
    strings.replace_confusables(sender.display_name) match "united healthcare"
    strings.replace_confusables(sender.display_name) starts_with "UHC"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    any(ml.nlu_classifier(body.current_thread.text).topics)
      and
        ml.nlu_classifier(body.current_thread.text).topics.confidence eq "high"
        ml.nlu_classifier(body.current_thread.text).topics.name eq "Professional and Career Development"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.display_nameinUHC Construction Services, UHCOM Faculty Affairsexcludes:sender.display_name field:"sender.display_name" value:"UHC Construction Services" field:"sender.display_name" value:"UHCOM Faculty Affairs"
sender.email.domain.root_domaininleavesource.com, uhc-customer.com, uhc.com, uhcmedicaresolutions.com, unitedhealthcare.com, unitedhealthcareupdate.com, yourhealth-wellnessteam.comexcludes:sender.email.domain.root_domain
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
ml.nlu_classifier(body.current_thread.text).topicsarray_any(no value, null check)excludes:ml.nlu_classifier(body.current_thread.text).topics

Indicators

These rows show field, operator, and value matches.

Brand impersonation: UPS

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

Detects messages impersonating UPS (United Parcel Service) through display name, email address patterns, subject content, or HTML styling that mimics UPS branding, while excluding legitimate UPS domains.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.html
  • headers
  • headers.auth_summary
  • sender.email
  • subject
  • type

Rule body

type.inbound
and sender.email.domain.root_domain not in ("ups.com", "upsemail.com")
and (
  sender.display_name in~ ("UPS My Choice", "UPS Services", "Ups.com")
  or regex.icontains(sender.display_name, 'ups-\w+')
  or strings.ilike(sender.email.local_part, "*united*parcel*service*")
  or strings.ilike(sender.email.domain.domain, '*united*parcel*service*')
  or strings.icontains(subject.subject, 'UPS delivery')
  or sender.email.local_part =~ "ups"
  or regex.icontains(sender.display_name,
                     "U[^a-zA-Z]P[^a-zA-Z]S(?:[^a-zA-Z]|$)"
  )
  or strings.icontains(body.html.raw, 'background-color:#351d20')
  or strings.icontains(body.html.raw, 'background-color: #351d20')
  or (
    regex.imatch(sender.display_name, 'ups')
    and not sender.email.domain.root_domain == "appleid.com"
  )
)
and (
  // Observed in the "footer" of impersation messages
  // added this due to the UPS image not loading on some emails
  strings.icontains(body.current_thread.text, "United Parcel Service of")
  or regex.icontains(body.current_thread.text,
                     "(©|®).{0,15}(?:U.?P.?S.?|United Parcel Service)"
  )
  or any(ml.logo_detect(file.message_screenshot()).brands, .name is not null)
)
and sender.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.

Detects messages impersonating UPS (United Parcel Service) through display name, email address patterns, subject content, or HTML styling that mimics UPS branding, while excluding legitimate UPS domains.

  1. inbound message
  2. sender.email.domain.root_domain not in ('ups.com', 'upsemail.com')
  3. any of:
    • sender.display_name in ('UPS My Choice', 'UPS Services', 'Ups.com')
    • sender.display_name matches 'ups-\\w+'
    • sender.email.local_part matches '*united*parcel*service*'
    • sender.email.domain.domain matches '*united*parcel*service*'
    • subject.subject contains 'UPS delivery'
    • sender.email.local_part is 'ups'
    • sender.display_name matches 'U[^a-zA-Z]P[^a-zA-Z]S(?:[^a-zA-Z]|$)'
    • body.html.raw contains 'background-color:#351d20'
    • body.html.raw contains 'background-color: #351d20'
    • all of:
      • sender.display_name matches 'ups'
      • not:
        • sender.email.domain.root_domain is 'appleid.com'
  4. any of:
    • body.current_thread.text contains 'United Parcel Service of'
    • body.current_thread.text matches '(©|®).{0,15}(?:U.?P.?S.?|United Parcel Service)'
    • any of ml.logo_detect(file.message_screenshot()).brands where:
      • .name is set
  5. sender.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, body.html.raw, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.email, sender.email.local_part, subject.subject, type.inbound. Sensors: file.message_screenshot, ml.logo_detect, regex.icontains, regex.imatch, strings.icontains, strings.ilike. Reference lists: $high_trust_sender_root_domains, $recipient_emails.

Indicators matched (13)

FieldMatchValue
sender.display_namememberUPS My Choice
sender.display_namememberUPS Services
sender.display_namememberUps.com
regex.icontainsregexups-\w+
strings.ilikesubstring*united*parcel*service*
strings.icontainssubstringUPS delivery
sender.email.local_partequalsups
regex.icontainsregexU[^a-zA-Z]P[^a-zA-Z]S(?:[^a-zA-Z]|$)
strings.icontainssubstringbackground-color:#351d20
strings.icontainssubstringbackground-color: #351d20
regex.imatchregexups
strings.icontainssubstringUnited Parcel Service of
1 more
regex.icontainsregex(©|®).{0,15}(?:U.?P.?S.?|United Parcel Service)

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    and
      not
        sender.email.domain.root_domain eq "appleid.com"
      sender.display_name regex_match "ups"
    body.html.raw contains "background-color: #351d20"
    body.html.raw contains "background-color:#351d20"
    sender.display_name in ["UPS My Choice", "UPS Services", "Ups.com"]
    sender.display_name regex_match "U[^a-zA-Z]P[^a-zA-Z]S(?:[^a-zA-Z]|$)"
    sender.display_name regex_match "ups-\\w+"
    sender.email.domain.domain wildcard "*united*parcel*service*"
    sender.email.local_part eq "ups"
    sender.email.local_part wildcard "*united*parcel*service*"
    subject.subject contains "UPS delivery"
  or
    any(ml.logo_detect(file.message_screenshot()).brands)
      ml.logo_detect(file.message_screenshot()).brands.name is_not_null
    body.current_thread.text contains "United Parcel Service of"
    body.current_thread.text regex_match "(©|®).{0,15}(?:U.?P.?S.?|United Parcel Service)"
  not
    sender.email.domain.root_domain in ["ups.com", "upsemail.com"]
  type.inbound eq "true"
   macro "sender.email.email not in recipient_emails"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

Brand impersonation: USPS

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

Impersonation of the United States Postal Service.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImage as content, Impersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.html
  • body.links
  • headers
  • headers.auth_summary
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  any(ml.logo_detect(file.message_screenshot()).brands, .name == "USPS")
  or strings.icontains(sender.display_name, "USPS")
  or strings.icontains(sender.display_name, "United States Postal Service")
  or regex.contains(body.html.display_text, 'USPS\s*\.\s*COM')
  or strings.icontains(body.current_thread.text, 'USPS Delivery Team')
  or any(ml.nlu_classifier(body.current_thread.text).entities,
         .name == "org" and .text =~ "USPS"
  )
)
and length(body.links) > 0
and 3 of (
  any(body.links,
      strings.ilike(.display_text,
                    "*check now*",
                    "*track*",
                    "*package*",
                    '*view your order*',
                    "*update*",
                    '*delivery address*',
                    "*parcel allocation*",
                    "*claim your parcel*",
                    "*delivery details*"
      )
  ),
  strings.ilike(body.current_thread.text,
                "*returned*to*sender*",
                "*redelivery*",
                '*USPS promotions*',
                '*review your package*',
                '*receiver address*',
                '*package details*',
                '*sorry tolet*',
                '*Due to an incorrect*',
                '*remain undeliverable*',
                "*service updates*"
  ),
  // impersonal greeting
  any(ml.nlu_classifier(body.current_thread.text).entities,
      .name == "recipient" and .text =~ "Customer"
  ),
  any(ml.nlu_classifier(body.current_thread.text).intents,
      .name == "cred_theft" and .confidence != "low"
  ),
  // free email sender
  sender.email.domain.root_domain in $free_email_providers,
  network.whois(sender.email.domain).days_old < 30,
  not network.whois(sender.email.domain).found,

  // contains link to recently registered domain
  any(body.links, network.whois(.href_url.domain).days_old < 15),
  (
    regex.icontains(strings.replace_confusables(body.html.display_text),
                    '\b(?:u.?s.?p.?s|shipping|delivery)\b'
    )
    and not regex.icontains(body.html.display_text,
                            '\b(?:usps|shipping|delivery)\b'
    )
  ),
  any(body.links, regex.icontains(.href_url.url, 'https?://[0-9]{7,12}/.+')),
  (
    any(body.links,
        strings.icontains(.display_url.domain.root_domain, 'usps')
        and .mismatched
    )
  )
)
and (
  sender.email.domain.root_domain not in (
    "usps.com",
    "opinions-inmoment.com", // https://faq.usps.com/s/article/USPS-Customer-Experience-Surveys
    "shipup.co", // third party shipping company
    "withings.com" // third party shipping company
  )
  or (
    sender.email.domain.root_domain in (
      "usps.com",
      "opinions-inmoment.com" // https://faq.usps.com/s/article/USPS-Customer-Experience-Surveys
    )
    and not headers.auth_summary.dmarc.pass
  )
)
// negate newsletters
and not (
  length(filter(body.links, .visible == true)) > 20
  or any(ml.nlu_classifier(body.html.display_text).topics,
         .name == "Newsletters and Digests"
  )
)
// not all links to usps.com
and not all(body.links, .href_url.domain.root_domain == "usps.com")
// negate legit forwards and replies
and not (
  (subject.is_reply or subject.is_forward)
  and length(body.previous_threads) > 0
  and (length(headers.references) > 0 or headers.in_reply_to is not null)
)
// 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
)
and not any(body.links,
            regex.icontains(.display_text, 'Track (?:Your Order|Shipment)')
            and .href_url.domain.domain == 'tools.usps.com'
)
and not sender.email.domain.root_domain in ('shopifyemail.com')

Detection logic

Scope: inbound message.

Impersonation of the United States Postal Service.

  1. inbound message
  2. any of:
    • any of ml.logo_detect(file.message_screenshot()).brands where:
      • .name is 'USPS'
    • sender.display_name contains 'USPS'
    • sender.display_name contains 'United States Postal Service'
    • body.html.display_text matches 'USPS\\s*\\.\\s*COM'
    • body.current_thread.text contains 'USPS Delivery Team'
    • any of ml.nlu_classifier(body.current_thread.text).entities where all hold:
      • .name is 'org'
      • .text is 'USPS'
  3. length(body.links) > 0
  4. at least 3 of:
    • any of body.links where:
      • .display_text matches any of 9 patterns
        • *check now*
        • *track*
        • *package*
        • *view your order*
        • *update*
        • *delivery address*
        • *parcel allocation*
        • *claim your parcel*
        • *delivery details*
    • body.current_thread.text matches any of 10 patterns
      • *returned*to*sender*
      • *redelivery*
      • *USPS promotions*
      • *review your package*
      • *receiver address*
      • *package details*
      • *sorry tolet*
      • *Due to an incorrect*
      • *remain undeliverable*
      • *service updates*
    • any of ml.nlu_classifier(body.current_thread.text).entities where all hold:
      • .name is 'recipient'
      • .text is 'Customer'
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'cred_theft'
      • .confidence is not 'low'
    • sender.email.domain.root_domain in $free_email_providers
    • network.whois(sender.email.domain).days_old < 30
    • not:
      • network.whois(sender.email.domain).found
    • any of body.links where:
      • network.whois(.href_url.domain).days_old < 15
    • all of:
      • strings.replace_confusables(body.html.display_text) matches '\\b(?:u.?s.?p.?s|shipping|delivery)\\b'
      • not:
        • body.html.display_text matches '\\b(?:usps|shipping|delivery)\\b'
    • any of body.links where:
      • .href_url.url matches 'https?://[0-9]{7,12}/.+'
    • any of body.links where all hold:
      • .display_url.domain.root_domain contains 'usps'
      • .mismatched
  5. any of:
    • sender.email.domain.root_domain not in ('usps.com', 'opinions-inmoment.com', 'shipup.co', 'withings.com')
    • all of:
      • sender.email.domain.root_domain in ('usps.com', 'opinions-inmoment.com')
      • not:
        • headers.auth_summary.dmarc.pass
  6. none of:
    • length(filter(body.links, .visible == True)) > 20
    • any of ml.nlu_classifier(body.html.display_text).topics where:
      • .name is 'Newsletters and Digests'
  7. not:
    • all of body.links where:
      • .href_url.domain.root_domain is 'usps.com'
  8. not:
    • all of:
      • any of:
        • subject.is_reply
        • subject.is_forward
      • length(body.previous_threads) > 0
      • any of:
        • length(headers.references) > 0
        • headers.in_reply_to is set
  9. 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
  10. not:
    • any of body.links where all hold:
      • .display_text matches 'Track (?:Your Order|Shipment)'
      • .href_url.domain.domain is 'tools.usps.com'
  11. not:
    • sender.email.domain.root_domain in ('shopifyemail.com')

Inspects: body.current_thread.text, body.html.display_text, body.links, body.links[].display_text, body.links[].display_url.domain.root_domain, body.links[].href_url.domain, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.url, body.links[].mismatched, body.links[].visible, body.previous_threads, headers.auth_summary.dmarc.pass, headers.in_reply_to, headers.references, sender.display_name, sender.email.domain, sender.email.domain.root_domain, subject.is_forward, subject.is_reply, type.inbound. Sensors: file.message_screenshot, ml.logo_detect, ml.nlu_classifier, network.whois, regex.contains, regex.icontains, strings.icontains, strings.ilike, strings.replace_confusables. Reference lists: $free_email_providers, $high_trust_sender_root_domains.

Indicators matched (34)

FieldMatchValue
ml.logo_detect(file.message_screenshot()).brands[].nameequalsUSPS
strings.icontainssubstringUSPS
strings.icontainssubstringUnited States Postal Service
regex.containsregexUSPS\s*\.\s*COM
strings.icontainssubstringUSPS Delivery Team
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsorg
ml.nlu_classifier(body.current_thread.text).entities[].textequalsUSPS
strings.ilikesubstring*check now*
strings.ilikesubstring*track*
strings.ilikesubstring*package*
strings.ilikesubstring*view your order*
strings.ilikesubstring*update*
22 more
strings.ilikesubstring*delivery address*
strings.ilikesubstring*parcel allocation*
strings.ilikesubstring*claim your parcel*
strings.ilikesubstring*delivery details*
strings.ilikesubstring*returned*to*sender*
strings.ilikesubstring*redelivery*
strings.ilikesubstring*USPS promotions*
strings.ilikesubstring*review your package*
strings.ilikesubstring*receiver address*
strings.ilikesubstring*package details*
strings.ilikesubstring*sorry tolet*
strings.ilikesubstring*Due to an incorrect*
strings.ilikesubstring*remain undeliverable*
strings.ilikesubstring*service updates*
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsrecipient
ml.nlu_classifier(body.current_thread.text).entities[].textequalsCustomer
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
regex.icontainsregex\b(?:u.?s.?p.?s|shipping|delivery)\b
regex.icontainsregexhttps?://[0-9]{7,12}/.+
strings.icontainssubstringusps
sender.email.domain.root_domainmemberusps.com
sender.email.domain.root_domainmemberopinions-inmoment.com

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        body.html.display_text regex_match "\\b(?:usps|shipping|delivery)\\b"
      strings.replace_confusables(body.html.display_text) regex_match "\\b(?:u.?s.?p.?s|shipping|delivery)\\b"
    any(body.links)
      or
        body.links.display_text match "check now"
        body.links.display_text match "claim your parcel"
        body.links.display_text match "delivery address"
        body.links.display_text match "delivery details"
        body.links.display_text match "package"
        body.links.display_text match "parcel allocation"
        body.links.display_text match "track"
        body.links.display_text match "update"
        body.links.display_text match "view your order"
    any(body.links)
      and
        body.links.display_url.domain.root_domain contains "usps"
        body.links.mismatched eq "true"
    any(ml.nlu_classifier(body.current_thread.text).entities)
      and
        ml.nlu_classifier(body.current_thread.text).entities.name eq "recipient"
        ml.nlu_classifier(body.current_thread.text).entities.text eq "Customer"
    any(ml.nlu_classifier(body.current_thread.text).intents)
      and
        ml.nlu_classifier(body.current_thread.text).intents.confidence ne "low"
        ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
    any(body.links)
      body.links.href_url.url regex_match "https?://[0-9]{7,12}/.+"
    any(body.links)
      network.whois func_call "network.whois(body.links[].href_url.domain).days_old < 15"
    not
      network.whois func_call "network.whois(sender.email.domain).found"
    body.current_thread.text match "Due to an incorrect"
    body.current_thread.text match "USPS promotions"
    body.current_thread.text match "package details"
    body.current_thread.text match "receiver address"
    body.current_thread.text match "redelivery"
    body.current_thread.text match "remain undeliverable"
    body.current_thread.text match "review your package"
    body.current_thread.text match "service updates"
    body.current_thread.text match "sorry tolet"
    body.current_thread.text wildcard "*returned*to*sender*"
    network.whois func_call "network.whois(sender.email.domain).days_old < 30"
     macro "sender.email.domain.root_domain in free_email_providers"
  not
    any(body.links)
      and
        body.links.display_text regex_match "Track (?:Your Order|Shipment)"
        body.links.href_url.domain.domain eq "tools.usps.com"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.root_domain in ["opinions-inmoment.com", "usps.com"]
    not
      sender.email.domain.root_domain in ["opinions-inmoment.com", "shipup.co", "usps.com", "withings.com"]
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    and
      or
        headers.in_reply_to is_not_null
        headers.references length_compare "0"
      or
        subject.is_forward eq "true"
        subject.is_reply eq "true"
      body.previous_threads length_compare "0"
  or
    any(ml.nlu_classifier(body.current_thread.text).entities)
      and
        ml.nlu_classifier(body.current_thread.text).entities.name eq "org"
        ml.nlu_classifier(body.current_thread.text).entities.text eq "USPS"
    any(ml.logo_detect(file.message_screenshot()).brands)
      ml.logo_detect(file.message_screenshot()).brands.name eq "USPS"
    body.current_thread.text contains "USPS Delivery Team"
    body.html.display_text regex_match "USPS\\s*\\.\\s*COM"
    sender.display_name contains "USPS"
    sender.display_name contains "United States Postal Service"
  not
    or
      any(ml.nlu_classifier(body.html.display_text).topics)
        ml.nlu_classifier(body.html.display_text).topics.name eq "Newsletters and Digests"
      filter(body.links, .visible == True) length_compare "20"
  not
    sender.email.domain.root_domain eq "shopifyemail.com"
  not
     macro "all(body.links)"
  body.links length_compare "0"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
body.linksarray_any(no value, null check)excludes:body.links
headers.in_reply_tois_not_null(no value, null check)excludes:headers.in_reply_to
headers.referenceslength_compare0excludes:headers.references field:"headers.references" value:"0"
subject.is_forwardeqtrueexcludes:subject.is_forward field:"subject.is_forward" value:"true"
subject.is_replyeqtrueexcludes:subject.is_reply field:"subject.is_reply" value:"true"
body.previous_threadslength_compare0excludes:body.previous_threads field:"body.previous_threads" value:"0"
ml.nlu_classifier(body.html.display_text).topicsarray_any(no value, null check)excludes:ml.nlu_classifier(body.html.display_text).topics
filter(body.links, .visible == True)length_compare20excludes:filter(body.links, .visible == True) field:"filter(body.links, .visible == True)" value:"20"
sender.email.domain.root_domaineqshopifyemail.comexcludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"shopifyemail.com"

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Vanta

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

Impersonation of Vanta.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  regex.imatch(sender.display_name, '\bvanta\b')
  or regex.imatch(sender.email.local_part, '(\b)vanta|vanta(\b)')
  or strings.ilevenshtein(sender.email.domain.sld, 'vanta') <= 1
)
and not (
  strings.ilike(sender.display_name, '*advantage*')
  or strings.ilike(sender.email.email, '*advantage*')
  or strings.ilevenshtein(sender.email.domain.sld, 'advantage') <= 1
)
and sender.email.domain.root_domain in $free_email_providers
and sender.email.email not in $sender_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.

Impersonation of Vanta.

  1. inbound message
  2. any of:
    • sender.display_name matches '\\bvanta\\b'
    • sender.email.local_part matches '(\\b)vanta|vanta(\\b)'
    • sender.email.domain.sld is similar to 'vanta'
  3. none of:
    • sender.display_name matches '*advantage*'
    • sender.email.email matches '*advantage*'
    • sender.email.domain.sld is similar to 'advantage'
  4. sender.email.domain.root_domain in $free_email_providers
  5. sender.email.email not in $sender_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: headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.root_domain, sender.email.domain.sld, sender.email.email, sender.email.local_part, type.inbound. Sensors: regex.imatch, strings.ilevenshtein, strings.ilike. Reference lists: $free_email_providers, $high_trust_sender_root_domains, $sender_emails.

Indicators matched (3)

FieldMatchValue
regex.imatchregex\bvanta\b
regex.imatchregex(\b)vanta|vanta(\b)
strings.ilevenshteinfuzzyvanta

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    or
      sender.display_name match "advantage"
      sender.email.email match "advantage"
      strings.ilevenshtein func_call "strings.ilevenshtein(sender.email.domain.sld, \"advantage\") <= 1"
  or
    sender.display_name regex_match "\\bvanta\\b"
    sender.email.local_part regex_match "(\\b)vanta|vanta(\\b)"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.email.domain.sld, \"vanta\") <= 1"
  type.inbound eq "true"
   macro "sender.email.domain.root_domain in free_email_providers"
   macro "sender.email.email not in sender_emails"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.display_namematchadvantageexcludes:sender.display_name field:"sender.display_name" value:"advantage"
sender.email.emailmatchadvantageexcludes:sender.email.email field:"sender.email.email" value:"advantage"

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Venmo

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

Impersonation of Venmo

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  strings.ilike(sender.display_name, '*venmo*')
  or strings.ilevenshtein(sender.display_name, 'venmo') <= 1
)
and sender.email.domain.root_domain not in~ (
  'venmo.com',
  'synchronybank.com',
  'venmocreditsurvey.com',
  'venmo-experience.com',
  'synchrony.com'
)

// and not if the sender.display.name contains "via" and dmarc pass from venmo.com
and not (
  (
    headers.auth_summary.dmarc.pass
    and headers.auth_summary.dmarc.details.from.root_domain == "venmo.com"
  )
  and strings.contains(sender.display_name, "via")
)

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

// and no false positives and not solicited
and (
  not profile.by_sender().any_messages_benign
  and not profile.by_sender().solicited
)

Detection logic

Scope: inbound message.

Impersonation of Venmo

  1. inbound message
  2. any of:
    • sender.display_name matches '*venmo*'
    • sender.display_name is similar to 'venmo'
  3. sender.email.domain.root_domain not in ('venmo.com', 'synchronybank.com', 'venmocreditsurvey.com', 'venmo-experience.com', 'synchrony.com')
  4. not:
    • all of:
      • all of:
        • headers.auth_summary.dmarc.pass
        • headers.auth_summary.dmarc.details.from.root_domain is 'venmo.com'
      • sender.display_name contains 'via'
  5. 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
  6. all of:
    • not:
      • profile.by_sender().any_messages_benign
    • not:
      • profile.by_sender().solicited

Inspects: headers.auth_summary.dmarc.details.from.root_domain, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender, strings.contains, strings.ilevenshtein, strings.ilike. Reference lists: $high_trust_sender_root_domains.

Indicators matched (2)

FieldMatchValue
strings.ilikesubstring*venmo*
strings.ilevenshteinfuzzyvenmo

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    and
      headers.auth_summary.dmarc.details.from.root_domain eq "venmo.com"
      headers.auth_summary.dmarc.pass eq "true"
      sender.display_name contains "via"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  not
    profile.by_sender func_call "profile.by_sender().solicited"
  or
    sender.display_name match "venmo"
    strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"venmo\") <= 1"
  not
    sender.email.domain.root_domain in ["synchrony.com", "synchronybank.com", "venmo-experience.com", "venmo.com", "venmocreditsurvey.com"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.auth_summary.dmarc.details.from.root_domaineqvenmo.comexcludes:headers.auth_summary.dmarc.details.from.root_domain field:"headers.auth_summary.dmarc.details.from.root_domain" value:"venmo.com"
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
sender.display_namecontainsviaexcludes:sender.display_name field:"sender.display_name" value:"via"
sender.email.domain.root_domaininsynchrony.com, synchronybank.com, venmo-experience.com, venmo.com, venmocreditsurvey.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Wells Fargo

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

Impersonation of Wells Fargo Bank.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.html
  • body.plain
  • headers
  • headers.auth_summary
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  sender.display_name =~ 'wellsfargo'
  or strings.ilevenshtein(strings.replace_confusables(sender.display_name),
                          'wellsfargo'
  ) <= 1
  or regex.icontains(strings.replace_confusables(sender.display_name),
                     'we(ll|ii)s?\s?farg(o|o͙)'
  )
  or strings.ilike(sender.email.domain.domain, '*wellsfargo*')
  or strings.ilike(subject.subject, '*wells fargo security*')
  or strings.ilike(body.plain.raw, '*wells fargo security team*')
  or strings.ilike(body.html.inner_text, '*wells fargo security team*')
  // Wells Fargo & Company (WFC)
  or (
    regex.icontains(sender.display_name, '\bW.?F.?C\b')
    and any([sender.display_name, subject.base],
            strings.ilike(.,
                          '*bank*',
                          '*security*',
                          '*processing*',
                          '*approval*',
                          '*refund*'
            )
    )
  )
)
and sender.email.domain.root_domain not in~ (
  'wellsfargo.com',
  'wellsfargoadvisors.com',
  'transunion.com',
  'wellsfargoemail.com',
  'wellsfargorewards.com',
  'comcast-spectacor.com',
  'investordelivery.com',
  'comcastspectacor.com',
  'wfadvisors.com',
  'wellsfargomerchantservicesllc.com'
)
and (
  sender.email.email not in $recipient_emails
  or regex.icontains(sender.email.email, "no.?reply")
)

// 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
  or sender.email.email in (
    "drive-shares-noreply@google.com",
    "drive-shares-dm-noreply@google.com"
  ) // Google Drive abuse has been observed
)

Detection logic

Scope: inbound message.

Impersonation of Wells Fargo Bank.

  1. inbound message
  2. any of:
    • sender.display_name is 'wellsfargo'
    • strings.replace_confusables(sender.display_name) is similar to 'wellsfargo'
    • strings.replace_confusables(sender.display_name) matches 'we(ll|ii)s?\\s?farg(o|o͙)'
    • sender.email.domain.domain matches '*wellsfargo*'
    • subject.subject matches '*wells fargo security*'
    • body.plain.raw matches '*wells fargo security team*'
    • body.html.inner_text matches '*wells fargo security team*'
    • all of:
      • sender.display_name matches '\\bW.?F.?C\\b'
      • any of [sender.display_name, subject.base] where:
        • . matches any of 5 patterns
          • *bank*
          • *security*
          • *processing*
          • *approval*
          • *refund*
  3. sender.email.domain.root_domain not in ('wellsfargo.com', 'wellsfargoadvisors.com', 'transunion.com', 'wellsfargoemail.com', 'wellsfargorewards.com', 'comcast-spectacor.com', 'investordelivery.com', 'comcastspectacor.com', 'wfadvisors.com', 'wellsfargomerchantservicesllc.com')
  4. any of:
    • sender.email.email not in $recipient_emails
    • sender.email.email matches 'no.?reply'
  5. 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
    • sender.email.email in ('drive-shares-noreply@google.com', 'drive-shares-dm-noreply@google.com')

Inspects: body.html.inner_text, body.plain.raw, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.email, subject.base, subject.subject, type.inbound. Sensors: regex.icontains, strings.ilevenshtein, strings.ilike, strings.replace_confusables. Reference lists: $high_trust_sender_root_domains, $recipient_emails.

Indicators matched (15)

FieldMatchValue
sender.display_nameequalswellsfargo
strings.ilevenshteinfuzzywellsfargo
regex.icontainsregexwe(ll|ii)s?\s?farg(o|o͙)
strings.ilikesubstring*wellsfargo*
strings.ilikesubstring*wells fargo security*
strings.ilikesubstring*wells fargo security team*
regex.icontainsregex\bW.?F.?C\b
strings.ilikesubstring*bank*
strings.ilikesubstring*security*
strings.ilikesubstring*processing*
strings.ilikesubstring*approval*
strings.ilikesubstring*refund*
3 more
regex.icontainsregexno.?reply
sender.email.emailmemberdrive-shares-noreply@google.com
sender.email.emailmemberdrive-shares-dm-noreply@google.com

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      any([sender.display_name, subject.base])
        or
          [sender.display_name, subject.base] match "approval"
          [sender.display_name, subject.base] match "bank"
          [sender.display_name, subject.base] match "processing"
          [sender.display_name, subject.base] match "refund"
          [sender.display_name, subject.base] match "security"
      sender.display_name regex_match "\\bW.?F.?C\\b"
    body.html.inner_text match "wells fargo security team"
    body.plain.raw match "wells fargo security team"
    sender.display_name eq "wellsfargo"
    sender.email.domain.domain match "wellsfargo"
    strings.ilevenshtein func_call "strings.ilevenshtein(strings.replace_confusables(sender.display_name), \"wellsfargo\") <= 1"
    strings.replace_confusables(sender.display_name) regex_match "we(ll|ii)s?\\s?farg(o|o͙)"
    subject.subject match "wells fargo security"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
    sender.email.email in ["drive-shares-dm-noreply@google.com", "drive-shares-noreply@google.com"]
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    sender.email.domain.root_domain in ["comcast-spectacor.com", "comcastspectacor.com", "investordelivery.com", "transunion.com", "wellsfargo.com", "wellsfargoadvisors.com", "wellsfargoemail.com", "wellsfargomerchantservicesllc.com", "wellsfargorewards.com", "wfadvisors.com"]
  or
    sender.email.email regex_match "no.?reply"
     macro "sender.email.email not in recipient_emails"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domainincomcast-spectacor.com, comcastspectacor.com, investordelivery.com, transunion.com, wellsfargo.com, wellsfargoadvisors.com, wellsfargoemail.com, wellsfargomerchantservicesllc.com, wellsfargorewards.com, wfadvisors.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Wise

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

Impersonating Wise Financial, an online banking platform.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • body.links
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  regex.icontains(sender.display_name, '\bwise\b')
  or strings.ilike(sender.email.domain.domain, '*wise*')
)
and (
  any(ml.nlu_classifier(body.current_thread.text).tags,
      .name in ("payment", "invoice")
  )
  or any(ml.nlu_classifier(body.current_thread.text).intents,
         .name in ("cred_theft", "steal_pii") and .confidence == "high"
  )
)
and (
  any(attachments,
      .file_type in $file_extensions_common_archives
      or .file_type in $file_extensions_executables
      or .file_type in $file_extensions_macros
      or .file_type in ("lz")
      or (
        .file_extension is null
        and .file_type == "unknown"
        and .content_type == "application/octet-stream"
        and .size < 100000000
      )
  )
  or any(body.links,
         regex.icontains(.display_text,
                         // https://github.com/sublime-security/static-files/blob/main/suspicious_subjects_regex.txt
                         "termination.*notice",
                         "38417",
                         ":completed",
                         "[il1]{2}mit.*ma[il1]{2} ?bo?x",
                         "[il][il][il]egai[ -]",
                         "[li][li][li]ega[li] attempt",
                         "[ng]-?[io]n .*block",
                         "[ng]-?[io]n .*cancel",
                         "[ng]-?[io]n .*deactiv",
                         "[ng]-?[io]n .*disabl",
                         "action.*required",
                         "abandon.*package",
                         "about.your.account",
                         "acc(ou)?n?t (is )?on ho[li]d",
                         "acc(ou)?n?t.*terminat",
                         "acc(oun)?t.*[il1]{2}mitation",
                         "access.*limitation",
                         "account (will be )?block",
                         "account.*de-?activat",
                         "account.*locked",
                         "account.*re-verification",
                         "account.*security",
                         "account.*suspension",
                         "account.has.been",
                         "account.has.expired",
                         "account.will.be.blocked",
                         "account v[il]o[li]at",
                         "activity.*acc(oun)?t",
                         "almost.full",
                         "app[li]e.[il]d",
                         "authenticate.*account",
                         "been.*suspend",
                         "clos.*of.*account.*processed",
                         "confirm.your.account",
                         "courier.*able",
                         "crediential.*notif",
                         "deactivation.*in.*progress",
                         "delivery.*attempt.*failed",
                         "document.received",
                         "documented.*shared.*with.*you",
                         "dropbox.*document",
                         "e-?ma[il1]+ .{010}suspen",
                         "e-?ma[il1]{1} user",
                         "e-?ma[il1]{2} acc",
                         "e-?ma[il1]{2}.*up.?grade",
                         "e.?ma[il1]{2}.*server",
                         "e.?ma[il1]{2}.*suspend",
                         "email.update",
                         "faxed you",
                         "fraud(ulent)?.*charge",
                         "from.helpdesk",
                         "fu[il1]{2}.*ma[il1]+[ -]?box",
                         "has.been.*suspended",
                         "has.been.limited",
                         "have.locked",
                         "he[li]p ?desk upgrade",
                         "heipdesk",
                         "i[il]iega[il]",
                         "ii[il]ega[il]",
                         "incoming e?mail",
                         "incoming.*fax",
                         "lock.*security",
                         "ma[il1]{1}[ -]?box.*quo",
                         "ma[il1]{2}[ -]?box.*fu[il1]",
                         "ma[il1]{2}box.*[il1]{2}mit",
                         "ma[il1]{2}box stor",
                         "mail on.?hold",
                         "mail.*box.*migration",
                         "mail.*de-?activat",
                         "mail.update.required",
                         "mails.*pending",
                         "messages.*pending",
                         "missed.*shipping.*notification",
                         "missed.shipment.notification",
                         "must.update.your.account",
                         "new [sl][io]g?[nig][ -]?in from",
                         "new voice ?-?mail",
                         "notifications.*pending",
                         "office.*3.*6.*5.*suspend",
                         "office365",
                         "on google docs with you",
                         "online doc",
                         "password.*compromised",
                         "periodic maintenance",
                         "potential(ly)? unauthorized",
                         "refund not approved",
                         "revised.*policy",
                         "scam",
                         "scanned.?invoice",
                         "secured?.update",
                         "security breach",
                         "securlty",
                         "signed.*delivery",
                         "status of your .{314}? ?delivery",
                         "susp[il1]+c[il1]+ous.*act[il1]+v[il1]+ty",
                         "suspicious.*sign.*[io]n",
                         "suspicious.activit",
                         "temporar(il)?y deactivate",
                         "temporar[il1]{2}y disab[li]ed",
                         "temporarily.*lock",
                         "un-?usua[li].activity",
                         "unable.*deliver",
                         "unauthorized.*activit",
                         "unauthorized.device",
                         "undelivered message",
                         "unread.*doc",
                         "unusual.activity",
                         "upgrade.*account",
                         "upgrade.notice",
                         "urgent message",
                         "urgent.verification",
                         "v[il1]o[li1]at[il1]on security",
                         "va[il1]{1}date.*ma[il1]{2}[ -]?box",
                         "verification ?-?require",
                         "verification( )?-?need",
                         "verify.your?.account",
                         "web ?-?ma[il1]{2}",
                         "web[ -]?ma[il1]{2}",
                         "will.be.suspended",
                         "your (customer )?account .as",
                         "your.office.365",
                         "your.online.access",

                         // https://github.com/sublime-security/static-files/blob/main/suspicious_subjects.txt
                         "account has been limited",
                         "action required",
                         "almost full",
                         "apd notifi cation",
                         "are you at your desk",
                         "are you available",
                         "attached file to docusign",
                         "banking is temporarily unavailable",
                         "bankofamerica",
                         "closing statement invoice",
                         "completed: docusign",
                         "de-activation of",
                         "delivery attempt",
                         "delivery stopped for shipment",
                         "detected suspicious",
                         "detected suspicious actvity",
                         "docu sign",
                         "document for you",
                         "document has been sent to you via docusign",
                         "document is ready for signature",
                         "docusign",
                         "encrypted message",
                         "failed delivery",
                         "fedex tracking",
                         "file was shared",
                         "freefax",
                         "fwd: due invoice paid",
                         "has shared",
                         "inbox is full",
                         "invitation to comment",
                         "invitation to edit",
                         "invoice due",
                         "left you a message",
                         "message from",
                         "new message",
                         "new voicemail",
                         "on desk",
                         "out of space",
                         "password reset",
                         "payment status",
                         "quick reply",
                         "re: w-2",
                         "required",
                         "required: completed docusign",
                         "ringcentral",
                         "scanned image",
                         "secured files",
                         "secured pdf",
                         "security alert",
                         "new sign-in",
                         "new sign in",
                         "sign-in attempt",
                         "sign in attempt",
                         "staff review",
                         "suspicious activity",
                         "unrecognized login attempt",
                         "upgrade immediately",
                         "urgent",
                         "wants to share",
                         "w2",
                         "you have notifications pending",
                         "your account",
                         "your amazon order",
                         "your document settlement",
                         "your order with amazon",
                         "your password has been compromised",
         )
  )
)
and sender.email.domain.root_domain not in~ (
  'wise.com',
  'wise.jobs',
  'splitwise.com',
  'connectwise.com'
)
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.

Impersonating Wise Financial, an online banking platform.

  1. inbound message
  2. any of:
    • sender.display_name matches '\\bwise\\b'
    • sender.email.domain.domain matches '*wise*'
  3. any of:
    • any of ml.nlu_classifier(body.current_thread.text).tags where:
      • .name in ('payment', 'invoice')
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name in ('cred_theft', 'steal_pii')
      • .confidence is 'high'
  4. any of:
    • any of attachments where any holds:
      • .file_type in $file_extensions_common_archives
      • .file_type in $file_extensions_executables
      • .file_type in $file_extensions_macros
      • .file_type in ('lz')
      • all of:
        • .file_extension is missing
        • .file_type is 'unknown'
        • .content_type is 'application/octet-stream'
        • .size < 100000000
    • any of body.links where:
      • .display_text matches any of 188 patterns
        • termination.*notice
        • 38417
        • :completed
        • [il1]{2}mit.*ma[il1]{2} ?bo?x
        • [il][il][il]egai[ -]
        • [li][li][li]ega[li] attempt
        • [ng]-?[io]n .*block
        • [ng]-?[io]n .*cancel
        • [ng]-?[io]n .*deactiv
        • [ng]-?[io]n .*disabl
        • action.*required
        • abandon.*package
        • about.your.account
        • acc(ou)?n?t (is )?on ho[li]d
        • acc(ou)?n?t.*terminat
        • acc(oun)?t.*[il1]{2}mitation
        • access.*limitation
        • account (will be )?block
        • account.*de-?activat
        • account.*locked
        • account.*re-verification
        • account.*security
        • account.*suspension
        • account.has.been
        • account.has.expired
        • account.will.be.blocked
        • account v[il]o[li]at
        • activity.*acc(oun)?t
        • almost.full
        • app[li]e.[il]d
        • authenticate.*account
        • been.*suspend
        • clos.*of.*account.*processed
        • confirm.your.account
        • courier.*able
        • crediential.*notif
        • deactivation.*in.*progress
        • delivery.*attempt.*failed
        • document.received
        • documented.*shared.*with.*you
        • dropbox.*document
        • e-?ma[il1]+ .{010}suspen
        • e-?ma[il1]{1} user
        • e-?ma[il1]{2} acc
        • e-?ma[il1]{2}.*up.?grade
        • e.?ma[il1]{2}.*server
        • e.?ma[il1]{2}.*suspend
        • email.update
        • faxed you
        • fraud(ulent)?.*charge
        • from.helpdesk
        • fu[il1]{2}.*ma[il1]+[ -]?box
        • has.been.*suspended
        • has.been.limited
        • have.locked
        • he[li]p ?desk upgrade
        • heipdesk
        • i[il]iega[il]
        • ii[il]ega[il]
        • incoming e?mail
        • incoming.*fax
        • lock.*security
        • ma[il1]{1}[ -]?box.*quo
        • ma[il1]{2}[ -]?box.*fu[il1]
        • ma[il1]{2}box.*[il1]{2}mit
        • ma[il1]{2}box stor
        • mail on.?hold
        • mail.*box.*migration
        • mail.*de-?activat
        • mail.update.required
        • mails.*pending
        • messages.*pending
        • missed.*shipping.*notification
        • missed.shipment.notification
        • must.update.your.account
        • new [sl][io]g?[nig][ -]?in from
        • new voice ?-?mail
        • notifications.*pending
        • office.*3.*6.*5.*suspend
        • office365
        • on google docs with you
        • online doc
        • password.*compromised
        • periodic maintenance
        • potential(ly)? unauthorized
        • refund not approved
        • revised.*policy
        • scam
        • scanned.?invoice
        • secured?.update
        • security breach
        • securlty
        • signed.*delivery
        • status of your .{314}? ?delivery
        • susp[il1]+c[il1]+ous.*act[il1]+v[il1]+ty
        • suspicious.*sign.*[io]n
        • suspicious.activit
        • temporar(il)?y deactivate
        • temporar[il1]{2}y disab[li]ed
        • temporarily.*lock
        • un-?usua[li].activity
        • unable.*deliver
        • unauthorized.*activit
        • unauthorized.device
        • undelivered message
        • unread.*doc
        • unusual.activity
        • upgrade.*account
        • upgrade.notice
        • urgent message
        • urgent.verification
        • v[il1]o[li1]at[il1]on security
        • va[il1]{1}date.*ma[il1]{2}[ -]?box
        • verification ?-?require
        • verification( )?-?need
        • verify.your?.account
        • web ?-?ma[il1]{2}
        • web[ -]?ma[il1]{2}
        • will.be.suspended
        • your (customer )?account .as
        • your.office.365
        • your.online.access
        • account has been limited
        • action required
        • almost full
        • apd notifi cation
        • are you at your desk
        • are you available
        • attached file to docusign
        • banking is temporarily unavailable
        • bankofamerica
        • closing statement invoice
        • completed: docusign
        • de-activation of
        • delivery attempt
        • delivery stopped for shipment
        • detected suspicious
        • detected suspicious actvity
        • docu sign
        • document for you
        • document has been sent to you via docusign
        • document is ready for signature
        • docusign
        • encrypted message
        • failed delivery
        • fedex tracking
        • file was shared
        • freefax
        • fwd: due invoice paid
        • has shared
        • inbox is full
        • invitation to comment
        • invitation to edit
        • invoice due
        • left you a message
        • message from
        • new message
        • new voicemail
        • on desk
        • out of space
        • password reset
        • payment status
        • quick reply
        • re: w-2
        • required
        • required: completed docusign
        • ringcentral
        • scanned image
        • secured files
        • secured pdf
        • security alert
        • new sign-in
        • new sign in
        • sign-in attempt
        • sign in attempt
        • staff review
        • suspicious activity
        • unrecognized login attempt
        • upgrade immediately
        • urgent
        • wants to share
        • w2
        • you have notifications pending
        • your account
        • your amazon order
        • your document settlement
        • your order with amazon
        • your password has been compromised
  5. sender.email.domain.root_domain not in ('wise.com', 'wise.jobs', 'splitwise.com', 'connectwise.com')
  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: attachments[].content_type, attachments[].file_extension, attachments[].file_type, attachments[].size, body.current_thread.text, body.links, body.links[].display_text, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: ml.nlu_classifier, regex.icontains, strings.ilike. Reference lists: $file_extensions_common_archives, $file_extensions_executables, $file_extensions_macros, $high_trust_sender_root_domains.

Indicators matched (198)

FieldMatchValue
regex.icontainsregex\bwise\b
strings.ilikesubstring*wise*
ml.nlu_classifier(body.current_thread.text).tags[].namememberpayment
ml.nlu_classifier(body.current_thread.text).tags[].namememberinvoice
ml.nlu_classifier(body.current_thread.text).intents[].namemembercred_theft
ml.nlu_classifier(body.current_thread.text).intents[].namemembersteal_pii
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh
attachments[].file_typememberlz
attachments[].file_typeequalsunknown
attachments[].content_typeequalsapplication/octet-stream
regex.icontainsregextermination.*notice
regex.icontainsregex38417
186 more
regex.icontainsregex:completed
regex.icontainsregex[il1]{2}mit.*ma[il1]{2} ?bo?x
regex.icontainsregex[il][il][il]egai[ -]
regex.icontainsregex[li][li][li]ega[li] attempt
regex.icontainsregex[ng]-?[io]n .*block
regex.icontainsregex[ng]-?[io]n .*cancel
regex.icontainsregex[ng]-?[io]n .*deactiv
regex.icontainsregex[ng]-?[io]n .*disabl
regex.icontainsregexaction.*required
regex.icontainsregexabandon.*package
regex.icontainsregexabout.your.account
regex.icontainsregexacc(ou)?n?t (is )?on ho[li]d
regex.icontainsregexacc(ou)?n?t.*terminat
regex.icontainsregexacc(oun)?t.*[il1]{2}mitation
regex.icontainsregexaccess.*limitation
regex.icontainsregexaccount (will be )?block
regex.icontainsregexaccount.*de-?activat
regex.icontainsregexaccount.*locked
regex.icontainsregexaccount.*re-verification
regex.icontainsregexaccount.*security
regex.icontainsregexaccount.*suspension
regex.icontainsregexaccount.has.been
regex.icontainsregexaccount.has.expired
regex.icontainsregexaccount.will.be.blocked
regex.icontainsregexaccount v[il]o[li]at
regex.icontainsregexactivity.*acc(oun)?t
regex.icontainsregexalmost.full
regex.icontainsregexapp[li]e.[il]d
regex.icontainsregexauthenticate.*account
regex.icontainsregexbeen.*suspend
regex.icontainsregexclos.*of.*account.*processed
regex.icontainsregexconfirm.your.account
regex.icontainsregexcourier.*able
regex.icontainsregexcrediential.*notif
regex.icontainsregexdeactivation.*in.*progress
regex.icontainsregexdelivery.*attempt.*failed
regex.icontainsregexdocument.received
regex.icontainsregexdocumented.*shared.*with.*you
regex.icontainsregexdropbox.*document
regex.icontainsregexe-?ma[il1]+ .{010}suspen
regex.icontainsregexe-?ma[il1]{1} user
regex.icontainsregexe-?ma[il1]{2} acc
regex.icontainsregexe-?ma[il1]{2}.*up.?grade
regex.icontainsregexe.?ma[il1]{2}.*server
regex.icontainsregexe.?ma[il1]{2}.*suspend
regex.icontainsregexemail.update
regex.icontainsregexfaxed you
regex.icontainsregexfraud(ulent)?.*charge
regex.icontainsregexfrom.helpdesk
regex.icontainsregexfu[il1]{2}.*ma[il1]+[ -]?box
regex.icontainsregexhas.been.*suspended
regex.icontainsregexhas.been.limited
regex.icontainsregexhave.locked
regex.icontainsregexhe[li]p ?desk upgrade
regex.icontainsregexheipdesk
regex.icontainsregexi[il]iega[il]
regex.icontainsregexii[il]ega[il]
regex.icontainsregexincoming e?mail
regex.icontainsregexincoming.*fax
regex.icontainsregexlock.*security
regex.icontainsregexma[il1]{1}[ -]?box.*quo
regex.icontainsregexma[il1]{2}[ -]?box.*fu[il1]
regex.icontainsregexma[il1]{2}box.*[il1]{2}mit
regex.icontainsregexma[il1]{2}box stor
regex.icontainsregexmail on.?hold
regex.icontainsregexmail.*box.*migration
regex.icontainsregexmail.*de-?activat
regex.icontainsregexmail.update.required
regex.icontainsregexmails.*pending
regex.icontainsregexmessages.*pending
regex.icontainsregexmissed.*shipping.*notification
regex.icontainsregexmissed.shipment.notification
regex.icontainsregexmust.update.your.account
regex.icontainsregexnew [sl][io]g?[nig][ -]?in from
regex.icontainsregexnew voice ?-?mail
regex.icontainsregexnotifications.*pending
regex.icontainsregexoffice.*3.*6.*5.*suspend
regex.icontainsregexoffice365
regex.icontainsregexon google docs with you
regex.icontainsregexonline doc
regex.icontainsregexpassword.*compromised
regex.icontainsregexperiodic maintenance
regex.icontainsregexpotential(ly)? unauthorized
regex.icontainsregexrefund not approved
regex.icontainsregexrevised.*policy
regex.icontainsregexscam
regex.icontainsregexscanned.?invoice
regex.icontainsregexsecured?.update
regex.icontainsregexsecurity breach
regex.icontainsregexsecurlty
regex.icontainsregexsigned.*delivery
regex.icontainsregexstatus of your .{314}? ?delivery
regex.icontainsregexsusp[il1]+c[il1]+ous.*act[il1]+v[il1]+ty
regex.icontainsregexsuspicious.*sign.*[io]n
regex.icontainsregexsuspicious.activit
regex.icontainsregextemporar(il)?y deactivate
regex.icontainsregextemporar[il1]{2}y disab[li]ed
regex.icontainsregextemporarily.*lock
regex.icontainsregexun-?usua[li].activity
regex.icontainsregexunable.*deliver
regex.icontainsregexunauthorized.*activit
regex.icontainsregexunauthorized.device
regex.icontainsregexundelivered message
regex.icontainsregexunread.*doc
regex.icontainsregexunusual.activity
regex.icontainsregexupgrade.*account
regex.icontainsregexupgrade.notice
regex.icontainsregexurgent message
regex.icontainsregexurgent.verification
regex.icontainsregexv[il1]o[li1]at[il1]on security
regex.icontainsregexva[il1]{1}date.*ma[il1]{2}[ -]?box
regex.icontainsregexverification ?-?require
regex.icontainsregexverification( )?-?need
regex.icontainsregexverify.your?.account
regex.icontainsregexweb ?-?ma[il1]{2}
regex.icontainsregexweb[ -]?ma[il1]{2}
regex.icontainsregexwill.be.suspended
regex.icontainsregexyour (customer )?account .as
regex.icontainsregexyour.office.365
regex.icontainsregexyour.online.access
regex.icontainsregexaccount has been limited
regex.icontainsregexaction required
regex.icontainsregexalmost full
regex.icontainsregexapd notifi cation
regex.icontainsregexare you at your desk
regex.icontainsregexare you available
regex.icontainsregexattached file to docusign
regex.icontainsregexbanking is temporarily unavailable
regex.icontainsregexbankofamerica
regex.icontainsregexclosing statement invoice
regex.icontainsregexcompleted: docusign
regex.icontainsregexde-activation of
regex.icontainsregexdelivery attempt
regex.icontainsregexdelivery stopped for shipment
regex.icontainsregexdetected suspicious
regex.icontainsregexdetected suspicious actvity
regex.icontainsregexdocu sign
regex.icontainsregexdocument for you
regex.icontainsregexdocument has been sent to you via docusign
regex.icontainsregexdocument is ready for signature
regex.icontainsregexdocusign
regex.icontainsregexencrypted message
regex.icontainsregexfailed delivery
regex.icontainsregexfedex tracking
regex.icontainsregexfile was shared
regex.icontainsregexfreefax
regex.icontainsregexfwd: due invoice paid
regex.icontainsregexhas shared
regex.icontainsregexinbox is full
regex.icontainsregexinvitation to comment
regex.icontainsregexinvitation to edit
regex.icontainsregexinvoice due
regex.icontainsregexleft you a message
regex.icontainsregexmessage from
regex.icontainsregexnew message
regex.icontainsregexnew voicemail
regex.icontainsregexon desk
regex.icontainsregexout of space
regex.icontainsregexpassword reset
regex.icontainsregexpayment status
regex.icontainsregexquick reply
regex.icontainsregexre: w-2
regex.icontainsregexrequired
regex.icontainsregexrequired: completed docusign
regex.icontainsregexringcentral
regex.icontainsregexscanned image
regex.icontainsregexsecured files
regex.icontainsregexsecured pdf
regex.icontainsregexsecurity alert
regex.icontainsregexnew sign-in
regex.icontainsregexnew sign in
regex.icontainsregexsign-in attempt
regex.icontainsregexsign in attempt
regex.icontainsregexstaff review
regex.icontainsregexsuspicious activity
regex.icontainsregexunrecognized login attempt
regex.icontainsregexupgrade immediately
regex.icontainsregexurgent
regex.icontainsregexwants to share
regex.icontainsregexw2
regex.icontainsregexyou have notifications pending
regex.icontainsregexyour account
regex.icontainsregexyour amazon order
regex.icontainsregexyour document settlement
regex.icontainsregexyour order with amazon
regex.icontainsregexyour password has been compromised

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(attachments)
      or
        and
          attachments.content_type eq "application/octet-stream"
          attachments.file_extension is_null
          attachments.file_type eq "unknown"
          attachments.size lt "100000000"
        attachments.file_type eq "lz"
         macro "attachments[].file_type in file_extensions_common_archives"
         macro "attachments[].file_type in file_extensions_executables"
         macro "attachments[].file_type in file_extensions_macros"
    any(body.links)
      or
        body.links.display_text regex_match "38417"
        body.links.display_text regex_match ":completed"
        body.links.display_text regex_match "[il1]{2}mit.*ma[il1]{2} ?bo?x"
        body.links.display_text regex_match "[il][il][il]egai[ -]"
        body.links.display_text regex_match "[li][li][li]ega[li] attempt"
        body.links.display_text regex_match "[ng]-?[io]n .*block"
        body.links.display_text regex_match "[ng]-?[io]n .*cancel"
        body.links.display_text regex_match "[ng]-?[io]n .*deactiv"
        body.links.display_text regex_match "[ng]-?[io]n .*disabl"
        body.links.display_text regex_match "abandon.*package"
        body.links.display_text regex_match "about.your.account"
        body.links.display_text regex_match "acc(ou)?n?t (is )?on ho[li]d"
        body.links.display_text regex_match "acc(ou)?n?t.*terminat"
        body.links.display_text regex_match "acc(oun)?t.*[il1]{2}mitation"
        body.links.display_text regex_match "access.*limitation"
        body.links.display_text regex_match "account (will be )?block"
        body.links.display_text regex_match "account has been limited"
        body.links.display_text regex_match "account v[il]o[li]at"
        body.links.display_text regex_match "account.*de-?activat"
        body.links.display_text regex_match "account.*locked"
        body.links.display_text regex_match "account.*re-verification"
        body.links.display_text regex_match "account.*security"
        body.links.display_text regex_match "account.*suspension"
        body.links.display_text regex_match "account.has.been"
        body.links.display_text regex_match "account.has.expired"
        body.links.display_text regex_match "account.will.be.blocked"
        body.links.display_text regex_match "action required"
        body.links.display_text regex_match "action.*required"
        body.links.display_text regex_match "activity.*acc(oun)?t"
        body.links.display_text regex_match "almost full"
        body.links.display_text regex_match "almost.full"
        body.links.display_text regex_match "apd notifi cation"
        body.links.display_text regex_match "app[li]e.[il]d"
        body.links.display_text regex_match "are you at your desk"
        body.links.display_text regex_match "are you available"
        body.links.display_text regex_match "attached file to docusign"
        body.links.display_text regex_match "authenticate.*account"
        body.links.display_text regex_match "banking is temporarily unavailable"
        body.links.display_text regex_match "bankofamerica"
        body.links.display_text regex_match "been.*suspend"
        body.links.display_text regex_match "clos.*of.*account.*processed"
        body.links.display_text regex_match "closing statement invoice"
        body.links.display_text regex_match "completed: docusign"
        body.links.display_text regex_match "confirm.your.account"
        body.links.display_text regex_match "courier.*able"
        body.links.display_text regex_match "crediential.*notif"
        body.links.display_text regex_match "de-activation of"
        body.links.display_text regex_match "deactivation.*in.*progress"
        body.links.display_text regex_match "delivery attempt"
        body.links.display_text regex_match "delivery stopped for shipment"
        body.links.display_text regex_match "delivery.*attempt.*failed"
        body.links.display_text regex_match "detected suspicious actvity"
        body.links.display_text regex_match "detected suspicious"
        body.links.display_text regex_match "docu sign"
        body.links.display_text regex_match "document for you"
        body.links.display_text regex_match "document has been sent to you via docusign"
        body.links.display_text regex_match "document is ready for signature"
        body.links.display_text regex_match "document.received"
        body.links.display_text regex_match "documented.*shared.*with.*you"
        body.links.display_text regex_match "docusign"
        body.links.display_text regex_match "dropbox.*document"
        body.links.display_text regex_match "e-?ma[il1]+ .{010}suspen"
        body.links.display_text regex_match "e-?ma[il1]{1} user"
        body.links.display_text regex_match "e-?ma[il1]{2} acc"
        body.links.display_text regex_match "e-?ma[il1]{2}.*up.?grade"
        body.links.display_text regex_match "e.?ma[il1]{2}.*server"
        body.links.display_text regex_match "e.?ma[il1]{2}.*suspend"
        body.links.display_text regex_match "email.update"
        body.links.display_text regex_match "encrypted message"
        body.links.display_text regex_match "failed delivery"
        body.links.display_text regex_match "faxed you"
        body.links.display_text regex_match "fedex tracking"
        body.links.display_text regex_match "file was shared"
        body.links.display_text regex_match "fraud(ulent)?.*charge"
        body.links.display_text regex_match "freefax"
        body.links.display_text regex_match "from.helpdesk"
        body.links.display_text regex_match "fu[il1]{2}.*ma[il1]+[ -]?box"
        body.links.display_text regex_match "fwd: due invoice paid"
        body.links.display_text regex_match "has shared"
        body.links.display_text regex_match "has.been.*suspended"
        body.links.display_text regex_match "has.been.limited"
        body.links.display_text regex_match "have.locked"
        body.links.display_text regex_match "he[li]p ?desk upgrade"
        body.links.display_text regex_match "heipdesk"
        body.links.display_text regex_match "i[il]iega[il]"
        body.links.display_text regex_match "ii[il]ega[il]"
        body.links.display_text regex_match "inbox is full"
        body.links.display_text regex_match "incoming e?mail"
        body.links.display_text regex_match "incoming.*fax"
        body.links.display_text regex_match "invitation to comment"
        body.links.display_text regex_match "invitation to edit"
        body.links.display_text regex_match "invoice due"
        body.links.display_text regex_match "left you a message"
        body.links.display_text regex_match "lock.*security"
        body.links.display_text regex_match "ma[il1]{1}[ -]?box.*quo"
        body.links.display_text regex_match "ma[il1]{2}[ -]?box.*fu[il1]"
        body.links.display_text regex_match "ma[il1]{2}box stor"
        body.links.display_text regex_match "ma[il1]{2}box.*[il1]{2}mit"
        body.links.display_text regex_match "mail on.?hold"
        body.links.display_text regex_match "mail.*box.*migration"
        body.links.display_text regex_match "mail.*de-?activat"
        body.links.display_text regex_match "mail.update.required"
        body.links.display_text regex_match "mails.*pending"
        body.links.display_text regex_match "message from"
        body.links.display_text regex_match "messages.*pending"
        body.links.display_text regex_match "missed.*shipping.*notification"
        body.links.display_text regex_match "missed.shipment.notification"
        body.links.display_text regex_match "must.update.your.account"
        body.links.display_text regex_match "new [sl][io]g?[nig][ -]?in from"
        body.links.display_text regex_match "new message"
        body.links.display_text regex_match "new sign in"
        body.links.display_text regex_match "new sign-in"
        body.links.display_text regex_match "new voice ?-?mail"
        body.links.display_text regex_match "new voicemail"
        body.links.display_text regex_match "notifications.*pending"
        body.links.display_text regex_match "office.*3.*6.*5.*suspend"
        body.links.display_text regex_match "office365"
        body.links.display_text regex_match "on desk"
        body.links.display_text regex_match "on google docs with you"
        body.links.display_text regex_match "online doc"
        body.links.display_text regex_match "out of space"
        body.links.display_text regex_match "password reset"
        body.links.display_text regex_match "password.*compromised"
        body.links.display_text regex_match "payment status"
        body.links.display_text regex_match "periodic maintenance"
        body.links.display_text regex_match "potential(ly)? unauthorized"
        body.links.display_text regex_match "quick reply"
        body.links.display_text regex_match "re: w-2"
        body.links.display_text regex_match "refund not approved"
        body.links.display_text regex_match "required"
        body.links.display_text regex_match "required: completed docusign"
        body.links.display_text regex_match "revised.*policy"
        body.links.display_text regex_match "ringcentral"
        body.links.display_text regex_match "scam"
        body.links.display_text regex_match "scanned image"
        body.links.display_text regex_match "scanned.?invoice"
        body.links.display_text regex_match "secured files"
        body.links.display_text regex_match "secured pdf"
        body.links.display_text regex_match "secured?.update"
        body.links.display_text regex_match "security alert"
        body.links.display_text regex_match "security breach"
        body.links.display_text regex_match "securlty"
        body.links.display_text regex_match "sign in attempt"
        body.links.display_text regex_match "sign-in attempt"
        body.links.display_text regex_match "signed.*delivery"
        body.links.display_text regex_match "staff review"
        body.links.display_text regex_match "status of your .{314}? ?delivery"
        body.links.display_text regex_match "susp[il1]+c[il1]+ous.*act[il1]+v[il1]+ty"
        body.links.display_text regex_match "suspicious activity"
        body.links.display_text regex_match "suspicious.*sign.*[io]n"
        body.links.display_text regex_match "suspicious.activit"
        body.links.display_text regex_match "temporar(il)?y deactivate"
        body.links.display_text regex_match "temporar[il1]{2}y disab[li]ed"
        body.links.display_text regex_match "temporarily.*lock"
        body.links.display_text regex_match "termination.*notice"
        body.links.display_text regex_match "un-?usua[li].activity"
        body.links.display_text regex_match "unable.*deliver"
        body.links.display_text regex_match "unauthorized.*activit"
        body.links.display_text regex_match "unauthorized.device"
        body.links.display_text regex_match "undelivered message"
        body.links.display_text regex_match "unread.*doc"
        body.links.display_text regex_match "unrecognized login attempt"
        body.links.display_text regex_match "unusual.activity"
        body.links.display_text regex_match "upgrade immediately"
        body.links.display_text regex_match "upgrade.*account"
        body.links.display_text regex_match "upgrade.notice"
        body.links.display_text regex_match "urgent message"
        body.links.display_text regex_match "urgent"
        body.links.display_text regex_match "urgent.verification"
        body.links.display_text regex_match "v[il1]o[li1]at[il1]on security"
        body.links.display_text regex_match "va[il1]{1}date.*ma[il1]{2}[ -]?box"
        body.links.display_text regex_match "verification ?-?require"
        body.links.display_text regex_match "verification( )?-?need"
        body.links.display_text regex_match "verify.your?.account"
        body.links.display_text regex_match "w2"
        body.links.display_text regex_match "wants to share"
        body.links.display_text regex_match "web ?-?ma[il1]{2}"
        body.links.display_text regex_match "web[ -]?ma[il1]{2}"
        body.links.display_text regex_match "will.be.suspended"
        body.links.display_text regex_match "you have notifications pending"
        body.links.display_text regex_match "your (customer )?account .as"
        body.links.display_text regex_match "your account"
        body.links.display_text regex_match "your amazon order"
        body.links.display_text regex_match "your document settlement"
        body.links.display_text regex_match "your order with amazon"
        body.links.display_text regex_match "your password has been compromised"
        body.links.display_text regex_match "your.office.365"
        body.links.display_text regex_match "your.online.access"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    any(ml.nlu_classifier(body.current_thread.text).intents)
      and
        ml.nlu_classifier(body.current_thread.text).intents.confidence eq "high"
        ml.nlu_classifier(body.current_thread.text).intents.name in ["cred_theft", "steal_pii"]
    any(ml.nlu_classifier(body.current_thread.text).tags)
      ml.nlu_classifier(body.current_thread.text).tags.name in ["invoice", "payment"]
  or
    sender.display_name regex_match "\\bwise\\b"
    sender.email.domain.domain match "wise"
  not
    sender.email.domain.root_domain in ["connectwise.com", "splitwise.com", "wise.com", "wise.jobs"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaininconnectwise.com, splitwise.com, wise.com, wise.jobsexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Wix

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

Detects messages impersonating Wix by using similar display names or domain names, while not originating from legitimate WIX domains or failing DMARC authentication from trusted senders.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • headers.domains
  • sender.email
  • type

Rule body

type.inbound
and (
  (
    regex.icontains(sender.display_name, '^WIX\b')
    or strings.ilike(sender.email.domain.domain, 'WIX')
  )
  or (
    strings.icontains(sender.display_name, 'wix')
    and regex.icontains(body.current_thread.text,
                        "Domain Expir(?:ation|y) Not(?:ice|ification)"
    )
    and strings.icontains(body.current_thread.text, "will be deactivated")
  )
  or regex.icontains(sender.display_name, 'w\x{206E}+i\x{206E}+x')
  // Wix address from footer
  or 2 of (
    strings.icontains(body.current_thread.text, 'Wix.com'),
    strings.icontains(body.current_thread.text, '100 Gansevoort St'),
    strings.icontains(body.current_thread.text, 'New York, NY 10014')
  )
  or (
    any(ml.nlu_classifier(body.current_thread.text).entities,
        .name in ("sender", "org") and regex.icontains(.text, '^wix\b')
    )
    and any(ml.nlu_classifier(body.current_thread.text).intents,
            .name == "cred_theft" and .confidence != "low"
    )
  )
)
and not (
  (
    sender.email.domain.root_domain in~ (
      "wix.com",
      "wixforms.com",
      "wixemails.com",
      "wixanswers.com",
      "wix-groups.com",
      "ascendbywix.com"
    )
    and headers.auth_summary.dmarc.pass
  )
)
// negation for messages traversing wix.com
and not (
  any(headers.domains, .root_domain in ("wix.com", "ascendbywix.com"))
  and headers.auth_summary.spf.pass
  and headers.auth_summary.dmarc.pass
)
and not profile.by_sender().solicited
// 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.

Detects messages impersonating Wix by using similar display names or domain names, while not originating from legitimate WIX domains or failing DMARC authentication from trusted senders.

  1. inbound message
  2. any of:
    • any of:
      • sender.display_name matches '^WIX\\b'
      • sender.email.domain.domain matches 'WIX'
    • all of:
      • sender.display_name contains 'wix'
      • body.current_thread.text matches 'Domain Expir(?:ation|y) Not(?:ice|ification)'
      • body.current_thread.text contains 'will be deactivated'
    • sender.display_name matches 'w\\x{206E}+i\\x{206E}+x'
    • at least 2 of:
      • body.current_thread.text contains 'Wix.com'
      • body.current_thread.text contains '100 Gansevoort St'
      • body.current_thread.text contains 'New York, NY 10014'
    • all of:
      • any of ml.nlu_classifier(body.current_thread.text).entities where all hold:
        • .name in ('sender', 'org')
        • .text matches '^wix\\b'
      • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
        • .name is 'cred_theft'
        • .confidence is not 'low'
  3. not:
    • all of:
      • sender.email.domain.root_domain in ('wix.com', 'wixforms.com', 'wixemails.com', 'wixanswers.com', 'wix-groups.com', 'ascendbywix.com')
      • headers.auth_summary.dmarc.pass
  4. not:
    • all of:
      • any of headers.domains where:
        • .root_domain in ('wix.com', 'ascendbywix.com')
      • headers.auth_summary.spf.pass
      • headers.auth_summary.dmarc.pass
  5. not:
    • profile.by_sender().solicited
  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.auth_summary.spf.pass, headers.domains, headers.domains[].root_domain, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender, regex.icontains, strings.icontains, strings.ilike. Reference lists: $high_trust_sender_root_domains.

Indicators matched (13)

FieldMatchValue
regex.icontainsregex^WIX\b
strings.ilikesubstringWIX
strings.icontainssubstringwix
regex.icontainsregexDomain Expir(?:ation|y) Not(?:ice|ification)
strings.icontainssubstringwill be deactivated
regex.icontainsregexw\x{206E}+i\x{206E}+x
strings.icontainssubstringWix.com
strings.icontainssubstring100 Gansevoort St
strings.icontainssubstringNew York, NY 10014
ml.nlu_classifier(body.current_thread.text).entities[].namemembersender
ml.nlu_classifier(body.current_thread.text).entities[].namememberorg
regex.icontainsregex^wix\b
1 more
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      any(ml.nlu_classifier(body.current_thread.text).entities)
        and
          ml.nlu_classifier(body.current_thread.text).entities.name in ["org", "sender"]
          ml.nlu_classifier(body.current_thread.text).entities.text regex_match "^wix\\b"
      any(ml.nlu_classifier(body.current_thread.text).intents)
        and
          ml.nlu_classifier(body.current_thread.text).intents.confidence ne "low"
          ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
    and
      body.current_thread.text contains "will be deactivated"
      body.current_thread.text regex_match "Domain Expir(?:ation|y) Not(?:ice|ification)"
      sender.display_name contains "wix"
    body.current_thread.text contains "100 Gansevoort St"
    body.current_thread.text contains "New York, NY 10014"
    body.current_thread.text contains "Wix.com"
    sender.display_name regex_match "^WIX\\b"
    sender.display_name regex_match "w\\x{206E}+i\\x{206E}+x"
    sender.email.domain.domain eq "WIX"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    and
      any(headers.domains)
        headers.domains.root_domain in ["ascendbywix.com", "wix.com"]
      headers.auth_summary.dmarc.pass eq "true"
      headers.auth_summary.spf.pass eq "true"
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.root_domain in ["ascendbywix.com", "wix-groups.com", "wix.com", "wixanswers.com", "wixemails.com", "wixforms.com"]
  not
    profile.by_sender func_call "profile.by_sender().solicited"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.domainsarray_any(no value, null check)excludes:headers.domains
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
headers.auth_summary.spf.passeqtrueexcludes:headers.auth_summary.spf.pass field:"headers.auth_summary.spf.pass" value:"true"
sender.email.domain.root_domaininascendbywix.com, wix-groups.com, wix.com, wixanswers.com, wixemails.com, wixforms.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Zoom (strict)

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

Impersonation of the video conferencing provider Zoom. This "strict" version of this rule will only flag when the sender's display name matches those used by Zoom exactly.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • sender.email
  • type

Rule body

type.inbound
and (
  sender.display_name =~ 'zoom'
  or sender.display_name =~ 'zoom video communications, inc.'
  or sender.display_name =~ 'zoom call'
)
and sender.email.domain.root_domain not in (
  'zoom.us',
  'zuora.com',
  'zoomgov.com',
  'zoom.com'
)
and (
  // if this comes from a free email provider,
  // flag if org has never sent an email to sender's email before
  (
    sender.email.domain.root_domain in $free_email_providers
    and not profile.by_sender().solicited
  )
  // if this comes from a custom domain,
  // flag if org has never sent an email to sender's domain before
  or (
    sender.email.domain.root_domain not in $free_email_providers
    and not profile.by_sender().solicited
  )
)

Detection logic

Scope: inbound message.

Impersonation of the video conferencing provider Zoom. This "strict" version of this rule will only flag when the sender's display name matches those used by Zoom exactly.

  1. inbound message
  2. any of:
    • sender.display_name is 'zoom'
    • sender.display_name is 'zoom video communications, inc.'
    • sender.display_name is 'zoom call'
  3. sender.email.domain.root_domain not in ('zoom.us', 'zuora.com', 'zoomgov.com', 'zoom.com')
  4. any of:
    • all of:
      • sender.email.domain.root_domain in $free_email_providers
      • not:
        • profile.by_sender().solicited
    • all of:
      • sender.email.domain.root_domain not in $free_email_providers
      • not:
        • profile.by_sender().solicited

Inspects: sender.display_name, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender. Reference lists: $free_email_providers.

Indicators matched (3)

FieldMatchValue
sender.display_nameequalszoom
sender.display_nameequalszoom video communications, inc.
sender.display_nameequalszoom call

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().solicited"
       macro "sender.email.domain.root_domain in free_email_providers"
    and
      not
        profile.by_sender func_call "profile.by_sender().solicited"
       macro "sender.email.domain.root_domain not in free_email_providers"
  or
    sender.display_name eq "zoom call"
    sender.display_name eq "zoom video communications, inc."
    sender.display_name eq "zoom"
  not
    sender.email.domain.root_domain in ["zoom.com", "zoom.us", "zoomgov.com", "zuora.com"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaininzoom.com, zoom.us, zoomgov.com, zuora.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
sender.display_nameeq
  • zoom
  • zoom call
  • zoom video communications, inc.
field:"sender.display_name" kind:eq
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Display name and subject impersonation using recipient SLD (new sender)

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

The recipient domain's SLD is used in the sender's display name and in the subject to impersonate the organization.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.links
  • headers
  • headers.auth_summary
  • mailbox
  • recipients
  • recipients.to
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  // recipient SLD is being impersonated in the subject + display name
  (
    // these are usually targeted with just 1 recipient,
    // but sometimes they CC themselves or have a blank CC
    (
      length(recipients.to) + length(recipients.cc) + length(recipients.bcc) <= 2
    )
    and any(recipients.to,
            length(.email.domain.sld) >= 4
            // ensure that we're checking the org SLD
            and .email.domain.sld in $org_slds
            and strings.icontains(subject.subject, .email.domain.sld)
            and strings.icontains(sender.display_name, .email.domain.sld)
    )
  )
  or (
    // accounts for BCC'd messages where the recipients are empty
    // if BCC, sometimes the recipient will be the attacker's email
    (
      length(recipients.to) + length(recipients.cc) + length(recipients.bcc) <= 2
    )
    and length(mailbox.email.domain.sld) >= 4
    and strings.icontains(subject.subject, mailbox.email.domain.sld)
    and strings.icontains(sender.display_name, mailbox.email.domain.sld)
  )
)
and (
  // at least 1 link or non-image attachment
  (
    length(body.links) > 0
    // these attacks all use compromosed senders, so we look for a domain
    // that doesn't match the sender's domain to weed out legit messages
    and any(body.links,
            .href_url.domain.root_domain != sender.email.domain.root_domain
    )
  )
  or length(filter(attachments, .file_type not in $file_types_images)) > 0
)
and not (
  strings.contains(sender.display_name, "on behalf of")
  and sender.email.domain.root_domain == "microsoftonline.com"
)
and all(recipients.to, .email.email != sender.email.email)

// negate org domain senders, which can often be misconfigured and fail
// authentication, causing them to be type.inbound instead of type.internal.
// this is fine because we should catch spoofs in other ways.
// also, we use root_domain here to account for subdomains used by internal tools that aren't connected to the tenant.
// this should also be safe because domains like onmicrosoft[.]com are tracked as FQDNs in $org_domains, so they won't match
and sender.email.domain.root_domain not in $org_domains

// 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
)
and (
  not profile.by_sender().solicited
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

The recipient domain's SLD is used in the sender's display name and in the subject to impersonate the organization.

  1. inbound message
  2. any of:
    • all of:
      • length(recipients.to) + length(recipients.cc) + length(recipients.bcc) ≤ 2
      • any of recipients.to where all hold:
        • length(.email.domain.sld) ≥ 4
        • .email.domain.sld in $org_slds
        • strings.icontains(subject.subject)
        • strings.icontains(sender.display_name)
    • all of:
      • length(recipients.to) + length(recipients.cc) + length(recipients.bcc) ≤ 2
      • length(mailbox.email.domain.sld) ≥ 4
      • strings.icontains(subject.subject)
      • strings.icontains(sender.display_name)
  3. any of:
    • all of:
      • length(body.links) > 0
      • any of body.links where:
        • .href_url.domain.root_domain is not sender.email.domain.root_domain
    • length(filter(attachments, .file_type not in $file_types_images)) > 0
  4. not:
    • all of:
      • sender.display_name contains 'on behalf of'
      • sender.email.domain.root_domain is 'microsoftonline.com'
  5. all of recipients.to where:
    • .email.email is not sender.email.email
  6. sender.email.domain.root_domain not in $org_domains
  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
  8. any of:
    • not:
      • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  9. not:
    • profile.by_sender().any_messages_benign

Inspects: attachments[].file_type, body.links, body.links[].href_url.domain.root_domain, headers.auth_summary.dmarc.pass, mailbox.email.domain.sld, recipients.to, recipients.to[].email.domain.sld, recipients.to[].email.email, sender.display_name, sender.email.domain.root_domain, sender.email.email, subject.subject, type.inbound. Sensors: profile.by_sender, strings.contains, strings.icontains. Reference lists: $file_types_images, $high_trust_sender_root_domains, $org_domains, $org_slds.

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      any(recipients.to)
        and
          recipients.to.email.domain.sld length_compare "4"
          strings.icontains func_call "strings.icontains(sender.display_name)"
          strings.icontains func_call "strings.icontains(subject.subject)"
           macro "recipients.to[].email.domain.sld in org_slds"
       macro "((length(recipients.to) + length(recipients.cc)) + length(recipients.bcc)) <= 2"
    and
      mailbox.email.domain.sld length_compare "4"
      strings.icontains func_call "strings.icontains(sender.display_name)"
      strings.icontains func_call "strings.icontains(subject.subject)"
       macro "((length(recipients.to) + length(recipients.cc)) + length(recipients.bcc)) <= 2"
  or
    and
      any(body.links)
        body.links.href_url.domain.root_domain cross_field_compare "sender.email.domain.root_domain"
      body.links length_compare "0"
    filter(attachments, .file_type not in $file_types_images) length_compare "0"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    not
      profile.by_sender func_call "profile.by_sender().solicited"
  not
    and
      sender.display_name contains "on behalf of"
      sender.email.domain.root_domain eq "microsoftonline.com"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  type.inbound eq "true"
   macro "all(recipients.to)"
   macro "sender.email.domain.root_domain not in org_domains"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.display_namecontainson behalf ofexcludes:sender.display_name field:"sender.display_name" value:"on behalf of"
sender.email.domain.root_domaineqmicrosoftonline.comexcludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"microsoftonline.com"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Display name impersonation using recipient SLD

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

The recipient domain's SLD is used in the sender's display name in order to impersonate the organization.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.links
  • headers
  • headers.auth_summary
  • mailbox
  • recipients
  • recipients.to
  • sender.email
  • type

Rule body

type.inbound
and (
  // recipient SLD is being impersonated in the display name
  (
    // these are usually targeted with just 1 recipient,
    // but sometimes they CC themselves or have a blank CC
    length(recipients.to) + length(recipients.cc)
 + length(recipients.bcc) <= 2
    and any(recipients.to,
            length(.email.domain.sld) >= 4
            and 
            // ensure that we're checking the org SLD
            .email.domain.sld in $org_slds
            and strings.icontains(sender.display_name, .email.domain.sld)
    )
  )
  or (
    // accounts for BCC'd messages where the recipients are empty
    // if BCC, sometimes the recipient will be the attacker's email
    length(recipients.to) + length(recipients.cc)
 + length(recipients.bcc) <= 2
    and length(mailbox.email.domain.sld) >= 4
    and strings.icontains(sender.display_name, mailbox.email.domain.sld)
  )
)
and (
  // at least 1 link or non-image attachment
  (
    length(body.links) > 0
    // these attacks all use compromosed senders, so we look for a domain
    // that doesn't match the sender's domain to weed out legit messages
    and any(body.links,
            .href_url.domain.root_domain != sender.email.domain.root_domain
    )
  )
  or length(filter(attachments, .file_type not in $file_types_images)) > 0
)
and not (
  strings.contains(sender.display_name, "on behalf of")
  and sender.email.domain.root_domain == "microsoftonline.com"
)
// negate pageproof updates and visit notifications
and not (sender.email.email in ("team@pageproof.com", "noreply@visitly.io"))
and all(recipients.to,
        .email.email != sender.email.email
        and (
          .email.domain.valid or strings.icontains(.display_name, "undisclosed")
        )
)

// negate org domain senders, which can often be misconfigured and fail
// authentication, causing them to be type.inbound instead of type.internal.
// this is fine because we should catch spoofs in other ways.
// also, we use root_domain here to account for subdomains used by internal tools that aren't connected to the tenant.
// this should also be safe because domains like onmicrosoft[.]com are tracked as FQDNs in $org_domains, so they won't match
and sender.email.domain.root_domain not in $org_domains
// negate tenant_domains
and not (
  sender.email.domain.domain in $tenant_domains
  and headers.auth_summary.dmarc.pass
)

// 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
)
and (
  (not profile.by_sender().solicited)
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

The recipient domain's SLD is used in the sender's display name in order to impersonate the organization.

  1. inbound message
  2. any of:
    • all of:
      • length(recipients.to) + length(recipients.cc) + length(recipients.bcc) ≤ 2
      • any of recipients.to where all hold:
        • length(.email.domain.sld) ≥ 4
        • .email.domain.sld in $org_slds
        • strings.icontains(sender.display_name)
    • all of:
      • length(recipients.to) + length(recipients.cc) + length(recipients.bcc) ≤ 2
      • length(mailbox.email.domain.sld) ≥ 4
      • strings.icontains(sender.display_name)
  3. any of:
    • all of:
      • length(body.links) > 0
      • any of body.links where:
        • .href_url.domain.root_domain is not sender.email.domain.root_domain
    • length(filter(attachments, .file_type not in $file_types_images)) > 0
  4. not:
    • all of:
      • sender.display_name contains 'on behalf of'
      • sender.email.domain.root_domain is 'microsoftonline.com'
  5. not:
    • sender.email.email in ('team@pageproof.com', 'noreply@visitly.io')
  6. all of recipients.to where all hold:
    • .email.email is not sender.email.email
    • any of:
      • .email.domain.valid
      • .display_name contains 'undisclosed'
  7. sender.email.domain.root_domain not in $org_domains
  8. not:
    • all of:
      • sender.email.domain.domain in $tenant_domains
      • headers.auth_summary.dmarc.pass
  9. 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
  10. any of:
    • not:
      • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  11. not:
    • profile.by_sender().any_messages_benign

Inspects: attachments[].file_type, body.links, body.links[].href_url.domain.root_domain, headers.auth_summary.dmarc.pass, mailbox.email.domain.sld, recipients.to, recipients.to[].display_name, recipients.to[].email.domain.sld, recipients.to[].email.domain.valid, recipients.to[].email.email, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: profile.by_sender, strings.contains, strings.icontains. Reference lists: $file_types_images, $high_trust_sender_root_domains, $org_domains, $org_slds, $tenant_domains.

Indicators matched (1)

FieldMatchValue
strings.icontainssubstringundisclosed

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      any(recipients.to)
        and
          recipients.to.email.domain.sld length_compare "4"
          strings.icontains func_call "strings.icontains(sender.display_name)"
           macro "recipients.to[].email.domain.sld in org_slds"
       macro "((length(recipients.to) + length(recipients.cc)) + length(recipients.bcc)) <= 2"
    and
      mailbox.email.domain.sld length_compare "4"
      strings.icontains func_call "strings.icontains(sender.display_name)"
       macro "((length(recipients.to) + length(recipients.cc)) + length(recipients.bcc)) <= 2"
  or
    and
      any(body.links)
        body.links.href_url.domain.root_domain cross_field_compare "sender.email.domain.root_domain"
      body.links length_compare "0"
    filter(attachments, .file_type not in $file_types_images) length_compare "0"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    not
      profile.by_sender func_call "profile.by_sender().solicited"
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.domain in tenant_domains"
  not
    and
      sender.display_name contains "on behalf of"
      sender.email.domain.root_domain eq "microsoftonline.com"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  not
    sender.email.email in ["noreply@visitly.io", "team@pageproof.com"]
  type.inbound eq "true"
   macro "all(recipients.to)"
   macro "sender.email.domain.root_domain not in org_domains"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

DocuSign impersonation via CloudHQ links

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

Identifies messages containing CloudHQ share links from senders outside the CloudHQ domain who are impersonating DocuSign in either the subject line or display name.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, BEC/Fraud
Tactics and techniquesImpersonation: Brand, Free file host

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • sender.email
  • subject
  • type

Rule body

type.inbound
and sender.email.domain.root_domain != 'cloudhq.net'
and any(body.links,
        .href_url.domain.root_domain == "cloudhq.net"
        and strings.starts_with(.href_url.path, "/s/")
)

// the subject or display_name includes docusign
and (
  regex.icontains(strings.replace_confusables(subject.subject),
                  '\bdocu\s*sign\b'
  )
  or regex.icontains(strings.replace_confusables(sender.display_name),
                     '\bdocu\s*sign\b'
  )
)

// there is one unique cloudhq link in the message
and length(distinct(filter(body.links,
                           .href_url.domain.root_domain == "cloudhq.net"
                    ),
                    .href_url.url
           )
) <= 1

Detection logic

Scope: inbound message.

Identifies messages containing CloudHQ share links from senders outside the CloudHQ domain who are impersonating DocuSign in either the subject line or display name.

  1. inbound message
  2. sender.email.domain.root_domain is not 'cloudhq.net'
  3. any of body.links where all hold:
    • .href_url.domain.root_domain is 'cloudhq.net'
    • .href_url.path starts with '/s/'
  4. any of:
    • strings.replace_confusables(subject.subject) matches '\\bdocu\\s*sign\\b'
    • strings.replace_confusables(sender.display_name) matches '\\bdocu\\s*sign\\b'
  5. length(distinct(filter(body.links, .href_url.domain.root_domain == 'cloudhq.net'), .href_url.url)) ≤ 1

Inspects: body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.path, sender.display_name, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: regex.icontains, strings.replace_confusables, strings.starts_with.

Indicators matched (3)

FieldMatchValue
body.links[].href_url.domain.root_domainequalscloudhq.net
strings.starts_withprefix/s/
regex.icontainsregex\bdocu\s*sign\b

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      body.links.href_url.domain.root_domain eq "cloudhq.net"
      body.links.href_url.path starts_with "/s/"
  or
    strings.replace_confusables(sender.display_name) regex_match "\\bdocu\\s*sign\\b"
    strings.replace_confusables(subject.subject) regex_match "\\bdocu\\s*sign\\b"
  distinct(filter(body.links, .href_url.domain.root_domain == 'cloudhq.net'), .href_url.url) length_compare "1"
  sender.email.domain.root_domain ne "cloudhq.net"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

DocuSign impersonation via spoofed Intuit sender

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

Detects messages appearing to come from Intuit domains with authentication failures while masquerading as DocuSign communications. The sender fails either SPF or DMARC verification, and includes DocuSign branding in either the subject line or display name.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Spoofing

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.auth_summary
  • sender.email
  • subject
  • type

Rule body

type.inbound
and sender.email.domain.root_domain in ("intuit.com")
// email auth fails
and (
  not headers.auth_summary.spf.pass
  or not coalesce(headers.auth_summary.dmarc.pass, false)
)
// the subject or display_name includes docusign
and (
  strings.icontains(subject.subject, "docusign")
  or strings.icontains(sender.display_name, "docusign")
)

Detection logic

Scope: inbound message.

Detects messages appearing to come from Intuit domains with authentication failures while masquerading as DocuSign communications. The sender fails either SPF or DMARC verification, and includes DocuSign branding in either the subject line or display name.

  1. inbound message
  2. sender.email.domain.root_domain in ('intuit.com')
  3. any of:
    • not:
      • headers.auth_summary.spf.pass
    • not:
      • coalesce(headers.auth_summary.dmarc.pass)
  4. any of:
    • subject.subject contains 'docusign'
    • sender.display_name contains 'docusign'

Inspects: headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, sender.display_name, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: strings.icontains.

Indicators matched (2)

FieldMatchValue
sender.email.domain.root_domainmemberintuit.com
strings.icontainssubstringdocusign

Stages and Predicates

Stage 1: mql_rule

and
  or
    not
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
    not
      headers.auth_summary.spf.pass eq "true"
  or
    sender.display_name contains "docusign"
    subject.subject contains "docusign"
  sender.email.domain.root_domain eq "intuit.com"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Domain impersonation: Freemail reply-to local lookalike with financial request

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

This technique takes advantage of the use of free email services for the reply-to address. By incorporating the sender domain in the local part of the reply-to address, the attacker creates a visually similar appearance to a legitimate email address.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesFree email provider, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.reply_to
  • sender.email
  • type

Rule body

type.inbound
and any(headers.reply_to,
        .email.email != sender.email.email
        and .email.domain.domain in $free_email_providers
        and .email.email not in $sender_emails
        and strings.contains(.email.local_part, sender.email.domain.sld)
)
and (
  any(ml.nlu_classifier(body.current_thread.text).intents,
      .name == "bec" and .confidence in ("medium", "high")
  )
  or (
    any(ml.nlu_classifier(body.current_thread.text).entities,
        .name == "financial"
    )
    and any(ml.nlu_classifier(body.current_thread.text).entities,
            .name == "request"
    )
    and any(ml.nlu_classifier(body.current_thread.text).entities,
            .name == "urgency"
    )
    and any(ml.nlu_classifier(body.current_thread.text).entities,
            .name == "sender"
    )
    and any(ml.nlu_classifier(body.current_thread.text).intents,
            .name != "benign"
    )
  )
)

Detection logic

Scope: inbound message.

This technique takes advantage of the use of free email services for the reply-to address. By incorporating the sender domain in the local part of the reply-to address, the attacker creates a visually similar appearance to a legitimate email address.

  1. inbound message
  2. any of headers.reply_to where all hold:
    • .email.email is not sender.email.email
    • .email.domain.domain in $free_email_providers
    • .email.email not in $sender_emails
    • strings.contains(.email.local_part)
  3. any of:
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'bec'
      • .confidence in ('medium', 'high')
    • all of:
      • any of ml.nlu_classifier(body.current_thread.text).entities where:
        • .name is 'financial'
      • any of ml.nlu_classifier(body.current_thread.text).entities where:
        • .name is 'request'
      • any of ml.nlu_classifier(body.current_thread.text).entities where:
        • .name is 'urgency'
      • any of ml.nlu_classifier(body.current_thread.text).entities where:
        • .name is 'sender'
      • any of ml.nlu_classifier(body.current_thread.text).intents where:
        • .name is not 'benign'

Inspects: body.current_thread.text, headers.reply_to, headers.reply_to[].email.domain.domain, headers.reply_to[].email.email, headers.reply_to[].email.local_part, sender.email.domain.sld, sender.email.email, type.inbound. Sensors: ml.nlu_classifier, strings.contains. Reference lists: $free_email_providers, $sender_emails.

Indicators matched (7)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).intents[].nameequalsbec
ml.nlu_classifier(body.current_thread.text).intents[].confidencemembermedium
ml.nlu_classifier(body.current_thread.text).intents[].confidencememberhigh
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsfinancial
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsrequest
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsurgency
ml.nlu_classifier(body.current_thread.text).entities[].nameequalssender

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      any(ml.nlu_classifier(body.current_thread.text).entities)
        ml.nlu_classifier(body.current_thread.text).entities.name eq "financial"
      any(ml.nlu_classifier(body.current_thread.text).entities)
        ml.nlu_classifier(body.current_thread.text).entities.name eq "request"
      any(ml.nlu_classifier(body.current_thread.text).entities)
        ml.nlu_classifier(body.current_thread.text).entities.name eq "sender"
      any(ml.nlu_classifier(body.current_thread.text).entities)
        ml.nlu_classifier(body.current_thread.text).entities.name eq "urgency"
      any(ml.nlu_classifier(body.current_thread.text).intents)
        ml.nlu_classifier(body.current_thread.text).intents.name ne "benign"
    any(ml.nlu_classifier(body.current_thread.text).intents)
      and
        ml.nlu_classifier(body.current_thread.text).intents.confidence in ["high", "medium"]
        ml.nlu_classifier(body.current_thread.text).intents.name eq "bec"
  any(headers.reply_to)
    and
      headers.reply_to.email.email cross_field_compare "sender.email.email"
      strings.contains func_call "strings.contains(headers.reply_to[].email.local_part)"
       macro "headers.reply_to[].email.domain.domain in free_email_providers"
       macro "headers.reply_to[].email.email not in sender_emails"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Employee impersonation with urgent request (untrusted sender)

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

Sender is using a display name that matches the display name of someone in your organization. Detects potential Business Email Compromise (BEC) attacks by analyzing text within email body from untrusted senders.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesImpersonation: Employee, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • sender.email
  • subject
  • type

Rule body

type.inbound

// ensure the display name contains a space to avoid single named process accounts eg. 'billing, payment'
and strings.contains(sender.display_name, " ")
and sender.display_name in~ $org_display_names
and (
  any(ml.nlu_classifier(body.current_thread.text).intents,
      .name == "bec" and .confidence == "high"
  )
  or (
    (
      any(ml.nlu_classifier(body.current_thread.text).entities,
          .name == "urgency"
      )
      and any(ml.nlu_classifier(body.current_thread.text).entities,
              .name == "request"
      )
    )
    and not any(ml.nlu_classifier(body.current_thread.text).intents,
                .name == "benign" and .confidence == "high"
    )
    and (
      (
        // there are intents returned
        any(ml.nlu_classifier(body.current_thread.text).intents, true)
        // short body that also contains an org display name
        or (
          length(body.current_thread.text) > 200
          and any(ml.nlu_classifier(body.current_thread.text).entities,
                  .name == "sender" and .text in~ $org_display_names
          )
        )
      )
      and not strings.istarts_with(subject.subject, "fwd:")
    )
  )
)
and (
  (
    profile.by_sender().prevalence in ("new", "outlier")
    and not profile.by_sender().solicited
  )
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_false_positives
  )
  or not headers.auth_summary.dmarc.pass
)

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

// 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
)
and not profile.by_sender().any_false_positives

Detection logic

Scope: inbound message.

Sender is using a display name that matches the display name of someone in your organization. Detects potential Business Email Compromise (BEC) attacks by analyzing text within email body from untrusted senders.

  1. inbound message
  2. sender.display_name contains ' '
  3. sender.display_name in $org_display_names
  4. any of:
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'bec'
      • .confidence is 'high'
    • all of:
      • all of:
        • any of ml.nlu_classifier(body.current_thread.text).entities where:
          • .name is 'urgency'
        • any of ml.nlu_classifier(body.current_thread.text).entities where:
          • .name is 'request'
      • not:
        • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
          • .name is 'benign'
          • .confidence is 'high'
      • all of:
        • any of:
          • any of ml.nlu_classifier(body.current_thread.text).intents where:
            • always true
          • all of:
            • length(body.current_thread.text) > 200
            • any of ml.nlu_classifier(body.current_thread.text).entities where all hold:
              • .name is 'sender'
              • .text in $org_display_names
        • not:
          • subject.subject starts with 'fwd:'
  5. any of:
    • all of:
      • profile.by_sender().prevalence in ('new', 'outlier')
      • not:
        • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_false_positives
    • not:
      • headers.auth_summary.dmarc.pass
  6. any of:
    • all of:
      • sender.email.domain.root_domain in $org_domains
      • not:
        • headers.auth_summary.dmarc.pass
    • sender.email.domain.root_domain not in $org_domains
  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
  8. not:
    • profile.by_sender().any_false_positives

Inspects: body.current_thread.text, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender, strings.contains, strings.istarts_with. Reference lists: $high_trust_sender_root_domains, $org_display_names, $org_domains.

Indicators matched (6)

FieldMatchValue
strings.containssubstring
ml.nlu_classifier(body.current_thread.text).intents[].nameequalsbec
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsurgency
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsrequest
ml.nlu_classifier(body.current_thread.text).entities[].nameequalssender

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      or
        and
          any(ml.nlu_classifier(body.current_thread.text).entities)
            and
              ml.nlu_classifier(body.current_thread.text).entities.name eq "sender"
               macro "ml.nlu_classifier(body.current_thread.text).entities[].text in org_display_names"
          body.current_thread.text length_compare "200"
        any(ml.nlu_classifier(body.current_thread.text).intents)
           macro "true"
      not
        any(ml.nlu_classifier(body.current_thread.text).intents)
          and
            ml.nlu_classifier(body.current_thread.text).intents.confidence eq "high"
            ml.nlu_classifier(body.current_thread.text).intents.name eq "benign"
      any(ml.nlu_classifier(body.current_thread.text).entities)
        ml.nlu_classifier(body.current_thread.text).entities.name eq "request"
      any(ml.nlu_classifier(body.current_thread.text).entities)
        ml.nlu_classifier(body.current_thread.text).entities.name eq "urgency"
      not
        subject.subject starts_with "fwd:"
    any(ml.nlu_classifier(body.current_thread.text).intents)
      and
        ml.nlu_classifier(body.current_thread.text).intents.confidence eq "high"
        ml.nlu_classifier(body.current_thread.text).intents.name eq "bec"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in org_domains"
     macro "sender.email.domain.root_domain not in org_domains"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_false_positives"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    and
      not
        profile.by_sender func_call "profile.by_sender().solicited"
      profile.by_sender func_call "profile.by_sender().prevalence in (new, outlier)"
    not
      headers.auth_summary.dmarc.pass eq "true"
  not
    profile.by_sender func_call "profile.by_sender().any_false_positives"
  sender.display_name contains " "
  type.inbound eq "true"
   macro "sender.display_name in org_display_names"

Indicators

These rows show field, operator, and value matches.

Employee impersonation: Payroll fraud

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

This rule detects messages impersonating employees, from unsolicited senders attempting to reroute payroll or alter payment details.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesImpersonation: Employee, Free email provider, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.hops
  • headers.reply_to
  • mailbox
  • recipients
  • sender.email
  • subject
  • type

Rule body

type.inbound
// ensure the display name contains a space to avoid single named process accounts eg. 'billing, payment'
and strings.contains(sender.display_name, " ")
and (
  sender.display_name in~ $org_display_names
  or subject.base in~ $org_display_names
)
and length(attachments) == 0
and length(body.links) < 10
and (
  length(body.current_thread.text) < 800
  or (
    any(map(filter(ml.nlu_classifier(body.current_thread.text).entities,
                   .name == "disclaimer"
            ),
            .text
        ),
        (length(body.current_thread.text) - length(.)) < 800
    )
  )
)
and (
  sender.email.domain.root_domain not in $org_domains
  or sender.email.domain.root_domain in $free_email_providers
)
and 1 of (
  regex.icontains(body.current_thread.text,
                  '(?:pay\s?(?:roll|check|date|day)|direct deposit|(?:acct|account) rephrase|paid.{0,50}problems|\bACH\b|\bdd\b|gehalt|salario|salary|employee self[-\s]?service|\bESS\b.{0,30}(?:portal|access|log[-\s]?in)|access.{0,30}(?:HR|employee).{0,30}portal)'
  ),
  regex.icontains(subject.subject,
                  '(?:pay\s?(?:roll|check|date|day)|direct deposit|(?:acct|account) rephrase|paid.{0,50}problems|\bACH\b|\bdd\b|gehalt|salario|salary|employee self[-\s]?service|\bESS\b.{0,15}portal)'
  )
)

// sender profile negations
and (
  not profile.by_sender_email().solicited
  or profile.by_sender().any_messages_malicious_or_spam
)
and not profile.by_sender().any_messages_benign

// negate highly trusted sender domains unless they fail DMARC authentication
and (
  (
    sender.email.domain.root_domain in $high_trust_sender_root_domains
    and (
      any(distinct(headers.hops, .authentication_results.dmarc is not null),
          strings.ilike(.authentication_results.dmarc, "*fail")
      )
    )
  )
  or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)

// negate legitimate conversations
and not (
  (
    length(headers.references) > 0
    or headers.in_reply_to is not null
    or (
      any(headers.hops,
          any(.fields,
              strings.ilike(.name, "x-autoreply")
              and strings.ilike(.value, "yes")
          )
      )
    )
  )
  // previous thread present
  and (
    (
      (subject.is_forward or subject.is_reply)
      and length(body.previous_threads) >= 1
    )
    // automatic reply structure
    or (
      strings.istarts_with(subject.base, "automatic reply")
      or strings.istarts_with(subject.base, "out of office")
    )
  )
)

// ignore personal <> work emails
and not (
  length(recipients.to) == 1
  and sender.email.domain.valid
  and all(headers.reply_to, .email.email == sender.email.email)
  and sender.display_name == mailbox.display_name
)

// topic negations
and not any(ml.nlu_classifier(body.current_thread.text).topics,
            .name == "Advertising and Promotions"
)

Detection logic

Scope: inbound message.

This rule detects messages impersonating employees, from unsolicited senders attempting to reroute payroll or alter payment details.

  1. inbound message
  2. sender.display_name contains ' '
  3. any of:
    • sender.display_name in $org_display_names
    • subject.base in $org_display_names
  4. length(attachments) is 0
  5. length(body.links) < 10
  6. any of:
    • length(body.current_thread.text) < 800
    • any of map(...) where:
      • length(body.current_thread.text) - length(.) < 800
  7. any of:
    • sender.email.domain.root_domain not in $org_domains
    • sender.email.domain.root_domain in $free_email_providers
  8. at least 1 of:
    • body.current_thread.text matches '(?:pay\\s?(?:roll|check|date|day)|direct deposit|(?:acct|account) rephrase|paid.{0,50}problems|\\bACH\\b|\\bdd\\b|gehalt|salario|salary|employee self[-\\s]?service|\\bESS\\b.{0,30}(?:portal|access|log[-\\s]?in)|access.{0,30}(?:HR|employee).{0,30}portal)'
    • subject.subject matches '(?:pay\\s?(?:roll|check|date|day)|direct deposit|(?:acct|account) rephrase|paid.{0,50}problems|\\bACH\\b|\\bdd\\b|gehalt|salario|salary|employee self[-\\s]?service|\\bESS\\b.{0,15}portal)'
  9. any of:
    • not:
      • profile.by_sender_email().solicited
    • profile.by_sender().any_messages_malicious_or_spam
  10. not:
    • profile.by_sender().any_messages_benign
  11. any of:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • any of distinct(headers.hops) where:
        • .authentication_results.dmarc matches '*fail'
    • sender.email.domain.root_domain not in $high_trust_sender_root_domains
  12. not:
    • all of:
      • any of:
        • length(headers.references) > 0
        • headers.in_reply_to is set
        • any of headers.hops where:
          • any of .fields where all hold:
            • .name matches 'x-autoreply'
            • .value matches 'yes'
      • any of:
        • all of:
          • any of:
            • subject.is_forward
            • subject.is_reply
          • length(body.previous_threads) ≥ 1
        • any of:
          • subject.base starts with 'automatic reply'
          • subject.base starts with 'out of office'
  13. not:
    • all of:
      • length(recipients.to) is 1
      • sender.email.domain.valid
      • all of headers.reply_to where:
        • .email.email is sender.email.email
      • sender.display_name is mailbox.display_name
  14. not:
    • any of ml.nlu_classifier(body.current_thread.text).topics where:
      • .name is 'Advertising and Promotions'

Inspects: body.current_thread.text, body.links, body.previous_threads, headers.hops, headers.hops[].authentication_results.dmarc, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, headers.in_reply_to, headers.references, headers.reply_to, headers.reply_to[].email.email, mailbox.display_name, recipients.to, sender.display_name, sender.email.domain.root_domain, sender.email.domain.valid, sender.email.email, subject.base, subject.is_forward, subject.is_reply, subject.subject, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender, profile.by_sender_email, regex.icontains, strings.contains, strings.ilike, strings.istarts_with. Reference lists: $free_email_providers, $high_trust_sender_root_domains, $org_display_names, $org_domains.

Indicators matched (5)

FieldMatchValue
strings.containssubstring
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsdisclaimer
regex.icontainsregex(?:pay\s?(?:roll|check|date|day)|direct deposit|(?:acct|account) rephrase|paid.{0,50}problems|\bACH\b|\bdd\b|gehalt|salario|salary|employee self[-\s]?service|\bESS\b.{0,30}(?:portal|access|log[-\s]?in)|access.{0,30}(?:HR|employee).{0,30}portal)
regex.icontainsregex(?:pay\s?(?:roll|check|date|day)|direct deposit|(?:acct|account) rephrase|paid.{0,50}problems|\bACH\b|\bdd\b|gehalt|salario|salary|employee self[-\s]?service|\bESS\b.{0,15}portal)
strings.ilikesubstring*fail

Stages and Predicates

Stage 1: mql_rule

and
  not
    and
      or
        any(headers.hops)
          any(headers.hops.fields)
            and
              headers.hops.fields[].name eq "x-autoreply"
              headers.hops.fields[].value eq "yes"
        headers.in_reply_to is_not_null
        headers.references length_compare "0"
      or
        and
          or
            subject.is_forward eq "true"
            subject.is_reply eq "true"
          body.previous_threads length_compare "1"
        subject.base starts_with "automatic reply"
        subject.base starts_with "out of office"
  or
    and
      any(distinct(headers.hops))
        distinct(headers.hops).authentication_results.dmarc ends_with "fail"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    any(ml.nlu_classifier(body.current_thread.text).topics)
      ml.nlu_classifier(body.current_thread.text).topics.name eq "Advertising and Promotions"
  or
    not
      profile.by_sender_email func_call "profile.by_sender_email().solicited"
    profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
  not
    and
      recipients.to length_compare "1"
      sender.display_name cross_field_compare "mailbox.display_name"
      sender.email.domain.valid eq "true"
       macro "all(headers.reply_to)"
  or
    any(map(...))
       macro "(length(body.current_thread.text) - length(map(...)[])) < 800"
    body.current_thread.text length_compare "800"
  or
    body.current_thread.text regex_match "(?:pay\\s?(?:roll|check|date|day)|direct deposit|(?:acct|account) rephrase|paid.{0,50}problems|\\bACH\\b|\\bdd\\b|gehalt|salario|salary|employee self[-\\s]?service|\\bESS\\b.{0,30}(?:portal|access|log[-\\s]?in)|access.{0,30}(?:HR|employee).{0,30}portal)"
    subject.subject regex_match "(?:pay\\s?(?:roll|check|date|day)|direct deposit|(?:acct|account) rephrase|paid.{0,50}problems|\\bACH\\b|\\bdd\\b|gehalt|salario|salary|employee self[-\\s]?service|\\bESS\\b.{0,15}portal)"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  or
     macro "sender.display_name in org_display_names"
     macro "subject.base in org_display_names"
  or
     macro "sender.email.domain.root_domain in free_email_providers"
     macro "sender.email.domain.root_domain not in org_domains"
  attachments length_compare "0"
  body.links length_compare "10"
  sender.display_name contains " "
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.hopsarray_any(no value, null check)excludes:headers.hops
headers.in_reply_tois_not_null(no value, null check)excludes:headers.in_reply_to
headers.referenceslength_compare0excludes:headers.references field:"headers.references" value:"0"
subject.is_forwardeqtrueexcludes:subject.is_forward field:"subject.is_forward" value:"true"
subject.is_replyeqtrueexcludes:subject.is_reply field:"subject.is_reply" value:"true"
body.previous_threadslength_compare1excludes:body.previous_threads field:"body.previous_threads" value:"1"
subject.basestarts_withautomatic replyexcludes:subject.base field:"subject.base" value:"automatic reply"
subject.basestarts_without of officeexcludes:subject.base field:"subject.base" value:"out of office"
ml.nlu_classifier(body.current_thread.text).topicsarray_any(no value, null check)excludes:ml.nlu_classifier(body.current_thread.text).topics
recipients.tolength_compare1excludes:recipients.to field:"recipients.to" value:"1"
sender.display_namecross_field_comparemailbox.display_nameexcludes:sender.display_name field:"sender.display_name" value:"mailbox.display_name"
sender.email.domain.valideqtrueexcludes:sender.email.domain.valid field:"sender.email.domain.valid" value:"true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textregex_match
  • (?:pay\s?(?:roll|check|date|day)|direct deposit|(?:acct|account) rephrase|paid.{0,50}problems|\bACH\b|\bdd\b|gehalt|salario|salary|employee self[-\s]?service|\bESS\b.{0,30}(?:portal|access|log[-\s]?in)|access.{0,30}(?:HR|employee).{0,30}portal)
field:"body.current_thread.text" kind:regex_match value:"(?:pay\s?(?:roll|check|date|day)|direct deposit|(?:acct|account) rephrase|paid.{0,50}problems|\bACH\b|\bdd\b|gehalt|salario|salary|employee self[-\s]?service|\bESS\b.{0,30}(?:portal|access|log[-\s]?in)|access.{0,30}(?:HR|employee).{0,30}portal)"
sender.display_namecontains
field:"sender.display_name" kind:contains value:" "
subject.subjectregex_match
  • (?:pay\s?(?:roll|check|date|day)|direct deposit|(?:acct|account) rephrase|paid.{0,50}problems|\bACH\b|\bdd\b|gehalt|salario|salary|employee self[-\s]?service|\bESS\b.{0,15}portal)
field:"subject.subject" kind:regex_match value:"(?:pay\s?(?:roll|check|date|day)|direct deposit|(?:acct|account) rephrase|paid.{0,50}problems|\bACH\b|\bdd\b|gehalt|salario|salary|employee self[-\s]?service|\bESS\b.{0,15}portal)"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Fake message thread - Untrusted sender with a mismatched freemail reply-to address

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

Fake Message Threads or Chain Reuse is a common confidence technique exploited by threat actors to bolster credibility. This is typically used in conjunction with a reply-to address that is not the same as the sender address.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesFree email provider, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.html
  • body.plain
  • headers
  • headers.hops
  • headers.reply_to
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  (
    profile.by_sender_email().prevalence in ("new", "outlier")
    and not profile.by_sender().solicited
  )
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)

// Reply-to is a freemail sender but From is not
and any(headers.reply_to,
        .email.domain.domain in $free_email_providers
        and not .email.domain.domain == sender.email.domain.domain
)

// Exclude marketing emails
and not strings.ilike(sender.email.local_part,
                      "support",
                      "sales",
                      "noreply",
                      "marketing"
)

// Exclude mailing lists
and not any(headers.hops,
            any(.fields,
                .name in ("x-google-group-id", "list-post", "mailing-list")
            )
)

// Check for Message Thread Indicators
and (
  regex.icontains(subject.subject, '\b(?:RE|FWD?)\s*:')
  or any([body.current_thread.text, body.html.display_text, body.plain.raw],
         3 of (
           strings.icontains(., "from:"),
           strings.icontains(., "to:"),
           strings.icontains(., "sent:"),
           strings.icontains(., "date:"),
           strings.icontains(., "cc:"),
           strings.icontains(., "subject:")
         )
  )
)

// Check for the Presence of References or In-Reply-To properties
and (length(headers.references) == 0 or headers.in_reply_to is null)

Detection logic

Scope: inbound message.

Fake Message Threads or Chain Reuse is a common confidence technique exploited by threat actors to bolster credibility. This is typically used in conjunction with a reply-to address that is not the same as the sender address.

  1. inbound message
  2. any of:
    • all of:
      • profile.by_sender_email().prevalence in ('new', 'outlier')
      • not:
        • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  3. any of headers.reply_to where all hold:
    • .email.domain.domain in $free_email_providers
    • not:
      • .email.domain.domain is sender.email.domain.domain
  4. not:
    • sender.email.local_part matches any of 4 patterns
      • support
      • sales
      • noreply
      • marketing
  5. not:
    • any of headers.hops where:
      • any of .fields where:
        • .name in ('x-google-group-id', 'list-post', 'mailing-list')
  6. any of:
    • subject.subject matches '\\b(?:RE|FWD?)\\s*:'
    • any of [body.current_thread.text, body.html.display_text, body.plain.raw] where:
      • at least 3 of 6: . contains any of 6 patterns
        • from:
        • to:
        • sent:
        • date:
        • cc:
        • subject:
  7. any of:
    • length(headers.references) is 0
    • headers.in_reply_to is missing

Inspects: body.current_thread.text, body.html.display_text, body.plain.raw, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.in_reply_to, headers.references, headers.reply_to, headers.reply_to[].email.domain.domain, sender.email.domain.domain, sender.email.local_part, subject.subject, type.inbound. Sensors: profile.by_sender, profile.by_sender_email, regex.icontains, strings.icontains, strings.ilike. Reference lists: $free_email_providers.

Indicators matched (7)

FieldMatchValue
regex.icontainsregex\b(?:RE|FWD?)\s*:
strings.icontainssubstringfrom:
strings.icontainssubstringto:
strings.icontainssubstringsent:
strings.icontainssubstringdate:
strings.icontainssubstringcc:
strings.icontainssubstringsubject:

Stages and Predicates

Stage 1: mql_rule

and
  or
    any([body.current_thread.text, body.html.display_text, body.plain.raw])
      or
        [body.current_thread.text, body.html.display_text, body.plain.raw] contains "cc:"
        [body.current_thread.text, body.html.display_text, body.plain.raw] contains "date:"
        [body.current_thread.text, body.html.display_text, body.plain.raw] contains "from:"
        [body.current_thread.text, body.html.display_text, body.plain.raw] contains "sent:"
        [body.current_thread.text, body.html.display_text, body.plain.raw] contains "subject:"
        [body.current_thread.text, body.html.display_text, body.plain.raw] contains "to:"
    subject.subject regex_match "\\b(?:RE|FWD?)\\s*:"
  not
    any(headers.hops)
      any(headers.hops.fields)
        headers.hops.fields.name in ["list-post", "mailing-list", "x-google-group-id"]
  any(headers.reply_to)
    and
      not
        headers.reply_to.email.domain.domain cross_field_compare "sender.email.domain.domain"
       macro "headers.reply_to[].email.domain.domain in free_email_providers"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    and
      not
        profile.by_sender func_call "profile.by_sender().solicited"
      profile.by_sender_email func_call "profile.by_sender_email().prevalence in (new, outlier)"
  not
    or
      sender.email.local_part eq "marketing"
      sender.email.local_part eq "noreply"
      sender.email.local_part eq "sales"
      sender.email.local_part eq "support"
  or
    headers.in_reply_to is_null
    headers.references length_compare "0"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

Fake shipping notification with link to free file hosting

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

This rule detects spam emails impersonating FedEx, UPS, or USPS with links to free file hosting.

Threat classification

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

CategoryValues
Attack typesSpam
Tactics and techniquesFree file host, Impersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.html
  • body.links
  • headers
  • headers.return_path
  • sender.email
  • type

Rule body

type.inbound
and length(attachments) == 0
and (
  regex.icontains(coalesce(body.html.inner_text, body.html.display_text),
                  '\bf[ _]?e[ _]?d[ _]?e[ _]?x\b'
  )
  and sender.email.domain.domain != "fedex.com"
  and headers.return_path.domain.domain != sender.email.domain.domain
  and any(body.links, strings.contains(.display_text, "track"))
  and length(body.links) < 10
)
and any(body.links,
        .href_url.domain.domain in $free_file_hosts
        or .href_url.domain.root_domain in $free_file_hosts
)
and (
  (
    sender.email.domain.root_domain in $free_email_providers
    and sender.email.email not in $sender_emails
  )
  or (
    sender.email.domain.root_domain not in $free_email_providers
    and sender.email.domain.root_domain not in $sender_domains
  )
  or sender.email.domain.valid == false
)

Detection logic

Scope: inbound message.

This rule detects spam emails impersonating FedEx, UPS, or USPS with links to free file hosting.

  1. inbound message
  2. length(attachments) is 0
  3. all of:
    • coalesce(body.html.inner_text, body.html.display_text) matches '\\bf[ _]?e[ _]?d[ _]?e[ _]?x\\b'
    • sender.email.domain.domain is not 'fedex.com'
    • headers.return_path.domain.domain is not sender.email.domain.domain
    • any of body.links where:
      • .display_text contains 'track'
    • length(body.links) < 10
  4. any of body.links where any holds:
    • .href_url.domain.domain in $free_file_hosts
    • .href_url.domain.root_domain in $free_file_hosts
  5. any of:
    • all of:
      • sender.email.domain.root_domain in $free_email_providers
      • sender.email.email not in $sender_emails
    • all of:
      • sender.email.domain.root_domain not in $free_email_providers
      • sender.email.domain.root_domain not in $sender_domains
    • sender.email.domain.valid is False

Inspects: body.html.display_text, body.html.inner_text, body.links, body.links[].display_text, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, headers.return_path.domain.domain, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.domain.valid, sender.email.email, type.inbound. Sensors: regex.icontains, strings.contains. Reference lists: $free_email_providers, $free_file_hosts, $sender_domains, $sender_emails.

Indicators matched (2)

FieldMatchValue
regex.icontainsregex\bf[ _]?e[ _]?d[ _]?e[ _]?x\b
strings.containssubstringtrack

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    or
       macro "body.links[].href_url.domain.domain in free_file_hosts"
       macro "body.links[].href_url.domain.root_domain in free_file_hosts"
  or
    and
       macro "sender.email.domain.root_domain in free_email_providers"
       macro "sender.email.email not in sender_emails"
    and
       macro "sender.email.domain.root_domain not in free_email_providers"
       macro "sender.email.domain.root_domain not in sender_domains"
    sender.email.domain.valid eq "false"
  any(body.links)
    body.links.display_text contains "track"
  attachments length_compare "0"
  body.links length_compare "10"
  coalesce(body.html.inner_text, body.html.display_text) regex_match "\\bf[ _]?e[ _]?d[ _]?e[ _]?x\\b"
  headers.return_path.domain.domain cross_field_compare "sender.email.domain.domain"
  sender.email.domain.domain ne "fedex.com"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Impersonation using recipient domain (untrusted sender)

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

The recipient's domain is used in the sender's display name in order to impersonate the organization. The impersonation has been observed to use both the recipient's full email address, as well as just the domain.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • headers
  • headers.auth_summary
  • recipients
  • recipients.to
  • sender.email
  • type

Rule body

type.inbound

// only 1 To: recipient
and length(recipients.to) + length(recipients.bcc) + length(recipients.cc) == 1

// custom domains only
and sender.email.domain.domain not in $free_email_providers
and any(recipients.to,
        // recipient's domain is in the sender's display name
        strings.icontains(sender.display_name, .email.domain.root_domain)
)
and not (
  (
    strings.contains(sender.display_name, "on behalf of")
    and sender.email.domain.root_domain == "microsoftonline.com"
  )
  or (
    strings.contains(sender.display_name, "via TransferXL")
    and sender.email.domain.root_domain == "transferxl.com"
  )
)
and all(recipients.to,
        .email.domain.root_domain != sender.email.domain.root_domain
)
and (
  profile.by_sender().prevalence in ("new", "outlier")
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)

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

The recipient's domain is used in the sender's display name in order to impersonate the organization. The impersonation has been observed to use both the recipient's full email address, as well as just the domain.

  1. inbound message
  2. length(recipients.to) + length(recipients.bcc) + length(recipients.cc) is 1
  3. sender.email.domain.domain not in $free_email_providers
  4. any of recipients.to where:
    • strings.icontains(sender.display_name)
  5. none of:
    • all of:
      • sender.display_name contains 'on behalf of'
      • sender.email.domain.root_domain is 'microsoftonline.com'
    • all of:
      • sender.display_name contains 'via TransferXL'
      • sender.email.domain.root_domain is 'transferxl.com'
  6. all of recipients.to where:
    • .email.domain.root_domain is not sender.email.domain.root_domain
  7. any of:
    • profile.by_sender().prevalence in ('new', 'outlier')
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  8. 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: headers.auth_summary.dmarc.pass, recipients.to, recipients.to[].email.domain.root_domain, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender, strings.contains, strings.icontains. Reference lists: $free_email_providers, $high_trust_sender_root_domains.

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    profile.by_sender func_call "profile.by_sender().prevalence in (new, outlier)"
  not
    or
      and
        sender.display_name contains "on behalf of"
        sender.email.domain.root_domain eq "microsoftonline.com"
      and
        sender.display_name contains "via TransferXL"
        sender.email.domain.root_domain eq "transferxl.com"
  any(recipients.to)
    strings.icontains func_call "strings.icontains(sender.display_name)"
  type.inbound eq "true"
   macro "((length(recipients.to) + length(recipients.bcc)) + length(recipients.cc)) == 1"
   macro "all(recipients.to)"
   macro "sender.email.domain.domain not in free_email_providers"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Impersonation: Australian Federal Police with criminal case language

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

Detects messages impersonating the Australian Federal Police using law enforcement terminology in the subject and sender display name, combined with official correspondence language including case references, investigation details, and compliance demands.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Extortion
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • subject
  • type

Rule body

type.inbound
and (
  strings.ilike(subject.base, '*afp*')
  or strings.ilike(subject.base, '*australian federal police*')
)
and (
  2 of (
    strings.ilike(subject.base, '*case*'),
    strings.ilike(subject.base, '*investigation*'),
    strings.ilike(subject.base, '*law enforcement*'),
    strings.ilike(subject.base, '*management*'),
    strings.ilike(subject.base, '*notice*'),
    strings.ilike(subject.base, '*reference*')
  )
)
and (
  regex.icontains(body.current_thread.text, 'investigation|correspondence')
  and regex.icontains(body.current_thread.text, 'case (?:reference|type)')
)

Detection logic

Scope: inbound message.

Detects messages impersonating the Australian Federal Police using law enforcement terminology in the subject and sender display name, combined with official correspondence language including case references, investigation details, and compliance demands.

  1. inbound message
  2. any of:
    • subject.base matches '*afp*'
    • subject.base matches '*australian federal police*'
  3. at least 2 of 6: subject.base matches any of 6 patterns
    • *case*
    • *investigation*
    • *law enforcement*
    • *management*
    • *notice*
    • *reference*
  4. all of:
    • body.current_thread.text matches 'investigation|correspondence'
    • body.current_thread.text matches 'case (?:reference|type)'

Inspects: body.current_thread.text, subject.base, type.inbound. Sensors: regex.icontains, strings.ilike.

Indicators matched (10)

FieldMatchValue
strings.ilikesubstring*afp*
strings.ilikesubstring*australian federal police*
strings.ilikesubstring*case*
strings.ilikesubstring*investigation*
strings.ilikesubstring*law enforcement*
strings.ilikesubstring*management*
strings.ilikesubstring*notice*
strings.ilikesubstring*reference*
regex.icontainsregexinvestigation|correspondence
regex.icontainsregexcase (?:reference|type)

Stages and Predicates

Stage 1: mql_rule

and
  or
    subject.base match "afp"
    subject.base match "australian federal police"
  or
    subject.base match "case"
    subject.base match "investigation"
    subject.base match "law enforcement"
    subject.base match "management"
    subject.base match "notice"
    subject.base match "reference"
  body.current_thread.text regex_match "case (?:reference|type)"
  body.current_thread.text regex_match "investigation|correspondence"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textregex_match
  • case (?:reference|type)
    • investigation
    • correspondence
field:"body.current_thread.text" kind:regex_match
subject.basewildcard
  • *afp*
  • *australian federal police*
  • *case*
  • *investigation*
  • *law enforcement*
  • *management*
  • *notice*
  • *reference*
field:"subject.base" kind:wildcard
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Impersonation: Chrome Web Store policy

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

Detects messages impersonating Chrome Web Store policy communications, including fake extension security alerts and policy acceptance requests. Messages using observed domains and specific HTML formatting patterns typical of this impersonation.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Free email provider, Lookalike domain

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.html
  • body.links
  • headers
  • headers.auth_summary
  • sender.email
  • subject
  • type

Rule body

type.inbound
and sender.email.domain.domain != 'gmail.com'
and (
  // subject and sender
  sender.email.domain.root_domain in (
    "chromeforextension.com",
    "forextensions.com",
    "supportchromestore.com"
  )
  or (
    2 of (
      strings.icontains(sender.email.domain.root_domain, 'chrome'),
      strings.icontains(sender.email.domain.root_domain, 'support'),
      strings.icontains(sender.email.domain.root_domain, 'extension'),
      strings.icontains(sender.email.domain.root_domain, 'webstore')
    )
  )
  or strings.icontains(sender.email.local_part, 'chromewebstore')
  or strings.icontains(sender.display_name, "Webstore Extension")
  or strings.icontains(subject.subject, 'Chrome Web Store Policy')
  // body and html
  or strings.icontains(body.html.raw,
                       '<div style="background-color:rgb(65,132,243);padding:50px 20px 0px">'
  )
  or regex.icontains(body.current_thread.text,
                     'Item name: [^\s]+ security extension'
  )
  or strings.icontains(body.current_thread.text,
                       'Chrome Web Store Developer Support'
  )
  or strings.icontains(body.current_thread.text, 'Developer Program Policies')
  or strings.icontains(body.current_thread.text,
                       'Relevant section of the program policy:'
  )
  or strings.icontains(body.current_thread.text,
                       'Please accept our policies to continue publishing your products.'
  )

  // links
  or (
    length(distinct(body.links, .href_url.domain.root_domain)) < 10
    and any(body.links,
            .href_url.domain.root_domain in (
              "checkpolicy.site",
              "extensionpolicyprivacy.com",
              "extensionpolicy.net",
              "policyextension.info"
            )
            or .href_url.path == '/extension-policy-check'
            or .display_text == "Go To Policy"
    )
  )
)
// negate messages sent by Google support
and not (
  sender.email.domain.root_domain == 'google.com'
  and headers.auth_summary.dmarc.pass
)

Detection logic

Scope: inbound message.

Detects messages impersonating Chrome Web Store policy communications, including fake extension security alerts and policy acceptance requests. Messages using observed domains and specific HTML formatting patterns typical of this impersonation.

  1. inbound message
  2. sender.email.domain.domain is not 'gmail.com'
  3. any of:
    • sender.email.domain.root_domain in ('chromeforextension.com', 'forextensions.com', 'supportchromestore.com')
    • at least 2 of 4: sender.email.domain.root_domain contains any of 4 patterns
      • chrome
      • support
      • extension
      • webstore
    • sender.email.local_part contains 'chromewebstore'
    • sender.display_name contains 'Webstore Extension'
    • subject.subject contains 'Chrome Web Store Policy'
    • body.html.raw contains '<div style="background-color:rgb(65,132,243);padding:50px 20px 0px">'
    • body.current_thread.text matches 'Item name: [^\\s]+ security extension'
    • body.current_thread.text contains 'Chrome Web Store Developer Support'
    • body.current_thread.text contains 'Developer Program Policies'
    • body.current_thread.text contains 'Relevant section of the program policy:'
    • body.current_thread.text contains 'Please accept our policies to continue publishing your products.'
    • all of:
      • length(distinct(body.links, .href_url.domain.root_domain)) < 10
      • any of body.links where any holds:
        • .href_url.domain.root_domain in ('checkpolicy.site', 'extensionpolicyprivacy.com', 'extensionpolicy.net', 'policyextension.info')
        • .href_url.path is '/extension-policy-check'
        • .display_text is 'Go To Policy'
  4. not:
    • all of:
      • sender.email.domain.root_domain is 'google.com'
      • headers.auth_summary.dmarc.pass

Inspects: body.current_thread.text, body.html.raw, body.links, body.links[].display_text, body.links[].href_url.domain.root_domain, body.links[].href_url.path, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.local_part, subject.subject, type.inbound. Sensors: regex.icontains, strings.icontains.

Indicators matched (22)

FieldMatchValue
sender.email.domain.root_domainmemberchromeforextension.com
sender.email.domain.root_domainmemberforextensions.com
sender.email.domain.root_domainmembersupportchromestore.com
strings.icontainssubstringchrome
strings.icontainssubstringsupport
strings.icontainssubstringextension
strings.icontainssubstringwebstore
strings.icontainssubstringchromewebstore
strings.icontainssubstringWebstore Extension
strings.icontainssubstringChrome Web Store Policy
strings.icontainssubstring<div style="background-color:rgb(65,132,243);padding:50px 20px 0px">
regex.icontainsregexItem name: [^\s]+ security extension
10 more
strings.icontainssubstringChrome Web Store Developer Support
strings.icontainssubstringDeveloper Program Policies
strings.icontainssubstringRelevant section of the program policy:
strings.icontainssubstringPlease accept our policies to continue publishing your products.
body.links[].href_url.domain.root_domainmembercheckpolicy.site
body.links[].href_url.domain.root_domainmemberextensionpolicyprivacy.com
body.links[].href_url.domain.root_domainmemberextensionpolicy.net
body.links[].href_url.domain.root_domainmemberpolicyextension.info
body.links[].href_url.pathequals/extension-policy-check
body.links[].display_textequalsGo To Policy

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      any(body.links)
        or
          body.links.display_text eq "Go To Policy"
          body.links.href_url.domain.root_domain in ["checkpolicy.site", "extensionpolicy.net", "extensionpolicyprivacy.com", "policyextension.info"]
          body.links.href_url.path eq "/extension-policy-check"
      distinct(body.links, .href_url.domain.root_domain) length_compare "10"
    body.current_thread.text contains "Chrome Web Store Developer Support"
    body.current_thread.text contains "Developer Program Policies"
    body.current_thread.text contains "Please accept our policies to continue publishing your products."
    body.current_thread.text contains "Relevant section of the program policy:"
    body.current_thread.text regex_match "Item name: [^\\s]+ security extension"
    body.html.raw contains "<div style=\"background-color:rgb(65,132,243);padding:50px 20px 0px\">"
    sender.display_name contains "Webstore Extension"
    sender.email.domain.root_domain contains "chrome"
    sender.email.domain.root_domain contains "extension"
    sender.email.domain.root_domain contains "support"
    sender.email.domain.root_domain contains "webstore"
    sender.email.domain.root_domain in ["chromeforextension.com", "forextensions.com", "supportchromestore.com"]
    sender.email.local_part contains "chromewebstore"
    subject.subject contains "Chrome Web Store Policy"
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.root_domain eq "google.com"
  sender.email.domain.domain ne "gmail.com"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

Impersonation: Employee name in subject with suspicious sender

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

Detects inbound messages where the sender is using a free email provider and their display name matches an known organizational display name. The sender's local part contains common organizational role keywords (mail, office, staff, executive), and the subject line matches the recipient's first name or display name, suggesting a targeted impersonation of an internal employee or executive.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesImpersonation: Employee, Impersonation: VIP, Free email provider, Social engineering, Spoofing

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • mailbox
  • sender.email
  • subject
  • type

Rule body

type.inbound
// suspicious local part
and strings.contains(sender.email.local_part,
                     'mail',
                     'office',
                     'staff',
                     'executive'
)
and (mailbox.first_name == subject.base or mailbox.display_name == subject.base)
and strings.contains(sender.display_name, " ")
and sender.display_name in~ $org_display_names
and sender.email.domain.root_domain in $free_email_providers

Detection logic

Scope: inbound message.

Detects inbound messages where the sender is using a free email provider and their display name matches an known organizational display name. The sender's local part contains common organizational role keywords (mail, office, staff, executive), and the subject line matches the recipient's first name or display name, suggesting a targeted impersonation of an internal employee or executive.

  1. inbound message
  2. sender.email.local_part contains any of 4 patterns
    • mail
    • office
    • staff
    • executive
  3. any of:
    • mailbox.first_name is subject.base
    • mailbox.display_name is subject.base
  4. sender.display_name contains ' '
  5. sender.display_name in $org_display_names
  6. sender.email.domain.root_domain in $free_email_providers

Inspects: mailbox.display_name, mailbox.first_name, sender.display_name, sender.email.domain.root_domain, sender.email.local_part, subject.base, type.inbound. Sensors: strings.contains. Reference lists: $free_email_providers, $org_display_names.

Indicators matched (5)

FieldMatchValue
strings.containssubstringmail
strings.containssubstringoffice
strings.containssubstringstaff
strings.containssubstringexecutive
strings.containssubstring

Stages and Predicates

Stage 1: mql_rule

and
  or
    mailbox.display_name cross_field_compare "subject.base"
    mailbox.first_name cross_field_compare "subject.base"
  or
    sender.email.local_part contains "executive"
    sender.email.local_part contains "mail"
    sender.email.local_part contains "office"
    sender.email.local_part contains "staff"
  sender.display_name contains " "
  type.inbound eq "true"
   macro "sender.display_name in org_display_names"
   macro "sender.email.domain.root_domain in free_email_providers"

Indicators

These rows show field, operator, and value matches.

Impersonation: Employee using fabricated identity in initial contact

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

Detects inbound messages that appear to be initial contact attempts where the sender uses a display name that doesn't match their email address, includes basic greetings referencing the subject line, and signs off with their display name. The message is short with no attachments, suggesting a social engineering setup for further communication.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesImpersonation: Employee, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • sender.email
  • subject
  • type

Rule body

type.inbound
// not a reply thread — this is initial contact
and length(headers.references) == 0
// short body, no attachments — initial contact social engineering
and length(body.current_thread.text) < 500
and length(attachments) == 0
// contains basic greeting
and any(["Hey", "Hi", "Hello"],
        strings.starts_with(body.current_thread.text,
                            strings.concat(.,
                                           " ",
                                           regex.extract(subject.base,
                                                         '^\P{L}*([\p{L}''-]+)'
                                           )[0].groups[0],
                                           ",\n"
                            )
        )
)
// ends with the senders display name
and strings.ends_with(body.current_thread.text,
                      strings.concat("\n", sender.display_name, ".")
)
// sender display name not in the actual email address local part
and any(regex.iextract(sender.display_name, '\w+'),
        .full_match not in~ (sender.email.local_part)
)

Detection logic

Scope: inbound message.

Detects inbound messages that appear to be initial contact attempts where the sender uses a display name that doesn't match their email address, includes basic greetings referencing the subject line, and signs off with their display name. The message is short with no attachments, suggesting a social engineering setup for further communication.

  1. inbound message
  2. length(headers.references) is 0
  3. length(body.current_thread.text) < 500
  4. length(attachments) is 0
  5. any of ['Hey', 'Hi', 'Hello'] where:
    • strings.starts_with(body.current_thread.text)
  6. strings.ends_with(body.current_thread.text)
  7. any of regex.iextract(sender.display_name) where:
    • .full_match not in (sender.email.local_part)

Inspects: body.current_thread.text, headers.references, sender.display_name, sender.email.local_part, subject.base, type.inbound. Sensors: regex.extract, regex.iextract, strings.concat, strings.ends_with, strings.starts_with.

Indicators matched (2)

FieldMatchValue
regex.extractregex^\P{L}*([\p{L}'-]+)
regex.iextractregex\w+

Stages and Predicates

Stage 1: mql_rule

and
  any(['Hey', 'Hi', 'Hello'])
    strings.starts_with func_call "strings.starts_with(body.current_thread.text)"
  any(regex.iextract(sender.display_name))
     macro "regex.iextract(sender.display_name)[].full_match not in (sender.email.local_part)"
  attachments length_compare "0"
  body.current_thread.text length_compare "500"
  headers.references length_compare "0"
  strings.ends_with func_call "strings.ends_with(body.current_thread.text)"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Impersonation: Executive using numbered local part

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

Detects messages from free email providers where the sender's email address uses a pattern commonly associated with executive impersonation, containing 'chair' or 'ceo' followed by numbers in the local part.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesFree email provider, Impersonation: VIP, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • sender.email
  • type

Rule body

type.inbound
and sender.email.domain.domain in $free_email_providers
and regex.icontains(sender.email.local_part, '^c(?:hair|eo)\d+')

Detection logic

Scope: inbound message.

Detects messages from free email providers where the sender's email address uses a pattern commonly associated with executive impersonation, containing 'chair' or 'ceo' followed by numbers in the local part.

  1. inbound message
  2. sender.email.domain.domain in $free_email_providers
  3. sender.email.local_part matches '^c(?:hair|eo)\\d+'

Inspects: sender.email.domain.domain, sender.email.local_part, type.inbound. Sensors: regex.icontains. Reference lists: $free_email_providers.

Indicators matched (1)

FieldMatchValue
regex.icontainsregex^c(?:hair|eo)\d+

Stages and Predicates

Stage 1: mql_rule

and
  sender.email.local_part regex_match "^c(?:hair|eo)\\d+"
  type.inbound eq "true"
   macro "sender.email.domain.domain in free_email_providers"

Indicators

These rows show field, operator, and value matches.

Impersonation: Human Resources with link or attachment and engaging language

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

Detects messages impersonating HR that contain at least 1 link or 1 attachment with engaging language in the body from an untrusted sender.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Credential Phishing
Tactics and techniquesImpersonation: Employee, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • body.links
  • headers
  • headers.auth_summary
  • headers.hops
  • sender.email
  • type

Rule body

type.inbound
and sender.email.domain.domain not in $org_domains
and (
  regex.icontains(sender.display_name,
                  '(\bh\W?r\W?\b|human\s?resources|hr depart(ment)?|employee relations)'
  )
  or (
    length(filter(ml.nlu_classifier(body.current_thread.text).entities,
                  .name == "sender"
           )
    ) == 1
    and any(ml.nlu_classifier(body.current_thread.text).entities,
            .name == "sender"
            and regex.icontains(.text,
                                '(\bh\W?r\W?\b|human\s?resources|hr depart(ment)?|employee relations)'
            )
    )
  )
)
and not (
  strings.icontains(sender.display_name, sender.email.domain.domain)
  and sender.email.domain.tld == "hr"
)

// negate replies
and (length(headers.references) == 0 or headers.in_reply_to is null)
// Negate common marketing mailers
and not (
  sender.display_name is not null
  and regex.icontains(sender.display_name,
                      'HR (?:Events|Expert|Support Center|Studies|Knowledge Cloud|News Library|Crowd|Solutions|Interests)|HR and People Operations'
  )
)
and not (
  any(headers.hops,
      strings.icontains(.authentication_results.spf_details.designator,
                        "constantcontact.com"
      )
  )
  or any(headers.hops,
         strings.icontains(.received_spf.designator, "constantcontact.com")
  )
  or (
    (
      any(headers.hops,
          .index == 0
          and any(.authentication_results.dkim_details,
                  .domain == "auth.ccsend.com"
          )
      )
    )
    and headers.auth_summary.dmarc.pass
  )
  or any(headers.references, strings.iends_with(., "ccsend.com"))
)
and (
  (0 < length(body.links) < 10 or length(attachments) > 0)
  // mass-mailer infra abuse results in an inflated link count due to mailer templates that include links for unsubbing, changing preferences, etc.
  // loosening the link count check as a result ensures we fire even with these conditions
  or (
    any(body.links,
        strings.ilike(.display_text,
                      "*unsubscribe*",
                      "update your preferences",
                      "add us to your address book"
        )
    )
    and 0 < length(body.links) < 15
  )
)
// Request and Urgency
and (
  (
    length(body.current_thread.text) > 100
    and any(ml.nlu_classifier(body.current_thread.text).entities,
            .name == "request"
    )
    and (
      any(ml.nlu_classifier(body.current_thread.text).entities,
          .name in ("urgency", "financial")
      )
      or (
        any(beta.ml_topic(body.current_thread.text).topics,
            .name == "Professional and Career Development"
            and .confidence == "high"
        )
        and any(ml.nlu_classifier(body.current_thread.text).intents,
                .name != "benign"
        )
      )
    )
  )
  or (
    length(body.current_thread.text) < 400
    and any(attachments,
            (.file_type in $file_types_images or .file_type == "pdf")
            and any(file.explode(.),
                    .scan.qr.type == "url"
                    and .scan.qr.url.domain.root_domain not in $org_domains
            )
    )
  )
)
// additional suspicious indicator
and (
  any(ml.nlu_classifier(body.current_thread.text).intents, .name != "benign")
  or length(ml.nlu_classifier(body.current_thread.text).intents) == 0 // not benign but not malicious either
  // 1-2 all caps body links
  or 0 < length(filter(body.links,
                       not (
                         strings.ilike(.display_text,
                                       "*unsubscribe*",
                                       "update your preferences",
                                       "add us to your address book"
                         )
                         or .href_url.domain.root_domain == 'aka.ms'
                       )
                       and regex.match(.display_text, '[A-Z ]+')
                ),
  ) < 3
  or any(attachments,
         (.file_type in $file_types_images or .file_type == "pdf")
         and any(file.explode(.),
                 any(ml.nlu_classifier(.scan.ocr.raw).intents,
                     .name == "cred_theft" and .confidence == "high"
                 )
         )
  )
)
// topic negation
and not any(beta.ml_topic(body.current_thread.text).topics,
            .name in (
              "Newsletters and Digests",
              "Advertising and Promotions",
              "Educational and Research",
            )
            and .confidence == "high"
)
and (
  profile.by_sender_email().prevalence in ("new", "outlier")
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
  or sender.email.email in (
    "adobesign@adobesign.com",
    "noreply@salesforce.com",
    "support@salesforce.com",
    "no-reply@salesforce.com"
  ) // abused services
)
// 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 (
        headers.auth_summary.dmarc.pass is null
        and not headers.auth_summary.spf.pass
      )
    )
  )
  or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)

Detection logic

Scope: inbound message.

Detects messages impersonating HR that contain at least 1 link or 1 attachment with engaging language in the body from an untrusted sender.

  1. inbound message
  2. sender.email.domain.domain not in $org_domains
  3. any of:
    • sender.display_name matches '(\\bh\\W?r\\W?\\b|human\\s?resources|hr depart(ment)?|employee relations)'
    • all of:
      • length(filter(ml.nlu_classifier(body.current_thread.text).entities, .name == 'sender')) is 1
      • any of ml.nlu_classifier(body.current_thread.text).entities where all hold:
        • .name is 'sender'
        • .text matches '(\\bh\\W?r\\W?\\b|human\\s?resources|hr depart(ment)?|employee relations)'
  4. not:
    • all of:
      • strings.icontains(sender.display_name)
      • sender.email.domain.tld is 'hr'
  5. any of:
    • length(headers.references) is 0
    • headers.in_reply_to is missing
  6. not:
    • all of:
      • sender.display_name is set
      • sender.display_name matches 'HR (?:Events|Expert|Support Center|Studies|Knowledge Cloud|News Library|Crowd|Solutions|Interests)|HR and People Operations'
  7. none of:
    • any of headers.hops where:
      • .authentication_results.spf_details.designator contains 'constantcontact.com'
    • any of headers.hops where:
      • .received_spf.designator contains 'constantcontact.com'
    • all of:
      • any of headers.hops where all hold:
        • .index is 0
        • any of .authentication_results.dkim_details where:
          • .domain is 'auth.ccsend.com'
      • headers.auth_summary.dmarc.pass
    • any of headers.references where:
      • . ends with 'ccsend.com'
  8. any of:
    • any of:
      • all of:
        • length(body.links) > 0
        • length(body.links) < 10
      • length(attachments) > 0
    • all of:
      • any of body.links where:
        • .display_text matches any of 3 patterns
          • *unsubscribe*
          • update your preferences
          • add us to your address book
      • all of:
        • length(body.links) > 0
        • length(body.links) < 15
  9. any of:
    • all of:
      • length(body.current_thread.text) > 100
      • any of ml.nlu_classifier(body.current_thread.text).entities where:
        • .name is 'request'
      • any of:
        • any of ml.nlu_classifier(body.current_thread.text).entities where:
          • .name in ('urgency', 'financial')
        • all of:
          • any of beta.ml_topic(body.current_thread.text).topics where all hold:
            • .name is 'Professional and Career Development'
            • .confidence is 'high'
          • any of ml.nlu_classifier(body.current_thread.text).intents where:
            • .name is not 'benign'
    • all of:
      • length(body.current_thread.text) < 400
      • any of attachments where all hold:
        • any of:
          • .file_type in $file_types_images
          • .file_type is 'pdf'
        • any of file.explode(.) where all hold:
          • .scan.qr.type is 'url'
          • .scan.qr.url.domain.root_domain not in $org_domains
  10. any of:
    • any of ml.nlu_classifier(body.current_thread.text).intents where:
      • .name is not 'benign'
    • length(ml.nlu_classifier(body.current_thread.text).intents) is 0
    • all of:
      • length(filter(body.links, not strings.ilike(.display_text, '*unsubscribe*', 'update your preferences', 'add us to your address book') or .href_url.domain.root_domain == 'aka.ms' and regex.match(.display_text, '[A-Z ]+'))) > 0
      • length(filter(body.links, not strings.ilike(.display_text, '*unsubscribe*', 'update your preferences', 'add us to your address book') or .href_url.domain.root_domain == 'aka.ms' and regex.match(.display_text, '[A-Z ]+'))) < 3
    • any of attachments where all hold:
      • any of:
        • .file_type in $file_types_images
        • .file_type is 'pdf'
      • any of file.explode(.) where:
        • any of ml.nlu_classifier(.scan.ocr.raw).intents where all hold:
          • .name is 'cred_theft'
          • .confidence is 'high'
  11. not:
    • any of beta.ml_topic(body.current_thread.text).topics where all hold:
      • .name in ('Newsletters and Digests', 'Advertising and Promotions', 'Educational and Research')
      • .confidence is 'high'
  12. any of:
    • profile.by_sender_email().prevalence in ('new', 'outlier')
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
    • sender.email.email in ('adobesign@adobesign.com', 'noreply@salesforce.com', 'support@salesforce.com', 'no-reply@salesforce.com')
  13. any of:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • any of:
        • not:
          • headers.auth_summary.dmarc.pass
        • all of:
          • headers.auth_summary.dmarc.pass is missing
          • not:
            • headers.auth_summary.spf.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[].display_text, body.links[].href_url.domain.root_domain, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.hops, headers.hops[].authentication_results.dkim_details, headers.hops[].authentication_results.dkim_details[].domain, headers.hops[].authentication_results.spf_details.designator, headers.hops[].index, headers.hops[].received_spf.designator, headers.in_reply_to, headers.references, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.domain.tld, sender.email.email, type.inbound. Sensors: beta.ml_topic, file.explode, ml.nlu_classifier, profile.by_sender, profile.by_sender_email, regex.icontains, regex.match, strings.icontains, strings.iends_with, strings.ilike. Reference lists: $file_types_images, $high_trust_sender_root_domains, $org_domains.

Indicators matched (19)

FieldMatchValue
regex.icontainsregex(\bh\W?r\W?\b|human\s?resources|hr depart(ment)?|employee relations)
ml.nlu_classifier(body.current_thread.text).entities[].nameequalssender
strings.ilikesubstring*unsubscribe*
strings.ilikesubstringupdate your preferences
strings.ilikesubstringadd us to your address book
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsrequest
ml.nlu_classifier(body.current_thread.text).entities[].namememberurgency
ml.nlu_classifier(body.current_thread.text).entities[].namememberfinancial
beta.ml_topic(body.current_thread.text).topics[].nameequalsProfessional and Career Development
beta.ml_topic(body.current_thread.text).topics[].confidenceequalshigh
attachments[].file_typeequalspdf
file.explode(attachments[])[].scan.qr.typeequalsurl
7 more
regex.matchregex[A-Z ]+
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].nameequalscred_theft
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidenceequalshigh
sender.email.emailmemberadobesign@adobesign.com
sender.email.emailmembernoreply@salesforce.com
sender.email.emailmembersupport@salesforce.com
sender.email.emailmemberno-reply@salesforce.com

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      or
        and
          any(beta.ml_topic(body.current_thread.text).topics)
            and
              beta.ml_topic(body.current_thread.text).topics.confidence eq "high"
              beta.ml_topic(body.current_thread.text).topics.name eq "Professional and Career Development"
          any(ml.nlu_classifier(body.current_thread.text).intents)
            ml.nlu_classifier(body.current_thread.text).intents.name ne "benign"
        any(ml.nlu_classifier(body.current_thread.text).entities)
          ml.nlu_classifier(body.current_thread.text).entities.name in ["financial", "urgency"]
      any(ml.nlu_classifier(body.current_thread.text).entities)
        ml.nlu_classifier(body.current_thread.text).entities.name eq "request"
      body.current_thread.text length_compare "100"
    and
      any(attachments)
        and
          any(file.explode(attachments))
            and
              file.explode(attachments[])[].scan.qr.type eq "url"
               macro "file.explode(attachments[])[].scan.qr.url.domain.root_domain not in org_domains"
          or
            attachments.file_type eq "pdf"
             macro "attachments[].file_type in file_types_images"
      body.current_thread.text length_compare "400"
  not
    or
      and
        any(headers.hops)
          and
            any(headers.hops.authentication_results.dkim_details)
              headers.hops.authentication_results.dkim_details.domain eq "auth.ccsend.com"
            headers.hops.index eq "0"
        headers.auth_summary.dmarc.pass eq "true"
      any(headers.hops)
        headers.hops.authentication_results.spf_details.designator contains "constantcontact.com"
      any(headers.hops)
        headers.hops.received_spf.designator contains "constantcontact.com"
      any(headers.references)
        headers.references ends_with "ccsend.com"
  or
    any(attachments)
      and
        any(file.explode(attachments))
          any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).intents)
            and
              ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidence eq "high"
              ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].name eq "cred_theft"
        or
          attachments.file_type eq "pdf"
           macro "attachments[].file_type in file_types_images"
    and
      filter(body.links, not strings.ilike(.display_text, '*unsubscribe*', 'update your preferences', 'add us to your address book') or .href_url.domain.root_domain == 'aka.ms' and regex.match(.display_text, '[A-Z ]+')) length_compare "0"
      filter(body.links, not strings.ilike(.display_text, '*unsubscribe*', 'update your preferences', 'add us to your address book') or .href_url.domain.root_domain == 'aka.ms' and regex.match(.display_text, '[A-Z ]+')) length_compare "3"
    any(ml.nlu_classifier(body.current_thread.text).intents)
      ml.nlu_classifier(body.current_thread.text).intents.name ne "benign"
    ml.nlu_classifier(body.current_thread.text).intents length_compare "0"
  or
    and
      or
        and
          not
            headers.auth_summary.spf.pass eq "true"
          headers.auth_summary.dmarc.pass is_null
        not
          headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    and
      any(body.links)
        or
          body.links.display_text eq "add us to your address book"
          body.links.display_text eq "update your preferences"
          body.links.display_text match "unsubscribe"
      body.links length_compare "0"
      body.links length_compare "15"
    and
      body.links length_compare "0"
      body.links length_compare "10"
    attachments length_compare "0"
  or
    and
      any(ml.nlu_classifier(body.current_thread.text).entities)
        and
          ml.nlu_classifier(body.current_thread.text).entities.name eq "sender"
          ml.nlu_classifier(body.current_thread.text).entities.text regex_match "(\\bh\\W?r\\W?\\b|human\\s?resources|hr depart(ment)?|employee relations)"
      filter(ml.nlu_classifier(body.current_thread.text).entities, .name == 'sender') length_compare "1"
    sender.display_name regex_match "(\\bh\\W?r\\W?\\b|human\\s?resources|hr depart(ment)?|employee relations)"
  not
    any(beta.ml_topic(body.current_thread.text).topics)
      and
        beta.ml_topic(body.current_thread.text).topics.confidence eq "high"
        beta.ml_topic(body.current_thread.text).topics.name in ["Advertising and Promotions", "Educational and Research", "Newsletters and Digests"]
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    profile.by_sender_email func_call "profile.by_sender_email().prevalence in (new, outlier)"
    sender.email.email in ["adobesign@adobesign.com", "no-reply@salesforce.com", "noreply@salesforce.com", "support@salesforce.com"]
  not
    and
      sender.display_name is_not_null
      sender.display_name regex_match "HR (?:Events|Expert|Support Center|Studies|Knowledge Cloud|News Library|Crowd|Solutions|Interests)|HR and People Operations"
  not
    and
      sender.email.domain.tld eq "hr"
      strings.icontains func_call "strings.icontains(sender.display_name)"
  or
    headers.in_reply_to is_null
    headers.references length_compare "0"
  type.inbound eq "true"
   macro "sender.email.domain.domain not in org_domains"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.hopsarray_any(no value, null check)excludes:headers.hops
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
headers.referencesarray_any(no value, null check)excludes:headers.references
beta.ml_topic(body.current_thread.text).topicsarray_any(no value, null check)excludes:beta.ml_topic(body.current_thread.text).topics
sender.display_nameis_not_null(no value, null check)excludes:sender.display_name
sender.display_nameregex_matchHR (?:Events|Expert|Support Center|Studies|Knowledge Cloud|News Library|Crowd|Solutions|Interests), HR and People Operationsexcludes:sender.display_name field:"sender.display_name" value:"HR (?:Events|Expert|Support Center|Studies|Knowledge Cloud|News Library|Crowd|Solutions|Interests)" field:"sender.display_name" value:"HR and People Operations"
sender.email.domain.tldeqhrexcludes:sender.email.domain.tld field:"sender.email.domain.tld" value:"hr"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
headers.auth_summary.dmarc.passis_null
  • (no value, null check)
field:"headers.auth_summary.dmarc.pass" kind:is_null
headers.in_reply_tois_null
  • (no value, null check)
field:"headers.in_reply_to" kind:is_null
sender.display_nameregex_match
  • (\bh\W?r\W?\b|human\s?resources|hr depart(ment)?|employee relations)
field:"sender.display_name" kind:regex_match value:"(\bh\W?r\W?\b|human\s?resources|hr depart(ment)?|employee relations)"
sender.email.emailin
  • adobesign@adobesign.com
  • no-reply@salesforce.com
  • noreply@salesforce.com
  • support@salesforce.com
field:"sender.email.email" kind:in
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Impersonation: IT Department mailbox storage alert

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

Detects inbound messages impersonating an internal IT Department by presenting a fake mailbox storage alert.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Employee, Social engineering, Out of band pivot

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.previous_threads
  • type

Rule body

type.inbound
and strings.contains(body.current_thread.text, 'MAILBOX STORAGE ALERT')
and all([
          'Clean Inbox',
          'Storage Guide',
          'Empty Deleted Items',
          'Clean Mailbox Now',
          'Contact IT Support'
        ],
        . in map(html.xpath(body.html, '//a').nodes, .display_text)
)
and any(body.previous_threads,
        strings.contains(.text, 'IT Department')
        and strings.contains(.text, 'call ext. 5555')
)

Detection logic

Scope: inbound message.

Detects inbound messages impersonating an internal IT Department by presenting a fake mailbox storage alert.

  1. inbound message
  2. body.current_thread.text contains 'MAILBOX STORAGE ALERT'
  3. all of ['Clean Inbox', 'Storage Guide', 'Empty Deleted Items', 'Clean Mailbox Now', 'Contact IT Support'] where:
    • . in map(html.xpath(body.html, '//a').nodes, .display_text)
  4. any of body.previous_threads where all hold:
    • .text contains 'IT Department'
    • .text contains 'call ext. 5555'

Inspects: body.current_thread.text, body.html, body.previous_threads, body.previous_threads[].text, type.inbound. Sensors: html.xpath, strings.contains.

Indicators matched (3)

FieldMatchValue
strings.containssubstringMAILBOX STORAGE ALERT
strings.containssubstringIT Department
strings.containssubstringcall ext. 5555

Stages and Predicates

Stage 1: mql_rule

and
  any(body.previous_threads)
    and
      body.previous_threads.text contains "IT Department"
      body.previous_threads.text contains "call ext. 5555"
  body.current_thread.text contains "MAILBOX STORAGE ALERT"
  type.inbound eq "true"
   macro "all(['Clean Inbox', 'Storage Guide', 'Empty Deleted Items', 'Clean Mailbox Now', 'Contact IT Support'])"

Indicators

These rows show field, operator, and value matches.

Impersonation: Legal firm with copyright infringement notice

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

Detects messages impersonating legal firms or copyright enforcement entities with extensive legal terminology, threatening language, and urgent compliance demands.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Extortion
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • recipients
  • sender.email
  • subject
  • type

Rule body

type.inbound
and length(body.previous_threads) == 0
and length(body.current_thread.text) < 5000
and (
  0 < length(body.links) < 10 or beta.scan_qr(file.message_screenshot()).found
)

// common strings in subject or base
and (
  2 of (
    strings.ilike(subject.base, '*Content*'),
    strings.ilike(subject.base, '*Compliance*'),
    strings.ilike(subject.base, '*Review*'),
    strings.ilike(subject.base, '*Legal*'),
    strings.ilike(subject.base, '*Formal*'),
    strings.ilike(subject.base, '*LLP*'),
    strings.ilike(subject.base, '*Unauthorized*'),
    strings.ilike(subject.base, '*Trademark*'),
    strings.ilike(subject.base, '*Law*'),
    strings.ilike(subject.base, '*Enforcement*'),
    strings.ilike(subject.base, '*Copyright*'),
    strings.ilike(subject.base, '*Violat*'),
    strings.ilike(subject.base, '*Intellectual*'),
    strings.ilike(subject.base, '*Concerning*'),
    strings.ilike(subject.base, '*Notice*'),
    strings.ilike(subject.base, '*Licensing*'),
    strings.ilike(subject.base, '*Clarification*'),
    strings.ilike(subject.base, '*Matter*'),
    strings.ilike(subject.base, '*Conflict*'),
    strings.ilike(subject.base, '*Ownership*'),
    strings.ilike(sender.display_name, '*Content*'),
    strings.ilike(sender.display_name, '*Copyright*'),
    strings.ilike(sender.display_name, '*Review*'),
    strings.ilike(sender.display_name, '*Legal*'),
    strings.ilike(sender.display_name, '*Investigation*'),
    strings.ilike(sender.display_name, '*LLP*'),
    strings.ilike(sender.display_name, '*Law*'),
    strings.ilike(sender.display_name, '*Intellectual*'),
    strings.ilike(sender.display_name, '*Notice*'),
    strings.ilike(sender.display_name, '*Matter*'),
    strings.ilike(sender.display_name, '*Dispute*'),
    strings.ilike(sender.display_name, '*Resolution*'),
    strings.ilike(sender.display_name, '*Advisory*'),
  )
)

// common strings in email current thread
and 15 of (
  strings.ilike(body.current_thread.text, '*copyright*'),
  strings.ilike(body.current_thread.text, '*trademark*'),
  strings.ilike(body.current_thread.text, '*inquiry*'),
  strings.ilike(body.current_thread.text, '*online*'),
  strings.ilike(body.current_thread.text, '*authorized*'),
  strings.ilike(body.current_thread.text, '*legal*'),
  strings.ilike(body.current_thread.text, '*represent*'),
  strings.ilike(body.current_thread.text, '*lawful*'),
  strings.ilike(body.current_thread.text, '*owner*'),
  strings.ilike(body.current_thread.text, '*materials*'),
  strings.ilike(body.current_thread.text, '*protected*'),
  strings.ilike(body.current_thread.text, '*infring*'),
  strings.ilike(body.current_thread.text, '*immediate*'),
  strings.ilike(body.current_thread.text, '*cessation*'),
  strings.ilike(body.current_thread.text, '*content*'),
  strings.ilike(body.current_thread.text, '*referenced*'),
  strings.ilike(body.current_thread.text, '*17 U.S.C. §*'),
  strings.ilike(body.current_thread.text, '*constitutes*'),
  strings.ilike(body.current_thread.text, '*authorization*'),
  strings.ilike(body.current_thread.text, '*removal*'),
  strings.ilike(body.current_thread.text, '*comply*'),
  strings.ilike(body.current_thread.text, '*failure*'),
  strings.ilike(body.current_thread.text, '*law firm*'),
  strings.ilike(body.current_thread.text, '*LLP*'),
  strings.ilike(body.current_thread.text, '*compliance*'),
  strings.ilike(body.current_thread.text, '*cease*'),
  strings.ilike(body.current_thread.text, '*protect*'),
  strings.ilike(body.current_thread.text, '*rights*'),
  strings.ilike(body.current_thread.text, '*penalty*'),
  strings.ilike(body.current_thread.text, '*perjury*'),
  strings.ilike(body.current_thread.text, '*holder*'),
  strings.ilike(body.current_thread.text, '*declare*'),
  strings.ilike(body.current_thread.text, '*sworn*'),
  strings.ilike(body.current_thread.text, '*affidavit*'),
  strings.ilike(body.current_thread.text, '*investigation*'),
  strings.ilike(body.current_thread.text, '*identified*'),
  strings.ilike(body.current_thread.text, '*reproduction*'),
  strings.ilike(body.current_thread.text, '*license*'),
  strings.ilike(body.current_thread.text, '*granted*'),
  strings.ilike(body.current_thread.text, '*permitting*'),
  strings.ilike(body.current_thread.text, '*evidence*'),
  strings.ilike(body.current_thread.text, '*proceedings*'),
  strings.ilike(body.current_thread.text, '*evidentiary*'),
  strings.ilike(body.current_thread.text, '*remove*'),
  strings.ilike(body.current_thread.text, '*suspend*'),
  strings.ilike(body.current_thread.text, '*discontinue*'),
  strings.ilike(body.current_thread.text, '*72 hours*'),
  strings.ilike(body.current_thread.text, '*48 hours*'),
  strings.ilike(body.current_thread.text, '*24 hours*'),
  strings.ilike(body.current_thread.text, '*proof*'),
  strings.ilike(body.current_thread.text, '*unresolved*'),
  strings.ilike(body.current_thread.text, '*accordance*'),
  strings.ilike(body.current_thread.text, '*procedures*'),
  strings.ilike(body.current_thread.text, '*interests*'),
  strings.ilike(body.current_thread.text, '*appeal*'),
  strings.ilike(body.current_thread.text, '*clarification*'),
  strings.ilike(body.current_thread.text, '*notice*'),
  strings.ilike(body.current_thread.text, '*dissemination*'),
  strings.ilike(body.current_thread.text, '*counter-notice*'),
  strings.ilike(body.current_thread.text, '*exploitation*'),
  strings.ilike(body.current_thread.text, '*remedial*'),
  strings.ilike(body.current_thread.text, '*particulars*'),
  strings.ilike(body.current_thread.text, '*fingerprint*'),
  strings.ilike(body.current_thread.text, '*confidentiality*'),
  strings.ilike(body.current_thread.text, '*assertion*'),
  strings.ilike(body.current_thread.text, '*counsel*'),
  strings.ilike(body.current_thread.text, '*privileged*'),
  strings.ilike(body.current_thread.text, '*directive*'),
)

// remove phrase from legitimate complaint
and not regex.icontains(body.current_thread.text,
                        '(?:we are passing the notice below|content has been removed|removed from our website|notice of intended action|I have not granted|I am the original creator|content you reported has been removed|complaint will be carefully reviewed|provide a list of violations|document confirming your right to act)'
)

// not copyright reports
and not regex.icontains(body.current_thread.text,
                        '(?:confirmation|received).{0,100}copyright report'
)

// verified dmca receiving/sending address
and not any([recipients.cc, recipients.to, recipients.bcc],
            any(.,
                .email.email in (
                  'dmca@vimeo.com',
                  'dmca@support.epicgames.com',
                  'takedowns@doppel.com',
                  'ipenforcement@epicgames.com'
                )
            )
)
and not strings.icontains(sender.email.domain.root_domain, 'edwinjamesip.com')

Detection logic

Scope: inbound message.

Detects messages impersonating legal firms or copyright enforcement entities with extensive legal terminology, threatening language, and urgent compliance demands.

  1. inbound message
  2. length(body.previous_threads) is 0
  3. length(body.current_thread.text) < 5000
  4. any of:
    • all of:
      • length(body.links) > 0
      • length(body.links) < 10
    • beta.scan_qr(file.message_screenshot()).found
  5. at least 2 of:
    • subject.base matches '*Content*'
    • subject.base matches '*Compliance*'
    • subject.base matches '*Review*'
    • subject.base matches '*Legal*'
    • subject.base matches '*Formal*'
    • subject.base matches '*LLP*'
    • subject.base matches '*Unauthorized*'
    • subject.base matches '*Trademark*'
    • subject.base matches '*Law*'
    • subject.base matches '*Enforcement*'
    • subject.base matches '*Copyright*'
    • subject.base matches '*Violat*'
    • subject.base matches '*Intellectual*'
    • subject.base matches '*Concerning*'
    • subject.base matches '*Notice*'
    • subject.base matches '*Licensing*'
    • subject.base matches '*Clarification*'
    • subject.base matches '*Matter*'
    • subject.base matches '*Conflict*'
    • subject.base matches '*Ownership*'
    • sender.display_name matches '*Content*'
    • sender.display_name matches '*Copyright*'
    • sender.display_name matches '*Review*'
    • sender.display_name matches '*Legal*'
    • sender.display_name matches '*Investigation*'
    • sender.display_name matches '*LLP*'
    • sender.display_name matches '*Law*'
    • sender.display_name matches '*Intellectual*'
    • sender.display_name matches '*Notice*'
    • sender.display_name matches '*Matter*'
    • sender.display_name matches '*Dispute*'
    • sender.display_name matches '*Resolution*'
    • sender.display_name matches '*Advisory*'
  6. at least 15 of 68: body.current_thread.text matches any of 68 patterns
    • *copyright*
    • *trademark*
    • *inquiry*
    • *online*
    • *authorized*
    • *legal*
    • *represent*
    • *lawful*
    • *owner*
    • *materials*
    • *protected*
    • *infring*
    • *immediate*
    • *cessation*
    • *content*
    • *referenced*
    • *17 U.S.C. §*
    • *constitutes*
    • *authorization*
    • *removal*
    • *comply*
    • *failure*
    • *law firm*
    • *LLP*
    • *compliance*
    • *cease*
    • *protect*
    • *rights*
    • *penalty*
    • *perjury*
    • *holder*
    • *declare*
    • *sworn*
    • *affidavit*
    • *investigation*
    • *identified*
    • *reproduction*
    • *license*
    • *granted*
    • *permitting*
    • *evidence*
    • *proceedings*
    • *evidentiary*
    • *remove*
    • *suspend*
    • *discontinue*
    • *72 hours*
    • *48 hours*
    • *24 hours*
    • *proof*
    • *unresolved*
    • *accordance*
    • *procedures*
    • *interests*
    • *appeal*
    • *clarification*
    • *notice*
    • *dissemination*
    • *counter-notice*
    • *exploitation*
    • *remedial*
    • *particulars*
    • *fingerprint*
    • *confidentiality*
    • *assertion*
    • *counsel*
    • *privileged*
    • *directive*
  7. not:
    • body.current_thread.text matches '(?:we are passing the notice below|content has been removed|removed from our website|notice of intended action|I have not granted|I am the original creator|content you reported has been removed|complaint will be carefully reviewed|provide a list of violations|document confirming your right to act)'
  8. not:
    • body.current_thread.text matches '(?:confirmation|received).{0,100}copyright report'
  9. not:
    • any of [recipients.cc, recipients.to, recipients.bcc] where:
      • any of . where:
        • .email.email in ('dmca@vimeo.com', 'dmca@support.epicgames.com', 'takedowns@doppel.com', 'ipenforcement@epicgames.com')
  10. not:
    • sender.email.domain.root_domain contains 'edwinjamesip.com'

Inspects: body.current_thread.text, body.links, body.previous_threads, recipients.bcc, recipients.cc, recipients.to, sender.display_name, sender.email.domain.root_domain, subject.base, type.inbound. Sensors: beta.scan_qr, file.message_screenshot, regex.icontains, strings.icontains, strings.ilike.

Indicators matched (91)

FieldMatchValue
strings.ilikesubstring*Content*
strings.ilikesubstring*Compliance*
strings.ilikesubstring*Review*
strings.ilikesubstring*Legal*
strings.ilikesubstring*Formal*
strings.ilikesubstring*LLP*
strings.ilikesubstring*Unauthorized*
strings.ilikesubstring*Trademark*
strings.ilikesubstring*Law*
strings.ilikesubstring*Enforcement*
strings.ilikesubstring*Copyright*
strings.ilikesubstring*Violat*
79 more
strings.ilikesubstring*Intellectual*
strings.ilikesubstring*Concerning*
strings.ilikesubstring*Notice*
strings.ilikesubstring*Licensing*
strings.ilikesubstring*Clarification*
strings.ilikesubstring*Matter*
strings.ilikesubstring*Conflict*
strings.ilikesubstring*Ownership*
strings.ilikesubstring*Investigation*
strings.ilikesubstring*Dispute*
strings.ilikesubstring*Resolution*
strings.ilikesubstring*Advisory*
strings.ilikesubstring*copyright*
strings.ilikesubstring*trademark*
strings.ilikesubstring*inquiry*
strings.ilikesubstring*online*
strings.ilikesubstring*authorized*
strings.ilikesubstring*legal*
strings.ilikesubstring*represent*
strings.ilikesubstring*lawful*
strings.ilikesubstring*owner*
strings.ilikesubstring*materials*
strings.ilikesubstring*protected*
strings.ilikesubstring*infring*
strings.ilikesubstring*immediate*
strings.ilikesubstring*cessation*
strings.ilikesubstring*content*
strings.ilikesubstring*referenced*
strings.ilikesubstring*17 U.S.C. §*
strings.ilikesubstring*constitutes*
strings.ilikesubstring*authorization*
strings.ilikesubstring*removal*
strings.ilikesubstring*comply*
strings.ilikesubstring*failure*
strings.ilikesubstring*law firm*
strings.ilikesubstring*compliance*
strings.ilikesubstring*cease*
strings.ilikesubstring*protect*
strings.ilikesubstring*rights*
strings.ilikesubstring*penalty*
strings.ilikesubstring*perjury*
strings.ilikesubstring*holder*
strings.ilikesubstring*declare*
strings.ilikesubstring*sworn*
strings.ilikesubstring*affidavit*
strings.ilikesubstring*investigation*
strings.ilikesubstring*identified*
strings.ilikesubstring*reproduction*
strings.ilikesubstring*license*
strings.ilikesubstring*granted*
strings.ilikesubstring*permitting*
strings.ilikesubstring*evidence*
strings.ilikesubstring*proceedings*
strings.ilikesubstring*evidentiary*
strings.ilikesubstring*remove*
strings.ilikesubstring*suspend*
strings.ilikesubstring*discontinue*
strings.ilikesubstring*72 hours*
strings.ilikesubstring*48 hours*
strings.ilikesubstring*24 hours*
strings.ilikesubstring*proof*
strings.ilikesubstring*unresolved*
strings.ilikesubstring*accordance*
strings.ilikesubstring*procedures*
strings.ilikesubstring*interests*
strings.ilikesubstring*appeal*
strings.ilikesubstring*clarification*
strings.ilikesubstring*notice*
strings.ilikesubstring*dissemination*
strings.ilikesubstring*counter-notice*
strings.ilikesubstring*exploitation*
strings.ilikesubstring*remedial*
strings.ilikesubstring*particulars*
strings.ilikesubstring*fingerprint*
strings.ilikesubstring*confidentiality*
strings.ilikesubstring*assertion*
strings.ilikesubstring*counsel*
strings.ilikesubstring*privileged*
strings.ilikesubstring*directive*

Stages and Predicates

Stage 1: mql_rule

and
  not
    any([recipients.cc, recipients.to, recipients.bcc])
      any([recipients.cc, recipients.to, recipients.bcc])
        [recipients.cc, recipients.to, recipients.bcc].email.email in ["dmca@support.epicgames.com", "dmca@vimeo.com", "ipenforcement@epicgames.com", "takedowns@doppel.com"]
  or
    and
      body.links length_compare "0"
      body.links length_compare "10"
    beta.scan_qr func_call "beta.scan_qr(file.message_screenshot()).found"
  or
    body.current_thread.text match "17 U.S.C. §"
    body.current_thread.text match "24 hours"
    body.current_thread.text match "48 hours"
    body.current_thread.text match "72 hours"
    body.current_thread.text match "LLP"
    body.current_thread.text match "accordance"
    body.current_thread.text match "affidavit"
    body.current_thread.text match "appeal"
    body.current_thread.text match "assertion"
    body.current_thread.text match "authorization"
    body.current_thread.text match "authorized"
    body.current_thread.text match "cease"
    body.current_thread.text match "cessation"
    body.current_thread.text match "clarification"
    body.current_thread.text match "compliance"
    body.current_thread.text match "comply"
    body.current_thread.text match "confidentiality"
    body.current_thread.text match "constitutes"
    body.current_thread.text match "content"
    body.current_thread.text match "copyright"
    body.current_thread.text match "counsel"
    body.current_thread.text match "counter-notice"
    body.current_thread.text match "declare"
    body.current_thread.text match "directive"
    body.current_thread.text match "discontinue"
    body.current_thread.text match "dissemination"
    body.current_thread.text match "evidence"
    body.current_thread.text match "evidentiary"
    body.current_thread.text match "exploitation"
    body.current_thread.text match "failure"
    body.current_thread.text match "fingerprint"
    body.current_thread.text match "granted"
    body.current_thread.text match "holder"
    body.current_thread.text match "identified"
    body.current_thread.text match "immediate"
    body.current_thread.text match "infring"
    body.current_thread.text match "inquiry"
    body.current_thread.text match "interests"
    body.current_thread.text match "investigation"
    body.current_thread.text match "law firm"
    body.current_thread.text match "lawful"
    body.current_thread.text match "legal"
    body.current_thread.text match "license"
    body.current_thread.text match "materials"
    body.current_thread.text match "notice"
    body.current_thread.text match "online"
    body.current_thread.text match "owner"
    body.current_thread.text match "particulars"
    body.current_thread.text match "penalty"
    body.current_thread.text match "perjury"
    body.current_thread.text match "permitting"
    body.current_thread.text match "privileged"
    body.current_thread.text match "procedures"
    body.current_thread.text match "proceedings"
    body.current_thread.text match "proof"
    body.current_thread.text match "protect"
    body.current_thread.text match "protected"
    body.current_thread.text match "referenced"
    body.current_thread.text match "remedial"
    body.current_thread.text match "removal"
    body.current_thread.text match "remove"
    body.current_thread.text match "represent"
    body.current_thread.text match "reproduction"
    body.current_thread.text match "rights"
    body.current_thread.text match "suspend"
    body.current_thread.text match "sworn"
    body.current_thread.text match "trademark"
    body.current_thread.text match "unresolved"
  not
    body.current_thread.text regex_match "(?:confirmation|received).{0,100}copyright report"
  not
    body.current_thread.text regex_match "(?:we are passing the notice below|content has been removed|removed from our website|notice of intended action|I have not granted|I am the original creator|content you reported has been removed|complaint will be carefully reviewed|provide a list of violations|document confirming your right to act)"
  or
    sender.display_name match "Advisory"
    sender.display_name match "Content"
    sender.display_name match "Copyright"
    sender.display_name match "Dispute"
    sender.display_name match "Intellectual"
    sender.display_name match "Investigation"
    sender.display_name match "LLP"
    sender.display_name match "Law"
    sender.display_name match "Legal"
    sender.display_name match "Matter"
    sender.display_name match "Notice"
    sender.display_name match "Resolution"
    sender.display_name match "Review"
    subject.base match "Clarification"
    subject.base match "Compliance"
    subject.base match "Concerning"
    subject.base match "Conflict"
    subject.base match "Content"
    subject.base match "Copyright"
    subject.base match "Enforcement"
    subject.base match "Formal"
    subject.base match "Intellectual"
    subject.base match "LLP"
    subject.base match "Law"
    subject.base match "Legal"
    subject.base match "Licensing"
    subject.base match "Matter"
    subject.base match "Notice"
    subject.base match "Ownership"
    subject.base match "Review"
    subject.base match "Trademark"
    subject.base match "Unauthorized"
    subject.base match "Violat"
  not
    sender.email.domain.root_domain contains "edwinjamesip.com"
  body.current_thread.text length_compare "5000"
  body.previous_threads length_compare "0"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
[recipients.cc, recipients.to, recipients.bcc]array_any(no value, null check)excludes:[recipients.cc, recipients.to, recipients.bcc]
body.current_thread.textregex_match(?:confirmation|received).{0,100}copyright reportexcludes:body.current_thread.text field:"body.current_thread.text" value:"(?:confirmation|received).{0,100}copyright report"
body.current_thread.textregex_match(?:we are passing the notice below|content has been removed|removed from our website|notice of intended action|I have not granted|I am the original creator|content you reported has been removed|complaint will be carefully reviewed|provide a list of violations|document confirming your right to act)excludes:body.current_thread.text field:"body.current_thread.text" value:"(?:we are passing the notice below|content has been removed|removed from our website|notice of intended action|I have not granted|I am the original creator|content you reported has been removed|complaint will be carefully reviewed|provide a list of violations|document confirming your right to act)"
sender.email.domain.root_domaincontainsedwinjamesip.comexcludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"edwinjamesip.com"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textwildcard
  • *17 U.S.C. §*
  • *24 hours*
  • *48 hours*
  • *72 hours*
  • *LLP*
  • *accordance*
  • *affidavit*
  • *appeal*
  • *assertion*
  • *authorization*
  • *authorized*
  • *cease*
  • *cessation*
  • *clarification*
  • *compliance*
  • *comply*
  • *confidentiality*
  • *constitutes*
  • *content*
  • *copyright*
  • *counsel*
  • *counter-notice*
  • *declare*
  • *directive*
  • *discontinue*
  • *dissemination*
  • *evidence*
  • *evidentiary*
  • *exploitation*
  • *failure*
  • *fingerprint*
  • *granted*
  • *holder*
  • *identified*
  • *immediate*
  • *infring*
  • *inquiry*
  • *interests*
  • *investigation*
  • *law firm*
  • +28 more values (see full rule source)
field:"body.current_thread.text" kind:wildcard
sender.display_namewildcard
  • *Advisory*
  • *Content*
  • *Copyright*
  • *Dispute*
  • *Intellectual*
  • *Investigation*
  • *LLP*
  • *Law*
  • *Legal*
  • *Matter*
  • *Notice*
  • *Resolution*
  • *Review*
field:"sender.display_name" kind:wildcard
subject.basewildcard
  • *Clarification*
  • *Compliance*
  • *Concerning*
  • *Conflict*
  • *Content*
  • *Copyright*
  • *Enforcement*
  • *Formal*
  • *Intellectual*
  • *LLP*
  • *Law*
  • *Legal*
  • *Licensing*
  • *Matter*
  • *Notice*
  • *Ownership*
  • *Review*
  • *Trademark*
  • *Unauthorized*
  • *Violat*
field:"subject.base" kind:wildcard
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Impersonation: Recipient organization in sender display name with credential theft image

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

Sender display name contains the recipient's organization domain while the actual email address differs. Message includes a single image attachment with OCR-detected credential theft language referencing the recipient's domain, and has no body text.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImage as content, Impersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • recipients
  • recipients.to[0]
  • type

Rule body

type.inbound
and length(body.links) <= 1
and length(attachments) == 1
and strings.icontains(sender.display_name, recipients.to[0].email.domain.sld)
and length(recipients.to) == 1
and recipients.to[0].email.domain.root_domain in $org_domains
and 
// No body text
(
  length(body.current_thread.text) == 0 or body.current_thread.text is null
)
and all(attachments,
        .file_type in $file_types_images
        //
        // This rule makes use of a beta feature and is subject to change without notice
        // using the beta feature in custom rules is not suggested until it has been formally released
        //
        and strings.icontains(beta.ocr(.).text,
                              recipients.to[0].email.domain.sld
        )
        and any(ml.nlu_classifier(beta.ocr(.).text).intents,
                .name == "cred_theft" and .confidence == "high"
        )
)

Detection logic

Scope: inbound message.

Sender display name contains the recipient's organization domain while the actual email address differs. Message includes a single image attachment with OCR-detected credential theft language referencing the recipient's domain, and has no body text.

  1. inbound message
  2. length(body.links) ≤ 1
  3. length(attachments) is 1
  4. strings.icontains(sender.display_name)
  5. length(recipients.to) is 1
  6. recipients.to[0].email.domain.root_domain in $org_domains
  7. any of:
    • length(body.current_thread.text) is 0
    • body.current_thread.text is missing
  8. all of attachments where all hold:
    • .file_type in $file_types_images
    • strings.icontains(beta.ocr(.).text)
    • any of ml.nlu_classifier(beta.ocr(.).text).intents where all hold:
      • .name is 'cred_theft'
      • .confidence is 'high'

Inspects: attachments[].file_type, body.current_thread.text, body.links, recipients.to, recipients.to[0].email.domain.root_domain, recipients.to[0].email.domain.sld, sender.display_name, type.inbound. Sensors: beta.ocr, ml.nlu_classifier, strings.icontains. Reference lists: $file_types_images, $org_domains.

Indicators matched (2)

FieldMatchValue
ml.nlu_classifier(beta.ocr(attachments[]).text).intents[].nameequalscred_theft
ml.nlu_classifier(beta.ocr(attachments[]).text).intents[].confidenceequalshigh

Stages and Predicates

Stage 1: mql_rule

and
  or
    body.current_thread.text is_null
    body.current_thread.text length_compare "0"
  attachments length_compare "1"
  body.links length_compare "1"
  recipients.to length_compare "1"
  strings.icontains func_call "strings.icontains(sender.display_name)"
  type.inbound eq "true"
   macro "all(attachments)"
   macro "recipients.to[0].email.domain.root_domain in org_domains"

Indicators

These rows show field, operator, and value matches.

Impersonation: Salesforce fake campaign failure notification

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

Detects messages impersonating Salesforce with urgent language about failed or cancelled campaigns, containing external links from first-time senders outside legitimate Salesforce domains.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.links
  • sender.email
  • type

Rule body

type.inbound
and strings.icontains(sender.display_name, "salesforce")
and sender.email.domain.root_domain not in (
  "salesforce.com",
  "force.com",
  "site.com",
  "agentforce.com"
)
and length(attachments) == 0
// theare are external links (not org or SF domains)
and length(filter(body.links,
                  .href_url.domain.domain not in $org_domains
                  and .href_url.domain.root_domain not in (
                    "salesforce.com",
                    "force.com",
                    "site.com" // salesforce CRM 
                  )
           )
) > 0
and length(body.current_thread.text) <= 600
and strings.contains(body.current_thread.text, 'campaign')
and any(ml.nlu_classifier(body.current_thread.text).entities,
        .name == "urgency" and regex.icontains(.text, "(failed|cancelled)")
)
and any(ml.nlu_classifier(body.current_thread.text).entities,
        .name == "request"
)

Detection logic

Scope: inbound message.

Detects messages impersonating Salesforce with urgent language about failed or cancelled campaigns, containing external links from first-time senders outside legitimate Salesforce domains.

  1. inbound message
  2. sender.display_name contains 'salesforce'
  3. sender.email.domain.root_domain not in ('salesforce.com', 'force.com', 'site.com', 'agentforce.com')
  4. length(attachments) is 0
  5. length(filter(body.links, .href_url.domain.domain not in $org_domains and .href_url.domain.root_domain not in ('salesforce.com', 'force.com', 'site.com'))) > 0
  6. length(body.current_thread.text) ≤ 600
  7. body.current_thread.text contains 'campaign'
  8. any of ml.nlu_classifier(body.current_thread.text).entities where all hold:
    • .name is 'urgency'
    • .text matches '(failed|cancelled)'
  9. any of ml.nlu_classifier(body.current_thread.text).entities where:
    • .name is 'request'

Inspects: body.current_thread.text, body.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, sender.display_name, sender.email.domain.root_domain, type.inbound. Sensors: ml.nlu_classifier, regex.icontains, strings.contains, strings.icontains. Reference lists: $org_domains.

Indicators matched (5)

FieldMatchValue
strings.icontainssubstringsalesforce
strings.containssubstringcampaign
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsurgency
regex.icontainsregex(failed|cancelled)
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsrequest

Stages and Predicates

Stage 1: mql_rule

and
  any(ml.nlu_classifier(body.current_thread.text).entities)
    and
      ml.nlu_classifier(body.current_thread.text).entities.name eq "urgency"
      ml.nlu_classifier(body.current_thread.text).entities.text regex_match "(failed|cancelled)"
  any(ml.nlu_classifier(body.current_thread.text).entities)
    ml.nlu_classifier(body.current_thread.text).entities.name eq "request"
  not
    sender.email.domain.root_domain in ["agentforce.com", "force.com", "salesforce.com", "site.com"]
  attachments length_compare "0"
  body.current_thread.text contains "campaign"
  body.current_thread.text length_compare "600"
  filter(body.links, .href_url.domain.domain not in $org_domains and .href_url.domain.root_domain not in ('salesforce.com', 'force.com', 'site.com')) length_compare "0"
  sender.display_name contains "salesforce"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaininagentforce.com, force.com, salesforce.com, site.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

Impersonation: SAM/SBA federal registration

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

Detects inbound messages impersonating SAM.gov or the Small Business Administration by matching sender display names against known spoofed naming patterns (e.g. sba-support, sam registration/renewal) or by identifying sam.gov references paired with an embedded 'renew entity' image lure. Legitimate senders from verified sba.gov, sam.gov, or other high-trust domains that pass DMARC authentication are excluded.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, BEC/Fraud
Tactics and techniquesImpersonation: Brand, Social engineering, Image as content

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and (
  regex.icontains(sender.display_name,
                  '^sam(?:\.gov\b|\s(?:renew|compliance))',
                  'final\ssam\.gov',
                  '^sba[\s-]?(?:e[fd]|\.gov)',
                  '^sba[\s-](?:connect|invoice|admin|eidl)\b',
                  '^sba[\s-]support[\s-]\w+'
  )
  or (
    strings.icontains(body.current_thread.text, 'sam.gov')
    and any(html.xpath(body.html, '//img/@src').nodes,
            strings.icontains(.raw, 'sam%20renew%20entity')
    )
  )
)
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.

Detects inbound messages impersonating SAM.gov or the Small Business Administration by matching sender display names against known spoofed naming patterns (e.g. sba-support, sam registration/renewal) or by identifying sam.gov references paired with an embedded 'renew entity' image lure. Legitimate senders from verified sba.gov, sam.gov, or other high-trust domains that pass DMARC authentication are excluded.

  1. inbound message
  2. any of:
    • sender.display_name matches any of 5 patterns
      • ^sam(?:\.gov\b|\s(?:renew|compliance))
      • final\ssam\.gov
      • ^sba[\s-]?(?:e[fd]|\.gov)
      • ^sba[\s-](?:connect|invoice|admin|eidl)\b
      • ^sba[\s-]support[\s-]\w+
    • all of:
      • body.current_thread.text contains 'sam.gov'
      • any of html.xpath(body.html, '//img/@src').nodes where:
        • .raw contains 'sam%20renew%20entity'
  3. 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, body.html, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.root_domain, type.inbound. Sensors: html.xpath, regex.icontains, strings.icontains. Reference lists: $high_trust_sender_root_domains.

Indicators matched (7)

FieldMatchValue
regex.icontainsregex^sam(?:\.gov\b|\s(?:renew|compliance))
regex.icontainsregexfinal\ssam\.gov
regex.icontainsregex^sba[\s-]?(?:e[fd]|\.gov)
regex.icontainsregex^sba[\s-](?:connect|invoice|admin|eidl)\b
regex.icontainsregex^sba[\s-]support[\s-]\w+
strings.icontainssubstringsam.gov
strings.icontainssubstringsam%20renew%20entity

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      any(html.xpath(body.html, '//img/@src').nodes)
        html.xpath(body.html, '//img/@src').nodes.raw contains "sam%20renew%20entity"
      body.current_thread.text contains "sam.gov"
    sender.display_name regex_match "^sam(?:\\.gov\\b|\\s(?:renew|compliance))"
    sender.display_name regex_match "^sba[\\s-](?:connect|invoice|admin|eidl)\\b"
    sender.display_name regex_match "^sba[\\s-]?(?:e[fd]|\\.gov)"
    sender.display_name regex_match "^sba[\\s-]support[\\s-]\\w+"
    sender.display_name regex_match "final\\ssam\\.gov"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textcontains
  • sam.gov
field:"body.current_thread.text" kind:contains value:"sam.gov"
sender.display_nameregex_match
  • ^sam(?:.gov\b|\s(?:renew|compliance))
  • ^sba[\s-](?:connect|invoice|admin|eidl)\b
  • ^sba[\s-]?(?:e[fd]|.gov)
  • ^sba[\s-]support[\s-]\w+
  • final\ssam.gov
field:"sender.display_name" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Impersonation: SharePoint reply header anomaly

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

Detects messages with SharePoint reply headers that lack standard reply characteristics and contain inconsistencies in thread elements and recipient patterns

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering, Impersonation: Brand, Evasion, Spoofing

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • body.html
  • body.plain
  • headers
  • recipients
  • recipients.to
  • sender.email
  • subject
  • type

Rule body

type.inbound
// appears to be a reply 
and strings.istarts_with(headers.in_reply_to, '<Share-')
and strings.ends_with(headers.in_reply_to, '@odspnotify>')
and any([body.current_thread.text, body.plain.raw],
        strings.ilike(.,
                      "*shared a file with you*",
                      "*shared with you*",
                      "*invited you to access a file*",
                      "*received a document*",
                      "*shared a document*",
                      "*shared a new document*",
                      "*shared this document*"
        )
)
and ( // but lacks other reply elements
  not (
    strings.istarts_with(subject.subject, "RE:")
    or strings.istarts_with(subject.subject, "RES:")
    or strings.istarts_with(subject.subject, "R:")
    or strings.istarts_with(subject.subject, "ODG:")
    or strings.istarts_with(subject.subject,
                            "答复:"
    ) // response
    or strings.istarts_with(subject.subject,
                            "回复:"
    ) // reply
    or strings.istarts_with(subject.subject, "AW:")
    or strings.istarts_with(subject.subject, "TR:")
    or strings.istarts_with(subject.subject, "FWD:")
    or strings.istarts_with(subject.subject, "Resposta automática:")
    or strings.istarts_with(subject.subject, "Automatische Antwort:")
    or strings.istarts_with(subject.subject, "Autosvar:")
    or regex.icontains(subject.subject,
                       '^(?:(?:\[[^\]]+\]\s?|EXT(?:ERNAL)?\s?){0,3}|[[:punct:]]{0,3}\w+[[:punct:]]{0,3}\s)(?:r[ev]|fwd?|tr|aw|automat(ic|ed) reply)\s?:'
    )
  )
  // the sender is the recipient 
  // or the recipients are hidden
  or (
    (
      sender.email.email in map(recipients.to, .email.email)
      and sum([
                length(recipients.bcc),
                length(recipients.to),
                length(recipients.cc)
              ]
      ) == 1
    )
    or length(recipients.to) == 0
    or all(recipients.to, .email.email is null or .email.email == "")
  )
)

// lack a previous thread with sharepoint stuff
and not any([body.current_thread.text, body.html.display_text, body.plain.raw],
            3 of (
              strings.icontains(., "from:"),
              strings.icontains(., "to:"),
              strings.icontains(., "sent:"),
              strings.icontains(., "date:"),
              strings.icontains(., "cc:"),
              strings.icontains(., "subject:")
            )
            and regex.icontains(.,
                                '(?:from|to|sent|date|cc|subject|wrote):.*shared with you',
                                '(?:from|to|sent|date|cc|subject|wrote):.*shared the folder .* with you',
                                '(?:from|to|sent|date|cc|subject|wrote):.*invited you to view a file',
            )
)

// negate bouncebacks and undeliverables
and not any(attachments,
            .content_type in (
              "message/global-delivery-status",
              "message/delivery-status"
            )
)

Detection logic

Scope: inbound message.

Detects messages with SharePoint reply headers that lack standard reply characteristics and contain inconsistencies in thread elements and recipient patterns

  1. inbound message
  2. headers.in_reply_to starts with '<Share-'
  3. headers.in_reply_to ends with '@odspnotify>'
  4. any of [body.current_thread.text, body.plain.raw] where:
    • . matches any of 7 patterns
      • *shared a file with you*
      • *shared with you*
      • *invited you to access a file*
      • *received a document*
      • *shared a document*
      • *shared a new document*
      • *shared this document*
  5. any of:
    • none of:
      • subject.subject starts with 'RE:'
      • subject.subject starts with 'RES:'
      • subject.subject starts with 'R:'
      • subject.subject starts with 'ODG:'
      • subject.subject starts with '答复:'
      • subject.subject starts with '回复:'
      • subject.subject starts with 'AW:'
      • subject.subject starts with 'TR:'
      • subject.subject starts with 'FWD:'
      • subject.subject starts with 'Resposta automática:'
      • subject.subject starts with 'Automatische Antwort:'
      • subject.subject starts with 'Autosvar:'
      • subject.subject matches '^(?:(?:\\[[^\\]]+\\]\\s?|EXT(?:ERNAL)?\\s?){0,3}|[[:punct:]]{0,3}\\w+[[:punct:]]{0,3}\\s)(?:r[ev]|fwd?|tr|aw|automat(ic|ed) reply)\\s?:'
    • any of:
      • all of:
        • sender.email.email in map(recipients.to, .email.email)
        • sum([length(recipients.bcc), length(recipients.to), length(recipients.cc)]) is 1
      • length(recipients.to) is 0
      • all of recipients.to where any holds:
        • .email.email is missing
        • .email.email is ''
  6. not:
    • any of [body.current_thread.text, body.html.display_text, body.plain.raw] where all hold:
      • at least 3 of 6: . contains any of 6 patterns
        • from:
        • to:
        • sent:
        • date:
        • cc:
        • subject:
      • . matches any of 3 patterns
        • (?:from|to|sent|date|cc|subject|wrote):.*shared with you
        • (?:from|to|sent|date|cc|subject|wrote):.*shared the folder .* with you
        • (?:from|to|sent|date|cc|subject|wrote):.*invited you to view a file
  7. not:
    • any of attachments where:
      • .content_type in ('message/global-delivery-status', 'message/delivery-status')

Inspects: attachments[].content_type, body.current_thread.text, body.html.display_text, body.plain.raw, headers.in_reply_to, recipients.bcc, recipients.cc, recipients.to, recipients.to[].email.email, sender.email.email, subject.subject, type.inbound. Sensors: regex.icontains, strings.ends_with, strings.icontains, strings.ilike, strings.istarts_with.

Indicators matched (10)

FieldMatchValue
strings.istarts_withprefix<Share-
strings.ends_withsuffix@odspnotify>
strings.ilikesubstring*shared a file with you*
strings.ilikesubstring*shared with you*
strings.ilikesubstring*invited you to access a file*
strings.ilikesubstring*received a document*
strings.ilikesubstring*shared a document*
strings.ilikesubstring*shared a new document*
strings.ilikesubstring*shared this document*
recipients.to[].email.emailequals

Stages and Predicates

Stage 1: mql_rule

and
  not
    any([body.current_thread.text, body.html.display_text, body.plain.raw])
      and
        or
          [body.current_thread.text, body.html.display_text, body.plain.raw] contains "cc:"
          [body.current_thread.text, body.html.display_text, body.plain.raw] contains "date:"
          [body.current_thread.text, body.html.display_text, body.plain.raw] contains "from:"
          [body.current_thread.text, body.html.display_text, body.plain.raw] contains "sent:"
          [body.current_thread.text, body.html.display_text, body.plain.raw] contains "subject:"
          [body.current_thread.text, body.html.display_text, body.plain.raw] contains "to:"
        or
          [body.current_thread.text, body.html.display_text, body.plain.raw] regex_match "(?:from|to|sent|date|cc|subject|wrote):.*invited you to view a file"
          [body.current_thread.text, body.html.display_text, body.plain.raw] regex_match "(?:from|to|sent|date|cc|subject|wrote):.*shared the folder .* with you"
          [body.current_thread.text, body.html.display_text, body.plain.raw] regex_match "(?:from|to|sent|date|cc|subject|wrote):.*shared with you"
  or
    not
      or
        subject.subject regex_match "^(?:(?:\\[[^\\]]+\\]\\s?|EXT(?:ERNAL)?\\s?){0,3}|[[:punct:]]{0,3}\\w+[[:punct:]]{0,3}\\s)(?:r[ev]|fwd?|tr|aw|automat(ic|ed) reply)\\s?:"
        subject.subject starts_with "AW:"
        subject.subject starts_with "Automatische Antwort:"
        subject.subject starts_with "Autosvar:"
        subject.subject starts_with "FWD:"
        subject.subject starts_with "ODG:"
        subject.subject starts_with "R:"
        subject.subject starts_with "RE:"
        subject.subject starts_with "RES:"
        subject.subject starts_with "Resposta automática:"
        subject.subject starts_with "TR:"
        subject.subject starts_with "回复:"
        subject.subject starts_with "答复:"
    and
      sum func_call "sum([length(recipients.bcc), length(recipients.to), length(recipients.cc)]) == 1"
       macro "sender.email.email in map(recipients.to, .email.email)"
    recipients.to length_compare "0"
     macro "all(recipients.to)"
  any([body.current_thread.text, body.plain.raw])
    or
      [body.current_thread.text, body.plain.raw] match "invited you to access a file"
      [body.current_thread.text, body.plain.raw] match "received a document"
      [body.current_thread.text, body.plain.raw] match "shared a document"
      [body.current_thread.text, body.plain.raw] match "shared a file with you"
      [body.current_thread.text, body.plain.raw] match "shared a new document"
      [body.current_thread.text, body.plain.raw] match "shared this document"
      [body.current_thread.text, body.plain.raw] match "shared with you"
  not
    any(attachments)
      attachments.content_type in ["message/delivery-status", "message/global-delivery-status"]
  headers.in_reply_to ends_with "@odspnotify>"
  headers.in_reply_to starts_with "<Share-"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
[body.current_thread.text, body.html.display_text, body.plain.raw]array_any(no value, null check)excludes:[body.current_thread.text, body.html.display_text, body.plain.raw]
attachmentsarray_any(no value, null check)excludes:attachments

Indicators

These rows show field, operator, and value matches.

Impersonation: Suspected supplier impersonation with suspicious content

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

This rule detects supplier impersonation by checking for: similar linked domains to the sender, non-freemail senders using freemail infrastructure, sender domains less than 90 days old, unsolicited communication or no prior interaction with the reply-to address, and a suspicious body.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesEvasion, Free email provider, Lookalike domain, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.links
  • body.plain
  • headers
  • headers.reply_to
  • sender.email
  • type

Rule body

type.inbound

// a linked domain is similar but not the same as the sender domain
and (
  any(body.links,
      length(.href_url.domain.sld) > 3
      and 0 < strings.levenshtein(.href_url.domain.sld, sender.email.domain.sld) <= 2

      // looking for lookalike domains above, typically the registrars won't match
      and network.whois(sender.email.domain).registrar_name != network.whois(.href_url.domain
      ).registrar_name

      // and one of the domains is less than 30 days old
      and (
        network.whois(sender.email.domain).days_old < 30
        or network.whois(.href_url.domain).days_old < 30
      )
  )
  and not sender.email.domain.root_domain == "onmicrosoft.com"
)
// the sender is not a freemail, but the message or the in-reply-to indicates it traversed a freemail infrastructure, likely an auto forwarding rule. Or the sender or reply-to domain is new
and (
  sender.email.domain.root_domain not in $free_email_providers
  and (
    any(headers.references,
        any($free_email_providers, strings.contains(.., .))
        and not strings.ends_with(., "outlook.com")
    )
    or (
      any($free_email_providers, strings.contains(headers.in_reply_to, .))
      // with the suspicious traversal tolerate 90 days
      and network.whois(sender.email.domain).days_old < 90
      and not strings.ends_with(headers.in_reply_to, 'outlook.com')
    )
    or any(headers.reply_to,
           network.whois(.email.domain).days_old < 30
           and .email.email != sender.email.email
    )
  )
)

//  not solicited, nor ever communicated with
and (
  not profile.by_sender_domain().solicited
  // reply-to is not in $recipient_emails
  or any(headers.reply_to, .email.email not in $recipient_emails)
)
and (
  2 of (
    // language attempting to engage
    (
      any(ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).entities,
          .name == "request"
      )
      and any(ml.nlu_classifier(coalesce(body.plain.raw,
                                         body.current_thread.text
                                )
              ).entities,
              .name == "financial"
      )
    ),
    // payment tag high confidence
    any(ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).tags,
        .name == "payment" and .confidence == "high"
    ),
    // invoicing language
    any(ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).tags,
        .name == "invoice"
    ),

    // urgency request
    any(ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).entities,
        .name == "urgency"
    )
  )
)

Detection logic

Scope: inbound message.

This rule detects supplier impersonation by checking for: similar linked domains to the sender, non-freemail senders using freemail infrastructure, sender domains less than 90 days old, unsolicited communication or no prior interaction with the reply-to address, and a suspicious body.

  1. inbound message
  2. all of:
    • any of body.links where all hold:
      • length(.href_url.domain.sld) > 3
      • all of:
        • strings.levenshtein(.href_url.domain.sld) > 0
        • strings.levenshtein(.href_url.domain.sld) ≤ 2
      • network.whois(sender.email.domain).registrar_name is not network.whois(.href_url.domain).registrar_name
      • any of:
        • network.whois(sender.email.domain).days_old < 30
        • network.whois(.href_url.domain).days_old < 30
    • not:
      • sender.email.domain.root_domain is 'onmicrosoft.com'
  3. all of:
    • sender.email.domain.root_domain not in $free_email_providers
    • any of:
      • any of headers.references where all hold:
        • any of $free_email_providers where:
          • strings.contains(.)
        • not:
          • . ends with 'outlook.com'
      • all of:
        • any of $free_email_providers where:
          • strings.contains(headers.in_reply_to)
        • network.whois(sender.email.domain).days_old < 90
        • not:
          • headers.in_reply_to ends with 'outlook.com'
      • any of headers.reply_to where all hold:
        • network.whois(.email.domain).days_old < 30
        • .email.email is not sender.email.email
  4. any of:
    • not:
      • profile.by_sender_domain().solicited
    • any of headers.reply_to where:
      • .email.email not in $recipient_emails
  5. at least 2 of:
    • all of:
      • any of ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).entities where:
        • .name is 'request'
      • any of ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).entities where:
        • .name is 'financial'
    • any of ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).tags where all hold:
      • .name is 'payment'
      • .confidence is 'high'
    • any of ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).tags where:
      • .name is 'invoice'
    • any of ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).entities where:
      • .name is 'urgency'

Inspects: body.current_thread.text, body.links, body.links[].href_url.domain, body.links[].href_url.domain.sld, body.plain.raw, headers.in_reply_to, headers.references, headers.reply_to, headers.reply_to[].email.domain, headers.reply_to[].email.email, sender.email.domain, sender.email.domain.root_domain, sender.email.domain.sld, sender.email.email, type.inbound. Sensors: ml.nlu_classifier, network.whois, profile.by_sender_domain, strings.contains, strings.ends_with, strings.levenshtein. Reference lists: $free_email_providers, $recipient_emails.

Indicators matched (6)

FieldMatchValue
ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).entities[].nameequalsrequest
ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).entities[].nameequalsfinancial
ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).tags[].nameequalspayment
ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).tags[].confidenceequalshigh
ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).tags[].nameequalsinvoice
ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).entities[].nameequalsurgency

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(headers.references)
      and
        not
          headers.references ends_with "outlook.com"
        any($free_email_providers)
          strings.contains func_call "strings.contains(headers.references[])"
    and
      not
        headers.in_reply_to ends_with "outlook.com"
      any($free_email_providers)
        strings.contains func_call "strings.contains(headers.in_reply_to)"
      network.whois func_call "network.whois(sender.email.domain).days_old < 90"
    any(headers.reply_to)
      and
        headers.reply_to.email.email cross_field_compare "sender.email.email"
        network.whois func_call "network.whois(headers.reply_to[].email.domain).days_old < 30"
  or
    and
      any(ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).entities)
        ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).entities.name eq "financial"
      any(ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).entities)
        ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).entities.name eq "request"
    any(ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).tags)
      and
        ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).tags.confidence eq "high"
        ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).tags.name eq "payment"
    any(ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).entities)
      ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).entities.name eq "urgency"
    any(ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).tags)
      ml.nlu_classifier(coalesce(body.plain.raw, body.current_thread.text)).tags.name eq "invoice"
  any(body.links)
    and
      or
        network.whois func_call "network.whois(body.links[].href_url.domain).days_old < 30"
        network.whois func_call "network.whois(sender.email.domain).days_old < 30"
      body.links.href_url.domain.sld length_compare "3"
      network.whois func_call "network.whois(sender.email.domain).registrar_name != network.whois(body.links[].href_url.domain).registrar_name"
      strings.levenshtein func_call "strings.levenshtein(body.links[].href_url.domain.sld) <= 2"
      strings.levenshtein func_call "strings.levenshtein(body.links[].href_url.domain.sld) > 0"
  or
    not
      profile.by_sender_domain func_call "profile.by_sender_domain().solicited"
    any(headers.reply_to)
       macro "headers.reply_to[].email.email not in recipient_emails"
  not
    sender.email.domain.root_domain eq "onmicrosoft.com"
  type.inbound eq "true"
   macro "sender.email.domain.root_domain not in free_email_providers"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaineqonmicrosoft.comexcludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"onmicrosoft.com"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

VIP Impersonation via Google Group relay with suspicious indicators

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

Public Google Groups can be used to impersonate internal senders, while the reply to address is not under organizational control, leading to fraud, credential phishing, or other unwanted outcomes.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Credential Phishing, Malware/Ransomware
Tactics and techniquesEvasion, Free email provider, Impersonation: Employee, Social engineering, Spoofing

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • headers.hops
  • headers.reply_to
  • headers.return_path
  • sender.email
  • subject
  • type

Rule body

(type.inbound or type.internal)
and sender.email.domain.root_domain in $org_domains

// subject, sender or reply to contains a VIP
and (
  any(headers.reply_to,
      any($org_vips, strings.contains(.display_name, ..display_name))
  )
  or any($org_vips, strings.contains(subject.subject, .display_name))
  or any($org_vips, strings.contains(sender.display_name, .display_name))
)
and any(headers.hops,
        any(.fields,
            strings.istarts_with(.name,
                                 "X-Authenticated-Sender",
                                 "X-Sender",
                                 "X-Original-Sender"
            )
        )
)

// reply to return path mismatch and not org domain
and any(headers.reply_to,
        .email.domain.root_domain != headers.return_path.domain.root_domain
        and .email.domain.root_domain not in $org_domains
)

// googlegroups found in hops
and any(headers.hops,
        .index == 0 and any(.fields, strings.icontains(.value, "googlegroups"))
)

// financial nlu entity in current thread
and 3 of (
  any(ml.nlu_classifier(body.current_thread.text).entities,
      .name == "financial"
  ),

  // invoice entity in display_text
  any(ml.nlu_classifier(body.current_thread.text).tags, .name == "invoice"),

  // fake thread
  (
    (subject.is_forward or subject.is_reply)
    and (
      (length(headers.references) == 0 and headers.in_reply_to is null)
      or headers.in_reply_to is null
    )
  ),

  // reply-to is freemail
  any(headers.reply_to, .email.domain.domain in $free_email_providers),

  // reply-to is not in $recipient_emails
  any(headers.reply_to, .email.email not in $recipient_emails),

  // dmarc authentication is freemail provider
  headers.auth_summary.dmarc.details.from.root_domain in $free_email_providers
)

Detection logic

Scope: inbound, internal message.

Public Google Groups can be used to impersonate internal senders, while the reply to address is not under organizational control, leading to fraud, credential phishing, or other unwanted outcomes.

  1. any of:
    • inbound message
    • internal message
  2. sender.email.domain.root_domain in $org_domains
  3. any of:
    • any of headers.reply_to where:
      • any of $org_vips where:
        • strings.contains(.display_name)
    • any of $org_vips where:
      • strings.contains(subject.subject)
    • any of $org_vips where:
      • strings.contains(sender.display_name)
  4. any of headers.hops where:
    • any of .fields where:
      • .name starts with any of 3 patterns
        • X-Authenticated-Sender
        • X-Sender
        • X-Original-Sender
  5. any of headers.reply_to where all hold:
    • .email.domain.root_domain is not headers.return_path.domain.root_domain
    • .email.domain.root_domain not in $org_domains
  6. any of headers.hops where all hold:
    • .index is 0
    • any of .fields where:
      • .value contains 'googlegroups'
  7. at least 3 of:
    • any of ml.nlu_classifier(body.current_thread.text).entities where:
      • .name is 'financial'
    • any of ml.nlu_classifier(body.current_thread.text).tags where:
      • .name is 'invoice'
    • all of:
      • any of:
        • subject.is_forward
        • subject.is_reply
      • any of:
        • all of:
          • length(headers.references) is 0
          • headers.in_reply_to is missing
        • headers.in_reply_to is missing
    • any of headers.reply_to where:
      • .email.domain.domain in $free_email_providers
    • any of headers.reply_to where:
      • .email.email not in $recipient_emails
    • headers.auth_summary.dmarc.details.from.root_domain in $free_email_providers

Inspects: body.current_thread.text, headers.auth_summary.dmarc.details.from.root_domain, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, headers.hops[].index, headers.in_reply_to, headers.references, headers.reply_to, headers.reply_to[].display_name, headers.reply_to[].email.domain.domain, headers.reply_to[].email.domain.root_domain, headers.reply_to[].email.email, headers.return_path.domain.root_domain, sender.display_name, sender.email.domain.root_domain, subject.is_forward, subject.is_reply, subject.subject, type.inbound, type.internal. Sensors: ml.nlu_classifier, strings.contains, strings.icontains, strings.istarts_with. Reference lists: $free_email_providers, $org_domains, $org_vips, $recipient_emails.

Indicators matched (6)

FieldMatchValue
strings.istarts_withprefixX-Authenticated-Sender
strings.istarts_withprefixX-Sender
strings.istarts_withprefixX-Original-Sender
strings.icontainssubstringgooglegroups
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsfinancial
ml.nlu_classifier(body.current_thread.text).tags[].nameequalsinvoice

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      or
        and
          headers.in_reply_to is_null
          headers.references length_compare "0"
        headers.in_reply_to is_null
      or
        subject.is_forward eq "true"
        subject.is_reply eq "true"
    any(ml.nlu_classifier(body.current_thread.text).entities)
      ml.nlu_classifier(body.current_thread.text).entities.name eq "financial"
    any(ml.nlu_classifier(body.current_thread.text).tags)
      ml.nlu_classifier(body.current_thread.text).tags.name eq "invoice"
    any(headers.reply_to)
       macro "headers.reply_to[].email.domain.domain in free_email_providers"
    any(headers.reply_to)
       macro "headers.reply_to[].email.email not in recipient_emails"
     macro "headers.auth_summary.dmarc.details.from.root_domain in free_email_providers"
  any(headers.hops)
    and
      any(headers.hops.fields)
        headers.hops.fields.value contains "googlegroups"
      headers.hops.index eq "0"
  any(headers.hops)
    any(headers.hops.fields)
      or
        headers.hops.fields[].name starts_with "X-Authenticated-Sender"
        headers.hops.fields[].name starts_with "X-Original-Sender"
        headers.hops.fields[].name starts_with "X-Sender"
  or
    any(headers.reply_to)
      any($org_vips)
        strings.contains func_call "strings.contains($org_vips[].display_name)"
    any($org_vips)
      strings.contains func_call "strings.contains(sender.display_name)"
    any($org_vips)
      strings.contains func_call "strings.contains(subject.subject)"
  any(headers.reply_to)
    and
      headers.reply_to.email.domain.root_domain cross_field_compare "headers.return_path.domain.root_domain"
       macro "headers.reply_to[].email.domain.root_domain not in org_domains"
  or
    type.inbound eq "true"
    type.internal eq "true"
   macro "sender.email.domain.root_domain in org_domains"

Indicators

These rows show field, operator, and value matches.

VIP impersonation with BEC language (near match, untrusted sender)

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

Sender is using a display name that matches the display name of someone in your $org_vips list. Detects potential Business Email Compromise (BEC) attacks by analyzing text within email body from untrusted senders.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesImpersonation: VIP, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • headers.reply_to
  • sender.email
  • type

Rule body

type.inbound
and any($org_vips,
        0 <= strings.ilevenshtein(sender.display_name, .display_name) < 4
)
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "bec" and .confidence in ("medium", "high")
)
and (
  (
    profile.by_sender().prevalence != "common"
    and not profile.by_sender().solicited
  )
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
  or profile.by_sender().days_since.last_outbound > 365
)
// negate sharepoint notifications originating from within the org
and not (
  sender.email.email in ('no-reply@sharepointonline.com')
  and length(headers.reply_to) > 0
  and all(headers.reply_to, .email.domain.root_domain in $org_domains)
)
// 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
)
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

Sender is using a display name that matches the display name of someone in your $org_vips list. Detects potential Business Email Compromise (BEC) attacks by analyzing text within email body from untrusted senders.

  1. inbound message
  2. any of $org_vips where all hold:
    • strings.ilevenshtein(sender.display_name) ≥ 0
    • strings.ilevenshtein(sender.display_name) < 4
  3. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name is 'bec'
    • .confidence in ('medium', 'high')
  4. any of:
    • all of:
      • profile.by_sender().prevalence is not 'common'
      • not:
        • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
    • profile.by_sender().days_since.last_outbound > 365
  5. not:
    • all of:
      • sender.email.email in ('no-reply@sharepointonline.com')
      • length(headers.reply_to) > 0
      • all of headers.reply_to where:
        • .email.domain.root_domain in $org_domains
  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
  7. not:
    • profile.by_sender().any_messages_benign

Inspects: body.current_thread.text, headers.auth_summary.dmarc.pass, headers.reply_to, headers.reply_to[].email.domain.root_domain, sender.display_name, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender, strings.ilevenshtein. Reference lists: $high_trust_sender_root_domains, $org_domains, $org_vips.

Indicators matched (3)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).intents[].nameequalsbec
ml.nlu_classifier(body.current_thread.text).intents[].confidencemembermedium
ml.nlu_classifier(body.current_thread.text).intents[].confidencememberhigh

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    and
      not
        profile.by_sender func_call "profile.by_sender().solicited"
      profile.by_sender func_call "profile.by_sender().prevalence != common"
    profile.by_sender func_call "profile.by_sender().days_since.last_outbound > 365"
  not
    and
      headers.reply_to length_compare "0"
      sender.email.email eq "no-reply@sharepointonline.com"
       macro "all(headers.reply_to)"
  any(ml.nlu_classifier(body.current_thread.text).intents)
    and
      ml.nlu_classifier(body.current_thread.text).intents.confidence in ["high", "medium"]
      ml.nlu_classifier(body.current_thread.text).intents.name eq "bec"
  any($org_vips)
    and
      strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name) < 4"
      strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name) >= 0"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.reply_tolength_compare0excludes:headers.reply_to field:"headers.reply_to" value:"0"
sender.email.emaileqno-reply@sharepointonline.comexcludes:sender.email.email field:"sender.email.email" value:"no-reply@sharepointonline.com"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

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

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • headers.reply_to
  • headers.x_authenticated_domain
  • headers.x_authenticated_sender
  • sender.email
  • type

Rule body

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')
  5. any of ml.nlu_classifier(body.current_thread.text).entities where:
    • .name is 'request'
  6. any of headers.reply_to where:
    • .email.email not in $recipient_emails
  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: 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

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    and
      headers.x_authenticated_sender.email cross_field_compare "sender.email.email"
       macro "headers.x_authenticated_domain.domain not in org_domains"
       macro "sender.email.domain.domain in org_domains"
     macro "sender.email.domain.domain not in org_domains"
  any(ml.nlu_classifier(body.current_thread.text).tags)
    and
      ml.nlu_classifier(body.current_thread.text).tags.confidence in ["high", "medium"]
      ml.nlu_classifier(body.current_thread.text).tags.name eq "invoice"
  any(ml.nlu_classifier(body.current_thread.text).entities)
    ml.nlu_classifier(body.current_thread.text).entities.name eq "request"
  any($org_vips)
    strings.contains func_call "strings.contains(sender.display_name)"
  any(headers.reply_to)
     macro "headers.reply_to[].email.email not in recipient_emails"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

VIP impersonation with urgent request (strict match, untrusted sender)

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

Sender is using a display name that matches the display name of someone in your $org_vips list. Detects potential Business Email Compromise (BEC) attacks by analyzing text within email body from untrusted senders.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesImpersonation: VIP, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • headers.reply_to
  • sender.email
  • type

Rule body

type.inbound
and any($org_vips, .display_name =~ sender.display_name)
and (
  any(ml.nlu_classifier(body.current_thread.text).intents,
      .name == "bec" and .confidence in ("medium", "high")
  )
  or (
    any(ml.nlu_classifier(body.current_thread.text).entities,
        .name == "urgency"
    )
    and any(ml.nlu_classifier(body.current_thread.text).entities,
            .name == "request"
    )
  )
)
and (
  (
    profile.by_sender().prevalence != "common"
    and not profile.by_sender().solicited
  )
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
  or profile.by_sender().days_since.last_outbound > 365
)
// negate sharepoint notifications originating from within the org
and not (
  sender.email.email in ('no-reply@sharepointonline.com')
  and length(headers.reply_to) > 0
  and all(headers.reply_to, .email.domain.root_domain in $org_domains)
)
// 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
)
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

Sender is using a display name that matches the display name of someone in your $org_vips list. Detects potential Business Email Compromise (BEC) attacks by analyzing text within email body from untrusted senders.

  1. inbound message
  2. any of $org_vips where:
    • .display_name is sender.display_name
  3. any of:
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'bec'
      • .confidence in ('medium', 'high')
    • all of:
      • any of ml.nlu_classifier(body.current_thread.text).entities where:
        • .name is 'urgency'
      • any of ml.nlu_classifier(body.current_thread.text).entities where:
        • .name is 'request'
  4. any of:
    • all of:
      • profile.by_sender().prevalence is not 'common'
      • not:
        • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
    • profile.by_sender().days_since.last_outbound > 365
  5. not:
    • all of:
      • sender.email.email in ('no-reply@sharepointonline.com')
      • length(headers.reply_to) > 0
      • all of headers.reply_to where:
        • .email.domain.root_domain in $org_domains
  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
  7. not:
    • profile.by_sender().any_messages_benign

Inspects: body.current_thread.text, headers.auth_summary.dmarc.pass, headers.reply_to, headers.reply_to[].email.domain.root_domain, sender.display_name, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender. Reference lists: $high_trust_sender_root_domains, $org_domains, $org_vips.

Indicators matched (5)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).intents[].nameequalsbec
ml.nlu_classifier(body.current_thread.text).intents[].confidencemembermedium
ml.nlu_classifier(body.current_thread.text).intents[].confidencememberhigh
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsurgency
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsrequest

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  or
    and
      any(ml.nlu_classifier(body.current_thread.text).entities)
        ml.nlu_classifier(body.current_thread.text).entities.name eq "request"
      any(ml.nlu_classifier(body.current_thread.text).entities)
        ml.nlu_classifier(body.current_thread.text).entities.name eq "urgency"
    any(ml.nlu_classifier(body.current_thread.text).intents)
      and
        ml.nlu_classifier(body.current_thread.text).intents.confidence in ["high", "medium"]
        ml.nlu_classifier(body.current_thread.text).intents.name eq "bec"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
    and
      not
        profile.by_sender func_call "profile.by_sender().solicited"
      profile.by_sender func_call "profile.by_sender().prevalence != common"
    profile.by_sender func_call "profile.by_sender().days_since.last_outbound > 365"
  not
    and
      headers.reply_to length_compare "0"
      sender.email.email eq "no-reply@sharepointonline.com"
       macro "all(headers.reply_to)"
  any($org_vips)
    $org_vips.display_name cross_field_compare "sender.display_name"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.reply_tolength_compare0excludes:headers.reply_to field:"headers.reply_to" value:"0"
sender.email.emaileqno-reply@sharepointonline.comexcludes:sender.email.email field:"sender.email.email" value:"no-reply@sharepointonline.com"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

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

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • headers.reply_to
  • sender.email
  • subject
  • type

Rule body

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

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(regex.extract(sender.display_name))
      any($org_vips)
        strings.contains func_call "strings.contains($org_vips[].display_name)"
    any($org_vips)
      strings.contains func_call "strings.contains(sender.display_name)"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       macro "sender.email.domain.domain in org_domains"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
  any(ml.nlu_classifier(body.current_thread.text).entities)
    ml.nlu_classifier(body.current_thread.text).entities.name eq "request"
  or
    strings.replace_confusables(subject.base) contains "W-2"
    subject.base contains "irs"
    subject.base contains "tax form"
    subject.base contains "w2"
    subject.base contains "wage"
  body.current_thread.text contains "W-2"
  headers.reply_to length_compare "0"
  type.inbound eq "true"
   macro "sender.email.email not in map(headers.reply_to, .email.email)"

Indicators

These rows show field, operator, and value matches.

X (Twitter) impersonation with credential phishing motives

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

This rule is designed to identify impersonation attempts by analyzing the display name or sender's local part for the solitary use of "X" provided the email doesn't originate from twitter.com or x.com. Natural Language Understanding (NLU) is used to check for credential theft requiring a medium-to-high confidence level for flagging.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • headers
  • headers.auth_summary
  • sender.email
  • type

Rule body

type.inbound
and sender.display_name =~ "x"
and sender.email.domain.root_domain not in ("twitter.com", "x.com")
and (
  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 != "low"
              )
      )
  )
  or any(ml.nlu_classifier(body.current_thread.text).intents,
         .name == "cred_theft" and .confidence != "low"
  )
)

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

  // salesforce has been abused for x/twitter phishing campaigns repeatedly 
  or sender.email.domain.root_domain == "salesforce.com"
)

Detection logic

Scope: inbound message.

This rule is designed to identify impersonation attempts by analyzing the display name or sender's local part for the solitary use of "X" provided the email doesn't originate from twitter.com or x.com. Natural Language Understanding (NLU) is used to check for credential theft requiring a medium-to-high confidence level for flagging.

  1. inbound message
  2. sender.display_name is 'x'
  3. sender.email.domain.root_domain not in ('twitter.com', 'x.com')
  4. any of:
    • 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 is not 'low'
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'cred_theft'
      • .confidence is not 'low'
  5. 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
    • sender.email.domain.root_domain is 'salesforce.com'

Inspects: attachments[].file_type, body.current_thread.text, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, ml.nlu_classifier. Reference lists: $file_types_images, $high_trust_sender_root_domains.

Indicators matched (4)

FieldMatchValue
sender.display_nameequalsx
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
sender.email.domain.root_domainequalssalesforce.com

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(attachments)
      and
        any(file.explode(attachments))
          any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).intents)
            and
              ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidence ne "low"
              ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].name eq "cred_theft"
         macro "attachments[].file_type in file_types_images"
    any(ml.nlu_classifier(body.current_thread.text).intents)
      and
        ml.nlu_classifier(body.current_thread.text).intents.confidence ne "low"
        ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
    sender.email.domain.root_domain eq "salesforce.com"
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    sender.email.domain.root_domain in ["twitter.com", "x.com"]
  sender.display_name eq "x"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.