Detection rules › Sublime MQL

Cloud storage impersonation with credential theft indicators

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

Detects messages impersonating cloud storage services that contain hyperlinked images leading to free file hosts, where message screenshots reveal high-confidence credential theft language and storage-related urgency tactics.

Threat classification

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

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

Event coverage

Rule body MQL

type.inbound
and 0 < length(body.current_thread.links) < 10
and any([subject.subject, sender.display_name],
        regex.icontains(., "(?:cloud|storage|mailbox|account|system|service)")
)
and any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents,
        .name == "cred_theft" and .confidence == "high"
)
and not any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).topics,
            .name == "Customer Service and Support" and .confidence == "high"
)
and regex.icontains(beta.ocr(file.message_screenshot()).text,
                    "storage.{0,50}full",
                    "free.{0,50}upgrade",
                    "storage.{0,50}details",
                    "storage.{0,50}quot",
                    "(?:mailbox|account|cloud).{0,50}(?:at risk|storage|disabled)"
)
and not strings.ilike(beta.ocr(file.message_screenshot()).text, "*free plan*")
and (
  any(body.current_thread.links,
      // fingerprints of a hyperlinked image
      .display_text is null
      and .display_url.url is null
      and .href_url.domain.domain not in $tenant_domains
      and (
        .href_url.domain.root_domain in $free_file_hosts
        or .href_url.domain.root_domain in $url_shorteners
        or network.whois(.href_url.domain).days_old < 365
        or .href_url.domain.root_domain == "beehiiv.com"
        or regex.icontains(.href_url.path, '^\/[a-z0-9]{20,}$')
        or (
          strings.icontains(.href_url.path, '.html')
          and coalesce(.href_url.domain.root_domain, "null") != coalesce(sender.email.domain.root_domain,
                                                                         ""
          )
        )
      )
  )
)
// 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 cloud storage services that contain hyperlinked images leading to free file hosts, where message screenshots reveal high-confidence credential theft language and storage-related urgency tactics.

  1. inbound message
  2. all of:
    • length(body.current_thread.links) > 0
    • length(body.current_thread.links) < 10
  3. any of [subject.subject, sender.display_name] where:
    • . matches '(?:cloud|storage|mailbox|account|system|service)'
  4. any of ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents where all hold:
    • .name is 'cred_theft'
    • .confidence is 'high'
  5. not:
    • any of ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).topics where all hold:
      • .name is 'Customer Service and Support'
      • .confidence is 'high'
  6. beta.ocr(file.message_screenshot()).text matches any of 5 patterns
    • storage.{0,50}full
    • free.{0,50}upgrade
    • storage.{0,50}details
    • storage.{0,50}quot
    • (?:mailbox|account|cloud).{0,50}(?:at risk|storage|disabled)
  7. not:
    • beta.ocr(file.message_screenshot()).text matches '*free plan*'
  8. any of body.current_thread.links where all hold:
    • .display_text is missing
    • .display_url.url is missing
    • .href_url.domain.domain not in $tenant_domains
    • any of:
      • .href_url.domain.root_domain in $free_file_hosts
      • .href_url.domain.root_domain in $url_shorteners
      • network.whois(.href_url.domain).days_old < 365
      • .href_url.domain.root_domain is 'beehiiv.com'
      • .href_url.path matches '^\\/[a-z0-9]{20,}$'
      • all of:
        • .href_url.path contains '.html'
        • coalesce(.href_url.domain.root_domain, 'null') is not coalesce(sender.email.domain.root_domain, '')
  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.links, body.current_thread.links[].display_text, body.current_thread.links[].display_url.url, body.current_thread.links[].href_url.domain, body.current_thread.links[].href_url.domain.domain, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.links[].href_url.path, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: beta.ocr, file.message_screenshot, ml.nlu_classifier, network.whois, regex.icontains, strings.icontains, strings.ilike. Reference lists: $free_file_hosts, $high_trust_sender_root_domains, $tenant_domains, $url_shorteners.

Indicators matched (14)

FieldMatchValue
regex.icontainsregex(?:cloud|storage|mailbox|account|system|service)
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(beta.ocr(file.message_screenshot()).text).topics[].nameequalsCustomer Service and Support
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).topics[].confidenceequalshigh
regex.icontainsregexstorage.{0,50}full
regex.icontainsregexfree.{0,50}upgrade
regex.icontainsregexstorage.{0,50}details
regex.icontainsregexstorage.{0,50}quot
regex.icontainsregex(?:mailbox|account|cloud).{0,50}(?:at risk|storage|disabled)
strings.ilikesubstring*free plan*
body.current_thread.links[].href_url.domain.root_domainequalsbeehiiv.com
2 more
regex.icontainsregex^\/[a-z0-9]{20,}$
strings.icontainssubstring.html