Detection rules › Sublime MQL

Link: PDF and financial display text to free file host

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

Detects messages containing a single link with PDF-named display text containing financial phrases that redirects to a free file hosting service, sent without previous message threads.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesFree file host, Free email provider, Social engineering

Event coverage

Rule body MQL

type.inbound
and length(body.links) < 20

// the message does not contain previous threads
and length(body.previous_threads) == 0

// no PDF attachments
and length(filter(attachments, .file_type == "pdf")) == 0
// there is only a single link to the free file host
and length(filter(body.links,
                  .href_url.domain.domain in $free_file_hosts
                  or .href_url.domain.root_domain in $free_file_hosts
                  or .href_url.domain.domain in $self_service_creation_platform_domains
                  or .href_url.domain.root_domain in $self_service_creation_platform_domains
                  or .href_url.domain.domain in $url_shorteners
                  or .href_url.domain.root_domain in $url_shorteners
                  or .href_url.domain.root_domain == "dynamics.com"
           )
) == 1
// there are few distinct domains in the message
and length(distinct(body.links, .href_url.domain.root_domain)) <= 3

// the display_text ends in .pdf and goes to a free file host
and any(body.links,
        strings.iends_with(.display_text, '.pdf')
        and (
          .href_url.domain.domain in $free_file_hosts
          or .href_url.domain.root_domain in $free_file_hosts
          or .href_url.domain.domain in $self_service_creation_platform_domains
          or .href_url.domain.root_domain in $self_service_creation_platform_domains
          or .href_url.domain.domain in $url_shorteners
          or .href_url.domain.root_domain in $url_shorteners
          or .href_url.domain.root_domain == "dynamics.com"
        )
        // the display text is financial related (remittance, invoice, etc)
        and (
          strings.icontains(.display_text, 'payment')
          or regex.icontains(.display_text, 'pay\b')
          or strings.icontains(.display_text, 'remit')
          or strings.icontains(.display_text, 'receipt')
          or strings.icontains(.display_text, 'Distribution')
          or strings.icontains(.display_text, 'payoff')
          or strings.icontains(.display_text, 'Wire Instructions')
          or regex.icontains(.display_text, 'ACH\b')
          or regex.icontains(.display_text, 'EFT\b')
          or strings.istarts_with(.display_text, 'INV')
          or strings.istarts_with(.display_text, 'View RFQ')
          or strings.istarts_with(.display_text, 'Contract')

          // the display text is the subject
          or (.display_text =~ subject.base and length(.display_text) > 0)
        )

        // negate links which make use of google icons inside of a bounding box
        // filter down to the link with the same display text
        and not any(filter(html.xpath(body.html,
                                      '//a[img[@src] or .//img[@src]][.//div[contains(@style, "border:1px solid")] or ancestor::div[contains(@style, "border:1px solid")]]'
                           ).nodes,
                           // the display text is the link we're inspecting
                           ..display_text == .display_text
                    ),
                    // inside this is a reference to the google icon 
                    strings.icontains(.raw, 'gstatic.com/docs/doclist/images/')
        )
)

Detection logic

Scope: inbound message.

Detects messages containing a single link with PDF-named display text containing financial phrases that redirects to a free file hosting service, sent without previous message threads.

  1. inbound message
  2. length(body.links) < 20
  3. length(body.previous_threads) is 0
  4. length(filter(attachments, .file_type == 'pdf')) is 0
  5. length(filter(body.links, .href_url.domain.domain in $free_file_hosts or .href_url.domain.root_domain in $free_file_hosts or .href_url.domain.domain in $self_service_creation_platform_domains or .href_url.domain.root_domain in $self_service_creation_platform_domains or .href_url.domain.domain in $url_shorteners or .href_url.domain.root_domain in $url_shorteners or .href_url.domain.root_domain == 'dynamics.com')) is 1
  6. length(distinct(body.links, .href_url.domain.root_domain)) ≤ 3
  7. any of body.links where all hold:
    • .display_text ends with '.pdf'
    • any of:
      • .href_url.domain.domain in $free_file_hosts
      • .href_url.domain.root_domain in $free_file_hosts
      • .href_url.domain.domain in $self_service_creation_platform_domains
      • .href_url.domain.root_domain in $self_service_creation_platform_domains
      • .href_url.domain.domain in $url_shorteners
      • .href_url.domain.root_domain in $url_shorteners
      • .href_url.domain.root_domain is 'dynamics.com'
    • any of:
      • .display_text contains 'payment'
      • .display_text matches 'pay\\b'
      • .display_text contains 'remit'
      • .display_text contains 'receipt'
      • .display_text contains 'Distribution'
      • .display_text contains 'payoff'
      • .display_text contains 'Wire Instructions'
      • .display_text matches 'ACH\\b'
      • .display_text matches 'EFT\\b'
      • .display_text starts with 'INV'
      • .display_text starts with 'View RFQ'
      • .display_text starts with 'Contract'
      • all of:
        • .display_text is subject.base
        • length(.display_text) > 0
    • not:
      • any of filter(...) where:
        • .raw contains 'gstatic.com/docs/doclist/images/'

Inspects: attachments[].file_type, body.html, body.links, body.links[].display_text, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.previous_threads, subject.base, type.inbound. Sensors: html.xpath, regex.icontains, strings.icontains, strings.iends_with, strings.istarts_with. Reference lists: $free_file_hosts, $self_service_creation_platform_domains, $url_shorteners.

Indicators matched (16)

FieldMatchValue
attachments[].file_typeequalspdf
body.links[].href_url.domain.root_domainequalsdynamics.com
strings.iends_withsuffix.pdf
strings.icontainssubstringpayment
regex.icontainsregexpay\b
strings.icontainssubstringremit
strings.icontainssubstringreceipt
strings.icontainssubstringDistribution
strings.icontainssubstringpayoff
strings.icontainssubstringWire Instructions
regex.icontainsregexACH\b
regex.icontainsregexEFT\b
4 more
strings.istarts_withprefixINV
strings.istarts_withprefixView RFQ
strings.istarts_withprefixContract
strings.icontainssubstringgstatic.com/docs/doclist/images/