Detection rules › Sublime MQL

Sublime MQL rules: cred

Link: Non-standard port 8443 in display URL

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

Detects links containing port 8443 in the display URL, which may indicate suspicious redirect or hosting infrastructure.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesEvasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
and (
  // no previous threads
  length(body.previous_threads) == 0
  // or is a fake thread
  or (
    (length(headers.references) == 0 or headers.in_reply_to is null)
    and (
      subject.is_reply
      or subject.is_forward
      or length(body.previous_threads) > 0
    )
  )
)
and any(body.links,
        strings.contains(.display_url.url, ':8443')
        and network.whois(.href_url.domain).days_old <= 365
)

// Negate noreply-spamdigest senders
and not (
  sender.email.email == "noreply-spamdigest@google.com"
  and headers.auth_summary.dmarc.pass
)

Detection logic

Scope: inbound message.

Detects links containing port 8443 in the display URL, which may indicate suspicious redirect or hosting infrastructure.

  1. inbound message
  2. any of:
    • length(body.previous_threads) is 0
    • all of:
      • any of:
        • length(headers.references) is 0
        • headers.in_reply_to is missing
      • any of:
        • subject.is_reply
        • subject.is_forward
        • length(body.previous_threads) > 0
  3. any of body.links where all hold:
    • .display_url.url contains ':8443'
    • network.whois(.href_url.domain).days_old ≤ 365
  4. not:
    • all of:
      • sender.email.email is 'noreply-spamdigest@google.com'
      • headers.auth_summary.dmarc.pass

Inspects: body.links, body.links[].display_url.url, body.links[].href_url.domain, body.previous_threads, headers.auth_summary.dmarc.pass, headers.in_reply_to, headers.references, sender.email.email, subject.is_forward, subject.is_reply, type.inbound. Sensors: network.whois, strings.contains.

Indicators matched (1)

FieldMatchValue
strings.containssubstring:8443

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      or
        body.previous_threads length_compare "0"
        subject.is_forward eq "true"
        subject.is_reply eq "true"
      or
        headers.in_reply_to is_null
        headers.references length_compare "0"
    body.previous_threads length_compare "0"
  any(body.links)
    and
      body.links.display_url.url contains ":8443"
      network.whois func_call "network.whois(body.links[].href_url.domain).days_old <= 365"
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.email eq "noreply-spamdigest@google.com"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

Suspicious invoice reference with missing or image-only attachments

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

This rule flags emails that reference invoices or payments but have suspicious characteristics: attachments are either missing or only images. It also checks for misleading links disguised as attachments and the presence of invoice-related keywords. The rule looks for potential credential theft or unusual requests, making it a strong indicator of phishing attempts.

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.current_thread
  • body.html
  • body.links
  • body.plain
  • headers
  • headers.auth_summary
  • sender.email
  • subject
  • type

Rule body

type.inbound

// more than 0 but less than 20 links
and 0 < length(body.links) < 20

// all attachments are images or there are 0 attachments
and (
  length(attachments) > 0 and all(attachments, .file_type in $file_types_images)
  or length(attachments) == 0
)

// subject contains payment/invoice language
and (
  any(ml.nlu_classifier(subject.subject).tags, .name in ("payment", "invoice"))
  or regex.contains(subject.subject,
                    '(?:\binv(?:oice|o)\b|in_v|in-voice|pay(?:ment|mnt)|pymt|\brec(?:eipt|pt|iept)\b|rcpt|confirm(?:ation)|cnfrm|cnf|po\b|p\.o\.|purch(?:ase)?-?order|\bord(?:er)?\b|bill(?:ing)|billing-info|transact(?:ion)|txn|trx|\bstmt\b|\bstmnt\b|remit(?:tance)|rmt|remndr|remind|\bdue(?:-date)\b|ovrdue|overdue|\bbal(?:ance)\b|\bpaid(?:-invoice)\b|requires\s+your\s+a(?:ttention|ction)|\b[fF]inal\s+(?:[nN]otice|[uU]npaid).{0,20}[iI]nvoice)',
                    // suspicious invoice format
                    '\d{6}\b.{10,30}(\d{2}\.){3}pdf'
  )
)

// link display text ends in a file extension or contain common payment terms
and (
  any(body.links,
      regex.imatch(.display_text,
                   '.*\.(?:doc|docm|docx|dot|dotm|pdf|ppa|ppam|ppsm|ppt|pptm|pptx|wbk|xla|xlam|xlm|xls|xlsb|xlsm|xlsx|xlt|xltm)$'
      )
  )
  or any(body.links,
         regex.icontains(.display_text,
                         '(?:\binv(?:oice|o)\b|in_v|in-voice|pay(?:ment|mnt)|pymt|\brec(?:eipt|pt|iept)\b|rcpt|req(?:uest)|rqst|\brq\b|\bpo\b|p\.o\.|purch(?:ase)?-?order|\bord(?:er)?\b|bill(?:ing)|billing-info|transact(?:ion)|txn|trx|\bstmt\b|\bstmnt\b|remit(?:tance)|rmt|remndr|remind|\bdue(?:-date)\b|ovrdue|overdue|\bbal(?:ance)\b|\bpaid(?:-invoice)\b|completed\s+doc(?:s|ument|uments)?\b)'
         )
  )
  or (
    any(body.links,
        regex.icontains(.display_text, '\bview\s+(invoice|attachment)')
    )
    and any([body.plain.raw, body.html.inner_text],
            any(ml.nlu_classifier(.).intents,
                .name == "cred_theft" and .confidence == "high"
            )
    )
  )
)

// the body references an attachment 
and (
  strings.contains(body.current_thread.text, "attach")
  // negate warning banners warning about the attachment(s)
  and (
    not (
      (
        regex.count(body.current_thread.text, "attach") == 1
        and regex.icontains(body.current_thread.text,
                            "(caution|warning).{0,30}attach"
        )
      )
      or ( // WeTransfer expiry warning notification
        sender.email.email == "noreply@wetransfer.com"
        and any(body.links,
                .display_text == "Don't send me these expiry reminders anymore"
        )
      )
    )
  )
)

// body text is determined to contain cred_theft language by nlu or contains a request with suspicious keywords
and (
  not (
    any(ml.nlu_classifier(body.current_thread.text).topics,
        .name in ("Shipping and Package", "Order Confirmations")
        and .confidence == "high"
    )
  )
  and (
    any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft"
    )
    or any(ml.nlu_classifier(body.current_thread.text).entities,
           .name == "request" and (strings.icontains(.text, "kindly"))
    )
  )
)
// 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

Detection logic

Scope: inbound message.

This rule flags emails that reference invoices or payments but have suspicious characteristics: attachments are either missing or only images. It also checks for misleading links disguised as attachments and the presence of invoice-related keywords. The rule looks for potential credential theft or unusual requests, making it a strong indicator of phishing attempts.

  1. inbound message
  2. all of:
    • length(body.links) > 0
    • length(body.links) < 20
  3. any of:
    • all of:
      • length(attachments) > 0
      • all of attachments where:
        • .file_type in $file_types_images
    • length(attachments) is 0
  4. any of:
    • any of ml.nlu_classifier(subject.subject).tags where:
      • .name in ('payment', 'invoice')
    • subject.subject matches any of 2 patterns
      • (?:\binv(?:oice|o)\b|in_v|in-voice|pay(?:ment|mnt)|pymt|\brec(?:eipt|pt|iept)\b|rcpt|confirm(?:ation)|cnfrm|cnf|po\b|p\.o\.|purch(?:ase)?-?order|\bord(?:er)?\b|bill(?:ing)|billing-info|transact(?:ion)|txn|trx|\bstmt\b|\bstmnt\b|remit(?:tance)|rmt|remndr|remind|\bdue(?:-date)\b|ovrdue|overdue|\bbal(?:ance)\b|\bpaid(?:-invoice)\b|requires\s+your\s+a(?:ttention|ction)|\b[fF]inal\s+(?:[nN]otice|[uU]npaid).{0,20}[iI]nvoice)
      • \d{6}\b.{10,30}(\d{2}\.){3}pdf
  5. any of:
    • any of body.links where:
      • .display_text matches '.*\\.(?:doc|docm|docx|dot|dotm|pdf|ppa|ppam|ppsm|ppt|pptm|pptx|wbk|xla|xlam|xlm|xls|xlsb|xlsm|xlsx|xlt|xltm)$'
    • any of body.links where:
      • .display_text matches '(?:\\binv(?:oice|o)\\b|in_v|in-voice|pay(?:ment|mnt)|pymt|\\brec(?:eipt|pt|iept)\\b|rcpt|req(?:uest)|rqst|\\brq\\b|\\bpo\\b|p\\.o\\.|purch(?:ase)?-?order|\\bord(?:er)?\\b|bill(?:ing)|billing-info|transact(?:ion)|txn|trx|\\bstmt\\b|\\bstmnt\\b|remit(?:tance)|rmt|remndr|remind|\\bdue(?:-date)\\b|ovrdue|overdue|\\bbal(?:ance)\\b|\\bpaid(?:-invoice)\\b|completed\\s+doc(?:s|ument|uments)?\\b)'
    • all of:
      • any of body.links where:
        • .display_text matches '\\bview\\s+(invoice|attachment)'
      • any of [body.plain.raw, body.html.inner_text] where:
        • any of ml.nlu_classifier(.).intents where all hold:
          • .name is 'cred_theft'
          • .confidence is 'high'
  6. all of:
    • body.current_thread.text contains 'attach'
    • none of:
      • all of:
        • regex.count(body.current_thread.text, 'attach') is 1
        • body.current_thread.text matches '(caution|warning).{0,30}attach'
      • all of:
        • sender.email.email is 'noreply@wetransfer.com'
        • any of body.links where:
          • .display_text is "Don't send me these expiry reminders anymore"
  7. all of:
    • not:
      • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
        • .name in ('Shipping and Package', 'Order Confirmations')
        • .confidence is 'high'
    • any 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 all hold:
        • .name is 'request'
        • .text contains 'kindly'
  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:
    • profile.by_sender().solicited

Inspects: attachments[].file_type, body.current_thread.text, body.html.inner_text, body.links, body.links[].display_text, body.plain.raw, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, sender.email.email, subject.subject, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender, regex.contains, regex.count, regex.icontains, regex.imatch, strings.contains, strings.icontains. Reference lists: $file_types_images, $high_trust_sender_root_domains.

Indicators matched (13)

FieldMatchValue
ml.nlu_classifier(subject.subject).tags[].namememberpayment
ml.nlu_classifier(subject.subject).tags[].namememberinvoice
regex.containsregex(?:\binv(?:oice|o)\b|in_v|in-voice|pay(?:ment|mnt)|pymt|\brec(?:eipt|pt|iept)\b|rcpt|confirm(?:ation)|cnfrm|cnf|po\b|p\.o\.|purch(?:ase)?-?order|\bord(?:er)?\b|bill(?:ing)|billing-info|transact(?:ion)|txn|trx|\bstmt\b|\bstmnt\b|remit(?:tance)|rmt|remndr|remind|\bdue(?:-date)\b|ovrdue|overdue|\bbal(?:ance)\b|\bpaid(?:-invoice)\b|requires\s+your\s+a(?:ttention|ction)|\b[fF]inal\s+(?:[nN]otice|[uU]npaid).{0,20}[iI]nvoice)
regex.containsregex\d{6}\b.{10,30}(\d{2}\.){3}pdf
regex.imatchregex.*\.(?:doc|docm|docx|dot|dotm|pdf|ppa|ppam|ppsm|ppt|pptm|pptx|wbk|xla|xlam|xlm|xls|xlsb|xlsm|xlsx|xlt|xltm)$
regex.icontainsregex(?:\binv(?:oice|o)\b|in_v|in-voice|pay(?:ment|mnt)|pymt|\brec(?:eipt|pt|iept)\b|rcpt|req(?:uest)|rqst|\brq\b|\bpo\b|p\.o\.|purch(?:ase)?-?order|\bord(?:er)?\b|bill(?:ing)|billing-info|transact(?:ion)|txn|trx|\bstmt\b|\bstmnt\b|remit(?:tance)|rmt|remndr|remind|\bdue(?:-date)\b|ovrdue|overdue|\bbal(?:ance)\b|\bpaid(?:-invoice)\b|completed\s+doc(?:s|ument|uments)?\b)
regex.icontainsregex\bview\s+(invoice|attachment)
ml.nlu_classifier([body.plain.raw, body.html.inner_text][]).intents[].nameequalscred_theft
ml.nlu_classifier([body.plain.raw, body.html.inner_text][]).intents[].confidenceequalshigh
strings.containssubstringattach
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsrequest
1 more
strings.icontainssubstringkindly

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      any([body.plain.raw, body.html.inner_text])
        any(ml.nlu_classifier([body.plain.raw, body.html.inner_text]).intents)
          and
            ml.nlu_classifier([body.plain.raw, body.html.inner_text][]).intents[].confidence eq "high"
            ml.nlu_classifier([body.plain.raw, body.html.inner_text][]).intents[].name eq "cred_theft"
      any(body.links)
        body.links.display_text regex_match "\\bview\\s+(invoice|attachment)"
    any(body.links)
      body.links.display_text regex_match "(?:\\binv(?:oice|o)\\b|in_v|in-voice|pay(?:ment|mnt)|pymt|\\brec(?:eipt|pt|iept)\\b|rcpt|req(?:uest)|rqst|\\brq\\b|\\bpo\\b|p\\.o\\.|purch(?:ase)?-?order|\\bord(?:er)?\\b|bill(?:ing)|billing-info|transact(?:ion)|txn|trx|\\bstmt\\b|\\bstmnt\\b|remit(?:tance)|rmt|remndr|remind|\\bdue(?:-date)\\b|ovrdue|overdue|\\bbal(?:ance)\\b|\\bpaid(?:-invoice)\\b|completed\\s+doc(?:s|ument|uments)?\\b)"
    any(body.links)
      body.links.display_text regex_match ".*\\.(?:doc|docm|docx|dot|dotm|pdf|ppa|ppam|ppsm|ppt|pptm|pptx|wbk|xla|xlam|xlm|xls|xlsb|xlsm|xlsx|xlt|xltm)$"
  not
    or
      and
        any(body.links)
          body.links.display_text eq "Don't send me these expiry reminders anymore"
        sender.email.email eq "noreply@wetransfer.com"
      and
        body.current_thread.text regex_match "(caution|warning).{0,30}attach"
        regex.count func_call "regex.count(body.current_thread.text, \"attach\") == 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
    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 "kindly"
    any(ml.nlu_classifier(body.current_thread.text).intents)
      ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
  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 ["Order Confirmations", "Shipping and Package"]
  or
    and
      attachments length_compare "0"
       macro "all(attachments)"
    attachments length_compare "0"
  or
    any(ml.nlu_classifier(subject.subject).tags)
      ml.nlu_classifier(subject.subject).tags.name in ["invoice", "payment"]
    subject.subject regex_match "(?:\\binv(?:oice|o)\\b|in_v|in-voice|pay(?:ment|mnt)|pymt|\\brec(?:eipt|pt|iept)\\b|rcpt|confirm(?:ation)|cnfrm|cnf|po\\b|p\\.o\\.|purch(?:ase)?-?order|\\bord(?:er)?\\b|bill(?:ing)|billing-info|transact(?:ion)|txn|trx|\\bstmt\\b|\\bstmnt\\b|remit(?:tance)|rmt|remndr|remind|\\bdue(?:-date)\\b|ovrdue|overdue|\\bbal(?:ance)\\b|\\bpaid(?:-invoice)\\b|requires\\s+your\\s+a(?:ttention|ction)|\\b[fF]inal\\s+(?:[nN]otice|[uU]npaid).{0,20}[iI]nvoice)"
    subject.subject regex_match "\\d{6}\\b.{10,30}(\\d{2}\\.){3}pdf"
  not
    profile.by_sender func_call "profile.by_sender().solicited"
  body.current_thread.text contains "attach"
  body.links length_compare "0"
  body.links length_compare "20"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
body.linksarray_any(no value, null check)excludes:body.links
sender.email.emaileqnoreply@wetransfer.comexcludes:sender.email.email field:"sender.email.email" value:"noreply@wetransfer.com"
body.current_thread.textregex_match(caution|warning).{0,30}attachexcludes:body.current_thread.text field:"body.current_thread.text" value:"(caution|warning).{0,30}attach"
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.

FieldKindValuesSearch
body.current_thread.textcontains
  • attach
field:"body.current_thread.text" kind:contains value:"attach"
subject.subjectregex_match
  • (?:\binv(?:oice|o)\b|in_v|in-voice|pay(?:ment|mnt)|pymt|\brec(?:eipt|pt|iept)\b|rcpt|confirm(?:ation)|cnfrm|cnf|po\b|p.o.|purch(?:ase)?-?order|\bord(?:er)?\b|bill(?:ing)|billing-info|transact(?:ion)|txn|trx|\bstmt\b|\bstmnt\b|remit(?:tance)|rmt|remndr|remind|\bdue(?:-date)\b|ovrdue|overdue|\bbal(?:ance)\b|\bpaid(?:-invoice)\b|requires\s+your\s+a(?:ttention|ction)|\b[fF]inal\s+(?:[nN]otice|[uU]npaid).{0,20}[iI]nvoice)
  • \d{6}\b.{10,30}(\d{2}.){3}pdf
field:"subject.subject" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"