Detection rules › Sublime MQL

Sublime MQL rules: link

RuleSeverity
Brand impersonation: Cloud services with credential theft intentmedium
Brand impersonation: Coinbase with suspicious linksmedium
Brand impersonation: Discord notificationmedium
Brand impersonation: Fake Faxmedium
Brand impersonation: Google fake sign-in warninghigh
Brand impersonation: Microsoft with low reputation linksmedium
Catbox.moe link from untrusted sourcemedium
Commonly abused sender TLD with engaging languagemedium
Credential phishing content and link (untrusted sender)high
Credential phishing language and suspicious indicators (unknown sender)medium
Credential phishing link (unknown sender)high
Credential phishing: 'Secure message' and engaging languagemedium
Credential phishing: Engaging language and other indicators (untrusted sender)medium
Credential phishing: Engaging language with IPFS linkhigh
Credential phishing: Fake password expiration from new and unsolicited sendermedium
Credential phishing: Fake storage alerts (unsolicited)medium
Credential Phishing: Suspicious language, link, recipients and other indicatorsmedium
Credential Phishing: W-2 lure with inline SVG Windows logohigh
Cyrillic vowel substitution in subject or display name from unknown sendermedium
Cyrillic vowel substitutions with suspicious subject from unknown sendermedium
Fake message thread with a suspicious link and engaging language from an unknown sendermedium
Fake voicemail notification (untrusted sender)medium
Fake Zoom meeting invite with suspicious linkmedium
Free subdomain link with login or captcha (untrusted sender)medium
Google Accelerated Mobile Pages (AMP) abusemedium
Google Drive direct download link from unsolicited sendermedium
Google Notification alert link from non-Google sendermedium
Google presentation open redirect phishingmedium
Google share notification with suspicious commentshigh
Link abuse: Self-service creation platform link with suspicious recipient behaviorhigh
Link to a domain with punycode charactersmedium
Link to auto-download of a suspicious file type (unsolicited)medium
Link to auto-downloaded disk image in encrypted zipmedium
Link to auto-downloaded DMG in archivemedium
Link to auto-downloaded DMG in encrypted ziphigh
Link to auto-downloaded file with Adobe brandinghigh
Link to auto-downloaded file with Google Drive brandinghigh
Link to Google Apps Script macro (unsolicited)medium
Link to Google Apps Script macro via comment taggingmedium
Link: .onion From Unsolicited Senderlow
Link: .su domain link redirection from new sender domainshigh
Link: /index.php enclosed in three asterisksmedium
Link: 9WOLF phishkit initial landing URIhigh
Link: Abused Adobe Expresshigh
Link: Adobe share from unsolicited sendermedium
Link: Adobe share with suspicious indicatorshigh
Link: Apple App Store link to apps impersonating AI adveristinghigh
Link: Apple App Store malicious ad manager themed apps from free email providermedium
Link: Apple TestFlight from suspicious sendermedium
Link: Base64 encoded recipient address in URL fragment with hex subdomainhigh
Link: Base64 encoded recipient address in URL fragment with subject hashlow
Link: BEC with newly registered domains and financial keywordsmedium
Link: Blogspot hosting explicit romance contentmedium
Link: chatbot.page platform abusemedium
Link: Common hidden directory observedmedium
Link: Commonly Abused Web Service redirecting to ZIP filemedium
Link: Compromised WordPress site redirecting to suspicious root domainhigh
Link: Concatenated display text concealing duplicate URLs with PDF referencemedium
Link: Credential phishing link with undisclosed recipientsmedium
Link: Credential phishing traversing Russian infrastructurehigh
Link: Credential phishing via WordPresshigh
Link: Credential theft with Cloudflare tunnel and recipient targetinghigh
Link: Credential theft with invisible Unicode character in page title from unsolicited senderhigh
Link: Cryptocurrency fraud with suspicious linkshigh
Link: CVE-2024-21413 Microsoft Outlook Remote Code Execution Vulnerabilitycritical
Link: Direct download of executable filelow
Link: Direct link to Dropbox Paper filelow
Link: Direct link to gamma.app document with mode parametermedium
Link: Direct link to keap.app contact-us pagemedium
Link: Direct link to limewire hosted filehigh
Link: Direct link to riddle.com hosted showcasemedium
Link: Direct link to Zoom Docs from non-Zoom sendermedium
Link: Direct MSI download from low reputation domainlow
Link: Direct POWR.io Form Builder with suspicious patternsmedium
Link: Display text matches subject linemedium
Link: Display text with excessive right-to-left mark characterslow
Link: Document sharing invitation templatehigh
Link: Document-themed link to newly registered domainmedium
Link: Excessive URL rewrite encodershigh
Link: Executable file download with suspicious message contenthigh
Link: Fake forwarded message with suspicious URL in plain textmedium
Link: Fake secure message notification templatemedium
Link: Figma design deck with credential theft languagemedium
Link: File sharing impersonation with suspicious language and sending patternsmedium
Link: File sharing pretext with suspicious body and linkmedium
Link: Financial account issue with suspicious indicatorsmedium
Link: Flagged bit.ly linkmedium
Link: Flare-branded credential harvesting via Cloudflare tunnelshigh
Link: Fraudulent state business filing noticemedium
Link: Free file host links from suspicious support sender with credential theft languagemedium
Link: Free file hosting with undisclosed recipientsmedium
Link: Generic financial document with proceedural timeline templatemedium
Link: Google Calendar invite linking to an open redirect from an untrusted freemail senderhigh
Link: Google Cloud Storage hosted credential harvesting pagehigh
Link: Google Cloud Storage impersonating with googledrive in URL pathhigh
Link: Google Cloud Storage link with index.php in URLhigh
Link: Google Cloud Storage link with redirect.html in URLhigh
Link: Google Cloud Storage redirect to external domainmedium
Link: Google Cloud Storage with short-path link deliverymedium
Link: Google Cloud Storage with suspicious URL patternhigh
Link: Google Drawings link from new sendermedium
Link: Google Firebase dynamic link that redirects to new domain (<7 days old)low
Link: Google Forms link with credential theft languagemedium
Link: Google Translate (unsolicited)low
Link: GoPhish query param valueslow
Link: Hotel booking spoofed display URLmedium
Link: HR impersonation with suspicious domain indicators and credential thefthigh
Link: HTML file with suspicious binary fragment ending patternhigh
Link: Invalid reply-to with recipient details in subject, body, and encoded linkmedium
Link: Invoice or receipt from freemail sender with customer service numberlow
Link: IPFSmedium
Link: IPv4-mapped IPv6 address obfuscationmedium
Link: JavaScript obfuscation with Telegram bot integrationhigh
Link: Jensi file preview link from unsolicited sendermedium
Link: Job recruitment lure from unsolicited sender with suspicious hostingmedium
Link: Landing page with search-ms protocol redirecthigh
Link: Mamba 2FA phishing kithigh
Link: Microsoft device code authentication with suspicious indicatorshigh
Link: Microsoft Dynamics 365 form phishinghigh
Link: Microsoft impersonation using hosted png with suspicious linkmedium
Link: Microsoft protected message with matching sender and recipient addressesmedium
Link: Mismatched free file host links with document luremedium
Link: Multiple HTTP protocols in single URLmedium
Link: Multistage landing - Abused Adobe Acrobat hosted PDFmedium
Link: Multistage landing - Abused Adobe frame.iohigh
Link: Multistage Landing - Abused Buildin.aimedium
Link: Multistage landing - Abused Docusignhigh
Link: Multistage landing - Abused Google Drivehigh
Link: Multistage landing - ClickUp abusehigh
Link: Multistage landing - FreshDesk knowledge base abusehigh
Link: Multistage landing - JotForm abusehigh
Link: Multistage landing - Ludus presentationmedium
Link: Multistage landing - Microsoft Forms abusehigh
Link: Multistage landing - Published Google Dochigh
Link: Multistage landing - Scribd documentmedium
Link: Multistage landing - Trello board abusehigh
Link: MyActiveCampaign Link Abusemedium
Link: Numeric IP obfuscation in URLmedium
Link: Obfuscation via userinfo with excessive URL paddingmedium
Link: Obfuscation via userinfo with suspicious indicatorslow
Link: Observed malicious URL path /redirect/redirect/high
Link: Observed URL pattern with specific domain registrarhigh
Link: PDF and financial display text to free file hosthigh
Link: PDF display text with fake copyright claim templatemedium
Link: PDF file disguised as HTML pagemedium
Link: PDF filename impersonation with credential theft languagemedium
Link: Personal SharePoint with invalid recipients and credential theft languagemedium
Link: Personalized URL with recipient address on commonly abused web servicemedium
Link: QR code in EML attachment with credential phishing indicatorshigh
Link: QR code with phishing disposition in img or pdfhigh
Link: QR Code with suspicious language (untrusted sender)medium
Link: QuickBooks image lure with suspicious linkmedium
Link: Recipient domain in URL pathhigh
Link: Recipient email address in 'eta' parameterhigh
Link: Referrer anonymization service from untrusted sendermedium
Link: Remittance payment request with timeline templatemedium
Link: RFI document reference pattern in display textmedium
Link: Romance/Sexual Language With Suspicious Linklow
Link: ScreenConnect installer with suspicious relay domainhigh
Link: ScreenConnect remote access tool delivery with unattended guest accesshigh
Link: Scribd fullscreen link from suspicious sendermedium
Link: Secure SharePoint file share from new or unusual senderlow
Link: Self-sender credential theft with configuration placeholderhigh
Link: Self-sender with IP geolocation check and suspicious link behaviormedium
Link: Self-sender with sender org in subject and credential theft indicatorhigh
Link: Self-sent message with quarterly document review requestcritical
Link: SharePoint filename matches org namemedium
Link: SharePoint files shared from GoDaddy federated tenantslow
Link: SharePoint OneNote or PDF link with self sender behaviormedium
Link: Shortened URL with fragment matching subjectmedium
Link: Squarespace infrastructure abusemedium
Link: Suspicious Family fragment parameter with encoded recipient datahigh
Link: Suspicious file retrieval with recipient targetinghigh
Link: Suspicious go.php redirect with document luremedium
Link: Suspicious HTML structure with subject mirrored in body and single linkmedium
Link: Suspicious Loom HTML file pathmedium
Link: Suspicious recipient with timeout redirectmedium
Link: Suspicious SharePoint document namelow
Link: Suspicious Sharepoint folder sharehigh
Link: Suspicious single-domain link with suspicious path and financial lure indicatorsmedium
Link: Suspicious URL path with binary character sequencemedium
Link: Suspicious URL with recipient targeting and special charactershigh
Link: Suspicious wp-admin path from mismatched sender domainmedium
Link: SVG with embedded recipient datahigh
Link: Tax document lure Portuguese/Spanish with suspicious domainsmedium
Link: Tycoon2FA phishing kit (non-exhaustive)high
Link: Uncommon SharePoint document type with sender's display namemedium
Link: Unformatted template with literal placeholder in mailto linkmedium
Link: Unicode character obfuscation in display name with base64-encoded URL fragmentmedium
Link: Unsolicited email contains link leading to Tycoon URL structurehigh
Link: Unsolicited email contains link to page containing Tycoon URI structurehigh
Link: URL fragment with hexadecimal pattern obfuscationhigh
Link: URL fragmented by hidden spanshigh
Link: URL path containing /moni/indexhigh
Link: URL redirecting to blob URLmedium
Link: URL scheme obfuscation via split HTML anchorshigh
Link: URL shortener chaining to workers.dev redirectmedium
Link: URL shortener with copy-paste instructions and credential theft languagelow
Link: URL using underscore-dot substitution in display textmedium
Link: Webflow link from unsolicited sendermedium
Link: WordPress admin targeting with recipient identifier in URL partshigh
Link: Zoho form link from unsolicited sendermedium
Low reputation link to auto-downloaded HTML file with smuggling indicatorshigh
Malware: Pikabot delivery via URL auto-downloadhigh
Microsoft device code phishingmedium
New link domain (<=10d) from untrusted sendermedium
Notion suspicious file sharemedium
Open redirect (go2.aspx) leading to Microsoft credential phishingmedium
Open Redirect: Google domain with /url path and suspicious indicatorsmedium
Open redirect: Google Web Lightmedium
Outlook hyperlink bypass: left-to-right mark (LRM) in base HTML tagmedium
Service abuse: Dropbox Paper with copy-paste instructionsmedium
Service abuse: Google Tag Manager debug cookie clearing with open redirect potentialhigh
Sharepoint online with external recipients and external display namemedium
Suspicious link to Looker Studio (lookerstudio.google.com) from a new and unsolicited sendermedium
Suspicious Links to Cloudflare R2 and Edge Servicesmedium
Suspicious message with unscannable Cloudflare linkmedium
Suspicious message with unscannable Vercel linkmedium
Suspicious Office 365 app authorization (OAuth) linkhigh

Brand impersonation: Cloud services with credential theft intent

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

Detects messages impersonating cloud services that contain high-confidence credential theft language and file sharing topics. The message starts with 'Cloud' or a cloud emoji or Cloud+ text, contains links to external domains not matching the sender's domain, and lacks recipient identification entities.

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

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

Rule body

type.inbound
and (
  any([body.current_thread.text, body.html.inner_text],
      strings.starts_with(., 'Cloud')
      or strings.icontains(., "Cloud+ ")
      or regex.icontains(., '^\x{FEFF}\s*Cloud')
  )
  // cloud emoji
  or regex.contains(body.current_thread.text, '^\x{2601}')
  or regex.icontains(body.current_thread.text, '^!\s*cloud storage')
  // address in the body
  or strings.icontains(body.current_thread.text,
                       '4563 Cloud Way, Server City, CA'
  )
  or any(html.xpath(body.html, '//img/@alt').nodes,
         regex.icontains(.raw, '^cloud (?:logo|storage)')
  )
  or regex.icontains(body.current_thread.text, 'cloud id:\s*#\d+')
  // body with cloud storage usage "percentage %"
  or (
    regex.icontains(body.current_thread.text,
                    '\bi?cloud\s(?:capacity|storage)\b'
    )
    and regex.icontains(body.current_thread.text, '\(?[0-9]{3}%\)?\s+?\b')
  )
)
and 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 (
          'File Sharing and Cloud Services',
          'Payment Information',
          'Financial Communications'
        )
        and .confidence != 'low'
)
// sender domain matches no body domains
and length(filter(body.links,
                  .href_url.scheme != 'mailto'
                  and .href_url.domain.root_domain is not null
                  and .href_url.domain.root_domain != 'oracle.com'
           )
) > 0
and all(filter(body.links,
               .href_url.scheme != 'mailto'
               and .href_url.domain.root_domain is not null
        ),
        .href_url.domain.root_domain != coalesce(sender.email.domain.root_domain,
                                                 ""
        )
)
// negate legit cloud companies
and not (
  coalesce(sender.email.domain.root_domain, "") in (
    "cloud-cme.com",
    "cloudcounting.online",
    "cloudhealthtech.com",
    "cloudpano.com"
  )
  // check for SPF or DMARC passed
  and (headers.auth_summary.spf.pass or headers.auth_summary.dmarc.pass)
)
// 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)
)
// negate Spark Cloud Attachments
and not any(headers.hops,
            .index == 0
            and any(.fields,
                    .name == "X-Readdle-Spark-Cloud-Attachment"
                    and .value is not null
            )
)
and not (
  sender.email.email == "noreply@icloud.com.cn"
  and coalesce(headers.auth_summary.dmarc.pass, false)
)

Detection logic

Scope: inbound message.

Detects messages impersonating cloud services that contain high-confidence credential theft language and file sharing topics. The message starts with 'Cloud' or a cloud emoji or Cloud+ text, contains links to external domains not matching the sender's domain, and lacks recipient identification entities.

  1. inbound message
  2. any of:
    • any of [body.current_thread.text, body.html.inner_text] where any holds:
      • . starts with 'Cloud'
      • . contains 'Cloud+ '
      • . matches '^\\x{FEFF}\\s*Cloud'
    • body.current_thread.text matches '^\\x{2601}'
    • body.current_thread.text matches '^!\\s*cloud storage'
    • body.current_thread.text contains '4563 Cloud Way, Server City, CA'
    • any of html.xpath(body.html, '//img/@alt').nodes where:
      • .raw matches '^cloud (?:logo|storage)'
    • body.current_thread.text matches 'cloud id:\\s*#\\d+'
    • all of:
      • body.current_thread.text matches '\\bi?cloud\\s(?:capacity|storage)\\b'
      • body.current_thread.text matches '\\(?[0-9]{3}%\\)?\\s+?\\b'
  3. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name is 'cred_theft'
    • .confidence is 'high'
  4. any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
    • .name in ('File Sharing and Cloud Services', 'Payment Information', 'Financial Communications')
    • .confidence is not 'low'
  5. length(filter(body.links, .href_url.scheme != 'mailto' and .href_url.domain.root_domain is not null and .href_url.domain.root_domain != 'oracle.com')) > 0
  6. all of filter(body.links) where:
    • .href_url.domain.root_domain is not coalesce(sender.email.domain.root_domain, '')
  7. not:
    • all of:
      • coalesce(sender.email.domain.root_domain, '') in ('cloud-cme.com', 'cloudcounting.online', 'cloudhealthtech.com', 'cloudpano.com')
      • any of:
        • headers.auth_summary.spf.pass
        • headers.auth_summary.dmarc.pass
  8. not:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • coalesce(headers.auth_summary.dmarc.pass)
  9. not:
    • any of headers.hops where all hold:
      • .index is 0
      • any of .fields where all hold:
        • .name is 'X-Readdle-Spark-Cloud-Attachment'
        • .value is set
  10. not:
    • all of:
      • sender.email.email is 'noreply@icloud.com.cn'
      • coalesce(headers.auth_summary.dmarc.pass)

Inspects: body.current_thread.text, body.html, body.html.inner_text, body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.scheme, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, headers.hops[].index, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: html.xpath, ml.nlu_classifier, regex.contains, regex.icontains, strings.icontains, strings.starts_with. Reference lists: $high_trust_sender_root_domains.

Indicators matched (15)

FieldMatchValue
strings.starts_withprefixCloud
strings.icontainssubstringCloud+
regex.icontainsregex^\x{FEFF}\s*Cloud
regex.containsregex^\x{2601}
regex.icontainsregex^!\s*cloud storage
strings.icontainssubstring4563 Cloud Way, Server City, CA
regex.icontainsregex^cloud (?:logo|storage)
regex.icontainsregexcloud id:\s*#\d+
regex.icontainsregex\bi?cloud\s(?:capacity|storage)\b
regex.icontainsregex\(?[0-9]{3}%\)?\s+?\b
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh
3 more
ml.nlu_classifier(body.current_thread.text).topics[].namememberFile Sharing and Cloud Services
ml.nlu_classifier(body.current_thread.text).topics[].namememberPayment Information
ml.nlu_classifier(body.current_thread.text).topics[].namememberFinancial Communications

Stages and Predicates

Stage 1: mql_rule

and
  not
    any(headers.hops)
      and
        any(headers.hops.fields)
          and
            headers.hops.fields[].name eq "X-Readdle-Spark-Cloud-Attachment"
            headers.hops.fields[].value is_not_null
        headers.hops.index eq "0"
  or
    any([body.current_thread.text, body.html.inner_text])
      or
        [body.current_thread.text, body.html.inner_text] contains "Cloud+ "
        [body.current_thread.text, body.html.inner_text] regex_match "^\\x{FEFF}\\s*Cloud"
        [body.current_thread.text, body.html.inner_text] starts_with "Cloud"
    and
      body.current_thread.text regex_match "\\(?[0-9]{3}%\\)?\\s+?\\b"
      body.current_thread.text regex_match "\\bi?cloud\\s(?:capacity|storage)\\b"
    any(html.xpath(body.html, '//img/@alt').nodes)
      html.xpath(body.html, '//img/@alt').nodes.raw regex_match "^cloud (?:logo|storage)"
    body.current_thread.text contains "4563 Cloud Way, Server City, CA"
    body.current_thread.text regex_match "^!\\s*cloud storage"
    body.current_thread.text regex_match "^\\x{2601}"
    body.current_thread.text regex_match "cloud id:\\s*#\\d+"
  not
    and
      or
        headers.auth_summary.dmarc.pass eq "true"
        headers.auth_summary.spf.pass eq "true"
      coalesce func_call "coalesce(sender.email.domain.root_domain, \"\") in (cloud-cme.com, cloudcounting.online, cloudhealthtech.com, cloudpano.com)"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
      sender.email.email eq "noreply@icloud.com.cn"
  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 eq "high"
      ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
  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 ["File Sharing and Cloud Services", "Financial Communications", "Payment Information"]
  filter(body.links, .href_url.scheme != 'mailto' and .href_url.domain.root_domain is not null and .href_url.domain.root_domain != 'oracle.com') length_compare "0"
  type.inbound eq "true"
   macro "all(filter(body.links))"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textcontains
  • 4563 Cloud Way, Server City, CA
field:"body.current_thread.text" kind:contains value:"4563 Cloud Way, Server City, CA"
body.current_thread.textregex_match
  • (?[0-9]{3}%)?\s+?\b
  • \bi?cloud\s(?:capacity|storage)\b
  • ^!\s*cloud storage
  • ^\x{2601}
  • cloud id:\s*#\d+
field:"body.current_thread.text" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Coinbase with suspicious links

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

Detects messages impersonating Coinbase with low reputation or url shortened links.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Free subdomain host, Image as content, Impersonation: Brand

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.links
  • sender.email
  • type

Rule body

type.inbound
and sender.email.domain.root_domain != "coinbase.com"

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

// none of the links are to coinbase.com
and all(body.links, .href_url.domain.root_domain != "coinbase.com")

// low rep or url shortened links found
and any(body.links,
        .href_url.domain.domain in $url_shorteners
        or .href_url.domain.domain in $social_landing_hosts

        // exempting legitimate Google Maps shortener
        and (
          not strings.ilike(.href_url.url, "http?://goo.gl/maps*")
          or (
            .href_url.domain.domain not in $tranco_1m
            or .href_url.domain.domain in $free_file_hosts
            or .href_url.domain.root_domain in $free_file_hosts
            or .href_url.domain.root_domain in $free_subdomain_hosts
            or .href_url.domain.domain in $url_shorteners
            or .href_url.domain.domain in $social_landing_hosts
            or 

            // mass mailer link, masks the actual URL
            .href_url.domain.root_domain in (
              "hubspotlinks.com",
              "mandrillapp.com",
              "sendgrid.net",
            )
          )
        )
)
// Coinbase logo
and (
  any(attachments,
      .file_type in $file_types_images
      and any(ml.logo_detect(.).brands, .name == "Coinbase")
  )
  or any(ml.logo_detect(file.message_screenshot()).brands, .name == "Coinbase")
)

Detection logic

Scope: inbound message.

Detects messages impersonating Coinbase with low reputation or url shortened links.

  1. inbound message
  2. sender.email.domain.root_domain is not 'coinbase.com'
  3. all of:
    • length(body.links) > 0
    • length(body.links) < 5
  4. all of body.links where:
    • .href_url.domain.root_domain is not 'coinbase.com'
  5. any of body.links where any holds:
    • .href_url.domain.domain in $url_shorteners
    • all of:
      • .href_url.domain.domain in $social_landing_hosts
      • any of:
        • not:
          • .href_url.url matches 'http?://goo.gl/maps*'
        • any of:
          • .href_url.domain.domain not in $tranco_1m
          • .href_url.domain.domain in $free_file_hosts
          • .href_url.domain.root_domain in $free_file_hosts
          • .href_url.domain.root_domain in $free_subdomain_hosts
          • .href_url.domain.domain in $url_shorteners
          • .href_url.domain.domain in $social_landing_hosts
          • .href_url.domain.root_domain in ('hubspotlinks.com', 'mandrillapp.com', 'sendgrid.net')
  6. any of:
    • any of attachments where all hold:
      • .file_type in $file_types_images
      • any of ml.logo_detect(.).brands where:
        • .name is 'Coinbase'
    • any of ml.logo_detect(file.message_screenshot()).brands where:
      • .name is 'Coinbase'

Inspects: attachments[].file_type, body.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.url, sender.email.domain.root_domain, type.inbound. Sensors: file.message_screenshot, ml.logo_detect, strings.ilike. Reference lists: $file_types_images, $free_file_hosts, $free_subdomain_hosts, $social_landing_hosts, $tranco_1m, $url_shorteners.

Indicators matched (5)

FieldMatchValue
body.links[].href_url.domain.root_domainmemberhubspotlinks.com
body.links[].href_url.domain.root_domainmembermandrillapp.com
body.links[].href_url.domain.root_domainmembersendgrid.net
ml.logo_detect(attachments[]).brands[].nameequalsCoinbase
ml.logo_detect(file.message_screenshot()).brands[].nameequalsCoinbase

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    or
      and
        or
          not
            body.links.href_url.url starts_with "http?://goo.gl/maps"
          body.links.href_url.domain.root_domain in ["hubspotlinks.com", "mandrillapp.com", "sendgrid.net"]
           macro "body.links[].href_url.domain.domain in free_file_hosts"
           macro "body.links[].href_url.domain.domain in social_landing_hosts"
           macro "body.links[].href_url.domain.domain in url_shorteners"
           macro "body.links[].href_url.domain.domain not in tranco_1m"
           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.domain in social_landing_hosts"
       macro "body.links[].href_url.domain.domain in url_shorteners"
  or
    any(attachments)
      and
        any(ml.logo_detect(attachments).brands)
          ml.logo_detect(attachments).brands.name eq "Coinbase"
         macro "attachments[].file_type in file_types_images"
    any(ml.logo_detect(file.message_screenshot()).brands)
      ml.logo_detect(file.message_screenshot()).brands.name eq "Coinbase"
  body.links length_compare "0"
  body.links length_compare "5"
  sender.email.domain.root_domain ne "coinbase.com"
  type.inbound eq "true"
   macro "all(body.links)"

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Discord notification

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

Detects inbound messages that impersonate Discord's notification system through display name spoofing, domain lookalikes, or logo usage in attachments. The messages contain typical Discord-style notification language in the subject line while failing authentication checks.

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
  • headers
  • headers.auth_summary
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  strings.ilike(sender.display_name, '*discord*')
  or (
    strings.ilevenshtein(sender.display_name, 'discord') <= 2
    and sender.display_name not in~ ("discogs")
  )
  or strings.ilike(sender.email.domain.domain, '*discord*')
  // Discord logo detection in image attachments
  or any(attachments,
         .file_type in $file_types_images
         and any(ml.logo_detect(.).brands,
                 .name == "Discord" and .confidence != "low"
         )
  )
  // Discord logo detection in message screenshot
  or any(ml.logo_detect(file.message_screenshot()).brands,
         .name == "Discord" and .confidence != "low"
  )
)
and (
  strings.icontains(subject.subject, 'you have received a new notification')
  or regex.icontains(subject.subject,
                     '(?:(?:new|unread|missed|pending|discord)\s+)?(?:message|notification|alert|activity|call) (?:from|waiting|pending)',
  )
  or strings.icontains(subject.subject, 'friend request')
  or strings.icontains(subject.subject, 'server invitation')
  or strings.icontains(subject.subject, 'mentioned you')
  or strings.icontains(subject.subject, 'direct message')
)
and not (
  sender.email.domain.root_domain in ("discord.com", "discogs.com")
  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
)

Detection logic

Scope: inbound message.

Detects inbound messages that impersonate Discord's notification system through display name spoofing, domain lookalikes, or logo usage in attachments. The messages contain typical Discord-style notification language in the subject line while failing authentication checks.

  1. inbound message
  2. any of:
    • sender.display_name matches '*discord*'
    • all of:
      • sender.display_name is similar to 'discord'
      • sender.display_name not in ('discogs')
    • sender.email.domain.domain matches '*discord*'
    • any of attachments where all hold:
      • .file_type in $file_types_images
      • any of ml.logo_detect(.).brands where all hold:
        • .name is 'Discord'
        • .confidence is not 'low'
    • any of ml.logo_detect(file.message_screenshot()).brands where all hold:
      • .name is 'Discord'
      • .confidence is not 'low'
  3. any of:
    • subject.subject contains 'you have received a new notification'
    • subject.subject matches '(?:(?:new|unread|missed|pending|discord)\\s+)?(?:message|notification|alert|activity|call) (?:from|waiting|pending)'
    • subject.subject contains 'friend request'
    • subject.subject contains 'server invitation'
    • subject.subject contains 'mentioned you'
    • subject.subject contains 'direct message'
  4. not:
    • all of:
      • sender.email.domain.root_domain in ('discord.com', 'discogs.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

Inspects: attachments[].file_type, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: file.message_screenshot, ml.logo_detect, regex.icontains, strings.icontains, strings.ilevenshtein, strings.ilike. Reference lists: $file_types_images, $high_trust_sender_root_domains.

Indicators matched (10)

FieldMatchValue
strings.ilikesubstring*discord*
strings.ilevenshteinfuzzydiscord
ml.logo_detect(attachments[]).brands[].nameequalsDiscord
ml.logo_detect(file.message_screenshot()).brands[].nameequalsDiscord
strings.icontainssubstringyou have received a new notification
regex.icontainsregex(?:(?:new|unread|missed|pending|discord)\s+)?(?:message|notification|alert|activity|call) (?:from|waiting|pending)
strings.icontainssubstringfriend request
strings.icontainssubstringserver invitation
strings.icontainssubstringmentioned you
strings.icontainssubstringdirect message

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(attachments)
      and
        any(ml.logo_detect(attachments).brands)
          and
            ml.logo_detect(attachments[]).brands[].confidence ne "low"
            ml.logo_detect(attachments[]).brands[].name eq "Discord"
         macro "attachments[].file_type in file_types_images"
    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 "Discord"
    and
      not
        sender.display_name eq "discogs"
      strings.ilevenshtein func_call "strings.ilevenshtein(sender.display_name, \"discord\") <= 2"
    sender.display_name match "discord"
    sender.email.domain.domain match "discord"
  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 ["discogs.com", "discord.com"]
  or
    subject.subject contains "direct message"
    subject.subject contains "friend request"
    subject.subject contains "mentioned you"
    subject.subject contains "server invitation"
    subject.subject contains "you have received a new notification"
    subject.subject regex_match "(?:(?:new|unread|missed|pending|discord)\\s+)?(?:message|notification|alert|activity|call) (?:from|waiting|pending)"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
sender.display_namewildcard
  • *discord*
field:"sender.display_name" kind:wildcard value:"*discord*"
sender.email.domain.domainwildcard
  • *discord*
field:"sender.email.domain.domain" kind:wildcard value:"*discord*"
subject.subjectcontains
  • direct message
  • friend request
  • mentioned you
  • server invitation
  • you have received a new notification
field:"subject.subject" kind:contains
subject.subjectregex_match
  • (?:(?:new|unread|missed|pending|discord)\s+)?(?:message|notification|alert|activity|call) (?:from|waiting|pending)
field:"subject.subject" kind:regex_match value:"(?:(?:new|unread|missed|pending|discord)\s+)?(?:message|notification|alert|activity|call) (?:from|waiting|pending)"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Fake Fax

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

Detects messages containing fax-related language and notification elements from senders outside of known legitimate fax service providers.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Image as content, Free file host, Free subdomain host, 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
  • sender.email
  • subject
  • type

Rule body

type.inbound
// Subject or sender contains fax
and (
  any([subject.subject, sender.display_name],
      regex.icontains(.,
                      '\bfax\b',
                      '[ve][[:punct:]]?fax',
                      '[[:punct:]]fax\b',
                      '\bfax[[:punct:]]',
                      'fr[[:punct:]].{0,25}document',
                      'e.?f.?a.?x'
      )
  )
)
and (
  // body.current_thread.text logic
  (
    ( // strong notification terms in either the subject or body.current_thread.text
      any([subject.subject, body.current_thread.text],
          strings.icontains(., "New Fax Received")
          or strings.icontains(., "e-Fax Document")
          or strings.icontains(., "Fax Status")
          or strings.icontains(., "Fax ID")
          or strings.icontains(., "Fax Message Delivered")
          or strings.icontains(., "Incoming Fax")
          or strings.icontains(., "New Fax Document")
          or strings.istarts_with(., 'Fax message')
          or regex.icontains(.,
                             '(?:received|have) (a|(?:(.?\d.?))) (?:new )?e?fax'
          )
          or regex.icontains(., "to view (th(?:e|is) )?(?:fax|message)")
          or regex.icontains(.,
                             'transmit(?:ted|ting)?(?:\s+\w+){0,2}\s+(?:fax|facsimile)',
                             '(?:fax|facsimile)\s+(?:\s+\w+){0,2}transmit(?:ted|ting)?',
          )
      )
      and (
        // combined with above, we should have very high confidence this is a fax message
        (
          // date
          strings.icontains(body.current_thread.text, "Date:")
          or strings.icontains(body.current_thread.text, "Time Sent:")
          or strings.icontains(body.current_thread.text, "Time Received:")
          or strings.icontains(body.current_thread.text, "Received")
          // page count
          or regex.icontains(body.current_thread.text, "Num(ber)? of Pages?")
          or strings.icontains(body.current_thread.text, "Type: PDF")
        )
        // commonly abused brands
        or (
          strings.icontains(body.current_thread.text,
                            "eFax is a registered trademark of Consensus"
          )
          or strings.icontains(body.current_thread.text, "RingCentral, Inc")
        )
        // there is a link with the display text of some CTA
        or any(body.links,
               strings.icontains(.display_text, "open fax")
               // review document, view document review and sign document
               or regex.icontains(.display_text,
                                  "(?:re)?view (?:(?:&|and) sign )?(?:complete )?document"
               )
               or strings.icontains(.display_text, "Open document")
        )
      )
    )
    // attachment logic
    or (
      // the body.current_thread.text length is very short (probably just a warning banner)
      // and the attachment isn't used in the body of the message
      length(body.current_thread.text) < 300
      // and there are attachments
      and 0 < length(attachments) < 5
      // the attachments shouldn't be images which are used in the body of the html
      and any(attachments,
              strings.icontains(.file_name, 'fax')
              or (
                // or they are used in the body and OCR on them contains fax wording
                // the image is used in the HTML body
                .file_type in $file_types_images
                and (
                  any(regex.extract(.content_id, '^\<(.*)\>$'),
                      any(.groups,
                          strings.icontains(body.html.raw,
                                            strings.concat('src="cid:', ., '"')
                          )
                      )
                  )
                  or strings.icontains(body.html.raw, .content_id)
                )
                and (
                  // and that image contains fax wording
                  strings.icontains(beta.ocr(.).text, "New Fax Received")
                  or strings.icontains(beta.ocr(.).text, "New Fax Document")
                  or regex.icontains(beta.ocr(.).text,
                                     "(?:received|have) a (?:new )?fax"
                  )
                  or regex.icontains(beta.ocr(.).text,
                                     "to view (th(?:e|is) )?(?:fax|message)"
                  )
                  or regex.icontains(beta.ocr(.).text,
                                     'transmit(?:ted|ting)?(?:\s+\w+){0,2}\s+(?:fax|facsimile)',
                                     '(?:fax|facsimile)\s+(?:\s+\w+){0,2}transmit(?:ted|ting)?',
                  )
                )
              )
      )
    )
  )
)
// negate known fax mailers
and not (
  sender.email.domain.root_domain in (
    "faxage.com",
    'fax2mail.com',
    'ringcentral.com',
    'ringcentral.biz',
    'avaya.com',
    'egoldfax.com',
    'efax.com',
    'hellofax.com',
    'mfax.io',
    'goto.com',
    'faxmessage.net',
    'fuze.com',
    'retarus.net',
    'srfax.com',
    'myfax.com',
    '8x8.com',
    'zoom.us',
    'faxhd.com',
    'humblefax.com',
    'bridge.insure',
    'telecomsvc.com'
  )
  and headers.auth_summary.dmarc.pass
)

Detection logic

Scope: inbound message.

Detects messages containing fax-related language and notification elements from senders outside of known legitimate fax service providers.

  1. inbound message
  2. any of [subject.subject, sender.display_name] where:
    • . matches any of 6 patterns
      • \bfax\b
      • [ve][[:punct:]]?fax
      • [[:punct:]]fax\b
      • \bfax[[:punct:]]
      • fr[[:punct:]].{0,25}document
      • e.?f.?a.?x
  3. any of:
    • all of:
      • any of [subject.subject, body.current_thread.text] where any holds:
        • . contains 'New Fax Received'
        • . contains 'e-Fax Document'
        • . contains 'Fax Status'
        • . contains 'Fax ID'
        • . contains 'Fax Message Delivered'
        • . contains 'Incoming Fax'
        • . contains 'New Fax Document'
        • . starts with 'Fax message'
        • . matches '(?:received|have) (a|(?:(.?\\d.?))) (?:new )?e?fax'
        • . matches 'to view (th(?:e|is) )?(?:fax|message)'
        • . matches any of 2 patterns
          • transmit(?:ted|ting)?(?:\s+\w+){0,2}\s+(?:fax|facsimile)
          • (?:fax|facsimile)\s+(?:\s+\w+){0,2}transmit(?:ted|ting)?
      • any of:
        • any of:
          • body.current_thread.text contains 'Date:'
          • body.current_thread.text contains 'Time Sent:'
          • body.current_thread.text contains 'Time Received:'
          • body.current_thread.text contains 'Received'
          • body.current_thread.text matches 'Num(ber)? of Pages?'
          • body.current_thread.text contains 'Type: PDF'
        • any of:
          • body.current_thread.text contains 'eFax is a registered trademark of Consensus'
          • body.current_thread.text contains 'RingCentral, Inc'
        • any of body.links where any holds:
          • .display_text contains 'open fax'
          • .display_text matches '(?:re)?view (?:(?:&|and) sign )?(?:complete )?document'
          • .display_text contains 'Open document'
    • all of:
      • length(body.current_thread.text) < 300
      • all of:
        • length(attachments) > 0
        • length(attachments) < 5
      • any of attachments where any holds:
        • .file_name contains 'fax'
        • all of:
          • .file_type in $file_types_images
          • any of:
            • any of regex.extract(.content_id) where:
              • any of .groups where:
                • strings.icontains(body.html.raw)
            • strings.icontains(body.html.raw)
          • any of:
            • beta.ocr(.).text contains 'New Fax Received'
            • beta.ocr(.).text contains 'New Fax Document'
            • beta.ocr(.).text matches '(?:received|have) a (?:new )?fax'
            • beta.ocr(.).text matches 'to view (th(?:e|is) )?(?:fax|message)'
            • beta.ocr(.).text matches any of 2 patterns
              • transmit(?:ted|ting)?(?:\s+\w+){0,2}\s+(?:fax|facsimile)
              • (?:fax|facsimile)\s+(?:\s+\w+){0,2}transmit(?:ted|ting)?
  4. not:
    • all of:
      • sender.email.domain.root_domain in ('faxage.com', 'fax2mail.com', 'ringcentral.com', 'ringcentral.biz', 'avaya.com', 'egoldfax.com', 'efax.com', 'hellofax.com', 'mfax.io', 'goto.com', 'faxmessage.net', 'fuze.com', 'retarus.net', 'srfax.com', 'myfax.com', '8x8.com', 'zoom.us', 'faxhd.com', 'humblefax.com', 'bridge.insure', 'telecomsvc.com')
      • headers.auth_summary.dmarc.pass

Inspects: attachments[].content_id, attachments[].file_name, attachments[].file_type, body.current_thread.text, body.html.raw, body.links, body.links[].display_text, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: beta.ocr, regex.extract, regex.icontains, strings.concat, strings.icontains, strings.istarts_with. Reference lists: $file_types_images.

Indicators matched (32)

FieldMatchValue
regex.icontainsregex\bfax\b
regex.icontainsregex[ve][[:punct:]]?fax
regex.icontainsregex[[:punct:]]fax\b
regex.icontainsregex\bfax[[:punct:]]
regex.icontainsregexfr[[:punct:]].{0,25}document
regex.icontainsregexe.?f.?a.?x
strings.icontainssubstringNew Fax Received
strings.icontainssubstringe-Fax Document
strings.icontainssubstringFax Status
strings.icontainssubstringFax ID
strings.icontainssubstringFax Message Delivered
strings.icontainssubstringIncoming Fax
20 more
strings.icontainssubstringNew Fax Document
strings.istarts_withprefixFax message
regex.icontainsregex(?:received|have) (a|(?:(.?\d.?))) (?:new )?e?fax
regex.icontainsregexto view (th(?:e|is) )?(?:fax|message)
regex.icontainsregextransmit(?:ted|ting)?(?:\s+\w+){0,2}\s+(?:fax|facsimile)
regex.icontainsregex(?:fax|facsimile)\s+(?:\s+\w+){0,2}transmit(?:ted|ting)?
strings.icontainssubstringDate:
strings.icontainssubstringTime Sent:
strings.icontainssubstringTime Received:
strings.icontainssubstringReceived
regex.icontainsregexNum(ber)? of Pages?
strings.icontainssubstringType: PDF
strings.icontainssubstringeFax is a registered trademark of Consensus
strings.icontainssubstringRingCentral, Inc
strings.icontainssubstringopen fax
regex.icontainsregex(?:re)?view (?:(?:&|and) sign )?(?:complete )?document
strings.icontainssubstringOpen document
strings.icontainssubstringfax
regex.extractregex^\<(.*)\>$
regex.icontainsregex(?:received|have) a (?:new )?fax

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      any(attachments)
        or
          and
            or
              any(regex.extract(attachments.content_id))
                any(regex.extract(attachments.content_id).groups)
                  strings.icontains func_call "strings.icontains(body.html.raw)"
              strings.icontains func_call "strings.icontains(body.html.raw)"
            or
              beta.ocr(attachments[]).text contains "New Fax Document"
              beta.ocr(attachments[]).text contains "New Fax Received"
              beta.ocr(attachments[]).text regex_match "(?:fax|facsimile)\\s+(?:\\s+\\w+){0,2}transmit(?:ted|ting)?"
              beta.ocr(attachments[]).text regex_match "(?:received|have) a (?:new )?fax"
              beta.ocr(attachments[]).text regex_match "to view (th(?:e|is) )?(?:fax|message)"
              beta.ocr(attachments[]).text regex_match "transmit(?:ted|ting)?(?:\\s+\\w+){0,2}\\s+(?:fax|facsimile)"
             macro "attachments[].file_type in file_types_images"
          attachments.file_name contains "fax"
      attachments length_compare "0"
      attachments length_compare "5"
      body.current_thread.text length_compare "300"
    and
      or
        any(body.links)
          or
            body.links.display_text contains "Open document"
            body.links.display_text contains "open fax"
            body.links.display_text regex_match "(?:re)?view (?:(?:&|and) sign )?(?:complete )?document"
        body.current_thread.text contains "Date:"
        body.current_thread.text contains "Received"
        body.current_thread.text contains "RingCentral, Inc"
        body.current_thread.text contains "Time Received:"
        body.current_thread.text contains "Time Sent:"
        body.current_thread.text contains "Type: PDF"
        body.current_thread.text contains "eFax is a registered trademark of Consensus"
        body.current_thread.text regex_match "Num(ber)? of Pages?"
      any([subject.subject, body.current_thread.text])
        or
          [subject.subject, body.current_thread.text] contains "Fax ID"
          [subject.subject, body.current_thread.text] contains "Fax Message Delivered"
          [subject.subject, body.current_thread.text] contains "Fax Status"
          [subject.subject, body.current_thread.text] contains "Incoming Fax"
          [subject.subject, body.current_thread.text] contains "New Fax Document"
          [subject.subject, body.current_thread.text] contains "New Fax Received"
          [subject.subject, body.current_thread.text] contains "e-Fax Document"
          [subject.subject, body.current_thread.text] regex_match "(?:fax|facsimile)\\s+(?:\\s+\\w+){0,2}transmit(?:ted|ting)?"
          [subject.subject, body.current_thread.text] regex_match "(?:received|have) (a|(?:(.?\\d.?))) (?:new )?e?fax"
          [subject.subject, body.current_thread.text] regex_match "to view (th(?:e|is) )?(?:fax|message)"
          [subject.subject, body.current_thread.text] regex_match "transmit(?:ted|ting)?(?:\\s+\\w+){0,2}\\s+(?:fax|facsimile)"
          [subject.subject, body.current_thread.text] starts_with "Fax message"
  any([subject.subject, sender.display_name])
    or
      [subject.subject, sender.display_name] regex_match "[[:punct:]]fax\\b"
      [subject.subject, sender.display_name] regex_match "[ve][[:punct:]]?fax"
      [subject.subject, sender.display_name] regex_match "\\bfax[[:punct:]]"
      [subject.subject, sender.display_name] regex_match "\\bfax\\b"
      [subject.subject, sender.display_name] regex_match "e.?f.?a.?x"
      [subject.subject, sender.display_name] regex_match "fr[[:punct:]].{0,25}document"
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.root_domain in ["8x8.com", "avaya.com", "bridge.insure", "efax.com", "egoldfax.com", "fax2mail.com", "faxage.com", "faxhd.com", "faxmessage.net", "fuze.com", "goto.com", "hellofax.com", "humblefax.com", "mfax.io", "myfax.com", "retarus.net", "ringcentral.biz", "ringcentral.com", "srfax.com", "telecomsvc.com", "zoom.us"]
  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_domainin8x8.com, avaya.com, bridge.insure, efax.com, egoldfax.com, fax2mail.com, faxage.com, faxhd.com, faxmessage.net, fuze.com, goto.com, hellofax.com, humblefax.com, mfax.io, myfax.com, retarus.net, ringcentral.biz, ringcentral.com, srfax.com, telecomsvc.com, zoom.usexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textcontains
  • Date:
  • Received
  • RingCentral, Inc
  • Time Received:
  • Time Sent:
  • Type: PDF
  • eFax is a registered trademark of Consensus
field:"body.current_thread.text" kind:contains
body.current_thread.textregex_match
  • Num(ber)? of Pages?
field:"body.current_thread.text" kind:regex_match value:"Num(ber)? of Pages?"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Brand impersonation: Google fake sign-in warning

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

Detects messages with image attachments containing fake Google sign-in warnings with no links leading to Google sites.

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.links
  • sender.email
  • type

Rule body

type.inbound
and length(body.links) > 0

// Google Logo in Attachment
and any(attachments,
        .file_type in $file_types_images
        and any(ml.logo_detect(.).brands, .name in ("Google"))
)
and any(attachments,
        .file_type in $file_types_images
        and (
          any(file.explode(.),
              // Fake activity warning
              3 of (
                strings.ilike(.scan.ocr.raw, "*new sign-in*"),
                strings.ilike(.scan.ocr.raw, "*google account*"),
                strings.ilike(.scan.ocr.raw, "*secure your account*"),
                strings.ilike(.scan.ocr.raw, "*check activity*"),
              )
          )
        )
)

// legitimate sign-in warnings contains links to google, gmail or googleapis.com
and (
  not all(body.links,
          .href_url.domain.root_domain in (
            "google.com",
            "gmail.com",
            "googleapis.com"
          )
          or .href_url.domain.root_domain is null
  )
)
and sender.email.domain.root_domain not in $org_domains
and sender.email.domain.root_domain != "google.com"

Detection logic

Scope: inbound message.

Detects messages with image attachments containing fake Google sign-in warnings with no links leading to Google sites.

  1. inbound message
  2. length(body.links) > 0
  3. any of attachments where all hold:
    • .file_type in $file_types_images
    • any of ml.logo_detect(.).brands where:
      • .name in ('Google')
  4. any of attachments where all hold:
    • .file_type in $file_types_images
    • any of file.explode(.) where:
      • at least 3 of 4: .scan.ocr.raw matches any of 4 patterns
        • *new sign-in*
        • *google account*
        • *secure your account*
        • *check activity*
  5. not:
    • all of body.links where any holds:
      • .href_url.domain.root_domain in ('google.com', 'gmail.com', 'googleapis.com')
      • .href_url.domain.root_domain is missing
  6. sender.email.domain.root_domain not in $org_domains
  7. sender.email.domain.root_domain is not 'google.com'

Inspects: attachments[].file_type, body.links, body.links[].href_url.domain.root_domain, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, ml.logo_detect, strings.ilike. Reference lists: $file_types_images, $org_domains.

Indicators matched (5)

FieldMatchValue
ml.logo_detect(attachments[]).brands[].namememberGoogle
strings.ilikesubstring*new sign-in*
strings.ilikesubstring*google account*
strings.ilikesubstring*secure your account*
strings.ilikesubstring*check activity*

Stages and Predicates

Stage 1: mql_rule

and
  any(attachments)
    and
      any(file.explode(attachments))
        or
          file.explode(attachments[])[].scan.ocr.raw match "check activity"
          file.explode(attachments[])[].scan.ocr.raw match "google account"
          file.explode(attachments[])[].scan.ocr.raw match "new sign-in"
          file.explode(attachments[])[].scan.ocr.raw match "secure your account"
       macro "attachments[].file_type in file_types_images"
  any(attachments)
    and
      any(ml.logo_detect(attachments).brands)
        ml.logo_detect(attachments).brands.name eq "Google"
       macro "attachments[].file_type in file_types_images"
  not
     macro "all(body.links)"
  body.links length_compare "0"
  sender.email.domain.root_domain ne "google.com"
  type.inbound eq "true"
   macro "sender.email.domain.root_domain not in org_domains"

Indicators

These rows show field, operator, and value matches.

Brand impersonation: Microsoft with low reputation links

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

Detects low reputation links with Microsoft specific indicators in the body.

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

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.domains
  • recipients
  • recipients.to
  • sender.email
  • subject
  • type

Rule body

type.inbound
and 0 < length(body.links) < 50
// suspicious link
and any(body.links,
        (
          .href_url.domain.tld == "ru"
          or .href_url.domain.root_domain not in $tranco_1m
          or .href_url.domain.domain in $free_file_hosts
          or .href_url.domain.root_domain in $free_file_hosts
          or .href_url.domain.root_domain in $free_subdomain_hosts
          or .href_url.domain.domain in $url_shorteners
          or .href_url.domain.domain in $social_landing_hosts
          // account for URL rewrites
          or (
            any(.href_url.query_params_decoded["domain"],
                strings.parse_domain(.).tld == "ru"
                or strings.parse_domain(.).root_domain not in~ $tranco_1m
                or strings.parse_domain(.).domain in~ $free_file_hosts
                or strings.parse_domain(.).root_domain in~ $free_file_hosts
                or strings.parse_domain(.).root_domain in~ $free_subdomain_hosts
                or strings.parse_domain(.).domain in~ $url_shorteners
                or strings.parse_domain(.).domain in~ $social_landing_hosts
            )
          )
          or 

          // mass mailer link, masks the actual URL
          .href_url.domain.root_domain in (
            "hubspotlinks.com",
            "mandrillapp.com",
            "sendgrid.net",
            "rs6.net"
          )

          // Google AMP redirect
          or (
            .href_url.domain.sld == "google"
            and strings.starts_with(.href_url.path, "/amp/")
          )

          // Recipient email address in link
          or any(body.links,
                 any(recipients.to,
                     strings.icontains(..href_url.url, .email.email)
                     and any(recipients.to, .email.domain.valid)
                 )
          )
          or .href_url.domain.root_domain == "beehiiv.com"
        )

        // exclude sources of potential FPs
        and (
          .href_url.domain.root_domain not in (
            "svc.ms",
            "sharepoint.com",
            "1drv.ms",
            "microsoft.com",
            "aka.ms",
            "msftauthimages.net",
            "office.com",
            "microsoftproject.com"
          )
          or any(body.links, .href_url.domain.domain in $free_file_hosts)
        )
        and .href_url.domain.root_domain not in $org_domains
        and .href_url.domain.valid
)

// not a reply
and (length(headers.references) == 0 or headers.in_reply_to is null)

// Microsoft logo
and (
  any(attachments,
      .file_type in $file_types_images
      and any(ml.logo_detect(.).brands, strings.starts_with(.name, "Microsoft"))
  )
  or strings.istarts_with(strings.replace_confusables(body.current_thread.text),
                          "Microsoft "
  )
  or (
    regex.imatch(strings.replace_confusables(body.current_thread.text),
                 '[\n\s]*[o0O]ff[il1]ce\b.*'
    )
    and not regex.icontains(strings.replace_confusables(body.current_thread.text
                            ),
                            'office (for lease|rent|sale)'
    )
  )
  or any(ml.logo_detect(file.message_screenshot()).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 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,
                     '<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)\)'
    )
  )
)

// suspicious content
and (
  // current thread is empty, but an image attachment is branded as microsoft.
  // common in image as content
  (
    body.current_thread.text == ""
    and any(attachments,
            .file_type in $file_types_images
            and any(ml.logo_detect(.).brands,
                    strings.starts_with(.name, "Microsoft")
            )
    )
  )
  or (
    strings.ilike(body.plain.raw,
                  "*password*",
                  "*document*",
                  "*voicemail*",
                  "*cache*",
                  "*fax*",
                  "*storage*",
                  "*quota*",
                  "*message*"
    )
    and strings.ilike(body.plain.raw,
                      "*terminated*",
                      "*review*",
                      "*expire*",
                      "*click*",
                      "*view*",
                      "*exceed*",
                      "*clear*",
                      "*only works*",
                      "*failed*",
                      "*deleted*",
                      "*revalidated*",
                      "*renewal*"
    )
  )
  or (
    any(attachments,
        .file_type in $file_types_images
        and any(file.explode(.),
                strings.ilike(.scan.ocr.raw,
                              "*password*",
                              "*document*",
                              "*voicemail*",
                              "*cache*",
                              "*fax*",
                              "*storage*",
                              "*quota*",
                              "*messages*"
                )
                and strings.ilike(.scan.ocr.raw,
                                  "*terminated*",
                                  "*review*",
                                  "*expire*",
                                  "*click*",
                                  "*view*",
                                  "*exceed*",
                                  "*clear*",
                                  "*only works*",
                                  "*failed*",
                                  "*deleted*"
                )
        )
    )
  )
  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
    //
    strings.ilike(beta.ocr(file.message_screenshot()).text,
                  "*password*",
                  "*document*",
                  "*voicemail*",
                  "*cache*",
                  "*fax*",
                  "*storage*",
                  "*quota*",
                  "*messages*"
    )
    and strings.ilike(beta.ocr(file.message_screenshot()).text,
                      "*terminated*",
                      "*review*",
                      "*expire*",
                      "*click*",
                      "*view*",
                      "*exceed*",
                      "*clear*",
                      "*only works*",
                      "*failed*",
                      "*deleted*",
                      "*revalidated*",
                      "*renewal*"
    )
  )
  or (
    any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft" and .confidence in~ ("medium", "high")
    )
    or 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 in ("medium", "high")
                   )
           )
    )
  )
)
and sender.email.domain.root_domain not in (
  "bing.com",
  "microsoft.com",
  "microsoftonline.com",
  "microsoftproject.com",
  "microsoftstoreemail.com",
  "microsoftsupport.com",
  "microsoft365.com",
  "office.com",
  "office365.com",
  "onedrive.com",
  "sharepointonline.com",
  "yammer.com",
)

// negate legitimate Office 365 bouncebacks
and not (
  length(attachments) > 0
  and all(attachments,
          .content_type in ("message/delivery-status", "message/rfc822")
  )
  and (sender.email.local_part in ('postmaster', 'mailer-daemon'))
)

// negate Microsoft "welcome to the X group" notifications
and not (
  headers.auth_summary.dmarc.pass
  and length(attachments) == 6
  and length(filter(attachments,
                    strings.istarts_with(.file_name, "GuestWelcomeEmail")
             )
  ) == 5
  and length(filter(body.links,
                    (
                      .href_url.domain.domain not in (
                        "outlook.office365.com",
                        "aka.ms",
                        "go.microsoft.com"
                      )
                    )
                    and not .href_url.domain.domain == sender.email.domain.domain
             )
  ) == 0
  and subject.subject == strings.replace_confusables(subject.subject)
)

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

// exclude marketing jargon from ms partners
and not regex.icontains(body.current_thread.text,
                        '(schedul(e|ing)|set up).{0,20}(call|meeting|demo|zoom|conversation|time|tool|discussion)|book.{0,10}(meeting|demo|call|slot|time)|connect.{0,12}(with me|phone|email)|my.{0,10}(calendar|cal)|reserve.{0,10}s[pl]ot|break the ice|want to know more?|miss your chance|if you no longer wish|if you no longer want|if you wish to opt out|low-code (development|approach|solution|journey|platform)|(?:invite|virtual).{0,30}(webinar|presentation)'
)

Detection logic

Scope: inbound message.

Detects low reputation links with Microsoft specific indicators in the body.

  1. inbound message
  2. all of:
    • length(body.links) > 0
    • length(body.links) < 50
  3. any of body.links where all hold:
    • any of:
      • .href_url.domain.tld is 'ru'
      • .href_url.domain.root_domain not in $tranco_1m
      • .href_url.domain.domain in $free_file_hosts
      • .href_url.domain.root_domain in $free_file_hosts
      • .href_url.domain.root_domain in $free_subdomain_hosts
      • .href_url.domain.domain in $url_shorteners
      • .href_url.domain.domain in $social_landing_hosts
      • any of .href_url.query_params_decoded['domain'] where any holds:
        • strings.parse_domain(.).tld is 'ru'
        • strings.parse_domain(.).root_domain not in $tranco_1m
        • strings.parse_domain(.).domain in $free_file_hosts
        • strings.parse_domain(.).root_domain in $free_file_hosts
        • strings.parse_domain(.).root_domain in $free_subdomain_hosts
        • strings.parse_domain(.).domain in $url_shorteners
        • strings.parse_domain(.).domain in $social_landing_hosts
      • .href_url.domain.root_domain in ('hubspotlinks.com', 'mandrillapp.com', 'sendgrid.net', 'rs6.net')
      • all of:
        • .href_url.domain.sld is 'google'
        • .href_url.path starts with '/amp/'
      • any of body.links where:
        • any of recipients.to where all hold:
          • strings.icontains(.href_url.url)
          • any of recipients.to where:
            • .email.domain.valid
      • .href_url.domain.root_domain is 'beehiiv.com'
    • any of:
      • .href_url.domain.root_domain not in ('svc.ms', 'sharepoint.com', '1drv.ms', 'microsoft.com', 'aka.ms', 'msftauthimages.net', 'office.com', 'microsoftproject.com')
      • any of body.links where:
        • .href_url.domain.domain in $free_file_hosts
    • .href_url.domain.root_domain not in $org_domains
    • .href_url.domain.valid
  4. any of:
    • length(headers.references) is 0
    • headers.in_reply_to is missing
  5. any of:
    • any of attachments where all hold:
      • .file_type in $file_types_images
      • any of ml.logo_detect(.).brands where:
        • .name starts with 'Microsoft'
    • strings.replace_confusables(body.current_thread.text) starts with 'Microsoft '
    • all of:
      • strings.replace_confusables(body.current_thread.text) matches '[\\n\\s]*[o0O]ff[il1]ce\\b.*'
      • not:
        • strings.replace_confusables(body.current_thread.text) matches 'office (for lease|rent|sale)'
    • any of ml.logo_detect(file.message_screenshot()).brands where:
      • .name starts with 'Microsoft'
    • 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 '<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)\)
  6. any of:
    • all of:
      • body.current_thread.text is ''
      • any of attachments where all hold:
        • .file_type in $file_types_images
        • any of ml.logo_detect(.).brands where:
          • .name starts with 'Microsoft'
    • all of:
      • body.plain.raw matches any of 8 patterns
        • *password*
        • *document*
        • *voicemail*
        • *cache*
        • *fax*
        • *storage*
        • *quota*
        • *message*
      • body.plain.raw matches any of 12 patterns
        • *terminated*
        • *review*
        • *expire*
        • *click*
        • *view*
        • *exceed*
        • *clear*
        • *only works*
        • *failed*
        • *deleted*
        • *revalidated*
        • *renewal*
    • any of attachments where all hold:
      • .file_type in $file_types_images
      • any of file.explode(.) where all hold:
        • .scan.ocr.raw matches any of 8 patterns
          • *password*
          • *document*
          • *voicemail*
          • *cache*
          • *fax*
          • *storage*
          • *quota*
          • *messages*
        • .scan.ocr.raw matches any of 10 patterns
          • *terminated*
          • *review*
          • *expire*
          • *click*
          • *view*
          • *exceed*
          • *clear*
          • *only works*
          • *failed*
          • *deleted*
    • all of:
      • beta.ocr(file.message_screenshot()).text matches any of 8 patterns
        • *password*
        • *document*
        • *voicemail*
        • *cache*
        • *fax*
        • *storage*
        • *quota*
        • *messages*
      • beta.ocr(file.message_screenshot()).text matches any of 12 patterns
        • *terminated*
        • *review*
        • *expire*
        • *click*
        • *view*
        • *exceed*
        • *clear*
        • *only works*
        • *failed*
        • *deleted*
        • *revalidated*
        • *renewal*
    • any of:
      • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
        • .name is 'cred_theft'
        • .confidence in ('medium', 'high')
      • 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 in ('medium', 'high')
  7. sender.email.domain.root_domain not in ('bing.com', 'microsoft.com', 'microsoftonline.com', 'microsoftproject.com', 'microsoftstoreemail.com', 'microsoftsupport.com', 'microsoft365.com', 'office.com', 'office365.com', 'onedrive.com', 'sharepointonline.com', 'yammer.com')
  8. not:
    • all of:
      • length(attachments) > 0
      • all of attachments where:
        • .content_type in ('message/delivery-status', 'message/rfc822')
      • sender.email.local_part in ('postmaster', 'mailer-daemon')
  9. not:
    • all of:
      • headers.auth_summary.dmarc.pass
      • length(attachments) is 6
      • length(filter(attachments, strings.istarts_with(.file_name, 'GuestWelcomeEmail'))) is 5
      • length(filter(body.links, .href_url.domain.domain not in ('outlook.office365.com', 'aka.ms', 'go.microsoft.com') and not .href_url.domain.domain == sender.email.domain.domain)) is 0
      • subject.subject is strings.replace_confusables(subject.subject)
  10. 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
  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
  12. any of:
    • not:
      • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  13. not:
    • profile.by_sender().any_messages_benign
  14. not:
    • body.current_thread.text matches '(schedul(e|ing)|set up).{0,20}(call|meeting|demo|zoom|conversation|time|tool|discussion)|book.{0,10}(meeting|demo|call|slot|time)|connect.{0,12}(with me|phone|email)|my.{0,10}(calendar|cal)|reserve.{0,10}s[pl]ot|break the ice|want to know more?|miss your chance|if you no longer wish|if you no longer want|if you wish to opt out|low-code (development|approach|solution|journey|platform)|(?:invite|virtual).{0,30}(webinar|presentation)'

Inspects: attachments[].content_type, attachments[].file_name, attachments[].file_type, body.current_thread.text, body.html.raw, body.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.sld, body.links[].href_url.domain.tld, body.links[].href_url.domain.valid, body.links[].href_url.path, body.links[].href_url.query_params_decoded['domain'], body.links[].href_url.url, body.plain.raw, headers.auth_summary.dmarc.pass, headers.domains, headers.domains[].root_domain, headers.in_reply_to, headers.message_id, headers.references, recipients.to, recipients.to[].email.domain.valid, recipients.to[].email.email, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.local_part, subject.subject, type.inbound. Sensors: beta.ocr, file.explode, file.message_screenshot, ml.logo_detect, ml.nlu_classifier, profile.by_sender, regex.icontains, regex.imatch, strings.ends_with, strings.icontains, strings.ilike, strings.istarts_with, strings.parse_domain, strings.replace_confusables, strings.starts_with. Reference lists: $file_types_images, $free_file_hosts, $free_subdomain_hosts, $high_trust_sender_root_domains, $org_domains, $social_landing_hosts, $tranco_1m, $url_shorteners.

Indicators matched (94)

FieldMatchValue
body.links[].href_url.domain.tldequalsru
body.links[].href_url.domain.root_domainmemberhubspotlinks.com
body.links[].href_url.domain.root_domainmembermandrillapp.com
body.links[].href_url.domain.root_domainmembersendgrid.net
body.links[].href_url.domain.root_domainmemberrs6.net
body.links[].href_url.domain.sldequalsgoogle
strings.starts_withprefix/amp/
body.links[].href_url.domain.root_domainequalsbeehiiv.com
strings.starts_withprefixMicrosoft
strings.istarts_withprefixMicrosoft
regex.imatchregex[\n\s]*[o0O]ff[il1]ce\b.*
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}
82 more
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.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)\)
body.current_thread.textequals
strings.ilikesubstring*password*
strings.ilikesubstring*document*
strings.ilikesubstring*voicemail*
strings.ilikesubstring*cache*
strings.ilikesubstring*fax*
strings.ilikesubstring*storage*
strings.ilikesubstring*quota*
strings.ilikesubstring*message*
strings.ilikesubstring*terminated*
strings.ilikesubstring*review*
strings.ilikesubstring*expire*
strings.ilikesubstring*click*
strings.ilikesubstring*view*
strings.ilikesubstring*exceed*
strings.ilikesubstring*clear*
strings.ilikesubstring*only works*
strings.ilikesubstring*failed*
strings.ilikesubstring*deleted*
strings.ilikesubstring*revalidated*
strings.ilikesubstring*renewal*
strings.ilikesubstring*messages*
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(file.explode(attachments[])[].scan.ocr.raw).intents[].nameequalscred_theft
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidencemembermedium
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidencememberhigh
body.links[].href_url.domain.domainmemberoutlook.office365.com
body.links[].href_url.domain.domainmemberaka.ms
body.links[].href_url.domain.domainmembergo.microsoft.com

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        any(body.links)
          any(recipients.to)
            and
              any(recipients.to)
                recipients.to.email.domain.valid eq "true"
              strings.icontains func_call "strings.icontains(body.links[].href_url.url)"
        any(body.links.href_url.query_params_decoded['domain'])
          or
            strings.parse_domain func_call "strings.parse_domain(body.links[].href_url.query_params_decoded['domain'][]).domain in~ free_file_hosts"
            strings.parse_domain func_call "strings.parse_domain(body.links[].href_url.query_params_decoded['domain'][]).domain in~ social_landing_hosts"
            strings.parse_domain func_call "strings.parse_domain(body.links[].href_url.query_params_decoded['domain'][]).domain in~ url_shorteners"
            strings.parse_domain func_call "strings.parse_domain(body.links[].href_url.query_params_decoded['domain'][]).root_domain in~ free_file_hosts"
            strings.parse_domain func_call "strings.parse_domain(body.links[].href_url.query_params_decoded['domain'][]).root_domain in~ free_subdomain_hosts"
            strings.parse_domain func_call "strings.parse_domain(body.links[].href_url.query_params_decoded['domain'][]).root_domain not in tranco_1m"
            strings.parse_domain func_call "strings.parse_domain(body.links[].href_url.query_params_decoded['domain'][]).tld == ru"
        and
          body.links.href_url.domain.sld eq "google"
          body.links.href_url.path starts_with "/amp/"
        body.links.href_url.domain.root_domain eq "beehiiv.com"
        body.links.href_url.domain.root_domain in ["hubspotlinks.com", "mandrillapp.com", "rs6.net", "sendgrid.net"]
        body.links.href_url.domain.tld eq "ru"
         macro "body.links[].href_url.domain.domain in free_file_hosts"
         macro "body.links[].href_url.domain.domain in social_landing_hosts"
         macro "body.links[].href_url.domain.domain in url_shorteners"
         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 not in tranco_1m"
      or
        not
          body.links.href_url.domain.root_domain in ["1drv.ms", "aka.ms", "microsoft.com", "microsoftproject.com", "msftauthimages.net", "office.com", "sharepoint.com", "svc.ms"]
        any(body.links)
           macro "body.links[].href_url.domain.domain in free_file_hosts"
      body.links.href_url.domain.valid eq "true"
       macro "body.links[].href_url.domain.root_domain not in org_domains"
  or
    any(attachments)
      and
        any(file.explode(attachments))
          and
            or
              file.explode(attachments[])[].scan.ocr.raw match "cache"
              file.explode(attachments[])[].scan.ocr.raw match "document"
              file.explode(attachments[])[].scan.ocr.raw match "fax"
              file.explode(attachments[])[].scan.ocr.raw match "messages"
              file.explode(attachments[])[].scan.ocr.raw match "password"
              file.explode(attachments[])[].scan.ocr.raw match "quota"
              file.explode(attachments[])[].scan.ocr.raw match "storage"
              file.explode(attachments[])[].scan.ocr.raw match "voicemail"
            or
              file.explode(attachments[])[].scan.ocr.raw match "clear"
              file.explode(attachments[])[].scan.ocr.raw match "click"
              file.explode(attachments[])[].scan.ocr.raw match "deleted"
              file.explode(attachments[])[].scan.ocr.raw match "exceed"
              file.explode(attachments[])[].scan.ocr.raw match "expire"
              file.explode(attachments[])[].scan.ocr.raw match "failed"
              file.explode(attachments[])[].scan.ocr.raw match "only works"
              file.explode(attachments[])[].scan.ocr.raw match "review"
              file.explode(attachments[])[].scan.ocr.raw match "terminated"
              file.explode(attachments[])[].scan.ocr.raw match "view"
         macro "attachments[].file_type in file_types_images"
    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 in ["high", "medium"]
              ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].name eq "cred_theft"
         macro "attachments[].file_type in file_types_images"
    and
      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 eq ""
    and
      or
        beta.ocr(file.message_screenshot()).text match "cache"
        beta.ocr(file.message_screenshot()).text match "document"
        beta.ocr(file.message_screenshot()).text match "fax"
        beta.ocr(file.message_screenshot()).text match "messages"
        beta.ocr(file.message_screenshot()).text match "password"
        beta.ocr(file.message_screenshot()).text match "quota"
        beta.ocr(file.message_screenshot()).text match "storage"
        beta.ocr(file.message_screenshot()).text match "voicemail"
      or
        beta.ocr(file.message_screenshot()).text match "clear"
        beta.ocr(file.message_screenshot()).text match "click"
        beta.ocr(file.message_screenshot()).text match "deleted"
        beta.ocr(file.message_screenshot()).text match "exceed"
        beta.ocr(file.message_screenshot()).text match "expire"
        beta.ocr(file.message_screenshot()).text match "failed"
        beta.ocr(file.message_screenshot()).text match "only works"
        beta.ocr(file.message_screenshot()).text match "renewal"
        beta.ocr(file.message_screenshot()).text match "revalidated"
        beta.ocr(file.message_screenshot()).text match "review"
        beta.ocr(file.message_screenshot()).text match "terminated"
        beta.ocr(file.message_screenshot()).text match "view"
    and
      or
        body.plain.raw match "cache"
        body.plain.raw match "document"
        body.plain.raw match "fax"
        body.plain.raw match "message"
        body.plain.raw match "password"
        body.plain.raw match "quota"
        body.plain.raw match "storage"
        body.plain.raw match "voicemail"
      or
        body.plain.raw match "clear"
        body.plain.raw match "click"
        body.plain.raw match "deleted"
        body.plain.raw match "exceed"
        body.plain.raw match "expire"
        body.plain.raw match "failed"
        body.plain.raw match "only works"
        body.plain.raw match "renewal"
        body.plain.raw match "revalidated"
        body.plain.raw match "review"
        body.plain.raw match "terminated"
        body.plain.raw match "view"
    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
      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
    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
      not
        strings.replace_confusables(body.current_thread.text) regex_match "office (for lease|rent|sale)"
      strings.replace_confusables(body.current_thread.text) regex_match "[\\n\\s]*[o0O]ff[il1]ce\\b.*"
    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 "<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 "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\\(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(ml.logo_detect(file.message_screenshot()).brands)
      ml.logo_detect(file.message_screenshot()).brands.name starts_with "Microsoft"
    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 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;\">"
    strings.replace_confusables(body.current_thread.text) starts_with "Microsoft "
  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
      attachments length_compare "0"
      sender.email.local_part in ["mailer-daemon", "postmaster"]
       macro "all(attachments)"
  not
    and
      attachments length_compare "6"
      filter(attachments, strings.istarts_with(.file_name, 'GuestWelcomeEmail')) length_compare "5"
      filter(body.links, .href_url.domain.domain not in ('outlook.office365.com', 'aka.ms', 'go.microsoft.com') and not .href_url.domain.domain == sender.email.domain.domain) length_compare "0"
      headers.auth_summary.dmarc.pass eq "true"
       macro "subject.subject == strings.replace_confusables(subject.subject)"
  not
    body.current_thread.text regex_match "(schedul(e|ing)|set up).{0,20}(call|meeting|demo|zoom|conversation|time|tool|discussion)|book.{0,10}(meeting|demo|call|slot|time)|connect.{0,12}(with me|phone|email)|my.{0,10}(calendar|cal)|reserve.{0,10}s[pl]ot|break the ice|want to know more?|miss your chance|if you no longer wish|if you no longer want|if you wish to opt out|low-code (development|approach|solution|journey|platform)|(?:invite|virtual).{0,30}(webinar|presentation)"
  or
    headers.in_reply_to is_null
    headers.references length_compare "0"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  not
    sender.email.domain.root_domain in ["bing.com", "microsoft.com", "microsoft365.com", "microsoftonline.com", "microsoftproject.com", "microsoftstoreemail.com", "microsoftsupport.com", "office.com", "office365.com", "onedrive.com", "sharepointonline.com", "yammer.com"]
  body.links length_compare "0"
  body.links length_compare "50"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
attachmentslength_compare0excludes:attachments field:"attachments" 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"
attachmentslength_compare6excludes:attachments field:"attachments" value:"6"
filter(attachments, strings.istarts_with(.file_name, 'GuestWelcomeEmail'))length_compare5excludes:filter(attachments, strings.istarts_with(.file_name, 'GuestWelcomeEmail')) field:"filter(attachments, strings.istarts_with(.file_name, 'GuestWelcomeEmail'))" value:"5"
filter(body.links, .href_url.domain.domain not in ('outlook.office365.com', 'aka.ms', 'go.microsoft.com') and not .href_url.domain.domain == sender.email.domain.domain)length_compare0excludes:filter(body.links, .href_url.domain.domain not in ('outlook.office365.com', 'aka.ms', 'go.microsoft.com') and not .href_url.domain.domain == sender.email.domain.domain) field:"filter(body.links, .href_url.domain.domain not in ('outlook.office365.com', 'aka.ms', 'go.microsoft.com') and not .href_url.domain.domain == sender.email.domain.domain)" value:"0"
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
body.current_thread.textregex_match(schedul(e|ing)|set up).{0,20}(call|meeting|demo|zoom|conversation|time|tool|discussion), book.{0,10}(meeting|demo|call|slot|time), connect.{0,12}(with me|phone|email), my.{0,10}(calendar|cal), reserve.{0,10}s[pl]ot, break the ice, want to know more?, miss your chance, if you no longer wish, if you no longer want, if you wish to opt out, low-code (development|approach|solution|journey|platform), (?:invite|virtual).{0,30}(webinar|presentation)excludes:body.current_thread.text
sender.email.domain.root_domaininbing.com, microsoft.com, microsoft365.com, microsoftonline.com, microsoftproject.com, microsoftstoreemail.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
beta.ocr(file.message_screenshot()).textwildcard
  • *cache*
  • *clear*
  • *click*
  • *deleted*
  • *document*
  • *exceed*
  • *expire*
  • *failed*
  • *fax*
  • *messages*
  • *only works*
  • *password*
  • *quota*
  • *renewal*
  • *revalidated*
  • *review*
  • *storage*
  • *terminated*
  • *view*
  • *voicemail*
field:"beta.ocr(file.message_screenshot()).text" kind:wildcard
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}
  • <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(217, 83, 51);">.{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>
  • 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((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(([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
body.plain.rawwildcard
  • *cache*
  • *clear*
  • *click*
  • *deleted*
  • *document*
  • *exceed*
  • *expire*
  • *failed*
  • *fax*
  • *message*
  • *only works*
  • *password*
  • *quota*
  • *renewal*
  • *revalidated*
  • *review*
  • *storage*
  • *terminated*
  • *view*
  • *voicemail*
field:"body.plain.raw" kind:wildcard
headers.in_reply_tois_null
  • (no value, null check)
field:"headers.in_reply_to" kind:is_null
strings.replace_confusables(body.current_thread.text)regex_match
  • [\n\s]*[o0O]ff[il1]ce\b.*
field:"strings.replace_confusables(body.current_thread.text)" kind:regex_match value:"[\n\s]*[o0O]ff[il1]ce\b.*"
strings.replace_confusables(body.current_thread.text)starts_with
  • Microsoft
field:"strings.replace_confusables(body.current_thread.text)" kind:starts_with value:"Microsoft "
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Catbox.moe link from untrusted source

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

Detects messages containing links to catbox.moe file hosting service from senders who either aren't in highly trusted domains or failed DMARC authentication

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware
Tactics and techniquesFree file host, 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 any(body.links,
        .href_url.domain.root_domain == "catbox.moe"
        and not strings.iends_with(.href_url.path, ".json")
)
// negate highly trusted sender domains unless they fail DMARC authentication
and (
  (
    sender.email.domain.root_domain in $high_trust_sender_root_domains
    and not coalesce(headers.auth_summary.dmarc.pass, false)
  )
  or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)

Detection logic

Scope: inbound message.

Detects messages containing links to catbox.moe file hosting service from senders who either aren't in highly trusted domains or failed DMARC authentication

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.domain.root_domain is 'catbox.moe'
    • not:
      • .href_url.path ends with '.json'
  3. any of:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • not:
        • coalesce(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, body.links[].href_url.path, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: strings.iends_with. Reference lists: $high_trust_sender_root_domains.

Indicators matched (1)

FieldMatchValue
body.links[].href_url.domain.root_domainequalscatbox.moe

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      not
        body.links.href_url.path ends_with ".json"
      body.links.href_url.domain.root_domain eq "catbox.moe"
  or
    and
      not
        coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       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"
  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"

Commonly abused sender TLD with engaging language

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

Message is from a commonly abused sender TLD, contains various suspicious indicators resembling credential theft, and is unsolicited.

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.links
  • headers
  • headers.auth_summary
  • recipients
  • recipients.to
  • sender.email
  • subject
  • type

Rule body

type.inbound

// we don't do a suspicious link check here
// because we are seeing abuse of mass marketing tools
// like campaign[.]adobe[.]com
// once we roll out better support for unfurling those,
// we can update this logic
and length(body.links) > 0

// commonly abused sender TLD
and strings.ilike(sender.email.domain.tld, "*.jp")
and 3 of (
  // language attempting to engage
  any(ml.nlu_classifier(body.current_thread.text).entities, .name == "request"),

  // financial request
  any(ml.nlu_classifier(body.current_thread.text).entities,
      .name == "financial"
  ),

  // urgency request
  any(ml.nlu_classifier(body.current_thread.text).entities, .name == "urgency"),

  // known suspicious pattern in the URL path
  any(body.links, regex.match(.href_url.path, '\/[a-z]{3}\d[a-z]')),

  // suspicious image that's most likely cred_theft
  any(attachments,
      .file_type in $file_types_images
      and any(file.explode(.),
              any(ml.nlu_classifier(.scan.ocr.raw).intents,
                  .name == "cred_theft"
              )
              or any(ml.nlu_classifier(.scan.ocr.raw).entities,
                     .name == "financial"
              )
      )
  ),

  // recipient's SLD is in the sender's display name
  any(recipients.to,
      strings.icontains(sender.display_name, .email.domain.sld)
      and (
        .email.domain.valid or strings.icontains(.display_name, "undisclosed")
      )
  ),

  // recipient's email address in the subject
  any(recipients.to,
      strings.icontains(subject.subject, .email.email)
      and (
        .email.domain.valid or strings.icontains(.display_name, "undisclosed")
      )
  ),
)
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 sender.email.domain.root_domain in ("amazon.co.jp")
// 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.

Message is from a commonly abused sender TLD, contains various suspicious indicators resembling credential theft, and is unsolicited.

  1. inbound message
  2. length(body.links) > 0
  3. sender.email.domain.tld matches '*.jp'
  4. at least 3 of:
    • 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 'financial'
    • any of ml.nlu_classifier(body.current_thread.text).entities where:
      • .name is 'urgency'
    • any of body.links where:
      • .href_url.path matches '\\/[a-z]{3}\\d[a-z]'
    • any of attachments where all hold:
      • .file_type in $file_types_images
      • any of file.explode(.) where any holds:
        • any of ml.nlu_classifier(.scan.ocr.raw).intents where:
          • .name is 'cred_theft'
        • any of ml.nlu_classifier(.scan.ocr.raw).entities where:
          • .name is 'financial'
    • any of recipients.to where all hold:
      • strings.icontains(sender.display_name)
      • any of:
        • .email.domain.valid
        • .display_name contains 'undisclosed'
    • any of recipients.to where all hold:
      • strings.icontains(subject.subject)
      • any of:
        • .email.domain.valid
        • .display_name contains 'undisclosed'
  5. any of:
    • not:
      • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  6. not:
    • sender.email.domain.root_domain in ('amazon.co.jp')
  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: attachments[].file_type, body.current_thread.text, body.links, body.links[].href_url.path, headers.auth_summary.dmarc.pass, 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.root_domain, sender.email.domain.tld, subject.subject, type.inbound. Sensors: file.explode, ml.nlu_classifier, profile.by_sender, regex.match, strings.icontains, strings.ilike. Reference lists: $file_types_images, $high_trust_sender_root_domains.

Indicators matched (8)

FieldMatchValue
strings.ilikesubstring*.jp
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsrequest
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsfinancial
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsurgency
regex.matchregex\/[a-z]{3}\d[a-z]
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].nameequalscred_theft
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).entities[].nameequalsfinancial
strings.icontainssubstringundisclosed

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(attachments)
      and
        any(file.explode(attachments))
          or
            any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).entities)
              ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).entities.name eq "financial"
            any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).intents)
              ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).intents.name eq "cred_theft"
         macro "attachments[].file_type in file_types_images"
    any(recipients.to)
      and
        or
          recipients.to.display_name contains "undisclosed"
          recipients.to.email.domain.valid eq "true"
        strings.icontains func_call "strings.icontains(sender.display_name)"
    any(recipients.to)
      and
        or
          recipients.to.display_name contains "undisclosed"
          recipients.to.email.domain.valid eq "true"
        strings.icontains func_call "strings.icontains(subject.subject)"
    any(body.links)
      body.links.href_url.path regex_match "\\/[a-z]{3}\\d[a-z]"
    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 "urgency"
  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
    sender.email.domain.root_domain eq "amazon.co.jp"
  body.links length_compare "0"
  sender.email.domain.tld ends_with ".jp"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaineqamazon.co.jpexcludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"amazon.co.jp"

Indicators

These rows show field, operator, and value matches.

Credential phishing content and link (untrusted sender)

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

Message contains credential theft language and a link to a credential phishing page from an unknown sender. We use Link Analysis in aggressive mode to increase our chances of scanning.

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.links
  • headers
  • headers.auth_summary
  • headers.hops
  • recipients
  • recipients.to
  • recipients.to[0]
  • sender.email
  • type

Rule body

type.inbound
and (
  any(ml.nlu_classifier(body.current_thread.text).intents,
      .name == "cred_theft" and .confidence in ("medium", "high")
  )
  // embedded in an image attachment
  // note: don't use message_screenshot() for now
  // because it's not limited to current_thread and may FP
  or 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 in ("medium", "high")
                 )
         )
  )
)
and any(body.links,
        .href_url.domain.root_domain not in ("outlook.com")
        and .href_url.domain.domain != "play.google.com"
        and ml.link_analysis(., mode="aggressive").effective_url.domain.domain != "play.google.com"
        and ml.link_analysis(., mode="aggressive").credphish.disposition == "phishing"
        and (
          ml.link_analysis(., mode="aggressive").credphish.confidence in (
            "medium",
            "high"
          )
          or ml.link_analysis(., mode="aggressive").credphish.contains_captcha
        )
        and not .href_url.domain.root_domain == "c3reservations.com"
)
and (
  (
    profile.by_sender_email().prevalence in ("new", "outlier")
    and not profile.by_sender_email().solicited
  )
  or (
    profile.by_sender_email().any_messages_malicious_or_spam
    and not profile.by_sender_email().any_messages_benign
  )
  // or there are no recipients
  or length(recipients.to) == 0
  // or the recipients are all invalid 
  or all(recipients.to, .email.domain.valid == false)

  // or the sender exhibits a "self sender" pattern
  or (
    length(recipients.to) == 1
    and recipients.to[0].email.email == sender.email.email
  )
)

// negate docusign 'via' messages
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")
)

// negate docusign originated emails
and not any(headers.hops,
            regex.imatch(.received.server.raw, '.+\.docusign.(?:net|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.

Message contains credential theft language and a link to a credential phishing page from an unknown sender. We use Link Analysis in aggressive mode to increase our chances of scanning.

  1. inbound message
  2. any of:
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'cred_theft'
      • .confidence in ('medium', 'high')
    • 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 in ('medium', 'high')
  3. any of body.links where all hold:
    • .href_url.domain.root_domain not in ('outlook.com')
    • .href_url.domain.domain is not 'play.google.com'
    • ml.link_analysis(.).effective_url.domain.domain is not 'play.google.com'
    • ml.link_analysis(.).credphish.disposition is 'phishing'
    • any of:
      • ml.link_analysis(.).credphish.confidence in ('medium', 'high')
      • ml.link_analysis(.).credphish.contains_captcha
    • not:
      • .href_url.domain.root_domain is 'c3reservations.com'
  4. any of:
    • all of:
      • profile.by_sender_email().prevalence in ('new', 'outlier')
      • not:
        • profile.by_sender_email().solicited
    • all of:
      • profile.by_sender_email().any_messages_malicious_or_spam
      • not:
        • profile.by_sender_email().any_messages_benign
    • length(recipients.to) is 0
    • all of recipients.to where:
      • .email.domain.valid is False
    • all of:
      • length(recipients.to) is 1
      • recipients.to[0].email.email is sender.email.email
  5. 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'
  6. not:
    • any of headers.hops where:
      • .received.server.raw matches '.+\\.docusign.(?:net|com)'
  7. 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.links, body.links[].href_url.domain.domain, 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.hops[].received.server.raw, recipients.to, recipients.to[0].email.email, recipients.to[].email.domain.valid, sender.display_name, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: file.explode, ml.link_analysis, ml.nlu_classifier, profile.by_sender_email, regex.imatch, strings.contains, strings.ends_with. Reference lists: $file_types_images, $high_trust_sender_root_domains.

Indicators matched (6)

FieldMatchValue
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(file.explode(attachments[])[].scan.ocr.raw).intents[].nameequalscred_theft
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidencemembermedium
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidencememberhigh

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 in ["high", "medium"]
              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 in ["high", "medium"]
        ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
  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"
  any(body.links)
    and
      not
        body.links.href_url.domain.root_domain eq "c3reservations.com"
      not
        body.links.href_url.domain.root_domain eq "outlook.com"
      or
        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.contains_captcha"
      body.links.href_url.domain.domain ne "play.google.com"
      ml.link_analysis func_call "ml.link_analysis(body.links[]).credphish.disposition == phishing"
      ml.link_analysis func_call "ml.link_analysis(body.links[]).effective_url.domain.domain != play.google.com"
  or
    and
      not
        profile.by_sender_email func_call "profile.by_sender_email().any_messages_benign"
      profile.by_sender_email func_call "profile.by_sender_email().any_messages_malicious_or_spam"
    and
      not
        profile.by_sender_email func_call "profile.by_sender_email().solicited"
      profile.by_sender_email func_call "profile.by_sender_email().prevalence in (new, outlier)"
    and
      recipients.to length_compare "1"
      recipients.to[0].email.email cross_field_compare "sender.email.email"
    recipients.to length_compare "0"
     macro "all(recipients.to)"
  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(headers.hops)
      headers.hops.received.server.raw regex_match ".+\\.docusign.(?:net|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"

Indicators

These rows show field, operator, and value matches.

Credential phishing language and suspicious indicators (unknown sender)

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

Message contains various suspicious indicators as well as engaging language resembling credential theft from an unknown sender.

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

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

Rule body

type.inbound
and (
  any(ml.nlu_classifier(body.current_thread.text).intents,
      .name == "cred_theft" and .confidence in ("medium", "high")
  )
  // embedded in an image attachment
  // note: don't use message_screenshot()
  // because it's not limited to current_thread and may FP
  or 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 == "high"
                 )
         )
  )
)
and 4 of (
  // impersonation of the recipient's domain or email address
  // in the subject to make it look more personalized
  any(recipients.to,
      (
        strings.icontains(subject.subject, .email.local_part)
        or strings.icontains(subject.subject, .email.domain.sld)
      )
      and (
        .email.domain.valid or strings.icontains(.display_name, "undisclosed")
      )
  ),
  // recipient's email address in the body. this is not very uncommon
  // for legit credential themed messages either
  any(recipients.to,
      (.email.domain.valid or strings.icontains(.display_name, "undisclosed"))
      and strings.icontains(body.current_thread.text, .email.email)
  ),
  ( // page contains turnstile captcha 
    any(body.links,
        strings.icontains(ml.link_analysis(., mode="aggressive").final_dom.raw,
                          'https://challenges.cloudflare.com/turnstile/',
        )
    )
  ),
  (
    // freemail providers should never be sending this type of email
    sender.email.domain.domain in $free_email_providers

    // if not freemail, it's suspicious if the sender's root domain
    // doesn't match any links in the body
    or (
      length(body.links) > 0
      and all(body.links,
              .href_url.domain.root_domain != sender.email.domain.root_domain
      )
    )
  ),
  strings.contains(body.current_thread.text,
                   "Your mailbox can no longer send or receive messages."
  ),
  // link redirects to a suspicious TLD
  any(body.links,
      any(ml.link_analysis(., mode="aggressive").redirect_history,
          .domain.tld in $suspicious_tlds
      )
  ),
  (
    // suspicious redirects
    // 3 or more different domains with 2 or more different TLDs
    // careful because click trackers will always make this at least 2
    // different domains and not unlikely 2 or more TLDs
    any(body.links,
        length(distinct(map(ml.link_analysis(., mode="aggressive").redirect_history,
                            .domain.tld
                        )
               )
        ) >= 2
        and length(distinct(map(ml.link_analysis(., mode="aggressive").redirect_history,
                                .domain.domain
                            )
                   )
        ) >= 3
    )
  ),
// maybe: any brand logo with high confidence
// maybe: recipients BCCd or undisclosed
)
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
  )
)

// negating Google Calendar invites
and (
  (
    (
      length(attachments) > 0
      and not all(attachments,
                  .content_type in ("text/calendar", "application/ics")
      )
    )
    and not (
      any(distinct(headers.hops, .authentication_results.dmarc is null),
          strings.ilike(.authentication_results.dmarc, "*pass")
          and strings.ilike(.authentication_results.spf_details.designator,
                            "*calendar-server.bounces.google.com"
          )
      )
    )
  )
  or length(attachments) == 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
)

Detection logic

Scope: inbound message.

Message contains various suspicious indicators as well as engaging language resembling credential theft from an unknown sender.

  1. inbound message
  2. any of:
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'cred_theft'
      • .confidence in ('medium', 'high')
    • 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 'high'
  3. at least 4 of:
    • any of recipients.to where all hold:
      • any of:
        • strings.icontains(subject.subject)
        • strings.icontains(subject.subject)
      • any of:
        • .email.domain.valid
        • .display_name contains 'undisclosed'
    • any of recipients.to where all hold:
      • any of:
        • .email.domain.valid
        • .display_name contains 'undisclosed'
      • strings.icontains(body.current_thread.text)
    • any of body.links where:
      • ml.link_analysis(., mode='aggressive').final_dom.raw contains 'https://challenges.cloudflare.com/turnstile/'
    • any of:
      • sender.email.domain.domain in $free_email_providers
      • all of:
        • length(body.links) > 0
        • all of body.links where:
          • .href_url.domain.root_domain is not sender.email.domain.root_domain
    • body.current_thread.text contains 'Your mailbox can no longer send or receive messages.'
    • any of body.links where:
      • any of ml.link_analysis(., mode='aggressive').redirect_history where:
        • .domain.tld in $suspicious_tlds
    • any of body.links where all hold:
      • length(distinct(map(ml.link_analysis(., mode='aggressive').redirect_history, .domain.tld))) ≥ 2
      • length(distinct(map(ml.link_analysis(., mode='aggressive').redirect_history, .domain.domain))) ≥ 3
  4. 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
  5. any of:
    • all of:
      • all of:
        • length(attachments) > 0
        • not:
          • all of attachments where:
            • .content_type in ('text/calendar', 'application/ics')
      • not:
        • any of distinct(headers.hops) where all hold:
          • .authentication_results.dmarc matches '*pass'
          • .authentication_results.spf_details.designator matches '*calendar-server.bounces.google.com'
    • length(attachments) is 0
  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_type, body.current_thread.text, body.links, body.links[].href_url.domain.root_domain, headers.auth_summary.dmarc.pass, headers.hops, headers.hops[].authentication_results.dmarc, recipients.to, recipients.to[].display_name, recipients.to[].email.domain.sld, recipients.to[].email.domain.valid, recipients.to[].email.email, recipients.to[].email.local_part, sender.email.domain.domain, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: file.explode, ml.link_analysis, ml.nlu_classifier, profile.by_sender, strings.contains, strings.icontains, strings.ilike. Reference lists: $file_types_images, $free_email_providers, $high_trust_sender_root_domains, $suspicious_tlds.

Indicators matched (8)

FieldMatchValue
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(file.explode(attachments[])[].scan.ocr.raw).intents[].nameequalscred_theft
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidenceequalshigh
strings.icontainssubstringundisclosed
strings.icontainssubstringhttps://challenges.cloudflare.com/turnstile/
strings.containssubstringYour mailbox can no longer send or receive messages.

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 eq "high"
              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 in ["high", "medium"]
        ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
  or
    and
      not
        any(distinct(headers.hops))
          and
            distinct(headers.hops).authentication_results.dmarc ends_with "pass"
            distinct(headers.hops).authentication_results.spf_details.designator ends_with "calendar-server.bounces.google.com"
      not
         macro "all(attachments)"
      attachments length_compare "0"
    attachments length_compare "0"
  or
    any(recipients.to)
      and
        or
          recipients.to.display_name contains "undisclosed"
          recipients.to.email.domain.valid eq "true"
        strings.icontains func_call "strings.icontains(body.current_thread.text)"
    any(recipients.to)
      and
        or
          recipients.to.display_name contains "undisclosed"
          recipients.to.email.domain.valid eq "true"
        strings.icontains func_call "strings.icontains(subject.subject)"
    any(body.links)
      and
        distinct(map(ml.link_analysis(body.links[], mode='aggressive').redirect_history, body.links[].domain.domain)) length_compare "3"
        distinct(map(ml.link_analysis(body.links[], mode='aggressive').redirect_history, body.links[].domain.tld)) length_compare "2"
    any(body.links)
      any(ml.link_analysis(body.links, mode='aggressive').redirect_history)
         macro "ml.link_analysis(body.links[], mode='aggressive').redirect_history[].domain.tld in suspicious_tlds"
    and
      body.links length_compare "0"
       macro "all(body.links)"
    any(body.links)
      ml.link_analysis(body.links[], mode='aggressive').final_dom.raw contains "https://challenges.cloudflare.com/turnstile/"
    body.current_thread.text contains "Your mailbox can no longer send or receive messages."
     macro "sender.email.domain.domain in free_email_providers"
  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 in (new, outlier)"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Credential phishing link (unknown sender)

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

Message contains a link to a credential phishing page from an unknown sender.

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

Rule body

type.inbound
and 0 < length(body.links) < 10
and any(body.links,
        ml.link_analysis(.).credphish.disposition == "phishing"
        and (
          ml.link_analysis(.).credphish.confidence in ("medium", "high")
          or ml.link_analysis(.).credphish.contains_captcha
        )
        and length(ml.link_analysis(.).final_dom.links) < 50
        // negate legitimate use of Google reCAPTCHA embedded badge
        and not (
          (
            ml.link_analysis(.).credphish.brand.name == "Captcha"
            or ml.link_analysis(.).credphish.contains_captcha
          )
          and length(html.xpath(ml.link_analysis(.).final_dom,
                                "//div[@class='grecaptcha-badge' and @data-style='bottomright']"
                     ).nodes
          ) == 1
        )
)
and (
  (
    not profile.by_sender().solicited
    and profile.by_sender().prevalence != "common"
  )
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)
// negate legit replies threads
and not (
  (
    strings.istarts_with(subject.subject, "RE:")
    // out of office auto-reply
    or strings.istarts_with(subject.subject, "Automatic reply:")
  )
  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
)

// exclude bounce backs & read receipts
and not strings.like(sender.email.local_part,
                     "*postmaster*",
                     "*mailer-daemon*",
                     "*administrator*"
)
and not regex.icontains(subject.subject, "^(undeliverable|read:)")
and not any(attachments, .content_type == "message/delivery-status")
// if the "References" is in the body of the message, it's probably a bounce
and not any(headers.references, strings.contains(body.html.display_text, .))
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

Message contains a link to a credential phishing page from an unknown sender.

  1. inbound message
  2. all of:
    • length(body.links) > 0
    • length(body.links) < 10
  3. any of body.links where all hold:
    • ml.link_analysis(.).credphish.disposition is 'phishing'
    • any of:
      • ml.link_analysis(.).credphish.confidence in ('medium', 'high')
      • ml.link_analysis(.).credphish.contains_captcha
    • length(ml.link_analysis(.).final_dom.links) < 50
    • not:
      • all of:
        • any of:
          • ml.link_analysis(.).credphish.brand.name is 'Captcha'
          • ml.link_analysis(.).credphish.contains_captcha
        • length(html.xpath(ml.link_analysis(.).final_dom, "//div[@class='grecaptcha-badge' and @data-style='bottomright']").nodes) is 1
  4. any of:
    • all of:
      • not:
        • profile.by_sender().solicited
      • profile.by_sender().prevalence is not 'common'
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  5. not:
    • all of:
      • any of:
        • subject.subject starts with 'RE:'
        • subject.subject starts with 'Automatic reply:'
      • any of:
        • length(headers.references) > 0
        • headers.in_reply_to is set
  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:
    • sender.email.local_part matches any of 3 patterns
      • *postmaster*
      • *mailer-daemon*
      • *administrator*
  8. not:
    • subject.subject matches '^(undeliverable|read:)'
  9. not:
    • any of attachments where:
      • .content_type is 'message/delivery-status'
  10. not:
    • any of headers.references where:
      • strings.contains(body.html.display_text)
  11. not:
    • profile.by_sender().any_messages_benign

Inspects: attachments[].content_type, body.html.display_text, body.links, headers.auth_summary.dmarc.pass, headers.in_reply_to, headers.references, sender.email.domain.root_domain, sender.email.local_part, subject.subject, type.inbound. Sensors: html.xpath, ml.link_analysis, profile.by_sender, regex.icontains, strings.contains, strings.istarts_with, strings.like. Reference lists: $high_trust_sender_root_domains.

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      not
        and
          or
            ml.link_analysis func_call "ml.link_analysis(body.links[]).credphish.brand.name == Captcha"
            ml.link_analysis func_call "ml.link_analysis(body.links[]).credphish.contains_captcha"
          html.xpath(ml.link_analysis(body.links[]).final_dom, "//div[@class='grecaptcha-badge' and @data-style='bottomright']").nodes length_compare "1"
      or
        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.contains_captcha"
      ml.link_analysis func_call "ml.link_analysis(body.links[]).credphish.disposition == phishing"
      ml.link_analysis(body.links[]).final_dom.links length_compare "50"
  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.subject starts_with "Automatic reply:"
        subject.subject starts_with "RE:"
  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"
  not
    any(attachments)
      attachments.content_type eq "message/delivery-status"
  not
    or
      sender.email.local_part match "administrator"
      sender.email.local_part match "mailer-daemon"
      sender.email.local_part match "postmaster"
  not
    any(headers.references)
      strings.contains func_call "strings.contains(body.html.display_text)"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  not
    subject.subject regex_match "^(undeliverable|read:)"
  body.links length_compare "0"
  body.links length_compare "10"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
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.subjectstarts_withAutomatic reply:excludes:subject.subject field:"subject.subject" value:"Automatic reply:"
subject.subjectstarts_withRE:excludes:subject.subject field:"subject.subject" value:"RE:"
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"
headers.referencesarray_any(no value, null check)excludes:headers.references
subject.subjectregex_match^(undeliverable|read:)excludes:subject.subject field:"subject.subject" value:"^(undeliverable|read:)"

Indicators

These rows show field, operator, and value matches.

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

Credential phishing: 'Secure message' and engaging language

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

Body contains language resembling credential theft, and a "secure message" from an untrusted sender.

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.links
  • body.previous_threads
  • headers
  • headers.auth_summary
  • headers.domains
  • headers.hops
  • recipients
  • recipients.to
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  (
    any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft" and .confidence == "high"
    )
    or any(body.current_thread.links,
           regex.icontains(.display_text, '(?:read|view|open) the message')
           and (
             .href_url.domain.root_domain not in $tranco_1m
             or .href_url.domain.domain in $free_file_hosts
             or .href_url.domain.root_domain in $free_file_hosts
             or .href_url.domain.root_domain in $free_subdomain_hosts
             or .href_url.domain.domain in $url_shorteners
             or .href_url.domain.domain in $social_landing_hosts
           )
    )
  )
  or any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents,
         .name == "cred_theft" and .confidence in ("medium", "high")
  )
)
and (
  (
    regex.icontains(body.current_thread.text,
                    "secured? (message|directory|document|file)"
    )
    or regex.icontains(subject.base,
                       "secured? (message|directory|document|file)"
    )
    or strings.icontains(body.current_thread.text, "document portal")
    or strings.icontains(body.current_thread.text, "encrypted message")
    or strings.icontains(body.current_thread.text, "protected message")
  )
  or any(body.previous_threads,
         regex.icontains(.text, "secured? (message|directory|document|file)")
         or strings.icontains(.text, "document portal")
         or strings.icontains(.text, "encrypted message")
         or strings.icontains(.text, "protected message")
  )
  or any(body.current_thread.links,
         regex.icontains(ml.link_analysis(.).final_dom.display_text,
                         'secured? (?:message|directory|document|file) access'
         )
         or regex.icontains(ml.link_analysis(.).final_dom.inner_text,
                            'secured? (?:message|directory|document|file) access'
         )
  )
  or (
    length(filter(ml.nlu_classifier(body.current_thread.text).entities,
                  .name == "urgency"
           )
    ) >= 2
    and any(ml.nlu_classifier(body.current_thread.text).topics,
            .name == "Secure Message" and .confidence != "low"
    )
  )
)
// has at least 1 link
and length(body.links) > 0

// negate legitimate message senders
and (
  sender.email.domain.root_domain not in ("protectedtrust.com")
  and any(body.links,
          .href_url.domain.root_domain != sender.email.domain.root_domain
  )
  // negate known secure mailers
  and not all(body.links,
              .href_url.domain.root_domain in (
                "mimecast.com",
                "cisco.com",
                "csiesafe.com"
              )
  )
  and any(headers.hops,
          .index == 0
          and not any(.fields,
                      strings.contains(.value,
                                       'multipart/mixed; boundary="PROOFPOINT_BOUNDARY_1"'
                      )
          )
  )
  and not (
    length(filter(attachments,
                  strings.ilike(.file_name,
                                "logo.*",
                                "lock.gif",
                                "SecureMessageAtt.html"
                  )
           )
    ) == 3
    and any(attachments,
            .file_type == "html"
            and any(file.explode(.),
                    .scan.html.title == "Proofpoint Encryption"
                    and any(.scan.url.urls,
                            strings.iends_with(.path,
                                               'formpostdir/safeformpost.aspx'
                            )
                    )
            )
            and strings.count(file.parse_html(.).raw, 'name="msg') > 3
    )
  )
  and not (
    any(headers.hops,
        any(.fields,
            .name in (
              'X-ZixNet',
              'X-VPM-MIV',
              'X-VPM-ActionCode',
              'X-VPM-SmtpTo'
            )
        )
    )
    and any(headers.domains,
            .root_domain in (
              "zixport.com",
              "zixcorp.com",
              "zixmail.net",
              "zixworks.com"
            )
    )
  )
  and not (
    any(headers.hops, any(.fields, .name == 'X-SendInc-Message-Id'))
    and any(headers.domains, .root_domain in ("sendinc.net"))
  )
  // negating Mimecast sends with MS banner and/or sender's email pulled out as a link
  and not length(filter(body.links,
                        (
                          .display_text is null
                          and .display_url.url == sender.email.domain.root_domain
                        )
                        or .href_url.domain.root_domain in (
                          "aka.ms",
                          "mimecast.com",
                          "cisco.com"
                        )
                 )
  ) == length(body.links)
)
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
  )
  // or the sender is all undisclosed or there are no recipients
  or (
    length(recipients.to) == 0
    or all(recipients.to,
           strings.ilike(.display_name, "undisclosed?recipients")
    )
  )
  // or the sender exhibits a "self sender" pattern
  or (
    length(recipients.to) == 1
    and any(recipients.to, .email.email == sender.email.email)
  )
)
and not profile.by_sender().any_messages_benign
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.

Body contains language resembling credential theft, and a "secure message" from an untrusted sender.

  1. inbound message
  2. 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 body.current_thread.links where all hold:
        • .display_text matches '(?:read|view|open) the message'
        • any of:
          • .href_url.domain.root_domain not in $tranco_1m
          • .href_url.domain.domain in $free_file_hosts
          • .href_url.domain.root_domain in $free_file_hosts
          • .href_url.domain.root_domain in $free_subdomain_hosts
          • .href_url.domain.domain in $url_shorteners
          • .href_url.domain.domain in $social_landing_hosts
    • any of ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents where all hold:
      • .name is 'cred_theft'
      • .confidence in ('medium', 'high')
  3. any of:
    • any of:
      • body.current_thread.text matches 'secured? (message|directory|document|file)'
      • subject.base matches 'secured? (message|directory|document|file)'
      • body.current_thread.text contains 'document portal'
      • body.current_thread.text contains 'encrypted message'
      • body.current_thread.text contains 'protected message'
    • any of body.previous_threads where any holds:
      • .text matches 'secured? (message|directory|document|file)'
      • .text contains 'document portal'
      • .text contains 'encrypted message'
      • .text contains 'protected message'
    • any of body.current_thread.links where any holds:
      • ml.link_analysis(.).final_dom.display_text matches 'secured? (?:message|directory|document|file) access'
      • ml.link_analysis(.).final_dom.inner_text matches 'secured? (?:message|directory|document|file) access'
    • all of:
      • length(filter(ml.nlu_classifier(body.current_thread.text).entities, .name == 'urgency')) ≥ 2
      • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
        • .name is 'Secure Message'
        • .confidence is not 'low'
  4. length(body.links) > 0
  5. all of:
    • sender.email.domain.root_domain not in ('protectedtrust.com')
    • any of body.links where:
      • .href_url.domain.root_domain is not sender.email.domain.root_domain
    • not:
      • all of body.links where:
        • .href_url.domain.root_domain in ('mimecast.com', 'cisco.com', 'csiesafe.com')
    • any of headers.hops where all hold:
      • .index is 0
      • not:
        • any of .fields where:
          • .value contains 'multipart/mixed; boundary="PROOFPOINT_BOUNDARY_1"'
    • not:
      • all of:
        • length(filter(attachments, strings.ilike(.file_name, 'logo.*', 'lock.gif', 'SecureMessageAtt.html'))) is 3
        • any of attachments where all hold:
          • .file_type is 'html'
          • any of file.explode(.) where all hold:
            • .scan.html.title is 'Proofpoint Encryption'
            • any of .scan.url.urls where:
              • .path ends with 'formpostdir/safeformpost.aspx'
          • strings.count(file.parse_html(.).raw, 'name="msg') > 3
    • not:
      • all of:
        • any of headers.hops where:
          • any of .fields where:
            • .name in ('X-ZixNet', 'X-VPM-MIV', 'X-VPM-ActionCode', 'X-VPM-SmtpTo')
        • any of headers.domains where:
          • .root_domain in ('zixport.com', 'zixcorp.com', 'zixmail.net', 'zixworks.com')
    • not:
      • all of:
        • any of headers.hops where:
          • any of .fields where:
            • .name is 'X-SendInc-Message-Id'
        • any of headers.domains where:
          • .root_domain in ('sendinc.net')
    • not:
      • length(filter(body.links, .display_text is null and .display_url.url == sender.email.domain.root_domain or .href_url.domain.root_domain in ('aka.ms', 'mimecast.com', 'cisco.com'))) is length(body.links)
  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
    • any of:
      • length(recipients.to) is 0
      • all of recipients.to where:
        • .display_name matches 'undisclosed?recipients'
    • all of:
      • length(recipients.to) is 1
      • any of recipients.to where:
        • .email.email is sender.email.email
  7. not:
    • profile.by_sender().any_messages_benign
  8. not:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • coalesce(headers.auth_summary.dmarc.pass)

Inspects: attachments[].file_name, attachments[].file_type, body.current_thread.links, body.current_thread.links[].display_text, body.current_thread.links[].href_url.domain.domain, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.text, body.links, body.links[].display_text, body.links[].display_url.url, body.links[].href_url.domain.root_domain, body.previous_threads, body.previous_threads[].text, headers.auth_summary.dmarc.pass, headers.domains, headers.domains[].root_domain, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, headers.hops[].index, recipients.to, recipients.to[].display_name, recipients.to[].email.email, sender.email.domain.root_domain, sender.email.email, subject.base, type.inbound. Sensors: beta.ocr, file.explode, file.message_screenshot, file.parse_html, ml.link_analysis, ml.nlu_classifier, profile.by_sender, regex.icontains, strings.contains, strings.count, strings.icontains, strings.iends_with, strings.ilike. Reference lists: $free_file_hosts, $free_subdomain_hosts, $high_trust_sender_root_domains, $social_landing_hosts, $tranco_1m, $url_shorteners.

Indicators matched (14)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh
regex.icontainsregex(?:read|view|open) the message
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
regex.icontainsregexsecured? (message|directory|document|file)
strings.icontainssubstringdocument portal
strings.icontainssubstringencrypted message
strings.icontainssubstringprotected message
regex.icontainsregexsecured? (?:message|directory|document|file) access
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsurgency
2 more
ml.nlu_classifier(body.current_thread.text).topics[].nameequalsSecure Message
strings.ilikesubstringundisclosed?recipients

Stages and Predicates

Stage 1: mql_rule

and
  not
    and
      any(attachments)
        and
          any(file.explode(attachments))
            and
              any(file.explode(attachments).scan.url.urls)
                file.explode(attachments).scan.url.urls.path ends_with "formpostdir/safeformpost.aspx"
              file.explode(attachments[])[].scan.html.title eq "Proofpoint Encryption"
          attachments.file_type eq "html"
          strings.count func_call "strings.count(file.parse_html(attachments[]).raw, \"name=\"msg\") > 3"
      filter(attachments, strings.ilike(.file_name, 'logo.*', 'lock.gif', 'SecureMessageAtt.html')) length_compare "3"
  not
    and
      any(headers.hops)
        any(headers.hops.fields)
          headers.hops.fields.name eq "X-SendInc-Message-Id"
      any(headers.domains)
        headers.domains.root_domain eq "sendinc.net"
  not
    and
      any(headers.hops)
        any(headers.hops.fields)
          headers.hops.fields.name in ["X-VPM-ActionCode", "X-VPM-MIV", "X-VPM-SmtpTo", "X-ZixNet"]
      any(headers.domains)
        headers.domains.root_domain in ["zixcorp.com", "zixmail.net", "zixport.com", "zixworks.com"]
  any(headers.hops)
    and
      not
        any(headers.hops.fields)
          headers.hops.fields.value contains "multipart/mixed; boundary=\"PROOFPOINT_BOUNDARY_1\""
      headers.hops.index eq "0"
  or
    and
      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 "Secure Message"
      filter(ml.nlu_classifier(body.current_thread.text).entities, .name == 'urgency') length_compare "2"
    any(body.previous_threads)
      or
        body.previous_threads.text contains "document portal"
        body.previous_threads.text contains "encrypted message"
        body.previous_threads.text contains "protected message"
        body.previous_threads.text regex_match "secured? (message|directory|document|file)"
    any(body.current_thread.links)
      or
        ml.link_analysis(body.current_thread.links[]).final_dom.display_text regex_match "secured? (?:message|directory|document|file) access"
        ml.link_analysis(body.current_thread.links[]).final_dom.inner_text regex_match "secured? (?:message|directory|document|file) access"
    body.current_thread.text contains "document portal"
    body.current_thread.text contains "encrypted message"
    body.current_thread.text contains "protected message"
    body.current_thread.text regex_match "secured? (message|directory|document|file)"
    subject.base regex_match "secured? (message|directory|document|file)"
  or
    any(body.current_thread.links)
      and
        or
           macro "body.current_thread.links[].href_url.domain.domain in free_file_hosts"
           macro "body.current_thread.links[].href_url.domain.domain in social_landing_hosts"
           macro "body.current_thread.links[].href_url.domain.domain in url_shorteners"
           macro "body.current_thread.links[].href_url.domain.root_domain in free_file_hosts"
           macro "body.current_thread.links[].href_url.domain.root_domain in free_subdomain_hosts"
           macro "body.current_thread.links[].href_url.domain.root_domain not in tranco_1m"
        body.current_thread.links.display_text regex_match "(?:read|view|open) the message"
    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"
    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"
  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)"
    and
      any(recipients.to)
        recipients.to.email.email cross_field_compare "sender.email.email"
      recipients.to length_compare "1"
    recipients.to length_compare "0"
     macro "all(recipients.to)"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
  any(body.links)
    body.links.href_url.domain.root_domain cross_field_compare "sender.email.domain.root_domain"
  not
    length func_call "length(filter(body.links, .display_text is null and .display_url.url == sender.email.domain.root_domain or .href_url.domain.root_domain in ('aka.ms', 'mimecast.com', 'cisco.com'))) == length(body.links)"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  not
    sender.email.domain.root_domain eq "protectedtrust.com"
  not
     macro "all(body.links)"
  body.links length_compare "0"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
attachmentsarray_any(no value, null check)excludes:attachments
filter(attachments, strings.ilike(.file_name, 'logo.*', 'lock.gif', 'SecureMessageAtt.html'))length_compare3excludes:filter(attachments, strings.ilike(.file_name, 'logo.*', 'lock.gif', 'SecureMessageAtt.html')) field:"filter(attachments, strings.ilike(.file_name, 'logo.*', 'lock.gif', 'SecureMessageAtt.html'))" value:"3"
headers.hopsarray_any(no value, null check)excludes:headers.hops
headers.domainsarray_any(no value, null check)excludes:headers.domains
sender.email.domain.root_domaineqprotectedtrust.comexcludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"protectedtrust.com"

Indicators

These rows show field, operator, and value matches.

Credential phishing: Engaging language and other indicators (untrusted sender)

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

Message contains various suspicious indicators as well as engaging language resembling credential theft from an untrusted sender.

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

  • attachments
  • body
  • body.current_thread
  • body.ips
  • body.links
  • headers
  • headers.auth_summary
  • headers.return_path
  • recipients
  • recipients.to
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  regex.icontains(subject.subject,
                  "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.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",
                  "crediential.*notif",
                  "clos.*of.*account.*processed",
                  "confirm.your.account",
                  "courier.*able",
                  "crediential.*notif",
                  "deactivation.*in.*progress",
                  "delivery.*attempt.*failed",
                  "disconnection.*notice",
                  "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} preview",
                  "e-?ma[il1]{2}.*up.?grade",
                  "e.?ma[il1]{2}.*server",
                  "e.?ma[il1]{2}.*suspend",
                  "electronic advisory",
                  "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",
                  "(?:payroll|salary|bonus).*Distribution",
                  "periodic maintenance",
                  "potential(ly)? unauthorized",
                  "refund not approved",
                  "report",
                  "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",
                  "(?:unrecognized|Unusual|suspicious|unknown) (?:log|sign).?[io]n attempt",
                  "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",
                  "de.activation",
                  "attn_task",
                  // 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",
                  "pay notification",
                  "quick reply",
                  "re: w-2",
                  "required",
                  "required: completed docusign",
                  "remittance",
                  "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",
                  "unusual signin",
                  "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",
  )
  or (
    regex.icontains(subject.subject, 'account.has.been')
    and not regex.icontains(subject.subject, 'account.has.been.*created')
  )
  or (
    regex.icontains(sender.display_name,
                    "Admin",
                    "Administrator",
                    "Alert",
                    "Assistant",
                    "Authenticat(or|ion)",
                    "Billing",
                    "Benefits",
                    "Bonus",
                    "CEO",
                    "CFO",
                    "CIO",
                    "CTO",
                    "Chairman",
                    "Claim",
                    "Confirm",
                    "Cpanel Mail",
                    "Critical",
                    "Customer Service",
                    "Deal",
                    "Discount",
                    "Director",
                    "Exclusive",
                    "Executive",
                    "Fax",
                    "Free",
                    "Gift",
                    '\bHR\b',
                    "Helpdesk",
                    "Human Resources",
                    "Immediate",
                    "Important",
                    "Info",
                    "Information",
                    "Invoice",
                    '\bIT\b',
                    '\bLegal\b',
                    "Lottery",
                    "Management",
                    "Manager",
                    "Member Services",
                    "Notification",
                    "Offer",
                    "Official Communication",
                    "Operations",
                    "Order",
                    "Partner",
                    "Payment",
                    "Payroll",
                    "Postmaster",
                    "President",
                    "Premium",
                    "Prize",
                    "Receipt",
                    "Refund",
                    "Registrar",
                    "Required",
                    "Reward",
                    "Sales",
                    "Secretary",
                    "Security",
                    "Server",
                    "Service",
                    "Storage",
                    "Support",
                    "Sweepstakes",
                    "System",
                    "Tax",
                    "Tech Support",
                    "Update",
                    "Upgrade",
                    "Urgent",
                    "Validate",
                    "Verify",
                    "VIP",
                    "Webmaster",
                    "Winner",
                    "DocReq\\b"
    )
    // add negation for common FPs in the sender display_name
    and not strings.icontains(sender.display_name, "service bulletin")
    and not strings.icontains(sender.display_name, "automotive service")
  )
)
and (
  4 of (
    any(recipients.to,
        .email.domain.valid
        and (
          strings.icontains(body.current_thread.text, .email.email)
          or strings.icontains(body.current_thread.text, .email.local_part)
        )
    ),
    any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft" and .confidence in ("medium", "high")
    ),
    any(ml.nlu_classifier(body.current_thread.text).entities,
        .name == "request"
    ),
    // recipient email address base64 encoded in link
    any(body.links,
        any(recipients.to,
            any(beta.scan_base64(..href_url.url,
                                 ignore_padding=true,
                                 format="url"
                ),
                strings.icontains(., ..email.email)
            )
        )
    ),
    (
      // freemail providers should never be sending this type of email
      sender.email.domain.domain in $free_email_providers

      // if not freemail, it's suspicious if the sender's root domain
      // doesn't match any links in the body
      or all(body.links,
             .href_url.domain.root_domain != sender.email.domain.root_domain
             and (
               .href_url.domain.root_domain not in $org_domains
               // ignore recipient email addresses in the body in relation to this check
               or (
                 .href_url.domain.root_domain in $org_domains
                 and any(recipients.to,
                         strings.icount(body.current_thread.text, .email.email) == strings.icount(body.current_thread.text,
                                                                                                  .email.domain.domain
                         )
                 )
               )
             )
      )

      // bulk mailers should also never be sending this type of email
      or all(filter(body.links,
                    .href_url.domain.domain not in (
                      "aka.ms",
                      "mimecast.com",
                      "mimecastprotect.com",
                      "cisco.com"
                    )
             ),
             .href_url.domain.root_domain in $bulk_mailer_url_root_domains
      )
    ),
    // in case it's embedded in an image attachment
    // note: don't use message_screenshot() because it's not limited to current_thread
    // and may FP
    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 == "high"
                )
        )
    ),
    strings.contains(body.current_thread.text,
                     "Your mailbox can no longer send or receive messages."
    ),
    any(body.links,
        strings.icontains(.href_url.query_params, 'redirect')
        or any(.href_url.rewrite.encoders,
               strings.icontains(., "open_redirect")
        )
    ),
    // multiple entities displaying urgency
    length(filter(ml.nlu_classifier(body.current_thread.text).entities,
                  .name == "urgency"
           )
    ) >= 2
    // and any body links
    and any(body.links,
            // display text contains a request
            any(ml.nlu_classifier(.display_text).entities, .name == "request")
    ),
    any(body.links,
        // display text contains a request
        (
          any(ml.nlu_classifier(.display_text).entities, .name == "request")
          or regex.match(.display_text, '^[^a-z]+$')
        )
        and (
          .href_url.domain.domain in $url_shorteners
          or .href_url.domain.domain in $social_landing_hosts
          or .href_url.domain.root_domain in $url_shorteners
          or .href_url.domain.root_domain in $social_landing_hosts
          or .href_url.domain.domain in $free_file_hosts
          or (
            .href_url.domain.root_domain in (
              "mimecast.com",
              "mimecastprotect.com"
            )
            and any(.href_url.query_params_decoded['domain'],
                    strings.parse_url(strings.concat("https://", .)).domain.domain in $url_shorteners
                    or strings.parse_url(strings.concat("https://", .)).domain.root_domain in $url_shorteners
                    or strings.parse_url(strings.concat("https://", .)).domain.domain in $free_file_hosts
                    or strings.parse_url(strings.concat("https://", .)).domain.root_domain in $free_subdomain_hosts
                    or strings.parse_url(strings.concat("https://", .)).domain.domain in $social_landing_hosts
                    or strings.parse_url(strings.concat("https://", .)).domain.root_domain in $social_landing_hosts
            )
          )
        )
    ),
    // common greetings via email.local_part
    any(recipients.to,
        length(.email.local_part) > 2
        and 
        // use count to ensure the email address is not part of a disclaimer
        strings.icount(body.current_thread.text, .email.local_part) > 
        // sum allows us to add more logic as needed
        strings.icount(body.current_thread.text,
                       strings.concat('was sent to ', .email.email)
        ) + strings.icount(body.current_thread.text,
                           strings.concat('intended for ', .email.email)
        )
    )
  )
  or (
    (
      // recipient's email address is in the body
      any(recipients.to,
          // use count to ensure the email address is not part of a disclaimer
          strings.icount(body.current_thread.text, .email.email) > 
          // sum allows us to add more logic as needed
          sum([
                strings.icount(body.current_thread.text,
                               strings.concat('was sent to ', .email.email)
                ),
                strings.icount(body.current_thread.text,
                               strings.concat('intended for ', .email.email)
                )
              ]
          )
      )
      // suspicious display text
      or (
        length(body.links) == 1
        and all(body.links,
                strings.ilike(.display_text, "*click here*", "*password*")
        )
      )
    )
    // link leads to a suspicious TLD or contains an IP address or contains multiple redirects
    and any(body.links,
            (
              ml.link_analysis(., mode="aggressive").effective_url.domain.tld in $suspicious_tlds
              or length(distinct(map(ml.link_analysis(., mode="aggressive").redirect_history,
                                     .domain.root_domain
                                 )
                        )
              ) >= 4
              or (
                any(body.ips,
                    any(body.links, strings.icontains(.href_url.url, ..ip))
                )
              )
            )
    )
  )
)
// exclude Google shared calendar messages
// Subject: "<sender name> has shared a calendar with you"
and headers.return_path.domain.domain != "calendar-server.bounces.google.com"
// negate calendar invites
and not (
  0 < length(attachments) < 3
  and all(attachments, .content_type in ("text/calendar", "application/ics"))
)
// negate replies
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, "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.icontains(subject.subject,
                           '^(\[[^\]]+\]\s?){0,3}(re|fwd?)\s?:'
        )
      )
    )
  )
  or length(headers.references) == 0
)
// bounce-back and DMARC report negations
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"
        )
    )
    or (
      length(attachments) == 1
      and all(attachments, .content_type in ("application/gzip"))
      and regex.icontains(subject.subject,
                          '(?:(Report\sDomain).*(Submitter).*(Report-ID))'
      )
    )
  )
)
and (
  (
    profile.by_sender().prevalence != "common"
    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 not headers.auth_summary.dmarc.pass
  )
  or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)
// FP avoidance
and not any(beta.ml_topic(body.current_thread.text).topics,
            .name in (
              "Advertising and Promotions",
              "Political Mail",
              "News and Current Events",
              "Newsletters and Digests"
            )
            and .confidence == "high"
)

Detection logic

Scope: inbound message.

Message contains various suspicious indicators as well as engaging language resembling credential theft from an untrusted sender.

  1. inbound message
  2. any of:
    • subject.subject matches any of 199 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.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
      • crediential.*notif
      • clos.*of.*account.*processed
      • confirm.your.account
      • courier.*able
      • crediential.*notif
      • deactivation.*in.*progress
      • delivery.*attempt.*failed
      • disconnection.*notice
      • 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} preview
      • e-?ma[il1]{2}.*up.?grade
      • e.?ma[il1]{2}.*server
      • e.?ma[il1]{2}.*suspend
      • electronic advisory
      • 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
      • (?:payroll|salary|bonus).*Distribution
      • periodic maintenance
      • potential(ly)? unauthorized
      • refund not approved
      • report
      • 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
      • (?:unrecognized|Unusual|suspicious|unknown) (?:log|sign).?[io]n attempt
      • 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
      • de.activation
      • attn_task
      • 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
      • pay notification
      • quick reply
      • re: w-2
      • required
      • required: completed docusign
      • remittance
      • 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
      • unusual signin
      • 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
    • all of:
      • subject.subject matches 'account.has.been'
      • not:
        • subject.subject matches 'account.has.been.*created'
    • all of:
      • sender.display_name matches any of 77 patterns
        • Admin
        • Administrator
        • Alert
        • Assistant
        • Authenticat(or|ion)
        • Billing
        • Benefits
        • Bonus
        • CEO
        • CFO
        • CIO
        • CTO
        • Chairman
        • Claim
        • Confirm
        • Cpanel Mail
        • Critical
        • Customer Service
        • Deal
        • Discount
        • Director
        • Exclusive
        • Executive
        • Fax
        • Free
        • Gift
        • \bHR\b
        • Helpdesk
        • Human Resources
        • Immediate
        • Important
        • Info
        • Information
        • Invoice
        • \bIT\b
        • \bLegal\b
        • Lottery
        • Management
        • Manager
        • Member Services
        • Notification
        • Offer
        • Official Communication
        • Operations
        • Order
        • Partner
        • Payment
        • Payroll
        • Postmaster
        • President
        • Premium
        • Prize
        • Receipt
        • Refund
        • Registrar
        • Required
        • Reward
        • Sales
        • Secretary
        • Security
        • Server
        • Service
        • Storage
        • Support
        • Sweepstakes
        • System
        • Tax
        • Tech Support
        • Update
        • Upgrade
        • Urgent
        • Validate
        • Verify
        • VIP
        • Webmaster
        • Winner
        • DocReq\\b
      • not:
        • sender.display_name contains 'service bulletin'
      • not:
        • sender.display_name contains 'automotive service'
  3. any of:
    • at least 4 of:
      • any of recipients.to where all hold:
        • .email.domain.valid
        • any of:
          • strings.icontains(body.current_thread.text)
          • strings.icontains(body.current_thread.text)
      • 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).entities where:
        • .name is 'request'
      • any of body.links where:
        • any of recipients.to where:
          • any of beta.scan_base64(.href_url.url) where:
            • strings.icontains(.)
      • any of:
        • sender.email.domain.domain in $free_email_providers
        • all of body.links where all hold:
          • .href_url.domain.root_domain is not sender.email.domain.root_domain
          • any of:
            • .href_url.domain.root_domain not in $org_domains
            • all of:
              • .href_url.domain.root_domain in $org_domains
              • any of recipients.to where:
                • strings.icount(body.current_thread.text) is strings.icount(body.current_thread.text, .email.domain.domain)
        • all of filter(body.links) where:
          • .href_url.domain.root_domain in $bulk_mailer_url_root_domains
      • 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 'high'
      • body.current_thread.text contains 'Your mailbox can no longer send or receive messages.'
      • any of body.links where any holds:
        • .href_url.query_params contains 'redirect'
        • any of .href_url.rewrite.encoders where:
          • . contains 'open_redirect'
      • all of:
        • length(filter(ml.nlu_classifier(body.current_thread.text).entities, .name == 'urgency')) ≥ 2
        • any of body.links where:
          • any of ml.nlu_classifier(.display_text).entities where:
            • .name is 'request'
      • any of body.links where all hold:
        • any of:
          • any of ml.nlu_classifier(.display_text).entities where:
            • .name is 'request'
          • .display_text matches '^[^a-z]+$'
        • any of:
          • .href_url.domain.domain in $url_shorteners
          • .href_url.domain.domain in $social_landing_hosts
          • .href_url.domain.root_domain in $url_shorteners
          • .href_url.domain.root_domain in $social_landing_hosts
          • .href_url.domain.domain in $free_file_hosts
          • all of:
            • .href_url.domain.root_domain in ('mimecast.com', 'mimecastprotect.com')
            • any of .href_url.query_params_decoded['domain'] where any holds:
              • strings.parse_url(strings.concat('https://', .)).domain.domain in $url_shorteners
              • strings.parse_url(strings.concat('https://', .)).domain.root_domain in $url_shorteners
              • strings.parse_url(strings.concat('https://', .)).domain.domain in $free_file_hosts
              • strings.parse_url(strings.concat('https://', .)).domain.root_domain in $free_subdomain_hosts
              • strings.parse_url(strings.concat('https://', .)).domain.domain in $social_landing_hosts
              • strings.parse_url(strings.concat('https://', .)).domain.root_domain in $social_landing_hosts
      • any of recipients.to where all hold:
        • length(.email.local_part) > 2
        • strings.icount(body.current_thread.text) > strings.icount(body.current_thread.text) + strings.icount(body.current_thread.text)
    • all of:
      • any of:
        • any of recipients.to where:
          • strings.icount(body.current_thread.text) > sum([strings.icount(body.current_thread.text, strings.concat('was sent to ', .email.email)), strings.icount(body.current_thread.text, strings.concat('intended for ', .email.email))])
        • all of:
          • length(body.links) is 1
          • all of body.links where:
            • .display_text matches any of 2 patterns
              • *click here*
              • *password*
      • any of body.links where any holds:
        • ml.link_analysis(.).effective_url.domain.tld in $suspicious_tlds
        • length(distinct(map(ml.link_analysis(., mode='aggressive').redirect_history, .domain.root_domain))) ≥ 4
        • any of body.ips where:
          • any of body.links where:
            • strings.icontains(.href_url.url)
  4. headers.return_path.domain.domain is not 'calendar-server.bounces.google.com'
  5. not:
    • all of:
      • all of:
        • length(attachments) > 0
        • length(attachments) < 3
      • all of attachments where:
        • .content_type in ('text/calendar', 'application/ics')
  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 '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
  7. not:
    • all of:
      • sender.email.local_part matches any of 3 patterns
        • *postmaster*
        • *mailer-daemon*
        • *administrator*
      • any of:
        • any of attachments where:
          • .content_type in ('message/rfc822', 'message/delivery-status', 'text/calendar')
        • all of:
          • length(attachments) is 1
          • all of attachments where:
            • .content_type in ('application/gzip')
          • subject.subject matches '(?:(Report\\sDomain).*(Submitter).*(Report-ID))'
  8. any of:
    • all of:
      • profile.by_sender().prevalence is not 'common'
      • not:
        • profile.by_sender_email().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  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 beta.ml_topic(body.current_thread.text).topics where all hold:
      • .name in ('Advertising and Promotions', 'Political Mail', 'News and Current Events', 'Newsletters and Digests')
      • .confidence is 'high'

Inspects: attachments[].content_type, attachments[].file_type, body.current_thread.text, body.ips, body.ips[].ip, body.links, body.links[].display_text, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.query_params, body.links[].href_url.query_params_decoded['domain'], body.links[].href_url.rewrite.encoders, body.links[].href_url.url, headers.auth_summary.dmarc.pass, headers.in_reply_to, headers.references, headers.return_path.domain.domain, recipients.to, recipients.to[].email.domain.domain, recipients.to[].email.domain.valid, recipients.to[].email.email, recipients.to[].email.local_part, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.local_part, subject.subject, type.inbound. Sensors: beta.ml_topic, beta.scan_base64, file.explode, ml.link_analysis, ml.nlu_classifier, profile.by_sender, profile.by_sender_email, regex.icontains, regex.match, strings.concat, strings.contains, strings.icontains, strings.icount, strings.ilike, strings.istarts_with, strings.like, strings.parse_url. Reference lists: $bulk_mailer_url_root_domains, $file_types_images, $free_email_providers, $free_file_hosts, $free_subdomain_hosts, $high_trust_sender_root_domains, $org_domains, $social_landing_hosts, $suspicious_tlds, $url_shorteners.

Indicators matched (292)

FieldMatchValue
regex.icontainsregextermination.*notice
regex.icontainsregex38417
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
280 more
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.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.icontainsregexcrediential.*notif
regex.icontainsregexclos.*of.*account.*processed
regex.icontainsregexconfirm.your.account
regex.icontainsregexcourier.*able
regex.icontainsregexdeactivation.*in.*progress
regex.icontainsregexdelivery.*attempt.*failed
regex.icontainsregexdisconnection.*notice
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} preview
regex.icontainsregexe-?ma[il1]{2}.*up.?grade
regex.icontainsregexe.?ma[il1]{2}.*server
regex.icontainsregexe.?ma[il1]{2}.*suspend
regex.icontainsregexelectronic advisory
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.icontainsregex(?:payroll|salary|bonus).*Distribution
regex.icontainsregexperiodic maintenance
regex.icontainsregexpotential(ly)? unauthorized
regex.icontainsregexrefund not approved
regex.icontainsregexreport
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.icontainsregex(?:unrecognized|Unusual|suspicious|unknown) (?:log|sign).?[io]n attempt
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.icontainsregexde.activation
regex.icontainsregexattn_task
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.icontainsregexpay notification
regex.icontainsregexquick reply
regex.icontainsregexre: w-2
regex.icontainsregexrequired
regex.icontainsregexrequired: completed docusign
regex.icontainsregexremittance
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.icontainsregexunusual signin
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
regex.icontainsregexaccount.has.been
regex.icontainsregexAdmin
regex.icontainsregexAdministrator
regex.icontainsregexAlert
regex.icontainsregexAssistant
regex.icontainsregexAuthenticat(or|ion)
regex.icontainsregexBilling
regex.icontainsregexBenefits
regex.icontainsregexBonus
regex.icontainsregexCEO
regex.icontainsregexCFO
regex.icontainsregexCIO
regex.icontainsregexCTO
regex.icontainsregexChairman
regex.icontainsregexClaim
regex.icontainsregexConfirm
regex.icontainsregexCpanel Mail
regex.icontainsregexCritical
regex.icontainsregexCustomer Service
regex.icontainsregexDeal
regex.icontainsregexDiscount
regex.icontainsregexDirector
regex.icontainsregexExclusive
regex.icontainsregexExecutive
regex.icontainsregexFax
regex.icontainsregexFree
regex.icontainsregexGift
regex.icontainsregex\bHR\b
regex.icontainsregexHelpdesk
regex.icontainsregexHuman Resources
regex.icontainsregexImmediate
regex.icontainsregexImportant
regex.icontainsregexInfo
regex.icontainsregexInformation
regex.icontainsregexInvoice
regex.icontainsregex\bIT\b
regex.icontainsregex\bLegal\b
regex.icontainsregexLottery
regex.icontainsregexManagement
regex.icontainsregexManager
regex.icontainsregexMember Services
regex.icontainsregexNotification
regex.icontainsregexOffer
regex.icontainsregexOfficial Communication
regex.icontainsregexOperations
regex.icontainsregexOrder
regex.icontainsregexPartner
regex.icontainsregexPayment
regex.icontainsregexPayroll
regex.icontainsregexPostmaster
regex.icontainsregexPresident
regex.icontainsregexPremium
regex.icontainsregexPrize
regex.icontainsregexReceipt
regex.icontainsregexRefund
regex.icontainsregexRegistrar
regex.icontainsregexRequired
regex.icontainsregexReward
regex.icontainsregexSales
regex.icontainsregexSecretary
regex.icontainsregexSecurity
regex.icontainsregexServer
regex.icontainsregexService
regex.icontainsregexStorage
regex.icontainsregexSupport
regex.icontainsregexSweepstakes
regex.icontainsregexSystem
regex.icontainsregexTax
regex.icontainsregexTech Support
regex.icontainsregexUpdate
regex.icontainsregexUpgrade
regex.icontainsregexUrgent
regex.icontainsregexValidate
regex.icontainsregexVerify
regex.icontainsregexVIP
regex.icontainsregexWebmaster
regex.icontainsregexWinner
regex.icontainsregexDocReq\\b
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(body.current_thread.text).entities[].nameequalsrequest
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].nameequalscred_theft
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidenceequalshigh
strings.containssubstringYour mailbox can no longer send or receive messages.
strings.icontainssubstringredirect
strings.icontainssubstringopen_redirect
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsurgency
ml.nlu_classifier(body.links[].display_text).entities[].nameequalsrequest
regex.matchregex^[^a-z]+$
body.links[].href_url.domain.root_domainmembermimecast.com
body.links[].href_url.domain.root_domainmembermimecastprotect.com
strings.ilikesubstring*click here*
strings.ilikesubstring*password*

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(body.links)
      and
        or
          and
            any(body.links.href_url.query_params_decoded['domain'])
              or
                strings.parse_url func_call "strings.parse_url(strings.concat('https://', body.links[].href_url.query_params_decoded['domain'][])).domain.domain in free_file_hosts"
                strings.parse_url func_call "strings.parse_url(strings.concat('https://', body.links[].href_url.query_params_decoded['domain'][])).domain.domain in social_landing_hosts"
                strings.parse_url func_call "strings.parse_url(strings.concat('https://', body.links[].href_url.query_params_decoded['domain'][])).domain.domain in url_shorteners"
                strings.parse_url func_call "strings.parse_url(strings.concat('https://', body.links[].href_url.query_params_decoded['domain'][])).domain.root_domain in free_subdomain_hosts"
                strings.parse_url func_call "strings.parse_url(strings.concat('https://', body.links[].href_url.query_params_decoded['domain'][])).domain.root_domain in social_landing_hosts"
                strings.parse_url func_call "strings.parse_url(strings.concat('https://', body.links[].href_url.query_params_decoded['domain'][])).domain.root_domain in url_shorteners"
            body.links.href_url.domain.root_domain in ["mimecast.com", "mimecastprotect.com"]
           macro "body.links[].href_url.domain.domain in free_file_hosts"
           macro "body.links[].href_url.domain.domain in social_landing_hosts"
           macro "body.links[].href_url.domain.domain in url_shorteners"
           macro "body.links[].href_url.domain.root_domain in social_landing_hosts"
           macro "body.links[].href_url.domain.root_domain in url_shorteners"
        or
          any(ml.nlu_classifier(body.links.display_text).entities)
            ml.nlu_classifier(body.links.display_text).entities.name eq "request"
          body.links.display_text regex_match "^[^a-z]+$"
    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"
         macro "attachments[].file_type in file_types_images"
    and
      any(body.links)
        or
          any(body.ips)
            any(body.links)
              strings.icontains func_call "strings.icontains(body.links[].href_url.url)"
          distinct(map(ml.link_analysis(body.links[], mode='aggressive').redirect_history, body.links[].domain.root_domain)) length_compare "4"
          ml.link_analysis func_call "ml.link_analysis(body.links[]).effective_url.domain.tld in suspicious_tlds"
      or
        and
          body.links length_compare "1"
           macro "all(body.links)"
        any(recipients.to)
          strings.icount func_call "strings.icount(body.current_thread.text) > sum([strings.icount(body.current_thread.text, strings.concat('was sent to ', recipients.to[].email.email)), strings.icount(body.current_thread.text, strings.concat('intended for ', recipients.to[].email.email))])"
    any(body.links)
      or
        any(body.links.href_url.rewrite.encoders)
          body.links.href_url.rewrite.encoders contains "open_redirect"
        body.links.href_url.query_params contains "redirect"
    and
      any(body.links)
        any(ml.nlu_classifier(body.links.display_text).entities)
          ml.nlu_classifier(body.links.display_text).entities.name eq "request"
      filter(ml.nlu_classifier(body.current_thread.text).entities, .name == 'urgency') length_compare "2"
    any(body.links)
      any(recipients.to)
        any(beta.scan_base64(body.links.href_url.url))
          strings.icontains func_call "strings.icontains(beta.scan_base64(body.links[].href_url.url)[])"
    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(recipients.to)
      and
        recipients.to.email.domain.valid eq "true"
        strings.icontains func_call "strings.icontains(body.current_thread.text)"
    any(recipients.to)
      and
        recipients.to.email.local_part length_compare "2"
         macro "strings.icount(body.current_thread.text) > (strings.icount(body.current_thread.text) + strings.icount(body.current_thread.text))"
    any(ml.nlu_classifier(body.current_thread.text).entities)
      ml.nlu_classifier(body.current_thread.text).entities.name eq "request"
    body.current_thread.text contains "Your mailbox can no longer send or receive messages."
     macro "all(body.links)"
     macro "all(filter(body.links))"
     macro "sender.email.domain.domain in free_email_providers"
  not
    and
      or
        and
          attachments length_compare "1"
          subject.subject regex_match "(?:(Report\\sDomain).*(Submitter).*(Report-ID))"
           macro "all(attachments)"
        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"
  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 "TR:"
          subject.subject starts_with "答复:"
      or
        headers.in_reply_to is_null
        headers.references length_compare "0"
    headers.references length_compare "0"
  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", "News and Current Events", "Newsletters and Digests", "Political Mail"]
  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_email func_call "profile.by_sender_email().solicited"
      profile.by_sender func_call "profile.by_sender().prevalence != common"
  or
    and
      not
        sender.display_name contains "automotive service"
      not
        sender.display_name contains "service bulletin"
      or
        sender.display_name regex_match "Admin"
        sender.display_name regex_match "Administrator"
        sender.display_name regex_match "Alert"
        sender.display_name regex_match "Assistant"
        sender.display_name regex_match "Authenticat(or|ion)"
        sender.display_name regex_match "Benefits"
        sender.display_name regex_match "Billing"
        sender.display_name regex_match "Bonus"
        sender.display_name regex_match "CEO"
        sender.display_name regex_match "CFO"
        sender.display_name regex_match "CIO"
        sender.display_name regex_match "CTO"
        sender.display_name regex_match "Chairman"
        sender.display_name regex_match "Claim"
        sender.display_name regex_match "Confirm"
        sender.display_name regex_match "Cpanel Mail"
        sender.display_name regex_match "Critical"
        sender.display_name regex_match "Customer Service"
        sender.display_name regex_match "Deal"
        sender.display_name regex_match "Director"
        sender.display_name regex_match "Discount"
        sender.display_name regex_match "DocReq\\\\b"
        sender.display_name regex_match "Exclusive"
        sender.display_name regex_match "Executive"
        sender.display_name regex_match "Fax"
        sender.display_name regex_match "Free"
        sender.display_name regex_match "Gift"
        sender.display_name regex_match "Helpdesk"
        sender.display_name regex_match "Human Resources"
        sender.display_name regex_match "Immediate"
        sender.display_name regex_match "Important"
        sender.display_name regex_match "Info"
        sender.display_name regex_match "Information"
        sender.display_name regex_match "Invoice"
        sender.display_name regex_match "Lottery"
        sender.display_name regex_match "Management"
        sender.display_name regex_match "Manager"
        sender.display_name regex_match "Member Services"
        sender.display_name regex_match "Notification"
        sender.display_name regex_match "Offer"
        sender.display_name regex_match "Official Communication"
        sender.display_name regex_match "Operations"
        sender.display_name regex_match "Order"
        sender.display_name regex_match "Partner"
        sender.display_name regex_match "Payment"
        sender.display_name regex_match "Payroll"
        sender.display_name regex_match "Postmaster"
        sender.display_name regex_match "Premium"
        sender.display_name regex_match "President"
        sender.display_name regex_match "Prize"
        sender.display_name regex_match "Receipt"
        sender.display_name regex_match "Refund"
        sender.display_name regex_match "Registrar"
        sender.display_name regex_match "Required"
        sender.display_name regex_match "Reward"
        sender.display_name regex_match "Sales"
        sender.display_name regex_match "Secretary"
        sender.display_name regex_match "Security"
        sender.display_name regex_match "Server"
        sender.display_name regex_match "Service"
        sender.display_name regex_match "Storage"
        sender.display_name regex_match "Support"
        sender.display_name regex_match "Sweepstakes"
        sender.display_name regex_match "System"
        sender.display_name regex_match "Tax"
        sender.display_name regex_match "Tech Support"
        sender.display_name regex_match "Update"
        sender.display_name regex_match "Upgrade"
        sender.display_name regex_match "Urgent"
        sender.display_name regex_match "VIP"
        sender.display_name regex_match "Validate"
        sender.display_name regex_match "Verify"
        sender.display_name regex_match "Webmaster"
        sender.display_name regex_match "Winner"
        sender.display_name regex_match "\\bHR\\b"
        sender.display_name regex_match "\\bIT\\b"
        sender.display_name regex_match "\\bLegal\\b"
    and
      not
        subject.subject regex_match "account.has.been.*created"
      subject.subject regex_match "account.has.been"
    subject.subject regex_match "(?:payroll|salary|bonus).*Distribution"
    subject.subject regex_match "(?:unrecognized|Unusual|suspicious|unknown) (?:log|sign).?[io]n attempt"
    subject.subject regex_match "38417"
    subject.subject regex_match ":completed"
    subject.subject regex_match "[il1]{2}mit.*ma[il1]{2} ?bo?x"
    subject.subject regex_match "[il][il][il]egai[ -]"
    subject.subject regex_match "[li][li][li]ega[li] attempt"
    subject.subject regex_match "[ng]-?[io]n .*block"
    subject.subject regex_match "[ng]-?[io]n .*cancel"
    subject.subject regex_match "[ng]-?[io]n .*deactiv"
    subject.subject regex_match "[ng]-?[io]n .*disabl"
    subject.subject regex_match "abandon.*package"
    subject.subject regex_match "about.your.account"
    subject.subject regex_match "acc(ou)?n?t (is )?on ho[li]d"
    subject.subject regex_match "acc(ou)?n?t.*terminat"
    subject.subject regex_match "acc(oun)?t.*[il1]{2}mitation"
    subject.subject regex_match "access.*limitation"
    subject.subject regex_match "account (will be )?block"
    subject.subject regex_match "account has been limited"
    subject.subject regex_match "account v[il]o[li]at"
    subject.subject regex_match "account.*de-?activat"
    subject.subject regex_match "account.*locked"
    subject.subject regex_match "account.*re-verification"
    subject.subject regex_match "account.*security"
    subject.subject regex_match "account.*suspension"
    subject.subject regex_match "account.has.expired"
    subject.subject regex_match "account.will.be.blocked"
    subject.subject regex_match "action required"
    subject.subject regex_match "action.*required"
    subject.subject regex_match "activity.*acc(oun)?t"
    subject.subject regex_match "almost full"
    subject.subject regex_match "almost.full"
    subject.subject regex_match "apd notifi cation"
    subject.subject regex_match "app[li]e.[il]d"
    subject.subject regex_match "are you at your desk"
    subject.subject regex_match "are you available"
    subject.subject regex_match "attached file to docusign"
    subject.subject regex_match "attn_task"
    subject.subject regex_match "authenticate.*account"
    subject.subject regex_match "banking is temporarily unavailable"
    subject.subject regex_match "bankofamerica"
    subject.subject regex_match "been.*suspend"
    subject.subject regex_match "clos.*of.*account.*processed"
    subject.subject regex_match "closing statement invoice"
    subject.subject regex_match "completed: docusign"
    subject.subject regex_match "confirm.your.account"
    subject.subject regex_match "courier.*able"
    subject.subject regex_match "crediential.*notif"
    subject.subject regex_match "de-activation of"
    subject.subject regex_match "de.activation"
    subject.subject regex_match "deactivation.*in.*progress"
    subject.subject regex_match "delivery attempt"
    subject.subject regex_match "delivery stopped for shipment"
    subject.subject regex_match "delivery.*attempt.*failed"
    subject.subject regex_match "detected suspicious actvity"
    subject.subject regex_match "detected suspicious"
    subject.subject regex_match "disconnection.*notice"
    subject.subject regex_match "docu sign"
    subject.subject regex_match "document for you"
    subject.subject regex_match "document has been sent to you via docusign"
    subject.subject regex_match "document is ready for signature"
    subject.subject regex_match "document.received"
    subject.subject regex_match "documented.*shared.*with.*you"
    subject.subject regex_match "docusign"
    subject.subject regex_match "dropbox.*document"
    subject.subject regex_match "e-?ma[il1]+ .{010}suspen"
    subject.subject regex_match "e-?ma[il1]{1} user"
    subject.subject regex_match "e-?ma[il1]{2} acc"
    subject.subject regex_match "e-?ma[il1]{2} preview"
    subject.subject regex_match "e-?ma[il1]{2}.*up.?grade"
    subject.subject regex_match "e.?ma[il1]{2}.*server"
    subject.subject regex_match "e.?ma[il1]{2}.*suspend"
    subject.subject regex_match "electronic advisory"
    subject.subject regex_match "email.update"
    subject.subject regex_match "encrypted message"
    subject.subject regex_match "failed delivery"
    subject.subject regex_match "faxed you"
    subject.subject regex_match "fedex tracking"
    subject.subject regex_match "file was shared"
    subject.subject regex_match "fraud(ulent)?.*charge"
    subject.subject regex_match "freefax"
    subject.subject regex_match "from.helpdesk"
    subject.subject regex_match "fu[il1]{2}.*ma[il1]+[ -]?box"
    subject.subject regex_match "fwd: due invoice paid"
    subject.subject regex_match "has shared"
    subject.subject regex_match "has.been.*suspended"
    subject.subject regex_match "has.been.limited"
    subject.subject regex_match "have.locked"
    subject.subject regex_match "he[li]p ?desk upgrade"
    subject.subject regex_match "heipdesk"
    subject.subject regex_match "i[il]iega[il]"
    subject.subject regex_match "ii[il]ega[il]"
    subject.subject regex_match "inbox is full"
    subject.subject regex_match "incoming e?mail"
    subject.subject regex_match "incoming.*fax"
    subject.subject regex_match "invitation to comment"
    subject.subject regex_match "invitation to edit"
    subject.subject regex_match "invoice due"
    subject.subject regex_match "left you a message"
    subject.subject regex_match "lock.*security"
    subject.subject regex_match "ma[il1]{1}[ -]?box.*quo"
    subject.subject regex_match "ma[il1]{2}[ -]?box.*fu[il1]"
    subject.subject regex_match "ma[il1]{2}box stor"
    subject.subject regex_match "ma[il1]{2}box.*[il1]{2}mit"
    subject.subject regex_match "mail on.?hold"
    subject.subject regex_match "mail.*box.*migration"
    subject.subject regex_match "mail.*de-?activat"
    subject.subject regex_match "mail.update.required"
    subject.subject regex_match "mails.*pending"
    subject.subject regex_match "message from"
    subject.subject regex_match "messages.*pending"
    subject.subject regex_match "missed.*shipping.*notification"
    subject.subject regex_match "missed.shipment.notification"
    subject.subject regex_match "must.update.your.account"
    subject.subject regex_match "new [sl][io]g?[nig][ -]?in from"
    subject.subject regex_match "new message"
    subject.subject regex_match "new sign in"
    subject.subject regex_match "new sign-in"
    subject.subject regex_match "new voice ?-?mail"
    subject.subject regex_match "new voicemail"
    subject.subject regex_match "notifications.*pending"
    subject.subject regex_match "office.*3.*6.*5.*suspend"
    subject.subject regex_match "office365"
    subject.subject regex_match "on desk"
    subject.subject regex_match "on google docs with you"
    subject.subject regex_match "online doc"
    subject.subject regex_match "out of space"
    subject.subject regex_match "password reset"
    subject.subject regex_match "password.*compromised"
    subject.subject regex_match "pay notification"
    subject.subject regex_match "payment status"
    subject.subject regex_match "periodic maintenance"
    subject.subject regex_match "potential(ly)? unauthorized"
    subject.subject regex_match "quick reply"
    subject.subject regex_match "re: w-2"
    subject.subject regex_match "refund not approved"
    subject.subject regex_match "remittance"
    subject.subject regex_match "report"
    subject.subject regex_match "required"
    subject.subject regex_match "required: completed docusign"
    subject.subject regex_match "revised.*policy"
    subject.subject regex_match "ringcentral"
    subject.subject regex_match "scam"
    subject.subject regex_match "scanned image"
    subject.subject regex_match "scanned.?invoice"
    subject.subject regex_match "secured files"
    subject.subject regex_match "secured pdf"
    subject.subject regex_match "secured?.update"
    subject.subject regex_match "security alert"
    subject.subject regex_match "security breach"
    subject.subject regex_match "securlty"
    subject.subject regex_match "sign in attempt"
    subject.subject regex_match "sign-in attempt"
    subject.subject regex_match "signed.*delivery"
    subject.subject regex_match "staff review"
    subject.subject regex_match "status of your .{314}? ?delivery"
    subject.subject regex_match "susp[il1]+c[il1]+ous.*act[il1]+v[il1]+ty"
    subject.subject regex_match "suspicious activity"
    subject.subject regex_match "suspicious.*sign.*[io]n"
    subject.subject regex_match "suspicious.activit"
    subject.subject regex_match "temporar(il)?y deactivate"
    subject.subject regex_match "temporar[il1]{2}y disab[li]ed"
    subject.subject regex_match "temporarily.*lock"
    subject.subject regex_match "termination.*notice"
    subject.subject regex_match "un-?usua[li].activity"
    subject.subject regex_match "unable.*deliver"
    subject.subject regex_match "unauthorized.*activit"
    subject.subject regex_match "unauthorized.device"
    subject.subject regex_match "undelivered message"
    subject.subject regex_match "unread.*doc"
    subject.subject regex_match "unrecognized login attempt"
    subject.subject regex_match "unusual signin"
    subject.subject regex_match "unusual.activity"
    subject.subject regex_match "upgrade immediately"
    subject.subject regex_match "upgrade.*account"
    subject.subject regex_match "upgrade.notice"
    subject.subject regex_match "urgent message"
    subject.subject regex_match "urgent"
    subject.subject regex_match "urgent.verification"
    subject.subject regex_match "v[il1]o[li1]at[il1]on security"
    subject.subject regex_match "va[il1]{1}date.*ma[il1]{2}[ -]?box"
    subject.subject regex_match "verification ?-?require"
    subject.subject regex_match "verification( )?-?need"
    subject.subject regex_match "verify.your?.account"
    subject.subject regex_match "w2"
    subject.subject regex_match "wants to share"
    subject.subject regex_match "web ?-?ma[il1]{2}"
    subject.subject regex_match "web[ -]?ma[il1]{2}"
    subject.subject regex_match "will.be.suspended"
    subject.subject regex_match "you have notifications pending"
    subject.subject regex_match "your (customer )?account .as"
    subject.subject regex_match "your account"
    subject.subject regex_match "your amazon order"
    subject.subject regex_match "your document settlement"
    subject.subject regex_match "your order with amazon"
    subject.subject regex_match "your password has been compromised"
    subject.subject regex_match "your.office.365"
    subject.subject regex_match "your.online.access"
  not
    and
      attachments length_compare "0"
      attachments length_compare "3"
       macro "all(attachments)"
  headers.return_path.domain.domain ne "calendar-server.bounces.google.com"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
attachmentslength_compare1excludes:attachments field:"attachments" value:"1"
subject.subjectregex_match(?:(Report\sDomain).*(Submitter).*(Report-ID))excludes:subject.subject field:"subject.subject" value:"(?:(Report\sDomain).*(Submitter).*(Report-ID))"
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"
beta.ml_topic(body.current_thread.text).topicsarray_any(no value, null check)excludes:beta.ml_topic(body.current_thread.text).topics
attachmentslength_compare0excludes:attachments field:"attachments" value:"0"
attachmentslength_compare3excludes:attachments field:"attachments" value:"3"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textcontains
  • Your mailbox can no longer send or receive messages.
field:"body.current_thread.text" kind:contains value:"Your mailbox can no longer send or receive messages."
headers.in_reply_tois_null
  • (no value, null check)
field:"headers.in_reply_to" kind:is_null
headers.return_path.domain.domainne
  • calendar-server.bounces.google.com
field:"headers.return_path.domain.domain" kind:ne value:"calendar-server.bounces.google.com"
sender.display_nameregex_match
  • Admin
  • Administrator
  • Alert
  • Assistant
  • Authenticat(or|ion)
  • Benefits
  • Billing
  • Bonus
  • CEO
  • CFO
  • CIO
  • CTO
  • Chairman
  • Claim
  • Confirm
  • Cpanel Mail
  • Critical
  • Customer Service
  • Deal
  • Director
  • Discount
  • DocReq\b
  • Exclusive
  • Executive
  • Fax
  • Free
  • Gift
  • Helpdesk
  • Human Resources
  • Immediate
  • Important
  • Info
  • Information
  • Invoice
  • Lottery
  • Management
  • Manager
  • Member Services
  • Notification
  • Offer
  • +37 more values (see full rule source)
field:"sender.display_name" kind:regex_match
subject.subjectregex_match
  • (?:payroll|salary|bonus).*Distribution
  • (?:unrecognized|Unusual|suspicious|unknown) (?:log|sign).?[io]n attempt
  • 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
  • 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 has been limited
  • account v[il]o[li]at
  • account.*de-?activat
  • account.*locked
  • account.*re-verification
  • account.*security
  • account.*suspension
  • account.has.been
  • account.has.expired
  • account.will.be.blocked
  • action required
  • action.*required
  • activity.*acc(oun)?t
  • almost full
  • almost.full
  • apd notifi cation
  • app[li]e.[il]d
  • are you at your desk
  • are you available
  • attached file to docusign
  • attn_task
  • authenticate.*account
  • +159 more values (see full rule source)
field:"subject.subject" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Credential phishing: Engaging language with IPFS link

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

Body contains credential theft indicators, and contains a link to an IPFS site. IPFS has been recently observed hosting phishing sites.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesFree file host, Free subdomain host, IPFS

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.html
  • type

Rule body

type.inbound
and strings.ilike(body.html.display_text, "*expir*")
and strings.ilike(body.html.display_text, "*password*")
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft"
)
and any(body.links,
        strings.icontains(ml.link_analysis(.).effective_url.url, 'ipfs')
        or (
          regex.icontains(ml.link_analysis(.).effective_url.path,
                          '[\.-/]ipfs|ipfs[\.-/]'
          )
          and ml.link_analysis(.).effective_url.domain.domain not in $org_domains
          and (
            (
              // don't include high rep domains
              ml.link_analysis(.).effective_url.domain.domain not in $tranco_1m
              and ml.link_analysis(.).effective_url.domain.domain not in $umbrella_1m
            )
            // if it's in Tranco or Umbrella, still include it if it's one of these
            or ml.link_analysis(.).effective_url.domain.domain in $free_file_hosts
            or ml.link_analysis(.).effective_url.domain.root_domain in $free_file_hosts
            or ml.link_analysis(.).effective_url.domain.root_domain in $free_subdomain_hosts
          )
        )
)

Detection logic

Scope: inbound message.

Body contains credential theft indicators, and contains a link to an IPFS site. IPFS has been recently observed hosting phishing sites.

  1. inbound message
  2. body.html.display_text matches '*expir*'
  3. body.html.display_text matches '*password*'
  4. any of ml.nlu_classifier(body.current_thread.text).intents where:
    • .name is 'cred_theft'
  5. any of body.links where any holds:
    • ml.link_analysis(.).effective_url.url contains 'ipfs'
    • all of:
      • ml.link_analysis(.).effective_url.path matches '[\\.-/]ipfs|ipfs[\\.-/]'
      • ml.link_analysis(.).effective_url.domain.domain not in $org_domains
      • any of:
        • all of:
          • ml.link_analysis(.).effective_url.domain.domain not in $tranco_1m
          • ml.link_analysis(.).effective_url.domain.domain not in $umbrella_1m
        • ml.link_analysis(.).effective_url.domain.domain in $free_file_hosts
        • ml.link_analysis(.).effective_url.domain.root_domain in $free_file_hosts
        • ml.link_analysis(.).effective_url.domain.root_domain in $free_subdomain_hosts

Inspects: body.current_thread.text, body.html.display_text, body.links, type.inbound. Sensors: ml.link_analysis, ml.nlu_classifier, regex.icontains, strings.icontains, strings.ilike. Reference lists: $free_file_hosts, $free_subdomain_hosts, $org_domains, $tranco_1m, $umbrella_1m.

Indicators matched (5)

FieldMatchValue
strings.ilikesubstring*expir*
strings.ilikesubstring*password*
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
strings.icontainssubstringipfs
regex.icontainsregex[\.-/]ipfs|ipfs[\.-/]

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    or
      and
        or
          and
            ml.link_analysis func_call "ml.link_analysis(body.links[]).effective_url.domain.domain not in tranco_1m"
            ml.link_analysis func_call "ml.link_analysis(body.links[]).effective_url.domain.domain not in umbrella_1m"
          ml.link_analysis func_call "ml.link_analysis(body.links[]).effective_url.domain.domain in free_file_hosts"
          ml.link_analysis func_call "ml.link_analysis(body.links[]).effective_url.domain.root_domain in free_file_hosts"
          ml.link_analysis func_call "ml.link_analysis(body.links[]).effective_url.domain.root_domain in free_subdomain_hosts"
        ml.link_analysis func_call "ml.link_analysis(body.links[]).effective_url.domain.domain not in org_domains"
        ml.link_analysis(body.links[]).effective_url.path regex_match "[\\.-/]ipfs|ipfs[\\.-/]"
      ml.link_analysis(body.links[]).effective_url.url contains "ipfs"
  any(ml.nlu_classifier(body.current_thread.text).intents)
    ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
  body.html.display_text match "expir"
  body.html.display_text match "password"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Credential phishing: Fake password expiration from new and unsolicited sender

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

This rule looks for password expiration verbiage in the subject and body. Requiring between 1 - 9 links, a short body, and NLU in addition to statically specified term anchors. High trust senders are also negated.

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
  • headers
  • headers.auth_summary
  • headers.hops
  • recipients
  • recipients.to
  • sender.email
  • subject
  • type

Rule body

type.inbound

// few links which are not in $org_domains
and 0 < length(filter(body.links, .href_url.domain.domain not in $org_domains)) <= 10

// no attachments or suspicious attachment
and (
  length(attachments) == 0
  or any(filter(attachments, .file_type in ("pdf", "doc", "docx")),
         any(file.explode(.),
             .scan.entropy.entropy > 7 and length(.scan.ocr.raw) < 20
         )
  )
  // or there are duplicate pdfs in name
  or (
    length(filter(attachments, .file_type == "pdf")) > length(distinct(filter(attachments,
                                                                              .file_type == "pdf"
                                                                       ),
                                                                       .file_name
                                                              )
    )
    or 
    // all PDFs are the same MD5
    length(distinct(filter(attachments, .file_type == "pdf"), .md5)) == 1
    // the attachments are all images and not too many attachments
    or (
      all(attachments, .file_type in $file_types_images)
      and 0 < length(attachments) < 6
      // any of those attachments are Microsoft branded
      and any(attachments,
              any(ml.logo_detect(.).brands,
                  (
                    strings.istarts_with(.name, "Microsoft")
                    or .name == "Generic Webmail"
                  )
                  and .confidence == "high"
              )
              // it's just an icon
              or length(beta.ocr(.).text) < 20
              or beta.parse_exif(.).image_height == beta.parse_exif(.).image_width
      )
    )
  )
)

// body contains expire, expiration, loose, lose
and (
  regex.icontains(body.current_thread.text,
                  '(expir(e(d|s)?|ation|s)?|\blo(o)?se\b|(?:offices?|microsoft).365|re.{0,3}confirm)|due for update'
  )
  and not strings.icontains(body.current_thread.text, 'link expires in ')
)
and (
  // subject or body contains account or access
  any([subject.subject, body.current_thread.text],
      regex.icontains(., "account|access|your email|mailbox")
  )
  // suspicious use of recipients email address
  or any(recipients.to,
         any([subject.subject, body.current_thread.text],
             strings.icontains(strings.replace_confusables(.),
                               ..email.local_part
             )
             or strings.icontains(strings.replace_confusables(.), ..email.email)
         )
  )
)

// subject or body must contains password
and any([
          strings.replace_confusables(subject.subject),
          strings.replace_confusables(body.current_thread.text)
        ],
        regex.icontains(., '\bpassword\b', '\bmulti.?factor\b')
)
and (
  any(ml.nlu_classifier(strings.replace_confusables(body.current_thread.text)).intents,
      .name == "cred_theft" and .confidence == "high"
  )
  or 3 of (
    strings.icontains(strings.replace_confusables(body.current_thread.text),
                      'password'
    ),
    regex.icontains(strings.replace_confusables(body.current_thread.text),
                    'password\s*(?:\w+\s+){0,4}\s*reconfirm'
    ),
    regex.icontains(strings.replace_confusables(body.current_thread.text),
                    'keep\s*(?:\w+\s+){0,4}\s*password'
    ),
    strings.icontains(strings.replace_confusables(body.current_thread.text),
                      'password is due'
    ),
    strings.icontains(strings.replace_confusables(body.current_thread.text),
                      'expiration'
    ),
    strings.icontains(strings.replace_confusables(body.current_thread.text),
                      'expire'
    ),
    strings.icontains(strings.replace_confusables(body.current_thread.text),
                      'expiring'
    ),
    strings.icontains(strings.replace_confusables(body.current_thread.text),
                      'kindly'
    ),
    strings.icontains(strings.replace_confusables(body.current_thread.text),
                      'renew'
    ),
    strings.icontains(strings.replace_confusables(body.current_thread.text),
                      'review'
    ),
    strings.icontains(strings.replace_confusables(body.current_thread.text),
                      'click below'
    ),
    strings.icontains(strings.replace_confusables(body.current_thread.text),
                      'kicked out'
    ),
    strings.icontains(strings.replace_confusables(body.current_thread.text),
                      'required now'
    ),
    strings.icontains(strings.replace_confusables(body.current_thread.text),
                      'immediate action'
    ),
    strings.icontains(strings.replace_confusables(body.current_thread.text),
                      'security update'
    ),
    strings.icontains(strings.replace_confusables(body.current_thread.text),
                      'blocked'
    ),
    strings.icontains(strings.replace_confusables(body.current_thread.text),
                      'locked'
    ),
    strings.icontains(strings.replace_confusables(body.current_thread.text),
                      'interruption'
    ),
    strings.icontains(strings.replace_confusables(body.current_thread.text),
                      'action is not taken'
    ),
  )
)

// body length between 200 and 2000
and (
  200 < length(body.current_thread.text) < 2000

  // excessive whitespace
  or (
    regex.icontains(body.html.raw, '(?:(?:<br\s*/?>\s*){20,}|\n{20,})')
    or regex.icontains(body.html.raw, '(?:<p[^>]*>\s*<br\s*/?>\s*</p>\s*){30,}')
    or regex.icontains(body.html.raw,
                       '(?:<p class=".*?"><span style=".*?"><o:p>&nbsp;</o:p></span></p>\s*){30,}'
    )
    or regex.icontains(body.html.raw, '(?:<p>\s*&nbsp;\s*</p>\s*){7,}')
    or regex.icontains(body.html.raw, '(?:<p>\s*&nbsp;\s*</p>\s*<br>\s*){7,}')
    or regex.icontains(body.html.raw,
                       '(?:<p[^>]*>\s*&nbsp;\s*<br>\s*</p>\s*){5,}'
    )
    or regex.icontains(body.html.raw, '(?:<p[^>]*>&nbsp;</p>\s*){7,}')
  )
)

// a body link does not match the sender domain
and any(body.links,
        (
          .href_url.domain.root_domain != sender.email.domain.root_domain
          // or link URL contains an IPv4 address
          or (
            .href_url.domain.root_domain is null
            and regex.icontains(.href_url.url, '(\d{1,3}.){3}\d{1,3}')
          )
        )
        and .href_url.domain.root_domain not in $org_domains
)

// and no false positives and not solicited
and (
  (
    not profile.by_sender_email().any_messages_benign
    and not profile.by_sender_email().solicited
  )
  or (
    sender.email.domain.domain in $org_domains
    and not headers.auth_summary.spf.pass
  )
)

// not a reply
and (length(headers.references) == 0 or headers.in_reply_to 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 (
      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
)

Detection logic

Scope: inbound message.

This rule looks for password expiration verbiage in the subject and body. Requiring between 1 - 9 links, a short body, and NLU in addition to statically specified term anchors. High trust senders are also negated.

  1. inbound message
  2. all of:
    • length(filter(body.links, .href_url.domain.domain not in $org_domains)) > 0
    • length(filter(body.links, .href_url.domain.domain not in $org_domains)) ≤ 10
  3. any of:
    • length(attachments) is 0
    • any of filter(attachments) where:
      • any of file.explode(.) where all hold:
        • .scan.entropy.entropy > 7
        • length(.scan.ocr.raw) < 20
    • any of:
      • length(filter(attachments, .file_type == 'pdf')) > length(distinct(filter(attachments, .file_type == 'pdf'), .file_name))
      • length(distinct(filter(attachments, .file_type == 'pdf'), .md5)) is 1
      • all of:
        • all of attachments where:
          • .file_type in $file_types_images
        • all of:
          • length(attachments) > 0
          • length(attachments) < 6
        • any of attachments where any holds:
          • any of ml.logo_detect(.).brands where all hold:
            • any of:
              • .name starts with 'Microsoft'
              • .name is 'Generic Webmail'
            • .confidence is 'high'
          • length(beta.ocr(.).text) < 20
          • beta.parse_exif(.).image_height is beta.parse_exif(.).image_width
  4. all of:
    • body.current_thread.text matches '(expir(e(d|s)?|ation|s)?|\\blo(o)?se\\b|(?:offices?|microsoft).365|re.{0,3}confirm)|due for update'
    • not:
      • body.current_thread.text contains 'link expires in '
  5. any of:
    • any of [subject.subject, body.current_thread.text] where:
      • . matches 'account|access|your email|mailbox'
    • any of recipients.to where:
      • any of [subject.subject, body.current_thread.text] where any holds:
        • strings.icontains(strings.replace_confusables(.))
        • strings.icontains(strings.replace_confusables(.))
  6. any of [strings.replace_confusables(subject.subject), strings.replace_confusables(body.current_thread.text)] where:
    • . matches any of 2 patterns
      • \bpassword\b
      • \bmulti.?factor\b
  7. any of:
    • any of ml.nlu_classifier(strings.replace_confusables(body.current_thread.text)).intents where all hold:
      • .name is 'cred_theft'
      • .confidence is 'high'
    • at least 3 of:
      • strings.replace_confusables(body.current_thread.text) contains 'password'
      • strings.replace_confusables(body.current_thread.text) matches 'password\\s*(?:\\w+\\s+){0,4}\\s*reconfirm'
      • strings.replace_confusables(body.current_thread.text) matches 'keep\\s*(?:\\w+\\s+){0,4}\\s*password'
      • strings.replace_confusables(body.current_thread.text) contains 'password is due'
      • strings.replace_confusables(body.current_thread.text) contains 'expiration'
      • strings.replace_confusables(body.current_thread.text) contains 'expire'
      • strings.replace_confusables(body.current_thread.text) contains 'expiring'
      • strings.replace_confusables(body.current_thread.text) contains 'kindly'
      • strings.replace_confusables(body.current_thread.text) contains 'renew'
      • strings.replace_confusables(body.current_thread.text) contains 'review'
      • strings.replace_confusables(body.current_thread.text) contains 'click below'
      • strings.replace_confusables(body.current_thread.text) contains 'kicked out'
      • strings.replace_confusables(body.current_thread.text) contains 'required now'
      • strings.replace_confusables(body.current_thread.text) contains 'immediate action'
      • strings.replace_confusables(body.current_thread.text) contains 'security update'
      • strings.replace_confusables(body.current_thread.text) contains 'blocked'
      • strings.replace_confusables(body.current_thread.text) contains 'locked'
      • strings.replace_confusables(body.current_thread.text) contains 'interruption'
      • strings.replace_confusables(body.current_thread.text) contains 'action is not taken'
  8. any of:
    • all of:
      • length(body.current_thread.text) > 200
      • length(body.current_thread.text) < 2000
    • body.html.raw matches any of 7 patterns
      • (?:(?:<br\s*/?>\s*){20,}|\n{20,})
      • (?:<p[^>]*>\s*<br\s*/?>\s*</p>\s*){30,}
      • (?:<p class=".*?"><span style=".*?"><o:p>&nbsp;</o:p></span></p>\s*){30,}
      • (?:<p>\s*&nbsp;\s*</p>\s*){7,}
      • (?:<p>\s*&nbsp;\s*</p>\s*<br>\s*){7,}
      • (?:<p[^>]*>\s*&nbsp;\s*<br>\s*</p>\s*){5,}
      • (?:<p[^>]*>&nbsp;</p>\s*){7,}
  9. any of body.links where all hold:
    • any of:
      • .href_url.domain.root_domain is not sender.email.domain.root_domain
      • all of:
        • .href_url.domain.root_domain is missing
        • .href_url.url matches '(\\d{1,3}.){3}\\d{1,3}'
    • .href_url.domain.root_domain not in $org_domains
  10. any of:
    • all of:
      • not:
        • profile.by_sender_email().any_messages_benign
      • not:
        • profile.by_sender_email().solicited
    • all of:
      • sender.email.domain.domain in $org_domains
      • not:
        • headers.auth_summary.spf.pass
  11. any of:
    • length(headers.references) is 0
    • headers.in_reply_to is missing
  12. 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

Inspects: attachments[].file_type, body.current_thread.text, body.html.raw, body.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.url, headers.auth_summary.spf.pass, headers.hops, headers.hops[].authentication_results.dmarc, headers.in_reply_to, headers.references, recipients.to, recipients.to[].email.email, recipients.to[].email.local_part, sender.email.domain.domain, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: beta.ocr, beta.parse_exif, file.explode, ml.logo_detect, ml.nlu_classifier, profile.by_sender_email, regex.icontains, strings.icontains, strings.ilike, strings.istarts_with, strings.replace_confusables. Reference lists: $file_types_images, $high_trust_sender_root_domains, $org_domains.

Indicators matched (41)

FieldMatchValue
attachments[].file_typememberpdf
attachments[].file_typememberdoc
attachments[].file_typememberdocx
attachments[].file_typeequalspdf
strings.istarts_withprefixMicrosoft
ml.logo_detect(attachments[]).brands[].nameequalsGeneric Webmail
ml.logo_detect(attachments[]).brands[].confidenceequalshigh
regex.icontainsregex(expir(e(d|s)?|ation|s)?|\blo(o)?se\b|(?:offices?|microsoft).365|re.{0,3}confirm)|due for update
regex.icontainsregexaccount|access|your email|mailbox
regex.icontainsregex\bpassword\b
regex.icontainsregex\bmulti.?factor\b
ml.nlu_classifier(strings.replace_confusables(body.current_thread.text)).intents[].nameequalscred_theft
29 more
ml.nlu_classifier(strings.replace_confusables(body.current_thread.text)).intents[].confidenceequalshigh
strings.icontainssubstringpassword
regex.icontainsregexpassword\s*(?:\w+\s+){0,4}\s*reconfirm
regex.icontainsregexkeep\s*(?:\w+\s+){0,4}\s*password
strings.icontainssubstringpassword is due
strings.icontainssubstringexpiration
strings.icontainssubstringexpire
strings.icontainssubstringexpiring
strings.icontainssubstringkindly
strings.icontainssubstringrenew
strings.icontainssubstringreview
strings.icontainssubstringclick below
strings.icontainssubstringkicked out
strings.icontainssubstringrequired now
strings.icontainssubstringimmediate action
strings.icontainssubstringsecurity update
strings.icontainssubstringblocked
strings.icontainssubstringlocked
strings.icontainssubstringinterruption
strings.icontainssubstringaction is not taken
regex.icontainsregex(?:(?:<br\s*/?>\s*){20,}|\n{20,})
regex.icontainsregex(?:<p[^>]*>\s*<br\s*/?>\s*</p>\s*){30,}
regex.icontainsregex(?:<p class=".*?"><span style=".*?"><o:p>&nbsp;</o:p></span></p>\s*){30,}
regex.icontainsregex(?:<p>\s*&nbsp;\s*</p>\s*){7,}
regex.icontainsregex(?:<p>\s*&nbsp;\s*</p>\s*<br>\s*){7,}
regex.icontainsregex(?:<p[^>]*>\s*&nbsp;\s*<br>\s*</p>\s*){5,}
regex.icontainsregex(?:<p[^>]*>&nbsp;</p>\s*){7,}
regex.icontainsregex(\d{1,3}.){3}\d{1,3}
strings.ilikesubstring*fail

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      any(attachments)
        or
          any(ml.logo_detect(attachments).brands)
            and
              or
                ml.logo_detect(attachments[]).brands[].name eq "Generic Webmail"
                ml.logo_detect(attachments[]).brands[].name starts_with "Microsoft"
              ml.logo_detect(attachments[]).brands[].confidence eq "high"
          beta.ocr(attachments[]).text length_compare "20"
          beta.parse_exif func_call "beta.parse_exif(attachments[]).image_height == beta.parse_exif(attachments[]).image_width"
      attachments length_compare "0"
      attachments length_compare "6"
       macro "all(attachments)"
    any(filter(attachments))
      any(file.explode(filter(attachments)))
        and
          file.explode(filter(attachments)[])[].scan.entropy.entropy gt "7"
          file.explode(filter(attachments)[])[].scan.ocr.raw length_compare "20"
    attachments length_compare "0"
    distinct(filter(attachments, .file_type == 'pdf'), .md5) length_compare "1"
    length func_call "length(filter(attachments, .file_type == 'pdf')) > length(distinct(filter(attachments, .file_type == 'pdf'), .file_name))"
  any(body.links)
    and
      or
        and
          body.links.href_url.domain.root_domain is_null
          body.links.href_url.url regex_match "(\\d{1,3}.){3}\\d{1,3}"
        body.links.href_url.domain.root_domain cross_field_compare "sender.email.domain.root_domain"
       macro "body.links[].href_url.domain.root_domain not in org_domains"
  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"
  or
    and
      not
        headers.auth_summary.spf.pass eq "true"
       macro "sender.email.domain.domain in org_domains"
    and
      not
        profile.by_sender_email func_call "profile.by_sender_email().any_messages_benign"
      not
        profile.by_sender_email func_call "profile.by_sender_email().solicited"
  or
    any(ml.nlu_classifier(strings.replace_confusables(body.current_thread.text)).intents)
      and
        ml.nlu_classifier(strings.replace_confusables(body.current_thread.text)).intents.confidence eq "high"
        ml.nlu_classifier(strings.replace_confusables(body.current_thread.text)).intents.name eq "cred_theft"
    strings.replace_confusables(body.current_thread.text) contains "action is not taken"
    strings.replace_confusables(body.current_thread.text) contains "blocked"
    strings.replace_confusables(body.current_thread.text) contains "click below"
    strings.replace_confusables(body.current_thread.text) contains "expiration"
    strings.replace_confusables(body.current_thread.text) contains "expire"
    strings.replace_confusables(body.current_thread.text) contains "expiring"
    strings.replace_confusables(body.current_thread.text) contains "immediate action"
    strings.replace_confusables(body.current_thread.text) contains "interruption"
    strings.replace_confusables(body.current_thread.text) contains "kicked out"
    strings.replace_confusables(body.current_thread.text) contains "kindly"
    strings.replace_confusables(body.current_thread.text) contains "locked"
    strings.replace_confusables(body.current_thread.text) contains "password is due"
    strings.replace_confusables(body.current_thread.text) contains "password"
    strings.replace_confusables(body.current_thread.text) contains "renew"
    strings.replace_confusables(body.current_thread.text) contains "required now"
    strings.replace_confusables(body.current_thread.text) contains "review"
    strings.replace_confusables(body.current_thread.text) contains "security update"
    strings.replace_confusables(body.current_thread.text) regex_match "keep\\s*(?:\\w+\\s+){0,4}\\s*password"
    strings.replace_confusables(body.current_thread.text) regex_match "password\\s*(?:\\w+\\s+){0,4}\\s*reconfirm"
  or
    any(recipients.to)
      any([subject.subject, body.current_thread.text])
        strings.icontains func_call "strings.icontains(strings.replace_confusables([subject.subject, body.current_thread.text][]))"
    any([subject.subject, body.current_thread.text])
      [subject.subject, body.current_thread.text] regex_match "account|access|your email|mailbox"
  any([strings.replace_confusables(subject.subject), strings.replace_confusables(body.current_thread.text)])
    or
      [strings.replace_confusables(subject.subject), strings.replace_confusables(body.current_thread.text)] regex_match "\\bmulti.?factor\\b"
      [strings.replace_confusables(subject.subject), strings.replace_confusables(body.current_thread.text)] regex_match "\\bpassword\\b"
  or
    and
      body.current_thread.text length_compare "200"
      body.current_thread.text length_compare "2000"
    body.html.raw regex_match "(?:(?:<br\\s*/?>\\s*){20,}|\\n{20,})"
    body.html.raw regex_match "(?:<p class=\".*?\"><span style=\".*?\"><o:p>&nbsp;</o:p></span></p>\\s*){30,}"
    body.html.raw regex_match "(?:<p>\\s*&nbsp;\\s*</p>\\s*){7,}"
    body.html.raw regex_match "(?:<p>\\s*&nbsp;\\s*</p>\\s*<br>\\s*){7,}"
    body.html.raw regex_match "(?:<p[^>]*>&nbsp;</p>\\s*){7,}"
    body.html.raw regex_match "(?:<p[^>]*>\\s*&nbsp;\\s*<br>\\s*</p>\\s*){5,}"
    body.html.raw regex_match "(?:<p[^>]*>\\s*<br\\s*/?>\\s*</p>\\s*){30,}"
  not
    body.current_thread.text contains "link expires in "
  or
    headers.in_reply_to is_null
    headers.references length_compare "0"
  body.current_thread.text regex_match "(expir(e(d|s)?|ation|s)?|\\blo(o)?se\\b|(?:offices?|microsoft).365|re.{0,3}confirm)|due for update"
  filter(body.links, .href_url.domain.domain not in $org_domains) length_compare "0"
  filter(body.links, .href_url.domain.domain not in $org_domains) length_compare "10"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
body.current_thread.textcontainslink expires in excludes:body.current_thread.text field:"body.current_thread.text" value:"link expires in "

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textregex_match
    • (expir(e(d|s)?|ation|s)?|\blo(o)?se\b|(?:offices?|microsoft).365|re.{0,3}confirm)
    • due for update
field:"body.current_thread.text" kind:regex_match
body.html.rawregex_match
  • (?:(?:<br\s*/?>\s*){20,}|\n{20,})
  • (?:<p class=".*?"><span style=".*?"><o:p> </o:p></span></p>\s*){30,}
  • (?:<p>\s* \s*</p>\s*){7,}
  • (?:<p>\s* \s*</p>\s*<br>\s*){7,}
  • (?:<p[^>]*>\s*<br\s*/?>\s*</p>\s*){30,}
  • (?:<p[^>]*>\s* \s*<br>\s*</p>\s*){5,}
  • (?:<p[^>]*> </p>\s*){7,}
field:"body.html.raw" kind:regex_match
headers.in_reply_tois_null
  • (no value, null check)
field:"headers.in_reply_to" kind:is_null
strings.replace_confusables(body.current_thread.text)contains
  • action is not taken
  • blocked
  • click below
  • expiration
  • expire
  • expiring
  • immediate action
  • interruption
  • kicked out
  • kindly
  • locked
  • password
  • password is due
  • renew
  • required now
  • review
  • security update
field:"strings.replace_confusables(body.current_thread.text)" kind:contains
strings.replace_confusables(body.current_thread.text)regex_match
  • keep\s*(?:\w+\s+){0,4}\s*password
  • password\s*(?:\w+\s+){0,4}\s*reconfirm
field:"strings.replace_confusables(body.current_thread.text)" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Credential phishing: Fake storage alerts (unsolicited)

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

This rule targets credential phishing attempts disguised as storage space alerts, activating for inbound emails with specific storage-related keywords and evaluating sender trustworthiness and history.

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.links
  • headers
  • headers.auth_summary
  • headers.domains
  • sender.email
  • subject
  • type

Rule body

type.inbound
and (
  (
    0 < length(body.links) < 8
    and any([subject.subject, sender.display_name],
            regex.icontains(., "(?:storage|mailbox)")
    )
  )
  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
    //
    any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents,
        .name == "cred_theft" 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",
                        "email.{0,50}storage",
                        "total.{0,50}storage",
                        "storage.{0,50}limit",
                        "cloud.{0,50}update payment",
    )
    and not strings.ilike(beta.ocr(file.message_screenshot()).text,
                          "*free plan*"
    )
  )
  or (
    any(body.links,
        // fingerprints of a hyperlinked image
        .display_text is null
        and .display_url.url is null
        and (
          .href_url.domain.root_domain in $free_file_hosts
          or .href_url.domain.root_domain == "beehiiv.com"
        )
    )
    and length(attachments) == 1
    and all(attachments,
            .file_type in $file_types_images
            and .size > 2000
            and any(file.explode(.),
                    regex.icontains(.scan.ocr.raw,
                                    "storage.{0,50}full",
                                    "free.{0,50}upgrade",
                                    "storage.{0,50}details",
                                    "storage.{0,50}quot",
                                    "email.{0,50}storage",
                                    "total.{0,50}storage"
                    )
            )
    )
  )
)
and (
  strings.icontains(subject.subject,
                    "exceeded",
                    "out of",
                    "mailbox",
                    "icloud",
                    "all storage used",
                    "compliance",
                    "critical",
                    "problem",
                    "max storage",
                    "be deleted",
                    "action required",
                    "undelivered messages",
                    "review storage",
                    "subscription terminated",
                    "final notice",
                    "data retention",
                    "file deletion",
                    "suspend"
  )
  or regex.icontains(subject.subject,
                     '\bfull\b',
                     '\blimit(?:ed|\b)',
                     "storage (?:space|capacity warning|is used)",
                     '(?:upgrade|\bact\b) (?:today|now)',
                     'at (?:100|9[0-9](?:\.\d+)?|one[\s-]?hundred) ?(?:percent|%)',
                     'back(?:ing|ed)? up'
  )
)

// negate customer service requests about storage
and not any(ml.nlu_classifier(body.current_thread.text).topics,
            .name == "Customer Service and Support" and .confidence == "high"
)

// negate links to loopnet.com - a popular commerical property listing service
and not (any(body.links, .href_url.domain.root_domain == "loopnet.com"))

// negate legitimate sharepoint storage alerts
and (
  (
    sender.email.email == "no-reply@sharepointonline.com"
    and not headers.auth_summary.dmarc.pass
    and (
      not all(body.links,
              .href_url.domain.root_domain in~ (
                "sharepoint.com",
                "microsoft.com",
                "aka.ms"
              )
      )
    )
  )
  or sender.email.email != "no-reply@sharepointonline.com"
)

// negate legitimate iCloud China storage alerts
and (
  (
    sender.email.email == "noreply@icloud.com.cn"
    and not headers.auth_summary.dmarc.pass
    and (
      not all(body.links,
              .href_url.domain.root_domain in~ ("icloud.com", "aka.ms")
      )
    )
  )
  or sender.email.email != "noreply@icloud.com.cn"
)

// negate bouncebacks and undeliverables
and not any(attachments,
            .content_type in (
              "message/global-delivery-status",
              "message/delivery-status",
            )
            or (
              .content_type == "message/rfc822"
              and any(file.parse_eml(.).attachments,
                      .content_type in (
                        "message/global-delivery-status",
                        "message/delivery-status",
                      )
              )
            )
)

// 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
)
// negate instances where proofpoint sends a review of a reported message via analyzer
and not (
  sender.email.email == "analyzer@analyzer.securityeducation.com"
  and any(headers.domains, .root_domain == "pphosted.com")
  and headers.auth_summary.spf.pass
  and headers.auth_summary.dmarc.pass
)

Detection logic

Scope: inbound message.

This rule targets credential phishing attempts disguised as storage space alerts, activating for inbound emails with specific storage-related keywords and evaluating sender trustworthiness and history.

  1. inbound message
  2. any of:
    • all of:
      • all of:
        • length(body.links) > 0
        • length(body.links) < 8
      • any of [subject.subject, sender.display_name] where:
        • . matches '(?:storage|mailbox)'
    • all of:
      • any of ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents where all hold:
        • .name is 'cred_theft'
        • .confidence is 'high'
      • beta.ocr(file.message_screenshot()).text matches any of 8 patterns
        • storage.{0,50}full
        • free.{0,50}upgrade
        • storage.{0,50}details
        • storage.{0,50}quot
        • email.{0,50}storage
        • total.{0,50}storage
        • storage.{0,50}limit
        • cloud.{0,50}update payment
      • not:
        • beta.ocr(file.message_screenshot()).text matches '*free plan*'
    • all of:
      • any of body.links where all hold:
        • .display_text is missing
        • .display_url.url is missing
        • any of:
          • .href_url.domain.root_domain in $free_file_hosts
          • .href_url.domain.root_domain is 'beehiiv.com'
      • length(attachments) is 1
      • all of attachments where all hold:
        • .file_type in $file_types_images
        • .size > 2000
        • any of file.explode(.) where:
          • .scan.ocr.raw matches any of 6 patterns
            • storage.{0,50}full
            • free.{0,50}upgrade
            • storage.{0,50}details
            • storage.{0,50}quot
            • email.{0,50}storage
            • total.{0,50}storage
  3. any of:
    • subject.subject contains any of 18 patterns
      • exceeded
      • out of
      • mailbox
      • icloud
      • all storage used
      • compliance
      • critical
      • problem
      • max storage
      • be deleted
      • action required
      • undelivered messages
      • review storage
      • subscription terminated
      • final notice
      • data retention
      • file deletion
      • suspend
    • subject.subject matches any of 6 patterns
      • \bfull\b
      • \blimit(?:ed|\b)
      • storage (?:space|capacity warning|is used)
      • (?:upgrade|\bact\b) (?:today|now)
      • at (?:100|9[0-9](?:\.\d+)?|one[\s-]?hundred) ?(?:percent|%)
      • back(?:ing|ed)? up
  4. not:
    • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
      • .name is 'Customer Service and Support'
      • .confidence is 'high'
  5. not:
    • any of body.links where:
      • .href_url.domain.root_domain is 'loopnet.com'
  6. any of:
    • all of:
      • sender.email.email is 'no-reply@sharepointonline.com'
      • not:
        • headers.auth_summary.dmarc.pass
      • not:
        • all of body.links where:
          • .href_url.domain.root_domain in ('sharepoint.com', 'microsoft.com', 'aka.ms')
    • sender.email.email is not 'no-reply@sharepointonline.com'
  7. any of:
    • all of:
      • sender.email.email is 'noreply@icloud.com.cn'
      • not:
        • headers.auth_summary.dmarc.pass
      • not:
        • all of body.links where:
          • .href_url.domain.root_domain in ('icloud.com', 'aka.ms')
    • sender.email.email is not 'noreply@icloud.com.cn'
  8. not:
    • any of attachments where any holds:
      • .content_type in ('message/global-delivery-status', 'message/delivery-status')
      • all of:
        • .content_type is 'message/rfc822'
        • any of file.parse_eml(.).attachments where:
          • .content_type in ('message/global-delivery-status', 'message/delivery-status')
  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
    • profile.by_sender().any_messages_malicious_or_spam
  11. not:
    • all of:
      • sender.email.email is 'analyzer@analyzer.securityeducation.com'
      • any of headers.domains where:
        • .root_domain is 'pphosted.com'
      • headers.auth_summary.spf.pass
      • headers.auth_summary.dmarc.pass

Inspects: attachments[].content_type, attachments[].file_type, attachments[].size, body.current_thread.text, body.links, body.links[].display_text, body.links[].display_url.url, body.links[].href_url.domain.root_domain, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.domains, headers.domains[].root_domain, sender.display_name, sender.email.domain.root_domain, sender.email.email, subject.subject, type.inbound. Sensors: beta.ocr, file.explode, file.message_screenshot, file.parse_eml, ml.nlu_classifier, profile.by_sender, regex.icontains, strings.icontains, strings.ilike. Reference lists: $file_types_images, $free_file_hosts, $high_trust_sender_root_domains.

Indicators matched (38)

FieldMatchValue
regex.icontainsregex(?:storage|mailbox)
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents[].nameequalscred_theft
ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents[].confidenceequalshigh
regex.icontainsregexstorage.{0,50}full
regex.icontainsregexfree.{0,50}upgrade
regex.icontainsregexstorage.{0,50}details
regex.icontainsregexstorage.{0,50}quot
regex.icontainsregexemail.{0,50}storage
regex.icontainsregextotal.{0,50}storage
regex.icontainsregexstorage.{0,50}limit
regex.icontainsregexcloud.{0,50}update payment
body.links[].href_url.domain.root_domainequalsbeehiiv.com
26 more
strings.icontainssubstringexceeded
strings.icontainssubstringout of
strings.icontainssubstringmailbox
strings.icontainssubstringicloud
strings.icontainssubstringall storage used
strings.icontainssubstringcompliance
strings.icontainssubstringcritical
strings.icontainssubstringproblem
strings.icontainssubstringmax storage
strings.icontainssubstringbe deleted
strings.icontainssubstringaction required
strings.icontainssubstringundelivered messages
strings.icontainssubstringreview storage
strings.icontainssubstringsubscription terminated
strings.icontainssubstringfinal notice
strings.icontainssubstringdata retention
strings.icontainssubstringfile deletion
strings.icontainssubstringsuspend
regex.icontainsregex\bfull\b
regex.icontainsregex\blimit(?:ed|\b)
regex.icontainsregexstorage (?:space|capacity warning|is used)
regex.icontainsregex(?:upgrade|\bact\b) (?:today|now)
regex.icontainsregexat (?:100|9[0-9](?:\.\d+)?|one[\s-]?hundred) ?(?:percent|%)
regex.icontainsregexback(?:ing|ed)? up
sender.email.emailequalsno-reply@sharepointonline.com
sender.email.emailequalsnoreply@icloud.com.cn

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      any(body.links)
        and
          or
            body.links.href_url.domain.root_domain eq "beehiiv.com"
             macro "body.links[].href_url.domain.root_domain in free_file_hosts"
          body.links.display_text is_null
          body.links.display_url.url is_null
      attachments length_compare "1"
       macro "all(attachments)"
    and
      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"
      not
        beta.ocr(file.message_screenshot()).text match "free plan"
      or
        beta.ocr(file.message_screenshot()).text regex_match "cloud.{0,50}update payment"
        beta.ocr(file.message_screenshot()).text regex_match "email.{0,50}storage"
        beta.ocr(file.message_screenshot()).text regex_match "free.{0,50}upgrade"
        beta.ocr(file.message_screenshot()).text regex_match "storage.{0,50}details"
        beta.ocr(file.message_screenshot()).text regex_match "storage.{0,50}full"
        beta.ocr(file.message_screenshot()).text regex_match "storage.{0,50}limit"
        beta.ocr(file.message_screenshot()).text regex_match "storage.{0,50}quot"
        beta.ocr(file.message_screenshot()).text regex_match "total.{0,50}storage"
    and
      any([subject.subject, sender.display_name])
        [subject.subject, sender.display_name] regex_match "(?:storage|mailbox)"
      body.links length_compare "0"
      body.links length_compare "8"
  not
    any(attachments)
      or
        and
          any(file.parse_eml(attachments).attachments)
            file.parse_eml(attachments).attachments.content_type in ["message/delivery-status", "message/global-delivery-status"]
          attachments.content_type eq "message/rfc822"
        attachments.content_type in ["message/delivery-status", "message/global-delivery-status"]
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
      not
         macro "all(body.links)"
      sender.email.email eq "no-reply@sharepointonline.com"
    sender.email.email ne "no-reply@sharepointonline.com"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
      not
         macro "all(body.links)"
      sender.email.email eq "noreply@icloud.com.cn"
    sender.email.email ne "noreply@icloud.com.cn"
  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 eq "pphosted.com"
      headers.auth_summary.dmarc.pass eq "true"
      headers.auth_summary.spf.pass eq "true"
      sender.email.email eq "analyzer@analyzer.securityeducation.com"
  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 "Customer Service and Support"
  not
    any(body.links)
      body.links.href_url.domain.root_domain eq "loopnet.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"
  or
    subject.subject contains "action required"
    subject.subject contains "all storage used"
    subject.subject contains "be deleted"
    subject.subject contains "compliance"
    subject.subject contains "critical"
    subject.subject contains "data retention"
    subject.subject contains "exceeded"
    subject.subject contains "file deletion"
    subject.subject contains "final notice"
    subject.subject contains "icloud"
    subject.subject contains "mailbox"
    subject.subject contains "max storage"
    subject.subject contains "out of"
    subject.subject contains "problem"
    subject.subject contains "review storage"
    subject.subject contains "subscription terminated"
    subject.subject contains "suspend"
    subject.subject contains "undelivered messages"
    subject.subject regex_match "(?:upgrade|\\bact\\b) (?:today|now)"
    subject.subject regex_match "\\bfull\\b"
    subject.subject regex_match "\\blimit(?:ed|\\b)"
    subject.subject regex_match "at (?:100|9[0-9](?:\\.\\d+)?|one[\\s-]?hundred) ?(?:percent|%)"
    subject.subject regex_match "back(?:ing|ed)? up"
    subject.subject regex_match "storage (?:space|capacity warning|is used)"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
attachmentsarray_any(no value, null check)excludes:attachments
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.emaileqanalyzer@analyzer.securityeducation.comexcludes:sender.email.email field:"sender.email.email" value:"analyzer@analyzer.securityeducation.com"
ml.nlu_classifier(body.current_thread.text).topicsarray_any(no value, null check)excludes:ml.nlu_classifier(body.current_thread.text).topics
body.linksarray_any(no value, null check)excludes:body.links

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
beta.ocr(file.message_screenshot()).textregex_match
  • cloud.{0,50}update payment
  • email.{0,50}storage
  • free.{0,50}upgrade
  • storage.{0,50}details
  • storage.{0,50}full
  • storage.{0,50}limit
  • storage.{0,50}quot
  • total.{0,50}storage
field:"beta.ocr(file.message_screenshot()).text" kind:regex_match
sender.email.emaileq
  • no-reply@sharepointonline.com
  • noreply@icloud.com.cn
field:"sender.email.email" kind:eq
sender.email.emailne
  • no-reply@sharepointonline.com
  • noreply@icloud.com.cn
field:"sender.email.email" kind:ne
subject.subjectcontains
  • action required
  • all storage used
  • be deleted
  • compliance
  • critical
  • data retention
  • exceeded
  • file deletion
  • final notice
  • icloud
  • mailbox
  • max storage
  • out of
  • problem
  • review storage
  • subscription terminated
  • suspend
  • undelivered messages
field:"subject.subject" kind:contains
subject.subjectregex_match
  • (?:upgrade|\bact\b) (?:today|now)
  • \bfull\b
  • \blimit(?:ed|\b)
  • at (?:100|9[0-9](?:.\d+)?|one[\s-]?hundred) ?(?:percent|%)
  • back(?:ing|ed)? up
  • storage (?:space|capacity warning|is used)
field:"subject.subject" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Credential Phishing: Suspicious language, link, recipients and other indicators

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

The rule flags inbound messages with no visible recipients, contain all-caps text, and include links from certain free hosts. It also checks for signs of credential theft using machine learning classifiers and is from an untrusted sender.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.links
  • recipients
  • recipients.to
  • subject
  • type

Rule body

type.inbound

// no recipients defined
and (
  length(recipients.to) == 0
  or all(recipients.to, .display_name == "Undisclosed recipients")
)
and length(recipients.cc) == 0
and length(recipients.bcc) == 0
and any(body.links,

        // suspicious link
        // we've particularly seen 1drv.ms abused
        // if using the full list causes FPs, we can reduce the 
        // scope to a hard-coded list or add exclusions
        (
          .href_url.domain.domain in $free_file_hosts
          or .href_url.domain.root_domain in $free_file_hosts
          or .href_url.domain.root_domain in $free_subdomain_hosts
        )

        // link text is in all caps
        and regex.match(.display_text, "[A-Z ]+")
)

// any confidence cred_theft classification
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft"
)

// 'org' entity is in all caps
and any(ml.nlu_classifier(body.current_thread.text).entities,
        .name == "org" and regex.match(.text, "[A-Z ]+")
)

// subject is in all caps
and regex.match(subject.subject, "[A-Z ]+")
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.

The rule flags inbound messages with no visible recipients, contain all-caps text, and include links from certain free hosts. It also checks for signs of credential theft using machine learning classifiers and is from an untrusted sender.

  1. inbound message
  2. any of:
    • length(recipients.to) is 0
    • all of recipients.to where:
      • .display_name is 'Undisclosed recipients'
  3. length(recipients.cc) is 0
  4. length(recipients.bcc) is 0
  5. any of body.links where all hold:
    • any of:
      • .href_url.domain.domain in $free_file_hosts
      • .href_url.domain.root_domain in $free_file_hosts
      • .href_url.domain.root_domain in $free_subdomain_hosts
    • .display_text matches '[A-Z ]+'
  6. any of ml.nlu_classifier(body.current_thread.text).intents where:
    • .name is 'cred_theft'
  7. any of ml.nlu_classifier(body.current_thread.text).entities where all hold:
    • .name is 'org'
    • .text matches '[A-Z ]+'
  8. subject.subject matches '[A-Z ]+'
  9. 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: body.current_thread.text, body.links, body.links[].display_text, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, recipients.bcc, recipients.cc, recipients.to, recipients.to[].display_name, subject.subject, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender, regex.match. Reference lists: $free_file_hosts, $free_subdomain_hosts.

Indicators matched (4)

FieldMatchValue
recipients.to[].display_nameequalsUndisclosed recipients
regex.matchregex[A-Z ]+
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsorg

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)"
  any(body.links)
    and
      or
         macro "body.links[].href_url.domain.domain in free_file_hosts"
         macro "body.links[].href_url.domain.root_domain in free_file_hosts"
         macro "body.links[].href_url.domain.root_domain in free_subdomain_hosts"
      body.links.display_text regex_match "[A-Z ]+"
  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 regex_match "[A-Z ]+"
  any(ml.nlu_classifier(body.current_thread.text).intents)
    ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
  or
    recipients.to length_compare "0"
     macro "all(recipients.to)"
  recipients.bcc length_compare "0"
  recipients.cc length_compare "0"
  subject.subject regex_match "[A-Z ]+"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Credential Phishing: W-2 lure with inline SVG Windows logo

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

Detects inbound messages containing a link with W-2 display text and an inline SVG constructed from four colored rectangles approximating the Microsoft Windows logo. Threat actors use hand-crafted SVG elements rather than image attachments to bypass image-based detection and render a convincing Windows or Microsoft brand impersonation directly in the email body. The color matching uses fuzzy hex ranges to account for minor variations across campaigns.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, HTML smuggling, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.html
  • type

Rule body

type.inbound
// display text contains a reference to W2
and any(body.current_thread.links,
        regex.icontains(strings.replace_confusables(.display_text),
                        '(?:W|VV)\s*-?\s*2'
        )
)
// inline SVG that mimics the Windows logo
and regex.icontains(body.html.raw,
                    '<rect x="\d+" y="\d+" width="\d+" height="\d+" fill="#[c-f][0-9a-f][0-3][0-9a-f][0-3][0-9a-f]">\s*<\/rect>\s*<rect x="\d+" y="\d+" width="\d+" height="\d+" fill="#[0-3][0-9a-f][8-f][0-9a-f][2-6][0-9a-f]">\s*<\/rect>\s*<rect x="\d+" y="\d+" width="\d+" height="\d+" fill="#[0-3][0-9a-f][5-9][0-9a-f][a-f][0-9a-f]">\s*<\/rect>\s*<rect x="\d+" y="\d+" width="\d+" height="\d+" fill="#[c-f][0-9a-f][a-f][0-9a-f][0-3][0-9a-f]">\s*<\/rect>\s*<\/svg>\s*<\/td>'
)

Detection logic

Scope: inbound message.

Detects inbound messages containing a link with W-2 display text and an inline SVG constructed from four colored rectangles approximating the Microsoft Windows logo. Threat actors use hand-crafted SVG elements rather than image attachments to bypass image-based detection and render a convincing Windows or Microsoft brand impersonation directly in the email body. The color matching uses fuzzy hex ranges to account for minor variations across campaigns.

  1. inbound message
  2. any of body.current_thread.links where:
    • strings.replace_confusables(.display_text) matches '(?:W|VV)\\s*-?\\s*2'
  3. body.html.raw matches '<rect x="\\d+" y="\\d+" width="\\d+" height="\\d+" fill="#[c-f][0-9a-f][0-3][0-9a-f][0-3][0-9a-f]">\\s*<\\/rect>\\s*<rect x="\\d+" y="\\d+" width="\\d+" height="\\d+" fill="#[0-3][0-9a-f][8-f][0-9a-f][2-6][0-9a-f]">\\s*<\\/rect>\\s*<rect x="\\d+" y="\\d+" width="\\d+" height="\\d+" fill="#[0-3][0-9a-f][5-9][0-9a-f][a-f][0-9a-f]">\\s*<\\/rect>\\s*<rect x="\\d+" y="\\d+" width="\\d+" height="\\d+" fill="#[c-f][0-9a-f][a-f][0-9a-f][0-3][0-9a-f]">\\s*<\\/rect>\\s*<\\/svg>\\s*<\\/td>'

Inspects: body.current_thread.links, body.current_thread.links[].display_text, body.html.raw, type.inbound. Sensors: regex.icontains, strings.replace_confusables.

Indicators matched (2)

FieldMatchValue
regex.icontainsregex(?:W|VV)\s*-?\s*2
regex.icontainsregex<rect x="\d+" y="\d+" width="\d+" height="\d+" fill="#[c-f][0-9a-f][0-3][0-9a-f][0-3][0-9a-f]">\s*<\/rect>\s*<rect x="\d+" y="\d+" width="\d+" height="\d+" fill="#[0-3][0-9a-f][8-f][0-9a-f][2-6][0-9a-f]">\s*<\/rect>\s*<rect x="\d+" y="\d+" width="\d+" height="\d+" fill="#[0-3][0-9a-f][5-9][0-9a-f][a-f][0-9a-f]">\s*<\/rect>\s*<rect x="\d+" y="\d+" width="\d+" height="\d+" fill="#[c-f][0-9a-f][a-f][0-9a-f][0-3][0-9a-f]">\s*<\/rect>\s*<\/svg>\s*<\/td>

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    strings.replace_confusables(body.current_thread.links[].display_text) regex_match "(?:W|VV)\\s*-?\\s*2"
  body.html.raw regex_match "<rect x=\"\\d+\" y=\"\\d+\" width=\"\\d+\" height=\"\\d+\" fill=\"#[c-f][0-9a-f][0-3][0-9a-f][0-3][0-9a-f]\">\\s*<\\/rect>\\s*<rect x=\"\\d+\" y=\"\\d+\" width=\"\\d+\" height=\"\\d+\" fill=\"#[0-3][0-9a-f][8-f][0-9a-f][2-6][0-9a-f]\">\\s*<\\/rect>\\s*<rect x=\"\\d+\" y=\"\\d+\" width=\"\\d+\" height=\"\\d+\" fill=\"#[0-3][0-9a-f][5-9][0-9a-f][a-f][0-9a-f]\">\\s*<\\/rect>\\s*<rect x=\"\\d+\" y=\"\\d+\" width=\"\\d+\" height=\"\\d+\" fill=\"#[c-f][0-9a-f][a-f][0-9a-f][0-3][0-9a-f]\">\\s*<\\/rect>\\s*<\\/svg>\\s*<\\/td>"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.html.rawregex_match
  • <rect x="\d+" y="\d+" width="\d+" height="\d+" fill="#[c-f][0-9a-f][0-3][0-9a-f][0-3][0-9a-f]">\s*<\/rect>\s*<rect x="\d+" y="\d+" width="\d+" height="\d+" fill="#[0-3][0-9a-f][8-f][0-9a-f][2-6][0-9a-f]">\s*<\/rect>\s*<rect x="\d+" y="\d+" width="\d+" height="\d+" fill="#[0-3][0-9a-f][5-9][0-9a-f][a-f][0-9a-f]">\s*<\/rect>\s*<rect x="\d+" y="\d+" width="\d+" height="\d+" fill="#[c-f][0-9a-f][a-f][0-9a-f][0-3][0-9a-f]">\s*<\/rect>\s*<\/svg>\s*<\/td>
field:"body.html.raw" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Cyrillic vowel substitution in subject or display name from unknown sender

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

This rule detects unsolicited messages containing a mix of Cyrillic and Latin characters in the subject or sender's name while excluding emails from Russian domains and specific Google Calendar notification bounce emails.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Social engineering, Spoofing

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound

// message contains between 1 and 9 links
and (
  0 < length(body.links) < 10
  or (
    length(body.links) == 0
    and length(attachments) > 0
    and body.current_thread.text == ""
  )
)

//  display name or subject contains Cyrillic vowels in addition to standard letters
and any([subject.subject, sender.display_name],
        regex.icontains(., '(а|е|и|о|у)') and regex.icontains(., '[a-z]')
)

// and the senders tld or return path is not "ru"
and not (
  sender.email.domain.tld == "ru" or headers.return_path.domain.tld == "ru"
)
// and the return path is not 'calendar-server.bounces.google.com'
and not headers.return_path.domain.domain == 'calendar-server.bounces.google.com'
and not headers.return_path.domain.domain == 'identity-reachout.bounces.google.com'
and not headers.return_path.domain.domain == 'bounce-sg.zoom.us'
and not headers.return_path.domain.domain == 'bounce.dataminr.com'
and not headers.return_path.domain.domain == 'mail-us.atlassian.net'

// the message is unsolicited and no false positives
and (
  not profile.by_sender().solicited
  or (
    length(headers.reply_to) > 0
    and all(headers.reply_to, .email.email not in $recipient_emails)
  )
)
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

This rule detects unsolicited messages containing a mix of Cyrillic and Latin characters in the subject or sender's name while excluding emails from Russian domains and specific Google Calendar notification bounce emails.

  1. inbound message
  2. any of:
    • all of:
      • length(body.links) > 0
      • length(body.links) < 10
    • all of:
      • length(body.links) is 0
      • length(attachments) > 0
      • body.current_thread.text is ''
  3. any of [subject.subject, sender.display_name] where all hold:
    • . matches '(а|е|и|о|у)'
    • . matches '[a-z]'
  4. none of:
    • sender.email.domain.tld is 'ru'
    • headers.return_path.domain.tld is 'ru'
  5. not:
    • headers.return_path.domain.domain is 'calendar-server.bounces.google.com'
  6. not:
    • headers.return_path.domain.domain is 'identity-reachout.bounces.google.com'
  7. not:
    • headers.return_path.domain.domain is 'bounce-sg.zoom.us'
  8. not:
    • headers.return_path.domain.domain is 'bounce.dataminr.com'
  9. not:
    • headers.return_path.domain.domain is 'mail-us.atlassian.net'
  10. any of:
    • not:
      • profile.by_sender().solicited
    • all of:
      • length(headers.reply_to) > 0
      • all of headers.reply_to where:
        • .email.email not in $recipient_emails
  11. not:
    • profile.by_sender().any_messages_benign

Inspects: body.current_thread.text, body.links, headers.reply_to, headers.reply_to[].email.email, headers.return_path.domain.domain, headers.return_path.domain.tld, sender.display_name, sender.email.domain.tld, subject.subject, type.inbound. Sensors: profile.by_sender, regex.icontains. Reference lists: $recipient_emails.

Indicators matched (3)

FieldMatchValue
body.current_thread.textequals
regex.icontainsregex(а|е|и|о|у)
regex.icontainsregex[a-z]

Stages and Predicates

Stage 1: mql_rule

and
  any([subject.subject, sender.display_name])
    and
      [subject.subject, sender.display_name] regex_match "(а|е|и|о|у)"
      [subject.subject, sender.display_name] regex_match "[a-z]"
  or
    and
      attachments length_compare "0"
      body.current_thread.text eq ""
      body.links length_compare "0"
    and
      body.links length_compare "0"
      body.links length_compare "10"
  or
    and
      headers.reply_to length_compare "0"
       macro "all(headers.reply_to)"
    not
      profile.by_sender func_call "profile.by_sender().solicited"
  not
    or
      headers.return_path.domain.tld eq "ru"
      sender.email.domain.tld eq "ru"
  not
    headers.return_path.domain.domain eq "bounce-sg.zoom.us"
  not
    headers.return_path.domain.domain eq "bounce.dataminr.com"
  not
    headers.return_path.domain.domain eq "calendar-server.bounces.google.com"
  not
    headers.return_path.domain.domain eq "identity-reachout.bounces.google.com"
  not
    headers.return_path.domain.domain eq "mail-us.atlassian.net"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  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"

Cyrillic vowel substitutions with suspicious subject from unknown sender

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

This rule detects unsolicited messages with between 1-9 links containing a suspicious subject as well as Cyrillic vowel substitutions detected in either the subject or the senders display name.

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
  • headers
  • headers.reply_to
  • subject
  • type

Rule body

type.inbound
and 0 < length(body.links) < 10

//  display name or subject contains Cyrillic/Greek confusables alongside Latin
and any([subject.subject, sender.display_name],
        (
          regex.contains(.,
                         '[a-zA-Z][\x{430}\x{435}\x{438}\x{43e}\x{443}\x{440}\x{441}\x{445}\x{456}\x{410}\x{412}\x{415}\x{41a}\x{41c}\x{41d}\x{41e}\x{420}\x{421}\x{422}\x{425}\x{391}\x{392}\x{395}\x{396}\x{397}\x{399}\x{39a}\x{39c}\x{39d}\x{39f}\x{3a1}\x{3a4}\x{3a5}\x{3a7}\x{3bf}]|[\x{430}\x{435}\x{438}\x{43e}\x{443}\x{440}\x{441}\x{445}\x{456}\x{410}\x{412}\x{415}\x{41a}\x{41c}\x{41d}\x{41e}\x{420}\x{421}\x{422}\x{425}\x{391}\x{392}\x{395}\x{396}\x{397}\x{399}\x{39a}\x{39c}\x{39d}\x{39f}\x{3a1}\x{3a4}\x{3a5}\x{3a7}\x{3bf}][a-zA-Z]'
          )
          or regex.icontains(., '(а|е|и|о|у)') and regex.icontains(., '[a-z]')
        )
)

// and suspicious subject
and regex.icontains(subject.subject,
                    // 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",
                    "unauthorized.sign.?in",
                    "unrecognized.*activit",
                    "unrecognized.sign.?in",
                    "unrecognized.*activit",
                    "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",
)

// the message is unsolicited and no false positives
and (
  not profile.by_sender().solicited
  or (
    length(headers.reply_to) > 0
    and all(headers.reply_to, .email.email not in $recipient_emails)
  )
)
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

This rule detects unsolicited messages with between 1-9 links containing a suspicious subject as well as Cyrillic vowel substitutions detected in either the subject or the senders display name.

  1. inbound message
  2. all of:
    • length(body.links) > 0
    • length(body.links) < 10
  3. any of [subject.subject, sender.display_name] where any holds:
    • . matches '[a-zA-Z][\\x{430}\\x{435}\\x{438}\\x{43e}\\x{443}\\x{440}\\x{441}\\x{445}\\x{456}\\x{410}\\x{412}\\x{415}\\x{41a}\\x{41c}\\x{41d}\\x{41e}\\x{420}\\x{421}\\x{422}\\x{425}\\x{391}\\x{392}\\x{395}\\x{396}\\x{397}\\x{399}\\x{39a}\\x{39c}\\x{39d}\\x{39f}\\x{3a1}\\x{3a4}\\x{3a5}\\x{3a7}\\x{3bf}]|[\\x{430}\\x{435}\\x{438}\\x{43e}\\x{443}\\x{440}\\x{441}\\x{445}\\x{456}\\x{410}\\x{412}\\x{415}\\x{41a}\\x{41c}\\x{41d}\\x{41e}\\x{420}\\x{421}\\x{422}\\x{425}\\x{391}\\x{392}\\x{395}\\x{396}\\x{397}\\x{399}\\x{39a}\\x{39c}\\x{39d}\\x{39f}\\x{3a1}\\x{3a4}\\x{3a5}\\x{3a7}\\x{3bf}][a-zA-Z]'
    • all of:
      • . matches '(а|е|и|о|у)'
      • . matches '[a-z]'
  4. subject.subject matches any of 192 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
    • unauthorized.sign.?in
    • unrecognized.*activit
    • unrecognized.sign.?in
    • unrecognized.*activit
    • 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. any of:
    • not:
      • profile.by_sender().solicited
    • all of:
      • length(headers.reply_to) > 0
      • all of headers.reply_to where:
        • .email.email not in $recipient_emails
  6. not:
    • profile.by_sender().any_messages_benign

Inspects: body.links, headers.reply_to, headers.reply_to[].email.email, sender.display_name, subject.subject, type.inbound. Sensors: profile.by_sender, regex.contains, regex.icontains. Reference lists: $recipient_emails.

Indicators matched (194)

FieldMatchValue
regex.containsregex[a-zA-Z][\x{430}\x{435}\x{438}\x{43e}\x{443}\x{440}\x{441}\x{445}\x{456}\x{410}\x{412}\x{415}\x{41a}\x{41c}\x{41d}\x{41e}\x{420}\x{421}\x{422}\x{425}\x{391}\x{392}\x{395}\x{396}\x{397}\x{399}\x{39a}\x{39c}\x{39d}\x{39f}\x{3a1}\x{3a4}\x{3a5}\x{3a7}\x{3bf}]|[\x{430}\x{435}\x{438}\x{43e}\x{443}\x{440}\x{441}\x{445}\x{456}\x{410}\x{412}\x{415}\x{41a}\x{41c}\x{41d}\x{41e}\x{420}\x{421}\x{422}\x{425}\x{391}\x{392}\x{395}\x{396}\x{397}\x{399}\x{39a}\x{39c}\x{39d}\x{39f}\x{3a1}\x{3a4}\x{3a5}\x{3a7}\x{3bf}][a-zA-Z]
regex.icontainsregex(а|е|и|о|у)
regex.icontainsregex[a-z]
regex.icontainsregextermination.*notice
regex.icontainsregex38417
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
182 more
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.icontainsregexunauthorized.sign.?in
regex.icontainsregexunrecognized.*activit
regex.icontainsregexunrecognized.sign.?in
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
  any([subject.subject, sender.display_name])
    or
      and
        [subject.subject, sender.display_name] regex_match "(а|е|и|о|у)"
        [subject.subject, sender.display_name] regex_match "[a-z]"
      [subject.subject, sender.display_name] regex_match "[a-zA-Z][\\x{430}\\x{435}\\x{438}\\x{43e}\\x{443}\\x{440}\\x{441}\\x{445}\\x{456}\\x{410}\\x{412}\\x{415}\\x{41a}\\x{41c}\\x{41d}\\x{41e}\\x{420}\\x{421}\\x{422}\\x{425}\\x{391}\\x{392}\\x{395}\\x{396}\\x{397}\\x{399}\\x{39a}\\x{39c}\\x{39d}\\x{39f}\\x{3a1}\\x{3a4}\\x{3a5}\\x{3a7}\\x{3bf}]|[\\x{430}\\x{435}\\x{438}\\x{43e}\\x{443}\\x{440}\\x{441}\\x{445}\\x{456}\\x{410}\\x{412}\\x{415}\\x{41a}\\x{41c}\\x{41d}\\x{41e}\\x{420}\\x{421}\\x{422}\\x{425}\\x{391}\\x{392}\\x{395}\\x{396}\\x{397}\\x{399}\\x{39a}\\x{39c}\\x{39d}\\x{39f}\\x{3a1}\\x{3a4}\\x{3a5}\\x{3a7}\\x{3bf}][a-zA-Z]"
  or
    and
      headers.reply_to length_compare "0"
       macro "all(headers.reply_to)"
    not
      profile.by_sender func_call "profile.by_sender().solicited"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  or
    subject.subject regex_match "38417"
    subject.subject regex_match ":completed"
    subject.subject regex_match "[il1]{2}mit.*ma[il1]{2} ?bo?x"
    subject.subject regex_match "[il][il][il]egai[ -]"
    subject.subject regex_match "[li][li][li]ega[li] attempt"
    subject.subject regex_match "[ng]-?[io]n .*block"
    subject.subject regex_match "[ng]-?[io]n .*cancel"
    subject.subject regex_match "[ng]-?[io]n .*deactiv"
    subject.subject regex_match "[ng]-?[io]n .*disabl"
    subject.subject regex_match "abandon.*package"
    subject.subject regex_match "about.your.account"
    subject.subject regex_match "acc(ou)?n?t (is )?on ho[li]d"
    subject.subject regex_match "acc(ou)?n?t.*terminat"
    subject.subject regex_match "acc(oun)?t.*[il1]{2}mitation"
    subject.subject regex_match "access.*limitation"
    subject.subject regex_match "account (will be )?block"
    subject.subject regex_match "account has been limited"
    subject.subject regex_match "account v[il]o[li]at"
    subject.subject regex_match "account.*de-?activat"
    subject.subject regex_match "account.*locked"
    subject.subject regex_match "account.*re-verification"
    subject.subject regex_match "account.*security"
    subject.subject regex_match "account.*suspension"
    subject.subject regex_match "account.has.been"
    subject.subject regex_match "account.has.expired"
    subject.subject regex_match "account.will.be.blocked"
    subject.subject regex_match "action required"
    subject.subject regex_match "action.*required"
    subject.subject regex_match "activity.*acc(oun)?t"
    subject.subject regex_match "almost full"
    subject.subject regex_match "almost.full"
    subject.subject regex_match "apd notifi cation"
    subject.subject regex_match "app[li]e.[il]d"
    subject.subject regex_match "are you at your desk"
    subject.subject regex_match "are you available"
    subject.subject regex_match "attached file to docusign"
    subject.subject regex_match "authenticate.*account"
    subject.subject regex_match "banking is temporarily unavailable"
    subject.subject regex_match "bankofamerica"
    subject.subject regex_match "been.*suspend"
    subject.subject regex_match "clos.*of.*account.*processed"
    subject.subject regex_match "closing statement invoice"
    subject.subject regex_match "completed: docusign"
    subject.subject regex_match "confirm.your.account"
    subject.subject regex_match "courier.*able"
    subject.subject regex_match "crediential.*notif"
    subject.subject regex_match "de-activation of"
    subject.subject regex_match "deactivation.*in.*progress"
    subject.subject regex_match "delivery attempt"
    subject.subject regex_match "delivery stopped for shipment"
    subject.subject regex_match "delivery.*attempt.*failed"
    subject.subject regex_match "detected suspicious actvity"
    subject.subject regex_match "detected suspicious"
    subject.subject regex_match "docu sign"
    subject.subject regex_match "document for you"
    subject.subject regex_match "document has been sent to you via docusign"
    subject.subject regex_match "document is ready for signature"
    subject.subject regex_match "document.received"
    subject.subject regex_match "documented.*shared.*with.*you"
    subject.subject regex_match "docusign"
    subject.subject regex_match "dropbox.*document"
    subject.subject regex_match "e-?ma[il1]+ .{010}suspen"
    subject.subject regex_match "e-?ma[il1]{1} user"
    subject.subject regex_match "e-?ma[il1]{2} acc"
    subject.subject regex_match "e-?ma[il1]{2}.*up.?grade"
    subject.subject regex_match "e.?ma[il1]{2}.*server"
    subject.subject regex_match "e.?ma[il1]{2}.*suspend"
    subject.subject regex_match "email.update"
    subject.subject regex_match "encrypted message"
    subject.subject regex_match "failed delivery"
    subject.subject regex_match "faxed you"
    subject.subject regex_match "fedex tracking"
    subject.subject regex_match "file was shared"
    subject.subject regex_match "fraud(ulent)?.*charge"
    subject.subject regex_match "freefax"
    subject.subject regex_match "from.helpdesk"
    subject.subject regex_match "fu[il1]{2}.*ma[il1]+[ -]?box"
    subject.subject regex_match "fwd: due invoice paid"
    subject.subject regex_match "has shared"
    subject.subject regex_match "has.been.*suspended"
    subject.subject regex_match "has.been.limited"
    subject.subject regex_match "have.locked"
    subject.subject regex_match "he[li]p ?desk upgrade"
    subject.subject regex_match "heipdesk"
    subject.subject regex_match "i[il]iega[il]"
    subject.subject regex_match "ii[il]ega[il]"
    subject.subject regex_match "inbox is full"
    subject.subject regex_match "incoming e?mail"
    subject.subject regex_match "incoming.*fax"
    subject.subject regex_match "invitation to comment"
    subject.subject regex_match "invitation to edit"
    subject.subject regex_match "invoice due"
    subject.subject regex_match "left you a message"
    subject.subject regex_match "lock.*security"
    subject.subject regex_match "ma[il1]{1}[ -]?box.*quo"
    subject.subject regex_match "ma[il1]{2}[ -]?box.*fu[il1]"
    subject.subject regex_match "ma[il1]{2}box stor"
    subject.subject regex_match "ma[il1]{2}box.*[il1]{2}mit"
    subject.subject regex_match "mail on.?hold"
    subject.subject regex_match "mail.*box.*migration"
    subject.subject regex_match "mail.*de-?activat"
    subject.subject regex_match "mail.update.required"
    subject.subject regex_match "mails.*pending"
    subject.subject regex_match "message from"
    subject.subject regex_match "messages.*pending"
    subject.subject regex_match "missed.*shipping.*notification"
    subject.subject regex_match "missed.shipment.notification"
    subject.subject regex_match "must.update.your.account"
    subject.subject regex_match "new [sl][io]g?[nig][ -]?in from"
    subject.subject regex_match "new message"
    subject.subject regex_match "new sign in"
    subject.subject regex_match "new sign-in"
    subject.subject regex_match "new voice ?-?mail"
    subject.subject regex_match "new voicemail"
    subject.subject regex_match "notifications.*pending"
    subject.subject regex_match "office.*3.*6.*5.*suspend"
    subject.subject regex_match "office365"
    subject.subject regex_match "on desk"
    subject.subject regex_match "on google docs with you"
    subject.subject regex_match "online doc"
    subject.subject regex_match "out of space"
    subject.subject regex_match "password reset"
    subject.subject regex_match "password.*compromised"
    subject.subject regex_match "payment status"
    subject.subject regex_match "periodic maintenance"
    subject.subject regex_match "potential(ly)? unauthorized"
    subject.subject regex_match "quick reply"
    subject.subject regex_match "re: w-2"
    subject.subject regex_match "refund not approved"
    subject.subject regex_match "required"
    subject.subject regex_match "required: completed docusign"
    subject.subject regex_match "revised.*policy"
    subject.subject regex_match "ringcentral"
    subject.subject regex_match "scam"
    subject.subject regex_match "scanned image"
    subject.subject regex_match "scanned.?invoice"
    subject.subject regex_match "secured files"
    subject.subject regex_match "secured pdf"
    subject.subject regex_match "secured?.update"
    subject.subject regex_match "security alert"
    subject.subject regex_match "security breach"
    subject.subject regex_match "securlty"
    subject.subject regex_match "sign in attempt"
    subject.subject regex_match "sign-in attempt"
    subject.subject regex_match "signed.*delivery"
    subject.subject regex_match "staff review"
    subject.subject regex_match "status of your .{314}? ?delivery"
    subject.subject regex_match "susp[il1]+c[il1]+ous.*act[il1]+v[il1]+ty"
    subject.subject regex_match "suspicious activity"
    subject.subject regex_match "suspicious.*sign.*[io]n"
    subject.subject regex_match "suspicious.activit"
    subject.subject regex_match "temporar(il)?y deactivate"
    subject.subject regex_match "temporar[il1]{2}y disab[li]ed"
    subject.subject regex_match "temporarily.*lock"
    subject.subject regex_match "termination.*notice"
    subject.subject regex_match "un-?usua[li].activity"
    subject.subject regex_match "unable.*deliver"
    subject.subject regex_match "unauthorized.*activit"
    subject.subject regex_match "unauthorized.device"
    subject.subject regex_match "unauthorized.sign.?in"
    subject.subject regex_match "undelivered message"
    subject.subject regex_match "unread.*doc"
    subject.subject regex_match "unrecognized login attempt"
    subject.subject regex_match "unrecognized.*activit"
    subject.subject regex_match "unrecognized.sign.?in"
    subject.subject regex_match "unusual.activity"
    subject.subject regex_match "upgrade immediately"
    subject.subject regex_match "upgrade.*account"
    subject.subject regex_match "upgrade.notice"
    subject.subject regex_match "urgent message"
    subject.subject regex_match "urgent"
    subject.subject regex_match "urgent.verification"
    subject.subject regex_match "v[il1]o[li1]at[il1]on security"
    subject.subject regex_match "va[il1]{1}date.*ma[il1]{2}[ -]?box"
    subject.subject regex_match "verification ?-?require"
    subject.subject regex_match "verification( )?-?need"
    subject.subject regex_match "verify.your?.account"
    subject.subject regex_match "w2"
    subject.subject regex_match "wants to share"
    subject.subject regex_match "web ?-?ma[il1]{2}"
    subject.subject regex_match "web[ -]?ma[il1]{2}"
    subject.subject regex_match "will.be.suspended"
    subject.subject regex_match "you have notifications pending"
    subject.subject regex_match "your (customer )?account .as"
    subject.subject regex_match "your account"
    subject.subject regex_match "your amazon order"
    subject.subject regex_match "your document settlement"
    subject.subject regex_match "your order with amazon"
    subject.subject regex_match "your password has been compromised"
    subject.subject regex_match "your.office.365"
    subject.subject regex_match "your.online.access"
  body.links length_compare "0"
  body.links length_compare "10"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
subject.subjectregex_match
  • 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
  • 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 has been limited
  • account v[il]o[li]at
  • account.*de-?activat
  • account.*locked
  • account.*re-verification
  • account.*security
  • account.*suspension
  • account.has.been
  • account.has.expired
  • account.will.be.blocked
  • action required
  • action.*required
  • activity.*acc(oun)?t
  • almost full
  • almost.full
  • apd notifi cation
  • app[li]e.[il]d
  • are you at your desk
  • are you available
  • attached file to docusign
  • authenticate.*account
  • banking is temporarily unavailable
  • bankofamerica
  • been.*suspend
  • +151 more values (see full rule source)
field:"subject.subject" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Fake message thread with a suspicious link and engaging language from an unknown sender

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

Detects fake message threads with suspicious links and financial request language

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

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

Rule body

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

// fake thread check
and (subject.is_reply or subject.is_forward)

// Check for the Presence of References or In-Reply-To properties
and (
  (length(headers.references) == 0 and headers.in_reply_to is null)
  or headers.in_reply_to is null
)

// sender's domain is not in body, and body has > 0 links
and length(body.links) > 0
and sender.email.domain.root_domain not in $free_email_providers
and not any(body.links,
            .href_url.domain.root_domain == sender.email.domain.root_domain
)

// unusual sender (email address rarely sends to your organization)
and sender.email.email not in $sender_emails

// unusual sender domain (domain rarely sends to your organization)
and sender.email.domain.domain not in $sender_domains
and 4 of (
  // language attempting to engage
  (
    any(ml.nlu_classifier(body.current_thread.text).entities,
        .name == "request"
    )
    and any(ml.nlu_classifier(body.current_thread.text).entities,
            .name == "financial"
    )
  ),

  // invoicing language
  any(ml.nlu_classifier(body.current_thread.text).tags, .name == "invoice"),

  // urgency request
  any(ml.nlu_classifier(body.current_thread.text).entities, .name == "urgency"),

  // cred_theft detection
  any(ml.nlu_classifier(body.current_thread.text).intents,
      .name == "cred_theft" and .confidence in~ ("medium", "high")
  ),

  // commonly abused sender TLD
  strings.ilike(sender.email.domain.tld, "*.jp"),

  // headers traverse abused TLD
  any(headers.domains, strings.ilike(.tld, "*.jp")),

  // known suspicious pattern in the URL path
  any(body.links, regex.match(.href_url.path, '\/[a-z]{3}\d[a-z]')),

  // link display text is in all caps
  any(body.links, regex.match(.display_text, '[A-Z ]+')),

  // display name contains an email
  regex.contains(sender.display_name, '[a-z0-9]+@[a-z]+'),

  // Sender domain is empty
  sender.email.domain.domain == "",

  // sender domain matches no body domains
  all(body.links,
      .href_url.domain.root_domain != sender.email.domain.root_domain
  ),
)

// 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 fake message threads with suspicious links and financial request language

  1. inbound message
  2. length(body.links) < 10
  3. any of:
    • subject.is_reply
    • subject.is_forward
  4. any of:
    • all of:
      • length(headers.references) is 0
      • headers.in_reply_to is missing
    • headers.in_reply_to is missing
  5. length(body.links) > 0
  6. sender.email.domain.root_domain not in $free_email_providers
  7. not:
    • any of body.links where:
      • .href_url.domain.root_domain is sender.email.domain.root_domain
  8. sender.email.email not in $sender_emails
  9. sender.email.domain.domain not in $sender_domains
  10. at least 4 of:
    • all of:
      • 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 'financial'
    • any of ml.nlu_classifier(body.current_thread.text).tags where:
      • .name is 'invoice'
    • any of ml.nlu_classifier(body.current_thread.text).entities where:
      • .name is 'urgency'
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'cred_theft'
      • .confidence in ('medium', 'high')
    • sender.email.domain.tld matches '*.jp'
    • any of headers.domains where:
      • .tld matches '*.jp'
    • any of body.links where:
      • .href_url.path matches '\\/[a-z]{3}\\d[a-z]'
    • any of body.links where:
      • .display_text matches '[A-Z ]+'
    • sender.display_name matches '[a-z0-9]+@[a-z]+'
    • sender.email.domain.domain is ''
    • all of body.links where:
      • .href_url.domain.root_domain is not sender.email.domain.root_domain
  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.text, body.links, body.links[].display_text, body.links[].href_url.domain.root_domain, body.links[].href_url.path, headers.auth_summary.dmarc.pass, headers.domains, headers.domains[].tld, 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, subject.is_forward, subject.is_reply, type.inbound. Sensors: ml.nlu_classifier, regex.contains, regex.match, strings.ilike. Reference lists: $free_email_providers, $high_trust_sender_root_domains, $sender_domains, $sender_emails.

Indicators matched (12)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsrequest
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsfinancial
ml.nlu_classifier(body.current_thread.text).tags[].nameequalsinvoice
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsurgency
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
strings.ilikesubstring*.jp
regex.matchregex\/[a-z]{3}\d[a-z]
regex.matchregex[A-Z ]+
regex.containsregex[a-z0-9]+@[a-z]+
sender.email.domain.domainequals

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 "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).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(body.links)
      body.links.display_text regex_match "[A-Z ]+"
    any(body.links)
      body.links.href_url.path regex_match "\\/[a-z]{3}\\d[a-z]"
    any(headers.domains)
      headers.domains.tld ends_with ".jp"
    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).tags)
      ml.nlu_classifier(body.current_thread.text).tags.name eq "invoice"
    sender.display_name regex_match "[a-z0-9]+@[a-z]+"
    sender.email.domain.domain eq ""
    sender.email.domain.tld ends_with ".jp"
     macro "all(body.links)"
  not
    any(body.links)
      body.links.href_url.domain.root_domain cross_field_compare "sender.email.domain.root_domain"
  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"
  body.links length_compare "0"
  body.links length_compare "10"
  type.inbound eq "true"
   macro "sender.email.domain.domain not in sender_domains"
   macro "sender.email.domain.root_domain not in free_email_providers"
   macro "sender.email.email not in sender_emails"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
body.linksarray_any(no value, null check)excludes:body.links

Indicators

These rows show field, operator, and value matches.

Fake voicemail notification (untrusted sender)

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

This rule detects a common credential phishing vector enticing the user to engage with links under the premise that they have a voicemail to retrieve. The rule looks for voicemail verbiage in the display name, body, subject or a combination of those elements with emojis or a medium to high credential theft NLU Intent from first-time + unsolicited sender.

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
  • headers
  • headers.auth_summary
  • headers.domains
  • headers.hops
  • recipients
  • recipients.to
  • sender.email
  • subject
  • type

Rule body

type.inbound
// contains links or attachments
and (
  (
    0 < length(filter(body.links, .href_url.scheme != "mailto")) <= 25
    or 0 < length(distinct(attachments, .md5)) <= 3
  )
  and 0 <= length(distinct(attachments, .md5)) <= 8
)

// the subject or display_name need some keywords which are voicemail related
and (
  any([subject.subject, sender.display_name],
      regex.icontains(.,
                      // split phrases that occur within 3 words between or only punctuation between them
                      '(?:v[nm](\b|[[:punct:]])?|\bv[o0][il1]ce(?:mail|message)?|audi[o0]|incoming|missed(?:\sa\s)?|left( a)?|wireless)(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:mail|message|msg|recording|received|notif|support|ca[li1][li1]\d*\b|ca[il1][il1](?:er)?|log|transcript(?:ion)?)\b',
                      // regex specific to v-mail, v_msg, v,mail, etc
                      // list of "secondary" words synced with regex above this one
                      'v[[:punct:]](?:mail|message|msg|recording|received|notif|support|ca[li1][li1]\d*\b|ca[il1][il1](?:er)?|log|transcript(?:ion)?\b)',
                      // split phrases that start with "caller" that occur within 3 words between or only punctation
                      'ca[li1][li1](?:er)?(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:v[nm](\b|[[:punct:]])?|\bv[o0][il1]ce(?:mail|message)?|audi[o0]|missed(?:\sa\s)?|left( a)?)',
                      // strong phrases
                      '(?:open mp3|audi[o0] note|\.wav|left a vm|[^\s]+voip[^\s]*|unanswered.*ca[li1][li1]|incoming.vm|left msg|wireless ca[li1][li1]er|VM Service|v[o0][il1]ce message|missed.ca[li1][li1](?:e[rd])?|\bca[li1][li1].(?:support|service)(?: for| log)?|missed.{0,10} VM|new v[o0][il1]cemail from|new.v.m.from.\+?\d+|new v[o0][il1]cemail?(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}transcript(s|ion)?|message received|new (?:message|call|voicemail).{0,15}(?:info|notification|alert)|incoming transmission|voice note)',
                      // starts in the format of `(4)` and contains some voicemail keywords
                      '^\(\d\)\s(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:message|voip|v[o0][il1]ce|unread|call)',
                      'ca[li1][li1](?:er)?(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:playback|transcript)',

                      // obfuscated phone number with at least one digit in the area code and at least one obfuscated number in the last group
                      // 555-555-555X, 555-555-XXXX, 555-5XX-XXXX
                      '\b1?\(?(\d{3}|\d{2}[\*X]|\d[\*X]{2})\)?[^a-z0-9]{0,2}(\d{2,3}|\d{2}[\*X]|\d[\*X]{2}|[\*X]{2,3})[^a-z0-9]{0,4}(\d{3}[\*X]|\d{2}[\*X]{2}|\d[\*X]{3}|[\*X]{3,4})[^0-9]',
                      // obfuscated phone number with at least one digit in the prefix
                      // XXX-555-5555, XXX-5XX-XXXX
                      '\b1?\(?(\d{2}[\*X]|\d[\*X]{2}|[\*X]{2,3})\)?[^a-z0-9]{0,2}(\d{2,3}|\d{2}[\*X]|\d[\*X]{2})[^a-z0-9]{0,4}(\d{4}|\d{3}[\*X]|\d{2}[\*X]{2}|\d[\*X]{3}|[\*X]{3,4})\b',
                      // obfuscated voicemail/voicemessage keywords
                      'v[o0][il1]ce[\s\-_]?m(?:ail|sg|essage)?[\*X\.\-_]{2,}',
                      'v[o0][il1]cem[\*X\.\-_]{2,}',
                      // "X new voice..." patterns
                      '\d+\s+new.*v[o0][il1]ce(?:mail|message|m[\*]+)?',
                      // sent-message patterns
                      '(?:sent|new|incoming)[\s\-]+message.*(v[o0][il1]ce|<.*@.*>)',
      )
  )
  // body.current_thread.text inspection should be very specific to avoid FP
  or regex.icontains(strings.replace_confusables(body.current_thread.text),
                     // body.current_thread.text,
                     'sent (?:from|by) (?:your )?v[o0][il1]ce (?:ma[il1][li1] )?system',
                     '(?:(?:new|this) |^)(?:v[o0][il1]ce(?:ma[il1][li1])?|aud[il1][o0]) (?:message|notification|record)',
                     'v[o0][il1]cema[il1][li1] (is )?attached',
                     'an? (?:new )?encrypted v[o0][il1]cemail',
                     'a (?:new )?pending message',
                     'Your? have (?: an?)?incoming v[o0][il1]ceRec',
                     "you(?:\'ve| have) a (?:new )?m[il1]ssed ca[li1][li1]",
                     'New V[o0][il1]cema[il1][li1] Received',
                     'New m[il1]ssed ca[li1][li1] record',
                     '\bv[o0][il1]cema[il1][li1] transcript\b',
                     'Listen to V[o0][il1]ceMa[il1][li1]',
                     'New v[o0][il1]cema[il1][li1] from',
                     'v[o0][il1]ce note'
  )
  // pull out two regexes that could benefit from negations
  or (
    regex.icontains(body.current_thread.text,
                    // body.current_thread.text,
                    '(?:you|we) (?:have |received )+(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:\b|\s+)v[o0][il1]ce\s?(?:ma[il1][li1]|aud[il1][o0]|message|notification)',
                    'left you a (?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:v[o0][il1]ce(?:ma[il1][li1])?|aud[il1][o0])(?: message|notification)?',
    )
    and not regex.icontains(body.current_thread.text,
                            '(?:I(?:\sjust)?|just(?: called you at (?:\d+[[:punct:]])+) and)? left you a (?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:v[o0][il1]ce(?:mail)?|audio)(?: message)?'
    )
    and not regex.icontains(body.current_thread.text,
                            'you (?:have |received )my voice\s?(?:mail|audio|message)'
    )
  )
  // Reuse the body.current_thread.text logic against the OCR output of the message screenshot
  or (
    length(attachments) > 0
    and (
      all(attachments,
          .file_type in $file_types_images
          and beta.parse_exif(.).image_height != 1
      )
      // there is a mix of fake audio attachments and images
      or (
        length(filter(attachments,
                      strings.starts_with(.content_type, "audio")
                      // confirm the content type with .file_type
                      // we have seen attachments claim to be audio/* files, only to be exploded as something else
                      and not .file_type in ("wav", "mp3")
               )
        ) 
        // the total # of fake audio attachments + the total # of image attachments = the total # of attachments
        // meaning, all attachments that are NOT fake audio attachments MUST be images
        + length(filter(attachments,
                        .file_type in $file_types_images
                        and beta.parse_exif(.).image_height != 1
                 )
        ) == length(attachments)
      )
    )
    and any((filter(file.explode(file.message_screenshot()), .depth == 0)),
            regex.icontains(.scan.ocr.raw,
                            // body.current_thread.text,
                            'sent (?:from|by) (?:your )?v[o0][il1]ce (?:ma[il1][li1] )?system',
                            '(?:(?:new|this) |^)(?:v[o0][il1]ce(?:ma[il1][li1])?|aud[il1][o0]) (?:message|notification|record)',
                            'v[o0][il1]cema[il1][li1] (is )?attached',
                            'an? (?:new )?encrypted v[o0][il1]cemail',
                            'a (?:new )?pending message',
                            'Your? have (?: an?)?incoming v[o0][il1]ceRec',
                            "you(?:\'ve| have) a (?:new )?m[il1]ssed ca[li1][li1]",
                            'New V[o0][il1]cema[il1][li1] Received',
                            'New m[il1]ssed ca[li1][li1] record',
                            '\bv[o0][il1]cema[il1][li1] transcript\b',
                            'Listen to V[o0][il1]ceMa[il1][li1]',
                            'New v[o0][il1]cema[il1][li1] from',
                            'v[o0][il1]ce note'
            )
            or (
              regex.icontains(.scan.ocr.raw,
                              // body.current_thread.text,
                              '(?:you|we) (?:have |received )+(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:\b|\s+)v[o0][il1]ce\s?(?:ma[il1][li1]|aud[il1][o0]|message|notification)',
                              'left you a (?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:v[o0][il1]ce(?:mail)?|audi[o0])(?: message)?',
              )
              and not regex.icontains(body.current_thread.text,
                                      '(?:I(?:\sjust)?|just) left you a (?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:voice(?:mail)?|audio)(?: message)?'
              )
              and not regex.icontains(body.current_thread.text,
                                      'you (?:have |received )my voice\s?(?:mail|audio|message)'
              )
            )
    )
  )
  or strings.icontains(body.html.raw, '<title>Voicemail Notification</title>')
  or strings.icontains(body.html.raw, '<!-- Voicemail phone logo')
)
and 2 of (
  (
    // the sender is a freemail
    sender.email.domain.root_domain in $free_email_providers
  ),
  (
    any(ml.nlu_classifier(body.current_thread.text).intents,
        .name in ("cred_theft") and .confidence in ("medium", "high")
    )
    or 
    // use the OCR from the message screenshot
    any(filter(file.explode(file.message_screenshot()), .depth == 0),
        any(ml.nlu_classifier(.scan.ocr.raw).intents,
            .name in ("cred_theft") and .confidence in ("medium", "high")
        )
    )
  ),
  (
    any(attachments,
        .content_type in ("html", "text", "text/html")
        and any(ml.logo_detect(file.html_screenshot(.)).brands,
                .name in ("Microsoft") and .confidence in ("medium", "high")
        )
    )
  ),
  (
    regex.icontains(sender.display_name,
                    '(v[o0][il1]ce|audi[o0]|call|missed|caii)(\s?|-)(mail|message|recording|call|caii)|(transcription|Caller.?ID)'
    )
  ),
  // attachment names are often HTML and voice mail related
  (
    any(attachments,
        // this logic is reused below for eml attachments
        // ensure updates occur both places
        (
          .content_type in ("html", "text", "text/html")
          or .file_type in ("html", "unknown", "svg")
          or .file_type == "pdf"
        )
        and (
          regex.icontains(.file_name,
                          '(?:v[o0][il1]ce|aud[i1l][o0]|call|missed|caii|mail|message|recording|call|caii|transcr[il1]ption|v[nm]|audi[o0]|play|listen|unheard|msg)',
                          // contains a time
                          // 01min , 60secs
                          '0?[1-9]\s*min(?:(?:ute)?s)?',
                          '\d{1,2}\s*s(?:ec(?:ond)?s)?',
                          // (00:50s)
                          // 3:26 seconds
                          '[\(\[]?(?:\d{1,2}[\:\s-])\d{1,2}[\)\]]?\s*(?:s(?:(?:ecs?)onds)?)[\)\]]?',
                          // 03min25secs
                          '0?[1-9]\s*min(?:(?:ute)?s)?\d{1,2}\s*s(?:ec(?:ond)?s)?',
                          // [0:39]
                          // (0:39)
                          '[\(\[](?:\d{1,2}[\:\s-])\d{1,2}[\)\]]\s',
                          // contains an emoji
                          '[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}]'
          )
          // somtimes there is no name, it's just the extension which is also strange
          or .file_name in~ (".htm", ".html")
          // or sometimes it has no name....
          or .file_name is null
        )
    )
  ),
  // attachment contains javascript
  (
    any(attachments,
        (
          .content_type in ("html", "text", "text/html")
          or .file_type in ("html", "unknown", "svg")
        )
        and (
          (
            .size < 1500
            and any(file.explode(.), length(.scan.html.scripts) > 0)
          )
          // bypass the size requirement under these conditions
          or (
            // sync with https://github.com/sublime-security/sublime-rules/blob/main/detection-rules/attachment_svg_embedded_js.yml
            strings.ilike(file.parse_text(.,
                                          encodings=[
                                            "ascii",
                                            "utf8",
                                            "utf16-le"
                                          ]
                          ).text,
                          "*onload*",
                          "*window.location.href*",
                          "*onerror*",
                          "*CDATA*",
                          "*<script*",
                          "*</script*",
                          "*atob*",
                          "*location.assign*",
                          "*decodeURIComponent*"
            )
          )
        )
    )
  ),
  (
    any(attachments,
        (
          .content_type in ("html", "text", "text/html")
          or .file_type in ("html", "unknown", "svg")
        )
        and any(recipients.to,
                // the html attachment contains a receipient email address
                strings.contains(file.parse_html(..).raw, .email.email)
                // the sld of the domain is in the attachment name
                or strings.contains(..file_name, .email.domain.sld)
        )
    )
  ),
  // eml attachments
  (
    any(filter(attachments,
               .content_type == "message/rfc822" or .file_extension in ('eml')
        ),
        // which contain attachments
        // this is the same logic as above
        any(file.parse_eml(.).attachments,
            (
              .content_type in ("html", "text", "text/html")
              or .file_type in ("html", "unknown", "svg")
              or .file_type == "pdf"
            )
            and (
              regex.icontains(.file_name,
                              '(?:v[o0][il1]ce|aud[il1][o0]|call|missed|caii|mail|message|recording|call|caii|transcr[il1]ption|v[nm]|audi[o0]|play|listen|unheard|msg)',
                              // contains a time
                              // 01min , 60secs
                              '0?[1-9]\s*min(?:(?:ute)?s)?',
                              '\d{1,2}\s*s(?:ec(?:ond)?s)?',
                              // (00:50s)
                              // 3:26 seconds
                              '[\(\[]?(?:\d{1,2}[\:\s-])\d{1,2}[\)\]]?\s*(?:s(?:(?:ecs?)onds)?)[\)\]]?',
                              // 03min25secs
                              '0?[1-9]\s*min(?:(?:ute)?s)?\d{1,2}\s*s(?:ec(?:ond)?s)?',
                              // [0:39]
                              // (0:39)
                              '[\(\[](?:\d{1,2}[\:\s-])\d{1,2}[\)\]]\s',
                              // contains an emoji
                              '[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}]'
              )
              // somtimes there is no name, it's just the extension which is also strange
              or .file_name in~ (".htm", ".html")
              // or sometimes it has no name....
              or .file_name is null
            )
        )
    )
  ),
  // attached eml sender/recipeient/subject are all the same as the outer
  // and have an attachment or body links
  (
    any(filter(attachments,
               .content_type == "message/rfc822" or .file_extension in ('eml')
        ),
        // which contain attachments
        // this is the same logic as above
        file.parse_eml(.).subject.subject == subject.subject
        and file.parse_eml(.).sender.email.email == sender.email.email
        and (
          length(file.parse_eml(.).recipients.to) == length(recipients.to)
          and all(recipients.to,
                  .email.email in map(file.parse_eml(..).recipients.to,
                                      .email.email
                  )
          )
        )
        and (
          // there are attachments
          length(file.parse_eml(.).attachments) > 0
          // or body links
          or length(filter(file.parse_eml(.).body.links,
                           .href_url.domain.domain not in $org_domains
                           and .href_url.domain.root_domain not in $org_domains
                    )
          ) > 0
        )
    )
  ),
  // the body links contain the recipients email
  (
    length(filter(recipients.to, .email.email != "" or .email.domain.valid)) > 0
    and any(body.links,
            any(recipients.to,
                strings.icontains(..href_url.url, .email.email)
                or strings.icontains(..href_url.url, .email.local_part)
            )
    )
  ),
  (
    length(body.current_thread.text) < 700
    and regex.icontains(body.current_thread.text,
                        'Méssãge|Méssage|Recéived|Addréss'
    )
  ),
  (
    // sender domain matches no body domains
    // only inspect "links" that have a display_text and display_url is null to remove "plain text" email address from being caught
    length(filter(body.links,
                  .display_text is not null
                  and .display_url.url is null
                  and .href_url.domain.valid
           )
    ) > 0
    and all(filter(body.links,
                   .display_text is not null
                   and .display_url.url is null
                   and .href_url.domain.valid
            ),
            .href_url.domain.root_domain != sender.email.domain.root_domain
            and .href_url.domain.root_domain not in $org_domains
            and .href_url.domain.root_domain not in ("aka.ms")
            and .href_url.domain.root_domain not in (
              "unitelvoice.com",
              "googleapis.com",
              "dialmycalls.com",
              "ringcentral.biz",
              "google.com"
            )
    )
  ),
  // the body links contain vm related phrases
  (
    any(body.links,
        regex.contains(.display_text, '[^a-z]*[A-Z][^a-z]*')
        and regex.icontains(.display_text,
                            '(?:v[nm]|v[o0][il1]ce|audi[o0]|ca[li][li]|missed|preview)(\s?|-)(mail|message|recording|call|caii)|transcription|open mp3|audi[o0] note|listen|playback|\(?(?:\*\*\*|[0-9]{3})?.(?:\*\*\*|[0-9]{3})[^a-z]{0,2}(?:\*{4}|\d+\*+)|play|voice note'
        )
        // negate FP terms in link display texts
        and not strings.icontains(.display_text, 'voice call center')
    )
  ),
  (
    any(body.links,
        .href_url.path == "/ctt"
        and regex.icontains(.display_text,
                            '(v[nm]|v[o0][il1]ce|audi[o0]|call|missed|caii)(\s?|-)(mail|message|recording|call|caii)|transcription|open mp3|audi[o0] note|listen|playback|\(?(?:\*\*\*|[0-9]{3})?.(?:\*\*\*|[0-9]{3})[^a-z]{0,2}(?:\*{4}|\d+\*+)|play|voice note'
        )
        // negate FP terms in link display texts
        and not strings.icontains(.display_text, 'voice call center')
    )
  ),
  // new domains
  (
    any(body.links,
        network.whois(.href_url.domain).days_old < 10
        and not strings.icontains(.href_url.path, "unsubscribe")
    )
  ),
  // sld use in sender/subject selements
  (
    any(recipients.to,
        // recipient's SLD is in the sender's display name
        strings.icontains(sender.display_name, .email.domain.sld)
        // recipient's SLD is in the sender's display name
        or strings.icontains(subject.subject, .email.domain.sld)
        // recipient's SLD is in the senders local_part
        or strings.icontains(sender.email.local_part, .email.domain.sld)
    )
  ),
  // often times the subject or sender display name will contain time references
  (
    any([sender.display_name, subject.subject, body.current_thread.text],
        regex.icontains(.,
                        // 01min , 60secs
                        '0?[1-9]\s*min(?:(?:ute)?s)?\b',
                        '\d{1,2}\s*s(?:ec(?:ond)?s)?\b',
                        // (00:50s)
                        // 3:26 seconds
                        '[\(\[]?(?:\d{1,2}[\:\s-])\d{1,2}[\)\]]?\s*(?:s(?:(?:ecs?)onds)?)[\)\]]?',
                        // 03min25secs
                        '0?[1-9]\s*min(?:(?:ute)?s)?\d{1,2}\s*s(?:ec(?:ond)?s)?',
                        // [0:39]
                        // (0:39)
                        '[\(\[](?:\d{1,2}[\:\s-])\d{1,2}[\)\]]\s'
        )
    )
    // resuse the same logic against ORC output of message_screenshot
    or any(filter(file.explode(file.message_screenshot()), .depth == 0),
           regex.icontains(.scan.ocr.raw,
                           // 01min , 60secs
                           '0?[1-9]\s*min(?:(?:ute)?s)?\b',
                           '\d{1,2}\s*s(?:ec(?:ond)?s)?\b',
                           // (00:50s)
                           // 3:26 seconds
                           '[\(\[]?(?:\d{1,2}[\:\s-])\d{1,2}[\)\]]?\s*(?:s(?:(?:ecs?)onds)?)[\)\]]?',
                           // 03min25secs
                           '0?[1-9]\s*min(?:(?:ute)?s)?\d{1,2}\s*s(?:ec(?:ond)?s)?',
                           // [0:39]
                           // (0:39)
                           '[\(\[](?:\d{1,2}[\:\s-])\d{1,2}[\)\]]\s'
           )
    )
  ),
  // often times the subject or sender display name will contain dates
  (
    any([sender.display_name, subject.subject],
        // days of week
        any([
              'monday',
              'tuesday',
              'wednesday',
              'thursday',
              'friday',
              'saturday',
              'sunday'
            ],
            strings.icontains(.., .)
        )
        // months
        // may is problematic for words like "Mayor", "Maybe", "MayFlower", etc
        or any([
                 "January",
                 "February",
                 "March",
                 "April",
                 "June",
                 "July",
                 "August",
                 "September",
                 "October",
                 "November",
                 "December"
               ],
               strings.icontains(.., .)
        )
        // use a regex for May
        or regex.icontains(., '\bmay\b')
        // common date formats
        or regex.contains(.,
                          // YYYY-MM-DD or YY-MM-DD (ISO 8601 format)
                          '\d{2}(\d{2})?-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])',
                          // MM/DD/YYYY or MM/DD/YY (US format)
                          '(0[1-9]|1[0-2])/(0[1-9]|[12]\d|3[01])/\d{2}(\d{2})?',
                          // DD/MM/YYYY or DD/MM/YY (European format)
                          '(0[1-9]|[12]\d|3[01])/(0[1-9]|1[0-2])/\d{2}(\d{2})?',
                          // Month DD, YYYY or Month DD, YY (e.g., March 15, 2024 or March 15, 24)
                          '(January|February|March|April|May|June|July|August|September|October|November|December) (0[1-9]|[12]\d|3[01]), \d{2}(\d{2})?'
        )
        // common time formats
        or regex.contains(.,
                          // Example: 23:45, 08:30
                          '([01]\d|2[0-3]):([0-5]\d)',
                          // Example: 23:45:59, 08:30:12
                          '([01]\d|2[0-3]):([0-5]\d):([0-5]\d)',
                          // Example: 08:30 AM, 12:45 pm
                          '(0[1-9]|1[0-2]):([0-5]\d)\s?([AaPp][Mm])',
                          // Example: 08:30 AM, 12:45 pm
                          '(0[1-9]|1[0-2]):([0-5]\d):([0-5]\d) ?([AaPp][Mm])'
        )
    )
    // or use the OCR results from file.message_screenshot
    or any(filter(file.explode(file.message_screenshot()), .depth == 0),
           // days of week
           any([
                 'monday',
                 'tuesday',
                 'wednesday',
                 'thursday',
                 'friday',
                 'saturday',
                 'sunday'
               ],
               strings.icontains(..scan.ocr.raw, .)
           )
           // months
           // may is problematic for words like "Mayor", "Maybe", "MayFlower", etc
           or any([
                    "January",
                    "February",
                    "March",
                    "April",
                    "June",
                    "July",
                    "August",
                    "September",
                    "October",
                    "November",
                    "December"
                  ],
                  strings.icontains(..scan.ocr.raw, .)
           )
           // use a regex for May
           or regex.contains(.scan.ocr.raw, '\bMay\b')
           // common date formats
           or regex.contains(.scan.ocr.raw,
                             // YYYY-MM-DD or YY-MM-DD (ISO 8601 format)
                             '\d{2}(\d{2})?-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])',
                             // MM/DD/YYYY or MM/DD/YY (US format)
                             '(0[1-9]|1[0-2])/(0[1-9]|[12]\d|3[01])/\d{2}(\d{2})?',
                             // DD/MM/YYYY or DD/MM/YY (European format)
                             '(0[1-9]|[12]\d|3[01])/(0[1-9]|1[0-2])/\d{2}(\d{2})?',
                             // Month DD, YYYY or Month DD, YY (e.g., March 15, 2024 or March 15, 24)
                             '(January|February|March|April|May|June|July|August|September|October|November|December) (0[1-9]|[12]\d|3[01]), \d{2}(\d{2})?'
           )
           // common time formats
           or regex.contains(.scan.ocr.raw,
                             // Example: 23:45, 08:30
                             '([01]\d|2[0-3]):([0-5]\d)',
                             // Example: 23:45:59, 08:30:12
                             '([01]\d|2[0-3]):([0-5]\d):([0-5]\d)',
                             // Example: 08:30 AM, 12:45 pm
                             '(0[1-9]|1[0-2]):([0-5]\d)\s?([AaPp][Mm])',
                             // Example: 08:30 AM, 12:45 pm
                             '(0[1-9]|1[0-2]):([0-5]\d):([0-5]\d) ?([AaPp][Mm])'
           )
    )
  ),
  // there are often emoji in the sender display name
  (
    any([sender.display_name, subject.subject],
        // contains an emoji
        regex.contains(.,
                       '[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}]'
        )
        // negate where the emoji occur in tags
        and not regex.contains(.,
                               '^(?:\[[^\]]*\]\s*)*\[[^\]]*[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}][^\]]*\]'
        )
    )
  ),
  // an attachment is a pdf, image, or document that contains a url
  (
    1 <= length(attachments) <= 2
    and any(attachments,
            (
              .file_type in $file_types_images
              or .file_type == "pdf"
              or .file_extension in $file_extensions_macros
            )
            and any(file.explode(.),
                    .scan.qr.type == "url"
                    or strings.icontains(.scan.qr.data, 'http')
                    or any(recipients.to,
                           strings.icontains(..scan.qr.data, .email.local_part)
                           or strings.icontains(..scan.qr.data, .email.email)
                    )
            )
    )
  )
)

// negating legit replies and legitimate audio file attachments and known voicemail senders
and not (
  sender.email.domain.valid
  and sender.email.domain.root_domain in (
    "magicjack.com",
    "magicjackforbusiness.com",
    "unitelvoice.com",
    "voipinterface.net",
    "ringcentral.biz",
    "verizonwireless.com",
    "t-mobile.com",
    "justcall.io",
    "airtel.com",
    "grasshopper.com",
    "ooma.com",
    "ui.com"
  )
)
and not (
  any(attachments,
      strings.starts_with(.content_type, "audio")
      // confirm the content type with .file_type
      // we have seen attachments claim to be audio/* files, only to be exploded as something else
      and .file_type in ("wav", "mp3")
  )
)
and not (
  (
    strings.istarts_with(subject.subject, "RE:")
    // out of office auto-reply
    // the NLU model will handle these better natively soon
    or strings.istarts_with(subject.subject, "Automatic reply:")
  )
  and (length(headers.references) > 0 or headers.in_reply_to is not null)
)
// bounce-back negations
and not any(attachments,
            any(file.parse_eml(.).attachments,
                .content_type == "message/delivery-status"
            )
)
// bounce-back negations
and not (
  any(attachments,
      .content_type in ("message/delivery-status", "text/calendar")
  )
)
// negate newsletters
and not (
  (
    any(ml.nlu_classifier(body.current_thread.text).topics,
        .name in (
          "Newsletters and Digests",
          "B2B Cold Outreach",
          "Events and Webinars"
        )
        and .confidence == "high"
    )
  )
  and not strings.icontains(body.current_thread.text,
                            "this voicemail was shared by"
  )
)
// negate bouncebacks from proofpoint
and not (
  sender.display_name == "Mail Delivery Subsystem"
  and strings.ends_with(headers.message_id, "pphosted.com>")
  and any(headers.hops,
          .index == 0 and strings.contains(.received.server.raw, "pphosted.com")
  )
  and any(attachments, .content_type == "message/rfc822")
)
// negate CheckPoint encrypted messages
and not (
  // CheckPoint banner
  length(attachments) == 1
  and any(body.links, .href_url.domain.root_domain == "checkpointcloudsec.com")
  and strings.istarts_with(headers.message_id, "<encrypted")
  and any(headers.domains, .root_domain == "checkpointcloudsec.com")
)
// an impersonated high trust domain
and (
  (
    sender.email.domain.root_domain in $high_trust_sender_root_domains
    and not headers.auth_summary.dmarc.pass
    // service abuse
    and not sender.email.email in ("noreply-application-integration@google.com")
  )
  or sender.email.domain.root_domain not in $high_trust_sender_root_domains

  // sender profile
  or (
    (
      not sender.email.domain.root_domain in $org_domains
      and (profile.by_sender_email().prevalence not in ("common"))
      and not profile.by_sender_email().solicited
    )
    or (
      profile.by_sender_email().any_messages_malicious_or_spam
      and not profile.by_sender_email().any_messages_benign
    )
    // match if the sender is in org domains but failed auth
    or (
      sender.email.domain.domain in $org_domains
      and not coalesce(headers.auth_summary.dmarc.pass, false)
    )
    // match if the sender address is blank or null
    or (regex.match(sender.email.email, "") or sender.email.email is null)
  )
)

Detection logic

Scope: inbound message.

This rule detects a common credential phishing vector enticing the user to engage with links under the premise that they have a voicemail to retrieve. The rule looks for voicemail verbiage in the display name, body, subject or a combination of those elements with emojis or a medium to high credential theft NLU Intent from first-time + unsolicited sender.

  1. inbound message
  2. all of:
    • any of:
      • all of:
        • length(filter(body.links, .href_url.scheme != 'mailto')) > 0
        • length(filter(body.links, .href_url.scheme != 'mailto')) ≤ 25
      • all of:
        • length(distinct(attachments, .md5)) > 0
        • length(distinct(attachments, .md5)) ≤ 3
    • all of:
      • length(distinct(attachments, .md5)) ≥ 0
      • length(distinct(attachments, .md5)) ≤ 8
  3. any of:
    • any of [subject.subject, sender.display_name] where:
      • . matches any of 12 patterns
        • (?:v[nm](\b|[[:punct:]])?|\bv[o0][il1]ce(?:mail|message)?|audi[o0]|incoming|missed(?:\sa\s)?|left( a)?|wireless)(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:mail|message|msg|recording|received|notif|support|ca[li1][li1]\d*\b|ca[il1][il1](?:er)?|log|transcript(?:ion)?)\b
        • v[[:punct:]](?:mail|message|msg|recording|received|notif|support|ca[li1][li1]\d*\b|ca[il1][il1](?:er)?|log|transcript(?:ion)?\b)
        • ca[li1][li1](?:er)?(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:v[nm](\b|[[:punct:]])?|\bv[o0][il1]ce(?:mail|message)?|audi[o0]|missed(?:\sa\s)?|left( a)?)
        • (?:open mp3|audi[o0] note|\.wav|left a vm|[^\s]+voip[^\s]*|unanswered.*ca[li1][li1]|incoming.vm|left msg|wireless ca[li1][li1]er|VM Service|v[o0][il1]ce message|missed.ca[li1][li1](?:e[rd])?|\bca[li1][li1].(?:support|service)(?: for| log)?|missed.{0,10} VM|new v[o0][il1]cemail from|new.v.m.from.\+?\d+|new v[o0][il1]cemail?(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}transcript(s|ion)?|message received|new (?:message|call|voicemail).{0,15}(?:info|notification|alert)|incoming transmission|voice note)
        • ^\(\d\)\s(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:message|voip|v[o0][il1]ce|unread|call)
        • ca[li1][li1](?:er)?(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:playback|transcript)
        • \b1?\(?(\d{3}|\d{2}[\*X]|\d[\*X]{2})\)?[^a-z0-9]{0,2}(\d{2,3}|\d{2}[\*X]|\d[\*X]{2}|[\*X]{2,3})[^a-z0-9]{0,4}(\d{3}[\*X]|\d{2}[\*X]{2}|\d[\*X]{3}|[\*X]{3,4})[^0-9]
        • \b1?\(?(\d{2}[\*X]|\d[\*X]{2}|[\*X]{2,3})\)?[^a-z0-9]{0,2}(\d{2,3}|\d{2}[\*X]|\d[\*X]{2})[^a-z0-9]{0,4}(\d{4}|\d{3}[\*X]|\d{2}[\*X]{2}|\d[\*X]{3}|[\*X]{3,4})\b
        • v[o0][il1]ce[\s\-_]?m(?:ail|sg|essage)?[\*X\.\-_]{2,}
        • v[o0][il1]cem[\*X\.\-_]{2,}
        • \d+\s+new.*v[o0][il1]ce(?:mail|message|m[\*]+)?
        • (?:sent|new|incoming)[\s\-]+message.*(v[o0][il1]ce|<.*@.*>)
    • strings.replace_confusables(body.current_thread.text) matches any of 13 patterns
      • sent (?:from|by) (?:your )?v[o0][il1]ce (?:ma[il1][li1] )?system
      • (?:(?:new|this) |^)(?:v[o0][il1]ce(?:ma[il1][li1])?|aud[il1][o0]) (?:message|notification|record)
      • v[o0][il1]cema[il1][li1] (is )?attached
      • an? (?:new )?encrypted v[o0][il1]cemail
      • a (?:new )?pending message
      • Your? have (?: an?)?incoming v[o0][il1]ceRec
      • you(?:\'ve| have) a (?:new )?m[il1]ssed ca[li1][li1]
      • New V[o0][il1]cema[il1][li1] Received
      • New m[il1]ssed ca[li1][li1] record
      • \bv[o0][il1]cema[il1][li1] transcript\b
      • Listen to V[o0][il1]ceMa[il1][li1]
      • New v[o0][il1]cema[il1][li1] from
      • v[o0][il1]ce note
    • all of:
      • body.current_thread.text matches any of 2 patterns
        • (?:you|we) (?:have |received )+(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:\b|\s+)v[o0][il1]ce\s?(?:ma[il1][li1]|aud[il1][o0]|message|notification)
        • left you a (?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:v[o0][il1]ce(?:ma[il1][li1])?|aud[il1][o0])(?: message|notification)?
      • not:
        • body.current_thread.text matches '(?:I(?:\\sjust)?|just(?: called you at (?:\\d+[[:punct:]])+) and)? left you a (?:\\w+(\\s\\w+)?|[[:punct:]]+|\\s+){0,3}(?:v[o0][il1]ce(?:mail)?|audio)(?: message)?'
      • not:
        • body.current_thread.text matches 'you (?:have |received )my voice\\s?(?:mail|audio|message)'
    • all of:
      • length(attachments) > 0
      • any of:
        • all of attachments where all hold:
          • .file_type in $file_types_images
          • beta.parse_exif(.).image_height is not 1
        • length(filter(attachments, strings.starts_with(.content_type, 'audio') and not .file_type in ('wav', 'mp3'))) + length(filter(attachments, .file_type in $file_types_images and beta.parse_exif(.).image_height != 1)) is length(attachments)
      • any of filter(...) where any holds:
        • .scan.ocr.raw matches any of 13 patterns
          • sent (?:from|by) (?:your )?v[o0][il1]ce (?:ma[il1][li1] )?system
          • (?:(?:new|this) |^)(?:v[o0][il1]ce(?:ma[il1][li1])?|aud[il1][o0]) (?:message|notification|record)
          • v[o0][il1]cema[il1][li1] (is )?attached
          • an? (?:new )?encrypted v[o0][il1]cemail
          • a (?:new )?pending message
          • Your? have (?: an?)?incoming v[o0][il1]ceRec
          • you(?:\'ve| have) a (?:new )?m[il1]ssed ca[li1][li1]
          • New V[o0][il1]cema[il1][li1] Received
          • New m[il1]ssed ca[li1][li1] record
          • \bv[o0][il1]cema[il1][li1] transcript\b
          • Listen to V[o0][il1]ceMa[il1][li1]
          • New v[o0][il1]cema[il1][li1] from
          • v[o0][il1]ce note
        • all of:
          • .scan.ocr.raw matches any of 2 patterns
            • (?:you|we) (?:have |received )+(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:\b|\s+)v[o0][il1]ce\s?(?:ma[il1][li1]|aud[il1][o0]|message|notification)
            • left you a (?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:v[o0][il1]ce(?:mail)?|audi[o0])(?: message)?
          • not:
            • body.current_thread.text matches '(?:I(?:\\sjust)?|just) left you a (?:\\w+(\\s\\w+)?|[[:punct:]]+|\\s+){0,3}(?:voice(?:mail)?|audio)(?: message)?'
          • not:
            • body.current_thread.text matches 'you (?:have |received )my voice\\s?(?:mail|audio|message)'
    • body.html.raw contains '<title>Voicemail Notification</title>'
    • body.html.raw contains '<!-- Voicemail phone logo'
  4. at least 2 of:
    • sender.email.domain.root_domain in $free_email_providers
    • any of:
      • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
        • .name in ('cred_theft')
        • .confidence in ('medium', 'high')
      • any of filter(...) where:
        • any of ml.nlu_classifier(.scan.ocr.raw).intents where all hold:
          • .name in ('cred_theft')
          • .confidence in ('medium', 'high')
    • any of attachments where all hold:
      • .content_type in ('html', 'text', 'text/html')
      • any of ml.logo_detect(file.html_screenshot(.)).brands where all hold:
        • .name in ('Microsoft')
        • .confidence in ('medium', 'high')
    • sender.display_name matches '(v[o0][il1]ce|audi[o0]|call|missed|caii)(\\s?|-)(mail|message|recording|call|caii)|(transcription|Caller.?ID)'
    • any of attachments where all hold:
      • any of:
        • .content_type in ('html', 'text', 'text/html')
        • .file_type in ('html', 'unknown', 'svg')
        • .file_type is 'pdf'
      • any of:
        • .file_name matches any of 7 patterns
          • (?:v[o0][il1]ce|aud[i1l][o0]|call|missed|caii|mail|message|recording|call|caii|transcr[il1]ption|v[nm]|audi[o0]|play|listen|unheard|msg)
          • 0?[1-9]\s*min(?:(?:ute)?s)?
          • \d{1,2}\s*s(?:ec(?:ond)?s)?
          • [\(\[]?(?:\d{1,2}[\:\s-])\d{1,2}[\)\]]?\s*(?:s(?:(?:ecs?)onds)?)[\)\]]?
          • 0?[1-9]\s*min(?:(?:ute)?s)?\d{1,2}\s*s(?:ec(?:ond)?s)?
          • [\(\[](?:\d{1,2}[\:\s-])\d{1,2}[\)\]]\s
          • [\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}]
        • .file_name in ('.htm', '.html')
        • .file_name is missing
    • any of attachments where all hold:
      • any of:
        • .content_type in ('html', 'text', 'text/html')
        • .file_type in ('html', 'unknown', 'svg')
      • any of:
        • all of:
          • .size < 1500
          • any of file.explode(.) where:
            • length(.scan.html.scripts) > 0
        • file.parse_text(., encodings=['ascii', 'utf8', 'utf16-le']).text matches any of 9 patterns
          • *onload*
          • *window.location.href*
          • *onerror*
          • *CDATA*
          • *<script*
          • *</script*
          • *atob*
          • *location.assign*
          • *decodeURIComponent*
    • any of attachments where all hold:
      • any of:
        • .content_type in ('html', 'text', 'text/html')
        • .file_type in ('html', 'unknown', 'svg')
      • any of recipients.to where any holds:
        • strings.contains(file.parse_html(.).raw)
        • strings.contains(.file_name)
    • any of filter(attachments) where:
      • any of file.parse_eml(.).attachments where all hold:
        • any of:
          • .content_type in ('html', 'text', 'text/html')
          • .file_type in ('html', 'unknown', 'svg')
          • .file_type is 'pdf'
        • any of:
          • .file_name matches any of 7 patterns
            • (?:v[o0][il1]ce|aud[il1][o0]|call|missed|caii|mail|message|recording|call|caii|transcr[il1]ption|v[nm]|audi[o0]|play|listen|unheard|msg)
            • 0?[1-9]\s*min(?:(?:ute)?s)?
            • \d{1,2}\s*s(?:ec(?:ond)?s)?
            • [\(\[]?(?:\d{1,2}[\:\s-])\d{1,2}[\)\]]?\s*(?:s(?:(?:ecs?)onds)?)[\)\]]?
            • 0?[1-9]\s*min(?:(?:ute)?s)?\d{1,2}\s*s(?:ec(?:ond)?s)?
            • [\(\[](?:\d{1,2}[\:\s-])\d{1,2}[\)\]]\s
            • [\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}]
          • .file_name in ('.htm', '.html')
          • .file_name is missing
    • any of filter(attachments) where all hold:
      • file.parse_eml(.).subject.subject is subject.subject
      • file.parse_eml(.).sender.email.email is sender.email.email
      • all of:
        • length(file.parse_eml(.).recipients.to) is length(recipients.to)
        • all of recipients.to where:
          • .email.email in map(file.parse_eml(.).recipients.to, .email.email)
      • any of:
        • length(file.parse_eml(.).attachments) > 0
        • length(filter(file.parse_eml(.).body.links, .href_url.domain.domain not in $org_domains and .href_url.domain.root_domain not in $org_domains)) > 0
    • all of:
      • length(filter(recipients.to, .email.email != '' or .email.domain.valid)) > 0
      • any of body.links where:
        • any of recipients.to where any holds:
          • strings.icontains(.href_url.url)
          • strings.icontains(.href_url.url)
    • all of:
      • length(body.current_thread.text) < 700
      • body.current_thread.text matches 'Méssãge|Méssage|Recéived|Addréss'
    • all of:
      • length(filter(body.links, .display_text is not null and .display_url.url is null and .href_url.domain.valid)) > 0
      • all of filter(body.links) where all hold:
        • .href_url.domain.root_domain is not sender.email.domain.root_domain
        • .href_url.domain.root_domain not in $org_domains
        • .href_url.domain.root_domain not in ('aka.ms')
        • .href_url.domain.root_domain not in ('unitelvoice.com', 'googleapis.com', 'dialmycalls.com', 'ringcentral.biz', 'google.com')
    • any of body.links where all hold:
      • .display_text matches '[^a-z]*[A-Z][^a-z]*'
      • .display_text matches '(?:v[nm]|v[o0][il1]ce|audi[o0]|ca[li][li]|missed|preview)(\\s?|-)(mail|message|recording|call|caii)|transcription|open mp3|audi[o0] note|listen|playback|\\(?(?:\\*\\*\\*|[0-9]{3})?.(?:\\*\\*\\*|[0-9]{3})[^a-z]{0,2}(?:\\*{4}|\\d+\\*+)|play|voice note'
      • not:
        • .display_text contains 'voice call center'
    • any of body.links where all hold:
      • .href_url.path is '/ctt'
      • .display_text matches '(v[nm]|v[o0][il1]ce|audi[o0]|call|missed|caii)(\\s?|-)(mail|message|recording|call|caii)|transcription|open mp3|audi[o0] note|listen|playback|\\(?(?:\\*\\*\\*|[0-9]{3})?.(?:\\*\\*\\*|[0-9]{3})[^a-z]{0,2}(?:\\*{4}|\\d+\\*+)|play|voice note'
      • not:
        • .display_text contains 'voice call center'
    • any of body.links where all hold:
      • network.whois(.href_url.domain).days_old < 10
      • not:
        • .href_url.path contains 'unsubscribe'
    • any of recipients.to where any holds:
      • strings.icontains(sender.display_name)
      • strings.icontains(subject.subject)
      • strings.icontains(sender.email.local_part)
    • any of:
      • any of [sender.display_name, subject.subject, body.current_thread.text] where:
        • . matches any of 5 patterns
          • 0?[1-9]\s*min(?:(?:ute)?s)?\b
          • \d{1,2}\s*s(?:ec(?:ond)?s)?\b
          • [\(\[]?(?:\d{1,2}[\:\s-])\d{1,2}[\)\]]?\s*(?:s(?:(?:ecs?)onds)?)[\)\]]?
          • 0?[1-9]\s*min(?:(?:ute)?s)?\d{1,2}\s*s(?:ec(?:ond)?s)?
          • [\(\[](?:\d{1,2}[\:\s-])\d{1,2}[\)\]]\s
      • any of filter(...) where:
        • .scan.ocr.raw matches any of 5 patterns
          • 0?[1-9]\s*min(?:(?:ute)?s)?\b
          • \d{1,2}\s*s(?:ec(?:ond)?s)?\b
          • [\(\[]?(?:\d{1,2}[\:\s-])\d{1,2}[\)\]]?\s*(?:s(?:(?:ecs?)onds)?)[\)\]]?
          • 0?[1-9]\s*min(?:(?:ute)?s)?\d{1,2}\s*s(?:ec(?:ond)?s)?
          • [\(\[](?:\d{1,2}[\:\s-])\d{1,2}[\)\]]\s
    • any of:
      • any of [sender.display_name, subject.subject] where any holds:
        • any of ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'] where:
          • strings.icontains(.)
        • any of ['January', 'February', 'March', 'April', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] where:
          • strings.icontains(.)
        • . matches '\\bmay\\b'
        • . matches any of 4 patterns
          • \d{2}(\d{2})?-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])
          • (0[1-9]|1[0-2])/(0[1-9]|[12]\d|3[01])/\d{2}(\d{2})?
          • (0[1-9]|[12]\d|3[01])/(0[1-9]|1[0-2])/\d{2}(\d{2})?
          • (January|February|March|April|May|June|July|August|September|October|November|December) (0[1-9]|[12]\d|3[01]), \d{2}(\d{2})?
        • . matches any of 4 patterns
          • ([01]\d|2[0-3]):([0-5]\d)
          • ([01]\d|2[0-3]):([0-5]\d):([0-5]\d)
          • (0[1-9]|1[0-2]):([0-5]\d)\s?([AaPp][Mm])
          • (0[1-9]|1[0-2]):([0-5]\d):([0-5]\d) ?([AaPp][Mm])
      • any of filter(...) where any holds:
        • any of ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'] where:
          • strings.icontains(.scan.ocr.raw)
        • any of ['January', 'February', 'March', 'April', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] where:
          • strings.icontains(.scan.ocr.raw)
        • .scan.ocr.raw matches '\\bMay\\b'
        • .scan.ocr.raw matches any of 4 patterns
          • \d{2}(\d{2})?-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])
          • (0[1-9]|1[0-2])/(0[1-9]|[12]\d|3[01])/\d{2}(\d{2})?
          • (0[1-9]|[12]\d|3[01])/(0[1-9]|1[0-2])/\d{2}(\d{2})?
          • (January|February|March|April|May|June|July|August|September|October|November|December) (0[1-9]|[12]\d|3[01]), \d{2}(\d{2})?
        • .scan.ocr.raw matches any of 4 patterns
          • ([01]\d|2[0-3]):([0-5]\d)
          • ([01]\d|2[0-3]):([0-5]\d):([0-5]\d)
          • (0[1-9]|1[0-2]):([0-5]\d)\s?([AaPp][Mm])
          • (0[1-9]|1[0-2]):([0-5]\d):([0-5]\d) ?([AaPp][Mm])
    • any of [sender.display_name, subject.subject] where all hold:
      • . matches '[\\x{1F300}-\\x{1F5FF}\\x{1F600}-\\x{1F64F}\\x{1F680}-\\x{1F6FF}\\x{1F700}-\\x{1F77F}\\x{1F780}-\\x{1F7FF}\\x{1F900}-\\x{1F9FF}\\x{2600}-\\x{26FF}\\x{2700}-\\x{27BF}\\x{2300}-\\x{23FF}]'
      • not:
        • . matches '^(?:\\[[^\\]]*\\]\\s*)*\\[[^\\]]*[\\x{1F300}-\\x{1F5FF}\\x{1F600}-\\x{1F64F}\\x{1F680}-\\x{1F6FF}\\x{1F700}-\\x{1F77F}\\x{1F780}-\\x{1F7FF}\\x{1F900}-\\x{1F9FF}\\x{2600}-\\x{26FF}\\x{2700}-\\x{27BF}\\x{2300}-\\x{23FF}][^\\]]*\\]'
    • all of:
      • all of:
        • length(attachments) ≥ 1
        • length(attachments) ≤ 2
      • any of attachments where all hold:
        • any of:
          • .file_type in $file_types_images
          • .file_type is 'pdf'
          • .file_extension in $file_extensions_macros
        • any of file.explode(.) where any holds:
          • .scan.qr.type is 'url'
          • .scan.qr.data contains 'http'
          • any of recipients.to where any holds:
            • strings.icontains(.scan.qr.data)
            • strings.icontains(.scan.qr.data)
  5. not:
    • all of:
      • sender.email.domain.valid
      • sender.email.domain.root_domain in ('magicjack.com', 'magicjackforbusiness.com', 'unitelvoice.com', 'voipinterface.net', 'ringcentral.biz', 'verizonwireless.com', 't-mobile.com', 'justcall.io', 'airtel.com', 'grasshopper.com', 'ooma.com', 'ui.com')
  6. not:
    • any of attachments where all hold:
      • .content_type starts with 'audio'
      • .file_type in ('wav', 'mp3')
  7. not:
    • all of:
      • any of:
        • subject.subject starts with 'RE:'
        • subject.subject starts with 'Automatic reply:'
      • any of:
        • length(headers.references) > 0
        • headers.in_reply_to is set
  8. not:
    • any of attachments where:
      • any of file.parse_eml(.).attachments where:
        • .content_type is 'message/delivery-status'
  9. not:
    • any of attachments where:
      • .content_type in ('message/delivery-status', 'text/calendar')
  10. not:
    • all of:
      • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
        • .name in ('Newsletters and Digests', 'B2B Cold Outreach', 'Events and Webinars')
        • .confidence is 'high'
      • not:
        • body.current_thread.text contains 'this voicemail was shared by'
  11. not:
    • all of:
      • sender.display_name is 'Mail Delivery Subsystem'
      • headers.message_id ends with 'pphosted.com>'
      • any of headers.hops where all hold:
        • .index is 0
        • .received.server.raw contains 'pphosted.com'
      • any of attachments where:
        • .content_type is 'message/rfc822'
  12. not:
    • all of:
      • length(attachments) is 1
      • any of body.links where:
        • .href_url.domain.root_domain is 'checkpointcloudsec.com'
      • headers.message_id starts with '<encrypted'
      • any of headers.domains where:
        • .root_domain is 'checkpointcloudsec.com'
  13. any of:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • not:
        • headers.auth_summary.dmarc.pass
      • not:
        • sender.email.email in ('noreply-application-integration@google.com')
    • sender.email.domain.root_domain not in $high_trust_sender_root_domains
    • any of:
      • all of:
        • not:
          • sender.email.domain.root_domain in $org_domains
        • profile.by_sender_email().prevalence not in ('common')
        • not:
          • profile.by_sender_email().solicited
      • all of:
        • profile.by_sender_email().any_messages_malicious_or_spam
        • not:
          • profile.by_sender_email().any_messages_benign
      • all of:
        • sender.email.domain.domain in $org_domains
        • not:
          • coalesce(headers.auth_summary.dmarc.pass)
      • any of:
        • sender.email.email matches ''
        • sender.email.email is missing

Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_name, attachments[].file_type, attachments[].md5, attachments[].size, body.current_thread.text, body.html.raw, body.links, body.links[].display_text, body.links[].display_url.url, body.links[].href_url.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.valid, body.links[].href_url.path, body.links[].href_url.scheme, body.links[].href_url.url, headers.auth_summary.dmarc.pass, headers.domains, headers.domains[].root_domain, headers.hops, headers.hops[].index, headers.hops[].received.server.raw, headers.in_reply_to, headers.message_id, headers.references, 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.domain, sender.email.domain.root_domain, sender.email.domain.valid, sender.email.email, sender.email.local_part, subject.subject, type.inbound. Sensors: beta.parse_exif, file.explode, file.html_screenshot, file.message_screenshot, file.parse_eml, file.parse_html, file.parse_text, ml.logo_detect, ml.nlu_classifier, network.whois, profile.by_sender_email, regex.contains, regex.icontains, regex.match, strings.contains, strings.ends_with, strings.icontains, strings.ilike, strings.istarts_with, strings.replace_confusables, strings.starts_with. Reference lists: $file_extensions_macros, $file_types_images, $free_email_providers, $high_trust_sender_root_domains, $org_domains.

Indicators matched (99)

FieldMatchValue
regex.icontainsregex(?:v[nm](\b|[[:punct:]])?|\bv[o0][il1]ce(?:mail|message)?|audi[o0]|incoming|missed(?:\sa\s)?|left( a)?|wireless)(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:mail|message|msg|recording|received|notif|support|ca[li1][li1]\d*\b|ca[il1][il1](?:er)?|log|transcript(?:ion)?)\b
regex.icontainsregexv[[:punct:]](?:mail|message|msg|recording|received|notif|support|ca[li1][li1]\d*\b|ca[il1][il1](?:er)?|log|transcript(?:ion)?\b)
regex.icontainsregexca[li1][li1](?:er)?(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:v[nm](\b|[[:punct:]])?|\bv[o0][il1]ce(?:mail|message)?|audi[o0]|missed(?:\sa\s)?|left( a)?)
regex.icontainsregex(?:open mp3|audi[o0] note|\.wav|left a vm|[^\s]+voip[^\s]*|unanswered.*ca[li1][li1]|incoming.vm|left msg|wireless ca[li1][li1]er|VM Service|v[o0][il1]ce message|missed.ca[li1][li1](?:e[rd])?|\bca[li1][li1].(?:support|service)(?: for| log)?|missed.{0,10} VM|new v[o0][il1]cemail from|new.v.m.from.\+?\d+|new v[o0][il1]cemail?(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}transcript(s|ion)?|message received|new (?:message|call|voicemail).{0,15}(?:info|notification|alert)|incoming transmission|voice note)
regex.icontainsregex^\(\d\)\s(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:message|voip|v[o0][il1]ce|unread|call)
regex.icontainsregexca[li1][li1](?:er)?(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:playback|transcript)
regex.icontainsregex\b1?\(?(\d{3}|\d{2}[\*X]|\d[\*X]{2})\)?[^a-z0-9]{0,2}(\d{2,3}|\d{2}[\*X]|\d[\*X]{2}|[\*X]{2,3})[^a-z0-9]{0,4}(\d{3}[\*X]|\d{2}[\*X]{2}|\d[\*X]{3}|[\*X]{3,4})[^0-9]
regex.icontainsregex\b1?\(?(\d{2}[\*X]|\d[\*X]{2}|[\*X]{2,3})\)?[^a-z0-9]{0,2}(\d{2,3}|\d{2}[\*X]|\d[\*X]{2})[^a-z0-9]{0,4}(\d{4}|\d{3}[\*X]|\d{2}[\*X]{2}|\d[\*X]{3}|[\*X]{3,4})\b
regex.icontainsregexv[o0][il1]ce[\s\-_]?m(?:ail|sg|essage)?[\*X\.\-_]{2,}
regex.icontainsregexv[o0][il1]cem[\*X\.\-_]{2,}
regex.icontainsregex\d+\s+new.*v[o0][il1]ce(?:mail|message|m[\*]+)?
regex.icontainsregex(?:sent|new|incoming)[\s\-]+message.*(v[o0][il1]ce|<.*@.*>)
87 more
regex.icontainsregexsent (?:from|by) (?:your )?v[o0][il1]ce (?:ma[il1][li1] )?system
regex.icontainsregex(?:(?:new|this) |^)(?:v[o0][il1]ce(?:ma[il1][li1])?|aud[il1][o0]) (?:message|notification|record)
regex.icontainsregexv[o0][il1]cema[il1][li1] (is )?attached
regex.icontainsregexan? (?:new )?encrypted v[o0][il1]cemail
regex.icontainsregexa (?:new )?pending message
regex.icontainsregexYour? have (?: an?)?incoming v[o0][il1]ceRec
regex.icontainsregexyou(?:\'ve| have) a (?:new )?m[il1]ssed ca[li1][li1]
regex.icontainsregexNew V[o0][il1]cema[il1][li1] Received
regex.icontainsregexNew m[il1]ssed ca[li1][li1] record
regex.icontainsregex\bv[o0][il1]cema[il1][li1] transcript\b
regex.icontainsregexListen to V[o0][il1]ceMa[il1][li1]
regex.icontainsregexNew v[o0][il1]cema[il1][li1] from
regex.icontainsregexv[o0][il1]ce note
regex.icontainsregex(?:you|we) (?:have |received )+(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:\b|\s+)v[o0][il1]ce\s?(?:ma[il1][li1]|aud[il1][o0]|message|notification)
regex.icontainsregexleft you a (?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:v[o0][il1]ce(?:ma[il1][li1])?|aud[il1][o0])(?: message|notification)?
regex.icontainsregexleft you a (?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:v[o0][il1]ce(?:mail)?|audi[o0])(?: message)?
strings.icontainssubstring<title>Voicemail Notification</title>
strings.icontainssubstring<!-- Voicemail phone logo
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
ml.nlu_classifier(filter(...)[].scan.ocr.raw).intents[].namemembercred_theft
ml.nlu_classifier(filter(...)[].scan.ocr.raw).intents[].confidencemembermedium
ml.nlu_classifier(filter(...)[].scan.ocr.raw).intents[].confidencememberhigh
attachments[].content_typememberhtml
attachments[].content_typemembertext
attachments[].content_typemembertext/html
ml.logo_detect(file.html_screenshot(attachments[])).brands[].namememberMicrosoft
ml.logo_detect(file.html_screenshot(attachments[])).brands[].confidencemembermedium
ml.logo_detect(file.html_screenshot(attachments[])).brands[].confidencememberhigh
regex.icontainsregex(v[o0][il1]ce|audi[o0]|call|missed|caii)(\s?|-)(mail|message|recording|call|caii)|(transcription|Caller.?ID)
attachments[].file_typememberhtml
attachments[].file_typememberunknown
attachments[].file_typemembersvg
attachments[].file_typeequalspdf
regex.icontainsregex(?:v[o0][il1]ce|aud[i1l][o0]|call|missed|caii|mail|message|recording|call|caii|transcr[il1]ption|v[nm]|audi[o0]|play|listen|unheard|msg)
regex.icontainsregex0?[1-9]\s*min(?:(?:ute)?s)?
regex.icontainsregex\d{1,2}\s*s(?:ec(?:ond)?s)?
regex.icontainsregex[\(\[]?(?:\d{1,2}[\:\s-])\d{1,2}[\)\]]?\s*(?:s(?:(?:ecs?)onds)?)[\)\]]?
regex.icontainsregex0?[1-9]\s*min(?:(?:ute)?s)?\d{1,2}\s*s(?:ec(?:ond)?s)?
regex.icontainsregex[\(\[](?:\d{1,2}[\:\s-])\d{1,2}[\)\]]\s
regex.icontainsregex[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}]
attachments[].file_namemember.htm
attachments[].file_namemember.html
strings.ilikesubstring*onload*
strings.ilikesubstring*window.location.href*
strings.ilikesubstring*onerror*
strings.ilikesubstring*CDATA*
strings.ilikesubstring*<script*
strings.ilikesubstring*</script*
strings.ilikesubstring*atob*
strings.ilikesubstring*location.assign*
strings.ilikesubstring*decodeURIComponent*
attachments[].content_typeequalsmessage/rfc822
attachments[].file_extensionmembereml
file.parse_eml(filter(attachments)[]).attachments[].content_typememberhtml
file.parse_eml(filter(attachments)[]).attachments[].content_typemembertext
file.parse_eml(filter(attachments)[]).attachments[].content_typemembertext/html
file.parse_eml(filter(attachments)[]).attachments[].file_typememberhtml
file.parse_eml(filter(attachments)[]).attachments[].file_typememberunknown
file.parse_eml(filter(attachments)[]).attachments[].file_typemembersvg
file.parse_eml(filter(attachments)[]).attachments[].file_typeequalspdf
regex.icontainsregex(?:v[o0][il1]ce|aud[il1][o0]|call|missed|caii|mail|message|recording|call|caii|transcr[il1]ption|v[nm]|audi[o0]|play|listen|unheard|msg)
file.parse_eml(filter(attachments)[]).attachments[].file_namemember.htm
file.parse_eml(filter(attachments)[]).attachments[].file_namemember.html
regex.icontainsregexMéssãge|Méssage|Recéived|Addréss
regex.containsregex[^a-z]*[A-Z][^a-z]*
regex.icontainsregex(?:v[nm]|v[o0][il1]ce|audi[o0]|ca[li][li]|missed|preview)(\s?|-)(mail|message|recording|call|caii)|transcription|open mp3|audi[o0] note|listen|playback|\(?(?:\*\*\*|[0-9]{3})?.(?:\*\*\*|[0-9]{3})[^a-z]{0,2}(?:\*{4}|\d+\*+)|play|voice note
body.links[].href_url.pathequals/ctt
regex.icontainsregex(v[nm]|v[o0][il1]ce|audi[o0]|call|missed|caii)(\s?|-)(mail|message|recording|call|caii)|transcription|open mp3|audi[o0] note|listen|playback|\(?(?:\*\*\*|[0-9]{3})?.(?:\*\*\*|[0-9]{3})[^a-z]{0,2}(?:\*{4}|\d+\*+)|play|voice note
regex.icontainsregex0?[1-9]\s*min(?:(?:ute)?s)?\b
regex.icontainsregex\d{1,2}\s*s(?:ec(?:ond)?s)?\b
regex.icontainsregex\bmay\b
regex.containsregex\d{2}(\d{2})?-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])
regex.containsregex(0[1-9]|1[0-2])/(0[1-9]|[12]\d|3[01])/\d{2}(\d{2})?
regex.containsregex(0[1-9]|[12]\d|3[01])/(0[1-9]|1[0-2])/\d{2}(\d{2})?
regex.containsregex(January|February|March|April|May|June|July|August|September|October|November|December) (0[1-9]|[12]\d|3[01]), \d{2}(\d{2})?
regex.containsregex([01]\d|2[0-3]):([0-5]\d)
regex.containsregex([01]\d|2[0-3]):([0-5]\d):([0-5]\d)
regex.containsregex(0[1-9]|1[0-2]):([0-5]\d)\s?([AaPp][Mm])
regex.containsregex(0[1-9]|1[0-2]):([0-5]\d):([0-5]\d) ?([AaPp][Mm])
regex.containsregex\bMay\b
regex.containsregex[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}]
file.explode(attachments[])[].scan.qr.typeequalsurl
strings.icontainssubstringhttp
strings.icontainssubstringthis voicemail was shared by
regex.matchregex

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      any(attachments)
        and
          any(file.explode(attachments))
            or
              any(recipients.to)
                strings.icontains func_call "strings.icontains(file.explode(attachments[])[].scan.qr.data)"
              file.explode(attachments[])[].scan.qr.data contains "http"
              file.explode(attachments[])[].scan.qr.type eq "url"
          or
            attachments.file_type eq "pdf"
             macro "attachments[].file_extension in file_extensions_macros"
             macro "attachments[].file_type in file_types_images"
      attachments length_compare "1"
      attachments length_compare "2"
    any(attachments)
      and
        or
          and
            any(file.explode(attachments))
              file.explode(attachments).scan.html.scripts length_compare "0"
            attachments.size lt "1500"
          file.parse_text(attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text match "</script"
          file.parse_text(attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text match "<script"
          file.parse_text(attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text match "CDATA"
          file.parse_text(attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text match "atob"
          file.parse_text(attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text match "decodeURIComponent"
          file.parse_text(attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text match "location.assign"
          file.parse_text(attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text match "onerror"
          file.parse_text(attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text match "onload"
          file.parse_text(attachments[], encodings=['ascii', 'utf8', 'utf16-le']).text match "window.location.href"
        or
          attachments.content_type in ["html", "text", "text/html"]
          attachments.file_type in ["html", "svg", "unknown"]
    any(filter(attachments))
      any(file.parse_eml(filter(attachments)).attachments)
        and
          or
            file.parse_eml(filter(attachments)[]).attachments[].content_type in ["html", "text", "text/html"]
            file.parse_eml(filter(attachments)[]).attachments[].file_type eq "pdf"
            file.parse_eml(filter(attachments)[]).attachments[].file_type in ["html", "svg", "unknown"]
          or
            file.parse_eml(filter(attachments)[]).attachments[].file_name in [".htm", ".html"]
            file.parse_eml(filter(attachments)[]).attachments[].file_name is_null
            file.parse_eml(filter(attachments)[]).attachments[].file_name regex_match "(?:v[o0][il1]ce|aud[il1][o0]|call|missed|caii|mail|message|recording|call|caii|transcr[il1]ption|v[nm]|audi[o0]|play|listen|unheard|msg)"
            file.parse_eml(filter(attachments)[]).attachments[].file_name regex_match "0?[1-9]\\s*min(?:(?:ute)?s)?"
            file.parse_eml(filter(attachments)[]).attachments[].file_name regex_match "0?[1-9]\\s*min(?:(?:ute)?s)?\\d{1,2}\\s*s(?:ec(?:ond)?s)?"
            file.parse_eml(filter(attachments)[]).attachments[].file_name regex_match "[\\(\\[](?:\\d{1,2}[\\:\\s-])\\d{1,2}[\\)\\]]\\s"
            file.parse_eml(filter(attachments)[]).attachments[].file_name regex_match "[\\(\\[]?(?:\\d{1,2}[\\:\\s-])\\d{1,2}[\\)\\]]?\\s*(?:s(?:(?:ecs?)onds)?)[\\)\\]]?"
            file.parse_eml(filter(attachments)[]).attachments[].file_name regex_match "[\\x{1F300}-\\x{1F5FF}\\x{1F600}-\\x{1F64F}\\x{1F680}-\\x{1F6FF}\\x{1F700}-\\x{1F77F}\\x{1F780}-\\x{1F7FF}\\x{1F900}-\\x{1F9FF}\\x{2600}-\\x{26FF}\\x{2700}-\\x{27BF}\\x{2300}-\\x{23FF}]"
            file.parse_eml(filter(attachments)[]).attachments[].file_name regex_match "\\d{1,2}\\s*s(?:ec(?:ond)?s)?"
    any(attachments)
      and
        any(ml.logo_detect(file.html_screenshot(attachments)).brands)
          and
            ml.logo_detect(file.html_screenshot(attachments[])).brands[].confidence in ["high", "medium"]
            ml.logo_detect(file.html_screenshot(attachments[])).brands[].name eq "Microsoft"
        attachments.content_type in ["html", "text", "text/html"]
    any(attachments)
      and
        any(recipients.to)
          or
            strings.contains func_call "strings.contains(attachments[].file_name)"
            strings.contains func_call "strings.contains(file.parse_html(attachments[]).raw)"
        or
          attachments.content_type in ["html", "text", "text/html"]
          attachments.file_type in ["html", "svg", "unknown"]
    any([sender.display_name, subject.subject])
      and
        not
          [sender.display_name, subject.subject] regex_match "^(?:\\[[^\\]]*\\]\\s*)*\\[[^\\]]*[\\x{1F300}-\\x{1F5FF}\\x{1F600}-\\x{1F64F}\\x{1F680}-\\x{1F6FF}\\x{1F700}-\\x{1F77F}\\x{1F780}-\\x{1F7FF}\\x{1F900}-\\x{1F9FF}\\x{2600}-\\x{26FF}\\x{2700}-\\x{27BF}\\x{2300}-\\x{23FF}][^\\]]*\\]"
        [sender.display_name, subject.subject] regex_match "[\\x{1F300}-\\x{1F5FF}\\x{1F600}-\\x{1F64F}\\x{1F680}-\\x{1F6FF}\\x{1F700}-\\x{1F77F}\\x{1F780}-\\x{1F7FF}\\x{1F900}-\\x{1F9FF}\\x{2600}-\\x{26FF}\\x{2700}-\\x{27BF}\\x{2300}-\\x{23FF}]"
    any(attachments)
      and
        or
          attachments.content_type in ["html", "text", "text/html"]
          attachments.file_type eq "pdf"
          attachments.file_type in ["html", "svg", "unknown"]
        or
          attachments.file_name in [".htm", ".html"]
          attachments.file_name is_null
          attachments.file_name regex_match "(?:v[o0][il1]ce|aud[i1l][o0]|call|missed|caii|mail|message|recording|call|caii|transcr[il1]ption|v[nm]|audi[o0]|play|listen|unheard|msg)"
          attachments.file_name regex_match "0?[1-9]\\s*min(?:(?:ute)?s)?"
          attachments.file_name regex_match "0?[1-9]\\s*min(?:(?:ute)?s)?\\d{1,2}\\s*s(?:ec(?:ond)?s)?"
          attachments.file_name regex_match "[\\(\\[](?:\\d{1,2}[\\:\\s-])\\d{1,2}[\\)\\]]\\s"
          attachments.file_name regex_match "[\\(\\[]?(?:\\d{1,2}[\\:\\s-])\\d{1,2}[\\)\\]]?\\s*(?:s(?:(?:ecs?)onds)?)[\\)\\]]?"
          attachments.file_name regex_match "[\\x{1F300}-\\x{1F5FF}\\x{1F600}-\\x{1F64F}\\x{1F680}-\\x{1F6FF}\\x{1F700}-\\x{1F77F}\\x{1F780}-\\x{1F7FF}\\x{1F900}-\\x{1F9FF}\\x{2600}-\\x{26FF}\\x{2700}-\\x{27BF}\\x{2300}-\\x{23FF}]"
          attachments.file_name regex_match "\\d{1,2}\\s*s(?:ec(?:ond)?s)?"
    any(body.links)
      and
        not
          body.links.display_text contains "voice call center"
        body.links.display_text regex_match "(?:v[nm]|v[o0][il1]ce|audi[o0]|ca[li][li]|missed|preview)(\\s?|-)(mail|message|recording|call|caii)|transcription|open mp3|audi[o0] note|listen|playback|\\(?(?:\\*\\*\\*|[0-9]{3})?.(?:\\*\\*\\*|[0-9]{3})[^a-z]{0,2}(?:\\*{4}|\\d+\\*+)|play|voice note"
        body.links.display_text regex_match "[^a-z]*[A-Z][^a-z]*"
    any(body.links)
      and
        not
          body.links.display_text contains "voice call center"
        body.links.display_text regex_match "(v[nm]|v[o0][il1]ce|audi[o0]|call|missed|caii)(\\s?|-)(mail|message|recording|call|caii)|transcription|open mp3|audi[o0] note|listen|playback|\\(?(?:\\*\\*\\*|[0-9]{3})?.(?:\\*\\*\\*|[0-9]{3})[^a-z]{0,2}(?:\\*{4}|\\d+\\*+)|play|voice note"
        body.links.href_url.path eq "/ctt"
    any(body.links)
      and
        not
          body.links.href_url.path contains "unsubscribe"
        network.whois func_call "network.whois(body.links[].href_url.domain).days_old < 10"
    any(filter(attachments))
      and
        or
          file.parse_eml(filter(attachments)[]).attachments length_compare "0"
          filter(file.parse_eml(filter(attachments)[]).body.links, filter(attachments)[].href_url.domain.domain not in $org_domains and filter(attachments)[].href_url.domain.root_domain not in $org_domains) length_compare "0"
        file.parse_eml func_call "file.parse_eml(filter(attachments)[]).sender.email.email == sender.email.email"
        file.parse_eml func_call "file.parse_eml(filter(attachments)[]).subject.subject == subject.subject"
        length func_call "length(file.parse_eml(filter(attachments)[]).recipients.to) == length(recipients.to)"
         macro "all(recipients.to)"
    any(filter(...))
      any(ml.nlu_classifier(filter(...).scan.ocr.raw).intents)
        and
          ml.nlu_classifier(filter(...)[].scan.ocr.raw).intents[].confidence in ["high", "medium"]
          ml.nlu_classifier(filter(...)[].scan.ocr.raw).intents[].name eq "cred_theft"
    any([sender.display_name, subject.subject])
      or
        any(['January', 'February', 'March', 'April', 'June', 'July', 'August', 'September', 'October', 'November', 'December'])
          strings.icontains func_call "strings.icontains([sender.display_name, subject.subject][])"
        any(['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'])
          strings.icontains func_call "strings.icontains([sender.display_name, subject.subject][])"
        [sender.display_name, subject.subject] regex_match "(0[1-9]|1[0-2])/(0[1-9]|[12]\\d|3[01])/\\d{2}(\\d{2})?"
        [sender.display_name, subject.subject] regex_match "(0[1-9]|1[0-2]):([0-5]\\d):([0-5]\\d) ?([AaPp][Mm])"
        [sender.display_name, subject.subject] regex_match "(0[1-9]|1[0-2]):([0-5]\\d)\\s?([AaPp][Mm])"
        [sender.display_name, subject.subject] regex_match "(0[1-9]|[12]\\d|3[01])/(0[1-9]|1[0-2])/\\d{2}(\\d{2})?"
        [sender.display_name, subject.subject] regex_match "(January|February|March|April|May|June|July|August|September|October|November|December) (0[1-9]|[12]\\d|3[01]), \\d{2}(\\d{2})?"
        [sender.display_name, subject.subject] regex_match "([01]\\d|2[0-3]):([0-5]\\d)"
        [sender.display_name, subject.subject] regex_match "([01]\\d|2[0-3]):([0-5]\\d):([0-5]\\d)"
        [sender.display_name, subject.subject] regex_match "\\bmay\\b"
        [sender.display_name, subject.subject] regex_match "\\d{2}(\\d{2})?-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])"
    and
      any(body.links)
        any(recipients.to)
          strings.icontains func_call "strings.icontains(body.links[].href_url.url)"
      filter(recipients.to, .email.email != '' or .email.domain.valid) length_compare "0"
    any(filter(...))
      or
        any(['January', 'February', 'March', 'April', 'June', 'July', 'August', 'September', 'October', 'November', 'December'])
          strings.icontains func_call "strings.icontains(filter(...)[].scan.ocr.raw)"
        any(['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'])
          strings.icontains func_call "strings.icontains(filter(...)[].scan.ocr.raw)"
        filter(...).scan.ocr.raw regex_match "(0[1-9]|1[0-2])/(0[1-9]|[12]\\d|3[01])/\\d{2}(\\d{2})?"
        filter(...).scan.ocr.raw regex_match "(0[1-9]|1[0-2]):([0-5]\\d):([0-5]\\d) ?([AaPp][Mm])"
        filter(...).scan.ocr.raw regex_match "(0[1-9]|1[0-2]):([0-5]\\d)\\s?([AaPp][Mm])"
        filter(...).scan.ocr.raw regex_match "(0[1-9]|[12]\\d|3[01])/(0[1-9]|1[0-2])/\\d{2}(\\d{2})?"
        filter(...).scan.ocr.raw regex_match "(January|February|March|April|May|June|July|August|September|October|November|December) (0[1-9]|[12]\\d|3[01]), \\d{2}(\\d{2})?"
        filter(...).scan.ocr.raw regex_match "([01]\\d|2[0-3]):([0-5]\\d)"
        filter(...).scan.ocr.raw regex_match "([01]\\d|2[0-3]):([0-5]\\d):([0-5]\\d)"
        filter(...).scan.ocr.raw regex_match "\\bMay\\b"
        filter(...).scan.ocr.raw regex_match "\\d{2}(\\d{2})?-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])"
    any([sender.display_name, subject.subject, body.current_thread.text])
      or
        [sender.display_name, subject.subject, body.current_thread.text] regex_match "0?[1-9]\\s*min(?:(?:ute)?s)?\\b"
        [sender.display_name, subject.subject, body.current_thread.text] regex_match "0?[1-9]\\s*min(?:(?:ute)?s)?\\d{1,2}\\s*s(?:ec(?:ond)?s)?"
        [sender.display_name, subject.subject, body.current_thread.text] regex_match "[\\(\\[](?:\\d{1,2}[\\:\\s-])\\d{1,2}[\\)\\]]\\s"
        [sender.display_name, subject.subject, body.current_thread.text] regex_match "[\\(\\[]?(?:\\d{1,2}[\\:\\s-])\\d{1,2}[\\)\\]]?\\s*(?:s(?:(?:ecs?)onds)?)[\\)\\]]?"
        [sender.display_name, subject.subject, body.current_thread.text] regex_match "\\d{1,2}\\s*s(?:ec(?:ond)?s)?\\b"
    any(filter(...))
      or
        filter(...).scan.ocr.raw regex_match "0?[1-9]\\s*min(?:(?:ute)?s)?\\b"
        filter(...).scan.ocr.raw regex_match "0?[1-9]\\s*min(?:(?:ute)?s)?\\d{1,2}\\s*s(?:ec(?:ond)?s)?"
        filter(...).scan.ocr.raw regex_match "[\\(\\[](?:\\d{1,2}[\\:\\s-])\\d{1,2}[\\)\\]]\\s"
        filter(...).scan.ocr.raw regex_match "[\\(\\[]?(?:\\d{1,2}[\\:\\s-])\\d{1,2}[\\)\\]]?\\s*(?:s(?:(?:ecs?)onds)?)[\\)\\]]?"
        filter(...).scan.ocr.raw regex_match "\\d{1,2}\\s*s(?:ec(?:ond)?s)?\\b"
    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(recipients.to)
      or
        strings.icontains func_call "strings.icontains(sender.display_name)"
        strings.icontains func_call "strings.icontains(sender.email.local_part)"
        strings.icontains func_call "strings.icontains(subject.subject)"
    and
      body.current_thread.text length_compare "700"
      body.current_thread.text regex_match "Méssãge|Méssage|Recéived|Addréss"
    and
      filter(body.links, .display_text is not null and .display_url.url is null and .href_url.domain.valid) length_compare "0"
       macro "all(filter(body.links))"
    sender.display_name regex_match "(v[o0][il1]ce|audi[o0]|call|missed|caii)(\\s?|-)(mail|message|recording|call|caii)|(transcription|Caller.?ID)"
     macro "sender.email.domain.root_domain in free_email_providers"
  or
    and
      any(filter(...))
        or
          and
            not
              body.current_thread.text regex_match "(?:I(?:\\sjust)?|just) left you a (?:\\w+(\\s\\w+)?|[[:punct:]]+|\\s+){0,3}(?:voice(?:mail)?|audio)(?: message)?"
            not
              body.current_thread.text regex_match "you (?:have |received )my voice\\s?(?:mail|audio|message)"
            or
              filter(...).scan.ocr.raw regex_match "(?:you|we) (?:have |received )+(?:\\w+(\\s\\w+)?|[[:punct:]]+|\\s+){0,3}(?:\\b|\\s+)v[o0][il1]ce\\s?(?:ma[il1][li1]|aud[il1][o0]|message|notification)"
              filter(...).scan.ocr.raw regex_match "left you a (?:\\w+(\\s\\w+)?|[[:punct:]]+|\\s+){0,3}(?:v[o0][il1]ce(?:mail)?|audi[o0])(?: message)?"
          filter(...).scan.ocr.raw regex_match "(?:(?:new|this) |^)(?:v[o0][il1]ce(?:ma[il1][li1])?|aud[il1][o0]) (?:message|notification|record)"
          filter(...).scan.ocr.raw regex_match "Listen to V[o0][il1]ceMa[il1][li1]"
          filter(...).scan.ocr.raw regex_match "New V[o0][il1]cema[il1][li1] Received"
          filter(...).scan.ocr.raw regex_match "New m[il1]ssed ca[li1][li1] record"
          filter(...).scan.ocr.raw regex_match "New v[o0][il1]cema[il1][li1] from"
          filter(...).scan.ocr.raw regex_match "Your? have (?: an?)?incoming v[o0][il1]ceRec"
          filter(...).scan.ocr.raw regex_match "\\bv[o0][il1]cema[il1][li1] transcript\\b"
          filter(...).scan.ocr.raw regex_match "a (?:new )?pending message"
          filter(...).scan.ocr.raw regex_match "an? (?:new )?encrypted v[o0][il1]cemail"
          filter(...).scan.ocr.raw regex_match "sent (?:from|by) (?:your )?v[o0][il1]ce (?:ma[il1][li1] )?system"
          filter(...).scan.ocr.raw regex_match "v[o0][il1]ce note"
          filter(...).scan.ocr.raw regex_match "v[o0][il1]cema[il1][li1] (is )?attached"
          filter(...).scan.ocr.raw regex_match "you(?:\\'ve| have) a (?:new )?m[il1]ssed ca[li1][li1]"
      or
         macro "(length(filter(attachments, strings.starts_with(.content_type, 'audio') and not .file_type in ('wav', 'mp3'))) + length(filter(attachments, .file_type in $file_types_images and beta.parse_exif(.).image_height != 1))) == length(attachments)"
         macro "all(attachments)"
      attachments length_compare "0"
    any([subject.subject, sender.display_name])
      or
        [subject.subject, sender.display_name] regex_match "(?:open mp3|audi[o0] note|\\.wav|left a vm|[^\\s]+voip[^\\s]*|unanswered.*ca[li1][li1]|incoming.vm|left msg|wireless ca[li1][li1]er|VM Service|v[o0][il1]ce message|missed.ca[li1][li1](?:e[rd])?|\\bca[li1][li1].(?:support|service)(?: for| log)?|missed.{0,10} VM|new v[o0][il1]cemail from|new.v.m.from.\\+?\\d+|new v[o0][il1]cemail?(?:\\w+(\\s\\w+)?|[[:punct:]]+|\\s+){0,3}transcript(s|ion)?|message received|new (?:message|call|voicemail).{0,15}(?:info|notification|alert)|incoming transmission|voice note)"
        [subject.subject, sender.display_name] regex_match "(?:sent|new|incoming)[\\s\\-]+message.*(v[o0][il1]ce|<.*@.*>)"
        [subject.subject, sender.display_name] regex_match "(?:v[nm](\\b|[[:punct:]])?|\\bv[o0][il1]ce(?:mail|message)?|audi[o0]|incoming|missed(?:\\sa\\s)?|left( a)?|wireless)(?:\\w+(\\s\\w+)?|[[:punct:]]+|\\s+){0,3}(?:mail|message|msg|recording|received|notif|support|ca[li1][li1]\\d*\\b|ca[il1][il1](?:er)?|log|transcript(?:ion)?)\\b"
        [subject.subject, sender.display_name] regex_match "\\b1?\\(?(\\d{2}[\\*X]|\\d[\\*X]{2}|[\\*X]{2,3})\\)?[^a-z0-9]{0,2}(\\d{2,3}|\\d{2}[\\*X]|\\d[\\*X]{2})[^a-z0-9]{0,4}(\\d{4}|\\d{3}[\\*X]|\\d{2}[\\*X]{2}|\\d[\\*X]{3}|[\\*X]{3,4})\\b"
        [subject.subject, sender.display_name] regex_match "\\b1?\\(?(\\d{3}|\\d{2}[\\*X]|\\d[\\*X]{2})\\)?[^a-z0-9]{0,2}(\\d{2,3}|\\d{2}[\\*X]|\\d[\\*X]{2}|[\\*X]{2,3})[^a-z0-9]{0,4}(\\d{3}[\\*X]|\\d{2}[\\*X]{2}|\\d[\\*X]{3}|[\\*X]{3,4})[^0-9]"
        [subject.subject, sender.display_name] regex_match "\\d+\\s+new.*v[o0][il1]ce(?:mail|message|m[\\*]+)?"
        [subject.subject, sender.display_name] regex_match "^\\(\\d\\)\\s(?:\\w+(\\s\\w+)?|[[:punct:]]+|\\s+){0,3}(?:message|voip|v[o0][il1]ce|unread|call)"
        [subject.subject, sender.display_name] regex_match "ca[li1][li1](?:er)?(?:\\w+(\\s\\w+)?|[[:punct:]]+|\\s+){0,3}(?:playback|transcript)"
        [subject.subject, sender.display_name] regex_match "ca[li1][li1](?:er)?(?:\\w+(\\s\\w+)?|[[:punct:]]+|\\s+){0,3}(?:v[nm](\\b|[[:punct:]])?|\\bv[o0][il1]ce(?:mail|message)?|audi[o0]|missed(?:\\sa\\s)?|left( a)?)"
        [subject.subject, sender.display_name] regex_match "v[[:punct:]](?:mail|message|msg|recording|received|notif|support|ca[li1][li1]\\d*\\b|ca[il1][il1](?:er)?|log|transcript(?:ion)?\\b)"
        [subject.subject, sender.display_name] regex_match "v[o0][il1]ce[\\s\\-_]?m(?:ail|sg|essage)?[\\*X\\.\\-_]{2,}"
        [subject.subject, sender.display_name] regex_match "v[o0][il1]cem[\\*X\\.\\-_]{2,}"
    and
      not
        body.current_thread.text regex_match "(?:I(?:\\sjust)?|just(?: called you at (?:\\d+[[:punct:]])+) and)? left you a (?:\\w+(\\s\\w+)?|[[:punct:]]+|\\s+){0,3}(?:v[o0][il1]ce(?:mail)?|audio)(?: message)?"
      or
        body.current_thread.text regex_match "(?:you|we) (?:have |received )+(?:\\w+(\\s\\w+)?|[[:punct:]]+|\\s+){0,3}(?:\\b|\\s+)v[o0][il1]ce\\s?(?:ma[il1][li1]|aud[il1][o0]|message|notification)"
        body.current_thread.text regex_match "left you a (?:\\w+(\\s\\w+)?|[[:punct:]]+|\\s+){0,3}(?:v[o0][il1]ce(?:ma[il1][li1])?|aud[il1][o0])(?: message|notification)?"
      not
        body.current_thread.text regex_match "you (?:have |received )my voice\\s?(?:mail|audio|message)"
    body.html.raw contains "<!-- Voicemail phone logo"
    body.html.raw contains "<title>Voicemail Notification</title>"
    strings.replace_confusables(body.current_thread.text) regex_match "(?:(?:new|this) |^)(?:v[o0][il1]ce(?:ma[il1][li1])?|aud[il1][o0]) (?:message|notification|record)"
    strings.replace_confusables(body.current_thread.text) regex_match "Listen to V[o0][il1]ceMa[il1][li1]"
    strings.replace_confusables(body.current_thread.text) regex_match "New V[o0][il1]cema[il1][li1] Received"
    strings.replace_confusables(body.current_thread.text) regex_match "New m[il1]ssed ca[li1][li1] record"
    strings.replace_confusables(body.current_thread.text) regex_match "New v[o0][il1]cema[il1][li1] from"
    strings.replace_confusables(body.current_thread.text) regex_match "Your? have (?: an?)?incoming v[o0][il1]ceRec"
    strings.replace_confusables(body.current_thread.text) regex_match "\\bv[o0][il1]cema[il1][li1] transcript\\b"
    strings.replace_confusables(body.current_thread.text) regex_match "a (?:new )?pending message"
    strings.replace_confusables(body.current_thread.text) regex_match "an? (?:new )?encrypted v[o0][il1]cemail"
    strings.replace_confusables(body.current_thread.text) regex_match "sent (?:from|by) (?:your )?v[o0][il1]ce (?:ma[il1][li1] )?system"
    strings.replace_confusables(body.current_thread.text) regex_match "v[o0][il1]ce note"
    strings.replace_confusables(body.current_thread.text) regex_match "v[o0][il1]cema[il1][li1] (is )?attached"
    strings.replace_confusables(body.current_thread.text) regex_match "you(?:\\'ve| have) a (?:new )?m[il1]ssed ca[li1][li1]"
  not
    and
      any(headers.hops)
        and
          headers.hops.index eq "0"
          headers.hops.received.server.raw contains "pphosted.com"
      any(attachments)
        attachments.content_type eq "message/rfc822"
      headers.message_id ends_with "pphosted.com>"
      sender.display_name eq "Mail Delivery Subsystem"
  not
    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 in ["B2B Cold Outreach", "Events and Webinars", "Newsletters and Digests"]
      not
        body.current_thread.text contains "this voicemail was shared by"
  not
    any(attachments)
      and
        attachments.content_type starts_with "audio"
        attachments.file_type in ["mp3", "wav"]
  not
    and
      any(body.links)
        body.links.href_url.domain.root_domain eq "checkpointcloudsec.com"
      any(headers.domains)
        headers.domains.root_domain eq "checkpointcloudsec.com"
      attachments length_compare "1"
      headers.message_id starts_with "<encrypted"
  or
    and
      not
        coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       macro "sender.email.domain.domain in org_domains"
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
      not
        sender.email.email eq "noreply-application-integration@google.com"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
    and
      not
        profile.by_sender_email func_call "profile.by_sender_email().any_messages_benign"
      profile.by_sender_email func_call "profile.by_sender_email().any_messages_malicious_or_spam"
    and
      not
        profile.by_sender_email func_call "profile.by_sender_email().solicited"
      not
         macro "sender.email.domain.root_domain in org_domains"
      profile.by_sender_email func_call "profile.by_sender_email().prevalence not in (common)"
    sender.email.email is_null
    sender.email.email regex_match ""
     macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
  not
    any(attachments)
      any(file.parse_eml(attachments).attachments)
        file.parse_eml(attachments).attachments.content_type eq "message/delivery-status"
  not
    and
      or
        headers.in_reply_to is_not_null
        headers.references length_compare "0"
      or
        subject.subject starts_with "Automatic reply:"
        subject.subject starts_with "RE:"
  not
    any(attachments)
      attachments.content_type in ["message/delivery-status", "text/calendar"]
  or
    and
      distinct(attachments, .md5) length_compare "0"
      distinct(attachments, .md5) length_compare "3"
    and
      filter(body.links, .href_url.scheme != 'mailto') length_compare "0"
      filter(body.links, .href_url.scheme != 'mailto') length_compare "25"
  not
    and
      sender.email.domain.root_domain in ["airtel.com", "grasshopper.com", "justcall.io", "magicjack.com", "magicjackforbusiness.com", "ooma.com", "ringcentral.biz", "t-mobile.com", "ui.com", "unitelvoice.com", "verizonwireless.com", "voipinterface.net"]
      sender.email.domain.valid eq "true"
  distinct(attachments, .md5) length_compare "0"
  distinct(attachments, .md5) length_compare "8"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.hopsarray_any(no value, null check)excludes:headers.hops
attachmentsarray_any(no value, null check)excludes:attachments
headers.message_idends_withpphosted.com>excludes:headers.message_id field:"headers.message_id" value:"pphosted.com>"
sender.display_nameeqMail Delivery Subsystemexcludes:sender.display_name field:"sender.display_name" value:"Mail Delivery Subsystem"
ml.nlu_classifier(body.current_thread.text).topicsarray_any(no value, null check)excludes:ml.nlu_classifier(body.current_thread.text).topics
body.current_thread.textcontainsthis voicemail was shared byexcludes:body.current_thread.text field:"body.current_thread.text" value:"this voicemail was shared by"
body.linksarray_any(no value, null check)excludes:body.links
headers.domainsarray_any(no value, null check)excludes:headers.domains
attachmentslength_compare1excludes:attachments field:"attachments" value:"1"
headers.message_idstarts_with<encryptedexcludes:headers.message_id field:"headers.message_id" value:"<encrypted"
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.subjectstarts_withAutomatic reply:excludes:subject.subject field:"subject.subject" value:"Automatic reply:"
subject.subjectstarts_withRE:excludes:subject.subject field:"subject.subject" value:"RE:"
sender.email.domain.root_domaininairtel.com, grasshopper.com, justcall.io, magicjack.com, magicjackforbusiness.com, ooma.com, ringcentral.biz, t-mobile.com, ui.com, unitelvoice.com, verizonwireless.com, voipinterface.netexcludes:sender.email.domain.root_domain
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.textcontains
  • this voicemail was shared by
field:"body.current_thread.text" kind:contains value:"this voicemail was shared by"
body.current_thread.textregex_match
  • (?:you|we) (?:have |received )+(?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:\b|\s+)v[o0][il1]ce\s?(?:ma[il1][li1]|aud[il1][o0]|message|notification)
    • Méssãge
    • Méssage
    • Recéived
    • Addréss
  • left you a (?:\w+(\s\w+)?|[[:punct:]]+|\s+){0,3}(?:v[o0][il1]ce(?:ma[il1][li1])?|aud[il1][o0])(?: message|notification)?
field:"body.current_thread.text" kind:regex_match
body.html.rawcontains
  • <!-- Voicemail phone logo
  • <title>Voicemail Notification</title>
field:"body.html.raw" kind:contains
sender.display_nameregex_match
    • (v[o0][il1]ce|audi[o0]|call|missed|caii)(\s?|-)(mail|message|recording|call|caii)
    • (transcription|Caller.?ID)
field:"sender.display_name" kind:regex_match
sender.email.emailis_null
  • (no value, null check)
field:"sender.email.email" kind:is_null
strings.replace_confusables(body.current_thread.text)regex_match
  • (?:(?:new|this) |^)(?:v[o0][il1]ce(?:ma[il1][li1])?|aud[il1][o0]) (?:message|notification|record)
  • Listen to V[o0][il1]ceMa[il1][li1]
  • New V[o0][il1]cema[il1][li1] Received
  • New m[il1]ssed ca[li1][li1] record
  • New v[o0][il1]cema[il1][li1] from
  • Your? have (?: an?)?incoming v[o0][il1]ceRec
  • \bv[o0][il1]cema[il1][li1] transcript\b
  • a (?:new )?pending message
  • an? (?:new )?encrypted v[o0][il1]cemail
  • sent (?:from|by) (?:your )?v[o0][il1]ce (?:ma[il1][li1] )?system
  • v[o0][il1]ce note
  • v[o0][il1]cema[il1][li1] (is )?attached
  • you(?:\'ve| have) a (?:new )?m[il1]ssed ca[li1][li1]
field:"strings.replace_confusables(body.current_thread.text)" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Fake Zoom meeting invite with suspicious link

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

Detects messages impersonating Zoom meetings that contain suspicious links not hosted on legitimate Zoom domains, with recipients hidden as 'Undisclosed recipients' or missing entirely. The rule identifies Zoom-related language while excluding legitimate Zoom communications and meeting summaries.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Evasion, 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
  • subject
  • type

Rule body

type.inbound
and length(body.previous_threads) == 0
and length(ml.nlu_classifier(body.current_thread.text).topics) == 1
and all(ml.nlu_classifier(body.current_thread.text).topics,
        .name in ("Events and Webinars", "Software and App Updates")
        and .confidence != "low"
)

// Zoom meeting language
and strings.ilike(body.current_thread.text,
                  "*zoom meeting*",
                  "*meeting ID*",
                  "*participants*"
)

// suspicious recipients pattern
and (
  any(recipients.to, strings.ilike(.display_name, "undisclosed?recipients"))
  or length(recipients.to) == 0
)

// suspicious link
and not any(body.links,
            .href_url.domain.root_domain in (
              "zoom.us",
              "zoom.com",
              "emailprotection.link"
            )
            and any(.href_url.query_params_decoded['pwd'], . is not null)
)
and (
  any(body.links,
      .href_url.domain.tld in $suspicious_tlds
      // country code second-level domain
      or strings.istarts_with(.href_url.domain.tld, "com.")
      or (
        (
          length(ml.link_analysis(.).files_downloaded) > 0
          // Zoom logo on page
          or ml.link_analysis(.).credphish.brand.name == "Zoom"
          // blocked by a Cloudflare CAPTCHA
          or strings.icontains(ml.link_analysis(.).final_dom.raw,
                               'https://challenges.cloudflare.com/turnstile/',
          )
        )
        and ml.link_analysis(.).effective_url.domain.root_domain not in (
          "zoom.us",
          "zoom.com"
        )
      )
  )
)

// negate auto-generated meeting summaries
and not (
  strings.icontains(body.current_thread.text, "meeting summary")
  and strings.icontains(body.current_thread.text,
                        "AI-generated content may be inaccurate or misleading."
  )
)
and not (
  (subject.is_reply or subject.is_forward)
  and (length(headers.references) > 0 or headers.in_reply_to is not null)
)
// Not from a legitimate Zoom domain
and not (
  sender.email.domain.root_domain in (
    "zoom.us",
    "zuora.com",
    "zoomgov.com",
    "zoom.com",
    "zoom-x.de"
  )
  and headers.auth_summary.dmarc.pass
)

Detection logic

Scope: inbound message.

Detects messages impersonating Zoom meetings that contain suspicious links not hosted on legitimate Zoom domains, with recipients hidden as 'Undisclosed recipients' or missing entirely. The rule identifies Zoom-related language while excluding legitimate Zoom communications and meeting summaries.

  1. inbound message
  2. length(body.previous_threads) is 0
  3. length(ml.nlu_classifier(body.current_thread.text).topics) is 1
  4. all of ml.nlu_classifier(body.current_thread.text).topics where all hold:
    • .name in ('Events and Webinars', 'Software and App Updates')
    • .confidence is not 'low'
  5. body.current_thread.text matches any of 3 patterns
    • *zoom meeting*
    • *meeting ID*
    • *participants*
  6. any of:
    • any of recipients.to where:
      • .display_name matches 'undisclosed?recipients'
    • length(recipients.to) is 0
  7. not:
    • any of body.links where all hold:
      • .href_url.domain.root_domain in ('zoom.us', 'zoom.com', 'emailprotection.link')
      • any of .href_url.query_params_decoded['pwd'] where:
        • . is set
  8. any of body.links where any holds:
    • .href_url.domain.tld in $suspicious_tlds
    • .href_url.domain.tld starts with 'com.'
    • all of:
      • any of:
        • length(ml.link_analysis(.).files_downloaded) > 0
        • ml.link_analysis(.).credphish.brand.name is 'Zoom'
        • ml.link_analysis(.).final_dom.raw contains 'https://challenges.cloudflare.com/turnstile/'
      • ml.link_analysis(.).effective_url.domain.root_domain not in ('zoom.us', 'zoom.com')
  9. not:
    • all of:
      • body.current_thread.text contains 'meeting summary'
      • body.current_thread.text contains 'AI-generated content may be inaccurate or misleading.'
  10. not:
    • all of:
      • any of:
        • subject.is_reply
        • subject.is_forward
      • any of:
        • length(headers.references) > 0
        • headers.in_reply_to is set
  11. not:
    • all of:
      • sender.email.domain.root_domain in ('zoom.us', 'zuora.com', 'zoomgov.com', 'zoom.com', 'zoom-x.de')
      • headers.auth_summary.dmarc.pass

Inspects: body.current_thread.text, body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.tld, body.links[].href_url.query_params_decoded['pwd'], body.previous_threads, headers.auth_summary.dmarc.pass, headers.in_reply_to, headers.references, recipients.to, recipients.to[].display_name, sender.email.domain.root_domain, subject.is_forward, subject.is_reply, type.inbound. Sensors: ml.link_analysis, ml.nlu_classifier, strings.icontains, strings.ilike, strings.istarts_with. Reference lists: $suspicious_tlds.

Indicators matched (8)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).topics[].namememberEvents and Webinars
ml.nlu_classifier(body.current_thread.text).topics[].namememberSoftware and App Updates
strings.ilikesubstring*zoom meeting*
strings.ilikesubstring*meeting ID*
strings.ilikesubstring*participants*
strings.ilikesubstringundisclosed?recipients
strings.istarts_withprefixcom.
strings.icontainssubstringhttps://challenges.cloudflare.com/turnstile/

Stages and Predicates

Stage 1: mql_rule

and
  not
    any(body.links)
      and
        any(body.links.href_url.query_params_decoded['pwd'])
          body.links.href_url.query_params_decoded['pwd'] is_not_null
        body.links.href_url.domain.root_domain in ["emailprotection.link", "zoom.com", "zoom.us"]
  any(body.links)
    or
      and
        or
          ml.link_analysis func_call "ml.link_analysis(body.links[]).credphish.brand.name == Zoom"
          ml.link_analysis(body.links[]).files_downloaded length_compare "0"
          ml.link_analysis(body.links[]).final_dom.raw contains "https://challenges.cloudflare.com/turnstile/"
        ml.link_analysis func_call "ml.link_analysis(body.links[]).effective_url.domain.root_domain not in (zoom.us, zoom.com)"
      body.links.href_url.domain.tld starts_with "com."
       macro "body.links[].href_url.domain.tld in suspicious_tlds"
  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"
  not
    and
      body.current_thread.text contains "AI-generated content may be inaccurate or misleading."
      body.current_thread.text contains "meeting summary"
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.root_domain in ["zoom-x.de", "zoom.com", "zoom.us", "zoomgov.com", "zuora.com"]
  or
    any(recipients.to)
      recipients.to.display_name eq "undisclosed?recipients"
    recipients.to length_compare "0"
  or
    body.current_thread.text match "meeting ID"
    body.current_thread.text match "participants"
    body.current_thread.text match "zoom meeting"
  body.previous_threads length_compare "0"
  ml.nlu_classifier(body.current_thread.text).topics length_compare "1"
  type.inbound eq "true"
   macro "all(ml.nlu_classifier(body.current_thread.text).topics)"

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.current_thread.textcontainsAI-generated content may be inaccurate or misleading.excludes:body.current_thread.text field:"body.current_thread.text" value:"AI-generated content may be inaccurate or misleading."
body.current_thread.textcontainsmeeting summaryexcludes:body.current_thread.text field:"body.current_thread.text" value:"meeting summary"
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
sender.email.domain.root_domaininzoom-x.de, zoom.com, zoom.us, zoomgov.com, zuora.comexcludes:sender.email.domain.root_domain

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textwildcard
  • *meeting ID*
  • *participants*
  • *zoom meeting*
field:"body.current_thread.text" kind:wildcard
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Free subdomain link with login or captcha (untrusted sender)

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

Message contains a link that uses a free subdomain provider, and has a login or captcha on the page.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesFree subdomain host, 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 0 < length(body.links) < 10
and any(body.links,

        // contains login or captcha
        (
          ml.link_analysis(.).credphish.contains_login
          or ml.link_analysis(.).credphish.contains_captcha
        )

        // either the original or the redirect is a free subdomain
        and (
          ml.link_analysis(.).effective_url.domain.root_domain in $free_subdomain_hosts
          or .href_url.domain.root_domain in $free_subdomain_hosts
        )

        // exclude FP prone free subdomain hosts
        // if it's a known brand impersonation, we'll detect it in other rules
        and .href_url.domain.root_domain not in ("zendesk.com")
        and ml.link_analysis(.).effective_url.domain.root_domain not in (
          "zendesk.com"
        )
        and ml.link_analysis(.).effective_url.domain.domain not in (
          "login.squarespace.com"
        )
)

// exclude all freesubdomain links are images
and length(filter(body.links,
                  .href_url.domain.root_domain in $free_subdomain_hosts
                  and .href_url.domain.subdomain is not null
                  and .href_url.domain.subdomain != "www"
           )
) > 0
and not all(filter(body.links,
                   .href_url.domain.root_domain in $free_subdomain_hosts
                   and .href_url.domain.subdomain is not null
                   and .href_url.domain.subdomain != "www"
            ),
            (
              strings.ends_with(.href_url.url, "jpeg")
              or strings.ends_with(.href_url.url, "png")
            )
)

// exclude FP prone senders
and sender.email.domain.root_domain not in ("sharepointonline.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().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
  )
)
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

Message contains a link that uses a free subdomain provider, and has a login or captcha on the page.

  1. inbound message
  2. all of:
    • length(body.links) > 0
    • length(body.links) < 10
  3. any of body.links where all hold:
    • any of:
      • ml.link_analysis(.).credphish.contains_login
      • ml.link_analysis(.).credphish.contains_captcha
    • any of:
      • ml.link_analysis(.).effective_url.domain.root_domain in $free_subdomain_hosts
      • .href_url.domain.root_domain in $free_subdomain_hosts
    • .href_url.domain.root_domain not in ('zendesk.com')
    • ml.link_analysis(.).effective_url.domain.root_domain not in ('zendesk.com')
    • ml.link_analysis(.).effective_url.domain.domain not in ('login.squarespace.com')
  4. length(filter(body.links, .href_url.domain.root_domain in $free_subdomain_hosts and .href_url.domain.subdomain is not null and .href_url.domain.subdomain != 'www')) > 0
  5. not:
    • all of filter(body.links) where any holds:
      • .href_url.url ends with 'jpeg'
      • .href_url.url ends with 'png'
  6. sender.email.domain.root_domain not in ('sharepointonline.com')
  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:
    • 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
  9. not:
    • profile.by_sender().any_messages_benign

Inspects: body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.subdomain, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: ml.link_analysis, profile.by_sender, strings.ends_with. Reference lists: $free_subdomain_hosts, $high_trust_sender_root_domains.

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      not
        body.links.href_url.domain.root_domain eq "zendesk.com"
      or
        ml.link_analysis func_call "ml.link_analysis(body.links[]).credphish.contains_captcha"
        ml.link_analysis func_call "ml.link_analysis(body.links[]).credphish.contains_login"
      or
        ml.link_analysis func_call "ml.link_analysis(body.links[]).effective_url.domain.root_domain in free_subdomain_hosts"
         macro "body.links[].href_url.domain.root_domain in free_subdomain_hosts"
      ml.link_analysis func_call "ml.link_analysis(body.links[]).effective_url.domain.domain not in (login.squarespace.com)"
      ml.link_analysis func_call "ml.link_analysis(body.links[]).effective_url.domain.root_domain not in (zendesk.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
    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)"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  not
    sender.email.domain.root_domain eq "sharepointonline.com"
  not
     macro "all(filter(body.links))"
  body.links length_compare "0"
  body.links length_compare "10"
  filter(body.links, .href_url.domain.root_domain in $free_subdomain_hosts and .href_url.domain.subdomain is not null and .href_url.domain.subdomain != 'www') length_compare "0"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaineqsharepointonline.comexcludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"sharepointonline.com"

Indicators

These rows show field, operator, and value matches.

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

Google Accelerated Mobile Pages (AMP) abuse

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

This rule is designed to identify phishing attempts abusing Google AMP's URL structure for malicious activities. The rule aims to detect specific URL patterns, further analyzing both message content, as well as the destination of the link to distinguish between legitimate Google AMP pages and potential malicious usage.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesImpersonation: Brand, Open redirect

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • recipients
  • recipients.to
  • type

Rule body

type.inbound

// Any body links with a domain SLD of 'google' and a path starting with /amp
and any(body.links,
        .href_url.domain.sld == "google"
        and strings.starts_with(.href_url.path, "/amp/")

        // Brand Logo detected that is not google
        and (
          any(ml.logo_detect(file.message_screenshot()).brands,
              .name is not null and .name != "Google"
          )

          // or the page has a login or captcha
          or (
            ml.link_analysis(.).credphish.contains_login
            or ml.link_analysis(.).credphish.contains_captcha
          )

          // or linkanalysis concludes phishing of medium to high confidence
          or any([ml.link_analysis(.)],
                 .credphish.disposition == "phishing"
                 and .credphish.brand.confidence in ("medium", "high")
          )

          // or NLU detected cred theft on the landing page
          or any(file.explode(ml.link_analysis(.).screenshot),
                 any(ml.nlu_classifier(.scan.ocr.raw).intents,
                     .name == "cred_theft" and .confidence in ("medium", "high")
                 )

                 // captcha partially loaded
                 or strings.icontains(.scan.ocr.raw,
                                      "Checking if the site connection is secure"
                 )
          )

          // or the link display text contains "password"
          or strings.icontains(.display_text, "password")

          // or the link contains the recipients email in the url path
          or any(recipients.to,
                 strings.icontains(..href_url.path, .email.email)
                 and (
                   .email.domain.valid
                   or strings.icontains(.display_name, "undisclosed")
                 )
          )
        )
)

Detection logic

Scope: inbound message.

This rule is designed to identify phishing attempts abusing Google AMP's URL structure for malicious activities. The rule aims to detect specific URL patterns, further analyzing both message content, as well as the destination of the link to distinguish between legitimate Google AMP pages and potential malicious usage.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.domain.sld is 'google'
    • .href_url.path starts with '/amp/'
    • any of:
      • any of ml.logo_detect(file.message_screenshot()).brands where all hold:
        • .name is set
        • .name is not 'Google'
      • any of:
        • ml.link_analysis(.).credphish.contains_login
        • ml.link_analysis(.).credphish.contains_captcha
      • any of [ml.link_analysis(.)] where all hold:
        • .credphish.disposition is 'phishing'
        • .credphish.brand.confidence in ('medium', 'high')
      • any of file.explode(...) where any holds:
        • any of ml.nlu_classifier(.scan.ocr.raw).intents where all hold:
          • .name is 'cred_theft'
          • .confidence in ('medium', 'high')
        • .scan.ocr.raw contains 'Checking if the site connection is secure'
      • .display_text contains 'password'
      • any of recipients.to where all hold:
        • strings.icontains(.href_url.path)
        • any of:
          • .email.domain.valid
          • .display_name contains 'undisclosed'

Inspects: body.links, body.links[].display_text, body.links[].href_url.domain.sld, body.links[].href_url.path, recipients.to, recipients.to[].display_name, recipients.to[].email.domain.valid, recipients.to[].email.email, type.inbound. Sensors: file.explode, file.message_screenshot, ml.link_analysis, ml.logo_detect, ml.nlu_classifier, strings.icontains, strings.starts_with.

Indicators matched (11)

FieldMatchValue
body.links[].href_url.domain.sldequalsgoogle
strings.starts_withprefix/amp/
[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(file.explode(...)[].scan.ocr.raw).intents[].nameequalscred_theft
ml.nlu_classifier(file.explode(...)[].scan.ocr.raw).intents[].confidencemembermedium
ml.nlu_classifier(file.explode(...)[].scan.ocr.raw).intents[].confidencememberhigh
strings.icontainssubstringChecking if the site connection is secure
strings.icontainssubstringpassword
strings.icontainssubstringundisclosed

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        any(file.explode(...))
          or
            any(ml.nlu_classifier(file.explode(...).scan.ocr.raw).intents)
              and
                ml.nlu_classifier(file.explode(...)[].scan.ocr.raw).intents[].confidence in ["high", "medium"]
                ml.nlu_classifier(file.explode(...)[].scan.ocr.raw).intents[].name eq "cred_theft"
            file.explode(...).scan.ocr.raw contains "Checking if the site connection is secure"
        any(recipients.to)
          and
            or
              recipients.to.display_name contains "undisclosed"
              recipients.to.email.domain.valid eq "true"
            strings.icontains func_call "strings.icontains(body.links[].href_url.path)"
        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.logo_detect(file.message_screenshot()).brands)
          and
            ml.logo_detect(file.message_screenshot()).brands.name is_not_null
            ml.logo_detect(file.message_screenshot()).brands.name ne "Google"
        body.links.display_text contains "password"
        ml.link_analysis func_call "ml.link_analysis(body.links[]).credphish.contains_captcha"
        ml.link_analysis func_call "ml.link_analysis(body.links[]).credphish.contains_login"
      body.links.href_url.domain.sld eq "google"
      body.links.href_url.path starts_with "/amp/"
  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"

Google Drive direct download link from unsolicited sender

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

This rule detects Google Drive links that use the direct download URL pattern which automatically downloads files when clicked. This pattern is frequently used by threat actors to distribute malware. The links are formatted like: drive.google.com/uc?id=FILE_ID&export=download These links skip the preview page and immediately download the file to the user's device, which can be dangerous for recipients. Threat actors exploit this pattern to directly distribute malware while appearing to share legitimate content from a trusted service.

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware, Credential Phishing
Tactics and techniquesEvasion, Social engineering, Free file host

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 0 < length(body.links) < 10
and any(body.links,
        (
          // Match Google Drive direct download links
          strings.icontains(.href_url.url, "drive.google.com/uc") 
          and (
            strings.icontains(.href_url.url, "export=download")
            or strings.icontains(.href_url.query_params, "export=download")
          )
        )
)
// 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 (
  // Only trigger on unsolicited senders
  not profile.by_sender().solicited
  or (
    // Or senders with suspicious history
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)

Detection logic

Scope: inbound message.

This rule detects Google Drive links that use the direct download URL pattern which automatically downloads files when clicked. This pattern is frequently used by threat actors to distribute malware. The links are formatted like: drive.google.com/uc?id=FILE_ID&export=download These links skip the preview page and immediately download the file to the user's device, which can be dangerous for recipients. Threat actors exploit this pattern to directly distribute malware while appearing to share legitimate content from a trusted service.

  1. inbound message
  2. all of:
    • length(body.links) > 0
    • length(body.links) < 10
  3. any of body.links where all hold:
    • .href_url.url contains 'drive.google.com/uc'
    • any of:
      • .href_url.url contains 'export=download'
      • .href_url.query_params contains 'export=download'
  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. 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.links, body.links[].href_url.query_params, body.links[].href_url.url, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender, strings.icontains. Reference lists: $high_trust_sender_root_domains.

Indicators matched (2)

FieldMatchValue
strings.icontainssubstringdrive.google.com/uc
strings.icontainssubstringexport=download

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        body.links.href_url.query_params contains "export=download"
        body.links.href_url.url contains "export=download"
      body.links.href_url.url contains "drive.google.com/uc"
  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"
  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"

Google Notification alert link from non-Google sender

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

This rule detects messages that leverage a link to notifications.google.com not from google and from an untrusted sender. Commonly abused in salesforce phishing campaigns.

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

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

Rule body

type.inbound
// ignore messages from google[.]com unlesss they fail DMARC authentication
and (
  (
    sender.email.domain.root_domain in ("google.com", "youtube.com", "nest.com")
    and not headers.auth_summary.dmarc.pass
  )
  or sender.email.domain.root_domain not in (
    "google.com",
    "youtube.com",
    "nest.com"
  )
)
and any(body.links,
        .href_url.domain.domain == "notifications.google.com"
        and strings.starts_with(.href_url.path, "/g/p/")
)
and (
  any($suspicious_subjects, strings.icontains(subject.subject, .))
  or strings.ilike(subject.subject, '*verification*')
)
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
  )
  // we've observed salesforce abuse
  or sender.email.domain.root_domain == "salesforce.com"
  or headers.return_path.domain.root_domain == "salesforce.com"
)
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

This rule detects messages that leverage a link to notifications.google.com not from google and from an untrusted sender. Commonly abused in salesforce phishing campaigns.

  1. inbound message
  2. any of:
    • all of:
      • sender.email.domain.root_domain in ('google.com', 'youtube.com', 'nest.com')
      • not:
        • headers.auth_summary.dmarc.pass
    • sender.email.domain.root_domain not in ('google.com', 'youtube.com', 'nest.com')
  3. any of body.links where all hold:
    • .href_url.domain.domain is 'notifications.google.com'
    • .href_url.path starts with '/g/p/'
  4. any of:
    • any of $suspicious_subjects where:
      • strings.icontains(subject.subject)
    • subject.subject matches '*verification*'
  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_messages_benign
    • sender.email.domain.root_domain is 'salesforce.com'
    • headers.return_path.domain.root_domain is 'salesforce.com'
  6. not:
    • profile.by_sender().any_messages_benign

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.path, headers.auth_summary.dmarc.pass, headers.return_path.domain.root_domain, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: profile.by_sender, strings.icontains, strings.ilike, strings.starts_with. Reference lists: $suspicious_subjects.

Indicators matched (8)

FieldMatchValue
sender.email.domain.root_domainmembergoogle.com
sender.email.domain.root_domainmemberyoutube.com
sender.email.domain.root_domainmembernest.com
body.links[].href_url.domain.domainequalsnotifications.google.com
strings.starts_withprefix/g/p/
strings.ilikesubstring*verification*
sender.email.domain.root_domainequalssalesforce.com
headers.return_path.domain.root_domainequalssalesforce.com

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.root_domain in ["google.com", "nest.com", "youtube.com"]
    not
      sender.email.domain.root_domain in ["google.com", "nest.com", "youtube.com"]
  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)"
    headers.return_path.domain.root_domain eq "salesforce.com"
    sender.email.domain.root_domain eq "salesforce.com"
  any(body.links)
    and
      body.links.href_url.domain.domain eq "notifications.google.com"
      body.links.href_url.path starts_with "/g/p/"
  or
    any($suspicious_subjects)
      strings.icontains func_call "strings.icontains(subject.subject)"
    subject.subject match "verification"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Google presentation open redirect phishing

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

Detects emails containing links to Google Document Presentations that either have a single page with a single external link, have been removed for Terms of Service violations, or have been deleted.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Open redirect, 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 not strings.icontains(body.current_thread.text, 'invited you to edit')
and any(body.links,
        // body link is to a google doc presentation
        .href_url.domain.domain == "docs.google.com"
        and strings.istarts_with(.href_url.path, '/presentation/')

        // prefilter some to avoid clicking on _every_ google presentation link
        and ( 
          ( 
            // make sure the display text is in the current thread and not a previous one.
            strings.icontains(body.current_thread.text, .display_text)
            // the display_text ends with a word that is 4-10 long
            and regex.icontains(.display_text, '[[:punct:]\s][a-z0-9]{5,9}$')
            // that word has to include a letter AND a number
            and regex.icontains(.display_text,
                                '[[:punct:]\s](?:[a-z0-9]*[a-z][0-9][a-z0-9]*|[a-z0-9]*[0-9][a-z][a-z0-9]*)$'
            )
            and strings.iends_with(.href_url.path, '/pub')
          )
          or 
          // finally send the link to link analysis that presentation...
          (
            // contains a single link
            length(ml.link_analysis(., mode="aggressive").final_dom.links) == 1

            // cannot be edited via link provided
            and strings.contains(ml.link_analysis(., mode="aggressive").final_dom.raw,
                                 'canEdit:  false'
            )

            // and a single page
            and strings.contains(ml.link_analysis(., mode="aggressive").final_dom.raw,
                                 'slidePageCount:  1.0'
            )

            // where we have links which have been written via a google open redirect
            and any(ml.link_analysis(., mode="aggressive").final_dom.links,
                    // links are not in thhe org_domains
                    .href_url.domain.domain not in $org_domains
                    and (
                      (
                        // don't include high rep domains
                        .href_url.domain.domain not in $tranco_1m
                        and .href_url.domain.domain not in $umbrella_1m
                      )
                      // if it's in Tranco or Umbrella, still include it if it's one of these
                      or .href_url.domain.domain in $free_file_hosts
                      or .href_url.domain.root_domain in $free_file_hosts
                      or .href_url.domain.root_domain in $free_subdomain_hosts
                      // or it's a url shortner
                      or .href_url.domain.root_domain in $url_shorteners
                      or .href_url.domain.root_domain in $social_landing_hosts
                    )
                    // which have been "unrolled" by the google_open_redirect rule
                    and any(.href_url.rewrite.encoders,
                            . == "google_open_redirect"
                    )
            )
          )
          // or the presentation has been removed for violation of terms of service
          or strings.icontains(ml.link_analysis(., mode="aggressive").final_dom.display_text,
                               "We're sorry. You can't access this item because it is in violation of our Terms of Service."
          )
        )
)
// when the sender is not google, the sender should not be a common prevalence
and (
  ( // the message is not from google actual
    sender.email.email not in (
      'comments-noreply@docs.google.com',
      'drive-shares-dm-noreply@google.com',
      'drive-shares-noreply@google.com',
      'calendar-notification@google.com'
    )
    // ensure the sender prevalence is not common
    and profile.by_sender().prevalence != "common"
  )
  // or the message is from google actual
  or (
    sender.email.email in (
      'comments-noreply@docs.google.com',
      'drive-shares-dm-noreply@google.com',
      'drive-shares-noreply@google.com',
      'calendar-notification@google.com'
    )
  )
)

// not where the sender display name of the message is within org_display_names
and not (
  // the message is from google actual
  sender.email.email in (
    'comments-noreply@docs.google.com',
    'drive-shares-dm-noreply@google.com',
    'drive-shares-noreply@google.com',
    'calendar-notification@google.com'
  )
  and headers.auth_summary.dmarc.pass

  // but the sender display name is within org_display_names
  and any($org_display_names,
          strings.istarts_with(sender.display_name,
                               strings.concat(., " (via Google ")
          )
          or strings.istarts_with(sender.display_name,
                                  strings.concat(., " (Google ")
          )
  )
)
// negate highly trusted sender domains unless they fail DMARC authentication
// but ignore high_trust if the sender is one of the google actual senders
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 in $high_trust_sender_root_domains
      and sender.email.email in (
        'comments-noreply@docs.google.com',
        'drive-shares-dm-noreply@google.com',
        'drive-shares-noreply@google.com',
        'calendar-notification@google.com'
      )
    )
    or sender.email.domain.root_domain not in $high_trust_sender_root_domains
  )
)

Detection logic

Scope: inbound message.

Detects emails containing links to Google Document Presentations that either have a single page with a single external link, have been removed for Terms of Service violations, or have been deleted.

  1. inbound message
  2. not:
    • body.current_thread.text contains 'invited you to edit'
  3. any of body.links where all hold:
    • .href_url.domain.domain is 'docs.google.com'
    • .href_url.path starts with '/presentation/'
    • any of:
      • all of:
        • strings.icontains(body.current_thread.text)
        • .display_text matches '[[:punct:]\\s][a-z0-9]{5,9}$'
        • .display_text matches '[[:punct:]\\s](?:[a-z0-9]*[a-z][0-9][a-z0-9]*|[a-z0-9]*[0-9][a-z][a-z0-9]*)$'
        • .href_url.path ends with '/pub'
      • all of:
        • length(ml.link_analysis(., mode='aggressive').final_dom.links) is 1
        • ml.link_analysis(., mode='aggressive').final_dom.raw contains 'canEdit: false'
        • ml.link_analysis(., mode='aggressive').final_dom.raw contains 'slidePageCount: 1.0'
        • any of ml.link_analysis(., mode='aggressive').final_dom.links where all hold:
          • .href_url.domain.domain not in $org_domains
          • any of:
            • all of:
              • .href_url.domain.domain not in $tranco_1m
              • .href_url.domain.domain not in $umbrella_1m
            • .href_url.domain.domain in $free_file_hosts
            • .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
            • .href_url.domain.root_domain in $social_landing_hosts
          • any of .href_url.rewrite.encoders where:
            • . is 'google_open_redirect'
      • ml.link_analysis(., mode='aggressive').final_dom.display_text contains "We're sorry. You can't access this item because it is in violation of our Terms of Service."
  4. any of:
    • all of:
      • sender.email.email not in ('comments-noreply@docs.google.com', 'drive-shares-dm-noreply@google.com', 'drive-shares-noreply@google.com', 'calendar-notification@google.com')
      • profile.by_sender().prevalence is not 'common'
    • sender.email.email in ('comments-noreply@docs.google.com', 'drive-shares-dm-noreply@google.com', 'drive-shares-noreply@google.com', 'calendar-notification@google.com')
  5. not:
    • all of:
      • sender.email.email in ('comments-noreply@docs.google.com', 'drive-shares-dm-noreply@google.com', 'drive-shares-noreply@google.com', 'calendar-notification@google.com')
      • headers.auth_summary.dmarc.pass
      • any of $org_display_names where any holds:
        • strings.istarts_with(sender.display_name)
        • strings.istarts_with(sender.display_name)
  6. any of:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • not:
        • headers.auth_summary.dmarc.pass
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • sender.email.email in ('comments-noreply@docs.google.com', 'drive-shares-dm-noreply@google.com', 'drive-shares-noreply@google.com', 'calendar-notification@google.com')
    • sender.email.domain.root_domain not in $high_trust_sender_root_domains

Inspects: body.current_thread.text, body.links, body.links[].display_text, body.links[].href_url.domain.domain, body.links[].href_url.path, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: ml.link_analysis, profile.by_sender, regex.icontains, strings.concat, strings.contains, strings.icontains, strings.iends_with, strings.istarts_with. Reference lists: $free_file_hosts, $free_subdomain_hosts, $high_trust_sender_root_domains, $org_display_names, $org_domains, $social_landing_hosts, $tranco_1m, $umbrella_1m, $url_shorteners.

Indicators matched (13)

FieldMatchValue
body.links[].href_url.domain.domainequalsdocs.google.com
strings.istarts_withprefix/presentation/
regex.icontainsregex[[:punct:]\s][a-z0-9]{5,9}$
regex.icontainsregex[[:punct:]\s](?:[a-z0-9]*[a-z][0-9][a-z0-9]*|[a-z0-9]*[0-9][a-z][a-z0-9]*)$
strings.iends_withsuffix/pub
strings.containssubstringcanEdit: false
strings.containssubstringslidePageCount: 1.0
ml.link_analysis(body.links[], mode='aggressive').final_dom.links[].href_url.rewrite.encoders[]equalsgoogle_open_redirect
strings.icontainssubstringWe're sorry. You can't access this item because it is in violation of our Terms of Service.
sender.email.emailmembercomments-noreply@docs.google.com
sender.email.emailmemberdrive-shares-dm-noreply@google.com
sender.email.emailmemberdrive-shares-noreply@google.com
1 more
sender.email.emailmembercalendar-notification@google.com

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        and
          any(ml.link_analysis(body.links, mode='aggressive').final_dom.links)
            and
              or
                and
                   macro "ml.link_analysis(body.links[], mode='aggressive').final_dom.links[].href_url.domain.domain not in tranco_1m"
                   macro "ml.link_analysis(body.links[], mode='aggressive').final_dom.links[].href_url.domain.domain not in umbrella_1m"
                 macro "ml.link_analysis(body.links[], mode='aggressive').final_dom.links[].href_url.domain.domain in free_file_hosts"
                 macro "ml.link_analysis(body.links[], mode='aggressive').final_dom.links[].href_url.domain.root_domain in free_file_hosts"
                 macro "ml.link_analysis(body.links[], mode='aggressive').final_dom.links[].href_url.domain.root_domain in free_subdomain_hosts"
                 macro "ml.link_analysis(body.links[], mode='aggressive').final_dom.links[].href_url.domain.root_domain in social_landing_hosts"
                 macro "ml.link_analysis(body.links[], mode='aggressive').final_dom.links[].href_url.domain.root_domain in url_shorteners"
              any(ml.link_analysis(body.links, mode='aggressive').final_dom.links.href_url.rewrite.encoders)
                ml.link_analysis(body.links, mode='aggressive').final_dom.links.href_url.rewrite.encoders eq "google_open_redirect"
               macro "ml.link_analysis(body.links[], mode='aggressive').final_dom.links[].href_url.domain.domain not in org_domains"
          ml.link_analysis(body.links[], mode='aggressive').final_dom.links length_compare "1"
          ml.link_analysis(body.links[], mode='aggressive').final_dom.raw contains "canEdit:  false"
          ml.link_analysis(body.links[], mode='aggressive').final_dom.raw contains "slidePageCount:  1.0"
        and
          body.links.display_text regex_match "[[:punct:]\\s](?:[a-z0-9]*[a-z][0-9][a-z0-9]*|[a-z0-9]*[0-9][a-z][a-z0-9]*)$"
          body.links.display_text regex_match "[[:punct:]\\s][a-z0-9]{5,9}$"
          body.links.href_url.path ends_with "/pub"
          strings.icontains func_call "strings.icontains(body.current_thread.text)"
        ml.link_analysis(body.links[], mode='aggressive').final_dom.display_text contains "We're sorry. You can't access this item because it is in violation of our Terms of Service."
      body.links.href_url.domain.domain eq "docs.google.com"
      body.links.href_url.path starts_with "/presentation/"
  or
    and
      not
        headers.auth_summary.dmarc.pass eq "true"
       macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
    and
      sender.email.email in ["calendar-notification@google.com", "comments-noreply@docs.google.com", "drive-shares-dm-noreply@google.com", "drive-shares-noreply@google.com"]
       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.email in ["calendar-notification@google.com", "comments-noreply@docs.google.com", "drive-shares-dm-noreply@google.com", "drive-shares-noreply@google.com"]
      profile.by_sender func_call "profile.by_sender().prevalence != common"
    sender.email.email in ["calendar-notification@google.com", "comments-noreply@docs.google.com", "drive-shares-dm-noreply@google.com", "drive-shares-noreply@google.com"]
  not
    and
      any($org_display_names)
        strings.istarts_with func_call "strings.istarts_with(sender.display_name)"
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.email in ["calendar-notification@google.com", "comments-noreply@docs.google.com", "drive-shares-dm-noreply@google.com", "drive-shares-noreply@google.com"]
  not
    body.current_thread.text contains "invited you to edit"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
$org_display_namesarray_any(no value, null check)excludes:$org_display_names
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
sender.email.emailincalendar-notification@google.com, comments-noreply@docs.google.com, drive-shares-dm-noreply@google.com, drive-shares-noreply@google.comexcludes:sender.email.email
body.current_thread.textcontainsinvited you to editexcludes:body.current_thread.text field:"body.current_thread.text" value:"invited you to edit"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
sender.email.emailin
  • calendar-notification@google.com
  • comments-noreply@docs.google.com
  • drive-shares-dm-noreply@google.com
  • drive-shares-noreply@google.com
field:"sender.email.email" kind:in
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Google share notification with suspicious comments

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

This detection rule matches on messages which contain suspicious language within the comments of a Google share notification. Suspicious content within the comments section of the notification is deemed as email abbreviations such as FW:, FWD:, and RE: or by containing words that reference a file share.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: VIP, Free file host

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.html
  • headers
  • headers.auth_summary
  • headers.reply_to
  • sender.email
  • type

Rule body

type.inbound
and 
// message is from google actual
sender.email.domain.domain == 'google.com'
and (
  sender.email.local_part == "drive-shares-noreply"
  or sender.email.local_part == "drive-shares-dm-noreply"
)
// contains a comment
and strings.icontains(body.html.raw,
                      '<div style="margin-top:24px; color:#5F6368">'
)
// those comments contain what appears to be an email
and (
  regex.icontains(body.html.raw,
                  '</div>\s*<div style="margin-top:24px; color:#5F6368">\s*(?:RE|FWD?)\s*:'
  )
  // the comment contains wording that relates to sharing a file
  // the list before being sent through regexp-assemble
  //   "request to view", "shared a file",   "sent you a file",
  //   "file access request", "view shared document",
  //   "pending file request", "document shared", "view a file",
  //   "file sent to you", "invited to view", "file access invite",
  //   "click to view", "open shared file", "drive file request"
  or regex.icontains(body.html.raw,
                     '</div>\s*<div style="margin-top:24px; color:#5F6368">[^<]*(?:<[^\/][^<]*)*(?:file (?:access (?:request|invite)|sent to you)|(?:s(?:ent you|hared) a|open shared) file|d(?:rive file request|ocument shared)|(?:invited|request|click) to view|view (?:shared document|a file)|pending file request)[^<]*(?:<[^\/][^<]*)*</div>\s*</td>'
  )
)
// not where the sender display name of the message is within org_display_names
and not (
  // the message is from google actual
  sender.email.email in (
    'comments-noreply@docs.google.com',
    'drive-shares-dm-noreply@google.com',
    'drive-shares-noreply@google.com',
    'calendar-notification@google.com'
  )
  and headers.auth_summary.dmarc.pass
  // but the sender display name is within org_display_names
  and (
    any(regex.iextract(sender.display_name,
                       '^(?P<sender_display_name>.*)\((?:via )?Google'
        ),
        .named_groups["sender_display_name"] in~ $org_display_names
    )
    or (
      length(headers.reply_to) == 1
      and all(headers.reply_to, .email.domain.domain in $org_domains)
    )
  )
)

Detection logic

Scope: inbound message.

This detection rule matches on messages which contain suspicious language within the comments of a Google share notification. Suspicious content within the comments section of the notification is deemed as email abbreviations such as FW:, FWD:, and RE: or by containing words that reference a file share.

  1. inbound message
  2. sender.email.domain.domain is 'google.com'
  3. any of:
    • sender.email.local_part is 'drive-shares-noreply'
    • sender.email.local_part is 'drive-shares-dm-noreply'
  4. body.html.raw contains '<div style="margin-top:24px; color:#5F6368">'
  5. any of:
    • body.html.raw matches '</div>\\s*<div style="margin-top:24px; color:#5F6368">\\s*(?:RE|FWD?)\\s*:'
    • body.html.raw matches '</div>\\s*<div style="margin-top:24px; color:#5F6368">[^<]*(?:<[^\\/][^<]*)*(?:file (?:access (?:request|invite)|sent to you)|(?:s(?:ent you|hared) a|open shared) file|d(?:rive file request|ocument shared)|(?:invited|request|click) to view|view (?:shared document|a file)|pending file request)[^<]*(?:<[^\\/][^<]*)*</div>\\s*</td>'
  6. not:
    • all of:
      • sender.email.email in ('comments-noreply@docs.google.com', 'drive-shares-dm-noreply@google.com', 'drive-shares-noreply@google.com', 'calendar-notification@google.com')
      • headers.auth_summary.dmarc.pass
      • any of:
        • any of regex.iextract(sender.display_name) where:
          • .named_groups['sender_display_name'] in $org_display_names
        • all of:
          • length(headers.reply_to) is 1
          • all of headers.reply_to where:
            • .email.domain.domain in $org_domains

Inspects: body.html.raw, headers.auth_summary.dmarc.pass, headers.reply_to, headers.reply_to[].email.domain.domain, sender.display_name, sender.email.domain.domain, sender.email.email, sender.email.local_part, type.inbound. Sensors: regex.icontains, regex.iextract, strings.icontains. Reference lists: $org_display_names, $org_domains.

Indicators matched (6)

FieldMatchValue
sender.email.domain.domainequalsgoogle.com
sender.email.local_partequalsdrive-shares-noreply
sender.email.local_partequalsdrive-shares-dm-noreply
strings.icontainssubstring<div style="margin-top:24px; color:#5F6368">
regex.icontainsregex</div>\s*<div style="margin-top:24px; color:#5F6368">\s*(?:RE|FWD?)\s*:
regex.icontainsregex</div>\s*<div style="margin-top:24px; color:#5F6368">[^<]*(?:<[^\/][^<]*)*(?:file (?:access (?:request|invite)|sent to you)|(?:s(?:ent you|hared) a|open shared) file|d(?:rive file request|ocument shared)|(?:invited|request|click) to view|view (?:shared document|a file)|pending file request)[^<]*(?:<[^\/][^<]*)*</div>\s*</td>

Stages and Predicates

Stage 1: mql_rule

and
  not
    and
      or
        and
          headers.reply_to length_compare "1"
           macro "all(headers.reply_to)"
        any(regex.iextract(sender.display_name))
           macro "regex.iextract(sender.display_name)[].named_groups['sender_display_name'] in org_display_names"
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.email in ["calendar-notification@google.com", "comments-noreply@docs.google.com", "drive-shares-dm-noreply@google.com", "drive-shares-noreply@google.com"]
  or
    body.html.raw regex_match "</div>\\s*<div style=\"margin-top:24px; color:#5F6368\">[^<]*(?:<[^\\/][^<]*)*(?:file (?:access (?:request|invite)|sent to you)|(?:s(?:ent you|hared) a|open shared) file|d(?:rive file request|ocument shared)|(?:invited|request|click) to view|view (?:shared document|a file)|pending file request)[^<]*(?:<[^\\/][^<]*)*</div>\\s*</td>"
    body.html.raw regex_match "</div>\\s*<div style=\"margin-top:24px; color:#5F6368\">\\s*(?:RE|FWD?)\\s*:"
  or
    sender.email.local_part eq "drive-shares-dm-noreply"
    sender.email.local_part eq "drive-shares-noreply"
  body.html.raw contains "<div style=\"margin-top:24px; color:#5F6368\">"
  sender.email.domain.domain eq "google.com"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.reply_tolength_compare1excludes:headers.reply_to field:"headers.reply_to" value:"1"
regex.iextract(sender.display_name)array_any(no value, null check)excludes:regex.iextract(sender.display_name)
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
sender.email.emailincalendar-notification@google.com, comments-noreply@docs.google.com, drive-shares-dm-noreply@google.com, drive-shares-noreply@google.comexcludes:sender.email.email

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.html.rawcontains
  • <div style="margin-top:24px; color:#5F6368">
field:"body.html.raw" kind:contains
body.html.rawregex_match
  • </div>\s*<div style="margin-top:24px; color:#5F6368">[^<]*(?:<[^\/][^<]*)*(?:file (?:access (?:request|invite)|sent to you)|(?:s(?:ent you|hared) a|open shared) file|d(?:rive file request|ocument shared)|(?:invited|request|click) to view|view (?:shared document|a file)|pending file request)[^<]*(?:<[^\/][^<]*)*</div>\s*</td>
  • </div>\s*<div style="margin-top:24px; color:#5F6368">\s*(?:RE|FWD?)\s*:
field:"body.html.raw" kind:regex_match
sender.email.domain.domaineq
  • google.com
field:"sender.email.domain.domain" kind:eq value:"google.com"
sender.email.local_parteq
  • drive-shares-dm-noreply
  • drive-shares-noreply
field:"sender.email.local_part" kind:eq
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link abuse: Self-service creation platform link with suspicious recipient behavior

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

Detects messages from new freemail senders containing links to self-service creation platforms with all-caps display text, combined with suspicious recipient patterns such as invalid recipients, self-sending, or unusual CC/BCC configurations.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Credential Phishing, Spam
Tactics and techniquesFree email provider, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • recipients
  • recipients.cc
  • recipients.to
  • recipients.to[0]
  • sender.email
  • type

Rule body

type.inbound
// new freemail sender
and profile.by_sender_email().prevalence == "new"
and sender.email.domain.domain in $free_email_providers
// sus rcpt behavior
and (
  // invalid rcpt
  length(filter(recipients.to, .email.domain.valid)) == 0
  // self sender
  or (
    length(recipients.to) == 1
    and sender.email.email == recipients.to[0].email.email
  )
  // BCC is another freemail
  or (
    length(recipients.cc) == 1
    and all(recipients.cc, .email.domain.domain in $free_email_providers)
  )
  // the recipient is another freemail with bcc
  or (
    length(recipients.to) == 1
    and recipients.to[0].email.domain.domain in $free_email_providers
    and length(recipients.bcc) > 0
  )
)
// few body links
and length(body.current_thread.links) < 10
// the self_service_creation_platform contains a link with the display_text in all caps
and any(body.current_thread.links,
        (
          .href_url.domain.root_domain in $self_service_creation_platform_domains
          or .href_url.domain.domain in $self_service_creation_platform_domains
        )
        and regex.match(.display_text, '[A-Z0-9_\-\s]+')
)

Detection logic

Scope: inbound message.

Detects messages from new freemail senders containing links to self-service creation platforms with all-caps display text, combined with suspicious recipient patterns such as invalid recipients, self-sending, or unusual CC/BCC configurations.

  1. inbound message
  2. profile.by_sender_email().prevalence is 'new'
  3. sender.email.domain.domain in $free_email_providers
  4. any of:
    • length(filter(recipients.to, .email.domain.valid)) is 0
    • all of:
      • length(recipients.to) is 1
      • sender.email.email is recipients.to[0].email.email
    • all of:
      • length(recipients.cc) is 1
      • all of recipients.cc where:
        • .email.domain.domain in $free_email_providers
    • all of:
      • length(recipients.to) is 1
      • recipients.to[0].email.domain.domain in $free_email_providers
      • length(recipients.bcc) > 0
  5. length(body.current_thread.links) < 10
  6. any of body.current_thread.links where all hold:
    • any of:
      • .href_url.domain.root_domain in $self_service_creation_platform_domains
      • .href_url.domain.domain in $self_service_creation_platform_domains
    • .display_text matches '[A-Z0-9_\\-\\s]+'

Inspects: body.current_thread.links, body.current_thread.links[].display_text, body.current_thread.links[].href_url.domain.domain, body.current_thread.links[].href_url.domain.root_domain, recipients.bcc, recipients.cc, recipients.cc[].email.domain.domain, recipients.to, recipients.to[0].email.domain.domain, recipients.to[0].email.email, recipients.to[].email.domain.valid, sender.email.domain.domain, sender.email.email, type.inbound. Sensors: profile.by_sender_email, regex.match. Reference lists: $free_email_providers, $self_service_creation_platform_domains.

Indicators matched (1)

FieldMatchValue
regex.matchregex[A-Z0-9_\-\s]+

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    and
      or
         macro "body.current_thread.links[].href_url.domain.domain in self_service_creation_platform_domains"
         macro "body.current_thread.links[].href_url.domain.root_domain in self_service_creation_platform_domains"
      body.current_thread.links.display_text regex_match "[A-Z0-9_\\-\\s]+"
  or
    and
      recipients.bcc length_compare "0"
      recipients.to length_compare "1"
       macro "recipients.to[0].email.domain.domain in free_email_providers"
    and
      recipients.cc length_compare "1"
       macro "all(recipients.cc)"
    and
      recipients.to length_compare "1"
      sender.email.email cross_field_compare "recipients.to[0].email.email"
    filter(recipients.to, .email.domain.valid) length_compare "0"
  body.current_thread.links length_compare "10"
  profile.by_sender_email func_call "profile.by_sender_email().prevalence == new"
  type.inbound eq "true"
   macro "sender.email.domain.domain in free_email_providers"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
sender.email.emailcross_field_compare
  • recipients.to[0].email.email transforms: op:eq
field:"sender.email.email" kind:cross_field_compare value:"recipients.to[0].email.email"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link to a domain with punycode characters

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

The body contains a link to a domain with Punycode characters to hide the true URL destination, or contains non-printable ASCII content.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Lookalike domain, Punycode

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and (
  any(body.links,
      .href_url.domain.punycode is not null and .href_url.domain.valid == true
  )
  or any(body.links, strings.starts_with(.href_url.domain.domain, "xn--"))
)

Detection logic

Scope: inbound message.

The body contains a link to a domain with Punycode characters to hide the true URL destination, or contains non-printable ASCII content.

  1. inbound message
  2. any of:
    • any of body.links where all hold:
      • .href_url.domain.punycode is set
      • .href_url.domain.valid is True
    • any of body.links where:
      • .href_url.domain.domain starts with 'xn--'

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.punycode, body.links[].href_url.domain.valid, type.inbound. Sensors: strings.starts_with.

Indicators matched (1)

FieldMatchValue
strings.starts_withprefixxn--

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(body.links)
      and
        body.links.href_url.domain.punycode is_not_null
        body.links.href_url.domain.valid eq "true"
    any(body.links)
      body.links.href_url.domain.domain starts_with "xn--"
  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"

Link to auto-download of a suspicious file type (unsolicited)

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

A link in the body of the email downloads a suspicious file type (or embedded file) such as an LNK, JS, or VBA. Recursively explodes auto-downloaded files within archives to detect these file types. This rule also catches direct Google Drive download links (drive.google.com/uc?export=download) that automatically download archive files, as these are frequently abused by threat actors to distribute malware. This technique has been used by known threat actors in the wild.

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware
Tactics and techniquesEncryption, Evasion, LNK, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        // Detect suspicious direct Google Drive downloads
        (
          strings.icontains(.href_url.url, "drive.google.com/uc")
          and strings.icontains(.href_url.url, "export=download")
          and any(ml.link_analysis(., mode="aggressive").files_downloaded,
                  .file_extension in $file_extensions_common_archives
          )
        )
        or any(ml.link_analysis(.).files_downloaded,
               // call parse_exif to see if there is a sus file
               any(beta.parse_exif(.).fields,
                   .key == "ArchivedFileName"
                   and strings.ilike(.value,
                                     "*.dll",
                                     "*.html",
                                     "*.exe",
                                     "*.lnk",
                                     "*.js",
                                     "*.vba",
                                     "*.vbs",
                                     "*.vbe",
                                     "*.bat"
                   )
               )
               or any(file.explode(.),
                      (
                        // look for files in encrypted zips.
                        // if password cracking the zip wasn't
                        // successful, our only opportunity to look
                        // for suspicious file types is here under
                        // .zip.attempted_files
                        "encrypted_zip" in .flavors.yara
                        and any(.scan.zip.attempted_files,
                                strings.ilike(.,
                                              "*.dll",
                                              "*.html",
                                              "*.exe",
                                              "*.lnk",
                                              "*.js",
                                              "*.vba",
                                              "*.vbs",
                                              "*.vbe",
                                              "*.bat"
                                )
                        )
                      )
                      // for both non-encrypted zips and encrypted zips
                      // that were successfully cracked
                      or .file_extension in (
                        "dll",
                        "exe",
                        "html",
                        "lnk",
                        "js",
                        "vba",
                        "vbs",
                        "vbe",
                        "bat"
                      )
                      or strings.ilike(.file_name, "*.exe")
                      or (
                        .file_extension not in ("dll", "exe")
                        and (
                          .flavors.mime in ("application/x-dosexec")
                          or any(.flavors.yara, . in ('mz_file'))
                        )
                      )
                      or any(.flavors.yara, . == "macho_file")
               )
               and not (
                 ml.link_analysis(..).effective_url.domain.root_domain == "zoom.us"
                 and .file_extension == "exe"
               )
        )
)
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.

A link in the body of the email downloads a suspicious file type (or embedded file) such as an LNK, JS, or VBA. Recursively explodes auto-downloaded files within archives to detect these file types. This rule also catches direct Google Drive download links (drive.google.com/uc?export=download) that automatically download archive files, as these are frequently abused by threat actors to distribute malware. This technique has been used by known threat actors in the wild.

  1. inbound message
  2. any of body.links where any holds:
    • all of:
      • .href_url.url contains 'drive.google.com/uc'
      • .href_url.url contains 'export=download'
      • any of ml.link_analysis(., mode='aggressive').files_downloaded where:
        • .file_extension in $file_extensions_common_archives
    • any of ml.link_analysis(.).files_downloaded where any holds:
      • any of beta.parse_exif(.).fields where all hold:
        • .key is 'ArchivedFileName'
        • .value matches any of 9 patterns
          • *.dll
          • *.html
          • *.exe
          • *.lnk
          • *.js
          • *.vba
          • *.vbs
          • *.vbe
          • *.bat
      • all of:
        • any of file.explode(.) where any holds:
          • all of:
            • .flavors.yara contains 'encrypted_zip'
            • any of .scan.zip.attempted_files where:
              • . matches any of 9 patterns
                • *.dll
                • *.html
                • *.exe
                • *.lnk
                • *.js
                • *.vba
                • *.vbs
                • *.vbe
                • *.bat
          • .file_extension in ('dll', 'exe', 'html', 'lnk', 'js', 'vba', 'vbs', 'vbe', 'bat')
          • .file_name matches '*.exe'
          • all of:
            • .file_extension not in ('dll', 'exe')
            • any of:
              • .flavors.mime in ('application/x-dosexec')
              • any of .flavors.yara where:
                • . in ('mz_file')
          • any of .flavors.yara where:
            • . is 'macho_file'
        • not:
          • all of:
            • ml.link_analysis(.).effective_url.domain.root_domain is 'zoom.us'
            • .file_extension is 'exe'
  3. 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.links, body.links[].href_url.url, type.inbound. Sensors: beta.parse_exif, file.explode, ml.link_analysis, profile.by_sender, strings.icontains, strings.ilike. Reference lists: $file_extensions_common_archives.

Indicators matched (25)

FieldMatchValue
strings.icontainssubstringdrive.google.com/uc
strings.icontainssubstringexport=download
beta.parse_exif(ml.link_analysis(body.links[]).files_downloaded[]).fields[].keyequalsArchivedFileName
strings.ilikesubstring*.dll
strings.ilikesubstring*.html
strings.ilikesubstring*.exe
strings.ilikesubstring*.lnk
strings.ilikesubstring*.js
strings.ilikesubstring*.vba
strings.ilikesubstring*.vbs
strings.ilikesubstring*.vbe
strings.ilikesubstring*.bat
13 more
file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].flavors.yaracontainsencrypted_zip
file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].file_extensionmemberdll
file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].file_extensionmemberexe
file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].file_extensionmemberhtml
file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].file_extensionmemberlnk
file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].file_extensionmemberjs
file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].file_extensionmembervba
file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].file_extensionmembervbs
file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].file_extensionmembervbe
file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].file_extensionmemberbat
file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].flavors.mimememberapplication/x-dosexec
file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].flavors.yara[]membermz_file
file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].flavors.yara[]equalsmacho_file

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    or
      any(ml.link_analysis(body.links).files_downloaded)
        or
          and
            any(file.explode(ml.link_analysis(body.links).files_downloaded))
              or
                and
                  or
                    any(file.explode(ml.link_analysis(body.links).files_downloaded).flavors.yara)
                      file.explode(ml.link_analysis(body.links).files_downloaded).flavors.yara eq "mz_file"
                    file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].flavors.mime eq "application/x-dosexec"
                  not
                    file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].file_extension in ["dll", "exe"]
                and
                  any(file.explode(ml.link_analysis(body.links).files_downloaded).scan.zip.attempted_files)
                    or
                      file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].scan.zip.attempted_files[] ends_with ".bat"
                      file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].scan.zip.attempted_files[] ends_with ".dll"
                      file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].scan.zip.attempted_files[] ends_with ".exe"
                      file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].scan.zip.attempted_files[] ends_with ".html"
                      file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].scan.zip.attempted_files[] ends_with ".js"
                      file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].scan.zip.attempted_files[] ends_with ".lnk"
                      file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].scan.zip.attempted_files[] ends_with ".vba"
                      file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].scan.zip.attempted_files[] ends_with ".vbe"
                      file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].scan.zip.attempted_files[] ends_with ".vbs"
                  file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].flavors.yara contains "encrypted_zip"
                any(file.explode(ml.link_analysis(body.links).files_downloaded).flavors.yara)
                  file.explode(ml.link_analysis(body.links).files_downloaded).flavors.yara eq "macho_file"
                file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].file_extension in ["bat", "dll", "exe", "html", "js", "lnk", "vba", "vbe", "vbs"]
                file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].file_name ends_with ".exe"
            not
              and
                ml.link_analysis func_call "ml.link_analysis(body.links[]).effective_url.domain.root_domain == zoom.us"
                ml.link_analysis(body.links[]).files_downloaded[].file_extension eq "exe"
          any(beta.parse_exif(ml.link_analysis(body.links).files_downloaded).fields)
            and
              or
                beta.parse_exif(ml.link_analysis(body.links[]).files_downloaded[]).fields[].value ends_with ".bat"
                beta.parse_exif(ml.link_analysis(body.links[]).files_downloaded[]).fields[].value ends_with ".dll"
                beta.parse_exif(ml.link_analysis(body.links[]).files_downloaded[]).fields[].value ends_with ".exe"
                beta.parse_exif(ml.link_analysis(body.links[]).files_downloaded[]).fields[].value ends_with ".html"
                beta.parse_exif(ml.link_analysis(body.links[]).files_downloaded[]).fields[].value ends_with ".js"
                beta.parse_exif(ml.link_analysis(body.links[]).files_downloaded[]).fields[].value ends_with ".lnk"
                beta.parse_exif(ml.link_analysis(body.links[]).files_downloaded[]).fields[].value ends_with ".vba"
                beta.parse_exif(ml.link_analysis(body.links[]).files_downloaded[]).fields[].value ends_with ".vbe"
                beta.parse_exif(ml.link_analysis(body.links[]).files_downloaded[]).fields[].value ends_with ".vbs"
              beta.parse_exif(ml.link_analysis(body.links[]).files_downloaded[]).fields[].key eq "ArchivedFileName"
      and
        any(ml.link_analysis(body.links, mode='aggressive').files_downloaded)
           macro "ml.link_analysis(body.links[], mode='aggressive').files_downloaded[].file_extension in file_extensions_common_archives"
        body.links.href_url.url contains "drive.google.com/uc"
        body.links.href_url.url contains "export=download"
  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"
  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"

Link to auto-downloaded disk image in encrypted zip

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

A link in the body of the email downloads an encrypted zip that contains a disk image of the format IMG, ISO or VHD. This is a combination of file types used to deliver Qakbot.

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware
Tactics and techniquesEncryption, Evasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • type

Rule body

type.inbound
and any(body.links,
        any(ml.link_analysis(.).files_downloaded,
            any(file.explode(.),
                (
                  any(.flavors.yara, . == "encrypted_zip")
                  and any(.scan.zip.all_paths,
                          any([".img", ".iso", ".vhd"],
                              strings.ends_with(.., .)
                          )
                  )
                )
            )
        )
)
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.

A link in the body of the email downloads an encrypted zip that contains a disk image of the format IMG, ISO or VHD. This is a combination of file types used to deliver Qakbot.

  1. inbound message
  2. any of body.links where:
    • any of ml.link_analysis(.).files_downloaded where:
      • any of file.explode(.) where all hold:
        • any of .flavors.yara where:
          • . is 'encrypted_zip'
        • any of .scan.zip.all_paths where:
          • any of ['.img', '.iso', '.vhd'] where:
            • strings.ends_with(.)
  3. 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: body.links, type.inbound. Sensors: file.explode, ml.link_analysis, profile.by_sender, strings.ends_with.

Indicators matched (1)

FieldMatchValue
file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].flavors.yara[]equalsencrypted_zip

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    any(ml.link_analysis(body.links).files_downloaded)
      any(file.explode(ml.link_analysis(body.links).files_downloaded))
        and
          any(file.explode(ml.link_analysis(body.links).files_downloaded).scan.zip.all_paths)
            any(['.img', '.iso', '.vhd'])
              strings.ends_with func_call "strings.ends_with(file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].scan.zip.all_paths[])"
          any(file.explode(ml.link_analysis(body.links).files_downloaded).flavors.yara)
            file.explode(ml.link_analysis(body.links).files_downloaded).flavors.yara eq "encrypted_zip"
  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)"
  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"

Link to auto-downloaded DMG in archive

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

A link in the body of the message downloads an archive containing a DMG file. The message is not from a common or trusted sender and is unsolicited.

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware
Tactics and techniquesEvasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
and any(body.links,
        any(ml.link_analysis(.).files_downloaded,
            .file_extension in~ $file_extensions_common_archives
            and any(file.explode(.), .file_extension == "dmg")
        )
)
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
  )
)

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

A link in the body of the message downloads an archive containing a DMG file. The message is not from a common or trusted sender and is unsolicited.

  1. inbound message
  2. any of body.links where:
    • any of ml.link_analysis(.).files_downloaded where all hold:
      • .file_extension in $file_extensions_common_archives
      • any of file.explode(.) where:
        • .file_extension is 'dmg'
  3. 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
  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.links, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, ml.link_analysis, profile.by_sender. Reference lists: $file_extensions_common_archives, $high_trust_sender_root_domains.

Indicators matched (1)

FieldMatchValue
file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].file_extensionequalsdmg

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    any(ml.link_analysis(body.links).files_downloaded)
      and
        any(file.explode(ml.link_analysis(body.links).files_downloaded))
          file.explode(ml.link_analysis(body.links).files_downloaded).file_extension eq "dmg"
         macro "ml.link_analysis(body.links[]).files_downloaded[].file_extension in file_extensions_common_archives"
  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"
  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"

Link to auto-downloaded DMG in encrypted zip

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

A link in the body of the message downloads an encrypted zip that contains a DMG file. This technique has been observed ITW to deliver Meta Stealer, Atomic Stealer, and other MacOS malware. Notably, in some instances, the attacker poses as a recruiter and initiates back and forth conversation with the recipient.

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware
Tactics and techniquesEncryption, Evasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
and any(body.links,
        any(ml.link_analysis(.).files_downloaded,
            any(file.explode(.),
                (
                  any(.flavors.yara, . == "encrypted_zip")
                  and any(.scan.zip.all_paths,
                          any([".dmg"], strings.ends_with(.., .))
                  )
                )
            )
        )
)
and (
  profile.by_sender().prevalence != "common"
  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.

A link in the body of the message downloads an encrypted zip that contains a DMG file. This technique has been observed ITW to deliver Meta Stealer, Atomic Stealer, and other MacOS malware. Notably, in some instances, the attacker poses as a recruiter and initiates back and forth conversation with the recipient.

  1. inbound message
  2. any of body.links where:
    • any of ml.link_analysis(.).files_downloaded where:
      • any of file.explode(.) where all hold:
        • any of .flavors.yara where:
          • . is 'encrypted_zip'
        • any of .scan.zip.all_paths where:
          • any of ['.dmg'] where:
            • strings.ends_with(.)
  3. 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
  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.links, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, ml.link_analysis, profile.by_sender, strings.ends_with. Reference lists: $high_trust_sender_root_domains.

Indicators matched (1)

FieldMatchValue
file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].flavors.yara[]equalsencrypted_zip

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    any(ml.link_analysis(body.links).files_downloaded)
      any(file.explode(ml.link_analysis(body.links).files_downloaded))
        and
          any(file.explode(ml.link_analysis(body.links).files_downloaded).scan.zip.all_paths)
            any(['.dmg'])
              strings.ends_with func_call "strings.ends_with(file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].scan.zip.all_paths[])"
          any(file.explode(ml.link_analysis(body.links).files_downloaded).flavors.yara)
            file.explode(ml.link_analysis(body.links).files_downloaded).flavors.yara eq "encrypted_zip"
  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 != common"
  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"

Link to auto-downloaded file with Adobe branding

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

A link in the body of the email downloads a file from a site that uses Adobe branding as employed by threat actors, such as Qakbot.

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • type

Rule body

type.inbound
and any(body.links,
        // There are files downloaded
        length(ml.link_analysis(.).files_downloaded) > 0
        and 

        // Adobe branding
        ml.link_analysis(.).credphish.brand.name == "Adobe"
        and ml.link_analysis(.).credphish.brand.confidence == "high"
        and 

        // Qakbot text for user coercion
        any(file.explode(ml.link_analysis(.).screenshot),
            all(["the file is not displayed correctly", "document password"],
                strings.icontains(..scan.ocr.raw, .)
            )
        )
)
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.

A link in the body of the email downloads a file from a site that uses Adobe branding as employed by threat actors, such as Qakbot.

  1. inbound message
  2. any of body.links where all hold:
    • length(ml.link_analysis(.).files_downloaded) > 0
    • ml.link_analysis(.).credphish.brand.name is 'Adobe'
    • ml.link_analysis(.).credphish.brand.confidence is 'high'
    • any of file.explode(...) where:
      • all of ['the file is not displayed correctly', 'document password'] where:
        • strings.icontains(.scan.ocr.raw)
  3. 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.links, type.inbound. Sensors: file.explode, ml.link_analysis, profile.by_sender, strings.icontains.

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(body.links)
    and
      any(file.explode(...))
         macro "all(['the file is not displayed correctly', 'document password'])"
      ml.link_analysis func_call "ml.link_analysis(body.links[]).credphish.brand.confidence == high"
      ml.link_analysis func_call "ml.link_analysis(body.links[]).credphish.brand.name == Adobe"
      ml.link_analysis(body.links[]).files_downloaded length_compare "0"
  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"

Link to auto-downloaded file with Google Drive branding

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

A link in the body of the email downloads a file from a site that uses Google Drive branding as employed by threat actors, such as Qakbot.

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware
Tactics and techniquesImpersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and length(body.links) < 10
and any(body.links,
        // This isn't a Google Drive link
        .href_url.domain.root_domain != "google.com"
        and 

        // There are files downloaded
        length(ml.link_analysis(.).files_downloaded) > 0
        and 

        // Google Drive branding
        ml.link_analysis(.).credphish.brand.name == "GoogleDrive"
        and ml.link_analysis(.).credphish.brand.confidence == "high"
        and 

        // Hi from Qakbot
        any(file.explode(ml.link_analysis(.).screenshot),
            any([
                  "the file is not displayed correctly",
                  "use local downloaded file"
                ],
                strings.icontains(..scan.ocr.raw, .)
            )
        )
)
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.

A link in the body of the email downloads a file from a site that uses Google Drive branding as employed by threat actors, such as Qakbot.

  1. inbound message
  2. length(body.links) < 10
  3. any of body.links where all hold:
    • .href_url.domain.root_domain is not 'google.com'
    • length(ml.link_analysis(.).files_downloaded) > 0
    • ml.link_analysis(.).credphish.brand.name is 'GoogleDrive'
    • ml.link_analysis(.).credphish.brand.confidence is 'high'
    • any of file.explode(...) where:
      • any of ['the file is not displayed correctly', 'use local downloaded file'] where:
        • strings.icontains(.scan.ocr.raw)
  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.links, body.links[].href_url.domain.root_domain, type.inbound. Sensors: file.explode, ml.link_analysis, profile.by_sender, strings.icontains.

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      any(file.explode(...))
        any(['the file is not displayed correctly', 'use local downloaded file'])
          strings.icontains func_call "strings.icontains(file.explode(...)[].scan.ocr.raw)"
      body.links.href_url.domain.root_domain ne "google.com"
      ml.link_analysis func_call "ml.link_analysis(body.links[]).credphish.brand.confidence == high"
      ml.link_analysis func_call "ml.link_analysis(body.links[]).credphish.brand.name == GoogleDrive"
      ml.link_analysis(body.links[]).files_downloaded 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"
    not
      profile.by_sender func_call "profile.by_sender().solicited"
  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"

Link to Google Apps Script macro (unsolicited)

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

Message contains a Google Apps Script macro link. App Scripts can run arbitrary code, including redirecting the user to a malicious web page.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesOpen redirect, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        .href_url.domain.domain == "script.google.com"
        and strings.ilike(.href_url.path, "/macros*")
)
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.

Message contains a Google Apps Script macro link. App Scripts can run arbitrary code, including redirecting the user to a malicious web page.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.domain.domain is 'script.google.com'
    • .href_url.path matches '/macros*'
  3. 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: body.links, body.links[].href_url.domain.domain, body.links[].href_url.path, type.inbound. Sensors: profile.by_sender, strings.ilike.

Indicators matched (2)

FieldMatchValue
body.links[].href_url.domain.domainequalsscript.google.com
strings.ilikesubstring/macros*

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)"
  any(body.links)
    and
      body.links.href_url.domain.domain eq "script.google.com"
      body.links.href_url.path starts_with "/macros"
  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"

Link to Google Apps Script macro via comment tagging

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

Message contains a Google Apps Script macro link invoked from a comment on Google Slides|Docs. App Scripts can run arbitrary code, including redirecting the user to a malicious web page.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesSocial engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • body.plain
  • type

Rule body

type.inbound
and regex.contains(sender.display_name, '\(Google (Slides|Docs)')
and any(body.links,
        .href_url.domain.domain == "script.google.com"
        and strings.ilike(.href_url.path, "/macros*")
)
and 1 of (
  strings.ilike(body.plain.raw, '*you have ? hours*'),
  strings.ilike(body.plain.raw, '*transfer of funds*'),
  strings.ilike(body.plain.raw, '*order your funds*')
  // Or the Sender Display Name is not in your Org Display Names
  or not any($org_display_names,
             strings.istarts_with(sender.display_name,
                                  strings.concat(., " (Google ")
             )
  )
)

Detection logic

Scope: inbound message.

Message contains a Google Apps Script macro link invoked from a comment on Google Slides|Docs. App Scripts can run arbitrary code, including redirecting the user to a malicious web page.

  1. inbound message
  2. sender.display_name matches '\\(Google (Slides|Docs)'
  3. any of body.links where all hold:
    • .href_url.domain.domain is 'script.google.com'
    • .href_url.path matches '/macros*'
  4. at least 1 of:
    • body.plain.raw matches '*you have ? hours*'
    • body.plain.raw matches '*transfer of funds*'
    • any of:
      • body.plain.raw matches '*order your funds*'
      • not:
        • any of $org_display_names where:
          • strings.istarts_with(sender.display_name)

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.path, body.plain.raw, sender.display_name, type.inbound. Sensors: regex.contains, strings.concat, strings.ilike, strings.istarts_with. Reference lists: $org_display_names.

Indicators matched (6)

FieldMatchValue
regex.containsregex\(Google (Slides|Docs)
body.links[].href_url.domain.domainequalsscript.google.com
strings.ilikesubstring/macros*
strings.ilikesubstring*you have ? hours*
strings.ilikesubstring*transfer of funds*
strings.ilikesubstring*order your funds*

Stages and Predicates

Stage 1: mql_rule

and
  or
    not
      any($org_display_names)
        strings.istarts_with func_call "strings.istarts_with(sender.display_name)"
    body.plain.raw match "order your funds"
    body.plain.raw match "transfer of funds"
    body.plain.raw match "you have ? hours"
  any(body.links)
    and
      body.links.href_url.domain.domain eq "script.google.com"
      body.links.href_url.path starts_with "/macros"
  sender.display_name regex_match "\\(Google (Slides|Docs)"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.plain.rawwildcard
  • *order your funds*
  • *transfer of funds*
  • *you have ? hours*
field:"body.plain.raw" kind:wildcard
sender.display_nameregex_match
  • (Google (Slides|Docs)
field:"sender.display_name" kind:regex_match value:"(Google (Slides|Docs)"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link: .onion From Unsolicited Sender

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

Detects messages containing .onion (Tor network) links from unsolicited senders that either lack proper DMARC authentication or are not from trusted domains.

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware, Credential Phishing
Tactics and techniquesEvasion, 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 any(body.links, .href_url.domain.tld == "onion")
and not profile.by_sender_email().solicited
// 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 containing .onion (Tor network) links from unsolicited senders that either lack proper DMARC authentication or are not from trusted domains.

  1. inbound message
  2. any of body.links where:
    • .href_url.domain.tld is 'onion'
  3. not:
    • profile.by_sender_email().solicited
  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.links, body.links[].href_url.domain.tld, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender_email. Reference lists: $high_trust_sender_root_domains.

Indicators matched (1)

FieldMatchValue
body.links[].href_url.domain.tldequalsonion

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(body.links)
    body.links.href_url.domain.tld eq "onion"
  not
    profile.by_sender_email func_call "profile.by_sender_email().solicited"
  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"

Link: .su domain link redirection from new sender domains

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

Catches inbound messages from recently established sending domains where a link in the body ultimately redirects through a .su (Soviet Union) top-level domain, despite the visible link pointing elsewhere. These messages often masquerade as academic transcript requests, invitations, or administrative notices, using legitimate-looking business or organizational senders to deliver links that funnel recipients through .su-based redirect infrastructure, a technique commonly used to obscure the final malicious destination.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Spam
Tactics and techniquesOpen redirect, Social engineering, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and profile.by_sender_email().days_known < 7
and any(body.links,
        .href_url.domain.tld != "su"
        and any(ml.link_analysis(.).redirect_history, .domain.tld == "su")
)

Detection logic

Scope: inbound message.

Catches inbound messages from recently established sending domains where a link in the body ultimately redirects through a .su (Soviet Union) top-level domain, despite the visible link pointing elsewhere. These messages often masquerade as academic transcript requests, invitations, or administrative notices, using legitimate-looking business or organizational senders to deliver links that funnel recipients through .su-based redirect infrastructure, a technique commonly used to obscure the final malicious destination.

  1. inbound message
  2. profile.by_sender_email().days_known < 7
  3. any of body.links where all hold:
    • .href_url.domain.tld is not 'su'
    • any of ml.link_analysis(.).redirect_history where:
      • .domain.tld is 'su'

Inspects: body.links, body.links[].href_url.domain.tld, type.inbound. Sensors: ml.link_analysis, profile.by_sender_email.

Indicators matched (1)

FieldMatchValue
ml.link_analysis(body.links[]).redirect_history[].domain.tldequalssu

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      any(ml.link_analysis(body.links).redirect_history)
        ml.link_analysis(body.links).redirect_history.domain.tld eq "su"
      body.links.href_url.domain.tld ne "su"
  profile.by_sender_email func_call "profile.by_sender_email().days_known < 7"
  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"

Link: /index.php enclosed in three asterisks

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

Detects messages containing a specific pattern of triple asterisks surrounding HTTP links that point to PHP index pages with query parameters, indicating potential malicious behavior. This specific pattern has been observed within messages leading to FakeAV/Tech Support scams.

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware, Callback Phishing
Tactics and techniquesSocial engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • type

Rule body

type.inbound
and strings.count(body.current_thread.text, '* * *') == 2
and strings.contains(body.current_thread.text, ': http')
and strings.contains(body.current_thread.text, '/index.php?')
and regex.icontains(body.current_thread.text,
                    '\* \* \*(?:[^\r\n]+|[\r\n][^\r\n]*): https?:\/\/.*\/index\.php\?[a-z0-9]+(?:[^\r\n]+|[\r\n][^\r\n]*)\* \* \*'
)

Detection logic

Scope: inbound message.

Detects messages containing a specific pattern of triple asterisks surrounding HTTP links that point to PHP index pages with query parameters, indicating potential malicious behavior. This specific pattern has been observed within messages leading to FakeAV/Tech Support scams.

  1. inbound message
  2. strings.count(body.current_thread.text, '* * *') is 2
  3. body.current_thread.text contains ': http'
  4. body.current_thread.text contains '/index.php?'
  5. body.current_thread.text matches '\\* \\* \\*(?:[^\\r\\n]+|[\\r\\n][^\\r\\n]*): https?:\\/\\/.*\\/index\\.php\\?[a-z0-9]+(?:[^\\r\\n]+|[\\r\\n][^\\r\\n]*)\\* \\* \\*'

Inspects: body.current_thread.text, type.inbound. Sensors: regex.icontains, strings.contains, strings.count.

Indicators matched (3)

FieldMatchValue
strings.containssubstring: http
strings.containssubstring/index.php?
regex.icontainsregex\* \* \*(?:[^\r\n]+|[\r\n][^\r\n]*): https?:\/\/.*\/index\.php\?[a-z0-9]+(?:[^\r\n]+|[\r\n][^\r\n]*)\* \* \*

Stages and Predicates

Stage 1: mql_rule

and
  body.current_thread.text contains "/index.php?"
  body.current_thread.text contains ": http"
  body.current_thread.text regex_match "\\* \\* \\*(?:[^\\r\\n]+|[\\r\\n][^\\r\\n]*): https?:\\/\\/.*\\/index\\.php\\?[a-z0-9]+(?:[^\\r\\n]+|[\\r\\n][^\\r\\n]*)\\* \\* \\*"
  strings.count func_call "strings.count(body.current_thread.text, \"* * *\") == 2"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: 9WOLF phishkit initial landing URI

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

Detects links containing the '?ai=xd' query parameter associated with 9wolf phishing service initial landing pages.

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware
Tactics and techniquesEvasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
// known 9wolf initial landing uri struct
and any(body.links, strings.contains(.href_url.url, '?ai=xd'))

Detection logic

Scope: inbound message.

Detects links containing the '?ai=xd' query parameter associated with 9wolf phishing service initial landing pages.

  1. inbound message
  2. any of body.links where:
    • .href_url.url contains '?ai=xd'

Inspects: body.links, body.links[].href_url.url, type.inbound. Sensors: strings.contains.

Indicators matched (1)

FieldMatchValue
strings.containssubstring?ai=xd

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    body.links.href_url.url contains "?ai=xd"
  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"

Link: Abused Adobe Express

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

The detection rule matches on message groups which make use of Adobe Express as a landing page. The landing page contains links which are newly registered, use free file or subdomain hosts, url shortners or when visited are phishing pages, lead to a captcha or rediret to a top website.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Free subdomain host, Free file host

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(filter(body.links,
               // the link is a new.express.adobe.com page
               .href_url.domain.domain == "new.express.adobe.com"
               and strings.starts_with(.href_url.path, "/webpage/")
        ),
        // filter down the links on express.adobe.com page to those that are external to adobe
        // check that the length of external links is reasonable
        length(distinct(filter(ml.link_analysis(., mode="aggressive").final_dom.links,
                               // filter any links on the adobe express page which are
                               // on express.adobe.com
                               .href_url.domain.domain != 'new.express.adobe.com'
                               // or www.adobe.com (privacy page/report abuse/etc)
                               and .href_url.domain.domain != 'www.adobe.com'
                               // relative links (no domains)
                               and .href_url.domain.domain is not null
                        ),
                        .href_url.domain.domain
               )
        ) <= 10
        and any(filter(ml.link_analysis(., mode="aggressive").final_dom.links,
                       // filter any links on the adobe express page which are
                       // on express.adobe.com
                       .href_url.domain.domain != 'new.express.adobe.com'
                       // or www.adobe.com (privacy page/report abuse/etc)
                       and .href_url.domain.domain != 'www.adobe.com'
                       // relative links (no domains)
                       and .href_url.domain.domain is not null
                ),
                (
                  // any of those links domains are new
                  network.whois(.href_url.domain).days_old < 30

                  // go to free file hosts
                  or .href_url.domain.root_domain in $free_file_hosts
                  or .href_url.domain.domain in $free_file_hosts

                  // go to free subdomains hosts
                  or (
                    .href_url.domain.root_domain in $free_subdomain_hosts
                    // where there is a subdomain
                    and .href_url.domain.subdomain is not null
                    and .href_url.domain.subdomain != "www"
                  )
                  // go to url shortners
                  or .href_url.domain.root_domain in $url_shorteners
                  or .href_url.domain.root_domain in $social_landing_hosts
                  or .href_url.domain.domain in $url_shorteners
                  or .href_url.domain.domain in $social_landing_hosts
                  or (
                    // find any links that mention common "action" words
                    regex.icontains(.display_text,
                                    '(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)'
                    )
                    and (
                      // and when visiting those links, are phishing
                      ml.link_analysis(., mode="aggressive").credphish.disposition == "phishing"

                      // hit a captcha page
                      or ml.link_analysis(., mode="aggressive").credphish.contains_captcha

                      // or the page redirects to common website, observed when evasion happens
                      or (
                        length(ml.link_analysis(., mode="aggressive").redirect_history
                        ) > 0
                        and ml.link_analysis(., mode="aggressive").effective_url.domain.root_domain in $tranco_10k
                      )
                    )
                  )
                )
        )
)
and profile.by_sender().prevalence != "common"

Detection logic

Scope: inbound message.

The detection rule matches on message groups which make use of Adobe Express as a landing page. The landing page contains links which are newly registered, use free file or subdomain hosts, url shortners or when visited are phishing pages, lead to a captcha or rediret to a top website.

  1. inbound message
  2. any of filter(body.links) where all hold:
    • length(distinct(filter(ml.link_analysis(., mode='aggressive').final_dom.links, .href_url.domain.domain != 'new.express.adobe.com' and .href_url.domain.domain != 'www.adobe.com' and .href_url.domain.domain is not null), .href_url.domain.domain)) ≤ 10
    • any of filter(...) where any holds:
      • network.whois(.href_url.domain).days_old < 30
      • .href_url.domain.root_domain in $free_file_hosts
      • .href_url.domain.domain in $free_file_hosts
      • all of:
        • .href_url.domain.root_domain in $free_subdomain_hosts
        • .href_url.domain.subdomain is set
        • .href_url.domain.subdomain is not 'www'
      • .href_url.domain.root_domain in $url_shorteners
      • .href_url.domain.root_domain in $social_landing_hosts
      • .href_url.domain.domain in $url_shorteners
      • .href_url.domain.domain in $social_landing_hosts
      • all of:
        • .display_text matches '(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)'
        • any of:
          • ml.link_analysis(.).credphish.disposition is 'phishing'
          • ml.link_analysis(.).credphish.contains_captcha
          • all of:
            • length(ml.link_analysis(., mode='aggressive').redirect_history) > 0
            • ml.link_analysis(.).effective_url.domain.root_domain in $tranco_10k
  3. profile.by_sender().prevalence is not 'common'

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.path, type.inbound. Sensors: ml.link_analysis, network.whois, profile.by_sender, regex.icontains, strings.starts_with. Reference lists: $free_file_hosts, $free_subdomain_hosts, $social_landing_hosts, $tranco_10k, $url_shorteners.

Indicators matched (3)

FieldMatchValue
body.links[].href_url.domain.domainequalsnew.express.adobe.com
strings.starts_withprefix/webpage/
regex.icontainsregex(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)

Stages and Predicates

Stage 1: mql_rule

and
  any(filter(body.links))
    and
      any(filter(...))
        or
          and
            or
              and
                ml.link_analysis func_call "ml.link_analysis(filter(...)[]).effective_url.domain.root_domain in tranco_10k"
                ml.link_analysis(filter(...)[], mode='aggressive').redirect_history length_compare "0"
              ml.link_analysis func_call "ml.link_analysis(filter(...)[]).credphish.contains_captcha"
              ml.link_analysis func_call "ml.link_analysis(filter(...)[]).credphish.disposition == phishing"
            filter(...).display_text regex_match "(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)"
          and
            filter(...).href_url.domain.subdomain is_not_null
            filter(...).href_url.domain.subdomain ne "www"
             macro "filter(...)[].href_url.domain.root_domain in free_subdomain_hosts"
          network.whois func_call "network.whois(filter(...)[].href_url.domain).days_old < 30"
           macro "filter(...)[].href_url.domain.domain in free_file_hosts"
           macro "filter(...)[].href_url.domain.domain in social_landing_hosts"
           macro "filter(...)[].href_url.domain.domain in url_shorteners"
           macro "filter(...)[].href_url.domain.root_domain in free_file_hosts"
           macro "filter(...)[].href_url.domain.root_domain in social_landing_hosts"
           macro "filter(...)[].href_url.domain.root_domain in url_shorteners"
      distinct(filter(ml.link_analysis(filter(body.links)[], mode='aggressive').final_dom.links, filter(body.links)[].href_url.domain.domain != 'new.express.adobe.com' and filter(body.links)[].href_url.domain.domain != 'www.adobe.com' and filter(body.links)[].href_url.domain.domain is not null), filter(body.links)[].href_url.domain.domain) length_compare "10"
  profile.by_sender func_call "profile.by_sender().prevalence != common"
  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"

Link: Adobe share from unsolicited sender

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

This attack surface reduction rule matches on messages from Adobe which were sent by an email address (as determined by the sender display name) which doesn't appear to have a relationship with the recipient organization.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesFree file host, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
// from Adobe Actual
and strings.icontains(sender.display_name, 'via Adobe')
and sender.email.email == 'message@adobe.com'
and headers.auth_summary.dmarc.pass
// contains a link to open or review a share
and any(body.links, .display_text =~ "open" or .display_text =~ "review")
// attempt to ensure the sender (from the sender.display_name) does NOT have a relationship with to recipient org

// not sent from a Adobe User within the org's domains
and not any($org_domains,
            strings.icontains(sender.display_name,
                              strings.concat("@", ., ' via Adobe')
            )
)
// the org has never sent a message to the address within the sender.display_name
and not any($recipient_emails, strings.istarts_with(sender.display_name, .))

Detection logic

Scope: inbound message.

This attack surface reduction rule matches on messages from Adobe which were sent by an email address (as determined by the sender display name) which doesn't appear to have a relationship with the recipient organization.

  1. inbound message
  2. sender.display_name contains 'via Adobe'
  3. sender.email.email is 'message@adobe.com'
  4. headers.auth_summary.dmarc.pass
  5. any of body.links where any holds:
    • .display_text is 'open'
    • .display_text is 'review'
  6. not:
    • any of $org_domains where:
      • strings.icontains(sender.display_name)
  7. not:
    • any of $recipient_emails where:
      • strings.istarts_with(sender.display_name)

Inspects: body.links, body.links[].display_text, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.email, type.inbound. Sensors: strings.concat, strings.icontains, strings.istarts_with. Reference lists: $org_domains, $recipient_emails.

Indicators matched (4)

FieldMatchValue
strings.icontainssubstringvia Adobe
sender.email.emailequalsmessage@adobe.com
body.links[].display_textequalsopen
body.links[].display_textequalsreview

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    or
      body.links.display_text eq "open"
      body.links.display_text eq "review"
  not
    any($org_domains)
      strings.icontains func_call "strings.icontains(sender.display_name)"
  not
    any($recipient_emails)
      strings.istarts_with func_call "strings.istarts_with(sender.display_name)"
  headers.auth_summary.dmarc.pass eq "true"
  sender.display_name contains "via Adobe"
  sender.email.email eq "message@adobe.com"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
$org_domainsarray_any(no value, null check)excludes:$org_domains
$recipient_emailsarray_any(no value, null check)excludes:$recipient_emails

Indicators

These rows show field, operator, and value matches.

Link: Adobe share with suspicious indicators

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

The detection rule matches messages sent from Adobe and contain indicators of malicious use. The indicators include observed call to action phrases, suspicious filenames, all capital filenames, the sender's display name (as determined by NLU) included in the comment section, or Microsoft branding on the shared link.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Free file host

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
// from Adobe Actual
and strings.icontains(sender.display_name, 'via Adobe')
and sender.email.email == 'message@adobe.com'
and headers.auth_summary.dmarc.pass
// contains a link to open or review a share
and any(body.links, .display_text =~ "open" or .display_text =~ "review")

// not sent from a Adobe User within the org's domains
and not any($org_domains,
            strings.icontains(sender.display_name,
                              strings.concat("@", ., ' via Adobe')
            )
            // sometimes the email is in parentheses
            or strings.icontains(sender.display_name,
                                 strings.concat("@", ., ') via Adobe')
            )
)
and (
  // the comments observed wording, using the html to make sure it's in the actor controlled section of the message
  regex.icontains(body.html.raw,
                  '<tr>[\r\n]+<td style="color:#505050; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:18px; line-height:26px; padding-top:20px;">[\r\n]+<xmp style="font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:18px; line-height:26px overflow-x:auto; white-space:pre-wrap; white-space:-moz-pre-wrap; white-space:-pre-wrap; white-space:-o-pre-wrap; word-wrap:break-word;">Please review the attached below for your reference,'
  )
  // the filename shared
  or regex.icontains(body.html.raw,
                     // , ends in some random numbers
                     '<td style="color:#000000; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:24px; line-height:26px; padding-top:65px;">[\r\n]+<strong>[^\<]+<\/strong> (invited you to review|has shared) <strong>[^\<]+([]|[[:punct:]\s](?:AP|AR)?\d+[a-z]?)<\/strong></td>[\r\n]+</tr>'
  )
  // contains all capital letters, allowing for numbers
  or regex.contains(body.html.raw,
                    '<td style="color:#000000; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:24px; line-height:26px; padding-top:65px;">[\r\n]+<strong>[^\<]+<\/strong> (invited you to review|has shared) <strong>(?:[A-Z0-9_\-\s]+)<\/strong></td>[\r\n]+</tr>',
  )
  // contains commonly observed themes used by actors
  or regex.icontains(body.html.raw,
                     // , ends in some random numbers
                     '<td style=\"color:#000000; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:24px; line-height:26px; padding-top:65px;\">[\r\n]+<strong>[^\<]+<\/strong> invited you to review <strong>[^\<]*(Invoice|Payment|Agreement|Settlements|Overdue|Confidential|Transaction)[^\<]*<\/strong></td>[\r\n]+</tr>'
  )
  // the NLU detected "sender" is included within the body wrapped with new lines indicating it's a "signature"
  or any(filter(ml.nlu_classifier(body.current_thread.text).entities,
                .name == "sender"
                and .text not in ('Customer Support', 'SHARED ON')
                // in some cases the filename is detected as the sender
                // we can filter out this case when the detected "sender"
                // text is the file shared
                and not strings.icontains(body.current_thread.text,
                                          strings.concat("invited you to edit\n",
                                                         .text,
                                                         "\nOpen"
                                          )
                )
         ),
         strings.icontains(body.current_thread.text,
                           strings.concat("\n", .text, "\n")
         )
  )
  // finally we'll hit the actual page and see if we can get some enrichment functions to give up some gold
  or any(filter(body.links,
                .display_text =~ "open" or .display_text =~ "review"
         ),
         // detected as Microsoft
         any(ml.logo_detect(ml.link_analysis(., mode="aggressive").screenshot).brands,
             .name in ("Microsoft") and .confidence == "high"
         )
  )
)

Detection logic

Scope: inbound message.

The detection rule matches messages sent from Adobe and contain indicators of malicious use. The indicators include observed call to action phrases, suspicious filenames, all capital filenames, the sender's display name (as determined by NLU) included in the comment section, or Microsoft branding on the shared link.

  1. inbound message
  2. sender.display_name contains 'via Adobe'
  3. sender.email.email is 'message@adobe.com'
  4. headers.auth_summary.dmarc.pass
  5. any of body.links where any holds:
    • .display_text is 'open'
    • .display_text is 'review'
  6. not:
    • any of $org_domains where any holds:
      • strings.icontains(sender.display_name)
      • strings.icontains(sender.display_name)
  7. any of:
    • body.html.raw matches '<tr>[\\r\\n]+<td style="color:#505050; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:18px; line-height:26px; padding-top:20px;">[\\r\\n]+<xmp style="font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:18px; line-height:26px overflow-x:auto; white-space:pre-wrap; white-space:-moz-pre-wrap; white-space:-pre-wrap; white-space:-o-pre-wrap; word-wrap:break-word;">Please review the attached below for your reference,'
    • body.html.raw matches '<td style="color:#000000; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:24px; line-height:26px; padding-top:65px;">[\\r\\n]+<strong>[^\\<]+<\\/strong> (invited you to review|has shared) <strong>[^\\<]+([]|[[:punct:]\\s](?:AP|AR)?\\d+[a-z]?)<\\/strong></td>[\\r\\n]+</tr>'
    • body.html.raw matches '<td style="color:#000000; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:24px; line-height:26px; padding-top:65px;">[\\r\\n]+<strong>[^\\<]+<\\/strong> (invited you to review|has shared) <strong>(?:[A-Z0-9_\\-\\s]+)<\\/strong></td>[\\r\\n]+</tr>'
    • body.html.raw matches '<td style=\\"color:#000000; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:24px; line-height:26px; padding-top:65px;\\">[\\r\\n]+<strong>[^\\<]+<\\/strong> invited you to review <strong>[^\\<]*(Invoice|Payment|Agreement|Settlements|Overdue|Confidential|Transaction)[^\\<]*<\\/strong></td>[\\r\\n]+</tr>'
    • any of filter(...) where:
      • strings.icontains(body.current_thread.text)
    • any of filter(body.links) where:
      • any of ml.logo_detect(ml.link_analysis(., mode='aggressive').screenshot).brands where all hold:
        • .name in ('Microsoft')
        • .confidence is 'high'

Inspects: body.current_thread.text, body.html.raw, body.links, body.links[].display_text, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.email, type.inbound. Sensors: ml.link_analysis, ml.logo_detect, ml.nlu_classifier, regex.contains, regex.icontains, strings.concat, strings.icontains. Reference lists: $org_domains.

Indicators matched (11)

FieldMatchValue
strings.icontainssubstringvia Adobe
sender.email.emailequalsmessage@adobe.com
body.links[].display_textequalsopen
body.links[].display_textequalsreview
regex.icontainsregex<tr>[\r\n]+<td style="color:#505050; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:18px; line-height:26px; padding-top:20px;">[\r\n]+<xmp style="font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:18px; line-height:26px overflow-x:auto; white-space:pre-wrap; white-space:-moz-pre-wrap; white-space:-pre-wrap; white-space:-o-pre-wrap; word-wrap:break-word;">Please review the attached below for your reference,
regex.icontainsregex<td style="color:#000000; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:24px; line-height:26px; padding-top:65px;">[\r\n]+<strong>[^\<]+<\/strong> (invited you to review|has shared) <strong>[^\<]+([]|[[:punct:]\s](?:AP|AR)?\d+[a-z]?)<\/strong></td>[\r\n]+</tr>
regex.containsregex<td style="color:#000000; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:24px; line-height:26px; padding-top:65px;">[\r\n]+<strong>[^\<]+<\/strong> (invited you to review|has shared) <strong>(?:[A-Z0-9_\-\s]+)<\/strong></td>[\r\n]+</tr>
regex.icontainsregex<td style=\"color:#000000; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:24px; line-height:26px; padding-top:65px;\">[\r\n]+<strong>[^\<]+<\/strong> invited you to review <strong>[^\<]*(Invoice|Payment|Agreement|Settlements|Overdue|Confidential|Transaction)[^\<]*<\/strong></td>[\r\n]+</tr>
ml.nlu_classifier(body.current_thread.text).entities[].nameequalssender
ml.logo_detect(ml.link_analysis(filter(body.links)[], mode='aggressive').screenshot).brands[].namememberMicrosoft
ml.logo_detect(ml.link_analysis(filter(body.links)[], mode='aggressive').screenshot).brands[].confidenceequalshigh

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(filter(body.links))
      any(ml.logo_detect(ml.link_analysis(filter(body.links), mode='aggressive').screenshot).brands)
        and
          ml.logo_detect(ml.link_analysis(filter(body.links)[], mode='aggressive').screenshot).brands[].confidence eq "high"
          ml.logo_detect(ml.link_analysis(filter(body.links)[], mode='aggressive').screenshot).brands[].name eq "Microsoft"
    any(filter(...))
      strings.icontains func_call "strings.icontains(body.current_thread.text)"
    body.html.raw regex_match "<td style=\"color:#000000; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:24px; line-height:26px; padding-top:65px;\">[\\r\\n]+<strong>[^\\<]+<\\/strong> (invited you to review|has shared) <strong>(?:[A-Z0-9_\\-\\s]+)<\\/strong></td>[\\r\\n]+</tr>"
    body.html.raw regex_match "<td style=\"color:#000000; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:24px; line-height:26px; padding-top:65px;\">[\\r\\n]+<strong>[^\\<]+<\\/strong> (invited you to review|has shared) <strong>[^\\<]+([]|[[:punct:]\\s](?:AP|AR)?\\d+[a-z]?)<\\/strong></td>[\\r\\n]+</tr>"
    body.html.raw regex_match "<td style=\\\"color:#000000; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:24px; line-height:26px; padding-top:65px;\\\">[\\r\\n]+<strong>[^\\<]+<\\/strong> invited you to review <strong>[^\\<]*(Invoice|Payment|Agreement|Settlements|Overdue|Confidential|Transaction)[^\\<]*<\\/strong></td>[\\r\\n]+</tr>"
    body.html.raw regex_match "<tr>[\\r\\n]+<td style=\"color:#505050; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:18px; line-height:26px; padding-top:20px;\">[\\r\\n]+<xmp style=\"font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:18px; line-height:26px overflow-x:auto; white-space:pre-wrap; white-space:-moz-pre-wrap; white-space:-pre-wrap; white-space:-o-pre-wrap; word-wrap:break-word;\">Please review the attached below for your reference,"
  any(body.links)
    or
      body.links.display_text eq "open"
      body.links.display_text eq "review"
  not
    any($org_domains)
      strings.icontains func_call "strings.icontains(sender.display_name)"
  headers.auth_summary.dmarc.pass eq "true"
  sender.display_name contains "via Adobe"
  sender.email.email eq "message@adobe.com"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
$org_domainsarray_any(no value, null check)excludes:$org_domains

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.html.rawregex_match
  • <td style="color:#000000; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:24px; line-height:26px; padding-top:65px;">[\r\n]+<strong>[^\<]+<\/strong> (invited you to review|has shared) <strong>(?:[A-Z0-9_\-\s]+)<\/strong></td>[\r\n]+</tr>
  • <td style="color:#000000; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:24px; line-height:26px; padding-top:65px;">[\r\n]+<strong>[^\<]+<\/strong> (invited you to review|has shared) <strong>[^\<]+([]|[[:punct:]\s](?:AP|AR)?\d+[a-z]?)<\/strong></td>[\r\n]+</tr>
  • <td style=\"color:#000000; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:24px; line-height:26px; padding-top:65px;\">[\r\n]+<strong>[^\<]+<\/strong> invited you to review <strong>[^\<]*(Invoice|Payment|Agreement|Settlements|Overdue|Confidential|Transaction)[^\<]*<\/strong></td>[\r\n]+</tr>
  • <tr>[\r\n]+<td style="color:#505050; font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:18px; line-height:26px; padding-top:20px;">[\r\n]+<xmp style="font-family:adobe-clean, Helvetica Neue, Helvetica, Verdana, Arial, sans-serif; font-size:18px; line-height:26px overflow-x:auto; white-space:pre-wrap; white-space:-moz-pre-wrap; white-space:-pre-wrap; white-space:-o-pre-wrap; word-wrap:break-word;">Please review the attached below for your reference,
field:"body.html.raw" kind:regex_match
headers.auth_summary.dmarc.passeq
  • true transforms: boolean
field:"headers.auth_summary.dmarc.pass" kind:eq value:"true"
sender.display_namecontains
  • via Adobe
field:"sender.display_name" kind:contains value:"via Adobe"
sender.email.emaileq
  • message@adobe.com
field:"sender.email.email" kind:eq value:"message@adobe.com"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link: Apple App Store link to apps impersonating AI adveristing

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

Detects messages containing links to Apple App Store apps that impersonate popular AI services (OpenAI, ChatGPT, Meta, Gemini) and are categorized as advertising or management tools offered for free.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • type

Rule body

type.inbound
and any(filter(body.current_thread.links,
               .href_url.domain.domain in ('apps.apple.com')
        ),
        // testflight = <script name="schema:software-application" type="application/ld+json">
        // apps.apple.com = <script id="software-application" type="application/ld+json">
        any(html.xpath(ml.link_analysis(.).final_dom,
                       '//script[@id="software-application"][@type="application/ld+json"]'
            ).nodes,
            // extract just the value of this node and parse it as json
            any([
                  "openai",
                  "openal",
                  "open ai",
                  "open al",
                  "chatgpt",
                  "meta",
                  "gemini",
                  "gpt"
                ],
                strings.icontains(strings.parse_json(regex.iextract(..raw,
                                                                    '<script id="software-application" type="application/ld\+json">\s*(?P<app_overview>.*)\s+</script>'
                                                     )[0].named_groups["app_overview"]
                                  )["name"],
                                  .
                )
            )
            and regex.icontains(strings.parse_json(regex.iextract(.raw,
                                                                  '<script id="software-application" type="application/ld\+json">\s*(?P<app_overview>.*)\s+</script>'
                                                   )[0].named_groups["app_overview"]
                                )["name"],
                                '\b(?:suite|ads?|gpt|advert|manager?|campaigns?)'
            )
            and strings.parse_json(regex.iextract(.raw,
                                                  '<script id="software-application" type="application/ld\+json">\s*(?P<app_overview>.*)\s+</script>'
                                   )[0].named_groups["app_overview"]
            )["offers"]["category"] == "free"
        )
)

Detection logic

Scope: inbound message.

Detects messages containing links to Apple App Store apps that impersonate popular AI services (OpenAI, ChatGPT, Meta, Gemini) and are categorized as advertising or management tools offered for free.

  1. inbound message
  2. any of filter(body.current_thread.links) where:
    • any of html.xpath(ml.link_analysis(.).final_dom, '//script[@id="software-application"][@type="application/ld+json"]').nodes where all hold:
      • any of ['openai', 'openal', 'open ai', 'open al', 'chatgpt', 'meta', 'gemini', 'gpt'] where:
        • strings.icontains(strings.parse_json(regex.iextract(.raw, '<script id="software-application" type="application/ld\\+json">\\s*(?P<app_overview>.*)\\s+</script>')[0].named_groups['app_overview'])['name'])
      • strings.parse_json(regex.iextract(.raw, '<script id="software-application" type="application/ld\\+json">\\s*(?P<app_overview>.*)\\s+</script>')[0].named_groups['app_overview'])['name'] matches '\\b(?:suite|ads?|gpt|advert|manager?|campaigns?)'
      • strings.parse_json(regex.iextract(.raw, '<script id="software-application" type="application/ld\\+json">\\s*(?P<app_overview>.*)\\s+</script>')[0].named_groups['app_overview']).['offers']['category'] is 'free'

Inspects: body.current_thread.links, body.current_thread.links[].href_url.domain.domain, type.inbound. Sensors: html.xpath, ml.link_analysis, regex.icontains, regex.iextract, strings.icontains, strings.parse_json.

Indicators matched (3)

FieldMatchValue
body.current_thread.links[].href_url.domain.domainmemberapps.apple.com
regex.iextractregex<script id="software-application" type="application/ld\+json">\s*(?P<app_overview>.*)\s+</script>
regex.icontainsregex\b(?:suite|ads?|gpt|advert|manager?|campaigns?)

Stages and Predicates

Stage 1: mql_rule

and
  any(filter(body.current_thread.links))
    any(html.xpath(ml.link_analysis(filter(body.current_thread.links)).final_dom, '//script[@id="software-application"][@type="application/ld+json"]').nodes)
      and
        any(['openai', 'openal', 'open ai', 'open al', 'chatgpt', 'meta', 'gemini', 'gpt'])
          strings.icontains func_call "strings.icontains(strings.parse_json(regex.iextract(html.xpath(ml.link_analysis(filter(body.current_thread.links)[]).final_dom, '//script[@id=\"software-application\"][@type=\"application/ld+json\"]').nodes[].raw, '<script id=\"software-application\" type=\"application/ld\\\\+json\">\\\\s*(?P<app_overview>.*)\\\\s+</script>')[0].named_groups['app_overview'])['name'])"
        strings.parse_json func_call "strings.parse_json(regex.iextract(html.xpath(ml.link_analysis(filter(body.current_thread.links)[]).final_dom, '//script[@id=\"software-application\"][@type=\"application/ld+json\"]').nodes[].raw, '<script id=\"software-application\" type=\"application/ld\\\\+json\">\\\\s*(?P<app_overview>.*)\\\\s+</script>')[0].named_groups['app_overview']).['offers']['category'] == free"
        strings.parse_json(regex.iextract(html.xpath(ml.link_analysis(filter(body.current_thread.links)[]).final_dom, '//script[@id="software-application"][@type="application/ld+json"]').nodes[].raw, '<script id="software-application" type="application/ld\\+json">\\s*(?P<app_overview>.*)\\s+</script>')[0].named_groups['app_overview'])['name'] regex_match "\\b(?:suite|ads?|gpt|advert|manager?|campaigns?)"
  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"

Link: Apple App Store malicious ad manager themed apps from free email provider

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

Detects messages containing Apple App Store links with sent from free email providers, indicating potential abuse of legitimate Apple services hosting malicious ad manager themed applications.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, BEC/Fraud, Malware/Ransomware
Tactics and techniquesFree email provider, Social engineering, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
and any(body.current_thread.links,
        .href_url.domain.domain in ('apps.apple.com')
        and regex.icount(.href_url.path,
                         '[/-](?:suite|ads?|manager?|campaigns?)'
        ) >= 2
)
and sender.email.domain.domain in $free_email_providers

Detection logic

Scope: inbound message.

Detects messages containing Apple App Store links with sent from free email providers, indicating potential abuse of legitimate Apple services hosting malicious ad manager themed applications.

  1. inbound message
  2. any of body.current_thread.links where all hold:
    • .href_url.domain.domain in ('apps.apple.com')
    • regex.icount(.href_url.path, '[/-](?:suite|ads?|manager?|campaigns?)') ≥ 2
  3. sender.email.domain.domain in $free_email_providers

Inspects: body.current_thread.links, body.current_thread.links[].href_url.domain.domain, body.current_thread.links[].href_url.path, sender.email.domain.domain, type.inbound. Sensors: regex.icount. Reference lists: $free_email_providers.

Indicators matched (2)

FieldMatchValue
body.current_thread.links[].href_url.domain.domainmemberapps.apple.com
regex.icountregex[/-](?:suite|ads?|manager?|campaigns?)

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    and
      body.current_thread.links.href_url.domain.domain eq "apps.apple.com"
      regex.icount func_call "regex.icount(body.current_thread.links[].href_url.path, \"[/-](?:suite|ads?|manager?|campaigns?)\") >= 2"
  type.inbound eq "true"
   macro "sender.email.domain.domain in free_email_providers"

Indicators

These rows show field, operator, and value matches.

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

Link: Apple TestFlight from suspicious sender

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

Detects messages containing Apple TestFlight links from free email providers or suspicious senders with no prior benign communication history.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesFree email provider, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
and any(body.links,
        .href_url.domain.domain in ('testflight.apple.com')
        or (
          .href_url.domain.root_domain == "mimecastprotect.com"
          and any(.href_url.query_params_decoded['domain'],
                  . in ("testflight.apple.com")
          )
        )
)
and not (
  (subject.is_forward or subject.is_reply)
  and (length(headers.references) != 0 or headers.in_reply_to is not null)
  and length(body.previous_threads) > 0
)
and (
  sender.email.domain.domain in $free_email_providers
  or beta.profile.by_reply_to().solicited == false
  or (
    beta.profile.by_reply_to().any_messages_malicious_or_spam
    and not beta.profile.by_reply_to().any_messages_benign
  )
)

Detection logic

Scope: inbound message.

Detects messages containing Apple TestFlight links from free email providers or suspicious senders with no prior benign communication history.

  1. inbound message
  2. any of body.links where any holds:
    • .href_url.domain.domain in ('testflight.apple.com')
    • all of:
      • .href_url.domain.root_domain is 'mimecastprotect.com'
      • any of .href_url.query_params_decoded['domain'] where:
        • . in ('testflight.apple.com')
  3. not:
    • all of:
      • any of:
        • subject.is_forward
        • subject.is_reply
      • any of:
        • length(headers.references) is not 0
        • headers.in_reply_to is set
      • length(body.previous_threads) > 0
  4. any of:
    • sender.email.domain.domain in $free_email_providers
    • beta.profile.by_reply_to().solicited is False
    • all of:
      • beta.profile.by_reply_to().any_messages_malicious_or_spam
      • not:
        • beta.profile.by_reply_to().any_messages_benign

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.query_params_decoded['domain'], body.previous_threads, headers.in_reply_to, headers.references, sender.email.domain.domain, subject.is_forward, subject.is_reply, type.inbound. Sensors: beta.profile.by_reply_to. Reference lists: $free_email_providers.

Indicators matched (3)

FieldMatchValue
body.links[].href_url.domain.domainmembertestflight.apple.com
body.links[].href_url.domain.root_domainequalsmimecastprotect.com
body.links[].href_url.query_params_decoded['domain'][]membertestflight.apple.com

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    or
      and
        any(body.links.href_url.query_params_decoded['domain'])
          body.links.href_url.query_params_decoded['domain'] eq "testflight.apple.com"
        body.links.href_url.domain.root_domain eq "mimecastprotect.com"
      body.links.href_url.domain.domain eq "testflight.apple.com"
  or
    and
      not
        beta.profile.by_reply_to func_call "beta.profile.by_reply_to().any_messages_benign"
      beta.profile.by_reply_to func_call "beta.profile.by_reply_to().any_messages_malicious_or_spam"
    beta.profile.by_reply_to func_call "beta.profile.by_reply_to().solicited == false"
     macro "sender.email.domain.domain in free_email_providers"
  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"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
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"

Indicators

These rows show field, operator, and value matches.

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

Link: Base64 encoded recipient address in URL fragment with hex subdomain

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

Detects links containing a 40-character hexadecimal subdomain with the recipient's email address base64 encoded in the URL fragment, a technique used to personalize malicious links and evade detection.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • recipients
  • recipients.to[0]
  • type

Rule body

type.inbound
and any(body.links,
        length(.href_url.domain.subdomain) == 40
        and regex.match(.href_url.domain.subdomain, '^[a-f0-9]{40}')
        and any(strings.scan_base64(.href_url.fragment),
                . == recipients.to[0].email.email
        )
)

Detection logic

Scope: inbound message.

Detects links containing a 40-character hexadecimal subdomain with the recipient's email address base64 encoded in the URL fragment, a technique used to personalize malicious links and evade detection.

  1. inbound message
  2. any of body.links where all hold:
    • length(.href_url.domain.subdomain) is 40
    • .href_url.domain.subdomain matches '^[a-f0-9]{40}'
    • any of strings.scan_base64(.href_url.fragment) where:
      • . is recipients.to[0].email.email

Inspects: body.links, body.links[].href_url.domain.subdomain, body.links[].href_url.fragment, recipients.to[0].email.email, type.inbound. Sensors: regex.match, strings.scan_base64.

Indicators matched (1)

FieldMatchValue
regex.matchregex^[a-f0-9]{40}

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      any(strings.scan_base64(body.links.href_url.fragment))
        strings.scan_base64(body.links.href_url.fragment) cross_field_compare "recipients.to[0].email.email"
      body.links.href_url.domain.subdomain length_compare "40"
      body.links.href_url.domain.subdomain regex_match "^[a-f0-9]{40}"
  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"

Link: Base64 encoded recipient address in URL fragment with subject hash

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

Detects messages containing an alphanumeric string that is between 32 and 64 characters in the subject line that corresponds to a URL fragment containing the recipient's email address encoded in base64. This technique is commonly used to personalize malicious links and evade detection by embedding the target's email address within the URL structure.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEncryption, Evasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • recipients
  • recipients.to[0]
  • subject
  • type

Rule body

type.inbound
and any(regex.iextract(subject.subject,
                       '[^a-z0-9](?P<string>[a-z0-9]{32,64})(?:$|[^a-z0-9])'
        ),
        any(body.links,
            strings.contains(.href_url.fragment, ..named_groups["string"])
            and any(strings.scan_base64(.href_url.fragment),
                    strings.contains(., recipients.to[0].email.email)
            )
        )
)

Detection logic

Scope: inbound message.

Detects messages containing an alphanumeric string that is between 32 and 64 characters in the subject line that corresponds to a URL fragment containing the recipient's email address encoded in base64. This technique is commonly used to personalize malicious links and evade detection by embedding the target's email address within the URL structure.

  1. inbound message
  2. any of regex.iextract(subject.subject) where:
    • any of body.links where all hold:
      • strings.contains(.href_url.fragment)
      • any of strings.scan_base64(.href_url.fragment) where:
        • strings.contains(.)

Inspects: body.links, body.links[].href_url.fragment, recipients.to[0].email.email, subject.subject, type.inbound. Sensors: regex.iextract, strings.contains, strings.scan_base64.

Indicators matched (1)

FieldMatchValue
regex.iextractregex[^a-z0-9](?P<string>[a-z0-9]{32,64})(?:$|[^a-z0-9])

Stages and Predicates

Stage 1: mql_rule

and
  any(regex.iextract(subject.subject))
    any(body.links)
      and
        any(strings.scan_base64(body.links.href_url.fragment))
          strings.contains func_call "strings.contains(strings.scan_base64(body.links[].href_url.fragment)[])"
        strings.contains func_call "strings.contains(body.links[].href_url.fragment)"
  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"

Link: BEC with newly registered domains and financial keywords

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

Detects Business Email Compromise attacks containing links to newly registered domains (less than 60 days old) with invoice-related language and engaging action words. The message includes financial or payment terminology and prompts the recipient to take action through suspicious links. Uses natural language processing to identify credential theft or BEC intent while filtering out benign communications.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesSocial engineering, Evasion, Spoofing

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 0 < length(body.current_thread.links) < 15
and any(body.current_thread.links,
        network.whois(.href_url.domain).days_old < 60
        and regex.icontains(.display_text,
                            '(?:view|click|download|check|validate)'
        )
)
and regex.icontains(subject.base,
                    '\b(?:proposal|purchase|invoice|payment|wire|agreement|contract|settlement)\b'
)
and regex.icontains(body.current_thread.text,
                    '\bwire\b',
                    'payment',
                    'invoice',
                    '\bACH\b',
                    'kindly',
                    'document',
                    'urgent',
                    'confirm'
)
and (
  any(ml.nlu_classifier(body.current_thread.text).intents,
      .name in ("cred_theft", "bec") and .confidence != "low"
  )
  or any(ml.nlu_classifier(body.current_thread.text).tags,
         .name in ("invoice", "payment")
  )
)
// prevent benign emails
and not any(ml.nlu_classifier(body.current_thread.text).intents,
            .name == "benign"
)
// 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 Business Email Compromise attacks containing links to newly registered domains (less than 60 days old) with invoice-related language and engaging action words. The message includes financial or payment terminology and prompts the recipient to take action through suspicious links. Uses natural language processing to identify credential theft or BEC intent while filtering out benign communications.

  1. inbound message
  2. all of:
    • length(body.current_thread.links) > 0
    • length(body.current_thread.links) < 15
  3. any of body.current_thread.links where all hold:
    • network.whois(.href_url.domain).days_old < 60
    • .display_text matches '(?:view|click|download|check|validate)'
  4. subject.base matches '\\b(?:proposal|purchase|invoice|payment|wire|agreement|contract|settlement)\\b'
  5. body.current_thread.text matches any of 8 patterns
    • \bwire\b
    • payment
    • invoice
    • \bACH\b
    • kindly
    • document
    • urgent
    • confirm
  6. any of:
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name in ('cred_theft', 'bec')
      • .confidence is not 'low'
    • any of ml.nlu_classifier(body.current_thread.text).tags where:
      • .name in ('invoice', 'payment')
  7. not:
    • any of ml.nlu_classifier(body.current_thread.text).intents where:
      • .name is 'benign'
  8. 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, body.current_thread.text, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, subject.base, type.inbound. Sensors: ml.nlu_classifier, network.whois, regex.icontains. Reference lists: $high_trust_sender_root_domains.

Indicators matched (14)

FieldMatchValue
regex.icontainsregex(?:view|click|download|check|validate)
regex.icontainsregex\b(?:proposal|purchase|invoice|payment|wire|agreement|contract|settlement)\b
regex.icontainsregex\bwire\b
regex.icontainsregexpayment
regex.icontainsregexinvoice
regex.icontainsregex\bACH\b
regex.icontainsregexkindly
regex.icontainsregexdocument
regex.icontainsregexurgent
regex.icontainsregexconfirm
ml.nlu_classifier(body.current_thread.text).intents[].namemembercred_theft
ml.nlu_classifier(body.current_thread.text).intents[].namememberbec
2 more
ml.nlu_classifier(body.current_thread.text).tags[].namememberinvoice
ml.nlu_classifier(body.current_thread.text).tags[].namememberpayment

Stages and Predicates

Stage 1: mql_rule

and
  or
    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 in ["bec", "cred_theft"]
    any(ml.nlu_classifier(body.current_thread.text).tags)
      ml.nlu_classifier(body.current_thread.text).tags.name in ["invoice", "payment"]
  any(body.current_thread.links)
    and
      body.current_thread.links.display_text regex_match "(?:view|click|download|check|validate)"
      network.whois func_call "network.whois(body.current_thread.links[].href_url.domain).days_old < 60"
  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(ml.nlu_classifier(body.current_thread.text).intents)
      ml.nlu_classifier(body.current_thread.text).intents.name eq "benign"
  or
    body.current_thread.text regex_match "\\bACH\\b"
    body.current_thread.text regex_match "\\bwire\\b"
    body.current_thread.text regex_match "confirm"
    body.current_thread.text regex_match "document"
    body.current_thread.text regex_match "invoice"
    body.current_thread.text regex_match "kindly"
    body.current_thread.text regex_match "payment"
    body.current_thread.text regex_match "urgent"
  body.current_thread.links length_compare "0"
  body.current_thread.links length_compare "15"
  subject.base regex_match "\\b(?:proposal|purchase|invoice|payment|wire|agreement|contract|settlement)\\b"
  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

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textregex_match
  • \bACH\b
  • \bwire\b
  • confirm
  • document
  • invoice
  • kindly
  • payment
  • urgent
field:"body.current_thread.text" kind:regex_match
subject.baseregex_match
  • \b(?:proposal|purchase|invoice|payment|wire|agreement|contract|settlement)\b
field:"subject.base" kind:regex_match value:"\b(?:proposal|purchase|invoice|payment|wire|agreement|contract|settlement)\b"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link: Blogspot hosting explicit romance content

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

Detects inbound messages containing links to Blogspot domains that host explicit romance content, identified through natural language processing of the message body.

Threat classification

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

CategoryValues
Attack typesSpam
Tactics and techniquesFree subdomain host, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.links
  • type

Rule body

type.inbound
and any(body.links, .href_url.domain.root_domain == "blogspot.com")
and (
  any(ml.nlu_classifier(body.current_thread.text).topics,
      .name == "Sexually Explicit Messages"
  )
)

Detection logic

Scope: inbound message.

Detects inbound messages containing links to Blogspot domains that host explicit romance content, identified through natural language processing of the message body.

  1. inbound message
  2. any of body.links where:
    • .href_url.domain.root_domain is 'blogspot.com'
  3. any of ml.nlu_classifier(body.current_thread.text).topics where:
    • .name is 'Sexually Explicit Messages'

Inspects: body.current_thread.text, body.links, body.links[].href_url.domain.root_domain, type.inbound. Sensors: ml.nlu_classifier.

Indicators matched (2)

FieldMatchValue
body.links[].href_url.domain.root_domainequalsblogspot.com
ml.nlu_classifier(body.current_thread.text).topics[].nameequalsSexually Explicit Messages

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    body.links.href_url.domain.root_domain eq "blogspot.com"
  any(ml.nlu_classifier(body.current_thread.text).topics)
    ml.nlu_classifier(body.current_thread.text).topics.name eq "Sexually Explicit Messages"
  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"

Link: chatbot.page platform abuse

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

Detects abuse of chatbot.page where configurations suggest malicious intent, including incomplete contact information, free-tier usage, and suspicious question content.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering, Out of band pivot

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and length(filter(body.links, .href_url.domain.domain == "chatbot.page")) == 1
and any(body.links,
        .href_url.domain.domain == "chatbot.page"
        // pull out the <script> block that contains the JSON
        and (
          any(html.xpath(ml.link_analysis(.).final_dom,
                         '//script[contains(text(), "window.form")]'
              ).nodes,
              // parse out the JSON
              any(regex.extract(.raw, 'window.form = (?P<json>{.*})'),
                  // user didn't fill out any contact info, indicative of abuse
                  // a legitimate business would complete this information
                  strings.parse_json(.named_groups['json'])['emailSignature']['name'] == 'John Doe'
                  // a legitimate business would likely not be on the free plan
                  or strings.parse_json(.named_groups['json'])['config']['userPlan'] == 'free'
                  or (
                    // only 1 question
                    length(strings.parse_json(.named_groups['json'])['questions']
                    ) == 1
                    // pull out the link(s) in the question
                    and any(strings.parse_json(.named_groups['json'])['questions'],
                            any(.['links'],
                                // NLU on link display text
                                any(ml.nlu_classifier(.['text']).intents,
                                    .name == "cred_theft"
                                )
                                // LA on the link itself
                                or ml.link_analysis(strings.parse_url(.['value']
                                                    ),
                                                    mode="aggressive"
                                ).credphish.disposition == "phishing"
                            )
                    )
                  )
              )
          )
          or strings.icontains(ml.link_analysis(.).final_dom.display_text,
                               "This chatbot has been blocked by the administrator"
          )
        )
)

Detection logic

Scope: inbound message.

Detects abuse of chatbot.page where configurations suggest malicious intent, including incomplete contact information, free-tier usage, and suspicious question content.

  1. inbound message
  2. length(filter(body.links, .href_url.domain.domain == 'chatbot.page')) is 1
  3. any of body.links where all hold:
    • .href_url.domain.domain is 'chatbot.page'
    • any of:
      • any of html.xpath(ml.link_analysis(.).final_dom, '//script[contains(text(), "window.form")]').nodes where:
        • any of regex.extract(.raw) where any holds:
          • strings.parse_json(.named_groups['json']).['emailSignature']['name'] is 'John Doe'
          • strings.parse_json(.named_groups['json']).['config']['userPlan'] is 'free'
          • all of:
            • length(strings.parse_json(.named_groups['json'])['questions']) is 1
            • any of strings.parse_json(.named_groups['json'])['questions'] where:
              • any of .['links'] where any holds:
                • any of ml.nlu_classifier(.['text']).intents where:
                  • .name is 'cred_theft'
                • ml.link_analysis(strings.parse_url(.['value'])).credphish.disposition is 'phishing'
      • ml.link_analysis(.).final_dom.display_text contains 'This chatbot has been blocked by the administrator'

Inspects: body.links, body.links[].href_url.domain.domain, type.inbound. Sensors: html.xpath, ml.link_analysis, ml.nlu_classifier, regex.extract, strings.icontains, strings.parse_json, strings.parse_url.

Indicators matched (4)

FieldMatchValue
body.links[].href_url.domain.domainequalschatbot.page
regex.extractregexwindow.form = (?P<json>{.*})
ml.nlu_classifier(strings.parse_json(regex.extract(html.xpath(ml.link_analysis(body.links[]).final_dom, '//script[contains(text(), "window.form")]').nodes[].raw)[].named_groups['json'])['questions'][]['links'][]['text']).intents[].nameequalscred_theft
strings.icontainssubstringThis chatbot has been blocked by the administrator

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        any(html.xpath(ml.link_analysis(body.links).final_dom, '//script[contains(text(), "window.form")]').nodes)
          any(regex.extract(html.xpath(ml.link_analysis(body.links).final_dom, '//script[contains(text(), "window.form")]').nodes.raw))
            or
              and
                any(strings.parse_json(regex.extract(html.xpath(ml.link_analysis(body.links).final_dom, '//script[contains(text(), "window.form")]').nodes.raw).named_groups['json'])['questions'])
                  any(strings.parse_json(regex.extract(html.xpath(ml.link_analysis(body.links).final_dom, '//script[contains(text(), "window.form")]').nodes.raw).named_groups['json'])['questions']['links'])
                    or
                      any(ml.nlu_classifier(strings.parse_json(regex.extract(html.xpath(ml.link_analysis(body.links).final_dom, '//script[contains(text(), "window.form")]').nodes.raw).named_groups['json'])['questions']['links']['text']).intents)
                        ml.nlu_classifier(strings.parse_json(regex.extract(html.xpath(ml.link_analysis(body.links).final_dom, '//script[contains(text(), "window.form")]').nodes.raw).named_groups['json'])['questions']['links']['text']).intents.name eq "cred_theft"
                      ml.link_analysis func_call "ml.link_analysis(strings.parse_url(strings.parse_json(regex.extract(html.xpath(ml.link_analysis(body.links[]).final_dom, '//script[contains(text(), \"window.form\")]').nodes[].raw)[].named_groups['json'])['questions'][]['links'][]['value'])).credphish.disposition == phishing"
                strings.parse_json(regex.extract(html.xpath(ml.link_analysis(body.links[]).final_dom, '//script[contains(text(), "window.form")]').nodes[].raw)[].named_groups['json'])['questions'] length_compare "1"
              strings.parse_json func_call "strings.parse_json(regex.extract(html.xpath(ml.link_analysis(body.links[]).final_dom, '//script[contains(text(), \"window.form\")]').nodes[].raw)[].named_groups['json']).['config']['userPlan'] == free"
              strings.parse_json func_call "strings.parse_json(regex.extract(html.xpath(ml.link_analysis(body.links[]).final_dom, '//script[contains(text(), \"window.form\")]').nodes[].raw)[].named_groups['json']).['emailSignature']['name'] == John Doe"
        ml.link_analysis(body.links[]).final_dom.display_text contains "This chatbot has been blocked by the administrator"
      body.links.href_url.domain.domain eq "chatbot.page"
  filter(body.links, .href_url.domain.domain == 'chatbot.page') length_compare "1"
  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"

Link: Common hidden directory observed

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

Links in the message point to sensitive system directories like .git, .env, or .well-known that could expose confidential configuration data or system files. Actors will often abuse these directories to hide credential phishing landing pages of compromised sites.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion

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 0 < length(body.links) <= 10
and any(body.links,
        (
          strings.icontains(.href_url.path, "/.well-known/")
          and (
            // well-known with a directory behind it
            (
              regex.icontains(.href_url.path, '\/\.well-known\/[^\/]+\/')
              // doesn't contain anything after /pki-validation/ or contains godaddy.html after (which is their location for the validation)
              and not regex.imatch(.href_url.path,
                                   '/.well-known/pki-validation/(?:godaddy.html)?'
              )
            )
            // or a fragment in the url
            or .href_url.fragment is not null
          )
        )
        or strings.icontains(.href_url.path, "/.js/")
        or strings.icontains(.href_url.path, "/.env/")
        or strings.icontains(.href_url.path, "/.git/")
        or strings.icontains(.href_url.path, "/.svn/")
        or strings.icontains(.href_url.path, "/.hg/")
        or strings.icontains(.href_url.path, "/.DS_Store/")
        or strings.icontains(.href_url.path, "/.htpasswd/")
        or strings.icontains(.href_url.path, "/.htaccess/")
        or strings.icontains(.href_url.path, "/.bash_history/")
        or strings.icontains(.href_url.path, "/.bashrc/")
        or strings.icontains(.href_url.path, "/.zshrc/")
        or strings.icontains(.href_url.path, "/.profile/")
        or strings.icontains(.href_url.path, "/.wp/")
)
// 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.

Links in the message point to sensitive system directories like .git, .env, or .well-known that could expose confidential configuration data or system files. Actors will often abuse these directories to hide credential phishing landing pages of compromised sites.

  1. inbound message
  2. all of:
    • length(body.links) > 0
    • length(body.links) ≤ 10
  3. any of body.links where any holds:
    • all of:
      • .href_url.path contains '/.well-known/'
      • any of:
        • all of:
          • .href_url.path matches '\\/\\.well-known\\/[^\\/]+\\/'
          • not:
            • .href_url.path matches '/.well-known/pki-validation/(?:godaddy.html)?'
        • .href_url.fragment is set
    • .href_url.path contains '/.js/'
    • .href_url.path contains '/.env/'
    • .href_url.path contains '/.git/'
    • .href_url.path contains '/.svn/'
    • .href_url.path contains '/.hg/'
    • .href_url.path contains '/.DS_Store/'
    • .href_url.path contains '/.htpasswd/'
    • .href_url.path contains '/.htaccess/'
    • .href_url.path contains '/.bash_history/'
    • .href_url.path contains '/.bashrc/'
    • .href_url.path contains '/.zshrc/'
    • .href_url.path contains '/.profile/'
    • .href_url.path contains '/.wp/'
  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.links, body.links[].href_url.fragment, body.links[].href_url.path, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: regex.icontains, regex.imatch, strings.icontains. Reference lists: $high_trust_sender_root_domains.

Indicators matched (15)

FieldMatchValue
strings.icontainssubstring/.well-known/
regex.icontainsregex\/\.well-known\/[^\/]+\/
strings.icontainssubstring/.js/
strings.icontainssubstring/.env/
strings.icontainssubstring/.git/
strings.icontainssubstring/.svn/
strings.icontainssubstring/.hg/
strings.icontainssubstring/.DS_Store/
strings.icontainssubstring/.htpasswd/
strings.icontainssubstring/.htaccess/
strings.icontainssubstring/.bash_history/
strings.icontainssubstring/.bashrc/
3 more
strings.icontainssubstring/.zshrc/
strings.icontainssubstring/.profile/
strings.icontainssubstring/.wp/

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    or
      and
        or
          and
            not
              body.links.href_url.path regex_match "/.well-known/pki-validation/(?:godaddy.html)?"
            body.links.href_url.path regex_match "\\/\\.well-known\\/[^\\/]+\\/"
          body.links.href_url.fragment is_not_null
        body.links.href_url.path contains "/.well-known/"
      body.links.href_url.path contains "/.DS_Store/"
      body.links.href_url.path contains "/.bash_history/"
      body.links.href_url.path contains "/.bashrc/"
      body.links.href_url.path contains "/.env/"
      body.links.href_url.path contains "/.git/"
      body.links.href_url.path contains "/.hg/"
      body.links.href_url.path contains "/.htaccess/"
      body.links.href_url.path contains "/.htpasswd/"
      body.links.href_url.path contains "/.js/"
      body.links.href_url.path contains "/.profile/"
      body.links.href_url.path contains "/.svn/"
      body.links.href_url.path contains "/.wp/"
      body.links.href_url.path contains "/.zshrc/"
  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"
  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"

Link: Commonly Abused Web Service redirecting to ZIP file

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

Detects messages containing links from URL shorteners, free file hosts, or suspicious domains that redirect to ZIP file downloads, potentially indicating malware distribution.

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware
Tactics and techniquesFree file host, Free subdomain host, Open redirect, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • recipients
  • recipients.to[0]
  • type

Rule body

type.inbound
and 0 < length(body.links) < 15
and length(recipients.to) == 1
and recipients.to[0].email.domain.valid
and any(body.links,
        (
          // root domain is commonly abused
          .href_url.domain.root_domain in $url_shorteners
          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 $self_service_creation_platform_domains
          or .href_url.domain.tld in $suspicious_tlds
          // or somewhat recently reg'd domain
          or network.whois(.href_url.domain).days_old < 30
        )
        // we DONT want the original link to end in zip
        and not strings.iends_with(.href_url.url, '.zip')
        // we DO want the effective (redirected) url to end in zip
        and strings.iends_with(ml.link_analysis(.).effective_url.url, '.zip')
)

Detection logic

Scope: inbound message.

Detects messages containing links from URL shorteners, free file hosts, or suspicious domains that redirect to ZIP file downloads, potentially indicating malware distribution.

  1. inbound message
  2. all of:
    • length(body.links) > 0
    • length(body.links) < 15
  3. length(recipients.to) is 1
  4. recipients.to[0].email.domain.valid
  5. any of body.links where all hold:
    • any of:
      • .href_url.domain.root_domain in $url_shorteners
      • .href_url.domain.root_domain in $free_file_hosts
      • .href_url.domain.root_domain in $free_subdomain_hosts
      • .href_url.domain.root_domain in $self_service_creation_platform_domains
      • .href_url.domain.tld in $suspicious_tlds
      • network.whois(.href_url.domain).days_old < 30
    • not:
      • .href_url.url ends with '.zip'
    • ml.link_analysis(.).effective_url.url ends with '.zip'

Inspects: body.links, body.links[].href_url.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.tld, body.links[].href_url.url, recipients.to, recipients.to[0].email.domain.valid, type.inbound. Sensors: ml.link_analysis, network.whois, strings.iends_with. Reference lists: $free_file_hosts, $free_subdomain_hosts, $self_service_creation_platform_domains, $suspicious_tlds, $url_shorteners.

Indicators matched (1)

FieldMatchValue
strings.iends_withsuffix.zip

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      not
        body.links.href_url.url ends_with ".zip"
      or
        network.whois func_call "network.whois(body.links[].href_url.domain).days_old < 30"
         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"
         macro "body.links[].href_url.domain.tld in suspicious_tlds"
      ml.link_analysis(body.links[]).effective_url.url ends_with ".zip"
  body.links length_compare "0"
  body.links length_compare "15"
  recipients.to length_compare "1"
  recipients.to[0].email.domain.valid eq "true"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Compromised WordPress site redirecting to suspicious root domain

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

Inbound messages contain links routing through compromised WordPress installations (matching paths such as /wp-admin, /wp-includes, or /wp-content) that ultimately redirect to the root of an unrelated domain with no query parameters. The lure theme across observed samples centers on urgency around agreement review, document signing, and fund/profit notifications — designed to pressure recipients into clicking. The redirect pattern, combined with WordPress path indicators, suggests adversaries are abusing vulnerable WordPress sites as an intermediary hop to obscure the true destination.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, BEC/Fraud
Tactics and techniquesOpen redirect, Evasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • type

Rule body

type.inbound
and any(filter(body.current_thread.links,
               regex.icontains(.href_url.path,
                               '^\/wp-(?:admin|includes|content)'
               )
               // remove "the newsletter plugin" encoded URLs
               and not (
                 .href_url.path == "/wp-admin/admin-ajax.php"
                 and .href_url.query_params_decoded["action"][0] == "tnptr"
                 and 'nltr' in keys(.href_url.query_params_decoded)
               )
        ),
        // redirected to a page that is a "root" page
        any(ml.link_analysis(.).redirect_history,
            .path == "/"
            and .domain.root_domain != ..href_url.domain.root_domain
            // no query_params
            and (.query_params == "" or .query_params is null)
            and (.domain.subdomain is null or .domain.subdomain == "www")
        )
)

Detection logic

Scope: inbound message.

Inbound messages contain links routing through compromised WordPress installations (matching paths such as /wp-admin, /wp-includes, or /wp-content) that ultimately redirect to the root of an unrelated domain with no query parameters. The lure theme across observed samples centers on urgency around agreement review, document signing, and fund/profit notifications — designed to pressure recipients into clicking. The redirect pattern, combined with WordPress path indicators, suggests adversaries are abusing vulnerable WordPress sites as an intermediary hop to obscure the true destination.

  1. inbound message
  2. any of filter(body.current_thread.links) where:
    • any of ml.link_analysis(.).redirect_history where all hold:
      • .path is '/'
      • .domain.root_domain is not .href_url.domain.root_domain
      • any of:
        • .query_params is ''
        • .query_params is missing
      • any of:
        • .domain.subdomain is missing
        • .domain.subdomain is 'www'

Inspects: body.current_thread.links, body.current_thread.links[].href_url.path, body.current_thread.links[].href_url.query_params_decoded, body.current_thread.links[].href_url.query_params_decoded['action'][0], type.inbound. Sensors: ml.link_analysis, regex.icontains.

Indicators matched (4)

FieldMatchValue
regex.icontainsregex^\/wp-(?:admin|includes|content)
ml.link_analysis(filter(body.current_thread.links)[]).redirect_history[].pathequals/
ml.link_analysis(filter(body.current_thread.links)[]).redirect_history[].query_paramsequals
ml.link_analysis(filter(body.current_thread.links)[]).redirect_history[].domain.subdomainequalswww

Stages and Predicates

Stage 1: mql_rule

and
  any(filter(body.current_thread.links))
    any(ml.link_analysis(filter(body.current_thread.links)).redirect_history)
      and
        or
          ml.link_analysis(filter(body.current_thread.links)[]).redirect_history[].domain.subdomain eq "www"
          ml.link_analysis(filter(body.current_thread.links)[]).redirect_history[].domain.subdomain is_null
        or
          ml.link_analysis(filter(body.current_thread.links)[]).redirect_history[].query_params eq ""
          ml.link_analysis(filter(body.current_thread.links)[]).redirect_history[].query_params is_null
        ml.link_analysis(filter(body.current_thread.links)[]).redirect_history[].domain.root_domain cross_field_compare "filter(body.current_thread.links).href_url.domain.root_domain"
        ml.link_analysis(filter(body.current_thread.links)[]).redirect_history[].path eq "/"
  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"

Link: Concatenated display text concealing duplicate URLs with PDF reference

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

Detects messages where two identical links are displayed as a single continuous text string, with the second link containing 'PDF' in its display text. This technique can be used to obscure the true nature of links by making them appear as legitimate document references.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • type

Rule body

type.inbound
and strings.contains(body.current_thread.text,
                     strings.concat(body.current_thread.links[0].display_text,
                                    body.current_thread.links[1].display_text
                     )
)
and body.current_thread.links[0].href_url.url == body.current_thread.links[1].href_url.url
and strings.icontains(body.current_thread.links[1].display_text, 'pdf')

Detection logic

Scope: inbound message.

Detects messages where two identical links are displayed as a single continuous text string, with the second link containing 'PDF' in its display text. This technique can be used to obscure the true nature of links by making them appear as legitimate document references.

  1. inbound message
  2. strings.contains(body.current_thread.text)
  3. body.current_thread.links[0].href_url.url is body.current_thread.links[1].href_url.url
  4. body.current_thread.links[1].display_text contains 'pdf'

Inspects: body.current_thread.links[0].display_text, body.current_thread.links[0].href_url.url, body.current_thread.links[1].display_text, body.current_thread.links[1].href_url.url, body.current_thread.text, type.inbound. Sensors: strings.concat, strings.contains, strings.icontains.

Indicators matched (1)

FieldMatchValue
strings.icontainssubstringpdf

Stages and Predicates

Stage 1: mql_rule

and
  body.current_thread.links[0].href_url.url cross_field_compare "body.current_thread.links[1].href_url.url"
  body.current_thread.links[1].display_text contains "pdf"
  strings.contains func_call "strings.contains(body.current_thread.text)"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Credential phishing link with undisclosed recipients

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

This rule detects messages with "Undisclosed Recipients" that contain a link to a credential phishing page.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
and (
  // No Recipients
  length(recipients.to) == 0
  or all(recipients.to, .display_name == "Undisclosed recipients")
)
and length(recipients.cc) == 0
and length(recipients.bcc) == 0
and any(body.links,
        ml.link_analysis(.).credphish.disposition == "phishing"
        and ml.link_analysis(.).credphish.confidence in ("medium", "high")
)
// 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.

This rule detects messages with "Undisclosed Recipients" that contain a link to a credential phishing page.

  1. inbound message
  2. any of:
    • length(recipients.to) is 0
    • all of recipients.to where:
      • .display_name is 'Undisclosed recipients'
  3. length(recipients.cc) is 0
  4. length(recipients.bcc) is 0
  5. any of body.links where all hold:
    • ml.link_analysis(.).credphish.disposition is 'phishing'
    • ml.link_analysis(.).credphish.confidence in ('medium', 'high')
  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().solicited
  8. not:
    • profile.by_sender().any_messages_benign

Inspects: body.links, headers.auth_summary.dmarc.pass, recipients.bcc, recipients.cc, recipients.to, recipients.to[].display_name, sender.email.domain.root_domain, type.inbound. Sensors: ml.link_analysis, profile.by_sender. Reference lists: $high_trust_sender_root_domains.

Indicators matched (1)

FieldMatchValue
recipients.to[].display_nameequalsUndisclosed recipients

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(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"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  not
    profile.by_sender func_call "profile.by_sender().solicited"
  or
    recipients.to length_compare "0"
     macro "all(recipients.to)"
  recipients.bcc length_compare "0"
  recipients.cc length_compare "0"
  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"

Link: Credential phishing traversing Russian infrastructure

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

This rule detects credential phishing attempts in emails traversing Russian TLDs by aggressively analyzing links for signs of phishing, including suspicious keywords, login prompts, or links flagged for credential theft, excluding emails from trusted domains unless they fail DMARC verification.

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

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

Rule body

type.inbound
and any(headers.domains, .tld in ("ru", "su"))
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft" and .confidence in ("medium", "high")
)
and 0 < length(body.links) < 5
and any(body.links,
        beta.linkanalysis(., mode="aggressive").credphish.disposition == "phishing"
        or (
          strings.icontains(beta.linkanalysis(., mode="aggressive").final_dom.raw,
                            "Pàsswórd"
          )
          and (
            beta.linkanalysis(., mode="aggressive").credphish.contains_login
            or beta.linkanalysis(.).credphish.contains_captcha
          )
        )
        or beta.linkanalysis(., mode="aggressive").effective_url.domain.tld in $suspicious_tlds
)
and (
  not profile.by_sender().solicited
  or profile.by_sender().any_messages_malicious_or_spam
)

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

Detection logic

Scope: inbound message.

This rule detects credential phishing attempts in emails traversing Russian TLDs by aggressively analyzing links for signs of phishing, including suspicious keywords, login prompts, or links flagged for credential theft, excluding emails from trusted domains unless they fail DMARC verification.

  1. inbound message
  2. any of headers.domains where:
    • .tld in ('ru', 'su')
  3. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name is 'cred_theft'
    • .confidence in ('medium', 'high')
  4. all of:
    • length(body.links) > 0
    • length(body.links) < 5
  5. any of body.links where any holds:
    • beta.linkanalysis(.).credphish.disposition is 'phishing'
    • all of:
      • beta.linkanalysis(., mode='aggressive').final_dom.raw contains 'Pàsswórd'
      • any of:
        • beta.linkanalysis(.).credphish.contains_login
        • beta.linkanalysis(.).credphish.contains_captcha
    • beta.linkanalysis(.).effective_url.domain.tld in $suspicious_tlds
  6. any of:
    • not:
      • profile.by_sender().solicited
    • profile.by_sender().any_messages_malicious_or_spam
  7. 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

Inspects: body.current_thread.text, body.links, headers.domains, headers.domains[].tld, headers.hops, headers.hops[].authentication_results.dmarc, sender.email.domain.root_domain, type.inbound. Sensors: beta.linkanalysis, ml.nlu_classifier, profile.by_sender, strings.icontains, strings.ilike. Reference lists: $high_trust_sender_root_domains, $suspicious_tlds.

Indicators matched (7)

FieldMatchValue
headers.domains[].tldmemberru
headers.domains[].tldmembersu
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
strings.icontainssubstringPàsswórd
strings.ilikesubstring*fail

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    or
      and
        or
          beta.linkanalysis func_call "beta.linkanalysis(body.links[]).credphish.contains_captcha"
          beta.linkanalysis func_call "beta.linkanalysis(body.links[]).credphish.contains_login"
        beta.linkanalysis(body.links[], mode='aggressive').final_dom.raw contains "Pàsswórd"
      beta.linkanalysis func_call "beta.linkanalysis(body.links[]).credphish.disposition == phishing"
      beta.linkanalysis func_call "beta.linkanalysis(body.links[]).effective_url.domain.tld in suspicious_tlds"
  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"
  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
      profile.by_sender func_call "profile.by_sender().solicited"
    profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
  any(headers.domains)
    headers.domains.tld in ["ru", "su"]
  body.links length_compare "0"
  body.links length_compare "5"
  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"

Link: Credential phishing via WordPress

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

Detects when non-WordPress senders link to suspended or malicious WordPress blog sites, commonly used to redirect users to credential harvesting pages.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering, Free subdomain host

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
and sender.email.domain.root_domain != "wordpress.com"
// there are few links
and 0 < length(body.links) <= 5
// there are wordpress links
and any(body.links,
        .href_url.domain.root_domain == "wordpress.com"
        and .href_url.domain.domain != "wordpress.com"
)
// a single link to wordpress site
and length(filter(body.links,
                  .href_url.domain.root_domain == "wordpress.com"
                  and .href_url.domain.domain != "wordpress.com"
           )
) == 1

// not a reply
and length(headers.references) == 0
and headers.in_reply_to is null

// we detect the wordpress page has phishing
and any(filter(body.links, .href_url.domain.root_domain == "wordpress.com"),
        ml.link_analysis(.).credphish.disposition == "phishing"
        or strings.icontains(ml.link_analysis(.).final_dom.display_text,
                             'This blog has been archived or suspended in accordance with our Terms of Service'
        )
)

Detection logic

Scope: inbound message.

Detects when non-WordPress senders link to suspended or malicious WordPress blog sites, commonly used to redirect users to credential harvesting pages.

  1. inbound message
  2. sender.email.domain.root_domain is not 'wordpress.com'
  3. all of:
    • length(body.links) > 0
    • length(body.links) ≤ 5
  4. any of body.links where all hold:
    • .href_url.domain.root_domain is 'wordpress.com'
    • .href_url.domain.domain is not 'wordpress.com'
  5. length(filter(body.links, .href_url.domain.root_domain == 'wordpress.com' and .href_url.domain.domain != 'wordpress.com')) is 1
  6. length(headers.references) is 0
  7. headers.in_reply_to is missing
  8. any of filter(body.links) where any holds:
    • ml.link_analysis(.).credphish.disposition is 'phishing'
    • ml.link_analysis(.).final_dom.display_text contains 'This blog has been archived or suspended in accordance with our Terms of Service'

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, headers.in_reply_to, headers.references, sender.email.domain.root_domain, type.inbound. Sensors: ml.link_analysis, strings.icontains.

Indicators matched (2)

FieldMatchValue
body.links[].href_url.domain.root_domainequalswordpress.com
strings.icontainssubstringThis blog has been archived or suspended in accordance with our Terms of Service

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      body.links.href_url.domain.domain ne "wordpress.com"
      body.links.href_url.domain.root_domain eq "wordpress.com"
  any(filter(body.links))
    or
      ml.link_analysis func_call "ml.link_analysis(filter(body.links)[]).credphish.disposition == phishing"
      ml.link_analysis(filter(body.links)[]).final_dom.display_text contains "This blog has been archived or suspended in accordance with our Terms of Service"
  body.links length_compare "0"
  body.links length_compare "5"
  filter(body.links, .href_url.domain.root_domain == 'wordpress.com' and .href_url.domain.domain != 'wordpress.com') length_compare "1"
  headers.in_reply_to is_null
  headers.references length_compare "0"
  sender.email.domain.root_domain ne "wordpress.com"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Credential theft with Cloudflare tunnel and recipient targeting

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

Detects messages containing credential theft language and links to trycloudflare.com tunnels that include the recipient's email address in the URL path, indicating personalized targeting for credential harvesting.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • recipients
  • recipients.to[0]
  • type

Rule body

type.inbound
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == 'cred_theft' and .confidence != 'low'
)
and any(body.current_thread.links,
        .href_url.domain.root_domain == 'trycloudflare.com'
        and strings.icontains(.href_url.path, recipients.to[0].email.email)
)

Detection logic

Scope: inbound message.

Detects messages containing credential theft language and links to trycloudflare.com tunnels that include the recipient's email address in the URL path, indicating personalized targeting for credential harvesting.

  1. inbound message
  2. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name is 'cred_theft'
    • .confidence is not 'low'
  3. any of body.current_thread.links where all hold:
    • .href_url.domain.root_domain is 'trycloudflare.com'
    • strings.icontains(.href_url.path)

Inspects: body.current_thread.links, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.links[].href_url.path, body.current_thread.text, recipients.to[0].email.email, type.inbound. Sensors: ml.nlu_classifier, strings.icontains.

Indicators matched (2)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
body.current_thread.links[].href_url.domain.root_domainequalstrycloudflare.com

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    and
      body.current_thread.links.href_url.domain.root_domain eq "trycloudflare.com"
      strings.icontains func_call "strings.icontains(body.current_thread.links[].href_url.path)"
  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"
  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"

Link: Credential theft with invisible Unicode character in page title from unsolicited sender

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

Detects messages containing credential theft language and links to pages with invisible Unicode characters in the title tag, a technique commonly used to evade detection in fraudulent pages.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • recipients
  • recipients.to[0]
  • type

Rule body

type.inbound
// single recipient
and length(recipients.to) == 1
// valid recipient domain
and recipients.to[0].email.domain.valid
// between 1 and 14 links in the email
and 0 < length(body.links) < 15
// length of current thread is under 11k
and length(body.current_thread.text) < 11000
// tycoon captchas often have a page title with a specific unicode invisible char
and any(body.links,
        strings.contains(ml.link_analysis(., mode="aggressive").final_dom.raw,
                         "<title>\u{200B}</title>"
        )
        and length(ml.link_analysis(., mode="aggressive").final_dom.raw) < 10000
)
// unsolicited message
and not profile.by_sender().solicited

Detection logic

Scope: inbound message.

Detects messages containing credential theft language and links to pages with invisible Unicode characters in the title tag, a technique commonly used to evade detection in fraudulent pages.

  1. inbound message
  2. length(recipients.to) is 1
  3. recipients.to[0].email.domain.valid
  4. all of:
    • length(body.links) > 0
    • length(body.links) < 15
  5. length(body.current_thread.text) < 11000
  6. any of body.links where all hold:
    • ml.link_analysis(., mode='aggressive').final_dom.raw contains '<title>\\u{200B}</title>'
    • length(ml.link_analysis(., mode='aggressive').final_dom.raw) < 10000
  7. not:
    • profile.by_sender().solicited

Inspects: body.current_thread.text, body.links, recipients.to, recipients.to[0].email.domain.valid, type.inbound. Sensors: ml.link_analysis, profile.by_sender, strings.contains.

Indicators matched (1)

FieldMatchValue
strings.containssubstring<title>\u{200B}</title>

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      ml.link_analysis(body.links[], mode='aggressive').final_dom.raw contains "<title>\\u{200B}</title>"
      ml.link_analysis(body.links[], mode='aggressive').final_dom.raw length_compare "10000"
  not
    profile.by_sender func_call "profile.by_sender().solicited"
  body.current_thread.text length_compare "11000"
  body.links length_compare "0"
  body.links length_compare "15"
  recipients.to length_compare "1"
  recipients.to[0].email.domain.valid eq "true"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Cryptocurrency fraud with suspicious links

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

Detects messages containing financial communications about cryptocurrency or bitcoin with links to suspicious domains, URL shorteners, newly registered domains, or domains with known cryptocurrency fraud indicators. The rule analyzes link behavior including redirects, specific abuse patterns, and JavaScript configurations commonly used in cryptocurrency scams. Excludes legitimate cryptocurrency platforms with proper authentication.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesSocial engineering, Evasion, Free subdomain host, Scripting

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 any(ml.nlu_classifier(body.current_thread.text).topics,
        .name in ("Financial Communications")
)
and strings.ilike(body.current_thread.text, "*cryptocurrency*", "*bitcoin*")
and not any(ml.nlu_classifier(body.current_thread.text).topics,
            .name in (
              'Advertising and Promotions',
              'Newsletters and Digests',
              'News and Current Events',
              'Legal and Compliance'
            )
)
and not any(ml.nlu_classifier(body.current_thread.text).intents,
            .name == "benign" and .confidence == "high"
)
and any(body.links,
        (
          .href_url.domain.tld in $suspicious_tlds
          or .href_url.domain.root_domain in $url_shorteners
          or network.whois(.href_url.domain).days_old < 30
          // 1 distinct link domain that's not the sender domain
          or length(distinct(filter(body.links,
                                    .href_url.domain.root_domain != sender.email.domain.root_domain
                             ),
                             .href_url.domain.root_domain
                    )
          ) == 1
        )
        and (
          any(ml.link_analysis(., mode="aggressive").unique_urls_accessed,
              // known paths
              strings.ilike(.path, "/payouts/img/*", "/img/coins/*")
              // abused service to fetch coin prices
              or .domain.domain == "api.coingecko.com"
              // suspicious TLD that isn't the original link domain
              or (
                .domain.tld in $suspicious_tlds
                and .domain.root_domain != ..href_url.domain.root_domain
              )
          )
          or any(ml.link_analysis(., mode="aggressive").redirect_history,
                 // traversed a domain that is not the body link domain OR the effective domain
                 .domain.root_domain != ..href_url.domain.root_domain
                 and .domain.root_domain != ml.link_analysis(.,
                                                             mode="aggressive"
                 ).effective_url.domain.root_domain
          )
          // locate and extract the configuration on the page
          or (
            length(html.xpath(ml.link_analysis(., mode="aggressive").final_dom,
                              '//script/text()'
                   ).nodes
            ) == 1
            and any(html.xpath(ml.link_analysis(., mode="aggressive").final_dom,
                               '//script'
                    ).nodes,
                    any(file.explode(.),
                        length(filter(.scan.javascript.identifiers,
                                      strings.ilike(., "pay*")
                               )
                        ) == 27
                        or any(.scan.javascript.strings,
                               strings.icontains(., "pay.php")
                        )
                    )
            )
          )
        )
)
and not (
  sender.email.domain.root_domain in (
    "gemini.com",
    "ledger.com",
    "binance.com",
    "trezor.io",
    "kraken.com",
    "solana.com",
    "metamask.com",
    "ethereum.org",
    "bloomberg.com"
  )
  and headers.auth_summary.dmarc.pass
)

Detection logic

Scope: inbound message.

Detects messages containing financial communications about cryptocurrency or bitcoin with links to suspicious domains, URL shorteners, newly registered domains, or domains with known cryptocurrency fraud indicators. The rule analyzes link behavior including redirects, specific abuse patterns, and JavaScript configurations commonly used in cryptocurrency scams. Excludes legitimate cryptocurrency platforms with proper authentication.

  1. inbound message
  2. any of ml.nlu_classifier(body.current_thread.text).topics where:
    • .name in ('Financial Communications')
  3. body.current_thread.text matches any of 2 patterns
    • *cryptocurrency*
    • *bitcoin*
  4. not:
    • any of ml.nlu_classifier(body.current_thread.text).topics where:
      • .name in ('Advertising and Promotions', 'Newsletters and Digests', 'News and Current Events', 'Legal and Compliance')
  5. not:
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'benign'
      • .confidence is 'high'
  6. any of body.links where all hold:
    • any of:
      • .href_url.domain.tld in $suspicious_tlds
      • .href_url.domain.root_domain in $url_shorteners
      • network.whois(.href_url.domain).days_old < 30
      • length(distinct(filter(body.links, .href_url.domain.root_domain != sender.email.domain.root_domain), .href_url.domain.root_domain)) is 1
    • any of:
      • any of ml.link_analysis(., mode='aggressive').unique_urls_accessed where any holds:
        • .path matches any of 2 patterns
          • /payouts/img/*
          • /img/coins/*
        • .domain.domain is 'api.coingecko.com'
        • all of:
          • .domain.tld in $suspicious_tlds
          • .domain.root_domain is not .href_url.domain.root_domain
      • any of ml.link_analysis(., mode='aggressive').redirect_history where all hold:
        • .domain.root_domain is not .href_url.domain.root_domain
        • .domain.root_domain is not ml.link_analysis(., mode='aggressive').effective_url.domain.root_domain
      • all of:
        • length(html.xpath(ml.link_analysis(., mode='aggressive').final_dom, '//script/text()').nodes) is 1
        • any of html.xpath(ml.link_analysis(., mode='aggressive').final_dom, '//script').nodes where:
          • any of file.explode(.) where any holds:
            • length(filter(.scan.javascript.identifiers, strings.ilike(., 'pay*'))) is 27
            • any of .scan.javascript.strings where:
              • . contains 'pay.php'
  7. not:
    • all of:
      • sender.email.domain.root_domain in ('gemini.com', 'ledger.com', 'binance.com', 'trezor.io', 'kraken.com', 'solana.com', 'metamask.com', 'ethereum.org', 'bloomberg.com')
      • headers.auth_summary.dmarc.pass

Inspects: body.current_thread.text, body.links, body.links[].href_url.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.tld, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, html.xpath, ml.link_analysis, ml.nlu_classifier, network.whois, strings.icontains, strings.ilike. Reference lists: $suspicious_tlds, $url_shorteners.

Indicators matched (8)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).topics[].namememberFinancial Communications
strings.ilikesubstring*cryptocurrency*
strings.ilikesubstring*bitcoin*
strings.ilikesubstring/payouts/img/*
strings.ilikesubstring/img/coins/*
ml.link_analysis(body.links[], mode='aggressive').unique_urls_accessed[].domain.domainequalsapi.coingecko.com
strings.ilikesubstringpay*
strings.icontainssubstringpay.php

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        and
          any(html.xpath(ml.link_analysis(body.links, mode='aggressive').final_dom, '//script').nodes)
            any(file.explode(html.xpath(ml.link_analysis(body.links, mode='aggressive').final_dom, '//script').nodes))
              or
                any(file.explode(html.xpath(ml.link_analysis(body.links, mode='aggressive').final_dom, '//script').nodes).scan.javascript.strings)
                  file.explode(html.xpath(ml.link_analysis(body.links, mode='aggressive').final_dom, '//script').nodes).scan.javascript.strings contains "pay.php"
                filter(file.explode(html.xpath(ml.link_analysis(body.links[], mode='aggressive').final_dom, '//script').nodes[])[].scan.javascript.identifiers, strings.ilike(file.explode(html.xpath(ml.link_analysis(body.links[], mode='aggressive').final_dom, '//script').nodes[])[], 'pay*')) length_compare "27"
          html.xpath(ml.link_analysis(body.links[], mode='aggressive').final_dom, '//script/text()').nodes length_compare "1"
        any(ml.link_analysis(body.links, mode='aggressive').unique_urls_accessed)
          or
            and
              ml.link_analysis(body.links[], mode='aggressive').unique_urls_accessed[].domain.root_domain cross_field_compare "body.links.href_url.domain.root_domain"
               macro "ml.link_analysis(body.links[], mode='aggressive').unique_urls_accessed[].domain.tld in suspicious_tlds"
            ml.link_analysis(body.links[], mode='aggressive').unique_urls_accessed[].domain.domain eq "api.coingecko.com"
            ml.link_analysis(body.links[], mode='aggressive').unique_urls_accessed[].path starts_with "/img/coins/"
            ml.link_analysis(body.links[], mode='aggressive').unique_urls_accessed[].path starts_with "/payouts/img/"
        any(ml.link_analysis(body.links, mode='aggressive').redirect_history)
          and
            ml.link_analysis(body.links[], mode='aggressive').redirect_history[].domain.root_domain cross_field_compare "body.links.href_url.domain.root_domain"
             macro "ml.link_analysis(body.links[], mode='aggressive').redirect_history[].domain.root_domain != ml.link_analysis(ml.link_analysis(body.links[], mode='aggressive').redirect_history[], mode='aggressive').effective_url.domain.root_domain"
      or
        distinct(filter(body.links, body.links[].href_url.domain.root_domain != sender.email.domain.root_domain), body.links[].href_url.domain.root_domain) length_compare "1"
        network.whois func_call "network.whois(body.links[].href_url.domain).days_old < 30"
         macro "body.links[].href_url.domain.root_domain in url_shorteners"
         macro "body.links[].href_url.domain.tld in suspicious_tlds"
  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"
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.root_domain in ["binance.com", "bloomberg.com", "ethereum.org", "gemini.com", "kraken.com", "ledger.com", "metamask.com", "solana.com", "trezor.io"]
  not
    any(ml.nlu_classifier(body.current_thread.text).topics)
      ml.nlu_classifier(body.current_thread.text).topics.name in ["Advertising and Promotions", "Legal and Compliance", "News and Current Events", "Newsletters and Digests"]
  or
    body.current_thread.text match "bitcoin"
    body.current_thread.text match "cryptocurrency"
  any(ml.nlu_classifier(body.current_thread.text).topics)
    ml.nlu_classifier(body.current_thread.text).topics.name eq "Financial Communications"
  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
headers.auth_summary.dmarc.passeqtrueexcludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true"
sender.email.domain.root_domaininbinance.com, bloomberg.com, ethereum.org, gemini.com, kraken.com, ledger.com, metamask.com, solana.com, trezor.ioexcludes:sender.email.domain.root_domain
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.

Link: CVE-2024-21413 Microsoft Outlook Remote Code Execution Vulnerability

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

This rule detects messages containing links exploiting CVE-2024-21413, which can lead to RCE. Successful exploitation can bypass built-in Outlook protections for malicious links embedded in messages by using the file:// protocol and an exclamation mark to URLs pointing to attacker-controlled servers."

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware
Tactics and techniquesEvasion, Exploit

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        .href_url.scheme == "file"
        and regex.icontains(.href_url.url, '\.[a-z]{2,4}(\.[a-z]{2,4})?!')
)

Detection logic

Scope: inbound message.

This rule detects messages containing links exploiting CVE-2024-21413, which can lead to RCE. Successful exploitation can bypass built-in Outlook protections for malicious links embedded in messages by using the file:// protocol and an exclamation mark to URLs pointing to attacker-controlled servers."

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.scheme is 'file'
    • .href_url.url matches '\\.[a-z]{2,4}(\\.[a-z]{2,4})?!'

Inspects: body.links, body.links[].href_url.scheme, body.links[].href_url.url, type.inbound. Sensors: regex.icontains.

Indicators matched (2)

FieldMatchValue
body.links[].href_url.schemeequalsfile
regex.icontainsregex\.[a-z]{2,4}(\.[a-z]{2,4})?!

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      body.links.href_url.scheme eq "file"
      body.links.href_url.url regex_match "\\.[a-z]{2,4}(\\.[a-z]{2,4})?!"
  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"

Link: Direct download of executable file

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

Detects messages containing links that directly download executable (.exe) files, with a limited number of distinct links that are either unrelated to the sender's domain or not in the top 10k most popular websites.

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware
Tactics and techniquesEvasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
// the link leads to a direct download of an EXE file
and any(body.current_thread.links,
        strings.iends_with(.href_url.url, '.exe')
        and not .href_url.domain.root_domain == sender.email.domain.root_domain
        and not (
          .href_url.domain.root_domain in $tranco_10k
          // if the link is to a free_file_hosts that is in tracno, still match (bitbucket, githubusercontent, etc.)
          and not .href_url.domain.root_domain in $free_file_hosts
        )
)

Detection logic

Scope: inbound message.

Detects messages containing links that directly download executable (.exe) files, with a limited number of distinct links that are either unrelated to the sender's domain or not in the top 10k most popular websites.

  1. inbound message
  2. any of body.current_thread.links where all hold:
    • .href_url.url ends with '.exe'
    • not:
      • .href_url.domain.root_domain is sender.email.domain.root_domain
    • not:
      • all of:
        • .href_url.domain.root_domain in $tranco_10k
        • not:
          • .href_url.domain.root_domain in $free_file_hosts

Inspects: body.current_thread.links, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.links[].href_url.url, sender.email.domain.root_domain, type.inbound. Sensors: strings.iends_with. Reference lists: $free_file_hosts, $tranco_10k.

Indicators matched (1)

FieldMatchValue
strings.iends_withsuffix.exe

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    and
      not
        and
          not
             macro "body.current_thread.links[].href_url.domain.root_domain in free_file_hosts"
           macro "body.current_thread.links[].href_url.domain.root_domain in tranco_10k"
      not
        body.current_thread.links.href_url.domain.root_domain cross_field_compare "sender.email.domain.root_domain"
      body.current_thread.links.href_url.url ends_with ".exe"
  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"

Link: Direct link to Dropbox Paper file

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

Detects inbound messages containing links to Dropbox Paper documents using the /scl/fi/ sharing path with a .paper file extension and an rlkey query parameter. This pattern is commonly abused to host phishing content or malicious redirects behind Dropbox's trusted domain, allowing messages to bypass reputation-based filtering while luring recipients into opening a shared document.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesFree file host, Social engineering, Out of band pivot

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • type

Rule body

type.inbound
and any(body.current_thread.links,
        .href_url.domain.root_domain == "dropbox.com"
        and strings.istarts_with(.href_url.path, '/scl/fi/')
        and strings.iends_with(.href_url.path, '.paper')
        and 'rlkey' in keys(.href_url.query_params_decoded)
)

Detection logic

Scope: inbound message.

Detects inbound messages containing links to Dropbox Paper documents using the /scl/fi/ sharing path with a .paper file extension and an rlkey query parameter. This pattern is commonly abused to host phishing content or malicious redirects behind Dropbox's trusted domain, allowing messages to bypass reputation-based filtering while luring recipients into opening a shared document.

  1. inbound message
  2. any of body.current_thread.links where all hold:
    • .href_url.domain.root_domain is 'dropbox.com'
    • .href_url.path starts with '/scl/fi/'
    • .href_url.path ends with '.paper'
    • keys(.href_url.query_params_decoded) contains 'rlkey'

Inspects: body.current_thread.links, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.links[].href_url.path, body.current_thread.links[].href_url.query_params_decoded, type.inbound. Sensors: strings.iends_with, strings.istarts_with.

Indicators matched (4)

FieldMatchValue
body.current_thread.links[].href_url.domain.root_domainequalsdropbox.com
strings.istarts_withprefix/scl/fi/
strings.iends_withsuffix.paper
keys(body.current_thread.links[].href_url.query_params_decoded)containsrlkey

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    and
      body.current_thread.links.href_url.domain.root_domain eq "dropbox.com"
      body.current_thread.links.href_url.path ends_with ".paper"
      body.current_thread.links.href_url.path starts_with "/scl/fi/"
      keys(body.current_thread.links[].href_url.query_params_decoded) contains "rlkey"
  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"

Link: Direct link to gamma.app document with mode parameter

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

Detects URLs linking to Gamma App presentation or document mode, which has been used to host malicious content due to its trusted domain status and presentation capabilities.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesFree file host, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and length(body.links) < 10
and any(body.links,
        (
          .href_url.domain.root_domain == "gamma.app"
          or strings.icontains(.href_url.query_params, 'gamma.app')
          or strings.icontains(.href_url.query_params, 'gamma%2eapp')
          or strings.icontains(.href_url.query_params, 'gamma%252eapp')
        )
        and regex.icontains(.href_url.query_params, 'mode=(present|doc)')
)

Detection logic

Scope: inbound message.

Detects URLs linking to Gamma App presentation or document mode, which has been used to host malicious content due to its trusted domain status and presentation capabilities.

  1. inbound message
  2. length(body.links) < 10
  3. any of body.links where all hold:
    • any of:
      • .href_url.domain.root_domain is 'gamma.app'
      • .href_url.query_params contains 'gamma.app'
      • .href_url.query_params contains 'gamma%2eapp'
      • .href_url.query_params contains 'gamma%252eapp'
    • .href_url.query_params matches 'mode=(present|doc)'

Inspects: body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.query_params, type.inbound. Sensors: regex.icontains, strings.icontains.

Indicators matched (5)

FieldMatchValue
body.links[].href_url.domain.root_domainequalsgamma.app
strings.icontainssubstringgamma.app
strings.icontainssubstringgamma%2eapp
strings.icontainssubstringgamma%252eapp
regex.icontainsregexmode=(present|doc)

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        body.links.href_url.domain.root_domain eq "gamma.app"
        body.links.href_url.query_params contains "gamma%252eapp"
        body.links.href_url.query_params contains "gamma%2eapp"
        body.links.href_url.query_params contains "gamma.app"
      body.links.href_url.query_params regex_match "mode=(present|doc)"
  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"

Link: Direct link to keap.app contact-us page

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

Detects URLs linking to Keap App contact us, which has been used to host malicious content due to its trusted domain status and product capabilities

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesFree file host, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and length(body.links) < 10
and any(body.links,
        (
          .href_url.domain.root_domain == "keap.app"
          and strings.istarts_with(.href_url.path, '/contact-us/')
        )
        // encoded within the query_params (common for open redirects)
        or (
          (
            strings.icontains(.href_url.query_params, 'keap.app')
            or strings.icontains(.href_url.query_params, 'keap%2eapp')
            or strings.icontains(.href_url.query_params, 'keap%252eapp')
          )
          and strings.istarts_with(.href_url.query_params, '/contact-us/')
        )
)
and length(filter(body.links,
                  .href_url.domain.root_domain == "keap.app"
                  // encoded within the query_params (common for open redirects)
                  or strings.icontains(.href_url.query_params, 'keap.app')
                  or strings.icontains(.href_url.query_params, 'keap%2eapp')
                  or strings.icontains(.href_url.query_params, 'keap%252eapp')
           )
) == 1

Detection logic

Scope: inbound message.

Detects URLs linking to Keap App contact us, which has been used to host malicious content due to its trusted domain status and product capabilities

  1. inbound message
  2. length(body.links) < 10
  3. any of body.links where any holds:
    • all of:
      • .href_url.domain.root_domain is 'keap.app'
      • .href_url.path starts with '/contact-us/'
    • all of:
      • any of:
        • .href_url.query_params contains 'keap.app'
        • .href_url.query_params contains 'keap%2eapp'
        • .href_url.query_params contains 'keap%252eapp'
      • .href_url.query_params starts with '/contact-us/'
  4. length(filter(body.links, .href_url.domain.root_domain == 'keap.app' or strings.icontains(.href_url.query_params, 'keap.app') or strings.icontains(.href_url.query_params, 'keap%2eapp') or strings.icontains(.href_url.query_params, 'keap%252eapp'))) is 1

Inspects: body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.path, body.links[].href_url.query_params, type.inbound. Sensors: strings.icontains, strings.istarts_with.

Indicators matched (5)

FieldMatchValue
body.links[].href_url.domain.root_domainequalskeap.app
strings.istarts_withprefix/contact-us/
strings.icontainssubstringkeap.app
strings.icontainssubstringkeap%2eapp
strings.icontainssubstringkeap%252eapp

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    or
      and
        or
          body.links.href_url.query_params contains "keap%252eapp"
          body.links.href_url.query_params contains "keap%2eapp"
          body.links.href_url.query_params contains "keap.app"
        body.links.href_url.query_params starts_with "/contact-us/"
      and
        body.links.href_url.domain.root_domain eq "keap.app"
        body.links.href_url.path starts_with "/contact-us/"
  body.links length_compare "10"
  filter(body.links, .href_url.domain.root_domain == 'keap.app' or strings.icontains(.href_url.query_params, 'keap.app') or strings.icontains(.href_url.query_params, 'keap%2eapp') or strings.icontains(.href_url.query_params, 'keap%252eapp')) length_compare "1"
  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"

Link: Direct link to limewire hosted file

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

Message contains exactly one link to limewire.com domain with fewer than 10 total links in the body.

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware
Tactics and techniquesFree file host

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
// there are few links
and length(body.links) < 10
// contains a link to limewire
and any(body.links, .href_url.domain.domain == "limewire.com")
// is the only link to limewire
and length(filter(body.links,
                  .href_url.domain.root_domain == "limewire.com"
                  and strings.istarts_with(.href_url.path, "/d/")
           )
) == 1
and not 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
)
and not profile.by_sender_email().any_messages_benign

Detection logic

Scope: inbound message.

Message contains exactly one link to limewire.com domain with fewer than 10 total links in the body.

  1. inbound message
  2. length(body.links) < 10
  3. any of body.links where:
    • .href_url.domain.domain is 'limewire.com'
  4. length(filter(body.links, .href_url.domain.root_domain == 'limewire.com' and strings.istarts_with(.href_url.path, '/d/'))) is 1
  5. not:
    • length(body.previous_threads) > 0
  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_email().any_messages_benign

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.path, body.previous_threads, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender_email, strings.istarts_with. Reference lists: $high_trust_sender_root_domains.

Indicators matched (3)

FieldMatchValue
body.links[].href_url.domain.domainequalslimewire.com
body.links[].href_url.domain.root_domainequalslimewire.com
strings.istarts_withprefix/d/

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(body.links)
    body.links.href_url.domain.domain eq "limewire.com"
  not
    body.previous_threads length_compare "0"
  not
    profile.by_sender_email func_call "profile.by_sender_email().any_messages_benign"
  body.links length_compare "10"
  filter(body.links, .href_url.domain.root_domain == 'limewire.com' and strings.istarts_with(.href_url.path, '/d/')) length_compare "1"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
body.previous_threadslength_compare0excludes:body.previous_threads field:"body.previous_threads" value:"0"

Indicators

These rows show field, operator, and value matches.

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

Link: Direct link to riddle.com hosted showcase

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

Message contains a single link to a Riddle.com hosted showcase which has been observed abused for credential phishing landing

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesFree file host

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 length(body.links) < 20
and any(body.links, .href_url.domain.root_domain == "riddle.com")
and length(filter(body.links,
                  .href_url.domain.root_domain == "riddle.com"
                  and strings.istarts_with(.href_url.path, '/view/')
           )
) == 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
)
and not profile.by_sender_email().any_messages_benign

Detection logic

Scope: inbound message.

Message contains a single link to a Riddle.com hosted showcase which has been observed abused for credential phishing landing

  1. inbound message
  2. length(body.links) < 20
  3. any of body.links where:
    • .href_url.domain.root_domain is 'riddle.com'
  4. length(filter(body.links, .href_url.domain.root_domain == 'riddle.com' and strings.istarts_with(.href_url.path, '/view/'))) is 1
  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_email().any_messages_benign

Inspects: body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.path, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender_email, strings.istarts_with. Reference lists: $high_trust_sender_root_domains.

Indicators matched (2)

FieldMatchValue
body.links[].href_url.domain.root_domainequalsriddle.com
strings.istarts_withprefix/view/

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(body.links)
    body.links.href_url.domain.root_domain eq "riddle.com"
  not
    profile.by_sender_email func_call "profile.by_sender_email().any_messages_benign"
  body.links length_compare "20"
  filter(body.links, .href_url.domain.root_domain == 'riddle.com' and strings.istarts_with(.href_url.path, '/view/')) length_compare "1"
  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"

Link: Direct link to Zoom Docs from non-Zoom sender

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

Message includes a single link to Zoom Docs, with no other links to zoom and originates from a sender outside the Zoom organization

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering, Impersonation: Brand

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
// contains a link to zoom docs
and any(body.links, .href_url.domain.domain == "docs.zoom.us")
// is the only link to zoom
and length(filter(body.links, .href_url.domain.root_domain == "zoom.us")) == 1
// not from zoom.us
and not (
  sender.email.domain.root_domain == "zoom.us"
  and headers.auth_summary.dmarc.pass
)

Detection logic

Scope: inbound message.

Message includes a single link to Zoom Docs, with no other links to zoom and originates from a sender outside the Zoom organization

  1. inbound message
  2. any of body.links where:
    • .href_url.domain.domain is 'docs.zoom.us'
  3. length(filter(body.links, .href_url.domain.root_domain == 'zoom.us')) is 1
  4. not:
    • all of:
      • sender.email.domain.root_domain is 'zoom.us'
      • headers.auth_summary.dmarc.pass

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound.

Indicators matched (2)

FieldMatchValue
body.links[].href_url.domain.domainequalsdocs.zoom.us
body.links[].href_url.domain.root_domainequalszoom.us

Stages and Predicates

Stage 1: mql_rule

and
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      sender.email.domain.root_domain eq "zoom.us"
  any(body.links)
    body.links.href_url.domain.domain eq "docs.zoom.us"
  filter(body.links, .href_url.domain.root_domain == 'zoom.us') length_compare "1"
  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"

Link: Direct MSI download from low reputation domain

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

Detects messages containing links that directly download MSI files from domains not in the top 10k trusted sites and unrelated to the sender's domain.

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware
Tactics and techniquesEvasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
// low amount of distinct links which are unrelated to the sender or not in tranco_10k
and length(distinct(filter(body.current_thread.links,
                           .href_url.domain.root_domain != sender.email.domain.root_domain
                           and .href_url.domain.root_domain not in $tranco_10k
                    ),
                    .href_url.url
           )
) <= 5
// the link leads to a direct download of an MSI file
and any(body.current_thread.links, strings.iends_with(.href_url.url, '.msi'))

Detection logic

Scope: inbound message.

Detects messages containing links that directly download MSI files from domains not in the top 10k trusted sites and unrelated to the sender's domain.

  1. inbound message
  2. length(distinct(filter(body.current_thread.links, .href_url.domain.root_domain != sender.email.domain.root_domain and .href_url.domain.root_domain not in $tranco_10k), .href_url.url)) ≤ 5
  3. any of body.current_thread.links where:
    • .href_url.url ends with '.msi'

Inspects: body.current_thread.links, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.links[].href_url.url, sender.email.domain.root_domain, type.inbound. Sensors: strings.iends_with. Reference lists: $tranco_10k.

Indicators matched (1)

FieldMatchValue
strings.iends_withsuffix.msi

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    body.current_thread.links.href_url.url ends_with ".msi"
  distinct(filter(body.current_thread.links, .href_url.domain.root_domain != sender.email.domain.root_domain and .href_url.domain.root_domain not in $tranco_10k), .href_url.url) length_compare "5"
  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"

Link: Direct POWR.io Form Builder with suspicious patterns

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

Detects POWR.io forms with suspicious characteristics including unverified creators, cross-domain redirects, suspended accounts, or form owners from African time zones that don't match sender domains.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Callback Phishing
Tactics and techniquesSocial engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.links
  • sender.email
  • type

Rule body

type.inbound
and (
  (
    any(filter(body.links,
               (
                 (
                   .href_url.domain.root_domain == "powr.io"
                   and strings.icontains(.href_url.path, 'form-builder')
                 )
                 or (
                   (
                     strings.icontains(.href_url.query_params, 'powr.io')
                     or strings.icontains(.href_url.query_params, 'powr%2io')
                     or strings.icontains(.href_url.query_params, 'powr%252eio')
                   )
                   and strings.icontains(.href_url.query_params, 'form-builder')
                 )
               )
        ),
        // it's credphishing
        ml.link_analysis(.).credphish.disposition == "phishing"
        // these shouldn't show up here either
        or ml.link_analysis(.).credphish.contains_login
        or ml.link_analysis(.).credphish.contains_captcha
        // there is a redirect, and that redirect goes to a different domain than the sender root domain
        or any(regex.extract(ml.link_analysis(.).final_dom.raw,
                             'window\.CONTENT=(?P<content>[^\n]+)\;\n'
               ),
               strings.parse_json(.named_groups["content"])["afterSubmission"] == "redirect"
               and strings.parse_json(.named_groups["content"])["redirectLink"] != ""
               and not strings.icontains(strings.parse_json(.named_groups["content"]
                                         )["redirectLink"],
                                         sender.email.domain.root_domain
               )
        )
        // use the META data to inspect the "app_owner" data
        or any(regex.extract(ml.link_analysis(.).final_dom.raw,
                             'window\.META=(?P<meta>[^\n]+)\;\n'
               ),
               // the creator has been suspended or isn't active anymore
               strings.parse_json(.named_groups["meta"])["app_owner"]["status"] == "suspended"
               or strings.parse_json(.named_groups["meta"])["app_owner"]["active"] == false
               // did not verify the email address
               or strings.parse_json(.named_groups["meta"])["app_owner"]["has_verified_email?"] == false
               // the app_owner originated from a timezone in Africa
               or strings.starts_with(strings.parse_json(.named_groups["meta"])["app_owner"]["timezone"],
                                      'Africa/'
               )
               // the creator domain doesn't match the sender root domain
               or not strings.ends_with(strings.parse_json(.named_groups["meta"]
                                        )["app_owner"]["email"],
                                        sender.email.domain.root_domain
               )
        )
    )
    or any(attachments,
           (.file_extension == "eml" or .content_type == "message/rfc822")
           and any(filter(file.parse_eml(.).body.links,
                          (
                            (
                              .href_url.domain.root_domain == "powr.io"
                              and strings.icontains(.href_url.path,
                                                    'form-builder'
                              )
                            )
                            or (
                              (
                                strings.icontains(.href_url.query_params,
                                                  'powr.io'
                                )
                                or strings.icontains(.href_url.query_params,
                                                     'powr%2io'
                                )
                                or strings.icontains(.href_url.query_params,
                                                     'powr%252eio'
                                )
                              )
                              and strings.icontains(.href_url.query_params,
                                                    'form-builder'
                              )
                            )
                          )
                   ),
                   // it's credphishing
                   ml.link_analysis(.).credphish.disposition == "phishing"
                   // these shouldn't show up here either
                   or ml.link_analysis(.).credphish.contains_login
                   or ml.link_analysis(.).credphish.contains_captcha

                   // there is a redirect, and that redirect goes to a different domain than the sender root domain
                   or any(regex.extract(ml.link_analysis(.).final_dom.raw,
                                        'window\.CONTENT=(?P<content>[^\n]+)\;\n'
                          ),
                          strings.parse_json(.named_groups["content"])["afterSubmission"] == "redirect"
                          and strings.parse_json(.named_groups["content"])["redirectLink"] != ""
                          and not strings.icontains(strings.parse_json(.named_groups["content"]
                                                    )["redirectLink"],
                                                    sender.email.domain.root_domain
                          )
                   )
                   // the creator has been suspended
                   or any(regex.extract(ml.link_analysis(.).final_dom.raw,
                                        'window\.META=(?P<meta>[^\n]+)\;\n'
                          ),

                          // the creator has been suspended or isn't active anymore
                          strings.parse_json(.named_groups["meta"])["app_owner"]["status"] == "suspended"
                          or strings.parse_json(.named_groups["meta"])["app_owner"]["active"] == false
                          // did not verify the email address
                          or strings.parse_json(.named_groups["meta"])["app_owner"]["has_verified_email?"] == false
                          // the app_owner originated from a timezone in Africa
                          or strings.starts_with(strings.parse_json(.named_groups["meta"]
                                                 )["app_owner"]["timezone"],
                                                 'Africa/'
                          )
                          // the creator domain doesn't match the sender root domain
                          or not strings.ends_with(strings.parse_json(.named_groups["meta"]
                                                   )["app_owner"]["email"],
                                                   sender.email.domain.root_domain
                          )
                   )
           )
    )
  )
)

Detection logic

Scope: inbound message.

Detects POWR.io forms with suspicious characteristics including unverified creators, cross-domain redirects, suspended accounts, or form owners from African time zones that don't match sender domains.

  1. inbound message
  2. any of:
    • any of filter(body.links) where any holds:
      • ml.link_analysis(.).credphish.disposition is 'phishing'
      • ml.link_analysis(.).credphish.contains_login
      • ml.link_analysis(.).credphish.contains_captcha
      • any of regex.extract(...) where all hold:
        • strings.parse_json(.named_groups['content']).['afterSubmission'] is 'redirect'
        • strings.parse_json(.named_groups['content']).['redirectLink'] is not ''
        • not:
          • strings.icontains(strings.parse_json(.named_groups['content'])['redirectLink'])
      • any of regex.extract(...) where any holds:
        • strings.parse_json(.named_groups['meta']).['app_owner']['status'] is 'suspended'
        • strings.parse_json(.named_groups['meta']).['app_owner']['active'] is False
        • strings.parse_json(.named_groups['meta']).['app_owner']['has_verified_email?'] is False
        • strings.parse_json(.named_groups['meta'])['app_owner']['timezone'] starts with 'Africa/'
        • not:
          • strings.ends_with(strings.parse_json(.named_groups['meta'])['app_owner']['email'])
    • any of attachments where all hold:
      • any of:
        • .file_extension is 'eml'
        • .content_type is 'message/rfc822'
      • any of filter(...) where any holds:
        • ml.link_analysis(.).credphish.disposition is 'phishing'
        • ml.link_analysis(.).credphish.contains_login
        • ml.link_analysis(.).credphish.contains_captcha
        • any of regex.extract(...) where all hold:
          • strings.parse_json(.named_groups['content']).['afterSubmission'] is 'redirect'
          • strings.parse_json(.named_groups['content']).['redirectLink'] is not ''
          • not:
            • strings.icontains(strings.parse_json(.named_groups['content'])['redirectLink'])
        • any of regex.extract(...) where any holds:
          • strings.parse_json(.named_groups['meta']).['app_owner']['status'] is 'suspended'
          • strings.parse_json(.named_groups['meta']).['app_owner']['active'] is False
          • strings.parse_json(.named_groups['meta']).['app_owner']['has_verified_email?'] is False
          • strings.parse_json(.named_groups['meta'])['app_owner']['timezone'] starts with 'Africa/'
          • not:
            • strings.ends_with(strings.parse_json(.named_groups['meta'])['app_owner']['email'])

Inspects: attachments[].content_type, attachments[].file_extension, body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.path, body.links[].href_url.query_params, sender.email.domain.root_domain, type.inbound. Sensors: file.parse_eml, ml.link_analysis, regex.extract, strings.ends_with, strings.icontains, strings.parse_json, strings.starts_with.

Indicators matched (11)

FieldMatchValue
body.links[].href_url.domain.root_domainequalspowr.io
strings.icontainssubstringform-builder
strings.icontainssubstringpowr.io
strings.icontainssubstringpowr%2io
strings.icontainssubstringpowr%252eio
regex.extractregexwindow\.CONTENT=(?P<content>[^\n]+)\;\n
regex.extractregexwindow\.META=(?P<meta>[^\n]+)\;\n
strings.starts_withprefixAfrica/
attachments[].file_extensionequalseml
attachments[].content_typeequalsmessage/rfc822
file.parse_eml(attachments[]).body.links[].href_url.domain.root_domainequalspowr.io

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(attachments)
      and
        any(filter(...))
          or
            any(regex.extract(...))
              or
                not
                  strings.ends_with func_call "strings.ends_with(strings.parse_json(regex.extract(...)[].named_groups['meta'])['app_owner']['email'])"
                strings.parse_json func_call "strings.parse_json(regex.extract(...)[].named_groups['meta']).['app_owner']['active'] == false"
                strings.parse_json func_call "strings.parse_json(regex.extract(...)[].named_groups['meta']).['app_owner']['has_verified_email?'] == false"
                strings.parse_json func_call "strings.parse_json(regex.extract(...)[].named_groups['meta']).['app_owner']['status'] == suspended"
                strings.parse_json(regex.extract(...)[].named_groups['meta'])['app_owner']['timezone'] starts_with "Africa/"
            any(regex.extract(...))
              and
                not
                  strings.icontains func_call "strings.icontains(strings.parse_json(regex.extract(...)[].named_groups['content'])['redirectLink'])"
                strings.parse_json func_call "strings.parse_json(regex.extract(...)[].named_groups['content']).['afterSubmission'] == redirect"
                strings.parse_json func_call "strings.parse_json(regex.extract(...)[].named_groups['content']).['redirectLink'] != "
            ml.link_analysis func_call "ml.link_analysis(filter(...)[]).credphish.contains_captcha"
            ml.link_analysis func_call "ml.link_analysis(filter(...)[]).credphish.contains_login"
            ml.link_analysis func_call "ml.link_analysis(filter(...)[]).credphish.disposition == phishing"
        or
          attachments.content_type eq "message/rfc822"
          attachments.file_extension eq "eml"
    any(filter(body.links))
      or
        any(regex.extract(...))
          or
            not
              strings.ends_with func_call "strings.ends_with(strings.parse_json(regex.extract(...)[].named_groups['meta'])['app_owner']['email'])"
            strings.parse_json func_call "strings.parse_json(regex.extract(...)[].named_groups['meta']).['app_owner']['active'] == false"
            strings.parse_json func_call "strings.parse_json(regex.extract(...)[].named_groups['meta']).['app_owner']['has_verified_email?'] == false"
            strings.parse_json func_call "strings.parse_json(regex.extract(...)[].named_groups['meta']).['app_owner']['status'] == suspended"
            strings.parse_json(regex.extract(...)[].named_groups['meta'])['app_owner']['timezone'] starts_with "Africa/"
        any(regex.extract(...))
          and
            not
              strings.icontains func_call "strings.icontains(strings.parse_json(regex.extract(...)[].named_groups['content'])['redirectLink'])"
            strings.parse_json func_call "strings.parse_json(regex.extract(...)[].named_groups['content']).['afterSubmission'] == redirect"
            strings.parse_json func_call "strings.parse_json(regex.extract(...)[].named_groups['content']).['redirectLink'] != "
        ml.link_analysis func_call "ml.link_analysis(filter(body.links)[]).credphish.contains_captcha"
        ml.link_analysis func_call "ml.link_analysis(filter(body.links)[]).credphish.contains_login"
        ml.link_analysis func_call "ml.link_analysis(filter(body.links)[]).credphish.disposition == phishing"
  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"

Link: Display text matches subject line

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

Message with short body text contains a single link where the display text matches the subject line. The link is deceptive and the recipient patterns are unusual, such as the recipient's address appearing in the body or undisclosed recipients being used.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Credential Phishing
Tactics and techniquesSocial engineering, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.links
  • recipients
  • recipients.to
  • sender.email
  • subject
  • type

Rule body

type.inbound

// short body
and length(body.current_thread.text) < 1500

// suspicious recipient patterns
and (
  // recipient email is contained within the body
  (
    length(recipients.to) == 1
    and all(recipients.to,
            strings.icontains(body.current_thread.text, .email.email)
    )
  )
  // the sender is the recipient
  or sender.email.email in map(recipients.to, .email.email)
  // none of the recipients are valid (generally undisclosed recipients)
  or not all(recipients.to, .email.domain.valid)
)
// few overall links
and length(body.links) < 10
// none of the links are unsubscribe links
and not any(body.links,
            strings.icontains(.display_text, 'unsub')
            or strings.icontains(.href_url.url, 'unsub')
            or strings.icontains(.display_text, 'optout')
            or strings.icontains(.href_url.url, 'optout')
            or strings.icontains(.display_text, 'subscription')
            // google confidential email use the subject as a link
            or .href_url.domain.domain == "confidential-mail.google.com"
)

// even fewer links which are
and 0 < length(filter(body.links,
                      // not related to the sender domain
                      .href_url.domain.root_domain != sender.email.domain.root_domain
                      // not related to the recipient domain
                      and not any(recipients.to,
                                  .email.domain.root_domain == ..href_url.domain.root_domain
                      )
                      // filter out links common in signatures
                      and not .href_url.domain.root_domain in (
                        "facebook.com",
                        "instagram.com",
                        'twitter.com',
                        'x.com'
                      )
                      // do not contain a display_text (TP samples have the display_text of the subject)
                      // // this removes domains found in signatures
                      and .display_text is not null
                      // not the aka.ms in warning banners
                      and not .href_url.domain.domain == "aka.ms"
               )
) <= 3

// exactly one link with display text that matches the subject
and length(filter(body.links, subject.subject =~ .display_text)) == 1
and (
  // the link with the display_text of the subject
  any(filter(body.links, subject.subject =~ .display_text),
      // when visited is phishing
      ml.link_analysis(.).credphish.disposition == "phishing"
      or ml.link_analysis(.).final_dom.display_text == "Verify you are human"
      or .href_url.domain.root_domain in $self_service_creation_platform_domains
      or .href_url.domain.domain in $self_service_creation_platform_domains
      or .href_url.domain.domain in $url_shorteners
  )
  // or the body is cred_theft
  or any(ml.nlu_classifier(body.current_thread.text).intents,
         .name == "cred_theft"
  )
)

// the display text of a link is the subject
and subject.subject in map(body.links, .display_text)

// exclude common in signup links/password resets which are observed in links all the time
and not (
  strings.icontains(subject.subject, 'confirm')
  or strings.icontains(subject.subject, 'activate')
  or strings.icontains(subject.subject, 'reset')
  or strings.icontains(subject.subject, 'unlock')
  or strings.icontains(subject.subject, 'login')
  or strings.icontains(subject.subject, 'log in')
)

Detection logic

Scope: inbound message.

Message with short body text contains a single link where the display text matches the subject line. The link is deceptive and the recipient patterns are unusual, such as the recipient's address appearing in the body or undisclosed recipients being used.

  1. inbound message
  2. length(body.current_thread.text) < 1500
  3. any of:
    • all of:
      • length(recipients.to) is 1
      • all of recipients.to where:
        • strings.icontains(body.current_thread.text)
    • sender.email.email in map(recipients.to, .email.email)
    • not:
      • all of recipients.to where:
        • .email.domain.valid
  4. length(body.links) < 10
  5. not:
    • any of body.links where any holds:
      • .display_text contains 'unsub'
      • .href_url.url contains 'unsub'
      • .display_text contains 'optout'
      • .href_url.url contains 'optout'
      • .display_text contains 'subscription'
      • .href_url.domain.domain is 'confidential-mail.google.com'
  6. all of:
    • length(filter(body.links, .href_url.domain.root_domain != sender.email.domain.root_domain and not any(recipients.to, .email.domain.root_domain == ..href_url.domain.root_domain) and not .href_url.domain.root_domain in ('facebook.com', 'instagram.com', 'twitter.com', 'x.com') and .display_text is not null and not .href_url.domain.domain == 'aka.ms')) > 0
    • length(filter(body.links, .href_url.domain.root_domain != sender.email.domain.root_domain and not any(recipients.to, .email.domain.root_domain == ..href_url.domain.root_domain) and not .href_url.domain.root_domain in ('facebook.com', 'instagram.com', 'twitter.com', 'x.com') and .display_text is not null and not .href_url.domain.domain == 'aka.ms')) ≤ 3
  7. length(filter(body.links, subject.subject =~ .display_text)) is 1
  8. any of:
    • any of filter(body.links) where any holds:
      • ml.link_analysis(.).credphish.disposition is 'phishing'
      • ml.link_analysis(.).final_dom.display_text is 'Verify you are human'
      • .href_url.domain.root_domain in $self_service_creation_platform_domains
      • .href_url.domain.domain in $self_service_creation_platform_domains
      • .href_url.domain.domain in $url_shorteners
    • any of ml.nlu_classifier(body.current_thread.text).intents where:
      • .name is 'cred_theft'
  9. subject.subject in map(body.links, .display_text)
  10. none of:
    • subject.subject contains 'confirm'
    • subject.subject contains 'activate'
    • subject.subject contains 'reset'
    • subject.subject contains 'unlock'
    • subject.subject contains 'login'
    • subject.subject contains 'log in'

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.url, recipients.to, recipients.to[].email.domain.root_domain, recipients.to[].email.domain.valid, recipients.to[].email.email, sender.email.domain.root_domain, sender.email.email, subject.subject, type.inbound. Sensors: ml.link_analysis, ml.nlu_classifier, strings.icontains. Reference lists: $self_service_creation_platform_domains, $url_shorteners.

Indicators matched (1)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft

Stages and Predicates

Stage 1: mql_rule

and
  not
    any(body.links)
      or
        body.links.display_text contains "optout"
        body.links.display_text contains "subscription"
        body.links.display_text contains "unsub"
        body.links.href_url.domain.domain eq "confidential-mail.google.com"
        body.links.href_url.url contains "optout"
        body.links.href_url.url contains "unsub"
  or
    any(filter(body.links))
      or
        ml.link_analysis func_call "ml.link_analysis(filter(body.links)[]).credphish.disposition == phishing"
        ml.link_analysis func_call "ml.link_analysis(filter(body.links)[]).final_dom.display_text == Verify you are human"
         macro "filter(body.links)[].href_url.domain.domain in self_service_creation_platform_domains"
         macro "filter(body.links)[].href_url.domain.domain in url_shorteners"
         macro "filter(body.links)[].href_url.domain.root_domain in self_service_creation_platform_domains"
    any(ml.nlu_classifier(body.current_thread.text).intents)
      ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
  or
    and
      recipients.to length_compare "1"
       macro "all(recipients.to)"
    not
       macro "all(recipients.to)"
     macro "sender.email.email in map(recipients.to, .email.email)"
  not
    or
      subject.subject contains "activate"
      subject.subject contains "confirm"
      subject.subject contains "log in"
      subject.subject contains "login"
      subject.subject contains "reset"
      subject.subject contains "unlock"
  body.current_thread.text length_compare "1500"
  body.links length_compare "10"
  filter(body.links, .href_url.domain.root_domain != sender.email.domain.root_domain and not any(recipients.to, .email.domain.root_domain == ..href_url.domain.root_domain) and not .href_url.domain.root_domain in ('facebook.com', 'instagram.com', 'twitter.com', 'x.com') and .display_text is not null and not .href_url.domain.domain == 'aka.ms') length_compare "0"
  filter(body.links, .href_url.domain.root_domain != sender.email.domain.root_domain and not any(recipients.to, .email.domain.root_domain == ..href_url.domain.root_domain) and not .href_url.domain.root_domain in ('facebook.com', 'instagram.com', 'twitter.com', 'x.com') and .display_text is not null and not .href_url.domain.domain == 'aka.ms') length_compare "3"
  filter(body.links, subject.subject =~ .display_text) length_compare "1"
  type.inbound eq "true"
   macro "subject.subject in map(body.links, .display_text)"

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"

Link: Display text with excessive right-to-left mark characters

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

Detects links where the display text contains a high concentration of Unicode right-to-left mark characters (U+200F), which may be used to obfuscate or manipulate the visual representation of the link text to deceive recipients.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • type

Rule body

type.inbound
and length(html.xpath(body.html, '//a').nodes) < 10
and any(html.xpath(body.html, '//a').nodes,
        regex.icontains(.inner_text, '(?:[A-Za-z]\x{200F}){2,}[A-Za-z]')
)

Detection logic

Scope: inbound message.

Detects links where the display text contains a high concentration of Unicode right-to-left mark characters (U+200F), which may be used to obfuscate or manipulate the visual representation of the link text to deceive recipients.

  1. inbound message
  2. length(html.xpath(body.html, '//a').nodes) < 10
  3. any of html.xpath(body.html, '//a').nodes where:
    • .inner_text matches '(?:[A-Za-z]\\x{200F}){2,}[A-Za-z]'

Inspects: body.html, type.inbound. Sensors: html.xpath, regex.icontains.

Indicators matched (1)

FieldMatchValue
regex.icontainsregex(?:[A-Za-z]\x{200F}){2,}[A-Za-z]

Stages and Predicates

Stage 1: mql_rule

and
  any(html.xpath(body.html, '//a').nodes)
    html.xpath(body.html, '//a').nodes.inner_text regex_match "(?:[A-Za-z]\\x{200F}){2,}[A-Za-z]"
  html.xpath(body.html, '//a').nodes 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"

Link: Document sharing invitation template

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

Detects inbound messages containing text indicating a document sharing invitation with the specific phrase 'has invited you to VIEW the following document:', commonly used in malicious document sharing schemes.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering, Free file host

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • type

Rule body

type.inbound
and strings.contains(body.current_thread.text,
                     'has invited you to VIEW the following document:'
)
and length(body.current_thread.links) > 0

Detection logic

Scope: inbound message.

Detects inbound messages containing text indicating a document sharing invitation with the specific phrase 'has invited you to VIEW the following document:', commonly used in malicious document sharing schemes.

  1. inbound message
  2. body.current_thread.text contains 'has invited you to VIEW the following document:'
  3. length(body.current_thread.links) > 0

Inspects: body.current_thread.links, body.current_thread.text, type.inbound. Sensors: strings.contains.

Indicators matched (1)

FieldMatchValue
strings.containssubstringhas invited you to VIEW the following document:

Stages and Predicates

Stage 1: mql_rule

and
  body.current_thread.links length_compare "0"
  body.current_thread.text contains "has invited you to VIEW the following document:"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Document-themed link to newly registered domain

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

Detects inbound emails containing links whose display text mimics a document file (.xlsx, .xls, .pdf, .doc, .docx) but whose resolved destination domain was registered within the last 30 days, a strong indicator of a newly stood-up malicious infrastructure used to harvest credentials or deliver malware.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesSocial engineering, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • type

Rule body

type.inbound
and any(body.current_thread.links,
        strings.ends_with(.display_text,
                          '.xlsx',
                          '.xls',
                          '.pdf',
                          '.doc',
                          '.docx'
        )
        and network.whois(ml.link_analysis(., mode="aggressive").effective_url.domain
        ).days_old <= 30
)

Detection logic

Scope: inbound message.

Detects inbound emails containing links whose display text mimics a document file (.xlsx, .xls, .pdf, .doc, .docx) but whose resolved destination domain was registered within the last 30 days, a strong indicator of a newly stood-up malicious infrastructure used to harvest credentials or deliver malware.

  1. inbound message
  2. any of body.current_thread.links where all hold:
    • .display_text ends with any of 5 patterns
      • .xlsx
      • .xls
      • .pdf
      • .doc
      • .docx
    • network.whois(ml.link_analysis(., mode='aggressive').effective_url.domain).days_old ≤ 30

Inspects: body.current_thread.links, body.current_thread.links[].display_text, type.inbound. Sensors: ml.link_analysis, network.whois, strings.ends_with.

Indicators matched (5)

FieldMatchValue
strings.ends_withsuffix.xlsx
strings.ends_withsuffix.xls
strings.ends_withsuffix.pdf
strings.ends_withsuffix.doc
strings.ends_withsuffix.docx

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    and
      or
        body.current_thread.links.display_text ends_with ".doc"
        body.current_thread.links.display_text ends_with ".docx"
        body.current_thread.links.display_text ends_with ".pdf"
        body.current_thread.links.display_text ends_with ".xls"
        body.current_thread.links.display_text ends_with ".xlsx"
      network.whois func_call "network.whois(ml.link_analysis(body.current_thread.links[], mode='aggressive').effective_url.domain).days_old <= 30"
  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"

Link: Excessive URL rewrite encoders

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

Detects URLs with many (excessive) encoding patterns, including multiple instances of the same encoder or four or more distinct encoders. These techniques are commonly used to obfuscate malicious URLs and evade security filters.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesEncryption, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • type

Rule body

type.inbound
and any(body.current_thread.links,
        (
          // 4 or more encoders but they are all distinct
          length(.href_url.rewrite.encoders) >= 4
          and length(distinct(.href_url.rewrite.encoders)) >= 4
        )
)

Detection logic

Scope: inbound message.

Detects URLs with many (excessive) encoding patterns, including multiple instances of the same encoder or four or more distinct encoders. These techniques are commonly used to obfuscate malicious URLs and evade security filters.

  1. inbound message
  2. any of body.current_thread.links where all hold:
    • length(.href_url.rewrite.encoders) ≥ 4
    • length(distinct(.href_url.rewrite.encoders)) ≥ 4

Inspects: body.current_thread.links, body.current_thread.links[].href_url.rewrite.encoders, type.inbound.

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    and
      body.current_thread.links.href_url.rewrite.encoders length_compare "4"
      distinct(body.current_thread.links[].href_url.rewrite.encoders) length_compare "4"
  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"

Link: Executable file download with suspicious message content

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

Detects inbound messages containing links to executable files combined with high-confidence security, financial, or credential theft content indicators, while excluding legitimate trusted domains with proper DMARC authentication.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
and length(body.links) < 10
and any(body.links,
        any($file_extensions_executables,
            strings.iends_with(..href_url.url, strings.concat(".", .))
            // the display text is not going to reveal the executable extension
            and not strings.iends_with(..display_text, strings.concat(".", .))
        )
        and .href_url.path is not null
        // filter out some executables
        and not any(["com", "action", "js", "app"],
                    strings.iends_with(..href_url.url, .)
        )
        // .app links from Google Play
        and not .href_url.domain.domain == "play.google.com"
        and not .href_url.domain.root_domain in $high_trust_sender_root_domains
)
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)
)
and 2 of (
  any(ml.nlu_classifier(body.current_thread.text).topics,
      .name in ("Security and Authentication", "Financial Communications")
      and .confidence == "high"
  ),
  any(ml.nlu_classifier(body.current_thread.text).intents,
      .name == "cred_theft" and .confidence == "high"
  ),
  sender.email.domain.tld in $suspicious_tlds
)

// 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 inbound messages containing links to executable files combined with high-confidence security, financial, or credential theft content indicators, while excluding legitimate trusted domains with proper DMARC authentication.

  1. inbound message
  2. length(body.links) < 10
  3. any of body.links where all hold:
    • any of $file_extensions_executables where all hold:
      • strings.iends_with(.href_url.url)
      • not:
        • strings.iends_with(.display_text)
    • .href_url.path is set
    • not:
      • any of ['com', 'action', 'js', 'app'] where:
        • strings.iends_with(.href_url.url)
    • not:
      • .href_url.domain.domain is 'play.google.com'
    • not:
      • .href_url.domain.root_domain in $high_trust_sender_root_domains
  4. 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
  5. at least 2 of:
    • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
      • .name in ('Security and Authentication', 'Financial Communications')
      • .confidence is 'high'
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'cred_theft'
      • .confidence is 'high'
    • sender.email.domain.tld in $suspicious_tlds
  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.links, body.links[].display_text, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.path, body.links[].href_url.url, body.previous_threads, headers.auth_summary.dmarc.pass, headers.in_reply_to, headers.references, sender.email.domain.root_domain, sender.email.domain.tld, subject.is_forward, subject.is_reply, type.inbound. Sensors: ml.nlu_classifier, strings.concat, strings.iends_with. Reference lists: $file_extensions_executables, $high_trust_sender_root_domains, $suspicious_tlds.

Indicators matched (5)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).topics[].namememberSecurity and Authentication
ml.nlu_classifier(body.current_thread.text).topics[].namememberFinancial Communications
ml.nlu_classifier(body.current_thread.text).topics[].confidenceequalshigh
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      any($file_extensions_executables)
        and
          not
            strings.iends_with func_call "strings.iends_with(body.links[].display_text)"
          strings.iends_with func_call "strings.iends_with(body.links[].href_url.url)"
      not
        any(['com', 'action', 'js', 'app'])
          strings.iends_with func_call "strings.iends_with(body.links[].href_url.url)"
      not
        body.links.href_url.domain.domain eq "play.google.com"
      not
         macro "body.links[].href_url.domain.root_domain in high_trust_sender_root_domains"
      body.links.href_url.path is_not_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"
  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).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)
      and
        ml.nlu_classifier(body.current_thread.text).topics.confidence eq "high"
        ml.nlu_classifier(body.current_thread.text).topics.name in ["Financial Communications", "Security and Authentication"]
     macro "sender.email.domain.tld in suspicious_tlds"
  body.links length_compare "10"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
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"

Indicators

These rows show field, operator, and value matches.

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

Link: Fake forwarded message with suspicious URL in plain text

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

Detects inbound plain text messages (no HTML body) with no prior thread history that contain a URL and are structured as a forwarded message. The rule checks for a 'Begin forwarded message' preamble, either standalone or followed by a From field matching the sender's display name, suggesting the message may be disguising its origin or delivering malicious links via forwarded message formatting.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, BEC/Fraud
Tactics and techniquesSocial engineering, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.html
  • type

Rule body

type.inbound
and body.html.raw is null
and length(body.previous_threads) == 0
and regex.contains(body.current_thread.text, 'https?://')
and (
  regex.imatch(body.current_thread.preamble, 'begin forwarded message:\s*')
  or (
    regex.imatch(body.current_thread.preamble,
                 'begin forwarded message:\s*from:\s*[^<@\n]+\s*'
    )
    and strings.icontains(body.current_thread.preamble, sender.display_name)
  )
)

Detection logic

Scope: inbound message.

Detects inbound plain text messages (no HTML body) with no prior thread history that contain a URL and are structured as a forwarded message. The rule checks for a 'Begin forwarded message' preamble, either standalone or followed by a From field matching the sender's display name, suggesting the message may be disguising its origin or delivering malicious links via forwarded message formatting.

  1. inbound message
  2. body.html.raw is missing
  3. length(body.previous_threads) is 0
  4. body.current_thread.text matches 'https?://'
  5. any of:
    • body.current_thread.preamble matches 'begin forwarded message:\\s*'
    • all of:
      • body.current_thread.preamble matches 'begin forwarded message:\\s*from:\\s*[^<@\\n]+\\s*'
      • strings.icontains(body.current_thread.preamble)

Inspects: body.current_thread.preamble, body.current_thread.text, body.html.raw, body.previous_threads, sender.display_name, type.inbound. Sensors: regex.contains, regex.imatch, strings.icontains.

Indicators matched (3)

FieldMatchValue
regex.containsregexhttps?://
regex.imatchregexbegin forwarded message:\s*
regex.imatchregexbegin forwarded message:\s*from:\s*[^<@\n]+\s*

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      body.current_thread.preamble regex_match "begin forwarded message:\\s*from:\\s*[^<@\\n]+\\s*"
      strings.icontains func_call "strings.icontains(body.current_thread.preamble)"
    body.current_thread.preamble regex_match "begin forwarded message:\\s*"
  body.current_thread.text regex_match "https?://"
  body.html.raw is_null
  body.previous_threads length_compare "0"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Fake secure message notification template

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

Detects inbound messages containing links that match a specific HTML styling fingerprint characterized by a distinctive blue color scheme (rgb(41, 88, 140)), a bottom border of 10px solid with the same blue, and a padding of 1.6em. This combination of CSS properties is associated with malicious messages designed to lure recipients into clicking embedded links.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.html
  • type

Rule body

type.inbound
and length(body.links) > 0
and regex.icontains(body.html.raw,
                    'background-color\s*:\s*rgb\(41,\s*88,\s*140\)'
)
and regex.icontains(body.html.raw,
                    'border-bottom\s*:\s*10px\s+solid\s+rgb\(41,\s*88,\s*140\)'
)
and regex.icontains(body.html.raw, 'padding\s*:\s*1\.6em')

Detection logic

Scope: inbound message.

Detects inbound messages containing links that match a specific HTML styling fingerprint characterized by a distinctive blue color scheme (rgb(41, 88, 140)), a bottom border of 10px solid with the same blue, and a padding of 1.6em. This combination of CSS properties is associated with malicious messages designed to lure recipients into clicking embedded links.

  1. inbound message
  2. length(body.links) > 0
  3. body.html.raw matches 'background-color\\s*:\\s*rgb\\(41,\\s*88,\\s*140\\)'
  4. body.html.raw matches 'border-bottom\\s*:\\s*10px\\s+solid\\s+rgb\\(41,\\s*88,\\s*140\\)'
  5. body.html.raw matches 'padding\\s*:\\s*1\\.6em'

Inspects: body.html.raw, body.links, type.inbound. Sensors: regex.icontains.

Indicators matched (3)

FieldMatchValue
regex.icontainsregexbackground-color\s*:\s*rgb\(41,\s*88,\s*140\)
regex.icontainsregexborder-bottom\s*:\s*10px\s+solid\s+rgb\(41,\s*88,\s*140\)
regex.icontainsregexpadding\s*:\s*1\.6em

Stages and Predicates

Stage 1: mql_rule

and
  body.html.raw regex_match "background-color\\s*:\\s*rgb\\(41,\\s*88,\\s*140\\)"
  body.html.raw regex_match "border-bottom\\s*:\\s*10px\\s+solid\\s+rgb\\(41,\\s*88,\\s*140\\)"
  body.html.raw regex_match "padding\\s*:\\s*1\\.6em"
  body.links length_compare "0"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.html.rawregex_match
  • background-color\s*:\s*rgb(41,\s*88,\s*140)
  • border-bottom\s*:\s*10px\s+solid\s+rgb(41,\s*88,\s*140)
  • padding\s*:\s*1.6em
field:"body.html.raw" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link: Figma design deck with credential theft language

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

A single link to a Figma design deck that contains credential theft language. The message comes from either a new sender, one with previously detected malicious activity, or a known sender who has not been in contact for over 30 days and has no history of benign messages.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Free file host, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
// only one link to Figma
and length(distinct(filter(body.links,
                           .href_url.domain.root_domain in ("figma.com")
                           and (
                             strings.istarts_with(.href_url.path, "/deck")
                             or (
                               strings.istarts_with(.href_url.path, "/design")
                               and .href_url.query_params is not null
                             )
                           )
                    ),
                    .href_url.url
           )
) == 1
and any(filter(body.links,
               .href_url.domain.root_domain in ("figma.com")
               and (
                 strings.istarts_with(.href_url.path, "/deck")
                 or (
                   strings.istarts_with(.href_url.path, "/design")
                   and .href_url.query_params is not null
                 )
               )
        ),
        any(ml.nlu_classifier(beta.ocr(ml.link_analysis(.).screenshot).text).intents,
            .name == "cred_theft" and .confidence in ("medium", "high")
        )
        or any(ml.nlu_classifier(beta.ocr(ml.link_analysis(.).screenshot).text).topics,
               .name in ("E-Signature", "Secure Message")
               and .confidence != "low"
        )
)
and (
  (
    profile.by_sender().prevalence in ("new", "outlier")
    and not profile.by_sender().solicited
  )
  or profile.by_sender().any_messages_malicious_or_spam
  or profile.by_sender().days_since.last_contact > 30
  // individual sender profile
  or profile.by_sender_email().days_since.first_contact < 3
)
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

A single link to a Figma design deck that contains credential theft language. The message comes from either a new sender, one with previously detected malicious activity, or a known sender who has not been in contact for over 30 days and has no history of benign messages.

  1. inbound message
  2. length(distinct(filter(body.links, .href_url.domain.root_domain in ('figma.com') and strings.istarts_with(.href_url.path, '/deck') or strings.istarts_with(.href_url.path, '/design') and .href_url.query_params is not null), .href_url.url)) is 1
  3. any of filter(body.links) where any holds:
    • any of ml.nlu_classifier(beta.ocr(ml.link_analysis(.).screenshot).text).intents where all hold:
      • .name is 'cred_theft'
      • .confidence in ('medium', 'high')
    • any of ml.nlu_classifier(beta.ocr(ml.link_analysis(.).screenshot).text).topics where all hold:
      • .name in ('E-Signature', 'Secure Message')
      • .confidence is not 'low'
  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
    • profile.by_sender().days_since.last_contact > 30
    • profile.by_sender_email().days_since.first_contact < 3
  5. not:
    • profile.by_sender().any_messages_benign

Inspects: body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.path, body.links[].href_url.query_params, type.inbound. Sensors: beta.ocr, ml.link_analysis, ml.nlu_classifier, profile.by_sender, profile.by_sender_email, strings.istarts_with.

Indicators matched (8)

FieldMatchValue
body.links[].href_url.domain.root_domainmemberfigma.com
strings.istarts_withprefix/deck
strings.istarts_withprefix/design
ml.nlu_classifier(beta.ocr(ml.link_analysis(filter(body.links)[]).screenshot).text).intents[].nameequalscred_theft
ml.nlu_classifier(beta.ocr(ml.link_analysis(filter(body.links)[]).screenshot).text).intents[].confidencemembermedium
ml.nlu_classifier(beta.ocr(ml.link_analysis(filter(body.links)[]).screenshot).text).intents[].confidencememberhigh
ml.nlu_classifier(beta.ocr(ml.link_analysis(filter(body.links)[]).screenshot).text).topics[].namememberE-Signature
ml.nlu_classifier(beta.ocr(ml.link_analysis(filter(body.links)[]).screenshot).text).topics[].namememberSecure Message

Stages and Predicates

Stage 1: mql_rule

and
  any(filter(body.links))
    or
      any(ml.nlu_classifier(beta.ocr(ml.link_analysis(filter(body.links)).screenshot).text).intents)
        and
          ml.nlu_classifier(beta.ocr(ml.link_analysis(filter(body.links)[]).screenshot).text).intents[].confidence in ["high", "medium"]
          ml.nlu_classifier(beta.ocr(ml.link_analysis(filter(body.links)[]).screenshot).text).intents[].name eq "cred_theft"
      any(ml.nlu_classifier(beta.ocr(ml.link_analysis(filter(body.links)).screenshot).text).topics)
        and
          ml.nlu_classifier(beta.ocr(ml.link_analysis(filter(body.links)[]).screenshot).text).topics[].confidence ne "low"
          ml.nlu_classifier(beta.ocr(ml.link_analysis(filter(body.links)[]).screenshot).text).topics[].name in ["E-Signature", "Secure Message"]
  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"
    profile.by_sender func_call "profile.by_sender().days_since.last_contact > 30"
    profile.by_sender_email func_call "profile.by_sender_email().days_since.first_contact < 3"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  distinct(filter(body.links, .href_url.domain.root_domain in ('figma.com') and strings.istarts_with(.href_url.path, '/deck') or strings.istarts_with(.href_url.path, '/design') and .href_url.query_params is not null), .href_url.url) length_compare "1"
  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"

Link: File sharing impersonation with suspicious language and sending patterns

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

Detects messages containing file sharing and cloud services topics combined with BEC or credential theft language, featuring links with document-related display text that lead to low-reputation domains outside the sender's domain and organization.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Credential Phishing
Tactics and techniquesSocial engineering, Free subdomain host, Impersonation: Brand

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.links
  • headers
  • headers.auth_summary
  • headers.hops
  • headers.reply_to
  • headers.return_path
  • recipients
  • recipients.cc
  • recipients.cc[0]
  • recipients.to
  • recipients.to[0]
  • sender.email
  • type

Rule body

type.inbound
and any(ml.nlu_classifier(body.current_thread.text).topics,
        .name == "File Sharing and Cloud Services" and .confidence != "low"
)
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name in ("bec", "cred_theft") and .confidence != "low"
)
and any(body.links,
        regex.icontains(.display_text, "document", "download", "message")
        and .href_url.domain.root_domain != sender.email.domain.root_domain
        and .href_url.domain.root_domain not in $tranco_1m
        and .href_url.domain.root_domain not in $org_domains
        and .href_url.domain.valid

        // Exclude legitimate document services
        and not .href_url.domain.root_domain in $free_file_hosts
)
// suspicious sending/recipient pattern
and 1 of (
  (
    length(recipients.to) == 1
    and recipients.to[0].email.email == sender.email.email
  ),
  any(headers.reply_to,
      .email.domain.domain in $free_email_providers
      and .email.domain.domain != sender.email.domain.domain
  ),
  (
    length(recipients.to) == 1
    and length(recipients.cc) == 1
    and recipients.to[0].email.email == recipients.cc[0].email.email
  ),
  (
    strings.icontains(headers.return_path.local_part, "+SRS=")
    or strings.icontains(headers.auth_summary.spf.details.designator, "+SRS=")
    or any(headers.hops,
           strings.icontains(.authentication_results.spf_details.designator,
                             '+SRS='
           )
    )
  ),
  // No recipients visible
  (
    length(recipients.to) == 0
    or (
      all(recipients.to, .email.domain.valid == false)
      and all(recipients.cc, .email.domain.valid == false)
    )
  )
  and length(recipients.cc) == 0
)

// 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 containing file sharing and cloud services topics combined with BEC or credential theft language, featuring links with document-related display text that lead to low-reputation domains outside the sender's domain and organization.

  1. inbound message
  2. any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
    • .name is 'File Sharing and Cloud Services'
    • .confidence is not 'low'
  3. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name in ('bec', 'cred_theft')
    • .confidence is not 'low'
  4. any of body.links where all hold:
    • .display_text matches any of 3 patterns
      • document
      • download
      • message
    • .href_url.domain.root_domain is not sender.email.domain.root_domain
    • .href_url.domain.root_domain not in $tranco_1m
    • .href_url.domain.root_domain not in $org_domains
    • .href_url.domain.valid
    • not:
      • .href_url.domain.root_domain in $free_file_hosts
  5. at least 1 of:
    • all of:
      • length(recipients.to) is 1
      • recipients.to[0].email.email is sender.email.email
    • any of headers.reply_to where all hold:
      • .email.domain.domain in $free_email_providers
      • .email.domain.domain is not sender.email.domain.domain
    • all of:
      • length(recipients.to) is 1
      • length(recipients.cc) is 1
      • recipients.to[0].email.email is recipients.cc[0].email.email
    • any of:
      • headers.return_path.local_part contains '+SRS='
      • headers.auth_summary.spf.details.designator contains '+SRS='
      • any of headers.hops where:
        • .authentication_results.spf_details.designator contains '+SRS='
    • 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
      • length(recipients.cc) is 0
  6. 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[].href_url.domain.root_domain, body.links[].href_url.domain.valid, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.details.designator, headers.hops, headers.hops[].authentication_results.spf_details.designator, headers.reply_to, headers.reply_to[].email.domain.domain, headers.return_path.local_part, recipients.cc, recipients.cc[0].email.email, recipients.cc[].email.domain.valid, recipients.to, recipients.to[0].email.email, recipients.to[].email.domain.valid, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: ml.nlu_classifier, regex.icontains, strings.icontains. Reference lists: $free_email_providers, $free_file_hosts, $high_trust_sender_root_domains, $org_domains, $tranco_1m.

Indicators matched (7)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).topics[].nameequalsFile Sharing and Cloud Services
ml.nlu_classifier(body.current_thread.text).intents[].namememberbec
ml.nlu_classifier(body.current_thread.text).intents[].namemembercred_theft
regex.icontainsregexdocument
regex.icontainsregexdownload
regex.icontainsregexmessage
strings.icontainssubstring+SRS=

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      or
        and
           macro "all(recipients.cc)"
           macro "all(recipients.to)"
        recipients.to length_compare "0"
      recipients.cc length_compare "0"
    any(headers.reply_to)
      and
        headers.reply_to.email.domain.domain cross_field_compare "sender.email.domain.domain"
         macro "headers.reply_to[].email.domain.domain in free_email_providers"
    any(headers.hops)
      headers.hops.authentication_results.spf_details.designator contains "+SRS="
    and
      recipients.cc length_compare "1"
      recipients.to length_compare "1"
      recipients.to[0].email.email cross_field_compare "recipients.cc[0].email.email"
    and
      recipients.to length_compare "1"
      recipients.to[0].email.email cross_field_compare "sender.email.email"
    headers.auth_summary.spf.details.designator contains "+SRS="
    headers.return_path.local_part contains "+SRS="
  any(body.links)
    and
      or
        body.links.display_text regex_match "document"
        body.links.display_text regex_match "download"
        body.links.display_text regex_match "message"
      not
         macro "body.links[].href_url.domain.root_domain in free_file_hosts"
      body.links.href_url.domain.root_domain cross_field_compare "sender.email.domain.root_domain"
      body.links.href_url.domain.valid eq "true"
       macro "body.links[].href_url.domain.root_domain not in org_domains"
       macro "body.links[].href_url.domain.root_domain not in tranco_1m"
  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 ne "low"
      ml.nlu_classifier(body.current_thread.text).intents.name in ["bec", "cred_theft"]
  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 "File Sharing and Cloud Services"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: File sharing pretext with suspicious body and link

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

Detects messages containing file sharing pretext with a single link to self-service creation platforms or URL shorteners, where the link display text matches the email subject and points to suspicious domains.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • body.links
  • subject
  • type

Rule body

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

// file sharing pretext
and any(ml.nlu_classifier(body.current_thread.text).topics,
        .name == "File Sharing and Cloud Services" and .confidence != "low"
)

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

// body/link display text is related to the subject & links to suspicious domain
and any(body.links,
        (
          strings.icontains(.display_text, subject.base)
          or strings.icontains(body.current_thread.text,
                               strings.concat('"', subject.base, '"')
          )
        )
        and (
          .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"
        )

        // 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 file sharing pretext with a single link to self-service creation platforms or URL shorteners, where the link display text matches the email subject and points to suspicious domains.

  1. inbound message
  2. length(body.links) < 20
  3. any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
    • .name is 'File Sharing and Cloud Services'
    • .confidence is not 'low'
  4. length(body.previous_threads) is 0
  5. length(filter(attachments, .file_type == 'pdf')) is 0
  6. length(filter(body.links, .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
  7. length(distinct(body.links, .href_url.domain.root_domain)) ≤ 3
  8. any of body.links where all hold:
    • any of:
      • strings.icontains(.display_text)
      • strings.icontains(body.current_thread.text)
    • any of:
      • .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'
    • not:
      • any of filter(...) where:
        • .raw contains 'gstatic.com/docs/doclist/images/'

Inspects: attachments[].file_type, body.current_thread.text, 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, ml.nlu_classifier, strings.concat, strings.icontains. Reference lists: $self_service_creation_platform_domains, $url_shorteners.

Indicators matched (3)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).topics[].nameequalsFile Sharing and Cloud Services
attachments[].file_typeequalspdf
body.links[].href_url.domain.root_domainequalsdynamics.com

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      not
        any(filter(...))
          filter(...).raw contains "gstatic.com/docs/doclist/images/"
      or
        body.links.href_url.domain.root_domain eq "dynamics.com"
         macro "body.links[].href_url.domain.domain in self_service_creation_platform_domains"
         macro "body.links[].href_url.domain.domain in url_shorteners"
         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"
      or
        strings.icontains func_call "strings.icontains(body.current_thread.text)"
        strings.icontains func_call "strings.icontains(body.links[].display_text)"
  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 "File Sharing and Cloud Services"
  body.links length_compare "20"
  body.previous_threads length_compare "0"
  distinct(body.links, .href_url.domain.root_domain) length_compare "3"
  filter(attachments, .file_type == 'pdf') length_compare "0"
  filter(body.links, .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') length_compare "1"
  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"

Link: Financial account issue with suspicious indicators

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

Detects messages to single recipients containing language about account or payment issues combined with suspicious links or high-confidence credential theft indicators related to financial communications.

Threat classification

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

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

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
// single recipient
and length(recipients.to) == 1
// problem phrase commonly observed in lures
and regex.icontains(body.current_thread.text,
                    '(?:issue|problem) with your.{0,20}(?:card|account|renewal|payment|billing)'
)
// link is suspicious for one reason or another
and any(body.links,
        (
          .href_url.domain.domain in $url_shorteners
          or .href_url.domain.root_domain in $url_shorteners
          or .href_url.domain.root_domain in $free_file_hosts
          or .href_url.domain.domain in $free_file_hosts
          or .href_url.domain.root_domain in $free_subdomain_hosts
          or .href_url.domain.domain in $free_subdomain_hosts
          or .href_url.domain.root_domain in $self_service_creation_platform_domains
          or .href_url.domain.domain in $self_service_creation_platform_domains
          or .href_url.domain.tld in $suspicious_tlds
          or network.whois(.href_url.domain).days_old < 30
          or .href_url.domain.root_domain == 'sa.com'
        )
        and not .href_url.domain.root_domain in (
          'app.link',
          'sng.link',
          'onelink.me'
        )
        // no campaigns
        and not regex.icontains(.href_url.url,
                                '&utm_(?:campaign|medium|source)'
        )
)

// high confidence cred theft with a topic of either financial or payment comms
and 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 ("Financial Communications", "Payment Information")
        and .confidence == 'high'
)
// negate highly trusted sender domains unless they fail DMARC authentication
and (
  (
    sender.email.domain.root_domain in $high_trust_sender_root_domains
    and not coalesce(headers.auth_summary.dmarc.pass, false)
  )
  or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)

Detection logic

Scope: inbound message.

Detects messages to single recipients containing language about account or payment issues combined with suspicious links or high-confidence credential theft indicators related to financial communications.

  1. inbound message
  2. length(recipients.to) is 1
  3. body.current_thread.text matches '(?:issue|problem) with your.{0,20}(?:card|account|renewal|payment|billing)'
  4. any of body.links where all hold:
    • any of:
      • .href_url.domain.domain in $url_shorteners
      • .href_url.domain.root_domain in $url_shorteners
      • .href_url.domain.root_domain in $free_file_hosts
      • .href_url.domain.domain in $free_file_hosts
      • .href_url.domain.root_domain in $free_subdomain_hosts
      • .href_url.domain.domain in $free_subdomain_hosts
      • .href_url.domain.root_domain in $self_service_creation_platform_domains
      • .href_url.domain.domain in $self_service_creation_platform_domains
      • .href_url.domain.tld in $suspicious_tlds
      • network.whois(.href_url.domain).days_old < 30
      • .href_url.domain.root_domain is 'sa.com'
    • not:
      • .href_url.domain.root_domain in ('app.link', 'sng.link', 'onelink.me')
    • not:
      • .href_url.url matches '&utm_(?:campaign|medium|source)'
  5. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name is 'cred_theft'
    • .confidence is 'high'
  6. any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
    • .name in ('Financial Communications', 'Payment Information')
    • .confidence is 'high'
  7. any of:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • not:
        • coalesce(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, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.tld, body.links[].href_url.url, headers.auth_summary.dmarc.pass, recipients.to, sender.email.domain.root_domain, type.inbound. Sensors: ml.nlu_classifier, network.whois, regex.icontains. Reference lists: $free_file_hosts, $free_subdomain_hosts, $high_trust_sender_root_domains, $self_service_creation_platform_domains, $suspicious_tlds, $url_shorteners.

Indicators matched (7)

FieldMatchValue
regex.icontainsregex(?:issue|problem) with your.{0,20}(?:card|account|renewal|payment|billing)
body.links[].href_url.domain.root_domainequalssa.com
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[].namememberFinancial Communications
ml.nlu_classifier(body.current_thread.text).topics[].namememberPayment Information
ml.nlu_classifier(body.current_thread.text).topics[].confidenceequalshigh

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        body.links.href_url.domain.root_domain eq "sa.com"
        network.whois func_call "network.whois(body.links[].href_url.domain).days_old < 30"
         macro "body.links[].href_url.domain.domain in free_file_hosts"
         macro "body.links[].href_url.domain.domain in free_subdomain_hosts"
         macro "body.links[].href_url.domain.domain in self_service_creation_platform_domains"
         macro "body.links[].href_url.domain.domain in url_shorteners"
         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"
         macro "body.links[].href_url.domain.tld in suspicious_tlds"
      not
        body.links.href_url.domain.root_domain in ["app.link", "onelink.me", "sng.link"]
      not
        body.links.href_url.url regex_match "&utm_(?:campaign|medium|source)"
  or
    and
      not
        coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       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.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)
    and
      ml.nlu_classifier(body.current_thread.text).topics.confidence eq "high"
      ml.nlu_classifier(body.current_thread.text).topics.name in ["Financial Communications", "Payment Information"]
  body.current_thread.text regex_match "(?:issue|problem) with your.{0,20}(?:card|account|renewal|payment|billing)"
  recipients.to length_compare "1"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Flagged bit.ly link

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

Shortened link is blocked or gated by bit.ly. Indicator of malicious email.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion

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 any(body.links,
        // contains bit.ly link
        .href_url.domain.root_domain == "bit.ly"
        // link doesn't forward through
        and ml.link_analysis(.).effective_url.domain.domain == "bit.ly"
        // blocked or gated by bit.ly
        and strings.ilike(ml.link_analysis(.).final_dom.display_text,
                          "*link*blocked*",
                          "*flagged*by*"
        )
)

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

Shortened link is blocked or gated by bit.ly. Indicator of malicious email.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.domain.root_domain is 'bit.ly'
    • ml.link_analysis(.).effective_url.domain.domain is 'bit.ly'
    • ml.link_analysis(.).final_dom.display_text matches any of 2 patterns
      • *link*blocked*
      • *flagged*by*
  3. 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
  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: body.links, body.links[].href_url.domain.root_domain, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: ml.link_analysis, profile.by_sender, strings.ilike. Reference lists: $high_trust_sender_root_domains.

Indicators matched (3)

FieldMatchValue
body.links[].href_url.domain.root_domainequalsbit.ly
strings.ilikesubstring*link*blocked*
strings.ilikesubstring*flagged*by*

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(body.links)
    and
      or
        ml.link_analysis(body.links[]).final_dom.display_text wildcard "*flagged*by*"
        ml.link_analysis(body.links[]).final_dom.display_text wildcard "*link*blocked*"
      body.links.href_url.domain.root_domain eq "bit.ly"
      ml.link_analysis func_call "ml.link_analysis(body.links[]).effective_url.domain.domain == bit.ly"
  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"
  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"

Link: Flare-branded credential harvesting via Cloudflare tunnels

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

Detects inbound messages that begin with 'Flare' branding (such as FlareDoc, FlareAudio, FlareBill, FlareReport) and contain links to trycloudflare.com domains. This pattern represents a consistent actor template using Cloudflare tunnels for credential harvesting operations.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesFree subdomain host, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.links
  • type

Rule body

type.inbound
and strings.starts_with(body.current_thread.text, 'Flare') 
and any(body.links, .href_url.domain.root_domain == "trycloudflare.com")

Detection logic

Scope: inbound message.

Detects inbound messages that begin with 'Flare' branding (such as FlareDoc, FlareAudio, FlareBill, FlareReport) and contain links to trycloudflare.com domains. This pattern represents a consistent actor template using Cloudflare tunnels for credential harvesting operations.

  1. inbound message
  2. body.current_thread.text starts with 'Flare'
  3. any of body.links where:
    • .href_url.domain.root_domain is 'trycloudflare.com'

Inspects: body.current_thread.text, body.links, body.links[].href_url.domain.root_domain, type.inbound. Sensors: strings.starts_with.

Indicators matched (2)

FieldMatchValue
strings.starts_withprefixFlare
body.links[].href_url.domain.root_domainequalstrycloudflare.com

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    body.links.href_url.domain.root_domain eq "trycloudflare.com"
  body.current_thread.text starts_with "Flare"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Fraudulent state business filing notice

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

Detects inbound messages impersonating official state business compliance communications, such as Statements of Information or Certificates of Good Standing, that contain links to free subdomain hosting services. These messages use urgent language around filing deadlines or business suspensions to pressure recipients into clicking credential-harvesting links.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesFree subdomain host, Social engineering, Impersonation: 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 not subject.is_reply
and not subject.is_forward
and 2 of (
  strings.icontains(body.current_thread.text, "Statement of Information"),
  strings.icontains(body.current_thread.text, "Secretary of State"),
  regex.icontains(body.current_thread.text, 'filing (?:is )?overdue'),
  strings.icontains(body.current_thread.text, "Certificate of Good Standing"),
  strings.icontains(body.current_thread.text, "business suspension")
)
and any(body.current_thread.links,
        .href_url.domain.root_domain in $free_subdomain_hosts
)
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft" and .confidence == "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 inbound messages impersonating official state business compliance communications, such as Statements of Information or Certificates of Good Standing, that contain links to free subdomain hosting services. These messages use urgent language around filing deadlines or business suspensions to pressure recipients into clicking credential-harvesting links.

  1. inbound message
  2. not:
    • subject.is_reply
  3. not:
    • subject.is_forward
  4. at least 2 of:
    • body.current_thread.text contains 'Statement of Information'
    • body.current_thread.text contains 'Secretary of State'
    • body.current_thread.text matches 'filing (?:is )?overdue'
    • body.current_thread.text contains 'Certificate of Good Standing'
    • body.current_thread.text contains 'business suspension'
  5. any of body.current_thread.links where:
    • .href_url.domain.root_domain in $free_subdomain_hosts
  6. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name is 'cred_theft'
    • .confidence is 'high'
  7. 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[].href_url.domain.root_domain, body.current_thread.text, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, subject.is_forward, subject.is_reply, type.inbound. Sensors: ml.nlu_classifier, regex.icontains, strings.icontains. Reference lists: $free_subdomain_hosts, $high_trust_sender_root_domains.

Indicators matched (7)

FieldMatchValue
strings.icontainssubstringStatement of Information
strings.icontainssubstringSecretary of State
regex.icontainsregexfiling (?:is )?overdue
strings.icontainssubstringCertificate of Good Standing
strings.icontainssubstringbusiness suspension
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh

Stages and Predicates

Stage 1: mql_rule

and
  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 eq "high"
      ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
  or
    body.current_thread.text contains "Certificate of Good Standing"
    body.current_thread.text contains "Secretary of State"
    body.current_thread.text contains "Statement of Information"
    body.current_thread.text contains "business suspension"
    body.current_thread.text regex_match "filing (?:is )?overdue"
  not
    subject.is_forward eq "true"
  not
    subject.is_reply eq "true"
  any(body.current_thread.links)
     macro "body.current_thread.links[].href_url.domain.root_domain in free_subdomain_hosts"
  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
  • Certificate of Good Standing
  • Secretary of State
  • Statement of Information
  • business suspension
field:"body.current_thread.text" kind:contains
body.current_thread.textregex_match
  • filing (?:is )?overdue
field:"body.current_thread.text" kind:regex_match value:"filing (?:is )?overdue"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link: Free file host links from suspicious support sender with credential theft language

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

Detects inbound messages from senders using the local part 'support' that contain a small number of links pointing exclusively to free file hosting services. The message contains NLU signals indicate credential theft intent related to file sharing or cloud services.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesFree file host, 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.email.local_part == 'support'
and 1 < length(filter(body.current_thread.links,
                      not regex.icontains(.href_url.url,
                                          '\.(pdf|doc|docx|csv|xls|xlsx|ppt|pptx)'
                      )
               )
) <= 5
and all(body.current_thread.links,
        .href_url.domain.root_domain in $free_file_hosts
        or .href_url.domain.domain in $free_file_hosts
)
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == 'cred_theft' and .confidence != 'low'
)
and any(ml.nlu_classifier(body.current_thread.text).topics,
        .name == 'File Sharing and Cloud Services' and .confidence != 'low'
)
// 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 inbound messages from senders using the local part 'support' that contain a small number of links pointing exclusively to free file hosting services. The message contains NLU signals indicate credential theft intent related to file sharing or cloud services.

  1. inbound message
  2. sender.email.local_part is 'support'
  3. all of:
    • length(filter(body.current_thread.links, not regex.icontains(.href_url.url, '\\.(pdf|doc|docx|csv|xls|xlsx|ppt|pptx)'))) > 1
    • length(filter(body.current_thread.links, not regex.icontains(.href_url.url, '\\.(pdf|doc|docx|csv|xls|xlsx|ppt|pptx)'))) ≤ 5
  4. all of body.current_thread.links where any holds:
    • .href_url.domain.root_domain in $free_file_hosts
    • .href_url.domain.domain in $free_file_hosts
  5. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name is 'cred_theft'
    • .confidence is not 'low'
  6. any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
    • .name is 'File Sharing and Cloud Services'
    • .confidence is not 'low'
  7. 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[].href_url.domain.domain, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.links[].href_url.url, body.current_thread.text, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, sender.email.local_part, type.inbound. Sensors: ml.nlu_classifier, regex.icontains. Reference lists: $free_file_hosts, $high_trust_sender_root_domains.

Indicators matched (3)

FieldMatchValue
sender.email.local_partequalssupport
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).topics[].nameequalsFile Sharing and Cloud Services

Stages and Predicates

Stage 1: mql_rule

and
  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 ne "low"
      ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
  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 "File Sharing and Cloud Services"
  filter(body.current_thread.links, not regex.icontains(.href_url.url, '\\.(pdf|doc|docx|csv|xls|xlsx|ppt|pptx)')) length_compare "1"
  filter(body.current_thread.links, not regex.icontains(.href_url.url, '\\.(pdf|doc|docx|csv|xls|xlsx|ppt|pptx)')) length_compare "5"
  sender.email.local_part eq "support"
  type.inbound eq "true"
   macro "all(body.current_thread.links)"

Indicators

These rows show field, operator, and value matches.

Link: Free file hosting with undisclosed recipients

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

Detects messages containing links to free file hosting or subdomain services that are sent to undisclosed recipients or only CC/BCC recipients. The rule identifies suspicious distribution patterns where legitimate recipients are hidden, potentially indicating mass distribution of malicious content through file sharing platforms.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesFree file host, Free subdomain host, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.previous_threads
  • headers
  • headers.auth_summary
  • headers.hops
  • headers.return_path
  • mailbox
  • recipients
  • recipients.to
  • sender.email
  • type

Rule body

type.inbound
// no previous threads
and (
  length(body.previous_threads) == 0
  // If there is a previous thread, it is unrelated to current thread
  or any(body.previous_threads, .sender.email.email != mailbox.email.email)
)

// few links that aren't "social" links
and 0 < length(filter(body.current_thread.links,
                      .href_url.domain.root_domain not in (
                        'x.com',
                        'facebook.com',
                        'twitter.com',
                        'instagram.com',
                        'youtube.com',
                        'linkedin.com'
                      )
               )
) < 10

// undisclosed recipients or all recipients cc'd
and (
  any(recipients.to, strings.ilike(.display_name, "undisclosed?recipients"))
  or (length(recipients.cc) > 0 and length(recipients.to) == 0)
  or (length(recipients.bcc) > 0 and length(recipients.to) == 0)
  or (
    length(recipients.to) == 1
    and length(recipients.cc) == 0
    and length(recipients.bcc) == 0
    and all(recipients.to, .email.email == sender.email.email)
    and all(recipients.to, .email.email != mailbox.email.email)
  )
)

// links to free file hosts or free subdomain hosts
and any(body.current_thread.links,
        (
          .href_url.domain.root_domain in $free_file_hosts
          or .href_url.domain.root_domain in $free_subdomain_hosts
        )
        and .visible
        and not (
          .href_url.domain.root_domain == "googleusercontent.com"
          and strings.istarts_with(.href_url.path, "/mail-sig")
        )
        and not .href_url.domain.domain in $tenant_domains
)

// negate listmailers & benign threads
and not (
  any(headers.hops, any(.fields, .name == "List-Unsubscribe"))
  or any(ml.nlu_classifier(body.current_thread.text).intents,
         .name == "benign" and .confidence == "high"
  )
)
and not (
  (
    sender.email.domain.root_domain in ("twilio.com", "zendesk.com")
    or headers.return_path.domain.root_domain in ("twilio.com", "zendesk.com")
  )
  and coalesce(headers.auth_summary.dmarc.pass, false)
)

// unsolicited and passing auth, or failing/missing dmarc
and (
  (
    coalesce(headers.auth_summary.dmarc.pass, false)
    and not profile.by_sender().solicited
  )
  or profile.by_sender_email().days_since.last_inbound > 365
  or (not coalesce(headers.auth_summary.dmarc.pass, false))
)

Detection logic

Scope: inbound message.

Detects messages containing links to free file hosting or subdomain services that are sent to undisclosed recipients or only CC/BCC recipients. The rule identifies suspicious distribution patterns where legitimate recipients are hidden, potentially indicating mass distribution of malicious content through file sharing platforms.

  1. inbound message
  2. any of:
    • length(body.previous_threads) is 0
    • any of body.previous_threads where:
      • .sender.email.email is not mailbox.email.email
  3. all of:
    • length(filter(body.current_thread.links, .href_url.domain.root_domain not in ('x.com', 'facebook.com', 'twitter.com', 'instagram.com', 'youtube.com', 'linkedin.com'))) > 0
    • length(filter(body.current_thread.links, .href_url.domain.root_domain not in ('x.com', 'facebook.com', 'twitter.com', 'instagram.com', 'youtube.com', 'linkedin.com'))) < 10
  4. any of:
    • any of recipients.to where:
      • .display_name matches 'undisclosed?recipients'
    • all of:
      • length(recipients.cc) > 0
      • length(recipients.to) is 0
    • all of:
      • length(recipients.bcc) > 0
      • length(recipients.to) is 0
    • all of:
      • length(recipients.to) is 1
      • length(recipients.cc) is 0
      • length(recipients.bcc) is 0
      • all of recipients.to where:
        • .email.email is sender.email.email
      • all of recipients.to where:
        • .email.email is not mailbox.email.email
  5. any of body.current_thread.links where all hold:
    • any of:
      • .href_url.domain.root_domain in $free_file_hosts
      • .href_url.domain.root_domain in $free_subdomain_hosts
    • .visible
    • not:
      • all of:
        • .href_url.domain.root_domain is 'googleusercontent.com'
        • .href_url.path starts with '/mail-sig'
    • not:
      • .href_url.domain.domain in $tenant_domains
  6. none of:
    • any of headers.hops where:
      • any of .fields where:
        • .name is 'List-Unsubscribe'
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'benign'
      • .confidence is 'high'
  7. not:
    • all of:
      • any of:
        • sender.email.domain.root_domain in ('twilio.com', 'zendesk.com')
        • headers.return_path.domain.root_domain in ('twilio.com', 'zendesk.com')
      • coalesce(headers.auth_summary.dmarc.pass)
  8. any of:
    • all of:
      • coalesce(headers.auth_summary.dmarc.pass)
      • not:
        • profile.by_sender().solicited
    • profile.by_sender_email().days_since.last_inbound > 365
    • not:
      • coalesce(headers.auth_summary.dmarc.pass)

Inspects: body.current_thread.links, body.current_thread.links[].href_url.domain.domain, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.links[].href_url.path, body.current_thread.links[].visible, body.current_thread.text, body.previous_threads, body.previous_threads[].sender.email.email, headers.auth_summary.dmarc.pass, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.return_path.domain.root_domain, mailbox.email.email, recipients.bcc, recipients.cc, recipients.to, recipients.to[].display_name, recipients.to[].email.email, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender, profile.by_sender_email, strings.ilike, strings.istarts_with. Reference lists: $free_file_hosts, $free_subdomain_hosts, $tenant_domains.

Indicators matched (1)

FieldMatchValue
strings.ilikesubstringundisclosed?recipients

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    and
      not
        and
          body.current_thread.links.href_url.domain.root_domain eq "googleusercontent.com"
          body.current_thread.links.href_url.path starts_with "/mail-sig"
      not
         macro "body.current_thread.links[].href_url.domain.domain in tenant_domains"
      or
         macro "body.current_thread.links[].href_url.domain.root_domain in free_file_hosts"
         macro "body.current_thread.links[].href_url.domain.root_domain in free_subdomain_hosts"
      body.current_thread.links.visible eq "true"
  not
    or
      any(headers.hops)
        any(headers.hops.fields)
          headers.hops.fields.name eq "List-Unsubscribe"
      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"
  not
    and
      or
        headers.return_path.domain.root_domain in ["twilio.com", "zendesk.com"]
        sender.email.domain.root_domain in ["twilio.com", "zendesk.com"]
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
  or
    and
      not
        profile.by_sender func_call "profile.by_sender().solicited"
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
    not
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
    profile.by_sender_email func_call "profile.by_sender_email().days_since.last_inbound > 365"
  or
    any(body.previous_threads)
      body.previous_threads.sender.email.email cross_field_compare "mailbox.email.email"
    body.previous_threads length_compare "0"
  or
    and
      recipients.bcc length_compare "0"
      recipients.cc length_compare "0"
      recipients.to length_compare "1"
       macro "all(recipients.to)"
    and
      recipients.bcc length_compare "0"
      recipients.to length_compare "0"
    and
      recipients.cc length_compare "0"
      recipients.to length_compare "0"
    any(recipients.to)
      recipients.to.display_name eq "undisclosed?recipients"
  filter(body.current_thread.links, .href_url.domain.root_domain not in ('x.com', 'facebook.com', 'twitter.com', 'instagram.com', 'youtube.com', 'linkedin.com')) length_compare "0"
  filter(body.current_thread.links, .href_url.domain.root_domain not in ('x.com', 'facebook.com', 'twitter.com', 'instagram.com', 'youtube.com', 'linkedin.com')) length_compare "10"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.hopsarray_any(no value, null check)excludes:headers.hops
ml.nlu_classifier(body.current_thread.text).intentsarray_any(no value, null check)excludes:ml.nlu_classifier(body.current_thread.text).intents
headers.return_path.domain.root_domainintwilio.com, zendesk.comexcludes:headers.return_path.domain.root_domain field:"headers.return_path.domain.root_domain" value:"twilio.com" field:"headers.return_path.domain.root_domain" value:"zendesk.com"
sender.email.domain.root_domainintwilio.com, zendesk.comexcludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"twilio.com" field:"sender.email.domain.root_domain" value:"zendesk.com"

Indicators

These rows show field, operator, and value matches.

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

Link: Generic financial document with proceedural timeline template

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

Detects messages with generic greetings that reference payment releases & timelines, and exhibit unusual recipient patterns such as self-sending or missing recipients.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Credential Phishing
Tactics and techniquesSocial engineering, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.links
  • recipients
  • recipients.to
  • recipients.to[0]
  • sender.email
  • type

Rule body

type.inbound
// link limiter scopes thread hijacking but limits reports
and length(body.links) <= 40

// expectation of time
and regex.icontains(body.current_thread.text,
                    'will be released.{0,15}(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday),\s+(?:January|February|March|April|May|June|July|August|September|October|November|December)\s+\d{1,2},',
                    '\b[1-4]\W[1-4]\b.{1,10}days'
)

// link is malicious
and any(body.links,
        // key phrasing or nlu
        (
          regex.icontains(.display_text,
                          '(?:access|show|view).{0,10}(?:confirmation|message|payment|statement)',
                          'advice',
                          'deposit',
                          'document',
                          'eft',
                          'release',
                          'remit'
          )
          or any(ml.nlu_classifier(body.current_thread.text).topics,
                 .name == "Request to View Invoice" and .confidence == "high"
          )
        )
        // suspicious hosting
        and (
          .href_url.domain.domain in $free_file_hosts
          or .href_url.domain.root_domain in $free_file_hosts
          or .href_url.domain.tld in $suspicious_tlds
          or .href_url.domain.domain in $self_service_creation_platform_domains
          or (
            .href_url.domain.root_domain not in $tranco_1m
            and not .href_url.scheme == "mailto"
          )
          or .href_url.domain.root_domain in $url_shorteners
          // open redirect
          or strings.icontains(.href_url.query_params, '=https', 'url=', 'upn=')
          // bait and switch CTA observed
          or (
            strings.icontains(body.current_thread.text, "[message clipped]")
            and strings.icontains(.display_text, "view entire message")
          )
        )
        // negate org domains
        and .href_url.domain.valid != false
        and .href_url.domain.root_domain not in $org_domains
)

// suspicious sender behavior
and (
  (
    length(recipients.to) == 1
    and length(recipients.cc) == 0
    and sender.email.email == recipients.to[0].email.email
  )
  // the recipient is undisclosed or there are no recipients
  or (
    length(recipients.to) == 0
    or all(recipients.to, .email.domain.valid == false)
  )
)

Detection logic

Scope: inbound message.

Detects messages with generic greetings that reference payment releases & timelines, and exhibit unusual recipient patterns such as self-sending or missing recipients.

  1. inbound message
  2. length(body.links) ≤ 40
  3. body.current_thread.text matches any of 2 patterns
    • will be released.{0,15}(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday),\s+(?:January|February|March|April|May|June|July|August|September|October|November|December)\s+\d{1,2},
    • \b[1-4]\W[1-4]\b.{1,10}days
  4. any of body.links where all hold:
    • any of:
      • .display_text matches any of 7 patterns
        • (?:access|show|view).{0,10}(?:confirmation|message|payment|statement)
        • advice
        • deposit
        • document
        • eft
        • release
        • remit
      • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
        • .name is 'Request to View Invoice'
        • .confidence is 'high'
    • any of:
      • .href_url.domain.domain in $free_file_hosts
      • .href_url.domain.root_domain in $free_file_hosts
      • .href_url.domain.tld in $suspicious_tlds
      • .href_url.domain.domain in $self_service_creation_platform_domains
      • all of:
        • .href_url.domain.root_domain not in $tranco_1m
        • not:
          • .href_url.scheme is 'mailto'
      • .href_url.domain.root_domain in $url_shorteners
      • .href_url.query_params contains any of 3 patterns
        • =https
        • url=
        • upn=
      • all of:
        • body.current_thread.text contains '[message clipped]'
        • .display_text contains 'view entire message'
    • .href_url.domain.valid is not False
    • .href_url.domain.root_domain not in $org_domains
  5. any of:
    • all of:
      • length(recipients.to) is 1
      • length(recipients.cc) is 0
      • sender.email.email is recipients.to[0].email.email
    • any of:
      • length(recipients.to) is 0
      • all of recipients.to where:
        • .email.domain.valid is False

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.domain.tld, body.links[].href_url.domain.valid, body.links[].href_url.query_params, body.links[].href_url.scheme, recipients.cc, recipients.to, recipients.to[0].email.email, recipients.to[].email.domain.valid, sender.email.email, type.inbound. Sensors: ml.nlu_classifier, regex.icontains, strings.icontains. Reference lists: $free_file_hosts, $org_domains, $self_service_creation_platform_domains, $suspicious_tlds, $tranco_1m, $url_shorteners.

Indicators matched (16)

FieldMatchValue
regex.icontainsregexwill be released.{0,15}(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday),\s+(?:January|February|March|April|May|June|July|August|September|October|November|December)\s+\d{1,2},
regex.icontainsregex\b[1-4]\W[1-4]\b.{1,10}days
regex.icontainsregex(?:access|show|view).{0,10}(?:confirmation|message|payment|statement)
regex.icontainsregexadvice
regex.icontainsregexdeposit
regex.icontainsregexdocument
regex.icontainsregexeft
regex.icontainsregexrelease
regex.icontainsregexremit
ml.nlu_classifier(body.current_thread.text).topics[].nameequalsRequest to View Invoice
ml.nlu_classifier(body.current_thread.text).topics[].confidenceequalshigh
strings.icontainssubstring=https
4 more
strings.icontainssubstringurl=
strings.icontainssubstringupn=
strings.icontainssubstring[message clipped]
strings.icontainssubstringview entire message

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        and
          not
            body.links.href_url.scheme eq "mailto"
           macro "body.links[].href_url.domain.root_domain not in tranco_1m"
        and
          body.current_thread.text contains "[message clipped]"
          body.links.display_text contains "view entire message"
        body.links.href_url.query_params contains "=https"
        body.links.href_url.query_params contains "upn="
        body.links.href_url.query_params contains "url="
         macro "body.links[].href_url.domain.domain in free_file_hosts"
         macro "body.links[].href_url.domain.domain in self_service_creation_platform_domains"
         macro "body.links[].href_url.domain.root_domain in free_file_hosts"
         macro "body.links[].href_url.domain.root_domain in url_shorteners"
         macro "body.links[].href_url.domain.tld in suspicious_tlds"
      or
        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 "Request to View Invoice"
        body.links.display_text regex_match "(?:access|show|view).{0,10}(?:confirmation|message|payment|statement)"
        body.links.display_text regex_match "advice"
        body.links.display_text regex_match "deposit"
        body.links.display_text regex_match "document"
        body.links.display_text regex_match "eft"
        body.links.display_text regex_match "release"
        body.links.display_text regex_match "remit"
      body.links.href_url.domain.valid ne "false"
       macro "body.links[].href_url.domain.root_domain not in org_domains"
  or
    and
      recipients.cc length_compare "0"
      recipients.to length_compare "1"
      sender.email.email cross_field_compare "recipients.to[0].email.email"
    recipients.to length_compare "0"
     macro "all(recipients.to)"
  or
    body.current_thread.text regex_match "\\b[1-4]\\W[1-4]\\b.{1,10}days"
    body.current_thread.text regex_match "will be released.{0,15}(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday),\\s+(?:January|February|March|April|May|June|July|August|September|October|November|December)\\s+\\d{1,2},"
  body.links length_compare "40"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textregex_match
  • \b[1-4]\W[1-4]\b.{1,10}days
  • will be released.{0,15}(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday),\s+(?:January|February|March|April|May|June|July|August|September|October|November|December)\s+\d{1,2},
field:"body.current_thread.text" kind:regex_match
sender.email.emailcross_field_compare
  • recipients.to[0].email.email transforms: op:eq
field:"sender.email.email" kind:cross_field_compare value:"recipients.to[0].email.email"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link: Google Calendar invite linking to an open redirect from an untrusted freemail sender

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

Attackers invite users to view a Google Calendar whose name contains a suspicious link, generally linking to spam content such as crypto giveaways, using open redirects to mask the true destination.

Threat classification

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

CategoryValues
Attack typesSpam
Tactics and techniquesFree email provider, Free file host, ICS Phishing, Open redirect, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
and strings.iends_with(subject.subject, "has shared a calendar with you")
and strings.ilike(headers.message_id, "<calendar*@google.com>")
and sender.email.domain.domain in $free_email_providers
and any(body.links,
        any(.href_url.rewrite.encoders, strings.icontains(., "open_redirect"))
        or (
          any(ml.link_analysis(.).final_dom.links,
              any(.href_url.rewrite.encoders,
                  strings.icontains(., "open_redirect")
              )
          )
        )
)
and profile.by_sender().prevalence in ("new", "outlier")
// 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
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)

Detection logic

Scope: inbound message.

Attackers invite users to view a Google Calendar whose name contains a suspicious link, generally linking to spam content such as crypto giveaways, using open redirects to mask the true destination.

  1. inbound message
  2. subject.subject ends with 'has shared a calendar with you'
  3. headers.message_id matches '<calendar*@google.com>'
  4. sender.email.domain.domain in $free_email_providers
  5. any of body.links where any holds:
    • any of .href_url.rewrite.encoders where:
      • . contains 'open_redirect'
    • any of ml.link_analysis(.).final_dom.links where:
      • any of .href_url.rewrite.encoders where:
        • . contains 'open_redirect'
  6. profile.by_sender().prevalence in ('new', 'outlier')
  7. 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
  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

Inspects: body.links, body.links[].href_url.rewrite.encoders, headers.hops, headers.hops[].authentication_results.dmarc, headers.message_id, sender.email.domain.domain, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: ml.link_analysis, profile.by_sender, strings.icontains, strings.iends_with, strings.ilike. Reference lists: $free_email_providers, $high_trust_sender_root_domains.

Indicators matched (4)

FieldMatchValue
strings.iends_withsuffixhas shared a calendar with you
strings.ilikesubstring<calendar*@google.com>
strings.icontainssubstringopen_redirect
strings.ilikesubstring*fail

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    or
      any(ml.link_analysis(body.links).final_dom.links)
        any(ml.link_analysis(body.links).final_dom.links.href_url.rewrite.encoders)
          ml.link_analysis(body.links).final_dom.links.href_url.rewrite.encoders contains "open_redirect"
      any(body.links.href_url.rewrite.encoders)
        body.links.href_url.rewrite.encoders contains "open_redirect"
  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"
  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"
  headers.message_id wildcard "<calendar*@google.com>"
  profile.by_sender func_call "profile.by_sender().prevalence in (new, outlier)"
  subject.subject ends_with "has shared a calendar with you"
  type.inbound eq "true"
   macro "sender.email.domain.domain in free_email_providers"

Indicators

These rows show field, operator, and value matches.

Link: Google Cloud Storage hosted credential harvesting page

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

Detects inbound messages containing links to Google Cloud Storage (storage.googleapis.com) that follow a pattern of randomized bucket paths ending in a hashed directory and an index.html file. These links have been observed in messages impersonating professional networking and HR platform notifications, such as those mimicking recruiting outreach or job opportunity alerts from services like Sloneek and BambooHR, luring recipients to hosted credential harvesting pages.

Threat classification

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

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

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        (
          .href_url.domain.domain == "storage.googleapis.com"
          and regex.icontains(.href_url.path,
                              '^\/(?:[^-]+\-+)+[0-9a-f]{20}\/index\.html$'
          )
        )
        // workstream endcodes the URLs with sendgrid, if we click them, we can see if they redirect to the same strcuture
        or (
          .href_url.domain.domain == "sendgridlinks.workstream.is"
          and any(ml.link_analysis(., mode="aggressive").redirect_history,
                  .domain.domain == "storage.googleapis.com"
                  and regex.icontains(.path,
                                      '^\/(?:[^-]+\-+)+[0-9a-f]{20}\/index\.html$'
                  )
          )
        )
)

Detection logic

Scope: inbound message.

Detects inbound messages containing links to Google Cloud Storage (storage.googleapis.com) that follow a pattern of randomized bucket paths ending in a hashed directory and an index.html file. These links have been observed in messages impersonating professional networking and HR platform notifications, such as those mimicking recruiting outreach or job opportunity alerts from services like Sloneek and BambooHR, luring recipients to hosted credential harvesting pages.

  1. inbound message
  2. any of body.links where any holds:
    • all of:
      • .href_url.domain.domain is 'storage.googleapis.com'
      • .href_url.path matches '^\\/(?:[^-]+\\-+)+[0-9a-f]{20}\\/index\\.html$'
    • all of:
      • .href_url.domain.domain is 'sendgridlinks.workstream.is'
      • any of ml.link_analysis(., mode='aggressive').redirect_history where all hold:
        • .domain.domain is 'storage.googleapis.com'
        • .path matches '^\\/(?:[^-]+\\-+)+[0-9a-f]{20}\\/index\\.html$'

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.path, type.inbound. Sensors: ml.link_analysis, regex.icontains.

Indicators matched (4)

FieldMatchValue
body.links[].href_url.domain.domainequalsstorage.googleapis.com
regex.icontainsregex^\/(?:[^-]+\-+)+[0-9a-f]{20}\/index\.html$
body.links[].href_url.domain.domainequalssendgridlinks.workstream.is
ml.link_analysis(body.links[], mode='aggressive').redirect_history[].domain.domainequalsstorage.googleapis.com

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    or
      and
        any(ml.link_analysis(body.links, mode='aggressive').redirect_history)
          and
            ml.link_analysis(body.links[], mode='aggressive').redirect_history[].domain.domain eq "storage.googleapis.com"
            ml.link_analysis(body.links[], mode='aggressive').redirect_history[].path regex_match "^\\/(?:[^-]+\\-+)+[0-9a-f]{20}\\/index\\.html$"
        body.links.href_url.domain.domain eq "sendgridlinks.workstream.is"
      and
        body.links.href_url.domain.domain eq "storage.googleapis.com"
        body.links.href_url.path regex_match "^\\/(?:[^-]+\\-+)+[0-9a-f]{20}\\/index\\.html$"
  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"

Link: Google Cloud Storage impersonating with googledrive in URL path

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

Detects inbound messages containing links to Google Cloud Storage (storage.googleapis.com) with paths ending in 'googledrive.html', indicating abuse of Google's cloud storage service to impersonate Google Drive and potentially deliver malicious content.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Free file host

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        // use of storage.googleapis.com
        .href_url.domain.domain == "storage.googleapis.com"
        // with an actor controlled path that impersonates Google Drive
        and strings.iends_with(.href_url.path, 'googledrive.html')
)

Detection logic

Scope: inbound message.

Detects inbound messages containing links to Google Cloud Storage (storage.googleapis.com) with paths ending in 'googledrive.html', indicating abuse of Google's cloud storage service to impersonate Google Drive and potentially deliver malicious content.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.domain.domain is 'storage.googleapis.com'
    • .href_url.path ends with 'googledrive.html'

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.path, type.inbound. Sensors: strings.iends_with.

Indicators matched (2)

FieldMatchValue
body.links[].href_url.domain.domainequalsstorage.googleapis.com
strings.iends_withsuffixgoogledrive.html

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      body.links.href_url.domain.domain eq "storage.googleapis.com"
      body.links.href_url.path ends_with "googledrive.html"
  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"

Link: Google Cloud Storage link with index.php in URL

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

Detects inbound messages containing links hosted on storage.googleapis.com that point to an index.php path, either in the URL path or fragment. Attackers abuse Google Cloud Storage to host malicious content, leveraging the trusted domain to bypass security filters.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Free file host, Open redirect

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        .href_url.domain.domain == "storage.googleapis.com"
        and (
          strings.iends_with(.href_url.path, 'index.php')
          or regex.icontains(.href_url.fragment, '^\/?index.php')
        )
)

Detection logic

Scope: inbound message.

Detects inbound messages containing links hosted on storage.googleapis.com that point to an index.php path, either in the URL path or fragment. Attackers abuse Google Cloud Storage to host malicious content, leveraging the trusted domain to bypass security filters.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.domain.domain is 'storage.googleapis.com'
    • any of:
      • .href_url.path ends with 'index.php'
      • .href_url.fragment matches '^\\/?index.php'

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.fragment, body.links[].href_url.path, type.inbound. Sensors: regex.icontains, strings.iends_with.

Indicators matched (3)

FieldMatchValue
body.links[].href_url.domain.domainequalsstorage.googleapis.com
strings.iends_withsuffixindex.php
regex.icontainsregex^\/?index.php

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        body.links.href_url.fragment regex_match "^\\/?index.php"
        body.links.href_url.path ends_with "index.php"
      body.links.href_url.domain.domain eq "storage.googleapis.com"
  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"

Link: Google Cloud Storage link with redirect.html in URL

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

Detects inbound messages containing links that route through a redirect.html page hosted on Google Cloud Storage (storage.googleapis.com). Attackers abuse legitimate cloud storage infrastructure to host redirect pages that forward victims to malicious destinations, evading URL reputation checks.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Free file host, Open redirect

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        (
          strings.iends_with(.href_url.path, 'redirect.html')
          or strings.istarts_with(.href_url.fragment, '/redirect.html')
        )
        and .href_url.domain.domain == "storage.googleapis.com"
) 

Detection logic

Scope: inbound message.

Detects inbound messages containing links that route through a redirect.html page hosted on Google Cloud Storage (storage.googleapis.com). Attackers abuse legitimate cloud storage infrastructure to host redirect pages that forward victims to malicious destinations, evading URL reputation checks.

  1. inbound message
  2. any of body.links where all hold:
    • any of:
      • .href_url.path ends with 'redirect.html'
      • .href_url.fragment starts with '/redirect.html'
    • .href_url.domain.domain is 'storage.googleapis.com'

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.fragment, body.links[].href_url.path, type.inbound. Sensors: strings.iends_with, strings.istarts_with.

Indicators matched (3)

FieldMatchValue
strings.iends_withsuffixredirect.html
strings.istarts_withprefix/redirect.html
body.links[].href_url.domain.domainequalsstorage.googleapis.com

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        body.links.href_url.fragment starts_with "/redirect.html"
        body.links.href_url.path ends_with "redirect.html"
      body.links.href_url.domain.domain eq "storage.googleapis.com"
  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"

Link: Google Cloud Storage redirect to external domain

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

Messages contain links hosted on storage.googleapis.com that, when followed, redirect to a destination outside of googleapis.com. This technique abuses Google Cloud Storage's trusted reputation to bypass link reputation checks, with the actual payload hosted on an unrelated external domain. Observed lures include parcel delivery notifications impersonating shipping carriers (UPS, GLS), gambling bonus offers, health product promotions, and storage quota warnings.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Spam, Malware/Ransomware
Tactics and techniquesFree file host, Open redirect, Impersonation: Brand, Social engineering, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        .href_url.domain.domain == "storage.googleapis.com"
        and ml.link_analysis(., mode="aggressive").effective_url.domain.root_domain != "googleapis.com"
)

Detection logic

Scope: inbound message.

Messages contain links hosted on storage.googleapis.com that, when followed, redirect to a destination outside of googleapis.com. This technique abuses Google Cloud Storage's trusted reputation to bypass link reputation checks, with the actual payload hosted on an unrelated external domain. Observed lures include parcel delivery notifications impersonating shipping carriers (UPS, GLS), gambling bonus offers, health product promotions, and storage quota warnings.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.domain.domain is 'storage.googleapis.com'
    • ml.link_analysis(.).effective_url.domain.root_domain is not 'googleapis.com'

Inspects: body.links, body.links[].href_url.domain.domain, type.inbound. Sensors: ml.link_analysis.

Indicators matched (1)

FieldMatchValue
body.links[].href_url.domain.domainequalsstorage.googleapis.com

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      body.links.href_url.domain.domain eq "storage.googleapis.com"
      ml.link_analysis func_call "ml.link_analysis(body.links[]).effective_url.domain.root_domain != googleapis.com"
  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"

Link: Google Cloud Storage with short-path link delivery

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

Detects inbound messages containing links to Google Cloud Storage (storage.googleapis.com) where the URL path ends in 'ls' or 'lis', matching a pattern used to host redirector or landing pages. Observed across multilingual spam and unsolicited promotional messages — including fake parcel delivery notifications impersonating FedEx and T&T, as well as product advertisement lures — sent from a variety of compromised or unrelated sender domains. The consistent use of this specific GCS path pattern suggests a shared delivery infrastructure across multiple senders.

Threat classification

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

CategoryValues
Attack typesSpam, Credential Phishing
Tactics and techniquesFree file host, Evasion, Social engineering, Impersonation: Brand

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        .href_url.domain.domain == "storage.googleapis.com"
        // path ends with lis or ls
        and regex.icontains(.href_url.path, '^/[^\/]+/li?s$')
)

Detection logic

Scope: inbound message.

Detects inbound messages containing links to Google Cloud Storage (storage.googleapis.com) where the URL path ends in 'ls' or 'lis', matching a pattern used to host redirector or landing pages. Observed across multilingual spam and unsolicited promotional messages — including fake parcel delivery notifications impersonating FedEx and T&T, as well as product advertisement lures — sent from a variety of compromised or unrelated sender domains. The consistent use of this specific GCS path pattern suggests a shared delivery infrastructure across multiple senders.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.domain.domain is 'storage.googleapis.com'
    • .href_url.path matches '^/[^\\/]+/li?s$'

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.path, type.inbound. Sensors: regex.icontains.

Indicators matched (2)

FieldMatchValue
body.links[].href_url.domain.domainequalsstorage.googleapis.com
regex.icontainsregex^/[^\/]+/li?s$

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      body.links.href_url.domain.domain eq "storage.googleapis.com"
      body.links.href_url.path regex_match "^/[^\\/]+/li?s$"
  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"

Link: Google Cloud Storage with suspicious URL pattern

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

Detects inbound messages containing links to Google Cloud Storage (storage.googleapis.com) with suspicious URL path patterns that follow a specific actor-controlled structure commonly used for hosting malicious content.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesFree file host, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        // storage.googleapis.com
        .href_url.domain.domain == "storage.googleapis.com"
        // observed pattern in actor controlled url path
        and regex.contains(.href_url.path,
                           '^\/[a-z0-9]+-[a-z0-9]+-\d{8}\-[0-9a-f]+\/[^\.]+\.html'
        )
)

Detection logic

Scope: inbound message.

Detects inbound messages containing links to Google Cloud Storage (storage.googleapis.com) with suspicious URL path patterns that follow a specific actor-controlled structure commonly used for hosting malicious content.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.domain.domain is 'storage.googleapis.com'
    • .href_url.path matches '^\\/[a-z0-9]+-[a-z0-9]+-\\d{8}\\-[0-9a-f]+\\/[^\\.]+\\.html'

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.path, type.inbound. Sensors: regex.contains.

Indicators matched (2)

FieldMatchValue
body.links[].href_url.domain.domainequalsstorage.googleapis.com
regex.containsregex^\/[a-z0-9]+-[a-z0-9]+-\d{8}\-[0-9a-f]+\/[^\.]+\.html

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      body.links.href_url.domain.domain eq "storage.googleapis.com"
      body.links.href_url.path regex_match "^\\/[a-z0-9]+-[a-z0-9]+-\\d{8}\\-[0-9a-f]+\\/[^\\.]+\\.html"
  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"

Link: Google Drawings link from new sender

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

Detects messages containing Google Drawings links from previously unseen senders, which may indicate abuse of Google's drawing service for malicious content delivery.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, BEC/Fraud
Tactics and techniquesSocial engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • type

Rule body

type.inbound
// google drawings link
and any(body.current_thread.links,
        .href_url.domain.domain == "docs.google.com"
        and strings.istarts_with(.href_url.path, '/drawings')
        and (
          strings.icontains(.href_url.path, '/preview')
          or any(ml.nlu_classifier(body.current_thread.text).intents,
                 .name == "cred_theft" and .confidence != "low"
          )
        )
)
and profile.by_sender_email().prevalence == "new"

Detection logic

Scope: inbound message.

Detects messages containing Google Drawings links from previously unseen senders, which may indicate abuse of Google's drawing service for malicious content delivery.

  1. inbound message
  2. any of body.current_thread.links where all hold:
    • .href_url.domain.domain is 'docs.google.com'
    • .href_url.path starts with '/drawings'
    • any of:
      • .href_url.path contains '/preview'
      • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
        • .name is 'cred_theft'
        • .confidence is not 'low'
  3. profile.by_sender_email().prevalence is 'new'

Inspects: body.current_thread.links, body.current_thread.links[].href_url.domain.domain, body.current_thread.links[].href_url.path, body.current_thread.text, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender_email, strings.icontains, strings.istarts_with.

Indicators matched (4)

FieldMatchValue
body.current_thread.links[].href_url.domain.domainequalsdocs.google.com
strings.istarts_withprefix/drawings
strings.icontainssubstring/preview
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    and
      or
        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"
        body.current_thread.links.href_url.path contains "/preview"
      body.current_thread.links.href_url.domain.domain eq "docs.google.com"
      body.current_thread.links.href_url.path starts_with "/drawings"
  profile.by_sender_email func_call "profile.by_sender_email().prevalence == new"
  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"

Link: Google Firebase dynamic link that redirects to new domain (<7 days old)

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

An attacker may use Google's Firebase Dynamic Links to redirect a user to a malicious site. This rule identifies Firebase Dynamic Links where the destination domain is less than a week old.

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
  • type

Rule body

type.inbound
and any(body.links,
        .href_url.domain.root_domain =~ "goo.gl"
        and strings.icontains(.href_url.domain.domain, "app")
        and any(ml.link_analysis(.).redirect_history,
                network.whois(.domain).days_old < 7
        )
)

Detection logic

Scope: inbound message.

An attacker may use Google's Firebase Dynamic Links to redirect a user to a malicious site. This rule identifies Firebase Dynamic Links where the destination domain is less than a week old.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.domain.root_domain is 'goo.gl'
    • .href_url.domain.domain contains 'app'
    • any of ml.link_analysis(.).redirect_history where:
      • network.whois(.domain).days_old < 7

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, type.inbound. Sensors: ml.link_analysis, network.whois, strings.icontains.

Indicators matched (2)

FieldMatchValue
body.links[].href_url.domain.root_domainequalsgoo.gl
strings.icontainssubstringapp

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      any(ml.link_analysis(body.links).redirect_history)
        network.whois func_call "network.whois(ml.link_analysis(body.links[]).redirect_history[].domain).days_old < 7"
      body.links.href_url.domain.domain contains "app"
      body.links.href_url.domain.root_domain eq "goo.gl"
  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"

Link: Google Forms link with credential theft language

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

Detects messages containing Google Forms links paired with credential theft language from new senders. This technique abuses Google's trusted domain to host malicious forms designed to steal user credentials.

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

  • body
  • body.current_thread
  • type

Rule body

type.inbound
// cred_theft intent
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft" and .confidence != "low"
)
// google form link
and any(body.current_thread.links,
        (
          .href_url.domain.domain == "docs.google.com"
          and strings.istarts_with(.href_url.path, '/form')
        )
        or .href_url.domain.root_domain == "forms.gle"
)
// new sender
and profile.by_sender_email().prevalence == "new"

Detection logic

Scope: inbound message.

Detects messages containing Google Forms links paired with credential theft language from new senders. This technique abuses Google's trusted domain to host malicious forms designed to steal user credentials.

  1. inbound message
  2. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name is 'cred_theft'
    • .confidence is not 'low'
  3. any of body.current_thread.links where any holds:
    • all of:
      • .href_url.domain.domain is 'docs.google.com'
      • .href_url.path starts with '/form'
    • .href_url.domain.root_domain is 'forms.gle'
  4. profile.by_sender_email().prevalence is 'new'

Inspects: body.current_thread.links, body.current_thread.links[].href_url.domain.domain, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.links[].href_url.path, body.current_thread.text, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender_email, strings.istarts_with.

Indicators matched (4)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
body.current_thread.links[].href_url.domain.domainequalsdocs.google.com
strings.istarts_withprefix/form
body.current_thread.links[].href_url.domain.root_domainequalsforms.gle

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    or
      and
        body.current_thread.links.href_url.domain.domain eq "docs.google.com"
        body.current_thread.links.href_url.path starts_with "/form"
      body.current_thread.links.href_url.domain.root_domain eq "forms.gle"
  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"
  profile.by_sender_email func_call "profile.by_sender_email().prevalence == new"
  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"

Link: Google Translate (unsolicited)

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

Attackers have used the Google Translate service to deliver links to malicious sites repackaged with a translate.goog top-level domain. This rule identifies instances of Google Translate links from unsolicited senders.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesOpen redirect

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        "google_translate_open_redirect" in .href_url.rewrite.encoders
)
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.

Attackers have used the Google Translate service to deliver links to malicious sites repackaged with a translate.goog top-level domain. This rule identifies instances of Google Translate links from unsolicited senders.

  1. inbound message
  2. any of body.links where:
    • .href_url.rewrite.encoders contains 'google_translate_open_redirect'
  3. any of:
    • not:
      • profile.by_sender().solicited
    • profile.by_sender().any_messages_malicious_or_spam
  4. not:
    • profile.by_sender().any_messages_benign

Inspects: body.links, body.links[].href_url.rewrite.encoders, type.inbound. Sensors: profile.by_sender.

Indicators matched (1)

FieldMatchValue
body.links[].href_url.rewrite.encoderscontainsgoogle_translate_open_redirect

Stages and Predicates

Stage 1: mql_rule

and
  or
    not
      profile.by_sender func_call "profile.by_sender().solicited"
    profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
  any(body.links)
    body.links.href_url.rewrite.encoders contains "google_translate_open_redirect"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  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"

Link: GoPhish query param values

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

Detects links containing a 7-character alphanumeric 'rid' (default) query parameter, or any other variant identified, commonly used in tracking and targeting systems for malicious purposes.

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
  • type

Rule body

type.inbound
and sender.email.domain.root_domain not in $tranco_50k
// few body links
and length(body.links) < 20
// Adding loop of different query param values
// https://github.com/fin3ss3g0d/evilgophish/blob/main/replace_rid.sh
and any(["mid", "rid"],
        any(body.links,
            // not a common marketing url rewriter
            not .href_url.domain.root_domain == "vtiger.com"
            and not strings.icontains(.href_url.url, "vtiger.com")
            // myshopify return tracking numbers
            and not (
              length(.href_url.query_params_decoded["tracking_number"]) == 1
              and length(.href_url.query_params_decoded[..]) == 1
            )
            // the mid value present
            and length(.href_url.query_params_decoded[..]) == 1
            // the mid value is 7 bytes
            and length(.href_url.query_params_decoded[..][0]) == 7
            // contains letters and numbers
            and regex.imatch(.href_url.query_params_decoded[..][0],
                             '^[a-z0-9]{7}$'
            )
            and not regex.match(.href_url.query_params_decoded[..][0],
                                // not just numbers - ~0.00046% chance of being all numbers
                                '^[0-9]{7}$',
                                // not just lower case letters ~0.31% chance of all lowercase
                                '^[a-z]{7}$',
                                // not just upper case letters ~0.31% chance of being all uppercase
                                '^[A-Z]{7}$',
                                // a single letter followed by digits has ~0.00151% chance
                                '^[A-Za-z]\d{6}$'
            )
            // and not a common value observed in benign samples
            and not .href_url.query_params_decoded[..][0] == "Emailer"
            // .href_url.query_params_decoded is the wrong type for length
            // so count the number of param values, and ensure it's 3 or less
            and regex.icount(.href_url.query_params, '=[^\=]+(?:&|$)') <= 3
        )
)
// not high trust sender domains
and not (
  sender.email.domain.root_domain in $high_trust_sender_root_domains
  and coalesce(headers.auth_summary.dmarc.pass, false)
)
and not profile.by_sender_email().any_messages_benign

Detection logic

Scope: inbound message.

Detects links containing a 7-character alphanumeric 'rid' (default) query parameter, or any other variant identified, commonly used in tracking and targeting systems for malicious purposes.

  1. inbound message
  2. sender.email.domain.root_domain not in $tranco_50k
  3. length(body.links) < 20
  4. any of ['mid', 'rid'] where:
    • any of body.links where all hold:
      • not:
        • .href_url.domain.root_domain is 'vtiger.com'
      • not:
        • .href_url.url contains 'vtiger.com'
      • not:
        • all of:
          • length(.href_url.query_params_decoded['tracking_number']) is 1
          • length(.href_url.query_params_decoded[]) is 1
      • length(.href_url.query_params_decoded[]) is 1
      • length(.href_url.query_params_decoded[][0]) is 7
      • .href_url.query_params_decoded[][0] matches '^[a-z0-9]{7}$'
      • not:
        • .href_url.query_params_decoded[][0] matches any of 4 patterns
          • ^[0-9]{7}$
          • ^[a-z]{7}$
          • ^[A-Z]{7}$
          • ^[A-Za-z]\d{6}$
      • not:
        • .href_url.query_params_decoded[][0] is 'Emailer'
      • regex.icount(.href_url.query_params, '=[^\\=]+(?:&|$)') ≤ 3
  5. not:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • coalesce(headers.auth_summary.dmarc.pass)
  6. not:
    • profile.by_sender_email().any_messages_benign

Inspects: body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.query_params, body.links[].href_url.query_params_decoded['tracking_number'], body.links[].href_url.query_params_decoded[], body.links[].href_url.query_params_decoded[][0], body.links[].href_url.url, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender_email, regex.icount, regex.imatch, regex.match, strings.icontains. Reference lists: $high_trust_sender_root_domains, $tranco_50k.

Indicators matched (2)

FieldMatchValue
regex.imatchregex^[a-z0-9]{7}$
regex.icountregex=[^\=]+(?:&|$)

Stages and Predicates

Stage 1: mql_rule

and
  any(['mid', 'rid'])
    any(body.links)
      and
        not
          and
            body.links.href_url.query_params_decoded['tracking_number'] length_compare "1"
            body.links.href_url.query_params_decoded[] length_compare "1"
        not
          or
            body.links.href_url.query_params_decoded[][0] regex_match "^[0-9]{7}$"
            body.links.href_url.query_params_decoded[][0] regex_match "^[A-Z]{7}$"
            body.links.href_url.query_params_decoded[][0] regex_match "^[A-Za-z]\\d{6}$"
            body.links.href_url.query_params_decoded[][0] regex_match "^[a-z]{7}$"
        not
          body.links.href_url.domain.root_domain eq "vtiger.com"
        not
          body.links.href_url.query_params_decoded[][0] eq "Emailer"
        not
          body.links.href_url.url contains "vtiger.com"
        body.links.href_url.query_params_decoded[] length_compare "1"
        body.links.href_url.query_params_decoded[][0] length_compare "7"
        body.links.href_url.query_params_decoded[][0] regex_match "^[a-z0-9]{7}$"
        regex.icount func_call "regex.icount(body.links[].href_url.query_params, \"=[^\\=]+(?:&|$)\") <= 3"
  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_email func_call "profile.by_sender_email().any_messages_benign"
  body.links length_compare "20"
  type.inbound eq "true"
   macro "sender.email.domain.root_domain not in tranco_50k"

Indicators

These rows show field, operator, and value matches.

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

Link: Hotel booking spoofed display URL

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

Detects messages containing links with hotel-related display URLs that either redirect to different domains or contain suspicious parameters commonly used in booking scams and fraudulent hotel reservation schemes.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Credential Phishing
Tactics and techniquesEvasion, 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 any(body.links,
        strings.icontains(.display_url.url, 'booking.com')
        and not strings.icontains(.href_url.url,
                                  .display_url.domain.root_domain
        )
        and .display_url.domain.root_domain != .href_url.domain.root_domain
        and (
          regex.icontains(.display_url.url,
                          '(?:aid=\d{6}|label=gen\d+nr|review-bad|\b\w+\.html|expirince|hoteladmin|feedback)'
          )
          or .href_url.domain.root_domain == "share.google"
          or network.whois(.href_url.domain).days_old < 30
        )
        and .mismatched
)
and not strings.icontains(body.current_thread.text,
                          "unsubscribe from this list"
)
and not (
  sender.email.domain.root_domain == "booking.com"
  and coalesce(headers.auth_summary.dmarc.pass, false)
)

Detection logic

Scope: inbound message.

Detects messages containing links with hotel-related display URLs that either redirect to different domains or contain suspicious parameters commonly used in booking scams and fraudulent hotel reservation schemes.

  1. inbound message
  2. any of body.links where all hold:
    • .display_url.url contains 'booking.com'
    • not:
      • strings.icontains(.href_url.url)
    • .display_url.domain.root_domain is not .href_url.domain.root_domain
    • any of:
      • .display_url.url matches '(?:aid=\\d{6}|label=gen\\d+nr|review-bad|\\b\\w+\\.html|expirince|hoteladmin|feedback)'
      • .href_url.domain.root_domain is 'share.google'
      • network.whois(.href_url.domain).days_old < 30
    • .mismatched
  3. not:
    • body.current_thread.text contains 'unsubscribe from this list'
  4. not:
    • all of:
      • sender.email.domain.root_domain is 'booking.com'
      • coalesce(headers.auth_summary.dmarc.pass)

Inspects: body.current_thread.text, body.links, body.links[].display_url.domain.root_domain, body.links[].display_url.url, body.links[].href_url.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.url, body.links[].mismatched, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: network.whois, regex.icontains, strings.icontains.

Indicators matched (3)

FieldMatchValue
strings.icontainssubstringbooking.com
regex.icontainsregex(?:aid=\d{6}|label=gen\d+nr|review-bad|\b\w+\.html|expirince|hoteladmin|feedback)
body.links[].href_url.domain.root_domainequalsshare.google

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        body.links.display_url.url regex_match "(?:aid=\\d{6}|label=gen\\d+nr|review-bad|\\b\\w+\\.html|expirince|hoteladmin|feedback)"
        body.links.href_url.domain.root_domain eq "share.google"
        network.whois func_call "network.whois(body.links[].href_url.domain).days_old < 30"
      not
        strings.icontains func_call "strings.icontains(body.links[].href_url.url)"
      body.links.display_url.domain.root_domain cross_field_compare "body.links.href_url.domain.root_domain"
      body.links.display_url.url contains "booking.com"
      body.links.mismatched eq "true"
  not
    and
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
      sender.email.domain.root_domain eq "booking.com"
  not
    body.current_thread.text contains "unsubscribe from this list"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
sender.email.domain.root_domaineqbooking.comexcludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"booking.com"
body.current_thread.textcontainsunsubscribe from this listexcludes:body.current_thread.text field:"body.current_thread.text" value:"unsubscribe from this list"

Indicators

These rows show field, operator, and value matches.

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

Link: HR impersonation with suspicious domain indicators and credential theft

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

Detects messages impersonating HR departments containing many links with malformed domains, suspicious TLD patterns, and credential theft language detected through URL analysis.

Threat classification

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

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

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.links
  • subject
  • type

Rule body

type.inbound
// high number of links
and length(body.links) > 20
// hr-related subject or sender
and (
  regex.icontains(sender.display_name, "\\bhr\\b")
  or strings.icontains(sender.display_name, "human resources")
  or strings.icontains(sender.display_name, "employee relation")
  or regex.icontains(subject.subject, "sal[ai1l|]r[i1l|]es")
  or regex.icontains(subject.subject, "hr__.{0,30}")
  or regex.icontains(subject.subject, "work.{0,5}hours")
  or regex.icontains(subject.subject,
                     "instant:.{0,20}(salaries|salary|changed|update)"
  )
  or strings.icontains(body.current_thread.text, "vacation plan")
)
// suspect domain irregularities (like www.,company.com)
and any(body.links,
        (
          // malformed domains with comma variations
          regex.icontains(.display_text, "www.?,")
          // multiple consecutive dots
          or regex.icontains(.display_text, "\\.{2,}")
          // comma in domain position  
          or regex.icontains(.display_text, "\\.,")
          // suspicious TLD patterns that might be typosquatting
          or regex.icontains(.display_text, "\\.(tu|cg|mv|tk|3v|ct|jh)/")
          // random characters in TLD position
          or regex.icontains(.display_text,
                             "\\.[a-z0-9]{1,3}/[a-z0-9]+/[a-z0-9]+/"
          )
          // URLs that contain obvious credential theft terms in the path
          or regex.icontains(.display_text,
                             "/(sal[ai1l|]r[i1l|]es|login|auth|verify|portal|payment)/"
          )
        )
        and .visible == true
        and any(ml.nlu_classifier(beta.ocr(ml.link_analysis(.).screenshot).text).intents,
                .name == "cred_theft" and .confidence == "high"
        )
)
// exclusions for legitimate sources 
and not any(ml.nlu_classifier(body.current_thread.text).topics,
            .name in (
              "Security and Authentication",
              "Secure Message",
              "Newsletters and Digests",
              "Entertainment and Sports"
            )
            and .confidence in ("medium", "high")
)
// exclude messages with a bunch of previous corrospondance
and not length(body.previous_threads) > 5

Detection logic

Scope: inbound message.

Detects messages impersonating HR departments containing many links with malformed domains, suspicious TLD patterns, and credential theft language detected through URL analysis.

  1. inbound message
  2. length(body.links) > 20
  3. any of:
    • sender.display_name matches '\\\\bhr\\\\b'
    • sender.display_name contains 'human resources'
    • sender.display_name contains 'employee relation'
    • subject.subject matches 'sal[ai1l|]r[i1l|]es'
    • subject.subject matches 'hr__.{0,30}'
    • subject.subject matches 'work.{0,5}hours'
    • subject.subject matches 'instant:.{0,20}(salaries|salary|changed|update)'
    • body.current_thread.text contains 'vacation plan'
  4. any of body.links where all hold:
    • .display_text matches any of 6 patterns
      • www.?,
      • \\.{2,}
      • \\.,
      • \\.(tu|cg|mv|tk|3v|ct|jh)/
      • \\.[a-z0-9]{1,3}/[a-z0-9]+/[a-z0-9]+/
      • /(sal[ai1l|]r[i1l|]es|login|auth|verify|portal|payment)/
    • .visible is True
    • any of ml.nlu_classifier(beta.ocr(ml.link_analysis(.).screenshot).text).intents where all hold:
      • .name is 'cred_theft'
      • .confidence is 'high'
  5. not:
    • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
      • .name in ('Security and Authentication', 'Secure Message', 'Newsletters and Digests', 'Entertainment and Sports')
      • .confidence in ('medium', 'high')
  6. not:
    • length(body.previous_threads) > 5

Inspects: body.current_thread.text, body.links, body.links[].display_text, body.links[].visible, body.previous_threads, sender.display_name, subject.subject, type.inbound. Sensors: beta.ocr, ml.link_analysis, ml.nlu_classifier, regex.icontains, strings.icontains.

Indicators matched (16)

FieldMatchValue
regex.icontainsregex\\bhr\\b
strings.icontainssubstringhuman resources
strings.icontainssubstringemployee relation
regex.icontainsregexsal[ai1l|]r[i1l|]es
regex.icontainsregexhr__.{0,30}
regex.icontainsregexwork.{0,5}hours
regex.icontainsregexinstant:.{0,20}(salaries|salary|changed|update)
strings.icontainssubstringvacation plan
regex.icontainsregexwww.?,
regex.icontainsregex\\.{2,}
regex.icontainsregex\\.,
regex.icontainsregex\\.(tu|cg|mv|tk|3v|ct|jh)/
4 more
regex.icontainsregex\\.[a-z0-9]{1,3}/[a-z0-9]+/[a-z0-9]+/
regex.icontainsregex/(sal[ai1l|]r[i1l|]es|login|auth|verify|portal|payment)/
ml.nlu_classifier(beta.ocr(ml.link_analysis(body.links[]).screenshot).text).intents[].nameequalscred_theft
ml.nlu_classifier(beta.ocr(ml.link_analysis(body.links[]).screenshot).text).intents[].confidenceequalshigh

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      any(ml.nlu_classifier(beta.ocr(ml.link_analysis(body.links).screenshot).text).intents)
        and
          ml.nlu_classifier(beta.ocr(ml.link_analysis(body.links[]).screenshot).text).intents[].confidence eq "high"
          ml.nlu_classifier(beta.ocr(ml.link_analysis(body.links[]).screenshot).text).intents[].name eq "cred_theft"
      or
        body.links.display_text regex_match "/(sal[ai1l|]r[i1l|]es|login|auth|verify|portal|payment)/"
        body.links.display_text regex_match "\\\\.(tu|cg|mv|tk|3v|ct|jh)/"
        body.links.display_text regex_match "\\\\.,"
        body.links.display_text regex_match "\\\\.[a-z0-9]{1,3}/[a-z0-9]+/[a-z0-9]+/"
        body.links.display_text regex_match "\\\\.{2,}"
        body.links.display_text regex_match "www.?,"
      body.links.visible eq "true"
  not
    any(ml.nlu_classifier(body.current_thread.text).topics)
      and
        ml.nlu_classifier(body.current_thread.text).topics.confidence in ["high", "medium"]
        ml.nlu_classifier(body.current_thread.text).topics.name in ["Entertainment and Sports", "Newsletters and Digests", "Secure Message", "Security and Authentication"]
  or
    body.current_thread.text contains "vacation plan"
    sender.display_name contains "employee relation"
    sender.display_name contains "human resources"
    sender.display_name regex_match "\\\\bhr\\\\b"
    subject.subject regex_match "hr__.{0,30}"
    subject.subject regex_match "instant:.{0,20}(salaries|salary|changed|update)"
    subject.subject regex_match "sal[ai1l|]r[i1l|]es"
    subject.subject regex_match "work.{0,5}hours"
  not
    body.previous_threads length_compare "5"
  body.links length_compare "20"
  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
body.previous_threadslength_compare5excludes:body.previous_threads field:"body.previous_threads" value:"5"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textcontains
  • vacation plan
field:"body.current_thread.text" kind:contains value:"vacation plan"
sender.display_namecontains
  • employee relation
  • human resources
field:"sender.display_name" kind:contains
sender.display_nameregex_match
  • \bhr\b
field:"sender.display_name" kind:regex_match value:"\bhr\b"
subject.subjectregex_match
  • hr__.{0,30}
  • instant:.{0,20}(salaries|salary|changed|update)
  • sal[ai1l|]r[i1l|]es
  • work.{0,5}hours
field:"subject.subject" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link: HTML file with suspicious binary fragment ending pattern

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

Detects links to HTML files containing fragments with a suspicious pattern of alphanumeric characters followed by a 5-digit binary sequence, commonly used in malicious URL structures.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        strings.ends_with(.href_url.path, '.html')
        and regex.contains(.href_url.fragment, '\-[a-z0-9]+[01]{5}$')
)

Detection logic

Scope: inbound message.

Detects links to HTML files containing fragments with a suspicious pattern of alphanumeric characters followed by a 5-digit binary sequence, commonly used in malicious URL structures.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.path ends with '.html'
    • .href_url.fragment matches '\\-[a-z0-9]+[01]{5}$'

Inspects: body.links, body.links[].href_url.fragment, body.links[].href_url.path, type.inbound. Sensors: regex.contains, strings.ends_with.

Indicators matched (2)

FieldMatchValue
strings.ends_withsuffix.html
regex.containsregex\-[a-z0-9]+[01]{5}$

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      body.links.href_url.fragment regex_match "\\-[a-z0-9]+[01]{5}$"
      body.links.href_url.path ends_with ".html"
  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"

Link: Invalid reply-to with recipient details in subject, body, and encoded link

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

Detects inbound messages with an invalid reply-to address where the recipient's domain SLD appears in the subject, the recipient's local part and domain SLD appear in the body, and the recipient's full email address is base64-encoded within a link fragment.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, BEC/Fraud
Tactics and techniquesSocial engineering, Evasion, Spoofing

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.reply_to
  • recipients
  • recipients.to[0]
  • subject
  • type

Rule body

type.inbound
// Invalid reply-to address
and any(headers.reply_to, not .email.domain.valid)
and strings.icontains(subject.base, recipients.to[0].email.domain.sld)
and strings.icontains(body.current_thread.text,
                      recipients.to[0].email.local_part
)
and strings.icontains(body.current_thread.text,
                      recipients.to[0].email.domain.sld
)
and any(body.current_thread.links,
        any(strings.scan_base64(.href_url.fragment),
            . == recipients.to[0].email.email
        )
)

Detection logic

Scope: inbound message.

Detects inbound messages with an invalid reply-to address where the recipient's domain SLD appears in the subject, the recipient's local part and domain SLD appear in the body, and the recipient's full email address is base64-encoded within a link fragment.

  1. inbound message
  2. any of headers.reply_to where:
    • not:
      • .email.domain.valid
  3. strings.icontains(subject.base)
  4. strings.icontains(body.current_thread.text)
  5. strings.icontains(body.current_thread.text)
  6. any of body.current_thread.links where:
    • any of strings.scan_base64(.href_url.fragment) where:
      • . is recipients.to[0].email.email

Inspects: body.current_thread.links, body.current_thread.links[].href_url.fragment, body.current_thread.text, headers.reply_to, headers.reply_to[].email.domain.valid, recipients.to[0].email.domain.sld, recipients.to[0].email.email, recipients.to[0].email.local_part, subject.base, type.inbound. Sensors: strings.icontains, strings.scan_base64.

Stages and Predicates

Stage 1: mql_rule

and
  any(headers.reply_to)
    not
      headers.reply_to.email.domain.valid eq "true"
  any(body.current_thread.links)
    any(strings.scan_base64(body.current_thread.links.href_url.fragment))
      strings.scan_base64(body.current_thread.links.href_url.fragment) cross_field_compare "recipients.to[0].email.email"
  strings.icontains func_call "strings.icontains(body.current_thread.text)"
  strings.icontains func_call "strings.icontains(subject.base)"
  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"

Link: Invoice or receipt from freemail sender with customer service number

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

An email from a freemail sender which instructs the recipient to call a fraudulent customer service number.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Callback Phishing
Tactics and techniquesFree email provider, Impersonation: Brand, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • sender.email
  • type

Rule body

type.inbound
and sender.email.domain.root_domain in $free_email_providers
and any(body.links,
        .display_text == "Unsubscribe"
        and (
          length(.href_url.query_params) == 0 or .href_url.query_params is null
        )
        and (
          .href_url.path == "/"
          or .href_url.path is null
          or (
            .href_url.domain.root_domain == "google.com"
            and not strings.ilike(.href_url.path, "*/forms/*")
          )
        )
)
and sender.email.email not in $sender_emails

Detection logic

Scope: inbound message.

An email from a freemail sender which instructs the recipient to call a fraudulent customer service number.

  1. inbound message
  2. sender.email.domain.root_domain in $free_email_providers
  3. any of body.links where all hold:
    • .display_text is 'Unsubscribe'
    • any of:
      • length(.href_url.query_params) is 0
      • .href_url.query_params is missing
    • any of:
      • .href_url.path is '/'
      • .href_url.path is missing
      • all of:
        • .href_url.domain.root_domain is 'google.com'
        • not:
          • .href_url.path matches '*/forms/*'
  4. sender.email.email not in $sender_emails

Inspects: body.links, body.links[].display_text, body.links[].href_url.domain.root_domain, body.links[].href_url.path, body.links[].href_url.query_params, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: strings.ilike. Reference lists: $free_email_providers, $sender_emails.

Indicators matched (3)

FieldMatchValue
body.links[].display_textequalsUnsubscribe
body.links[].href_url.pathequals/
body.links[].href_url.domain.root_domainequalsgoogle.com

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        and
          not
            body.links.href_url.path match "/forms/"
          body.links.href_url.domain.root_domain eq "google.com"
        body.links.href_url.path eq "/"
        body.links.href_url.path is_null
      or
        body.links.href_url.query_params is_null
        body.links.href_url.query_params length_compare "0"
      body.links.display_text eq "Unsubscribe"
  type.inbound eq "true"
   macro "sender.email.domain.root_domain in free_email_providers"
   macro "sender.email.email not in sender_emails"

Indicators

These rows show field, operator, and value matches.

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

Link: IPFS

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

Detects messages containing links that have 'ipfs' in the domain, or unanalyzed links that contain 'ipfs' in the url. IPFS has been recently observed hosting phishing sites.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesFree file host, Free subdomain host, IPFS

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
and any(body.links,
        // Any body link domains contain "ipfs"
        (
          strings.icontains(.href_url.domain.domain, "ipfs")
          and not .href_url.domain.root_domain == "ipfs.com"
        )

        // Or the path contains ipfs anchored to a leading and trailing '-', '/', '.'
        or (
          regex.icontains(.href_url.query_params, '[\.-/]ipfs[\.-/]')
          and .href_url.domain.domain not in $org_domains
          and (
            (
              // don't include high rep domains
              .href_url.domain.domain not in $tranco_1m
              and .href_url.domain.domain not in $umbrella_1m
            )
            // if it's in Tranco or Umbrella, still include it if it's one of these
            or .href_url.domain.domain in $free_file_hosts
            or .href_url.domain.root_domain in $free_file_hosts
            or .href_url.domain.root_domain in $free_subdomain_hosts
          )
        )
)

// adding negation block for legitimate domains with ipfs in their name
and not sender.email.domain.domain in ("shipfsl.com")

// negate ipfs.com issues
and not any(recipients.to, .email.domain.domain == "ipfs.com")
and not (
  sender.email.domain.root_domain is not null
  and sender.email.domain.root_domain == "ipfs.com"
  and headers.auth_summary.dmarc.pass
)
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.

Detects messages containing links that have 'ipfs' in the domain, or unanalyzed links that contain 'ipfs' in the url. IPFS has been recently observed hosting phishing sites.

  1. inbound message
  2. any of body.links where any holds:
    • all of:
      • .href_url.domain.domain contains 'ipfs'
      • not:
        • .href_url.domain.root_domain is 'ipfs.com'
    • all of:
      • .href_url.query_params matches '[\\.-/]ipfs[\\.-/]'
      • .href_url.domain.domain not in $org_domains
      • any of:
        • all of:
          • .href_url.domain.domain not in $tranco_1m
          • .href_url.domain.domain not in $umbrella_1m
        • .href_url.domain.domain in $free_file_hosts
        • .href_url.domain.root_domain in $free_file_hosts
        • .href_url.domain.root_domain in $free_subdomain_hosts
  3. not:
    • sender.email.domain.domain in ('shipfsl.com')
  4. not:
    • any of recipients.to where:
      • .email.domain.domain is 'ipfs.com'
  5. not:
    • all of:
      • sender.email.domain.root_domain is set
      • sender.email.domain.root_domain is 'ipfs.com'
      • headers.auth_summary.dmarc.pass
  6. any of:
    • not:
      • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  7. not:
    • profile.by_sender().any_messages_benign

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.query_params, headers.auth_summary.dmarc.pass, recipients.to, recipients.to[].email.domain.domain, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender, regex.icontains, strings.icontains. Reference lists: $free_file_hosts, $free_subdomain_hosts, $org_domains, $tranco_1m, $umbrella_1m.

Indicators matched (2)

FieldMatchValue
strings.icontainssubstringipfs
regex.icontainsregex[\.-/]ipfs[\.-/]

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    or
      and
        or
          and
             macro "body.links[].href_url.domain.domain not in tranco_1m"
             macro "body.links[].href_url.domain.domain not in umbrella_1m"
           macro "body.links[].href_url.domain.domain in free_file_hosts"
           macro "body.links[].href_url.domain.root_domain in free_file_hosts"
           macro "body.links[].href_url.domain.root_domain in free_subdomain_hosts"
        body.links.href_url.query_params regex_match "[\\.-/]ipfs[\\.-/]"
         macro "body.links[].href_url.domain.domain not in org_domains"
      and
        not
          body.links.href_url.domain.root_domain eq "ipfs.com"
        body.links.href_url.domain.domain contains "ipfs"
  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"
      sender.email.domain.root_domain eq "ipfs.com"
      sender.email.domain.root_domain is_not_null
  not
    any(recipients.to)
      recipients.to.email.domain.domain eq "ipfs.com"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  not
    sender.email.domain.domain eq "shipfsl.com"
  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_domaineqipfs.comexcludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"ipfs.com"
sender.email.domain.root_domainis_not_null(no value, null check)excludes:sender.email.domain.root_domain
recipients.toarray_any(no value, null check)excludes:recipients.to
sender.email.domain.domaineqshipfsl.comexcludes:sender.email.domain.domain field:"sender.email.domain.domain" value:"shipfsl.com"

Indicators

These rows show field, operator, and value matches.

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

Link: IPv4-mapped IPv6 address obfuscation

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

Detects links containing IPv4-mapped IPv6 addresses in the format [::ffff:xxxx:xxxx], commonly used to obfuscate malicious URLs and evade detection systems.

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
  • type

Rule body

type.inbound
and any(body.links, .href_url.ip.translation.v4_to_v6)

Detection logic

Scope: inbound message.

Detects links containing IPv4-mapped IPv6 addresses in the format [::ffff:xxxx:xxxx], commonly used to obfuscate malicious URLs and evade detection systems.

  1. inbound message
  2. any of body.links where:
    • .href_url.ip.translation.v4_to_v6

Inspects: body.links, body.links[].href_url.ip.translation.v4_to_v6, type.inbound.

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    body.links.href_url.ip.translation.v4_to_v6 eq "true"
  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"

Link: JavaScript obfuscation with Telegram bot integration

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

Detects links containing obfuscated JavaScript code with embedded Telegram bot tokens or API references, indicating potential data exfiltration or command and control infrastructure.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Scripting

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • recipients
  • recipients.to[0]
  • type

Rule body

type.inbound
and 0 < length(body.links) < 15
and length(recipients.to) == 1
and recipients.to[0].email.domain.valid
and any(body.links,
        // javascript obfuscator code - https://obfuscator.io/
        regex.icontains(ml.link_analysis(.).final_dom.raw,
                        '(?:(?:return|function|var|let|const|parseInt)\(?\s*_0x[a-f0-9]{6}.{0,50}){5}'
        )
        and regex.icontains(ml.link_analysis(.).final_dom.raw,
                            // telegram bot token struct
                            '[\x22\x27][0-9]{10}:[a-z0-9_-]{20,35}[\x22\x27]',
                            // telegram strings
                            '(?:telegram(?:chatid|BotToken)|TELEGRAM_(?:BOT_TOKENS|CHAT_IDS)|api\.telegram\.org/bot|telegramToken)'
        )
)

Detection logic

Scope: inbound message.

Detects links containing obfuscated JavaScript code with embedded Telegram bot tokens or API references, indicating potential data exfiltration or command and control infrastructure.

  1. inbound message
  2. all of:
    • length(body.links) > 0
    • length(body.links) < 15
  3. length(recipients.to) is 1
  4. recipients.to[0].email.domain.valid
  5. any of body.links where all hold:
    • ml.link_analysis(.).final_dom.raw matches '(?:(?:return|function|var|let|const|parseInt)\\(?\\s*_0x[a-f0-9]{6}.{0,50}){5}'
    • ml.link_analysis(.).final_dom.raw matches any of 2 patterns
      • [\x22\x27][0-9]{10}:[a-z0-9_-]{20,35}[\x22\x27]
      • (?:telegram(?:chatid|BotToken)|TELEGRAM_(?:BOT_TOKENS|CHAT_IDS)|api\.telegram\.org/bot|telegramToken)

Inspects: body.links, recipients.to, recipients.to[0].email.domain.valid, type.inbound. Sensors: ml.link_analysis, regex.icontains.

Indicators matched (3)

FieldMatchValue
regex.icontainsregex(?:(?:return|function|var|let|const|parseInt)\(?\s*_0x[a-f0-9]{6}.{0,50}){5}
regex.icontainsregex[\x22\x27][0-9]{10}:[a-z0-9_-]{20,35}[\x22\x27]
regex.icontainsregex(?:telegram(?:chatid|BotToken)|TELEGRAM_(?:BOT_TOKENS|CHAT_IDS)|api\.telegram\.org/bot|telegramToken)

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        ml.link_analysis(body.links[]).final_dom.raw regex_match "(?:telegram(?:chatid|BotToken)|TELEGRAM_(?:BOT_TOKENS|CHAT_IDS)|api\\.telegram\\.org/bot|telegramToken)"
        ml.link_analysis(body.links[]).final_dom.raw regex_match "[\\x22\\x27][0-9]{10}:[a-z0-9_-]{20,35}[\\x22\\x27]"
      ml.link_analysis(body.links[]).final_dom.raw regex_match "(?:(?:return|function|var|let|const|parseInt)\\(?\\s*_0x[a-f0-9]{6}.{0,50}){5}"
  body.links length_compare "0"
  body.links length_compare "15"
  recipients.to length_compare "1"
  recipients.to[0].email.domain.valid eq "true"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Jensi file preview link from unsolicited sender

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

This detection rule matches on messaging containing at least one link to app.jensi.io from an unsolicited sender. Jensi provides a free trail enabling users to create upload documents and preview PDFs within the browser as native HTML. This services has been abused by threat actors to host landing pages directing victims to a next stage of credential phishing.

Threat classification

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

CategoryValues
Attack typesCallback Phishing
Tactics and techniquesFree file host, Free subdomain host

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 any(body.links,
        // jensi domain with preview link
        .href_url.domain.domain == 'app.jensi.io'
        and strings.istarts_with(.href_url.path, '/public/preview/file/')
)
// not solicited or from malicious/spam user with no FPs
and (
  not profile.by_sender().solicited
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)

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

This detection rule matches on messaging containing at least one link to app.jensi.io from an unsolicited sender. Jensi provides a free trail enabling users to create upload documents and preview PDFs within the browser as native HTML. This services has been abused by threat actors to host landing pages directing victims to a next stage of credential phishing.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.domain.domain is 'app.jensi.io'
    • .href_url.path starts with '/public/preview/file/'
  3. any of:
    • not:
      • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  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.links, body.links[].href_url.domain.domain, body.links[].href_url.path, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender, strings.istarts_with. Reference lists: $high_trust_sender_root_domains.

Indicators matched (2)

FieldMatchValue
body.links[].href_url.domain.domainequalsapp.jensi.io
strings.istarts_withprefix/public/preview/file/

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"
    not
      profile.by_sender func_call "profile.by_sender().solicited"
  any(body.links)
    and
      body.links.href_url.domain.domain eq "app.jensi.io"
      body.links.href_url.path starts_with "/public/preview/file/"
  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"

Link: Job recruitment lure from unsolicited sender with suspicious hosting

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

Message contains job recruitment language with links to suspicious hosting services including free file hosts, subdomain hosts, or URL shorteners from an unsolicited sender.

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

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

Rule body

type.inbound
// commonly observed abused senders
and sender.email.domain.root_domain in (
  'hireology.com',
  'appsheet.com',
  'welcomekit.co',
  'xero.com',
  'workforce.com',
  'eventbrite.com',
  'tiscali.it',
  'on24event.com',
  'talexio.com',
  'easy.jobs',
  'suitzzedash.com',
  'awsapps.com',
  'beehiiv.com'
)
and regex.icontains(sender.display_name, 'careers|jobs')
and (
  any(body.links,
      (
        // domain contains brand, but root domain is not legit brand domain
        regex.icontains(.href_url.domain.domain,
                        '(?:ferrari|tesla|vuitton|red[ -]?bull|nike|robert[ -]?half|adidas|coca[ -]?cola|instagram|spotify|reebok|marriott|starbucks|whatsapp|ledger|uber|ikea|canva|bbdo|mango)'
        )
        and not regex.icontains(.href_url.domain.root_domain,
                                '(?:spotify|instagram|ferarri|tesla|nike|adidas|louisvuitton|redbull|roberthalf|coca-cola|reebok|marriott|starbucks|whatsapp|ledger|uber|ikea|canva|bbdo|mango)\.com'
        )
      )
      and not regex.icontains(.display_text, 'unsubscribe')
  )
  or (
    regex.icontains(subject.base,
                    '(?:ferrari|tesla|vuitton|red.?bull|nike|robert[ _-]?half|adidas|coca[ _-]?cola|instagram|spotify|reebok|marriott|starbucks|whatsapp|ray[ _-]ban|meta talent|executive talent|talent acquisition|ledger|\buber\b|\bikea\b|canva|bbdo|mango)'
    )
    or regex.icontains(sender.display_name,
                       '(?:ferrari|tesla|vuitton|red.?bull|nike|robert[ _-]?half|adidas|coca[ _-]?cola|instagram|spotify|reebok|marriott|starbucks|whatsapp|ray[ _-]ban|meta talent|executive talent|talent acquisition|ledger|\buber\b|\bikea\b|canva|bbdo|mango)'
    )
    or regex.icontains(body.current_thread.text,
                       '\b(?:ferrari|tesla|vuitton|red.?bull|nike|robert[ _-]?half|adidas|coca[ _-]?cola|spotify|reebok|marriott|starbucks|whatsapp|ray[ _-]ban|meta talent|executive talent|talent acquisition|ledger|uber|ikea|canva|bbdo|mango)\b'
    )
    or regex.icontains(sender.display_name,
                       '^[a-z-]+\s*\|\s*(?:Careers|Recruitment|hiring talent|talent connect|talents recruitment$)'
    )
    or regex.icontains(sender.display_name, '\bIG\b.*(?:Recruitment|Strategy)')
  )
)
and not regex.icontains(body.current_thread.text,
                        '\b(?:facebook|copyright|llp|legal|vip|representative|case details|summit|training|conference|apartments|live\s*stream|masterclass|tickets|b2b networking|RSVP|discover more events|Marketing e Eventos|workshop|register here|vip|delivery date)\b'
)

Detection logic

Scope: inbound message.

Message contains job recruitment language with links to suspicious hosting services including free file hosts, subdomain hosts, or URL shorteners from an unsolicited sender.

  1. inbound message
  2. sender.email.domain.root_domain in ('hireology.com', 'appsheet.com', 'welcomekit.co', 'xero.com', 'workforce.com', 'eventbrite.com', 'tiscali.it', 'on24event.com', 'talexio.com', 'easy.jobs', 'suitzzedash.com', 'awsapps.com', 'beehiiv.com')
  3. sender.display_name matches 'careers|jobs'
  4. any of:
    • any of body.links where all hold:
      • all of:
        • .href_url.domain.domain matches '(?:ferrari|tesla|vuitton|red[ -]?bull|nike|robert[ -]?half|adidas|coca[ -]?cola|instagram|spotify|reebok|marriott|starbucks|whatsapp|ledger|uber|ikea|canva|bbdo|mango)'
        • not:
          • .href_url.domain.root_domain matches '(?:spotify|instagram|ferarri|tesla|nike|adidas|louisvuitton|redbull|roberthalf|coca-cola|reebok|marriott|starbucks|whatsapp|ledger|uber|ikea|canva|bbdo|mango)\\.com'
      • not:
        • .display_text matches 'unsubscribe'
    • any of:
      • subject.base matches '(?:ferrari|tesla|vuitton|red.?bull|nike|robert[ _-]?half|adidas|coca[ _-]?cola|instagram|spotify|reebok|marriott|starbucks|whatsapp|ray[ _-]ban|meta talent|executive talent|talent acquisition|ledger|\\buber\\b|\\bikea\\b|canva|bbdo|mango)'
      • sender.display_name matches '(?:ferrari|tesla|vuitton|red.?bull|nike|robert[ _-]?half|adidas|coca[ _-]?cola|instagram|spotify|reebok|marriott|starbucks|whatsapp|ray[ _-]ban|meta talent|executive talent|talent acquisition|ledger|\\buber\\b|\\bikea\\b|canva|bbdo|mango)'
      • body.current_thread.text matches '\\b(?:ferrari|tesla|vuitton|red.?bull|nike|robert[ _-]?half|adidas|coca[ _-]?cola|spotify|reebok|marriott|starbucks|whatsapp|ray[ _-]ban|meta talent|executive talent|talent acquisition|ledger|uber|ikea|canva|bbdo|mango)\\b'
      • sender.display_name matches '^[a-z-]+\\s*\\|\\s*(?:Careers|Recruitment|hiring talent|talent connect|talents recruitment$)'
      • sender.display_name matches '\\bIG\\b.*(?:Recruitment|Strategy)'
  5. not:
    • body.current_thread.text matches '\\b(?:facebook|copyright|llp|legal|vip|representative|case details|summit|training|conference|apartments|live\\s*stream|masterclass|tickets|b2b networking|RSVP|discover more events|Marketing e Eventos|workshop|register here|vip|delivery date)\\b'

Inspects: body.current_thread.text, body.links, body.links[].display_text, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, sender.display_name, sender.email.domain.root_domain, subject.base, type.inbound. Sensors: regex.icontains.

Indicators matched (19)

FieldMatchValue
sender.email.domain.root_domainmemberhireology.com
sender.email.domain.root_domainmemberappsheet.com
sender.email.domain.root_domainmemberwelcomekit.co
sender.email.domain.root_domainmemberxero.com
sender.email.domain.root_domainmemberworkforce.com
sender.email.domain.root_domainmembereventbrite.com
sender.email.domain.root_domainmembertiscali.it
sender.email.domain.root_domainmemberon24event.com
sender.email.domain.root_domainmembertalexio.com
sender.email.domain.root_domainmembereasy.jobs
sender.email.domain.root_domainmembersuitzzedash.com
sender.email.domain.root_domainmemberawsapps.com
7 more
sender.email.domain.root_domainmemberbeehiiv.com
regex.icontainsregexcareers|jobs
regex.icontainsregex(?:ferrari|tesla|vuitton|red[ -]?bull|nike|robert[ -]?half|adidas|coca[ -]?cola|instagram|spotify|reebok|marriott|starbucks|whatsapp|ledger|uber|ikea|canva|bbdo|mango)
regex.icontainsregex(?:ferrari|tesla|vuitton|red.?bull|nike|robert[ _-]?half|adidas|coca[ _-]?cola|instagram|spotify|reebok|marriott|starbucks|whatsapp|ray[ _-]ban|meta talent|executive talent|talent acquisition|ledger|\buber\b|\bikea\b|canva|bbdo|mango)
regex.icontainsregex\b(?:ferrari|tesla|vuitton|red.?bull|nike|robert[ _-]?half|adidas|coca[ _-]?cola|spotify|reebok|marriott|starbucks|whatsapp|ray[ _-]ban|meta talent|executive talent|talent acquisition|ledger|uber|ikea|canva|bbdo|mango)\b
regex.icontainsregex^[a-z-]+\s*\|\s*(?:Careers|Recruitment|hiring talent|talent connect|talents recruitment$)
regex.icontainsregex\bIG\b.*(?:Recruitment|Strategy)

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(body.links)
      and
        not
          body.links.display_text regex_match "unsubscribe"
        not
          body.links.href_url.domain.root_domain regex_match "(?:spotify|instagram|ferarri|tesla|nike|adidas|louisvuitton|redbull|roberthalf|coca-cola|reebok|marriott|starbucks|whatsapp|ledger|uber|ikea|canva|bbdo|mango)\\.com"
        body.links.href_url.domain.domain regex_match "(?:ferrari|tesla|vuitton|red[ -]?bull|nike|robert[ -]?half|adidas|coca[ -]?cola|instagram|spotify|reebok|marriott|starbucks|whatsapp|ledger|uber|ikea|canva|bbdo|mango)"
    body.current_thread.text regex_match "\\b(?:ferrari|tesla|vuitton|red.?bull|nike|robert[ _-]?half|adidas|coca[ _-]?cola|spotify|reebok|marriott|starbucks|whatsapp|ray[ _-]ban|meta talent|executive talent|talent acquisition|ledger|uber|ikea|canva|bbdo|mango)\\b"
    sender.display_name regex_match "(?:ferrari|tesla|vuitton|red.?bull|nike|robert[ _-]?half|adidas|coca[ _-]?cola|instagram|spotify|reebok|marriott|starbucks|whatsapp|ray[ _-]ban|meta talent|executive talent|talent acquisition|ledger|\\buber\\b|\\bikea\\b|canva|bbdo|mango)"
    sender.display_name regex_match "\\bIG\\b.*(?:Recruitment|Strategy)"
    sender.display_name regex_match "^[a-z-]+\\s*\\|\\s*(?:Careers|Recruitment|hiring talent|talent connect|talents recruitment$)"
    subject.base regex_match "(?:ferrari|tesla|vuitton|red.?bull|nike|robert[ _-]?half|adidas|coca[ _-]?cola|instagram|spotify|reebok|marriott|starbucks|whatsapp|ray[ _-]ban|meta talent|executive talent|talent acquisition|ledger|\\buber\\b|\\bikea\\b|canva|bbdo|mango)"
  not
    body.current_thread.text regex_match "\\b(?:facebook|copyright|llp|legal|vip|representative|case details|summit|training|conference|apartments|live\\s*stream|masterclass|tickets|b2b networking|RSVP|discover more events|Marketing e Eventos|workshop|register here|vip|delivery date)\\b"
  sender.display_name regex_match "careers|jobs"
  sender.email.domain.root_domain in ["appsheet.com", "awsapps.com", "beehiiv.com", "easy.jobs", "eventbrite.com", "hireology.com", "on24event.com", "suitzzedash.com", "talexio.com", "tiscali.it", "welcomekit.co", "workforce.com", "xero.com"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
body.current_thread.textregex_match\b(?:facebook|copyright|llp|legal|vip|representative|case details|summit|training|conference|apartments|live\s*stream|masterclass|tickets|b2b networking|RSVP|discover more events|Marketing e Eventos|workshop|register here|vip|delivery date)\bexcludes:body.current_thread.text field:"body.current_thread.text" value:"\b(?:facebook|copyright|llp|legal|vip|representative|case details|summit|training|conference|apartments|live\s*stream|masterclass|tickets|b2b networking|RSVP|discover more events|Marketing e Eventos|workshop|register here|vip|delivery date)\b"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textregex_match
  • \b(?:ferrari|tesla|vuitton|red.?bull|nike|robert[ _-]?half|adidas|coca[ _-]?cola|spotify|reebok|marriott|starbucks|whatsapp|ray[ _-]ban|meta talent|executive talent|talent acquisition|ledger|uber|ikea|canva|bbdo|mango)\b
field:"body.current_thread.text" kind:regex_match value:"\b(?:ferrari|tesla|vuitton|red.?bull|nike|robert[ _-]?half|adidas|coca[ _-]?cola|spotify|reebok|marriott|starbucks|whatsapp|ray[ _-]ban|meta talent|executive talent|talent acquisition|ledger|uber|ikea|canva|bbdo|mango)\b"
sender.display_nameregex_match
  • (?:ferrari|tesla|vuitton|red.?bull|nike|robert[ _-]?half|adidas|coca[ _-]?cola|instagram|spotify|reebok|marriott|starbucks|whatsapp|ray[ _-]ban|meta talent|executive talent|talent acquisition|ledger|\buber\b|\bikea\b|canva|bbdo|mango)
  • \bIG\b.*(?:Recruitment|Strategy)
  • ^[a-z-]+\s*|\s*(?:Careers|Recruitment|hiring talent|talent connect|talents recruitment$)
    • careers
    • jobs
field:"sender.display_name" kind:regex_match
sender.email.domain.root_domainin
  • appsheet.com
  • awsapps.com
  • beehiiv.com
  • easy.jobs
  • eventbrite.com
  • hireology.com
  • on24event.com
  • suitzzedash.com
  • talexio.com
  • tiscali.it
  • welcomekit.co
  • workforce.com
  • xero.com
field:"sender.email.domain.root_domain" kind:in
subject.baseregex_match
  • (?:ferrari|tesla|vuitton|red.?bull|nike|robert[ _-]?half|adidas|coca[ _-]?cola|instagram|spotify|reebok|marriott|starbucks|whatsapp|ray[ _-]ban|meta talent|executive talent|talent acquisition|ledger|\buber\b|\bikea\b|canva|bbdo|mango)
field:"subject.base" kind:regex_match value:"(?:ferrari|tesla|vuitton|red.?bull|nike|robert[ _-]?half|adidas|coca[ _-]?cola|instagram|spotify|reebok|marriott|starbucks|whatsapp|ray[ _-]ban|meta talent|executive talent|talent acquisition|ledger|\buber\b|\bikea\b|canva|bbdo|mango)"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link: Landing page with search-ms protocol redirect

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

Detects messages containing URL shortener links that redirect to search-ms protocol queries, which can be used to execute local file searches on Windows systems.

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware
Tactics and techniquesEvasion, Scripting

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and all(body.links, .href_url.domain.root_domain in $url_shorteners)
and any(body.links,
        regex.icontains(ml.link_analysis(., mode="aggressive").final_dom.raw,
                        'search-ms:[^\;]*query=[^\;]+\.lnk'
        )
)

Detection logic

Scope: inbound message.

Detects messages containing URL shortener links that redirect to search-ms protocol queries, which can be used to execute local file searches on Windows systems.

  1. inbound message
  2. all of body.links where:
    • .href_url.domain.root_domain in $url_shorteners
  3. any of body.links where:
    • ml.link_analysis(., mode='aggressive').final_dom.raw matches 'search-ms:[^\\;]*query=[^\\;]+\\.lnk'

Inspects: body.links, body.links[].href_url.domain.root_domain, type.inbound. Sensors: ml.link_analysis, regex.icontains. Reference lists: $url_shorteners.

Indicators matched (1)

FieldMatchValue
regex.icontainsregexsearch-ms:[^\;]*query=[^\;]+\.lnk

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    ml.link_analysis(body.links[], mode='aggressive').final_dom.raw regex_match "search-ms:[^\\;]*query=[^\\;]+\\.lnk"
  type.inbound eq "true"
   macro "all(body.links)"

Indicators

These rows show field, operator, and value matches.

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

Link: Mamba 2FA phishing kit

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

Detects links containing base64-encoded parameters characteristic of the Mamba 2FA phishing kit, specifically looking for 'sv=o365' and '&uid=USER' patterns in redirect history.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
and length(body.links) < 10
and (
  any(ml.nlu_classifier(body.current_thread.text).intents,
      .name in ('bec', 'cred_theft') and .confidence != 'low'
  )
  or (
    length(recipients.to) == 1
    and any(recipients.to,
            strings.icontains(body.current_thread.text, .email.email)
    )
    and regex.icontains(body.current_thread.text,
                        '(invoice|document|docusign|past due|confirm receipt)'
    )
  )
  or (
    sender.email.domain.domain == 'icloud.com'
    and any(attachments, .file_name == 'invite.ics')
  )
)
and any(body.links,
        any(ml.link_analysis(., mode="aggressive").redirect_history,
            (
              // sv= in base64 as well as commonly observed tag
              regex.contains(.url, '(?:(?:/?|=)c3Y9|N0123N)')
              // &uid=USER base64 offsets
              and (
                strings.contains(.url, 'JnVpZD1VU0VS')
                or strings.contains(.url, 'Z1aWQ9VVNFU')
                or strings.contains(.url, 'mdWlkPVVTRV')
              )
            )
        )
)

Detection logic

Scope: inbound message.

Detects links containing base64-encoded parameters characteristic of the Mamba 2FA phishing kit, specifically looking for 'sv=o365' and '&uid=USER' patterns in redirect history.

  1. inbound message
  2. length(body.links) < 10
  3. any of:
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name in ('bec', 'cred_theft')
      • .confidence is not 'low'
    • all of:
      • length(recipients.to) is 1
      • any of recipients.to where:
        • strings.icontains(body.current_thread.text)
      • body.current_thread.text matches '(invoice|document|docusign|past due|confirm receipt)'
    • all of:
      • sender.email.domain.domain is 'icloud.com'
      • any of attachments where:
        • .file_name is 'invite.ics'
  4. any of body.links where:
    • any of ml.link_analysis(., mode='aggressive').redirect_history where all hold:
      • .url matches '(?:(?:/?|=)c3Y9|N0123N)'
      • any of:
        • .url contains 'JnVpZD1VU0VS'
        • .url contains 'Z1aWQ9VVNFU'
        • .url contains 'mdWlkPVVTRV'

Inspects: attachments[].file_name, body.current_thread.text, body.links, recipients.to, recipients.to[].email.email, sender.email.domain.domain, type.inbound. Sensors: ml.link_analysis, ml.nlu_classifier, regex.contains, regex.icontains, strings.contains, strings.icontains.

Indicators matched (9)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).intents[].namememberbec
ml.nlu_classifier(body.current_thread.text).intents[].namemembercred_theft
regex.icontainsregex(invoice|document|docusign|past due|confirm receipt)
sender.email.domain.domainequalsicloud.com
attachments[].file_nameequalsinvite.ics
regex.containsregex(?:(?:/?|=)c3Y9|N0123N)
strings.containssubstringJnVpZD1VU0VS
strings.containssubstringZ1aWQ9VVNFU
strings.containssubstringmdWlkPVVTRV

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    any(ml.link_analysis(body.links, mode='aggressive').redirect_history)
      and
        or
          ml.link_analysis(body.links[], mode='aggressive').redirect_history[].url contains "JnVpZD1VU0VS"
          ml.link_analysis(body.links[], mode='aggressive').redirect_history[].url contains "Z1aWQ9VVNFU"
          ml.link_analysis(body.links[], mode='aggressive').redirect_history[].url contains "mdWlkPVVTRV"
        ml.link_analysis(body.links[], mode='aggressive').redirect_history[].url regex_match "(?:(?:/?|=)c3Y9|N0123N)"
  or
    and
      any(attachments)
        attachments.file_name eq "invite.ics"
      sender.email.domain.domain eq "icloud.com"
    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 in ["bec", "cred_theft"]
    and
      any(recipients.to)
        strings.icontains func_call "strings.icontains(body.current_thread.text)"
      body.current_thread.text regex_match "(invoice|document|docusign|past due|confirm receipt)"
      recipients.to length_compare "1"
  body.links length_compare "10"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Microsoft device code authentication with suspicious indicators

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

Detects messages containing links with Microsoft device code authentication patterns, including verification prompts, copy code instructions, and suspicious API endpoints or antibot tokens commonly used in device code takeover attacks.

Threat classification

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

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

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • recipients
  • type

Rule body

type.inbound
and length(recipients.to) == 1
and 0 < length(body.links) < 15
and any(body.links,
        // strings commonly observed in the microsoft device code phishing lure
        regex.icontains(ml.link_analysis(., mode="aggressive").final_dom.display_text,
                        "verification co(?:mplete|de)",
                        '\bcopy code\b',
                        "Secured by Microsoft",
                        "(?:redirecting to|opening) your document",
                        "preparing verification",
                        "(?:verify your identity|complete verification) with Microsoft"
        )
        // unique device code antibot token cookie, api path, ms device login path url
        and (
          regex.icontains(ml.link_analysis(., mode="aggressive").final_dom.raw,
                          'X-Antibot-Token',
                          '\/api\/device\/sta(?:rt|tus)\/',
                          'microsoft\.com\/devicelogin'
          )
          // or api path on workers dev associated with this activity
          or any(ml.link_analysis(., mode="aggressive").unique_urls_accessed,
                 strings.icontains(.path, '/api/device/start')
                 and strings.icontains(.domain.root_domain, 'workers.dev')
          )
        )
)

Detection logic

Scope: inbound message.

Detects messages containing links with Microsoft device code authentication patterns, including verification prompts, copy code instructions, and suspicious API endpoints or antibot tokens commonly used in device code takeover attacks.

  1. inbound message
  2. length(recipients.to) is 1
  3. all of:
    • length(body.links) > 0
    • length(body.links) < 15
  4. any of body.links where all hold:
    • ml.link_analysis(., mode='aggressive').final_dom.display_text matches any of 6 patterns
      • verification co(?:mplete|de)
      • \bcopy code\b
      • Secured by Microsoft
      • (?:redirecting to|opening) your document
      • preparing verification
      • (?:verify your identity|complete verification) with Microsoft
    • any of:
      • ml.link_analysis(., mode='aggressive').final_dom.raw matches any of 3 patterns
        • X-Antibot-Token
        • \/api\/device\/sta(?:rt|tus)\/
        • microsoft\.com\/devicelogin
      • any of ml.link_analysis(., mode='aggressive').unique_urls_accessed where all hold:
        • .path contains '/api/device/start'
        • .domain.root_domain contains 'workers.dev'

Inspects: body.links, recipients.to, type.inbound. Sensors: ml.link_analysis, regex.icontains, strings.icontains.

Indicators matched (11)

FieldMatchValue
regex.icontainsregexverification co(?:mplete|de)
regex.icontainsregex\bcopy code\b
regex.icontainsregexSecured by Microsoft
regex.icontainsregex(?:redirecting to|opening) your document
regex.icontainsregexpreparing verification
regex.icontainsregex(?:verify your identity|complete verification) with Microsoft
regex.icontainsregexX-Antibot-Token
regex.icontainsregex\/api\/device\/sta(?:rt|tus)\/
regex.icontainsregexmicrosoft\.com\/devicelogin
strings.icontainssubstring/api/device/start
strings.icontainssubstringworkers.dev

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        any(ml.link_analysis(body.links, mode='aggressive').unique_urls_accessed)
          and
            ml.link_analysis(body.links[], mode='aggressive').unique_urls_accessed[].domain.root_domain contains "workers.dev"
            ml.link_analysis(body.links[], mode='aggressive').unique_urls_accessed[].path contains "/api/device/start"
        ml.link_analysis(body.links[], mode='aggressive').final_dom.raw regex_match "X-Antibot-Token"
        ml.link_analysis(body.links[], mode='aggressive').final_dom.raw regex_match "\\/api\\/device\\/sta(?:rt|tus)\\/"
        ml.link_analysis(body.links[], mode='aggressive').final_dom.raw regex_match "microsoft\\.com\\/devicelogin"
      or
        ml.link_analysis(body.links[], mode='aggressive').final_dom.display_text regex_match "(?:redirecting to|opening) your document"
        ml.link_analysis(body.links[], mode='aggressive').final_dom.display_text regex_match "(?:verify your identity|complete verification) with Microsoft"
        ml.link_analysis(body.links[], mode='aggressive').final_dom.display_text regex_match "Secured by Microsoft"
        ml.link_analysis(body.links[], mode='aggressive').final_dom.display_text regex_match "\\bcopy code\\b"
        ml.link_analysis(body.links[], mode='aggressive').final_dom.display_text regex_match "preparing verification"
        ml.link_analysis(body.links[], mode='aggressive').final_dom.display_text regex_match "verification co(?:mplete|de)"
  body.links length_compare "0"
  body.links length_compare "15"
  recipients.to length_compare "1"
  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"

Link: Microsoft Dynamics 365 form phishing

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

Email body is suspicious, and links to a Microsoft Dynamics form. Known phishing tactic.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion

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 any(body.links,
        .href_url.domain.domain in (
          "ncv.microsoft.com",
          "customervoice.microsoft.com",
          "nam.dcv.ms"
        )
        and ml.link_analysis(.).effective_url.domain.domain == "customervoice.microsoft.com"

        // confirm it is a form
        and (
          any(ml.link_analysis(.).final_dom.links,
              .href_url.domain.domain == "cdn.forms.office.net"
          )
          or strings.icontains(ml.link_analysis(.).final_dom.raw,
                               "cdn.forms.office.net"
          )
          or .href_url.path == "/Pages/ResponsePage.aspx"
        )

        // analyze for credential phishing signals
        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
          //
          any(ml.nlu_classifier(beta.ocr(ml.link_analysis(.).screenshot).text).intents,
              .name == "cred_theft" and .confidence != "low"
          )
          or any(ml.nlu_classifier(body.current_thread.text).intents,
                 .name == "cred_theft" and .confidence != "low"
          )
        )
)
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

// 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 body is suspicious, and links to a Microsoft Dynamics form. Known phishing tactic.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.domain.domain in ('ncv.microsoft.com', 'customervoice.microsoft.com', 'nam.dcv.ms')
    • ml.link_analysis(.).effective_url.domain.domain is 'customervoice.microsoft.com'
    • any of:
      • any of ml.link_analysis(.).final_dom.links where:
        • .href_url.domain.domain is 'cdn.forms.office.net'
      • ml.link_analysis(.).final_dom.raw contains 'cdn.forms.office.net'
      • .href_url.path is '/Pages/ResponsePage.aspx'
    • any of:
      • any of ml.nlu_classifier(beta.ocr(ml.link_analysis(.).screenshot).text).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'
  3. any of:
    • not:
      • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  4. not:
    • profile.by_sender().any_messages_benign
  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, body.links, body.links[].href_url.domain.domain, body.links[].href_url.path, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: beta.ocr, ml.link_analysis, ml.nlu_classifier, profile.by_sender, strings.icontains. Reference lists: $high_trust_sender_root_domains.

Indicators matched (8)

FieldMatchValue
body.links[].href_url.domain.domainmemberncv.microsoft.com
body.links[].href_url.domain.domainmembercustomervoice.microsoft.com
body.links[].href_url.domain.domainmembernam.dcv.ms
ml.link_analysis(body.links[]).final_dom.links[].href_url.domain.domainequalscdn.forms.office.net
strings.icontainssubstringcdn.forms.office.net
body.links[].href_url.pathequals/Pages/ResponsePage.aspx
ml.nlu_classifier(beta.ocr(ml.link_analysis(body.links[]).screenshot).text).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        any(ml.nlu_classifier(beta.ocr(ml.link_analysis(body.links).screenshot).text).intents)
          and
            ml.nlu_classifier(beta.ocr(ml.link_analysis(body.links[]).screenshot).text).intents[].confidence ne "low"
            ml.nlu_classifier(beta.ocr(ml.link_analysis(body.links[]).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 ne "low"
            ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
      or
        any(ml.link_analysis(body.links).final_dom.links)
          ml.link_analysis(body.links).final_dom.links.href_url.domain.domain eq "cdn.forms.office.net"
        body.links.href_url.path eq "/Pages/ResponsePage.aspx"
        ml.link_analysis(body.links[]).final_dom.raw contains "cdn.forms.office.net"
      body.links.href_url.domain.domain in ["customervoice.microsoft.com", "nam.dcv.ms", "ncv.microsoft.com"]
      ml.link_analysis func_call "ml.link_analysis(body.links[]).effective_url.domain.domain == customervoice.microsoft.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
    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"
  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"

Link: Microsoft impersonation using hosted png with suspicious link

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

Detects messages with a link to a Microsoft hosted logo where the sender's display name and the display text of a link in the body are in all caps, and a request is being made from a first-time 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

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

Rule body

type.inbound

// display name is in all caps
and regex.match(sender.display_name, '[A-Z ]+')

// the sender is not microsoft
and sender.email.domain.root_domain not in~ (
  'microsoft.com',
  'microsoftsupport.com',
  'office.com'
)

// logo hosted on microsoft.com
and any(body.links,
        regex.icontains(.display_url.url,
                        '.{0,50}microsoft\.com\/.{0,70}logo.{0,25}\.png'
        )
)

// and at least one link display text is in all caps
and any(body.links,
        regex.icontains(.display_text, '[VIEW|CLICK|DOWNLOAD|CHECK]')
)

// request being made
and any(ml.nlu_classifier(body.html.inner_text).entities, .name == "request")

// sender domain matches no body domains
and not any(body.links,
            .href_url.domain.root_domain == sender.email.domain.root_domain
            and .href_url.domain.root_domain not in $tranco_1m
)

// org domain in the subject of the message
and any($org_domains, strings.icontains(subject.subject, .))
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.

Detects messages with a link to a Microsoft hosted logo where the sender's display name and the display text of a link in the body are in all caps, and a request is being made from a first-time sender.

  1. inbound message
  2. sender.display_name matches '[A-Z ]+'
  3. sender.email.domain.root_domain not in ('microsoft.com', 'microsoftsupport.com', 'office.com')
  4. any of body.links where:
    • .display_url.url matches '.{0,50}microsoft\\.com\\/.{0,70}logo.{0,25}\\.png'
  5. any of body.links where:
    • .display_text matches '[VIEW|CLICK|DOWNLOAD|CHECK]'
  6. any of ml.nlu_classifier(body.html.inner_text).entities where:
    • .name is 'request'
  7. not:
    • any of body.links where all hold:
      • .href_url.domain.root_domain is sender.email.domain.root_domain
      • .href_url.domain.root_domain not in $tranco_1m
  8. any of $org_domains where:
    • strings.icontains(subject.subject)
  9. 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: body.html.inner_text, body.links, body.links[].display_text, body.links[].display_url.url, body.links[].href_url.domain.root_domain, sender.display_name, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender, regex.icontains, regex.match, strings.icontains. Reference lists: $org_domains, $tranco_1m.

Indicators matched (4)

FieldMatchValue
regex.matchregex[A-Z ]+
regex.icontainsregex.{0,50}microsoft\.com\/.{0,70}logo.{0,25}\.png
regex.icontainsregex[VIEW|CLICK|DOWNLOAD|CHECK]
ml.nlu_classifier(body.html.inner_text).entities[].nameequalsrequest

Stages and Predicates

Stage 1: mql_rule

and
  not
    any(body.links)
      and
        body.links.href_url.domain.root_domain cross_field_compare "sender.email.domain.root_domain"
         macro "body.links[].href_url.domain.root_domain not in tranco_1m"
  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(body.links)
    body.links.display_text regex_match "[VIEW|CLICK|DOWNLOAD|CHECK]"
  any(body.links)
    body.links.display_url.url regex_match ".{0,50}microsoft\\.com\\/.{0,70}logo.{0,25}\\.png"
  any(ml.nlu_classifier(body.html.inner_text).entities)
    ml.nlu_classifier(body.html.inner_text).entities.name eq "request"
  not
    sender.email.domain.root_domain in ["microsoft.com", "microsoftsupport.com", "office.com"]
  any($org_domains)
    strings.icontains func_call "strings.icontains(subject.subject)"
  sender.display_name regex_match "[A-Z ]+"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

Link: Microsoft protected message with matching sender and recipient addresses

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

Detects when a user receives a protected message (RPMSG) with the to and from headers matching.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.links
  • recipients
  • recipients.to
  • sender.email
  • type

Rule body

type.inbound
// contains the rpmsg
and any(attachments,
        .file_extension == "rpmsg"
        or .content_type == "application/x-microsoft-rpmsg-message"
)
// contains the proper link
and any(body.links,
        .href_url.domain.root_domain == "office365.com"
        and (
          strings.icontains(.href_url.query_params, "InternetMessageID=")
          or strings.icontains(.href_url.path, '/Encryption/retrieve.ashx')
        )
)
// the To and From headers are the same
and length(recipients.to) == 1
and all(recipients.to, .email.email == sender.email.email)

Detection logic

Scope: inbound message.

Detects when a user receives a protected message (RPMSG) with the to and from headers matching.

  1. inbound message
  2. any of attachments where any holds:
    • .file_extension is 'rpmsg'
    • .content_type is 'application/x-microsoft-rpmsg-message'
  3. any of body.links where all hold:
    • .href_url.domain.root_domain is 'office365.com'
    • any of:
      • .href_url.query_params contains 'InternetMessageID='
      • .href_url.path contains '/Encryption/retrieve.ashx'
  4. length(recipients.to) is 1
  5. all of recipients.to where:
    • .email.email is sender.email.email

Inspects: attachments[].content_type, attachments[].file_extension, body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.path, body.links[].href_url.query_params, recipients.to, recipients.to[].email.email, sender.email.email, type.inbound. Sensors: strings.icontains.

Indicators matched (5)

FieldMatchValue
attachments[].file_extensionequalsrpmsg
attachments[].content_typeequalsapplication/x-microsoft-rpmsg-message
body.links[].href_url.domain.root_domainequalsoffice365.com
strings.icontainssubstringInternetMessageID=
strings.icontainssubstring/Encryption/retrieve.ashx

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        body.links.href_url.path contains "/Encryption/retrieve.ashx"
        body.links.href_url.query_params contains "InternetMessageID="
      body.links.href_url.domain.root_domain eq "office365.com"
  any(attachments)
    or
      attachments.content_type eq "application/x-microsoft-rpmsg-message"
      attachments.file_extension eq "rpmsg"
  recipients.to length_compare "1"
  type.inbound eq "true"
   macro "all(recipients.to)"

Indicators

These rows show field, operator, and value matches.

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

Link: Mismatched free file host links with document lure

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

Detects inbound emails containing mismatched hyperlinks where the displayed URL references a free file hosting service but the actual destination points to another free file host or a suspicious TLD. The rule combines this with NLU classification identifying BEC or credential theft intent, along with body text patterns common to fake document/scan notifications (e.g., 'scanned from', 'shared via', 'for your review') or short, urgency-driven messages. Trusted senders with passing DMARC are excluded to reduce false positives.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Credential Phishing
Tactics and techniquesFree file host, 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 any(filter(body.current_thread.links, .mismatched),
        any([.display_url.domain.domain, .display_url.domain.root_domain],
            . in $free_file_hosts
        )
        and (
          any([.href_url.domain.domain, .href_url.domain.root_domain],
              . in $free_file_hosts
          )
          or .href_url.domain.tld in $suspicious_tlds
        )
)
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name in ("bec", "cred_theft") and .confidence != "low"
)
and 2 of (
  regex.icontains(body.current_thread.text,
                  'scanned from',
                  'total images',
                  'attachment format',
                  'scan information',
                  'statement/remittance',
                  'versalink',
                  'made a file available',
                  'document from .{0,40}is available',
                  '(?:uploaded|shared) via',
                  '(?:report|available) for your review'
  ),
  regex.icontains(body.current_thread.text, '={5,}|_{10,}'),
  length(body.current_thread.text) < 700,
  regex.icontains(body.current_thread.text,
                  'kindly review',
                  'review the attached',
                  'let us know the next step',
                  'for your review',
                  'please review the'
  )
)
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 emails containing mismatched hyperlinks where the displayed URL references a free file hosting service but the actual destination points to another free file host or a suspicious TLD. The rule combines this with NLU classification identifying BEC or credential theft intent, along with body text patterns common to fake document/scan notifications (e.g., 'scanned from', 'shared via', 'for your review') or short, urgency-driven messages. Trusted senders with passing DMARC are excluded to reduce false positives.

  1. inbound message
  2. any of filter(body.current_thread.links) where all hold:
    • any of [.display_url.domain.domain, .display_url.domain.root_domain] where:
      • . in $free_file_hosts
    • any of:
      • any of [.href_url.domain.domain, .href_url.domain.root_domain] where:
        • . in $free_file_hosts
      • .href_url.domain.tld in $suspicious_tlds
  3. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name in ('bec', 'cred_theft')
    • .confidence is not 'low'
  4. at least 2 of:
    • body.current_thread.text matches any of 10 patterns
      • scanned from
      • total images
      • attachment format
      • scan information
      • statement/remittance
      • versalink
      • made a file available
      • document from .{0,40}is available
      • (?:uploaded|shared) via
      • (?:report|available) for your review
    • body.current_thread.text matches '={5,}|_{10,}'
    • length(body.current_thread.text) < 700
    • body.current_thread.text matches any of 5 patterns
      • kindly review
      • review the attached
      • let us know the next step
      • for your review
      • please review the
  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[].mismatched, body.current_thread.text, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: ml.nlu_classifier, regex.icontains. Reference lists: $free_file_hosts, $high_trust_sender_root_domains, $suspicious_tlds.

Indicators matched (18)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).intents[].namememberbec
ml.nlu_classifier(body.current_thread.text).intents[].namemembercred_theft
regex.icontainsregexscanned from
regex.icontainsregextotal images
regex.icontainsregexattachment format
regex.icontainsregexscan information
regex.icontainsregexstatement/remittance
regex.icontainsregexversalink
regex.icontainsregexmade a file available
regex.icontainsregexdocument from .{0,40}is available
regex.icontainsregex(?:uploaded|shared) via
regex.icontainsregex(?:report|available) for your review
6 more
regex.icontainsregex={5,}|_{10,}
regex.icontainsregexkindly review
regex.icontainsregexreview the attached
regex.icontainsregexlet us know the next step
regex.icontainsregexfor your review
regex.icontainsregexplease review the

Stages and Predicates

Stage 1: mql_rule

and
  any(filter(body.current_thread.links))
    and
      or
        any([filter(body.current_thread.links).href_url.domain.domain, filter(body.current_thread.links).href_url.domain.root_domain])
           macro "[filter(body.current_thread.links)[].href_url.domain.domain, filter(body.current_thread.links)[].href_url.domain.root_domain][] in free_file_hosts"
         macro "filter(body.current_thread.links)[].href_url.domain.tld in suspicious_tlds"
      any([filter(body.current_thread.links).display_url.domain.domain, filter(body.current_thread.links).display_url.domain.root_domain])
         macro "[filter(body.current_thread.links)[].display_url.domain.domain, filter(body.current_thread.links)[].display_url.domain.root_domain][] in free_file_hosts"
  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 ne "low"
      ml.nlu_classifier(body.current_thread.text).intents.name in ["bec", "cred_theft"]
  or
    body.current_thread.text length_compare "700"
    body.current_thread.text regex_match "(?:report|available) for your review"
    body.current_thread.text regex_match "(?:uploaded|shared) via"
    body.current_thread.text regex_match "={5,}|_{10,}"
    body.current_thread.text regex_match "attachment format"
    body.current_thread.text regex_match "document from .{0,40}is available"
    body.current_thread.text regex_match "for your review"
    body.current_thread.text regex_match "kindly review"
    body.current_thread.text regex_match "let us know the next step"
    body.current_thread.text regex_match "made a file available"
    body.current_thread.text regex_match "please review the"
    body.current_thread.text regex_match "review the attached"
    body.current_thread.text regex_match "scan information"
    body.current_thread.text regex_match "scanned from"
    body.current_thread.text regex_match "statement/remittance"
    body.current_thread.text regex_match "total images"
    body.current_thread.text regex_match "versalink"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textregex_match
  • (?:report|available) for your review
  • (?:uploaded|shared) via
    • ={5,}
    • _{10,}
  • attachment format
  • document from .{0,40}is available
  • for your review
  • kindly review
  • let us know the next step
  • made a file available
  • please review the
  • review the attached
  • scan information
  • scanned from
  • statement/remittance
  • total images
  • versalink
field:"body.current_thread.text" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link: Multiple HTTP protocols in single URL

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

Detects messages containing links with 5 or more HTTP protocol declarations within a single URL, indicating potential URL manipulation or obfuscation techniques.

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.current_thread
  • sender.email
  • type

Rule body

type.inbound
and 0 < length(body.current_thread.links) < 10
and any(body.current_thread.links,
        .visible
        // no ability to loop query_params_decoded, so create the non-decoded equivlent 
        and not strings.icontains(.href_url.url, 'unsubscribe')
        and not strings.icontains(.display_text, 'unsubscribe')
        and any(regex.extract(.href_url.query_params,
                              '[?&](?P<name>[^=&]+)(?:=(?P<value>[^&]*))?'
                ),

                // filter down to query params that start with a url
                regex.contains(.named_groups['value'],
                               '^(?:https?(?:%253[Aa]|%3[Aa]|:))?(?:%252[Ff]|%2[Ff]|/)(?:%252[Ff]|%2[Ff]|/)'
                )
                // the number of unique domains in the URL query param is greater or equal to three
                and length(distinct(map(filter(regex.iextract(.named_groups['value'],
                                                              '(?:https?(?:%253[Aa]|%3[Aa]|:))?(?:%252[Ff]|%2[Ff]|/)(?:%252[Ff]|%2[Ff]|/)(?P<domain>[^/\s&%]+)'
                                               ),
                                               // sometimes URLs have // and produce entries we want to skip
                                               // so ensure it's a valid domain first
                                               strings.parse_domain(.named_groups['domain']
                                               ).error is null
                                               and strings.parse_domain(.named_groups['domain']
                                               ).valid
                                               // remove domain that are the same as the sender root domain
                                               and strings.parse_domain(.named_groups['domain']
                                               ).root_domain != sender.email.domain.root_domain
                                        ),
                                        // return just the root domian
                                        strings.parse_domain(.named_groups['domain']
                                        ).root_domain
                                    ),
                                    .
                           )
                ) >= 3

                // there are three or more total URLs in that query param
                and regex.count(.named_groups['value'],
                                '(?:https?(?:%253[Aa]|%3[Aa]|:))?(?:%252[Ff]|%2[Ff]|/)(?:%252[Ff]|%2[Ff]|/)'
                ) >= 3
        )
)

Detection logic

Scope: inbound message.

Detects messages containing links with 5 or more HTTP protocol declarations within a single URL, indicating potential URL manipulation or obfuscation techniques.

  1. inbound message
  2. all of:
    • length(body.current_thread.links) > 0
    • length(body.current_thread.links) < 10
  3. any of body.current_thread.links where all hold:
    • .visible
    • not:
      • .href_url.url contains 'unsubscribe'
    • not:
      • .display_text contains 'unsubscribe'
    • any of regex.extract(.href_url.query_params) where all hold:
      • .named_groups['value'] matches '^(?:https?(?:%253[Aa]|%3[Aa]|:))?(?:%252[Ff]|%2[Ff]|/)(?:%252[Ff]|%2[Ff]|/)'
      • length(distinct(map(filter(regex.iextract(.named_groups['value'], '(?:https?(?:%253[Aa]|%3[Aa]|:))?(?:%252[Ff]|%2[Ff]|/)(?:%252[Ff]|%2[Ff]|/)(?P<domain>[^/\\s&%]+)'), strings.parse_domain(.named_groups['domain']).error is null and strings.parse_domain(.named_groups['domain']).valid and strings.parse_domain(.named_groups['domain']).root_domain != sender.email.domain.root_domain), strings.parse_domain(.named_groups['domain']).root_domain), .)) ≥ 3
      • regex.count(.named_groups['value'], '(?:https?(?:%253[Aa]|%3[Aa]|:))?(?:%252[Ff]|%2[Ff]|/)(?:%252[Ff]|%2[Ff]|/)') ≥ 3

Inspects: body.current_thread.links, body.current_thread.links[].display_text, body.current_thread.links[].href_url.query_params, body.current_thread.links[].href_url.url, body.current_thread.links[].visible, sender.email.domain.root_domain, type.inbound. Sensors: regex.contains, regex.count, regex.extract, regex.iextract, strings.icontains, strings.parse_domain.

Indicators matched (4)

FieldMatchValue
regex.extractregex[?&](?P<name>[^=&]+)(?:=(?P<value>[^&]*))?
regex.containsregex^(?:https?(?:%253[Aa]|%3[Aa]|:))?(?:%252[Ff]|%2[Ff]|/)(?:%252[Ff]|%2[Ff]|/)
regex.iextractregex(?:https?(?:%253[Aa]|%3[Aa]|:))?(?:%252[Ff]|%2[Ff]|/)(?:%252[Ff]|%2[Ff]|/)(?P<domain>[^/\s&%]+)
regex.countregex(?:https?(?:%253[Aa]|%3[Aa]|:))?(?:%252[Ff]|%2[Ff]|/)(?:%252[Ff]|%2[Ff]|/)

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    and
      any(regex.extract(body.current_thread.links.href_url.query_params))
        and
          distinct(map(filter(regex.iextract(regex.extract(body.current_thread.links[].href_url.query_params)[].named_groups['value'], '(?:https?(?:%253[Aa]|%3[Aa]|:))?(?:%252[Ff]|%2[Ff]|/)(?:%252[Ff]|%2[Ff]|/)(?P<domain>[^/\\s&%]+)'), strings.parse_domain(regex.extract(body.current_thread.links[].href_url.query_params)[].named_groups['domain']).error is null and strings.parse_domain(regex.extract(body.current_thread.links[].href_url.query_params)[].named_groups['domain']).valid and strings.parse_domain(regex.extract(body.current_thread.links[].href_url.query_params)[].named_groups['domain']).root_domain != sender.email.domain.root_domain), strings.parse_domain(regex.extract(body.current_thread.links[].href_url.query_params)[].named_groups['domain']).root_domain), regex.extract(body.current_thread.links[].href_url.query_params)[]) length_compare "3"
          regex.count func_call "regex.count(regex.extract(body.current_thread.links[].href_url.query_params)[].named_groups['value'], \"(?:https?(?:%253[Aa]|%3[Aa]|:))?(?:%252[Ff]|%2[Ff]|/)(?:%252[Ff]|%2[Ff]|/)\") >= 3"
          regex.extract(body.current_thread.links[].href_url.query_params)[].named_groups['value'] regex_match "^(?:https?(?:%253[Aa]|%3[Aa]|:))?(?:%252[Ff]|%2[Ff]|/)(?:%252[Ff]|%2[Ff]|/)"
      not
        body.current_thread.links.display_text contains "unsubscribe"
      not
        body.current_thread.links.href_url.url contains "unsubscribe"
      body.current_thread.links.visible eq "true"
  body.current_thread.links length_compare "0"
  body.current_thread.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"

Link: Multistage landing - Abused Adobe Acrobat hosted PDF

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

Detects an inbound message containing an Adobe Acrobat link that leads to a single page PDF document with suspicious indicators, including minimal text, brand logos, document viewer language, and the message is not a reply.

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
  • type

Rule body

type.inbound
and any(body.links,
        .href_url.domain.domain == "acrobat.adobe.com"
        and strings.istarts_with(.href_url.path, '/id/urn:')
)
and length(distinct(filter(body.links,
                           .href_url.domain.domain == "acrobat.adobe.com"
                           and strings.istarts_with(.href_url.path, '/id/urn:')
                    ),
                    .href_url.url
           )
) == 1
and any(filter(body.links,
               .href_url.domain.domain == "acrobat.adobe.com"
               and strings.istarts_with(.href_url.path, '/id/urn:')
        ),
        any(ml.link_analysis(., mode="aggressive").additional_responses,
            (
              any(file.explode(.file),
                  any(.scan.exiftool.fields,
                      // password protected pdf
                      .key == "Warning"
                      and strings.icontains(.value, "password protected")
                  )
              )
              // a low amount of links
              or (
                any(file.explode(.file), 1 <= length(.scan.url.urls) <= 2)
                // a single page
                and any(file.explode(.file),
                        .scan.exiftool.page_count == 1
                        // occurs when there are exif errors
                        or .scan.exiftool.page_count is null
                )
                // susipicious indicators
                and (
                  // logo detection of brands for file sharing companies
                  any(ml.logo_detect(.file).brands,
                      .name in ("DocuSign", "Adobe")
                      or strings.istarts_with(.name, 'Microsoft')
                  )
                  // look at the OCR of the document as well
                  or (
                    length(beta.ocr(.file).text) < 750
                    and (
                      regex.icontains(beta.ocr(.file).text, 'e-sign(?:ature)?')
                      or strings.icontains(beta.ocr(.file).text,
                                           'shared a document',
                                           'review and sign',
                                           'PDF viewer',
                                           "display this type of document",
                                           'please wait...',
                                           'New PDF Document',
                                           'view document',
                                           'open the secure review session'
                      )
                    )
                  )
                )
              )
            )
        )
)
and length(headers.references) == 0
and headers.in_reply_to is null

Detection logic

Scope: inbound message.

Detects an inbound message containing an Adobe Acrobat link that leads to a single page PDF document with suspicious indicators, including minimal text, brand logos, document viewer language, and the message is not a reply.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.domain.domain is 'acrobat.adobe.com'
    • .href_url.path starts with '/id/urn:'
  3. length(distinct(filter(body.links, .href_url.domain.domain == 'acrobat.adobe.com' and strings.istarts_with(.href_url.path, '/id/urn:')), .href_url.url)) is 1
  4. any of filter(body.links) where:
    • any of ml.link_analysis(., mode='aggressive').additional_responses where any holds:
      • any of file.explode(.file) where:
        • any of .scan.exiftool.fields where all hold:
          • .key is 'Warning'
          • .value contains 'password protected'
      • all of:
        • any of file.explode(.file) where all hold:
          • length(.scan.url.urls) ≥ 1
          • length(.scan.url.urls) ≤ 2
        • any of file.explode(.file) where any holds:
          • .scan.exiftool.page_count is 1
          • .scan.exiftool.page_count is missing
        • any of:
          • any of ml.logo_detect(.file).brands where any holds:
            • .name in ('DocuSign', 'Adobe')
            • .name starts with 'Microsoft'
          • all of:
            • length(beta.ocr(.file).text) < 750
            • any of:
              • beta.ocr(.file).text matches 'e-sign(?:ature)?'
              • beta.ocr(.file).text contains any of 8 patterns
                • shared a document
                • review and sign
                • PDF viewer
                • display this type of document
                • please wait...
                • New PDF Document
                • view document
                • open the secure review session
  5. length(headers.references) is 0
  6. headers.in_reply_to is missing

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.path, headers.in_reply_to, headers.references, type.inbound. Sensors: beta.ocr, file.explode, ml.link_analysis, ml.logo_detect, regex.icontains, strings.icontains, strings.istarts_with.

Indicators matched (16)

FieldMatchValue
body.links[].href_url.domain.domainequalsacrobat.adobe.com
strings.istarts_withprefix/id/urn:
file.explode(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file)[].scan.exiftool.fields[].keyequalsWarning
strings.icontainssubstringpassword protected
ml.logo_detect(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file).brands[].namememberDocuSign
ml.logo_detect(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file).brands[].namememberAdobe
strings.istarts_withprefixMicrosoft
regex.icontainsregexe-sign(?:ature)?
strings.icontainssubstringshared a document
strings.icontainssubstringreview and sign
strings.icontainssubstringPDF viewer
strings.icontainssubstringdisplay this type of document
4 more
strings.icontainssubstringplease wait...
strings.icontainssubstringNew PDF Document
strings.icontainssubstringview document
strings.icontainssubstringopen the secure review session

Stages and Predicates

Stage 1: mql_rule

and
  any(filter(body.links))
    any(ml.link_analysis(filter(body.links), mode='aggressive').additional_responses)
      or
        and
          or
            and
              or
                beta.ocr(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file).text contains "New PDF Document"
                beta.ocr(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file).text contains "PDF viewer"
                beta.ocr(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file).text contains "display this type of document"
                beta.ocr(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file).text contains "open the secure review session"
                beta.ocr(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file).text contains "please wait..."
                beta.ocr(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file).text contains "review and sign"
                beta.ocr(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file).text contains "shared a document"
                beta.ocr(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file).text contains "view document"
                beta.ocr(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file).text regex_match "e-sign(?:ature)?"
              beta.ocr(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file).text length_compare "750"
            any(ml.logo_detect(ml.link_analysis(filter(body.links), mode='aggressive').additional_responses.file).brands)
              or
                ml.logo_detect(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file).brands[].name in ["Adobe", "DocuSign"]
                ml.logo_detect(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file).brands[].name starts_with "Microsoft"
          any(file.explode(ml.link_analysis(filter(body.links), mode='aggressive').additional_responses.file))
            or
              file.explode(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file)[].scan.exiftool.page_count eq "1"
              file.explode(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file)[].scan.exiftool.page_count is_null
          any(file.explode(ml.link_analysis(filter(body.links), mode='aggressive').additional_responses.file))
            and
              file.explode(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file)[].scan.url.urls length_compare "1"
              file.explode(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file)[].scan.url.urls length_compare "2"
        any(file.explode(ml.link_analysis(filter(body.links), mode='aggressive').additional_responses.file))
          any(file.explode(ml.link_analysis(filter(body.links), mode='aggressive').additional_responses.file).scan.exiftool.fields)
            and
              file.explode(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file)[].scan.exiftool.fields[].key eq "Warning"
              file.explode(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].file)[].scan.exiftool.fields[].value contains "password protected"
  any(body.links)
    and
      body.links.href_url.domain.domain eq "acrobat.adobe.com"
      body.links.href_url.path starts_with "/id/urn:"
  distinct(filter(body.links, .href_url.domain.domain == 'acrobat.adobe.com' and strings.istarts_with(.href_url.path, '/id/urn:')), .href_url.url) length_compare "1"
  headers.in_reply_to is_null
  headers.references length_compare "0"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
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"

Link: Multistage landing - Abused Adobe frame.io

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

The detection rule matches on message groups which make use of Adobe's frame.io as a landing page. The landing page contains links which are newly registered, use free file or subdomain hosts, url shortners or when visited are phishing pages, lead to a captcha or redirect to a well-known domain, seen in evasion tactics.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, 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.domain == "frame.io"
// these messages contain no email address of the actual sender
// so sender profile won't be interesting
// however the subject and sender display names do contain the name of the frame.io account
// which sent the share

// negate where internal employees might have sent the message
and not any($org_display_names, strings.istarts_with(subject.subject, .))

// limiting scope to just "shares" in subject
and strings.icontains(subject.subject, ' shared ')

// the subject contains the name of the file that has been shared
// the body does not contain the name shared depending on how it's shared, 
// let us use the suspicious file shares from sharepoint here
// https://github.com/sublime-security/sublime-rules/blob/main/detection-rules/link_sharepoint_sus_name.yml
and (
  (
    // file sharing service references
    strings.icontains(subject.subject, 'dropbox')
    or strings.icontains(subject.subject, 'docusign')

    // file name lures
    // secure theme
    or regex.icontains(subject.subject, 'secured?.*(?:file|document|docs|fax)')
    or regex.icontains(subject.subject, 'important.*(?:file|document|docs|fax)')
    or regex.icontains(subject.subject, 'shared?.*(?:file|document|docs|fax)')
    or regex.icontains(subject.subject, 'protected.*(?:file|document|docs|fax)')
    or regex.icontains(subject.subject, 'encrypted.*(?:file|document|docs|fax)')

    // scanner theme
    or strings.icontains(subject.subject, 'scanne[rd]_')
    // image themed
    or strings.icontains(subject.subject, '_IMG_')
    or regex.icontains(subject.subject, '^IMG[_-](?:\d|\W)+$')

    // digits
    or regex.icontains(subject.subject, 'doc(?:ument)?\s?\d+$')
    or regex.icontains(subject.subject, '^\d+$')

    // onedrive theme
    or strings.icontains(subject.subject, 'one_docx')
    or strings.icontains(subject.subject, 'OneDrive')
    or regex.icontains(subject.subject, 'A document.*One.?Drive')

    // action in file name
    or strings.icontains(subject.subject, 'click here')
    or strings.icontains(subject.subject, 'Download PDF')
    or strings.icontains(subject.subject, 'Validate')

    // limited file name to "confidential"
    or subject.subject =~ 'Confidentiality'
    or subject.subject =~ 'Confidential'

    // invoice themes
    or any(ml.nlu_classifier(subject.subject).entities, .name == "financial")
    or strings.icontains(subject.subject, 'payment')
    or strings.icontains(subject.subject, 'invoice')
    or regex.icontains(subject.subject, 'INV(?:_|\s)?\d+$')
    // starts with INV_ or INV\x20
    or regex.icontains(subject.subject, '^INV(?:_|\s)')
    or regex.icontains(subject.subject, 'P[O0]\W+?\d+$')
    or strings.icontains(subject.subject, 'receipt')
    or strings.icontains(subject.subject, 'billing')
    or (
      strings.icontains(subject.subject, 'statement')
      and not subject.subject =~ "Privacy Statement"
    )
    or strings.icontains(subject.subject, 'Past Due')
    or regex.icontains(subject.subject, 'Remit(tance)?')
    or strings.icontains(subject.subject, 'Purchase Order')

    // contract language
    or strings.icontains(subject.subject, 'settlement')
    or strings.icontains(subject.subject, 'contract agreement')
    or regex.icontains(subject.subject, 'Pr[0o]p[0o]sal')
    or strings.icontains(subject.subject, 'contract doc')
  )
  or any(filter(body.links,
                .href_url.domain.root_domain == "frame.io"
                and (
                  strings.starts_with(.href_url.path, '/reviews/')
                  or strings.starts_with(.href_url.path, '/presentations/')
                )
         ),
         // when visiting the page on frame.io, the links contain
         // indications of being suspicious
         any(filter(ml.link_analysis(.).final_dom.links,
                    // remove links that are within frame.io or their default page
                    .href_url.domain.root_domain not in (
                      'frame.io',
                      'f.io',
                      'onetrust.com'
                    )
             ),
             (
               // any of those links domains are new
               network.whois(.href_url.domain).days_old < 30

               // go to free file hosts
               or .href_url.domain.root_domain in $free_file_hosts
               or .href_url.domain.domain in $free_file_hosts

               // go to free subdomains hosts
               or (
                 .href_url.domain.root_domain in $free_subdomain_hosts
                 // where there is a subdomain
                 and .href_url.domain.subdomain is not null
                 and .href_url.domain.subdomain != "www"
               )
               // go to url shortners
               or .href_url.domain.root_domain in $url_shorteners
               or .href_url.domain.root_domain in $social_landing_hosts
               or .href_url.domain.domain in $url_shorteners
               or .href_url.domain.domain in $social_landing_hosts
               or (
                 // find any links that mention common "action" words
                 regex.icontains(subject.subject,
                                 '(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)'
                 )
                 and (
                   // and when visiting those links, are phishing
                   ml.link_analysis(., mode="aggressive").credphish.disposition == "phishing"

                   // hit a captcha page
                   or ml.link_analysis(., mode="aggressive").credphish.contains_captcha

                   // or the page redirects to common website, observed when evasion happens
                   or (
                     length(ml.link_analysis(., mode="aggressive").redirect_history
                     ) > 0
                     and ml.link_analysis(., mode="aggressive").effective_url.domain.root_domain in $tranco_10k
                   )
                 )
               )
             )
         )

         // or search for QR codes in the screenshot of the frame.io page
         or any(file.explode(ml.link_analysis(.).screenshot),
                .depth == 0
                and (
                  (
                    .scan.qr.type == "url"
                    and .scan.qr.url.domain.root_domain not in (
                      'frame.io',
                      'f.io',
                      'onetrust.com'
                    )
                  )
                  // some samples have a pdf uploaded that contains a Sharepoint File Share lure.
                  // we can use ocr to detect this
                  or strings.icontains(.scan.ocr.raw,
                                       'This email contains a secure link to sharepoint'
                  )
                )
         )
  )
)

Detection logic

Scope: inbound message.

The detection rule matches on message groups which make use of Adobe's frame.io as a landing page. The landing page contains links which are newly registered, use free file or subdomain hosts, url shortners or when visited are phishing pages, lead to a captcha or redirect to a well-known domain, seen in evasion tactics.

  1. inbound message
  2. sender.email.domain.domain is 'frame.io'
  3. not:
    • any of $org_display_names where:
      • strings.istarts_with(subject.subject)
  4. subject.subject contains ' shared '
  5. any of:
    • any of:
      • subject.subject contains 'dropbox'
      • subject.subject contains 'docusign'
      • subject.subject matches 'secured?.*(?:file|document|docs|fax)'
      • subject.subject matches 'important.*(?:file|document|docs|fax)'
      • subject.subject matches 'shared?.*(?:file|document|docs|fax)'
      • subject.subject matches 'protected.*(?:file|document|docs|fax)'
      • subject.subject matches 'encrypted.*(?:file|document|docs|fax)'
      • subject.subject contains 'scanne[rd]_'
      • subject.subject contains '_IMG_'
      • subject.subject matches '^IMG[_-](?:\\d|\\W)+$'
      • subject.subject matches 'doc(?:ument)?\\s?\\d+$'
      • subject.subject matches '^\\d+$'
      • subject.subject contains 'one_docx'
      • subject.subject contains 'OneDrive'
      • subject.subject matches 'A document.*One.?Drive'
      • subject.subject contains 'click here'
      • subject.subject contains 'Download PDF'
      • subject.subject contains 'Validate'
      • subject.subject is 'Confidentiality'
      • subject.subject is 'Confidential'
      • any of ml.nlu_classifier(subject.subject).entities where:
        • .name is 'financial'
      • subject.subject contains 'payment'
      • subject.subject contains 'invoice'
      • subject.subject matches 'INV(?:_|\\s)?\\d+$'
      • subject.subject matches '^INV(?:_|\\s)'
      • subject.subject matches 'P[O0]\\W+?\\d+$'
      • subject.subject contains 'receipt'
      • subject.subject contains 'billing'
      • all of:
        • subject.subject contains 'statement'
        • not:
          • subject.subject is 'Privacy Statement'
      • subject.subject contains 'Past Due'
      • subject.subject matches 'Remit(tance)?'
      • subject.subject contains 'Purchase Order'
      • subject.subject contains 'settlement'
      • subject.subject contains 'contract agreement'
      • subject.subject matches 'Pr[0o]p[0o]sal'
      • subject.subject contains 'contract doc'
    • any of filter(body.links) where any holds:
      • any of filter(...) where any holds:
        • network.whois(.href_url.domain).days_old < 30
        • .href_url.domain.root_domain in $free_file_hosts
        • .href_url.domain.domain in $free_file_hosts
        • all of:
          • .href_url.domain.root_domain in $free_subdomain_hosts
          • .href_url.domain.subdomain is set
          • .href_url.domain.subdomain is not 'www'
        • .href_url.domain.root_domain in $url_shorteners
        • .href_url.domain.root_domain in $social_landing_hosts
        • .href_url.domain.domain in $url_shorteners
        • .href_url.domain.domain in $social_landing_hosts
        • all of:
          • subject.subject matches '(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)'
          • any of:
            • ml.link_analysis(.).credphish.disposition is 'phishing'
            • ml.link_analysis(.).credphish.contains_captcha
            • all of:
              • length(ml.link_analysis(., mode='aggressive').redirect_history) > 0
              • ml.link_analysis(.).effective_url.domain.root_domain in $tranco_10k
      • any of file.explode(...) where all hold:
        • .depth is 0
        • any of:
          • all of:
            • .scan.qr.type is 'url'
            • .scan.qr.url.domain.root_domain not in ('frame.io', 'f.io', 'onetrust.com')
          • .scan.ocr.raw contains 'This email contains a secure link to sharepoint'

Inspects: body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.path, sender.email.domain.domain, subject.subject, type.inbound. Sensors: file.explode, ml.link_analysis, ml.nlu_classifier, network.whois, regex.icontains, strings.icontains, strings.istarts_with, strings.starts_with. Reference lists: $free_file_hosts, $free_subdomain_hosts, $org_display_names, $social_landing_hosts, $tranco_10k, $url_shorteners.

Indicators matched (44)

FieldMatchValue
sender.email.domain.domainequalsframe.io
strings.icontainssubstring shared
strings.icontainssubstringdropbox
strings.icontainssubstringdocusign
regex.icontainsregexsecured?.*(?:file|document|docs|fax)
regex.icontainsregeximportant.*(?:file|document|docs|fax)
regex.icontainsregexshared?.*(?:file|document|docs|fax)
regex.icontainsregexprotected.*(?:file|document|docs|fax)
regex.icontainsregexencrypted.*(?:file|document|docs|fax)
strings.icontainssubstringscanne[rd]_
strings.icontainssubstring_IMG_
regex.icontainsregex^IMG[_-](?:\d|\W)+$
32 more
regex.icontainsregexdoc(?:ument)?\s?\d+$
regex.icontainsregex^\d+$
strings.icontainssubstringone_docx
strings.icontainssubstringOneDrive
regex.icontainsregexA document.*One.?Drive
strings.icontainssubstringclick here
strings.icontainssubstringDownload PDF
strings.icontainssubstringValidate
subject.subjectequalsConfidentiality
subject.subjectequalsConfidential
ml.nlu_classifier(subject.subject).entities[].nameequalsfinancial
strings.icontainssubstringpayment
strings.icontainssubstringinvoice
regex.icontainsregexINV(?:_|\s)?\d+$
regex.icontainsregex^INV(?:_|\s)
regex.icontainsregexP[O0]\W+?\d+$
strings.icontainssubstringreceipt
strings.icontainssubstringbilling
strings.icontainssubstringstatement
strings.icontainssubstringPast Due
regex.icontainsregexRemit(tance)?
strings.icontainssubstringPurchase Order
strings.icontainssubstringsettlement
strings.icontainssubstringcontract agreement
regex.icontainsregexPr[0o]p[0o]sal
strings.icontainssubstringcontract doc
body.links[].href_url.domain.root_domainequalsframe.io
strings.starts_withprefix/reviews/
strings.starts_withprefix/presentations/
regex.icontainsregex(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)
file.explode(...)[].scan.qr.typeequalsurl
strings.icontainssubstringThis email contains a secure link to sharepoint

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(filter(body.links))
      or
        any(file.explode(...))
          and
            or
              and
                not
                  file.explode(...).scan.qr.url.domain.root_domain in ["f.io", "frame.io", "onetrust.com"]
                file.explode(...).scan.qr.type eq "url"
              file.explode(...).scan.ocr.raw contains "This email contains a secure link to sharepoint"
            file.explode(...).depth eq "0"
        any(filter(...))
          or
            and
              or
                and
                  ml.link_analysis func_call "ml.link_analysis(filter(...)[]).effective_url.domain.root_domain in tranco_10k"
                  ml.link_analysis(filter(...)[], mode='aggressive').redirect_history length_compare "0"
                ml.link_analysis func_call "ml.link_analysis(filter(...)[]).credphish.contains_captcha"
                ml.link_analysis func_call "ml.link_analysis(filter(...)[]).credphish.disposition == phishing"
              subject.subject regex_match "(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)"
            and
              filter(...).href_url.domain.subdomain is_not_null
              filter(...).href_url.domain.subdomain ne "www"
               macro "filter(...)[].href_url.domain.root_domain in free_subdomain_hosts"
            network.whois func_call "network.whois(filter(...)[].href_url.domain).days_old < 30"
             macro "filter(...)[].href_url.domain.domain in free_file_hosts"
             macro "filter(...)[].href_url.domain.domain in social_landing_hosts"
             macro "filter(...)[].href_url.domain.domain in url_shorteners"
             macro "filter(...)[].href_url.domain.root_domain in free_file_hosts"
             macro "filter(...)[].href_url.domain.root_domain in social_landing_hosts"
             macro "filter(...)[].href_url.domain.root_domain in url_shorteners"
    and
      not
        subject.subject eq "Privacy Statement"
      subject.subject contains "statement"
    any(ml.nlu_classifier(subject.subject).entities)
      ml.nlu_classifier(subject.subject).entities.name eq "financial"
    subject.subject contains "Download PDF"
    subject.subject contains "OneDrive"
    subject.subject contains "Past Due"
    subject.subject contains "Purchase Order"
    subject.subject contains "Validate"
    subject.subject contains "_IMG_"
    subject.subject contains "billing"
    subject.subject contains "click here"
    subject.subject contains "contract agreement"
    subject.subject contains "contract doc"
    subject.subject contains "docusign"
    subject.subject contains "dropbox"
    subject.subject contains "invoice"
    subject.subject contains "one_docx"
    subject.subject contains "payment"
    subject.subject contains "receipt"
    subject.subject contains "scanne[rd]_"
    subject.subject contains "settlement"
    subject.subject eq "Confidential"
    subject.subject eq "Confidentiality"
    subject.subject regex_match "A document.*One.?Drive"
    subject.subject regex_match "INV(?:_|\\s)?\\d+$"
    subject.subject regex_match "P[O0]\\W+?\\d+$"
    subject.subject regex_match "Pr[0o]p[0o]sal"
    subject.subject regex_match "Remit(tance)?"
    subject.subject regex_match "^IMG[_-](?:\\d|\\W)+$"
    subject.subject regex_match "^INV(?:_|\\s)"
    subject.subject regex_match "^\\d+$"
    subject.subject regex_match "doc(?:ument)?\\s?\\d+$"
    subject.subject regex_match "encrypted.*(?:file|document|docs|fax)"
    subject.subject regex_match "important.*(?:file|document|docs|fax)"
    subject.subject regex_match "protected.*(?:file|document|docs|fax)"
    subject.subject regex_match "secured?.*(?:file|document|docs|fax)"
    subject.subject regex_match "shared?.*(?:file|document|docs|fax)"
  not
    any($org_display_names)
      strings.istarts_with func_call "strings.istarts_with(subject.subject)"
  sender.email.domain.domain eq "frame.io"
  subject.subject contains " shared "
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
$org_display_namesarray_any(no value, null check)excludes:$org_display_names

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
sender.email.domain.domaineq
  • frame.io
field:"sender.email.domain.domain" kind:eq value:"frame.io"
subject.subjectcontains
  • shared
  • Download PDF
  • OneDrive
  • Past Due
  • Purchase Order
  • Validate
  • _IMG_
  • billing
  • click here
  • contract agreement
  • contract doc
  • docusign
  • dropbox
  • invoice
  • one_docx
  • payment
  • receipt
  • scanne[rd]_
  • settlement
  • statement
field:"subject.subject" kind:contains
subject.subjecteq
  • Confidential
  • Confidentiality
field:"subject.subject" kind:eq
subject.subjectregex_match
  • A document.*One.?Drive
  • INV(?:_|\s)?\d+$
  • P[O0]\W+?\d+$
  • Pr[0o]p[0o]sal
  • Remit(tance)?
  • ^IMG[_-](?:\d|\W)+$
  • ^INV(?:_|\s)
  • ^\d+$
  • doc(?:ument)?\s?\d+$
  • encrypted.*(?:file|document|docs|fax)
  • important.*(?:file|document|docs|fax)
  • protected.*(?:file|document|docs|fax)
  • secured?.*(?:file|document|docs|fax)
  • shared?.*(?:file|document|docs|fax)
field:"subject.subject" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link: Multistage Landing - Abused Buildin.ai

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

Analyzes shared content links from buildin.ai domain that contain credential harvesting language with medium to high confidence in the display text.

Threat classification

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

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

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound

// filter to just buildin.ai
and any(filter(body.links,
               (
                 .href_url.domain.root_domain == "buildin.ai"
                 and strings.icontains(.href_url.path, '/share')
               // inspect display text
               )
        ),
        any(ml.nlu_classifier(ml.link_analysis(., mode="aggressive").final_dom.display_text
            ).intents,
            .name == "cred_theft" and .confidence in ("medium", "high")
        )
)

Detection logic

Scope: inbound message.

Analyzes shared content links from buildin.ai domain that contain credential harvesting language with medium to high confidence in the display text.

  1. inbound message
  2. any of filter(body.links) where:
    • any of ml.nlu_classifier(ml.link_analysis(., mode='aggressive').final_dom.display_text).intents where all hold:
      • .name is 'cred_theft'
      • .confidence in ('medium', 'high')

Inspects: body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.path, type.inbound. Sensors: ml.link_analysis, ml.nlu_classifier, strings.icontains.

Indicators matched (5)

FieldMatchValue
body.links[].href_url.domain.root_domainequalsbuildin.ai
strings.icontainssubstring/share
ml.nlu_classifier(ml.link_analysis(filter(body.links)[], mode='aggressive').final_dom.display_text).intents[].nameequalscred_theft
ml.nlu_classifier(ml.link_analysis(filter(body.links)[], mode='aggressive').final_dom.display_text).intents[].confidencemembermedium
ml.nlu_classifier(ml.link_analysis(filter(body.links)[], mode='aggressive').final_dom.display_text).intents[].confidencememberhigh

Stages and Predicates

Stage 1: mql_rule

and
  any(filter(body.links))
    any(ml.nlu_classifier(ml.link_analysis(filter(body.links), mode='aggressive').final_dom.display_text).intents)
      and
        ml.nlu_classifier(ml.link_analysis(filter(body.links)[], mode='aggressive').final_dom.display_text).intents[].confidence in ["high", "medium"]
        ml.nlu_classifier(ml.link_analysis(filter(body.links)[], mode='aggressive').final_dom.display_text).intents[].name eq "cred_theft"
  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"

Link: Multistage landing - Abused Docusign

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

The detection rule matches on message groups which make use of Docusign as a landing page. The landing page contains links which are newly registered, use free file or subdomain hosts, url shortners or when visited are phishing pages, lead to a captcha or rediret to a top website.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Free subdomain host, Free file host

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound

//
// 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
//
  
// reply-to email address has never been sent an email by the org
and not beta.profile.by_reply_to().solicited

// do not match if the reply_to address has been observed as a reply_to address
// of a message that has been classified as benign
and not beta.profile.by_reply_to().any_messages_benign

// message is from docusign actual
and sender.email.domain.root_domain == 'docusign.net'
and (headers.auth_summary.spf.pass or headers.auth_summary.dmarc.pass)

// filter out all the links, keeping only the links of interest
and any(filter(body.links,
               // target the DocuSign link
               (
                 regex.icontains(.display_text,
                                 "((view|show).completed.document|(?:re)?view doc|view.attached)"
                 )
                 or strings.icontains(.href_url.url, '/Signing/EmailStart.aspx')
                 or strings.icontains(.href_url.url, '/signing/emails/v')
               )
        ),

        // filter down the links on the docusign page to those that are external to docusign
        any(filter(ml.link_analysis(., mode="aggressive").final_dom.links,
                   .href_url.domain.root_domain != 'docusign.net'
                   and .href_url.domain.root_domain != 'docusign.com'
                   and .href_url.domain.root_domain not in $org_domains
                   // relative links (no domains)
                   and .href_url.domain.domain is not null
            ),
            (
              // any of those links domains are new
              network.whois(.href_url.domain).days_old < 30
              // go to free file hosts
              or .href_url.domain.root_domain in $free_file_hosts
              or .href_url.domain.domain in $free_file_hosts

              // go to free subdomains hosts
              or (
                .href_url.domain.root_domain in $free_subdomain_hosts
                // where there is a subdomain
                and .href_url.domain.subdomain is not null
                and .href_url.domain.subdomain != "www"
              )
              // go to url shortners
              or .href_url.domain.root_domain in $url_shorteners
              or .href_url.domain.root_domain in $social_landing_hosts
              or .href_url.domain.domain in $url_shorteners
              or .href_url.domain.domain in $social_landing_hosts
              or (
                // find any links that mention common "action" words
                regex.icontains(.display_text,
                                '(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)'
                )
                and (
                  // and when visiting those links, are phishing
                  ml.link_analysis(., mode="aggressive").credphish.disposition == "phishing"

                  // hit a captcha page
                  or ml.link_analysis(., mode="aggressive").credphish.contains_captcha

                  // or the page redirects to common website, observed when evasion happens
                  or (
                    length(ml.link_analysis(., mode="aggressive").redirect_history
                    ) > 0
                    and ml.link_analysis(., mode="aggressive").effective_url.domain.root_domain in $tranco_10k
                  )
                )
              )
            )
        )
)

Detection logic

Scope: inbound message.

The detection rule matches on message groups which make use of Docusign as a landing page. The landing page contains links which are newly registered, use free file or subdomain hosts, url shortners or when visited are phishing pages, lead to a captcha or rediret to a top website.

  1. inbound message
  2. not:
    • beta.profile.by_reply_to().solicited
  3. not:
    • beta.profile.by_reply_to().any_messages_benign
  4. sender.email.domain.root_domain is 'docusign.net'
  5. any of:
    • headers.auth_summary.spf.pass
    • headers.auth_summary.dmarc.pass
  6. any of filter(body.links) where:
    • any of filter(...) where any holds:
      • network.whois(.href_url.domain).days_old < 30
      • .href_url.domain.root_domain in $free_file_hosts
      • .href_url.domain.domain in $free_file_hosts
      • all of:
        • .href_url.domain.root_domain in $free_subdomain_hosts
        • .href_url.domain.subdomain is set
        • .href_url.domain.subdomain is not 'www'
      • .href_url.domain.root_domain in $url_shorteners
      • .href_url.domain.root_domain in $social_landing_hosts
      • .href_url.domain.domain in $url_shorteners
      • .href_url.domain.domain in $social_landing_hosts
      • all of:
        • .display_text matches '(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)'
        • any of:
          • ml.link_analysis(.).credphish.disposition is 'phishing'
          • ml.link_analysis(.).credphish.contains_captcha
          • all of:
            • length(ml.link_analysis(., mode='aggressive').redirect_history) > 0
            • ml.link_analysis(.).effective_url.domain.root_domain in $tranco_10k

Inspects: body.links, body.links[].display_text, body.links[].href_url.url, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, sender.email.domain.root_domain, type.inbound. Sensors: beta.profile.by_reply_to, ml.link_analysis, network.whois, regex.icontains, strings.icontains. Reference lists: $free_file_hosts, $free_subdomain_hosts, $org_domains, $social_landing_hosts, $tranco_10k, $url_shorteners.

Indicators matched (5)

FieldMatchValue
sender.email.domain.root_domainequalsdocusign.net
regex.icontainsregex((view|show).completed.document|(?:re)?view doc|view.attached)
strings.icontainssubstring/Signing/EmailStart.aspx
strings.icontainssubstring/signing/emails/v
regex.icontainsregex(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)

Stages and Predicates

Stage 1: mql_rule

and
  any(filter(body.links))
    any(filter(...))
      or
        and
          or
            and
              ml.link_analysis func_call "ml.link_analysis(filter(...)[]).effective_url.domain.root_domain in tranco_10k"
              ml.link_analysis(filter(...)[], mode='aggressive').redirect_history length_compare "0"
            ml.link_analysis func_call "ml.link_analysis(filter(...)[]).credphish.contains_captcha"
            ml.link_analysis func_call "ml.link_analysis(filter(...)[]).credphish.disposition == phishing"
          filter(...).display_text regex_match "(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)"
        and
          filter(...).href_url.domain.subdomain is_not_null
          filter(...).href_url.domain.subdomain ne "www"
           macro "filter(...)[].href_url.domain.root_domain in free_subdomain_hosts"
        network.whois func_call "network.whois(filter(...)[].href_url.domain).days_old < 30"
         macro "filter(...)[].href_url.domain.domain in free_file_hosts"
         macro "filter(...)[].href_url.domain.domain in social_landing_hosts"
         macro "filter(...)[].href_url.domain.domain in url_shorteners"
         macro "filter(...)[].href_url.domain.root_domain in free_file_hosts"
         macro "filter(...)[].href_url.domain.root_domain in social_landing_hosts"
         macro "filter(...)[].href_url.domain.root_domain in url_shorteners"
  not
    beta.profile.by_reply_to func_call "beta.profile.by_reply_to().any_messages_benign"
  not
    beta.profile.by_reply_to func_call "beta.profile.by_reply_to().solicited"
  or
    headers.auth_summary.dmarc.pass eq "true"
    headers.auth_summary.spf.pass eq "true"
  sender.email.domain.root_domain eq "docusign.net"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Multistage landing - Abused Google Drive

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

The detection rule matches on message groups which make use of Google Drive as a landing page. The landing page contains links which are newly registered, use free file or subdomain hosts, url shortners or when visited are phishing pages, lead to a captcha or redirect to a common website.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Free email provider, Free file host

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

//
// 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
//
// the reply-to address is new or unsolicited
and (
  // reply-to address has never sent an email to the org
  beta.profile.by_reply_to().prevalence == "new"

  // reply-to email address has never been sent an email by the org
  or not beta.profile.by_reply_to().solicited
)

// message is from google actual
and sender.email.domain.domain == 'google.com'
and (
  sender.email.local_part == "drive-shares-noreply"
  or sender.email.local_part == "drive-shares-dm-noreply"
)
and headers.auth_summary.spf.pass
and strings.ends_with(headers.auth_summary.spf.details.designator,
                      'doclist.bounces.google.com'
)
and headers.auth_summary.dmarc.pass

// not where the reply_to address is within org_domains
and not any(headers.reply_to, .email.domain.domain in $org_domains)

// not where the sender display name is within org_display_names
and not any(regex.iextract(sender.display_name,
                           '^(?P<sender_display_name>.*)\((?:via )?Google'
            ),
            .named_groups["sender_display_name"] in~ $org_display_names
)

// threat actors dont want others to edit the share
and not strings.icontains(body.current_thread.text, 'invited you to edit')
and (
  // check the shared filed name for suspicious indicators
  // alerting keywords
  regex.icontains(strings.replace_confusables(subject.subject),
                  ': \".*(?:Immediate|Urgent|Critical|Alert|Warning|Urgent|Important|Critical Alert|Security Notice)[!:\-]?[^\"]*\"'
  )
  // account issues
  or regex.icontains(strings.replace_confusables(subject.subject),
                     ': \".*(?:Online|Bank(?:ing)?|User|Account|Access|[[:punct:]\s]?(?:ID)|Transactions)\b.*\b(?:Security|Recover|Blocked|Suspen(?:ded|sion)|Restricted|Locked|Disabled|Frozen|Closed)[^\"]*\"'
  )
  // keywords themed as Suspicious
  or regex.icontains(strings.replace_confusables(subject.subject),
                     ': \".*(Suspicious|Unauthorized|Unrecognized|Fraudulent|Scam)\b.*\b(Activity|Transaction|Log[- ]?In|Access|Entry|Sign[- ]?In|Detected)[^\"]*\"'
  )
  // account/identify verification keywords
  or regex.icontains(strings.replace_confusables(subject.subject),
                     ': \".*(?:(?:Verify|Confirm|Update|Review|Complete)\b.*\b(Your (Identity|Account|Online[- ]?ID|Billing Information))|(?:(?:Action|Attention|Verification|Review)[[:punct:]\s](?:Needed|Required)))[^\"]*\"'
  )
  or ( // filenames that in References/ID keywords
    regex.icontains(strings.replace_confusables(subject.subject),
                    ': \".*[[:punct:]\s]+\w+[[:punct:]\s]*[a-zA-Z]*[0-9][a-zA-Z0-9]*\"$'
    )
    // the above regex is a bit "open", so close it by checking it with a more specific "ending" pattern.
    and regex.icontains(strings.replace_confusables(subject.subject),
                        '[[:punct:]]\s*[a-z0-9]{5,}\"$'
    )
  )

  // finally get ready to do link analysis
  // filter out all the links, keeping only the links of interest
  or any(filter(body.links,
                // target the "Open" link
                (
                  .href_url.domain.domain == "drive.google.com"
                  and strings.icontains(.href_url.path, '/view')
                  // this isn't controlled by the actor
                  and .display_text == "Open"
                )
         ),
         // the Google Drive page has been taken down due to TOS violations
         strings.icontains(ml.link_analysis(., mode="aggressive").final_dom.display_text,
                           "You can't access this item because it is in violation of our Terms of Service"
         )
         // if not taken down
         // inspect the links on the page
         or any(filter(ml.link_analysis(., mode="aggressive").additional_responses,
                       .url.path == "/viewerng/presspage"
                ),
                any(.json,
                    any(.,
                        any(., // this gets us to the array that contains the links embedded in the PDF
                            network.whois(strings.parse_url(.).domain).days_old < 30
                            or strings.parse_url(.).domain.tld in $suspicious_tlds
                            or (
                              strings.parse_url(.).domain.root_domain in $free_subdomain_hosts
                              and strings.parse_url(.).domain.subdomain is not null
                              and strings.parse_url(.).domain.subdomain != "www"
                            )
                            or strings.parse_url(.).domain.domain in $free_file_hosts
                            or strings.parse_url(.).domain.root_domain in $free_file_hosts
                            or strings.parse_url(.).domain.domain in $url_shorteners
                            or strings.parse_url(.).domain.domain in $social_landing_hosts
                            or strings.parse_url(.).domain.root_domain in $url_shorteners
                            or strings.parse_url(.).domain.root_domain in $social_landing_hosts
                        )
                    )
                )
         )
         // if not taken down
         // filter down the links on the google drive page to those that are external to google
         or any(filter(ml.link_analysis(., mode="aggressive").final_dom.links,
                       .href_url.domain.root_domain != 'google.com'
                       // relative links (no domains)
                       and .href_url.domain.domain is not null
                ),
                (
                  // any of those links domains are new
                  network.whois(.href_url.domain).days_old < 30
                  // go to free file hosts
                  or .href_url.domain.root_domain in $free_file_hosts
                  or .href_url.domain.domain in $free_file_hosts

                  // go to free subdomains hosts
                  or (
                    .href_url.domain.root_domain in $free_subdomain_hosts
                    // where there is a subdomain
                    and .href_url.domain.subdomain is not null
                    and .href_url.domain.subdomain != "www"
                  )
                  // go to url shortners
                  or .href_url.domain.root_domain in $url_shorteners
                  or .href_url.domain.root_domain in $social_landing_hosts
                  or .href_url.domain.domain in $url_shorteners
                  or .href_url.domain.domain in $social_landing_hosts
                  or (
                    // find any links that mention common "action" words
                    regex.icontains(.display_text,
                                    '(?:view|click|show|access|download|continue|goto|Validate|Va[il]idar|login|verify|account)'
                    )
                    and (
                      // and when visiting those links, are phishing
                      ml.link_analysis(., mode="aggressive").credphish.disposition == "phishing"

                      // hit a captcha page
                      or ml.link_analysis(., mode="aggressive").credphish.contains_captcha

                      // or the page redirects to common website, observed when evasion happens
                      or (
                        length(ml.link_analysis(., mode="aggressive").redirect_history
                        ) > 0
                        and ml.link_analysis(., mode="aggressive").effective_url.domain.root_domain in $tranco_10k
                      )
                    )
                  )
                )
         )
  )
)

Detection logic

Scope: inbound message.

The detection rule matches on message groups which make use of Google Drive as a landing page. The landing page contains links which are newly registered, use free file or subdomain hosts, url shortners or when visited are phishing pages, lead to a captcha or redirect to a common website.

  1. inbound message
  2. any of:
    • beta.profile.by_reply_to().prevalence is 'new'
    • not:
      • beta.profile.by_reply_to().solicited
  3. sender.email.domain.domain is 'google.com'
  4. any of:
    • sender.email.local_part is 'drive-shares-noreply'
    • sender.email.local_part is 'drive-shares-dm-noreply'
  5. headers.auth_summary.spf.pass
  6. headers.auth_summary.spf.details.designator ends with 'doclist.bounces.google.com'
  7. headers.auth_summary.dmarc.pass
  8. not:
    • any of headers.reply_to where:
      • .email.domain.domain in $org_domains
  9. not:
    • any of regex.iextract(sender.display_name) where:
      • .named_groups['sender_display_name'] in $org_display_names
  10. not:
    • body.current_thread.text contains 'invited you to edit'
  11. any of:
    • strings.replace_confusables(subject.subject) matches ': \\".*(?:Immediate|Urgent|Critical|Alert|Warning|Urgent|Important|Critical Alert|Security Notice)[!:\\-]?[^\\"]*\\"'
    • strings.replace_confusables(subject.subject) matches ': \\".*(?:Online|Bank(?:ing)?|User|Account|Access|[[:punct:]\\s]?(?:ID)|Transactions)\\b.*\\b(?:Security|Recover|Blocked|Suspen(?:ded|sion)|Restricted|Locked|Disabled|Frozen|Closed)[^\\"]*\\"'
    • strings.replace_confusables(subject.subject) matches ': \\".*(Suspicious|Unauthorized|Unrecognized|Fraudulent|Scam)\\b.*\\b(Activity|Transaction|Log[- ]?In|Access|Entry|Sign[- ]?In|Detected)[^\\"]*\\"'
    • strings.replace_confusables(subject.subject) matches ': \\".*(?:(?:Verify|Confirm|Update|Review|Complete)\\b.*\\b(Your (Identity|Account|Online[- ]?ID|Billing Information))|(?:(?:Action|Attention|Verification|Review)[[:punct:]\\s](?:Needed|Required)))[^\\"]*\\"'
    • all of:
      • strings.replace_confusables(subject.subject) matches ': \\".*[[:punct:]\\s]+\\w+[[:punct:]\\s]*[a-zA-Z]*[0-9][a-zA-Z0-9]*\\"$'
      • strings.replace_confusables(subject.subject) matches '[[:punct:]]\\s*[a-z0-9]{5,}\\"$'
    • any of filter(body.links) where any holds:
      • ml.link_analysis(., mode='aggressive').final_dom.display_text contains "You can't access this item because it is in violation of our Terms of Service"
      • any of filter(...) where:
        • any of .json where:
          • any of . where:
            • any of . where any holds:
              • network.whois(strings.parse_url(.).domain).days_old < 30
              • strings.parse_url(.).domain.tld in $suspicious_tlds
              • all of:
                • strings.parse_url(.).domain.root_domain in $free_subdomain_hosts
                • strings.parse_url(.).domain.subdomain is set
                • strings.parse_url(.).domain.subdomain is not 'www'
              • strings.parse_url(.).domain.domain in $free_file_hosts
              • strings.parse_url(.).domain.root_domain in $free_file_hosts
              • strings.parse_url(.).domain.domain in $url_shorteners
              • strings.parse_url(.).domain.domain in $social_landing_hosts
              • strings.parse_url(.).domain.root_domain in $url_shorteners
              • strings.parse_url(.).domain.root_domain in $social_landing_hosts
      • any of filter(...) where any holds:
        • network.whois(.href_url.domain).days_old < 30
        • .href_url.domain.root_domain in $free_file_hosts
        • .href_url.domain.domain in $free_file_hosts
        • all of:
          • .href_url.domain.root_domain in $free_subdomain_hosts
          • .href_url.domain.subdomain is set
          • .href_url.domain.subdomain is not 'www'
        • .href_url.domain.root_domain in $url_shorteners
        • .href_url.domain.root_domain in $social_landing_hosts
        • .href_url.domain.domain in $url_shorteners
        • .href_url.domain.domain in $social_landing_hosts
        • all of:
          • .display_text matches '(?:view|click|show|access|download|continue|goto|Validate|Va[il]idar|login|verify|account)'
          • any of:
            • ml.link_analysis(.).credphish.disposition is 'phishing'
            • ml.link_analysis(.).credphish.contains_captcha
            • all of:
              • length(ml.link_analysis(., mode='aggressive').redirect_history) > 0
              • ml.link_analysis(.).effective_url.domain.root_domain in $tranco_10k

Inspects: body.current_thread.text, 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.details.designator, headers.auth_summary.spf.pass, headers.reply_to, headers.reply_to[].email.domain.domain, sender.display_name, sender.email.domain.domain, sender.email.local_part, subject.subject, type.inbound. Sensors: beta.profile.by_reply_to, ml.link_analysis, network.whois, regex.icontains, regex.iextract, strings.ends_with, strings.icontains, strings.parse_url, strings.replace_confusables. Reference lists: $free_file_hosts, $free_subdomain_hosts, $org_display_names, $org_domains, $social_landing_hosts, $suspicious_tlds, $tranco_10k, $url_shorteners.

Indicators matched (16)

FieldMatchValue
sender.email.domain.domainequalsgoogle.com
sender.email.local_partequalsdrive-shares-noreply
sender.email.local_partequalsdrive-shares-dm-noreply
strings.ends_withsuffixdoclist.bounces.google.com
regex.icontainsregex: \".*(?:Immediate|Urgent|Critical|Alert|Warning|Urgent|Important|Critical Alert|Security Notice)[!:\-]?[^\"]*\"
regex.icontainsregex: \".*(?:Online|Bank(?:ing)?|User|Account|Access|[[:punct:]\s]?(?:ID)|Transactions)\b.*\b(?:Security|Recover|Blocked|Suspen(?:ded|sion)|Restricted|Locked|Disabled|Frozen|Closed)[^\"]*\"
regex.icontainsregex: \".*(Suspicious|Unauthorized|Unrecognized|Fraudulent|Scam)\b.*\b(Activity|Transaction|Log[- ]?In|Access|Entry|Sign[- ]?In|Detected)[^\"]*\"
regex.icontainsregex: \".*(?:(?:Verify|Confirm|Update|Review|Complete)\b.*\b(Your (Identity|Account|Online[- ]?ID|Billing Information))|(?:(?:Action|Attention|Verification|Review)[[:punct:]\s](?:Needed|Required)))[^\"]*\"
regex.icontainsregex: \".*[[:punct:]\s]+\w+[[:punct:]\s]*[a-zA-Z]*[0-9][a-zA-Z0-9]*\"$
regex.icontainsregex[[:punct:]]\s*[a-z0-9]{5,}\"$
body.links[].href_url.domain.domainequalsdrive.google.com
strings.icontainssubstring/view
4 more
body.links[].display_textequalsOpen
strings.icontainssubstringYou can't access this item because it is in violation of our Terms of Service
ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].url.pathequals/viewerng/presspage
regex.icontainsregex(?:view|click|show|access|download|continue|goto|Validate|Va[il]idar|login|verify|account)

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(filter(body.links))
      or
        any(filter(...))
          any(filter(...).json)
            any(filter(...).json)
              any(filter(...).json)
                or
                  and
                    strings.parse_url func_call "strings.parse_url(filter(...)[].json[][][]).domain.root_domain in free_subdomain_hosts"
                    strings.parse_url func_call "strings.parse_url(filter(...)[].json[][][]).domain.subdomain != www"
                    strings.parse_url(filter(...)[].json[][][]).domain.subdomain is_not_null
                  network.whois func_call "network.whois(strings.parse_url(filter(...)[].json[][][]).domain).days_old < 30"
                  strings.parse_url func_call "strings.parse_url(filter(...)[].json[][][]).domain.domain in free_file_hosts"
                  strings.parse_url func_call "strings.parse_url(filter(...)[].json[][][]).domain.domain in social_landing_hosts"
                  strings.parse_url func_call "strings.parse_url(filter(...)[].json[][][]).domain.domain in url_shorteners"
                  strings.parse_url func_call "strings.parse_url(filter(...)[].json[][][]).domain.root_domain in free_file_hosts"
                  strings.parse_url func_call "strings.parse_url(filter(...)[].json[][][]).domain.root_domain in social_landing_hosts"
                  strings.parse_url func_call "strings.parse_url(filter(...)[].json[][][]).domain.root_domain in url_shorteners"
                  strings.parse_url func_call "strings.parse_url(filter(...)[].json[][][]).domain.tld in suspicious_tlds"
        any(filter(...))
          or
            and
              or
                and
                  ml.link_analysis func_call "ml.link_analysis(filter(...)[]).effective_url.domain.root_domain in tranco_10k"
                  ml.link_analysis(filter(...)[], mode='aggressive').redirect_history length_compare "0"
                ml.link_analysis func_call "ml.link_analysis(filter(...)[]).credphish.contains_captcha"
                ml.link_analysis func_call "ml.link_analysis(filter(...)[]).credphish.disposition == phishing"
              filter(...).display_text regex_match "(?:view|click|show|access|download|continue|goto|Validate|Va[il]idar|login|verify|account)"
            and
              filter(...).href_url.domain.subdomain is_not_null
              filter(...).href_url.domain.subdomain ne "www"
               macro "filter(...)[].href_url.domain.root_domain in free_subdomain_hosts"
            network.whois func_call "network.whois(filter(...)[].href_url.domain).days_old < 30"
             macro "filter(...)[].href_url.domain.domain in free_file_hosts"
             macro "filter(...)[].href_url.domain.domain in social_landing_hosts"
             macro "filter(...)[].href_url.domain.domain in url_shorteners"
             macro "filter(...)[].href_url.domain.root_domain in free_file_hosts"
             macro "filter(...)[].href_url.domain.root_domain in social_landing_hosts"
             macro "filter(...)[].href_url.domain.root_domain in url_shorteners"
        ml.link_analysis(filter(body.links)[], mode='aggressive').final_dom.display_text contains "You can't access this item because it is in violation of our Terms of Service"
    and
      strings.replace_confusables(subject.subject) regex_match ": \\\".*[[:punct:]\\s]+\\w+[[:punct:]\\s]*[a-zA-Z]*[0-9][a-zA-Z0-9]*\\\"$"
      strings.replace_confusables(subject.subject) regex_match "[[:punct:]]\\s*[a-z0-9]{5,}\\\"$"
    strings.replace_confusables(subject.subject) regex_match ": \\\".*(?:(?:Verify|Confirm|Update|Review|Complete)\\b.*\\b(Your (Identity|Account|Online[- ]?ID|Billing Information))|(?:(?:Action|Attention|Verification|Review)[[:punct:]\\s](?:Needed|Required)))[^\\\"]*\\\""
    strings.replace_confusables(subject.subject) regex_match ": \\\".*(?:Immediate|Urgent|Critical|Alert|Warning|Urgent|Important|Critical Alert|Security Notice)[!:\\-]?[^\\\"]*\\\""
    strings.replace_confusables(subject.subject) regex_match ": \\\".*(?:Online|Bank(?:ing)?|User|Account|Access|[[:punct:]\\s]?(?:ID)|Transactions)\\b.*\\b(?:Security|Recover|Blocked|Suspen(?:ded|sion)|Restricted|Locked|Disabled|Frozen|Closed)[^\\\"]*\\\""
    strings.replace_confusables(subject.subject) regex_match ": \\\".*(Suspicious|Unauthorized|Unrecognized|Fraudulent|Scam)\\b.*\\b(Activity|Transaction|Log[- ]?In|Access|Entry|Sign[- ]?In|Detected)[^\\\"]*\\\""
  or
    not
      beta.profile.by_reply_to func_call "beta.profile.by_reply_to().solicited"
    beta.profile.by_reply_to func_call "beta.profile.by_reply_to().prevalence == new"
  not
    any(headers.reply_to)
       macro "headers.reply_to[].email.domain.domain in org_domains"
  not
    any(regex.iextract(sender.display_name))
       macro "regex.iextract(sender.display_name)[].named_groups['sender_display_name'] in org_display_names"
  not
    body.current_thread.text contains "invited you to edit"
  or
    sender.email.local_part eq "drive-shares-dm-noreply"
    sender.email.local_part eq "drive-shares-noreply"
  headers.auth_summary.dmarc.pass eq "true"
  headers.auth_summary.spf.details.designator ends_with "doclist.bounces.google.com"
  headers.auth_summary.spf.pass eq "true"
  sender.email.domain.domain eq "google.com"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.reply_toarray_any(no value, null check)excludes:headers.reply_to
regex.iextract(sender.display_name)array_any(no value, null check)excludes:regex.iextract(sender.display_name)
body.current_thread.textcontainsinvited you to editexcludes:body.current_thread.text field:"body.current_thread.text" value:"invited you to edit"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
headers.auth_summary.dmarc.passeq
  • true transforms: boolean
field:"headers.auth_summary.dmarc.pass" kind:eq value:"true"
headers.auth_summary.spf.details.designatorends_with
  • doclist.bounces.google.com
field:"headers.auth_summary.spf.details.designator" kind:ends_with value:"doclist.bounces.google.com"
headers.auth_summary.spf.passeq
  • true transforms: boolean
field:"headers.auth_summary.spf.pass" kind:eq value:"true"
sender.email.domain.domaineq
  • google.com
field:"sender.email.domain.domain" kind:eq value:"google.com"
sender.email.local_parteq
  • drive-shares-dm-noreply
  • drive-shares-noreply
field:"sender.email.local_part" kind:eq
strings.replace_confusables(subject.subject)regex_match
  • : \".*(?:(?:Verify|Confirm|Update|Review|Complete)\b.*\b(Your (Identity|Account|Online[- ]?ID|Billing Information))|(?:(?:Action|Attention|Verification|Review)[[:punct:]\s](?:Needed|Required)))[^\"]*\"
  • : \".*(?:Immediate|Urgent|Critical|Alert|Warning|Urgent|Important|Critical Alert|Security Notice)[!:\-]?[^\"]*\"
  • : \".*(?:Online|Bank(?:ing)?|User|Account|Access|[[:punct:]\s]?(?:ID)|Transactions)\b.*\b(?:Security|Recover|Blocked|Suspen(?:ded|sion)|Restricted|Locked|Disabled|Frozen|Closed)[^\"]*\"
  • : \".*(Suspicious|Unauthorized|Unrecognized|Fraudulent|Scam)\b.*\b(Activity|Transaction|Log[- ]?In|Access|Entry|Sign[- ]?In|Detected)[^\"]*\"
  • : \".*[[:punct:]\s]+\w+[[:punct:]\s]*[a-zA-Z]*[0-9][a-zA-Z0-9]*\"$
  • [[:punct:]]\s*[a-z0-9]{5,}\"$
field:"strings.replace_confusables(subject.subject)" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link: Multistage landing - ClickUp abuse

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

Detects ClickUp documents that contain external links to suspicious domains including new domains, free file hosts, URL shorteners, or links that redirect to phishing pages or contain captchas.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesEvasion, Free file host, Free subdomain host, Open redirect

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • type

Rule body

type.inbound
and any(body.current_thread.links,
        .href_url.domain.domain == "doc.clickup.com"
        and (
          // landing page has been removed
          strings.istarts_with(ml.link_analysis(.).final_dom.display_text,
                               'This page is currently unavailable'
          )
          // inspection of links within the doc.clickup.com
          or any(filter(ml.link_analysis(.).final_dom.links,
                        .href_url.domain.root_domain != 'clickup.com'
                        and .href_url.domain.root_domain not in $org_domains
                 ),
                 (
                   // any of those links domains are new
                   network.whois(.href_url.domain).days_old < 30
                   // go to free file hosts
                   or .href_url.domain.root_domain in $free_file_hosts
                   or .href_url.domain.domain in $free_file_hosts

                   // go to free subdomains hosts
                   or (
                     .href_url.domain.root_domain in $free_subdomain_hosts
                     // where there is a subdomain
                     and .href_url.domain.subdomain is not null
                     and .href_url.domain.subdomain != "www"
                   )
                   // go to url shorteners
                   or .href_url.domain.root_domain in $url_shorteners
                   or .href_url.domain.root_domain in $social_landing_hosts
                   or .href_url.domain.domain in $url_shorteners
                   or .href_url.domain.domain in $social_landing_hosts
                   // or the page has been taken down
                   or (
                     // find any links that mention common "action" words
                     regex.icontains(.display_text,
                                     '(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)'
                     )
                     and (
                       // and when visiting those links, are phishing
                       ml.link_analysis(., mode="aggressive").credphish.disposition == "phishing"

                       // hit a captcha page
                       or ml.link_analysis(., mode="aggressive").credphish.contains_captcha

                       // or the page redirects to common website, observed when evasion happens
                       or (
                         length(ml.link_analysis(., mode="aggressive").redirect_history
                         ) > 0
                         and ml.link_analysis(., mode="aggressive").effective_url.domain.root_domain in $tranco_10k
                       )
                     )
                   )
                 )
          )
        )
)

Detection logic

Scope: inbound message.

Detects ClickUp documents that contain external links to suspicious domains including new domains, free file hosts, URL shorteners, or links that redirect to phishing pages or contain captchas.

  1. inbound message
  2. any of body.current_thread.links where all hold:
    • .href_url.domain.domain is 'doc.clickup.com'
    • any of:
      • ml.link_analysis(.).final_dom.display_text starts with 'This page is currently unavailable'
      • any of filter(...) where any holds:
        • network.whois(.href_url.domain).days_old < 30
        • .href_url.domain.root_domain in $free_file_hosts
        • .href_url.domain.domain in $free_file_hosts
        • all of:
          • .href_url.domain.root_domain in $free_subdomain_hosts
          • .href_url.domain.subdomain is set
          • .href_url.domain.subdomain is not 'www'
        • .href_url.domain.root_domain in $url_shorteners
        • .href_url.domain.root_domain in $social_landing_hosts
        • .href_url.domain.domain in $url_shorteners
        • .href_url.domain.domain in $social_landing_hosts
        • all of:
          • .display_text matches '(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)'
          • any of:
            • ml.link_analysis(.).credphish.disposition is 'phishing'
            • ml.link_analysis(.).credphish.contains_captcha
            • all of:
              • length(ml.link_analysis(., mode='aggressive').redirect_history) > 0
              • ml.link_analysis(.).effective_url.domain.root_domain in $tranco_10k

Inspects: body.current_thread.links, body.current_thread.links[].href_url.domain.domain, type.inbound. Sensors: ml.link_analysis, network.whois, regex.icontains, strings.istarts_with. Reference lists: $free_file_hosts, $free_subdomain_hosts, $org_domains, $social_landing_hosts, $tranco_10k, $url_shorteners.

Indicators matched (3)

FieldMatchValue
body.current_thread.links[].href_url.domain.domainequalsdoc.clickup.com
strings.istarts_withprefixThis page is currently unavailable
regex.icontainsregex(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    and
      or
        any(filter(...))
          or
            and
              or
                and
                  ml.link_analysis func_call "ml.link_analysis(filter(...)[]).effective_url.domain.root_domain in tranco_10k"
                  ml.link_analysis(filter(...)[], mode='aggressive').redirect_history length_compare "0"
                ml.link_analysis func_call "ml.link_analysis(filter(...)[]).credphish.contains_captcha"
                ml.link_analysis func_call "ml.link_analysis(filter(...)[]).credphish.disposition == phishing"
              filter(...).display_text regex_match "(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)"
            and
              filter(...).href_url.domain.subdomain is_not_null
              filter(...).href_url.domain.subdomain ne "www"
               macro "filter(...)[].href_url.domain.root_domain in free_subdomain_hosts"
            network.whois func_call "network.whois(filter(...)[].href_url.domain).days_old < 30"
             macro "filter(...)[].href_url.domain.domain in free_file_hosts"
             macro "filter(...)[].href_url.domain.domain in social_landing_hosts"
             macro "filter(...)[].href_url.domain.domain in url_shorteners"
             macro "filter(...)[].href_url.domain.root_domain in free_file_hosts"
             macro "filter(...)[].href_url.domain.root_domain in social_landing_hosts"
             macro "filter(...)[].href_url.domain.root_domain in url_shorteners"
        ml.link_analysis(body.current_thread.links[]).final_dom.display_text starts_with "This page is currently unavailable"
      body.current_thread.links.href_url.domain.domain eq "doc.clickup.com"
  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"

Link: Multistage landing - FreshDesk knowledge base abuse

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

Detects messages containing links to Freshdesk support solution pages that redirect to external domains with credential theft language, excluding legitimate Freshworks domains and organizational domains.

Threat classification

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

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

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • sender.email
  • type

Rule body

type.inbound
and length(body.links) < 10
and any(filter(body.links,
               .href_url.domain.root_domain == "freshdesk.com"
               and strings.icontains(.href_url.path, 'support/solutions')
        ),
        // link to unknown domain on the page
        length(filter(ml.link_analysis(.).final_dom.links,
                      .href_url.domain.root_domain not in ("freshworks.com")
                      and .href_url.domain.root_domain not in $org_domains
                      and .href_url.domain.root_domain != sender.email.domain.root_domain
               )
        ) < 3
        // cred theft language on the page
        and any(ml.nlu_classifier(ml.link_analysis(.).final_dom.display_text).intents,
                .name == "cred_theft" and .confidence != "low"
        )
)

Detection logic

Scope: inbound message.

Detects messages containing links to Freshdesk support solution pages that redirect to external domains with credential theft language, excluding legitimate Freshworks domains and organizational domains.

  1. inbound message
  2. length(body.links) < 10
  3. any of filter(body.links) where all hold:
    • length(filter(ml.link_analysis(.).final_dom.links, .href_url.domain.root_domain not in ('freshworks.com') and .href_url.domain.root_domain not in $org_domains and .href_url.domain.root_domain != sender.email.domain.root_domain)) < 3
    • any of ml.nlu_classifier(ml.link_analysis(.).final_dom.display_text).intents where all hold:
      • .name is 'cred_theft'
      • .confidence is not 'low'

Inspects: body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.path, sender.email.domain.root_domain, type.inbound. Sensors: ml.link_analysis, ml.nlu_classifier, strings.icontains. Reference lists: $org_domains.

Indicators matched (3)

FieldMatchValue
body.links[].href_url.domain.root_domainequalsfreshdesk.com
strings.icontainssubstringsupport/solutions
ml.nlu_classifier(ml.link_analysis(filter(body.links)[]).final_dom.display_text).intents[].nameequalscred_theft

Stages and Predicates

Stage 1: mql_rule

and
  any(filter(body.links))
    and
      any(ml.nlu_classifier(ml.link_analysis(filter(body.links)).final_dom.display_text).intents)
        and
          ml.nlu_classifier(ml.link_analysis(filter(body.links)[]).final_dom.display_text).intents[].confidence ne "low"
          ml.nlu_classifier(ml.link_analysis(filter(body.links)[]).final_dom.display_text).intents[].name eq "cred_theft"
      filter(ml.link_analysis(filter(body.links)[]).final_dom.links, filter(body.links)[].href_url.domain.root_domain not in ('freshworks.com') and filter(body.links)[].href_url.domain.root_domain not in $org_domains and filter(body.links)[].href_url.domain.root_domain != sender.email.domain.root_domain) length_compare "3"
  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"

Link: Multistage landing - JotForm abuse

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

Detects a disabled JotForm that contains suspicious elements like secured document messaging, cloned forms, or suspicious action words in form items. Also checks for human verification pages and embedded links to credential collection sites.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and length(filter(body.links, .href_url.domain.root_domain == "jotform.com")) > 0
and any(filter(body.links, .href_url.domain.root_domain == "jotform.com"),
        // the form as been disabled
        strings.icontains(ml.link_analysis(.).final_dom.inner_text,
                          'This form is disabled...'
        )
        // lure to open a document with phishing intent
        or (
          any(ml.link_analysis(.).final_dom.links,
              regex.icontains(.display_text, "VIEW DOCUMENT ONLINE")
              and ml.link_analysis(.href_url).credphish.disposition == "phishing"
          )
        )
        // it contains suspicious elements within the extracted "appInfo"
        or any(regex.iextract(ml.link_analysis(.).final_dom.raw,
                              'window\.__appInfo = (?P<appInfo>\{[^\n]+\})\;\n'
               ),
               // the title/description/name contains suspicious keywords
               any([
                     strings.parse_json(.named_groups["appInfo"])["title"],
                     strings.parse_json(.named_groups["appInfo"])["description"],
                     strings.parse_json(.named_groups["appInfo"])["name"]
                   ],
                   strings.icontains(., 'secured document')
                   or strings.icontains(., 'Adobe PDF')
               )
               or any(strings.parse_json(.named_groups["appInfo"])["items"],
                      // find any links that mention common "action" words
                      any([.["description"], .["title"]],
                          regex.icontains(.,
                                          '(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)'
                          )
                      )

                      // inspect the linked page within the "buttonValue" or .title contains a link
                      or (
                        any([.["buttonValue"], .["title"]],
                            strings.icontains(., 'http')
                            and (
                              ml.link_analysis(strings.parse_url(.)).credphish.disposition == "phishing"
                              or ml.link_analysis(strings.parse_url(.)).credphish.contains_captcha == true
                              or strings.istarts_with(ml.link_analysis(strings.parse_url(.
                                                                       )
                                                      ).final_dom.inner_text,
                                                      'Verify you are human'
                              )
                            )
                        )
                      )
               )
        )
)

Detection logic

Scope: inbound message.

Detects a disabled JotForm that contains suspicious elements like secured document messaging, cloned forms, or suspicious action words in form items. Also checks for human verification pages and embedded links to credential collection sites.

  1. inbound message
  2. length(filter(body.links, .href_url.domain.root_domain == 'jotform.com')) > 0
  3. any of filter(body.links) where any holds:
    • ml.link_analysis(.).final_dom.inner_text contains 'This form is disabled...'
    • any of ml.link_analysis(.).final_dom.links where all hold:
      • .display_text matches 'VIEW DOCUMENT ONLINE'
      • ml.link_analysis(.href_url).credphish.disposition is 'phishing'
    • any of regex.iextract(...) where any holds:
      • any of [strings.parse_json(.named_groups['appInfo'])['title'], strings.parse_json(.named_groups['appInfo'])['description'], strings.parse_json(.named_groups['appInfo'])['name']] where any holds:
        • . contains 'secured document'
        • . contains 'Adobe PDF'
      • any of strings.parse_json(.named_groups['appInfo'])['items'] where any holds:
        • any of [.['description'], .['title']] where:
          • . matches '(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)'
        • any of [.['buttonValue'], .['title']] where all hold:
          • . contains 'http'
          • any of:
            • ml.link_analysis(strings.parse_url(.)).credphish.disposition is 'phishing'
            • ml.link_analysis(strings.parse_url(.)).credphish.contains_captcha is True
            • ml.link_analysis(strings.parse_url(.)).final_dom.inner_text starts with 'Verify you are human'

Inspects: body.links, body.links[].href_url.domain.root_domain, type.inbound. Sensors: ml.link_analysis, regex.icontains, regex.iextract, strings.icontains, strings.istarts_with, strings.parse_json, strings.parse_url.

Indicators matched (9)

FieldMatchValue
body.links[].href_url.domain.root_domainequalsjotform.com
strings.icontainssubstringThis form is disabled...
regex.icontainsregexVIEW DOCUMENT ONLINE
regex.iextractregexwindow\.__appInfo = (?P<appInfo>\{[^\n]+\})\;\n
strings.icontainssubstringsecured document
strings.icontainssubstringAdobe PDF
regex.icontainsregex(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)
strings.icontainssubstringhttp
strings.istarts_withprefixVerify you are human

Stages and Predicates

Stage 1: mql_rule

and
  any(filter(body.links))
    or
      any(regex.iextract(...))
        or
          any(strings.parse_json(regex.iextract(...).named_groups['appInfo'])['items'])
            or
              any([strings.parse_json(regex.iextract(...).named_groups['appInfo'])['items']['buttonValue'], strings.parse_json(regex.iextract(...).named_groups['appInfo'])['items']['title']])
                and
                  or
                    ml.link_analysis func_call "ml.link_analysis(strings.parse_url([strings.parse_json(regex.iextract(...)[].named_groups['appInfo'])['items'][]['buttonValue'], strings.parse_json(regex.iextract(...)[].named_groups['appInfo'])['items'][]['title']][])).credphish.contains_captcha == true"
                    ml.link_analysis func_call "ml.link_analysis(strings.parse_url([strings.parse_json(regex.iextract(...)[].named_groups['appInfo'])['items'][]['buttonValue'], strings.parse_json(regex.iextract(...)[].named_groups['appInfo'])['items'][]['title']][])).credphish.disposition == phishing"
                    ml.link_analysis(strings.parse_url([strings.parse_json(regex.iextract(...)[].named_groups['appInfo'])['items'][]['buttonValue'], strings.parse_json(regex.iextract(...)[].named_groups['appInfo'])['items'][]['title']][])).final_dom.inner_text starts_with "Verify you are human"
                  [strings.parse_json(regex.iextract(...)[].named_groups['appInfo'])['items'][]['buttonValue'], strings.parse_json(regex.iextract(...)[].named_groups['appInfo'])['items'][]['title']][] contains "http"
              any([strings.parse_json(regex.iextract(...).named_groups['appInfo'])['items']['description'], strings.parse_json(regex.iextract(...).named_groups['appInfo'])['items']['title']])
                [strings.parse_json(regex.iextract(...).named_groups['appInfo'])['items']['description'], strings.parse_json(regex.iextract(...).named_groups['appInfo'])['items']['title']] regex_match "(?:view|click|show|access|download|goto|Validate|Va[il]idar|login|verify|account)"
          any([strings.parse_json(regex.iextract(...).named_groups['appInfo'])['title'], strings.parse_json(regex.iextract(...).named_groups['appInfo'])['description'], strings.parse_json(regex.iextract(...).named_groups['appInfo'])['name']])
            or
              [strings.parse_json(regex.iextract(...)[].named_groups['appInfo'])['title'], strings.parse_json(regex.iextract(...)[].named_groups['appInfo'])['description'], strings.parse_json(regex.iextract(...)[].named_groups['appInfo'])['name']][] contains "Adobe PDF"
              [strings.parse_json(regex.iextract(...)[].named_groups['appInfo'])['title'], strings.parse_json(regex.iextract(...)[].named_groups['appInfo'])['description'], strings.parse_json(regex.iextract(...)[].named_groups['appInfo'])['name']][] contains "secured document"
      any(ml.link_analysis(filter(body.links)).final_dom.links)
        and
          ml.link_analysis func_call "ml.link_analysis(ml.link_analysis(filter(body.links)[]).final_dom.links[].href_url).credphish.disposition == phishing"
          ml.link_analysis(filter(body.links)[]).final_dom.links[].display_text regex_match "VIEW DOCUMENT ONLINE"
      ml.link_analysis(filter(body.links)[]).final_dom.inner_text contains "This form is disabled..."
  filter(body.links, .href_url.domain.root_domain == 'jotform.com') length_compare "0"
  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"

Link: Multistage landing - Ludus presentation

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

Detects when a standalone Ludus document link contains embedded links that are suspicious, particularly those targeting Microsoft services through various evasion techniques. The rule analyzes both the presentation content and linked destinations for suspicious patterns and redirects.

Threat classification

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

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

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
// only one link to Ludus
and length(distinct(filter(body.links,
                           .href_url.domain.root_domain in ("ludus.one")
                    ),
                    .href_url.url
           )
) == 1
and any(body.links,
        .href_url.domain.root_domain in ("ludus.one")
        and (
          any(ml.link_analysis(.).final_dom.links,
              .href_url.domain.root_domain != "ludus.com"
              // once we have additional responses, add # of slides == 1 logic
              and (
                .href_url.domain.tld in $suspicious_tlds
                or .href_url.domain.domain in $free_subdomain_hosts
                or .href_url.domain.root_domain in $free_subdomain_hosts
                // observed pattern in credential theft URLs
                or strings.ilike(.href_url.path,
                                 "*o365*",
                                 "*office365*",
                                 "*microsoft*"
                )
                // observed pattern in credential theft URLs
                or strings.ilike(.href_url.query_params,
                                 "*o365*",
                                 "*office365*",
                                 "*microsoft*"
                )
                // observed pattern in credential theft URLs
                or any(beta.scan_base64(.href_url.query_params),
                       strings.ilike(., "*o365*", "*office365*", "*microsoft*")
                )
                or ml.link_analysis(.href_url, mode="aggressive").credphish.disposition == "phishing"
                or ml.link_analysis(.href_url, mode="aggressive").credphish.contains_captcha
                or strings.icontains(ml.link_analysis(.href_url,
                                                      mode="aggressive"
                                     ).final_dom.display_text,
                                     "I'm Human"
                )
                // bails out to a well-known domain, seen in evasion attempts
                or (
                  length(ml.link_analysis(.href_url, mode="aggressive").redirect_history
                  ) > 0
                  and ml.link_analysis(.href_url, mode="aggressive").effective_url.domain.root_domain in $tranco_10k
                )
              )
          )
          // credential theft language on the main Scribd page
          or any(ml.nlu_classifier(beta.ocr(ml.link_analysis(.,
                                                             mode="aggressive"
                                            ).screenshot
                                   ).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
)

Detection logic

Scope: inbound message.

Detects when a standalone Ludus document link contains embedded links that are suspicious, particularly those targeting Microsoft services through various evasion techniques. The rule analyzes both the presentation content and linked destinations for suspicious patterns and redirects.

  1. inbound message
  2. length(distinct(filter(body.links, .href_url.domain.root_domain in ('ludus.one')), .href_url.url)) is 1
  3. any of body.links where all hold:
    • .href_url.domain.root_domain in ('ludus.one')
    • any of:
      • any of ml.link_analysis(.).final_dom.links where all hold:
        • .href_url.domain.root_domain is not 'ludus.com'
        • any of:
          • .href_url.domain.tld in $suspicious_tlds
          • .href_url.domain.domain in $free_subdomain_hosts
          • .href_url.domain.root_domain in $free_subdomain_hosts
          • .href_url.path matches any of 3 patterns
            • *o365*
            • *office365*
            • *microsoft*
          • .href_url.query_params matches any of 3 patterns
            • *o365*
            • *office365*
            • *microsoft*
          • any of beta.scan_base64(.href_url.query_params) where:
            • . matches any of 3 patterns
              • *o365*
              • *office365*
              • *microsoft*
          • ml.link_analysis(.href_url).credphish.disposition is 'phishing'
          • ml.link_analysis(.href_url).credphish.contains_captcha
          • ml.link_analysis(.href_url, mode='aggressive').final_dom.display_text contains "I'm Human"
          • all of:
            • length(ml.link_analysis(.href_url, mode='aggressive').redirect_history) > 0
            • ml.link_analysis(.href_url).effective_url.domain.root_domain in $tranco_10k
      • any of ml.nlu_classifier(beta.ocr(ml.link_analysis(., mode='aggressive').screenshot).text).intents where all hold:
        • .name is 'cred_theft'
        • .confidence is not 'low'
  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.links, body.links[].href_url.domain.root_domain, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: beta.ocr, beta.scan_base64, ml.link_analysis, ml.nlu_classifier, strings.icontains, strings.ilike. Reference lists: $free_subdomain_hosts, $high_trust_sender_root_domains, $suspicious_tlds, $tranco_10k.

Indicators matched (6)

FieldMatchValue
body.links[].href_url.domain.root_domainmemberludus.one
strings.ilikesubstring*o365*
strings.ilikesubstring*office365*
strings.ilikesubstring*microsoft*
strings.icontainssubstringI'm Human
ml.nlu_classifier(beta.ocr(ml.link_analysis(body.links[], mode='aggressive').screenshot).text).intents[].nameequalscred_theft

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        any(ml.link_analysis(body.links).final_dom.links)
          and
            or
              any(beta.scan_base64(ml.link_analysis(body.links).final_dom.links.href_url.query_params))
                or
                  beta.scan_base64(ml.link_analysis(body.links[]).final_dom.links[].href_url.query_params)[] match "microsoft"
                  beta.scan_base64(ml.link_analysis(body.links[]).final_dom.links[].href_url.query_params)[] match "o365"
                  beta.scan_base64(ml.link_analysis(body.links[]).final_dom.links[].href_url.query_params)[] match "office365"
              and
                ml.link_analysis func_call "ml.link_analysis(ml.link_analysis(body.links[]).final_dom.links[].href_url).effective_url.domain.root_domain in tranco_10k"
                ml.link_analysis(ml.link_analysis(body.links[]).final_dom.links[].href_url, mode='aggressive').redirect_history length_compare "0"
              ml.link_analysis func_call "ml.link_analysis(ml.link_analysis(body.links[]).final_dom.links[].href_url).credphish.contains_captcha"
              ml.link_analysis func_call "ml.link_analysis(ml.link_analysis(body.links[]).final_dom.links[].href_url).credphish.disposition == phishing"
              ml.link_analysis(body.links[]).final_dom.links[].href_url.path match "microsoft"
              ml.link_analysis(body.links[]).final_dom.links[].href_url.path match "o365"
              ml.link_analysis(body.links[]).final_dom.links[].href_url.path match "office365"
              ml.link_analysis(body.links[]).final_dom.links[].href_url.query_params match "microsoft"
              ml.link_analysis(body.links[]).final_dom.links[].href_url.query_params match "o365"
              ml.link_analysis(body.links[]).final_dom.links[].href_url.query_params match "office365"
              ml.link_analysis(ml.link_analysis(body.links[]).final_dom.links[].href_url, mode='aggressive').final_dom.display_text contains "I'm Human"
               macro "ml.link_analysis(body.links[]).final_dom.links[].href_url.domain.domain in free_subdomain_hosts"
               macro "ml.link_analysis(body.links[]).final_dom.links[].href_url.domain.root_domain in free_subdomain_hosts"
               macro "ml.link_analysis(body.links[]).final_dom.links[].href_url.domain.tld in suspicious_tlds"
            ml.link_analysis(body.links[]).final_dom.links[].href_url.domain.root_domain ne "ludus.com"
        any(ml.nlu_classifier(beta.ocr(ml.link_analysis(body.links, mode='aggressive').screenshot).text).intents)
          and
            ml.nlu_classifier(beta.ocr(ml.link_analysis(body.links[], mode='aggressive').screenshot).text).intents[].confidence ne "low"
            ml.nlu_classifier(beta.ocr(ml.link_analysis(body.links[], mode='aggressive').screenshot).text).intents[].name eq "cred_theft"
      body.links.href_url.domain.root_domain eq "ludus.one"
  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"
  distinct(filter(body.links, .href_url.domain.root_domain in ('ludus.one')), .href_url.url) length_compare "1"
  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"

Link: Multistage landing - Microsoft Forms abuse

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

The detection rule matches on message groups which make use of Microsoft Forms as a landing page. The landing page contains links which are newly registered, use free file or subdomain hosts, URL shorteners or when visited are phishing pages, lead to a captcha or redirect to a top website.

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
  • type

Rule body

type.inbound
and any(filter(body.links, .href_url.domain.domain == "forms.office.com"),
        // avoid doing Link Analysis if the display-text has strong indications of phishing
        (
          // replace confusables - observed ITW
          regex.icontains(strings.replace_confusables(.display_text),
                          'review|proposal|document|efax|restore|[o0]pen|secure|messaging|reset|account|verify|login|notification|alert|urgent|immediate|access|support|\bupdate\b|download|attachment|service|payment|remittance|invoice'
          )
          and not regex.icontains(strings.replace_confusables(.display_text),
                                  'customer service'
          )
          // add confidence to these strings by using profile.by_sender()
          and (
            not profile.by_sender().solicited
            and profile.by_sender().prevalence in ('new', 'outlier')
          )
        )
        or 
        // look at the final_dom.raw
        // if the page has been taken down, match
        strings.icontains(ml.link_analysis(., mode="aggressive").final_dom.raw,
                          'This form was blocked due to privacy or safety concerns.'
        )
        // this error has been shown before with the text "Phishing form from content scan. Inner Message: This form has been flagged for potential phishing."
        or any(ml.link_analysis(., mode="aggressive").additional_responses,
               strings.icontains(.json["error"]["message"], "phishing")
        )
        // or MS thinks there are phishing keywords
        or any(ml.link_analysis(., mode="aggressive").additional_responses,
               any(.json["form"]["questions"],
                   .["subtitleHasPhishingKeywords"] == true
               )
               or any(.json["form"]["questions"],
                      .["titleHasPhishingKeywords"] == true
               )
               or any(.json["form"]["descriptiveQuestions"],
                      .["titleHasPhishingKeywords"] == true
               )
               or any(.json["form"]["descriptiveQuestions"],
                      .["titleHasPhishingKeywords"] == true
               )
        )
        // this logic checks for three abnormal cases
        // 1) no questions
        // 2) questions, but no inputs
        // 3) a bunch of new lines (used to push down the submit button of the form)
        // AND 
        // // there is one or two links that isn't "standard" on the form
        or (
          (
            // 1) doesn't contain any sections or questions
            any(ml.link_analysis(., mode="aggressive").additional_responses,
                length(.json["form"]["descriptiveQuestions"]) == 0
                and length(.json["form"]["questions"]) == 0
            )
            or 
            // 2) Contains a form section header, but no actual inputs
            // possible question types are .Choice, .TextField, .Rating, .DateTime, .Ranking, .MatrixChoiceGroup, .MatrixChoice, and .NPS
            any(ml.link_analysis(., mode="aggressive").additional_responses,
                length(.json["form"]["descriptiveQuestions"]) > 0
                and length(.json["form"]["questions"]) == 0
            )
            or 
            // 3) a bunch of new lines (used to push down the submit button of the form)
            (
              strings.icount(ml.link_analysis(., mode="aggressive").final_dom.raw,
                             '<br><br>'
              ) > 20
              or strings.icount(ml.link_analysis(., mode="aggressive").final_dom.raw,
                                '\n\n'
              ) > 20
              or strings.icount(ml.link_analysis(., mode="aggressive").final_dom.raw,
                                '<span><span>'
              ) > 20
              or any(ml.link_analysis(., mode="aggressive").additional_responses,
                     any(.json["form"]["questions"],
                         strings.icount(.["formsProRTQuestionTitle"],
                                        '<br><br>'
                         ) > 20
                         or strings.icount(.["formsProRTQuestionTitle"], '\n\n') > 20
                         or strings.icount(.["formsProRTQuestionTitle"],
                                           '<span><span>'
                         ) > 20
                     )
              )
            )
          )
          // AND 
          and 
          // there is one or two links to another page
          0 < length(filter(ml.link_analysis(.).final_dom.links,
                            not (
                              (
                                (
                                  .display_text =~ "Privacy and cookies"
                                  or .display_text =~ "terms of use"
                                  or .display_text =~ "report abuse"
                                )
                                and .href_url.domain.root_domain =~ 'microsoft.com'
                              )
                              or .href_url.domain.root_domain =~ sender.email.domain.root_domain
                              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*"
                                  )
                                )
                              )
                            )
                     )
          ) <= 2
          and (
            not strings.contains(ml.link_analysis(., mode="aggressive").final_dom.raw,
                                 'role="progressbar" aria-label="Page 1 of '
            )
            or any(ml.link_analysis(., mode="aggressive").additional_responses,
                   .json["form"]["progressBarEnabled"] == false
            )
          )
        )
)

Detection logic

Scope: inbound message.

The detection rule matches on message groups which make use of Microsoft Forms as a landing page. The landing page contains links which are newly registered, use free file or subdomain hosts, URL shorteners or when visited are phishing pages, lead to a captcha or redirect to a top website.

  1. inbound message
  2. any of filter(body.links) where any holds:
    • all of:
      • strings.replace_confusables(.display_text) matches 'review|proposal|document|efax|restore|[o0]pen|secure|messaging|reset|account|verify|login|notification|alert|urgent|immediate|access|support|\\bupdate\\b|download|attachment|service|payment|remittance|invoice'
      • not:
        • strings.replace_confusables(.display_text) matches 'customer service'
      • all of:
        • not:
          • profile.by_sender().solicited
        • profile.by_sender().prevalence in ('new', 'outlier')
    • ml.link_analysis(., mode='aggressive').final_dom.raw contains 'This form was blocked due to privacy or safety concerns.'
    • any of ml.link_analysis(., mode='aggressive').additional_responses where:
      • .json['error']['message'] contains 'phishing'
    • any of ml.link_analysis(., mode='aggressive').additional_responses where any holds:
      • any of .json['form']['questions'] where:
        • .['subtitleHasPhishingKeywords'] is True
      • any of .json['form']['questions'] where:
        • .['titleHasPhishingKeywords'] is True
      • any of .json['form']['descriptiveQuestions'] where:
        • .['titleHasPhishingKeywords'] is True
      • any of .json['form']['descriptiveQuestions'] where:
        • .['titleHasPhishingKeywords'] is True
    • all of:
      • any of:
        • any of ml.link_analysis(., mode='aggressive').additional_responses where all hold:
          • length(.json['form']['descriptiveQuestions']) is 0
          • length(.json['form']['questions']) is 0
        • any of ml.link_analysis(., mode='aggressive').additional_responses where all hold:
          • length(.json['form']['descriptiveQuestions']) > 0
          • length(.json['form']['questions']) is 0
        • any of:
          • strings.icount(ml.link_analysis(., mode='aggressive').final_dom.raw, '<br><br>') > 20
          • strings.icount(ml.link_analysis(., mode='aggressive').final_dom.raw, '\\n\\n') > 20
          • strings.icount(ml.link_analysis(., mode='aggressive').final_dom.raw, '<span><span>') > 20
          • any of ml.link_analysis(., mode='aggressive').additional_responses where:
            • any of .json['form']['questions'] where any holds:
              • strings.icount(.['formsProRTQuestionTitle'], '<br><br>') > 20
              • strings.icount(.['formsProRTQuestionTitle'], '\\n\\n') > 20
              • strings.icount(.['formsProRTQuestionTitle'], '<span><span>') > 20
      • all of:
        • length(filter(ml.link_analysis(.).final_dom.links, not .display_text =~ 'Privacy and cookies' or .display_text =~ 'terms of use' or .display_text =~ 'report abuse' and .href_url.domain.root_domain =~ 'microsoft.com' or .href_url.domain.root_domain =~ sender.email.domain.root_domain or .href_url.domain.tld == 'ms' 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*'))) > 0
        • length(filter(ml.link_analysis(.).final_dom.links, not .display_text =~ 'Privacy and cookies' or .display_text =~ 'terms of use' or .display_text =~ 'report abuse' and .href_url.domain.root_domain =~ 'microsoft.com' or .href_url.domain.root_domain =~ sender.email.domain.root_domain or .href_url.domain.tld == 'ms' 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*'))) ≤ 2
      • any of:
        • not:
          • ml.link_analysis(., mode='aggressive').final_dom.raw contains 'role="progressbar" aria-label="Page 1 of '
        • any of ml.link_analysis(., mode='aggressive').additional_responses where:
          • .json['form']['progressBarEnabled'] is False

Inspects: body.links, body.links[].href_url.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: ml.link_analysis, network.whois, profile.by_sender, regex.icontains, strings.contains, strings.icontains, strings.icount, strings.ilike, strings.replace_confusables.

Indicators matched (4)

FieldMatchValue
body.links[].href_url.domain.domainequalsforms.office.com
regex.icontainsregexreview|proposal|document|efax|restore|[o0]pen|secure|messaging|reset|account|verify|login|notification|alert|urgent|immediate|access|support|\bupdate\b|download|attachment|service|payment|remittance|invoice
strings.icontainssubstringThis form was blocked due to privacy or safety concerns.
strings.icontainssubstringphishing

Stages and Predicates

Stage 1: mql_rule

and
  any(filter(body.links))
    or
      and
        or
          any(ml.link_analysis(filter(body.links), mode='aggressive').additional_responses)
            any(ml.link_analysis(filter(body.links), mode='aggressive').additional_responses.json['form']['questions'])
              or
                strings.icount func_call "strings.icount(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].json['form']['questions'][]['formsProRTQuestionTitle'], \"<br><br>\") > 20"
                strings.icount func_call "strings.icount(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].json['form']['questions'][]['formsProRTQuestionTitle'], \"<span><span>\") > 20"
                strings.icount func_call "strings.icount(ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].json['form']['questions'][]['formsProRTQuestionTitle'], \"\\n\\n\") > 20"
          any(ml.link_analysis(filter(body.links), mode='aggressive').additional_responses)
            and
              ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].json['form']['descriptiveQuestions'] length_compare "0"
              ml.link_analysis(filter(body.links)[], mode='aggressive').additional_responses[].json['form']['questions'] length_compare "0"
          strings.icount func_call "strings.icount(ml.link_analysis(filter(body.links)[], mode='aggressive').final_dom.raw, \"<br><br>\") > 20"
          strings.icount func_call "strings.icount(ml.link_analysis(filter(body.links)[], mode='aggressive').final_dom.raw, \"<span><span>\") > 20"
          strings.icount func_call "strings.icount(ml.link_analysis(filter(body.links)[], mode='aggressive').final_dom.raw, \"\\n\\n\") > 20"
        or
          any(ml.link_analysis(filter(body.links), mode='aggressive').additional_responses)
            ml.link_analysis(filter(body.links), mode='aggressive').additional_responses.json['form']['progressBarEnabled'] eq "false"
          not
            ml.link_analysis(filter(body.links)[], mode='aggressive').final_dom.raw contains "role=\"progressbar\" aria-label=\"Page 1 of "
        filter(ml.link_analysis(filter(body.links)[]).final_dom.links, not filter(body.links)[].display_text =~ 'Privacy and cookies' or filter(body.links)[].display_text =~ 'terms of use' or filter(body.links)[].display_text =~ 'report abuse' and filter(body.links)[].href_url.domain.root_domain =~ 'microsoft.com' or filter(body.links)[].href_url.domain.root_domain =~ sender.email.domain.root_domain or filter(body.links)[].href_url.domain.tld == 'ms' and network.whois(filter(body.links)[].href_url.domain).registrant_company == 'Microsoft Corporation' or strings.ilike(network.whois(filter(body.links)[].href_url.domain).registrar_name, '*MarkMonitor*', '*CSC Corporate*', '*com laude*')) length_compare "0"
        filter(ml.link_analysis(filter(body.links)[]).final_dom.links, not filter(body.links)[].display_text =~ 'Privacy and cookies' or filter(body.links)[].display_text =~ 'terms of use' or filter(body.links)[].display_text =~ 'report abuse' and filter(body.links)[].href_url.domain.root_domain =~ 'microsoft.com' or filter(body.links)[].href_url.domain.root_domain =~ sender.email.domain.root_domain or filter(body.links)[].href_url.domain.tld == 'ms' and network.whois(filter(body.links)[].href_url.domain).registrant_company == 'Microsoft Corporation' or strings.ilike(network.whois(filter(body.links)[].href_url.domain).registrar_name, '*MarkMonitor*', '*CSC Corporate*', '*com laude*')) length_compare "2"
      any(ml.link_analysis(filter(body.links), mode='aggressive').additional_responses)
        or
          any(ml.link_analysis(filter(body.links), mode='aggressive').additional_responses.json['form']['descriptiveQuestions'])
            ml.link_analysis(filter(body.links), mode='aggressive').additional_responses.json['form']['descriptiveQuestions']['titleHasPhishingKeywords'] eq "true"
          any(ml.link_analysis(filter(body.links), mode='aggressive').additional_responses.json['form']['questions'])
            ml.link_analysis(filter(body.links), mode='aggressive').additional_responses.json['form']['questions']['subtitleHasPhishingKeywords'] eq "true"
          any(ml.link_analysis(filter(body.links), mode='aggressive').additional_responses.json['form']['questions'])
            ml.link_analysis(filter(body.links), mode='aggressive').additional_responses.json['form']['questions']['titleHasPhishingKeywords'] eq "true"
      and
        not
          profile.by_sender func_call "profile.by_sender().solicited"
        not
          strings.replace_confusables(filter(body.links)[].display_text) regex_match "customer service"
        profile.by_sender func_call "profile.by_sender().prevalence in (new, outlier)"
        strings.replace_confusables(filter(body.links)[].display_text) regex_match "review|proposal|document|efax|restore|[o0]pen|secure|messaging|reset|account|verify|login|notification|alert|urgent|immediate|access|support|\\bupdate\\b|download|attachment|service|payment|remittance|invoice"
      any(ml.link_analysis(filter(body.links), mode='aggressive').additional_responses)
        ml.link_analysis(filter(body.links), mode='aggressive').additional_responses.json['error']['message'] contains "phishing"
      ml.link_analysis(filter(body.links)[], mode='aggressive').final_dom.raw contains "This form was blocked due to privacy or safety concerns."
  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"

Link: Multistage landing - Published Google Doc

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

A Google Docs document contains suspicious text and links that redirect to either newly registered domains, free subdomain hosts, URL shorteners, or domains with suspicious TLDs.

Threat classification

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

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

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
and not sender.email.domain.domain == "google.com"
and length(distinct(filter(body.links,
                           .href_url.domain.domain == "docs.google.com"
                    ),
                    .href_url.url
           )
) < 3
and any(filter(body.links,
               .href_url.domain.domain == "docs.google.com"
               and (
                 any(ml.nlu_classifier(.display_text).entities,
                     .name == "request"
                 )
                 or any(ml.nlu_classifier(.display_text).intents,
                        .name == "cred_theft"
                 )
               )
        ),
        strings.istarts_with(ml.link_analysis(., mode="aggressive").final_dom.display_text,
                             "Published using Google Docs"
        )
        // filter down to links in the document where the display text is suspicious
        and any(filter(ml.link_analysis(., mode="aggressive").final_dom.links,
                       any(ml.nlu_classifier(.display_text).entities,
                           .name == "request"
                       )
                       or any(ml.nlu_classifier(.display_text).intents,
                              .name == "cred_theft"
                       )
                ),
                (
                  // any of those links domains are new
                  network.whois(.href_url.domain).days_old < 30

                  // go to free subdomains hosts
                  or (
                    .href_url.domain.root_domain in $free_subdomain_hosts
                    // where there is a subdomain
                    and .href_url.domain.subdomain is not null
                    and .href_url.domain.subdomain != "www"
                  )
                  // go to url shortners
                  or .href_url.domain.root_domain in $url_shorteners
                  or .href_url.domain.root_domain in $social_landing_hosts
                  or .href_url.domain.domain in $url_shorteners
                  or .href_url.domain.domain in $social_landing_hosts

                  // go to suspicious TLDs
                  or .href_url.domain.tld in $suspicious_tlds

                  // check for a second stage website that contains a suspicious link
                  // in other words, this LA call is inspecting links in sites on the Google Doc page
                  // we have seen Google Docs -> Google Slides (which this call is inspecting) -> malicious site
                  or any(ml.link_analysis(.href_url).final_dom.links,
                         .href_url.domain.root_domain in $free_file_hosts
                         or .href_url.domain.domain in $free_file_hosts
                         or (
                           .href_url.domain.root_domain in $free_subdomain_hosts
                           // where there is a subdomain
                           and .href_url.domain.subdomain is not null
                           and .href_url.domain.subdomain != "www"
                         )
                         or .href_url.domain.root_domain in $url_shorteners
                         or .href_url.domain.root_domain in $social_landing_hosts
                         or .href_url.domain.domain in $url_shorteners
                         or .href_url.domain.domain in $social_landing_hosts

                         // go to suspicious TLDs
                         or .href_url.domain.tld in $suspicious_tlds
                  )
                )
        )
)
and not (
  length(headers.reply_to) == 1
  and all(headers.reply_to, .email.domain.domain in $org_domains)
)

Detection logic

Scope: inbound message.

A Google Docs document contains suspicious text and links that redirect to either newly registered domains, free subdomain hosts, URL shorteners, or domains with suspicious TLDs.

  1. inbound message
  2. not:
    • sender.email.domain.domain is 'google.com'
  3. length(distinct(filter(body.links, .href_url.domain.domain == 'docs.google.com'), .href_url.url)) < 3
  4. any of filter(body.links) where all hold:
    • ml.link_analysis(., mode='aggressive').final_dom.display_text starts with 'Published using Google Docs'
    • any of filter(...) where any holds:
      • network.whois(.href_url.domain).days_old < 30
      • all of:
        • .href_url.domain.root_domain in $free_subdomain_hosts
        • .href_url.domain.subdomain is set
        • .href_url.domain.subdomain is not 'www'
      • .href_url.domain.root_domain in $url_shorteners
      • .href_url.domain.root_domain in $social_landing_hosts
      • .href_url.domain.domain in $url_shorteners
      • .href_url.domain.domain in $social_landing_hosts
      • .href_url.domain.tld in $suspicious_tlds
      • any of ml.link_analysis(.href_url).final_dom.links where any holds:
        • .href_url.domain.root_domain in $free_file_hosts
        • .href_url.domain.domain in $free_file_hosts
        • all of:
          • .href_url.domain.root_domain in $free_subdomain_hosts
          • .href_url.domain.subdomain is set
          • .href_url.domain.subdomain is not 'www'
        • .href_url.domain.root_domain in $url_shorteners
        • .href_url.domain.root_domain in $social_landing_hosts
        • .href_url.domain.domain in $url_shorteners
        • .href_url.domain.domain in $social_landing_hosts
        • .href_url.domain.tld in $suspicious_tlds
  5. not:
    • all of:
      • length(headers.reply_to) is 1
      • all of headers.reply_to where:
        • .email.domain.domain in $org_domains

Inspects: body.links, body.links[].display_text, body.links[].href_url.domain.domain, headers.reply_to, headers.reply_to[].email.domain.domain, sender.email.domain.domain, type.inbound. Sensors: ml.link_analysis, ml.nlu_classifier, network.whois, strings.istarts_with. Reference lists: $free_file_hosts, $free_subdomain_hosts, $org_domains, $social_landing_hosts, $suspicious_tlds, $url_shorteners.

Indicators matched (6)

FieldMatchValue
body.links[].href_url.domain.domainequalsdocs.google.com
ml.nlu_classifier(body.links[].display_text).entities[].nameequalsrequest
ml.nlu_classifier(body.links[].display_text).intents[].nameequalscred_theft
strings.istarts_withprefixPublished using Google Docs
ml.nlu_classifier(ml.link_analysis(filter(body.links)[], mode='aggressive').final_dom.links[].display_text).entities[].nameequalsrequest
ml.nlu_classifier(ml.link_analysis(filter(body.links)[], mode='aggressive').final_dom.links[].display_text).intents[].nameequalscred_theft

Stages and Predicates

Stage 1: mql_rule

and
  any(filter(body.links))
    and
      any(filter(...))
        or
          any(ml.link_analysis(filter(...).href_url).final_dom.links)
            or
              and
                ml.link_analysis(filter(...)[].href_url).final_dom.links[].href_url.domain.subdomain is_not_null
                ml.link_analysis(filter(...)[].href_url).final_dom.links[].href_url.domain.subdomain ne "www"
                 macro "ml.link_analysis(filter(...)[].href_url).final_dom.links[].href_url.domain.root_domain in free_subdomain_hosts"
               macro "ml.link_analysis(filter(...)[].href_url).final_dom.links[].href_url.domain.domain in free_file_hosts"
               macro "ml.link_analysis(filter(...)[].href_url).final_dom.links[].href_url.domain.domain in social_landing_hosts"
               macro "ml.link_analysis(filter(...)[].href_url).final_dom.links[].href_url.domain.domain in url_shorteners"
               macro "ml.link_analysis(filter(...)[].href_url).final_dom.links[].href_url.domain.root_domain in free_file_hosts"
               macro "ml.link_analysis(filter(...)[].href_url).final_dom.links[].href_url.domain.root_domain in social_landing_hosts"
               macro "ml.link_analysis(filter(...)[].href_url).final_dom.links[].href_url.domain.root_domain in url_shorteners"
               macro "ml.link_analysis(filter(...)[].href_url).final_dom.links[].href_url.domain.tld in suspicious_tlds"
          and
            filter(...).href_url.domain.subdomain is_not_null
            filter(...).href_url.domain.subdomain ne "www"
             macro "filter(...)[].href_url.domain.root_domain in free_subdomain_hosts"
          network.whois func_call "network.whois(filter(...)[].href_url.domain).days_old < 30"
           macro "filter(...)[].href_url.domain.domain in social_landing_hosts"
           macro "filter(...)[].href_url.domain.domain in url_shorteners"
           macro "filter(...)[].href_url.domain.root_domain in social_landing_hosts"
           macro "filter(...)[].href_url.domain.root_domain in url_shorteners"
           macro "filter(...)[].href_url.domain.tld in suspicious_tlds"
      ml.link_analysis(filter(body.links)[], mode='aggressive').final_dom.display_text starts_with "Published using Google Docs"
  not
    and
      headers.reply_to length_compare "1"
       macro "all(headers.reply_to)"
  not
    sender.email.domain.domain eq "google.com"
  distinct(filter(body.links, .href_url.domain.domain == 'docs.google.com'), .href_url.url) length_compare "3"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.reply_tolength_compare1excludes:headers.reply_to field:"headers.reply_to" value:"1"
sender.email.domain.domaineqgoogle.comexcludes:sender.email.domain.domain field:"sender.email.domain.domain" value:"google.com"

Indicators

These rows show field, operator, and value matches.

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

Link: Multistage landing - Scribd document

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

Detects when a Scribd document contains embedded links that are suspicious, particularly those targeting Microsoft services through various evasion techniques. The rule analyzes both the document content and linked destinations for suspicious patterns and redirects.

Threat classification

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

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

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
// only one link to Scribd
and length(distinct(filter(body.links,
                           .href_url.domain.root_domain in ("scribd.com")
                           and strings.istarts_with(.href_url.path, "/document")
                    ),
                    .href_url.url
           )
) == 1
and any(body.links,
        .href_url.domain.root_domain == "scribd.com"
        and strings.istarts_with(.href_url.path, "/document")
        and (
          // target the embedded links via XPath
          any(html.xpath(ml.link_analysis(.).final_dom,
                         '//a[@class="ll"]/@href'
              ).nodes,
              strings.parse_url(.raw).domain.tld in $suspicious_tlds
              or strings.parse_url(.raw).domain.domain in $free_subdomain_hosts
              or strings.parse_url(.raw).domain.root_domain in $free_subdomain_hosts
              // observed pattern in credential theft URLs
              or strings.ilike(strings.parse_url(.raw).path,
                               "*o365*",
                               "*office365*",
                               "*microsoft*"
              )
              // observed pattern in credential theft URLs
              or strings.ilike(strings.parse_url(.raw).query_params,
                               "*o365*",
                               "*office365*",
                               "*microsoft*"
              )
              // observed pattern in credential theft URLs
              or any(beta.scan_base64(strings.parse_url(.raw).query_params),
                     strings.ilike(., "*o365*", "*office365*", "*microsoft*")
              )
              or ml.link_analysis(strings.parse_url(.raw), mode="aggressive").credphish.disposition == "phishing"
              or ml.link_analysis(strings.parse_url(.raw), mode="aggressive").credphish.contains_captcha
              or strings.icontains(ml.link_analysis(strings.parse_url(.raw),
                                                    mode="aggressive"
                                   ).final_dom.display_text,
                                   "I'm Human"
              )
              // bails out to a well-known domain, seen in evasion attempts
              or (
                length(ml.link_analysis(strings.parse_url(.raw),
                                        mode="aggressive"
                       ).redirect_history
                ) > 0
                and ml.link_analysis(strings.parse_url(.raw), mode="aggressive").effective_url.domain.root_domain in $tranco_10k
              )
          )
          // credential theft language on the main Scribd page
          or any(ml.nlu_classifier(beta.ocr(ml.link_analysis(.,
                                                             mode="aggressive"
                                            ).screenshot
                                   ).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
)

Detection logic

Scope: inbound message.

Detects when a Scribd document contains embedded links that are suspicious, particularly those targeting Microsoft services through various evasion techniques. The rule analyzes both the document content and linked destinations for suspicious patterns and redirects.

  1. inbound message
  2. length(distinct(filter(body.links, .href_url.domain.root_domain in ('scribd.com') and strings.istarts_with(.href_url.path, '/document')), .href_url.url)) is 1
  3. any of body.links where all hold:
    • .href_url.domain.root_domain is 'scribd.com'
    • .href_url.path starts with '/document'
    • any of:
      • any of html.xpath(ml.link_analysis(.).final_dom, '//a[@class="ll"]/@href').nodes where any holds:
        • strings.parse_url(.raw).domain.tld in $suspicious_tlds
        • strings.parse_url(.raw).domain.domain in $free_subdomain_hosts
        • strings.parse_url(.raw).domain.root_domain in $free_subdomain_hosts
        • strings.parse_url(.raw).path matches any of 3 patterns
          • *o365*
          • *office365*
          • *microsoft*
        • strings.parse_url(.raw).query_params matches any of 3 patterns
          • *o365*
          • *office365*
          • *microsoft*
        • any of beta.scan_base64(...) where:
          • . matches any of 3 patterns
            • *o365*
            • *office365*
            • *microsoft*
        • ml.link_analysis(strings.parse_url(.raw)).credphish.disposition is 'phishing'
        • ml.link_analysis(strings.parse_url(.raw)).credphish.contains_captcha
        • ml.link_analysis(strings.parse_url(.raw), mode='aggressive').final_dom.display_text contains "I'm Human"
        • all of:
          • length(ml.link_analysis(strings.parse_url(.raw), mode='aggressive').redirect_history) > 0
          • ml.link_analysis(strings.parse_url(.raw)).effective_url.domain.root_domain in $tranco_10k
      • any of ml.nlu_classifier(beta.ocr(ml.link_analysis(., mode='aggressive').screenshot).text).intents where all hold:
        • .name is 'cred_theft'
        • .confidence is not 'low'
  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.links, body.links[].href_url.domain.root_domain, body.links[].href_url.path, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: beta.ocr, beta.scan_base64, html.xpath, ml.link_analysis, ml.nlu_classifier, strings.icontains, strings.ilike, strings.istarts_with, strings.parse_url. Reference lists: $free_subdomain_hosts, $high_trust_sender_root_domains, $suspicious_tlds, $tranco_10k.

Indicators matched (8)

FieldMatchValue
body.links[].href_url.domain.root_domainmemberscribd.com
strings.istarts_withprefix/document
body.links[].href_url.domain.root_domainequalsscribd.com
strings.ilikesubstring*o365*
strings.ilikesubstring*office365*
strings.ilikesubstring*microsoft*
strings.icontainssubstringI'm Human
ml.nlu_classifier(beta.ocr(ml.link_analysis(body.links[], mode='aggressive').screenshot).text).intents[].nameequalscred_theft

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        any(html.xpath(ml.link_analysis(body.links).final_dom, '//a[@class="ll"]/@href').nodes)
          or
            any(beta.scan_base64(...))
              or
                beta.scan_base64(...) match "microsoft"
                beta.scan_base64(...) match "o365"
                beta.scan_base64(...) match "office365"
            and
              ml.link_analysis func_call "ml.link_analysis(strings.parse_url(html.xpath(ml.link_analysis(body.links[]).final_dom, '//a[@class=\"ll\"]/@href').nodes[].raw)).effective_url.domain.root_domain in tranco_10k"
              ml.link_analysis(strings.parse_url(html.xpath(ml.link_analysis(body.links[]).final_dom, '//a[@class="ll"]/@href').nodes[].raw), mode='aggressive').redirect_history length_compare "0"
            ml.link_analysis func_call "ml.link_analysis(strings.parse_url(html.xpath(ml.link_analysis(body.links[]).final_dom, '//a[@class=\"ll\"]/@href').nodes[].raw)).credphish.contains_captcha"
            ml.link_analysis func_call "ml.link_analysis(strings.parse_url(html.xpath(ml.link_analysis(body.links[]).final_dom, '//a[@class=\"ll\"]/@href').nodes[].raw)).credphish.disposition == phishing"
            ml.link_analysis(strings.parse_url(html.xpath(ml.link_analysis(body.links[]).final_dom, '//a[@class="ll"]/@href').nodes[].raw), mode='aggressive').final_dom.display_text contains "I'm Human"
            strings.parse_url func_call "strings.parse_url(html.xpath(ml.link_analysis(body.links[]).final_dom, '//a[@class=\"ll\"]/@href').nodes[].raw).domain.domain in free_subdomain_hosts"
            strings.parse_url func_call "strings.parse_url(html.xpath(ml.link_analysis(body.links[]).final_dom, '//a[@class=\"ll\"]/@href').nodes[].raw).domain.root_domain in free_subdomain_hosts"
            strings.parse_url func_call "strings.parse_url(html.xpath(ml.link_analysis(body.links[]).final_dom, '//a[@class=\"ll\"]/@href').nodes[].raw).domain.tld in suspicious_tlds"
            strings.parse_url(html.xpath(ml.link_analysis(body.links[]).final_dom, '//a[@class="ll"]/@href').nodes[].raw).path match "microsoft"
            strings.parse_url(html.xpath(ml.link_analysis(body.links[]).final_dom, '//a[@class="ll"]/@href').nodes[].raw).path match "o365"
            strings.parse_url(html.xpath(ml.link_analysis(body.links[]).final_dom, '//a[@class="ll"]/@href').nodes[].raw).path match "office365"
            strings.parse_url(html.xpath(ml.link_analysis(body.links[]).final_dom, '//a[@class="ll"]/@href').nodes[].raw).query_params match "microsoft"
            strings.parse_url(html.xpath(ml.link_analysis(body.links[]).final_dom, '//a[@class="ll"]/@href').nodes[].raw).query_params match "o365"
            strings.parse_url(html.xpath(ml.link_analysis(body.links[]).final_dom, '//a[@class="ll"]/@href').nodes[].raw).query_params match "office365"
        any(ml.nlu_classifier(beta.ocr(ml.link_analysis(body.links, mode='aggressive').screenshot).text).intents)
          and
            ml.nlu_classifier(beta.ocr(ml.link_analysis(body.links[], mode='aggressive').screenshot).text).intents[].confidence ne "low"
            ml.nlu_classifier(beta.ocr(ml.link_analysis(body.links[], mode='aggressive').screenshot).text).intents[].name eq "cred_theft"
      body.links.href_url.domain.root_domain eq "scribd.com"
      body.links.href_url.path starts_with "/document"
  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"
  distinct(filter(body.links, .href_url.domain.root_domain in ('scribd.com') and strings.istarts_with(.href_url.path, '/document')), .href_url.url) length_compare "1"
  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"

Link: Multistage landing - Trello board abuse

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

Detects suspicious Trello board links containing malicious indicators such as credential theft content, blocked users, malicious attachments, or boards with minimal content from unsolicited senders.

Threat classification

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

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

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(filter(body.links,
               .href_url.domain.root_domain == "trello.com"
               and strings.istarts_with(.href_url.path, "/b/")
        ),
        // avoid doing LinkAnalysis if the display-text has strong indications of phishing
        (
          // replace confusables - observed ITW
          regex.icontains(strings.replace_confusables(.display_text),
                          'review|proposal|document|efax|restore|[o0]pen|secure|messaging|reset|account|verify|login|notification|alert|urgent|immediate|access|support|\bupdate\b|download|attachment|service|payment|remittance|invoice|rfp|rfi|pdf|doc'
          )
          and not regex.icontains(strings.replace_confusables(.display_text),
                                  'customer service'
          )
          // add confidence to these strings by using profile.by_sender()
          and (
            not profile.by_sender_email().solicited
            and profile.by_sender_email().prevalence in ('new', 'outlier')
          )
        )
        or any(ml.link_analysis(.).additional_responses,
               // make sure we have a valid response first
               .json is not null
               and .status_code == 200
               and (
                 // less than 4 cards on the Trello board
                 (
                   .json['cards'] is not null
                   and (
                     length(.json['cards']) < 4
                     or any(.json['cards'],
                            // suspicious link in a card title
                            (
                              strings.parse_url(.['name']).domain.valid
                              and (
                                ml.link_analysis(strings.parse_url(.['name'])).credphish.disposition == "phishing"
                                or ml.link_analysis(strings.parse_url(.['name'])
                                ).credphish.contains_captcha
                                // CF Turnstile
                                or any(ml.link_analysis(strings.parse_url(.['name']
                                                        )
                                       ).unique_urls_accessed,
                                       .domain.domain == "challenges.cloudflare.com"
                                )
                              )
                            )
                            // Trello detected a malicious card attachment
                            or .['badges']['maliciousAttachments'] > 0
                     )
                   )
                 )
                 // Trello has blocked the user account
                 or any(.json['members'], .['activityBlocked'] == true)
                 // the user is the sole member of their Trello account and is the admin
                 or (
                   length(.json['organization']['memberships']) == 1
                   and all(.json['organization']['memberships'],
                           .['memberType'] == "admin"
                   )
                 )
               )
        )
)

Detection logic

Scope: inbound message.

Detects suspicious Trello board links containing malicious indicators such as credential theft content, blocked users, malicious attachments, or boards with minimal content from unsolicited senders.

  1. inbound message
  2. any of filter(body.links) where any holds:
    • all of:
      • strings.replace_confusables(.display_text) matches 'review|proposal|document|efax|restore|[o0]pen|secure|messaging|reset|account|verify|login|notification|alert|urgent|immediate|access|support|\\bupdate\\b|download|attachment|service|payment|remittance|invoice|rfp|rfi|pdf|doc'
      • not:
        • strings.replace_confusables(.display_text) matches 'customer service'
      • all of:
        • not:
          • profile.by_sender_email().solicited
        • profile.by_sender_email().prevalence in ('new', 'outlier')
    • any of ml.link_analysis(.).additional_responses where all hold:
      • .json is set
      • .status_code is 200
      • any of:
        • all of:
          • .json['cards'] is set
          • any of:
            • length(.json['cards']) < 4
            • any of .json['cards'] where any holds:
              • all of:
                • strings.parse_url(.['name']).domain.valid
                • any of:
                  • ml.link_analysis(strings.parse_url(.['name'])).credphish.disposition is 'phishing'
                  • ml.link_analysis(strings.parse_url(.['name'])).credphish.contains_captcha
                  • any of ml.link_analysis(strings.parse_url(.['name'])).unique_urls_accessed where:
                    • .domain.domain is 'challenges.cloudflare.com'
              • .['badges']['maliciousAttachments'] > 0
        • any of .json['members'] where:
          • .['activityBlocked'] is True
        • all of:
          • length(.json['organization']['memberships']) is 1
          • all of .json['organization']['memberships'] where:
            • .['memberType'] is 'admin'

Inspects: body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.path, type.inbound. Sensors: ml.link_analysis, profile.by_sender_email, regex.icontains, strings.istarts_with, strings.parse_url, strings.replace_confusables.

Indicators matched (5)

FieldMatchValue
body.links[].href_url.domain.root_domainequalstrello.com
strings.istarts_withprefix/b/
regex.icontainsregexreview|proposal|document|efax|restore|[o0]pen|secure|messaging|reset|account|verify|login|notification|alert|urgent|immediate|access|support|\bupdate\b|download|attachment|service|payment|remittance|invoice|rfp|rfi|pdf|doc
ml.link_analysis(strings.parse_url(ml.link_analysis(filter(body.links)[]).additional_responses[].json['cards'][]['name'])).unique_urls_accessed[].domain.domainequalschallenges.cloudflare.com
ml.link_analysis(filter(body.links)[]).additional_responses[].json['organization']['memberships'][]['memberType']equalsadmin

Stages and Predicates

Stage 1: mql_rule

and
  any(filter(body.links))
    or
      any(ml.link_analysis(filter(body.links)).additional_responses)
        and
          or
            and
              or
                any(ml.link_analysis(filter(body.links)).additional_responses.json['cards'])
                  or
                    and
                      or
                        any(ml.link_analysis(strings.parse_url(ml.link_analysis(filter(body.links)).additional_responses.json['cards']['name'])).unique_urls_accessed)
                          ml.link_analysis(strings.parse_url(ml.link_analysis(filter(body.links)).additional_responses.json['cards']['name'])).unique_urls_accessed.domain.domain eq "challenges.cloudflare.com"
                        ml.link_analysis func_call "ml.link_analysis(strings.parse_url(ml.link_analysis(filter(body.links)[]).additional_responses[].json['cards'][]['name'])).credphish.contains_captcha"
                        ml.link_analysis func_call "ml.link_analysis(strings.parse_url(ml.link_analysis(filter(body.links)[]).additional_responses[].json['cards'][]['name'])).credphish.disposition == phishing"
                      strings.parse_url func_call "strings.parse_url(ml.link_analysis(filter(body.links)[]).additional_responses[].json['cards'][]['name']).domain.valid"
                    ml.link_analysis(filter(body.links)[]).additional_responses[].json['cards'][]['badges']['maliciousAttachments'] gt "0"
                ml.link_analysis(filter(body.links)[]).additional_responses[].json['cards'] length_compare "4"
              ml.link_analysis(filter(body.links)[]).additional_responses[].json['cards'] is_not_null
            any(ml.link_analysis(filter(body.links)).additional_responses.json['members'])
              ml.link_analysis(filter(body.links)).additional_responses.json['members']['activityBlocked'] eq "true"
            and
              ml.link_analysis(filter(body.links)[]).additional_responses[].json['organization']['memberships'] length_compare "1"
               macro "all(ml.link_analysis(filter(body.links)[]).additional_responses[].json['organization']['memberships'])"
          ml.link_analysis(filter(body.links)[]).additional_responses[].json is_not_null
          ml.link_analysis(filter(body.links)[]).additional_responses[].status_code eq "200"
      and
        not
          profile.by_sender_email func_call "profile.by_sender_email().solicited"
        not
          strings.replace_confusables(filter(body.links)[].display_text) regex_match "customer service"
        profile.by_sender_email func_call "profile.by_sender_email().prevalence in (new, outlier)"
        strings.replace_confusables(filter(body.links)[].display_text) regex_match "review|proposal|document|efax|restore|[o0]pen|secure|messaging|reset|account|verify|login|notification|alert|urgent|immediate|access|support|\\bupdate\\b|download|attachment|service|payment|remittance|invoice|rfp|rfi|pdf|doc"
  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"

Link: MyActiveCampaign Link Abuse

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

Detects messages from myactivecampaign.com containing links and suspicious language that do not exclusively point to activehosted.com domains.

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

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

Rule body

type.inbound
and 0 < length(body.links) < 10
and sender.email.domain.root_domain == "myactivecampaign.com"
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft" and .confidence == "high"
)
and not all(body.links, .href_url.domain.root_domain == "activehosted.com")

Detection logic

Scope: inbound message.

Detects messages from myactivecampaign.com containing links and suspicious language that do not exclusively point to activehosted.com domains.

  1. inbound message
  2. all of:
    • length(body.links) > 0
    • length(body.links) < 10
  3. sender.email.domain.root_domain is 'myactivecampaign.com'
  4. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name is 'cred_theft'
    • .confidence is 'high'
  5. not:
    • all of body.links where:
      • .href_url.domain.root_domain is 'activehosted.com'

Inspects: body.current_thread.text, body.links, body.links[].href_url.domain.root_domain, sender.email.domain.root_domain, type.inbound. Sensors: ml.nlu_classifier.

Indicators matched (3)

FieldMatchValue
sender.email.domain.root_domainequalsmyactivecampaign.com
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh

Stages and Predicates

Stage 1: mql_rule

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"
  not
     macro "all(body.links)"
  body.links length_compare "0"
  body.links length_compare "10"
  sender.email.domain.root_domain eq "myactivecampaign.com"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Numeric IP obfuscation in URL

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

Detects inbound messages containing links where the host is a numeric-only IP representation, commonly used to bypass domain-based URL filtering.

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
  • type

Rule body

type.inbound
and any(body.links,
        any(.href_url.ip.translation.encoders,
            . in ('octal', 'decimal_integer')
        )
)

Detection logic

Scope: inbound message.

Detects inbound messages containing links where the host is a numeric-only IP representation, commonly used to bypass domain-based URL filtering.

  1. inbound message
  2. any of body.links where:
    • any of .href_url.ip.translation.encoders where:
      • . in ('octal', 'decimal_integer')

Inspects: body.links, body.links[].href_url.ip.translation.encoders, type.inbound.

Indicators matched (2)

FieldMatchValue
body.links[].href_url.ip.translation.encoders[]memberoctal
body.links[].href_url.ip.translation.encoders[]memberdecimal_integer

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    any(body.links.href_url.ip.translation.encoders)
      body.links.href_url.ip.translation.encoders in ["decimal_integer", "octal"]
  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"

Link: Obfuscation via userinfo with excessive URL padding

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

Identifies instances where a malicious actor leverages an excessively padded username within the userinfo portion of the URL to hide the true destination in preview windows.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Impersonation: Brand

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and 0 < length(body.links) < 100
and any(body.links,
        // Detects deceptive URLs where the URL appears to start with a trusted domain (e.g., youtube.com@),
        // but the actual destination domain is something else (e.g., malicious-site.com).
        // In such cases, browsers interpret the portion before the '@' symbol as a username (e.g., youtube.com),
        // and the URL resolves to the domain after the '@' symbol (malicious-site.com).
        // This technique is often used in phishing attacks to trick users into trusting the link by showing a familiar domain.
        // (?:%(?:25)?[a-f0-9]{2}){30,} is the key part which detects 30 or more URL encoded values before an @ (or a URL encoded @)
        regex.icontains(coalesce(.href_url.rewrite.original, .href_url.url),
                        'https?(?:(?:%3a|\:)?(?:\/|%2f){2})[^\/]+(?:\s+|%(?:25)?[a-f0-9]{2}|0x[a-f0-9]+){30,}(?:@|%(?:25)?40)[^\/]+(?:\/|%(?:25)?2f)'
        )
        and not (
          .href_url.domain.sld == "google"
          and strings.istarts_with(.href_url.path, '/maps/place')
        )
)

Detection logic

Scope: inbound message.

Identifies instances where a malicious actor leverages an excessively padded username within the userinfo portion of the URL to hide the true destination in preview windows.

  1. inbound message
  2. all of:
    • length(body.links) > 0
    • length(body.links) < 100
  3. any of body.links where all hold:
    • coalesce(.href_url.rewrite.original, .href_url.url) matches 'https?(?:(?:%3a|\\:)?(?:\\/|%2f){2})[^\\/]+(?:\\s+|%(?:25)?[a-f0-9]{2}|0x[a-f0-9]+){30,}(?:@|%(?:25)?40)[^\\/]+(?:\\/|%(?:25)?2f)'
    • not:
      • all of:
        • .href_url.domain.sld is 'google'
        • .href_url.path starts with '/maps/place'

Inspects: body.links, body.links[].href_url.domain.sld, body.links[].href_url.path, body.links[].href_url.rewrite.original, body.links[].href_url.url, type.inbound. Sensors: regex.icontains, strings.istarts_with.

Indicators matched (1)

FieldMatchValue
regex.icontainsregexhttps?(?:(?:%3a|\:)?(?:\/|%2f){2})[^\/]+(?:\s+|%(?:25)?[a-f0-9]{2}|0x[a-f0-9]+){30,}(?:@|%(?:25)?40)[^\/]+(?:\/|%(?:25)?2f)

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      not
        and
          body.links.href_url.domain.sld eq "google"
          body.links.href_url.path starts_with "/maps/place"
      coalesce(body.links[].href_url.rewrite.original, body.links[].href_url.url) regex_match "https?(?:(?:%3a|\\:)?(?:\\/|%2f){2})[^\\/]+(?:\\s+|%(?:25)?[a-f0-9]{2}|0x[a-f0-9]+){30,}(?:@|%(?:25)?40)[^\\/]+(?:\\/|%(?:25)?2f)"
  body.links length_compare "0"
  body.links length_compare "100"
  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"

Link: Obfuscation via userinfo with suspicious indicators

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

Detects URLs that use the @ symbol to hide suspicious domains or URL shorteners within the link structure, excluding legitimate email addresses and malformed mailto/telto links.

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
  • type

Rule body

type.inbound
and any(body.links,
        // this checks for a likely domain in the
        .href_url.username is not null
        and strings.contains(.href_url.username, '.')
        // and coalesce(strings.parse_domain(.href_url.username).valid, false)
        and .href_url.password is null
        and (
          .href_url.domain.domain in $url_shorteners
          or .href_url.domain.root_domain in $url_shorteners
          or .href_url.domain.domain in $free_file_hosts
          or .href_url.domain.root_domain in $free_file_hosts
          or .href_url.domain.domain in $free_subdomain_hosts
          or .href_url.domain.root_domain in $free_subdomain_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.tld in $suspicious_tlds
        )
        and not (
          coalesce(strings.parse_email(.href_url.url).domain.valid, false)
          and .parser == "hyperlink"
        )
        // we dont want to match on malformed mailto or telto links
        and not .href_url.scheme in ('mailto', "tel")
        and not regex.icontains(.href_url.username, '^(?:mail|tel)\s*to=')
        and not coalesce(regex.icontains(.href_url.query_params,
                                         '\bunsubscribe\b'
                         ),
                         false
        )

        // we dont want utm urls
        and not regex.icontains(.href_url.url,
                                'utm_(?:source|medium|term|campaign)='
        )
)

Detection logic

Scope: inbound message.

Detects URLs that use the @ symbol to hide suspicious domains or URL shorteners within the link structure, excluding legitimate email addresses and malformed mailto/telto links.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.username is set
    • .href_url.username contains '.'
    • .href_url.password is missing
    • any of:
      • .href_url.domain.domain in $url_shorteners
      • .href_url.domain.root_domain in $url_shorteners
      • .href_url.domain.domain in $free_file_hosts
      • .href_url.domain.root_domain in $free_file_hosts
      • .href_url.domain.domain in $free_subdomain_hosts
      • .href_url.domain.root_domain in $free_subdomain_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.tld in $suspicious_tlds
    • not:
      • all of:
        • coalesce(strings.parse_email(.href_url.url).domain.valid)
        • .parser is 'hyperlink'
    • not:
      • .href_url.scheme in ('mailto', 'tel')
    • not:
      • .href_url.username matches '^(?:mail|tel)\\s*to='
    • not:
      • coalesce(regex.icontains(.href_url.query_params, '\\bunsubscribe\\b'))
    • not:
      • .href_url.url matches 'utm_(?:source|medium|term|campaign)='

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.tld, body.links[].href_url.password, body.links[].href_url.query_params, body.links[].href_url.scheme, body.links[].href_url.url, body.links[].href_url.username, body.links[].parser, type.inbound. Sensors: regex.icontains, strings.contains, strings.parse_email. Reference lists: $free_file_hosts, $free_subdomain_hosts, $self_service_creation_platform_domains, $suspicious_tlds, $url_shorteners.

Indicators matched (1)

FieldMatchValue
strings.containssubstring.

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      not
        and
          body.links.parser eq "hyperlink"
          coalesce func_call "coalesce(strings.parse_email(body.links[].href_url.url).domain.valid)"
      not
        body.links.href_url.scheme in ["mailto", "tel"]
      not
        body.links.href_url.url regex_match "utm_(?:source|medium|term|campaign)="
      not
        body.links.href_url.username regex_match "^(?:mail|tel)\\s*to="
      not
        coalesce func_call "coalesce(regex.icontains(body.links[].href_url.query_params, '\\\\bunsubscribe\\\\b'))"
      or
         macro "body.links[].href_url.domain.domain in free_file_hosts"
         macro "body.links[].href_url.domain.domain in free_subdomain_hosts"
         macro "body.links[].href_url.domain.domain in self_service_creation_platform_domains"
         macro "body.links[].href_url.domain.domain in url_shorteners"
         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"
         macro "body.links[].href_url.domain.tld in suspicious_tlds"
      body.links.href_url.password is_null
      body.links.href_url.username contains "."
      body.links.href_url.username is_not_null
  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"

Link: Observed malicious URL path /redirect/redirect/

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

Inbound messages containing links whose path includes a repeated '/redirect/redirect/' segment. Observed lures include fake academic transcript notices, internal administrative notices, and generic invitations sent from a mix of compromised or unrelated legitimate domains, all leveraging the nested redirect to bypass link-scanning defenses and lead recipients to malicious landing pages.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesOpen redirect, Social engineering, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links, strings.icontains(.href_url.path, '/redirect/redirect/'))

Detection logic

Scope: inbound message.

Inbound messages containing links whose path includes a repeated '/redirect/redirect/' segment. Observed lures include fake academic transcript notices, internal administrative notices, and generic invitations sent from a mix of compromised or unrelated legitimate domains, all leveraging the nested redirect to bypass link-scanning defenses and lead recipients to malicious landing pages.

  1. inbound message
  2. any of body.links where:
    • .href_url.path contains '/redirect/redirect/'

Inspects: body.links, body.links[].href_url.path, type.inbound. Sensors: strings.icontains.

Indicators matched (1)

FieldMatchValue
strings.icontainssubstring/redirect/redirect/

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    body.links.href_url.path contains "/redirect/redirect/"
  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"

Link: Observed URL pattern with specific domain registrar

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

Detects messages using Element Email service infrastructure, identified by characteristic URL patterns with /f/ paths, unsubscribe links, single domain usage, and Cloudflare domain registration. This pattern indicates potential abuse of legitimate email marketing services.

Threat classification

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

CategoryValues
Attack typesSpam
Tactics and techniquesFree email provider

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
// Signs of Email Element use
// all links are the same domain
and length(distinct(body.current_thread.links, .href_url.domain.root_domain)) == 1
// all links contain the /f/
and all(body.current_thread.links,
        regex.icontains(.href_url.path, '^/(?:unsubscribe/)?f/')
)
// there is an unsub link
and length(filter(body.current_thread.links,
                  strings.icontains(.href_url.path, '/unsubscribe/f/')
           )
) == 1
// this actor uses CF for domain management
and network.whois(sender.email.domain).registrar_name == "Cloudflare, Inc."

Detection logic

Scope: inbound message.

Detects messages using Element Email service infrastructure, identified by characteristic URL patterns with /f/ paths, unsubscribe links, single domain usage, and Cloudflare domain registration. This pattern indicates potential abuse of legitimate email marketing services.

  1. inbound message
  2. length(distinct(body.current_thread.links, .href_url.domain.root_domain)) is 1
  3. all of body.current_thread.links where:
    • .href_url.path matches '^/(?:unsubscribe/)?f/'
  4. length(filter(body.current_thread.links, strings.icontains(.href_url.path, '/unsubscribe/f/'))) is 1
  5. network.whois(sender.email.domain).registrar_name is 'Cloudflare, Inc.'

Inspects: body.current_thread.links, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.links[].href_url.path, sender.email.domain, type.inbound. Sensors: network.whois, regex.icontains, strings.icontains.

Indicators matched (2)

FieldMatchValue
regex.icontainsregex^/(?:unsubscribe/)?f/
strings.icontainssubstring/unsubscribe/f/

Stages and Predicates

Stage 1: mql_rule

and
  distinct(body.current_thread.links, .href_url.domain.root_domain) length_compare "1"
  filter(body.current_thread.links, strings.icontains(.href_url.path, '/unsubscribe/f/')) length_compare "1"
  network.whois func_call "network.whois(sender.email.domain).registrar_name == Cloudflare, Inc."
  type.inbound eq "true"
   macro "all(body.current_thread.links)"

Indicators

These rows show field, operator, and value matches.

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

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

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.links
  • subject
  • type

Rule body

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 (15)

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
3 more
strings.istarts_withprefixINV
strings.istarts_withprefixView RFQ
strings.istarts_withprefixContract

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        and
          body.links.display_text cross_field_compare "subject.base"
          body.links.display_text length_compare "0"
        body.links.display_text contains "Distribution"
        body.links.display_text contains "Wire Instructions"
        body.links.display_text contains "payment"
        body.links.display_text contains "payoff"
        body.links.display_text contains "receipt"
        body.links.display_text contains "remit"
        body.links.display_text regex_match "ACH\\b"
        body.links.display_text regex_match "EFT\\b"
        body.links.display_text regex_match "pay\\b"
        body.links.display_text starts_with "Contract"
        body.links.display_text starts_with "INV"
        body.links.display_text starts_with "View RFQ"
      not
        any(filter(...))
          filter(...).raw contains "gstatic.com/docs/doclist/images/"
      or
        body.links.href_url.domain.root_domain eq "dynamics.com"
         macro "body.links[].href_url.domain.domain in free_file_hosts"
         macro "body.links[].href_url.domain.domain in self_service_creation_platform_domains"
         macro "body.links[].href_url.domain.domain in url_shorteners"
         macro "body.links[].href_url.domain.root_domain in free_file_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"
      body.links.display_text ends_with ".pdf"
  body.links length_compare "20"
  body.previous_threads length_compare "0"
  distinct(body.links, .href_url.domain.root_domain) length_compare "3"
  filter(attachments, .file_type == 'pdf') length_compare "0"
  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') length_compare "1"
  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"

Link: PDF display text with fake copyright claim template

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

Detects messages containing fake copyright claims with table rows with 25px height images and links where the display text references PDF content, potentially indicating malicious PDF delivery attempts through deceptive formatting.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesEvasion, Image as content, PDF

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • type

Rule body

type.inbound
and any(html.xpath(body.html, '//tr[td[1]/img[@height="25px"]]/td[2]//a]').nodes,
        strings.icontains(.display_text, "PDF")
)

Detection logic

Scope: inbound message.

Detects messages containing fake copyright claims with table rows with 25px height images and links where the display text references PDF content, potentially indicating malicious PDF delivery attempts through deceptive formatting.

  1. inbound message
  2. any of html.xpath(body.html, '//tr[td[1]/img[@height="25px"]]/td[2]//a]').nodes where:
    • .display_text contains 'PDF'

Inspects: body.html, type.inbound. Sensors: html.xpath, strings.icontains.

Indicators matched (1)

FieldMatchValue
strings.icontainssubstringPDF

Stages and Predicates

Stage 1: mql_rule

and
  any(html.xpath(body.html, '//tr[td[1]/img[@height="25px"]]/td[2]//a]').nodes)
    html.xpath(body.html, '//tr[td[1]/img[@height="25px"]]/td[2]//a]').nodes.display_text contains "PDF"
  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"

Link: PDF file disguised as HTML page

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

Detects inbound messages containing links that appear to reference PDF files but are actually HTML pages, indicated by URLs ending with '.pdf' followed by additional characters and '.html'. This technique is commonly used to bypass security filters and deceive recipients into believing they are accessing a legitimate PDF document.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesEvasion, PDF

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • type

Rule body

type.inbound
and any(body.current_thread.links,
        regex.icontains(.href_url.path, '\.pdf[^/]*\.html$')
) 

Detection logic

Scope: inbound message.

Detects inbound messages containing links that appear to reference PDF files but are actually HTML pages, indicated by URLs ending with '.pdf' followed by additional characters and '.html'. This technique is commonly used to bypass security filters and deceive recipients into believing they are accessing a legitimate PDF document.

  1. inbound message
  2. any of body.current_thread.links where:
    • .href_url.path matches '\\.pdf[^/]*\\.html$'

Inspects: body.current_thread.links, body.current_thread.links[].href_url.path, type.inbound. Sensors: regex.icontains.

Indicators matched (1)

FieldMatchValue
regex.icontainsregex\.pdf[^/]*\.html$

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    body.current_thread.links.href_url.path regex_match "\\.pdf[^/]*\\.html$"
  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"

Link: PDF filename impersonation with credential theft language

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

Detects messages where the link display text mimics a PDF filename containing the sender's domain name, combined with credential theft language or suspicious requests. The message is sent to an invalid recipient address or to the sender themselves, indicating potential abuse of email infrastructure.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering, Evasion, PDF

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • recipients
  • recipients.to[0]
  • sender.email
  • type

Rule body

type.inbound
// does not actually contain a PDF attachment
and not any(attachments, .file_extension == "pdf")
and (
  // extract the first body link and compare to the sender's sld, look for less than 4 levenshtein distances or the exact match on the sld in URL ending in .pdf 
  any(regex.iextract(body.current_thread.links[0].display_text,
                     '(?P<starter>.*)\b\d+\.pdf$'
      ),
      strings.ilevenshtein(.named_groups["starter"], sender.email.domain.sld) <= 4
  )
  or (
    strings.istarts_with(body.current_thread.links[0].display_text,
                         sender.email.domain.sld
    )
    and regex.icontains(body.current_thread.links[0].display_text,
                        '\b\d+\.pdf$'
    )
  )
)
// cred theft intent or other request language 
and (
  any(ml.nlu_classifier(body.current_thread.text).intents,
      .name == "cred_theft" and .confidence != "low"
  )
  or any(filter(ml.nlu_classifier(body.current_thread.text).entities,
                .name == "request"
         ),
         regex.icontains(.text, 'please (?:see|find|click|(?:re)?view)')
  )
)
// self sender pattern or sum of recipients is zero 
and (
  length(recipients.to) <= 1
  and (
    sender.email.email == recipients.to[0].email.email
    or recipients.to[0].email.domain.valid == false
    or sum([
             length(recipients.to),
             length(recipients.cc),
             length(recipients.bcc)
           ]
    ) == 0
  )
)

Detection logic

Scope: inbound message.

Detects messages where the link display text mimics a PDF filename containing the sender's domain name, combined with credential theft language or suspicious requests. The message is sent to an invalid recipient address or to the sender themselves, indicating potential abuse of email infrastructure.

  1. inbound message
  2. not:
    • any of attachments where:
      • .file_extension is 'pdf'
  3. any of:
    • any of regex.iextract(body.current_thread.links[0].display_text) where:
      • strings.ilevenshtein(.named_groups['starter']) ≤ 4
    • all of:
      • strings.istarts_with(body.current_thread.links[0].display_text)
      • body.current_thread.links[0].display_text matches '\\b\\d+\\.pdf$'
  4. any of:
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'cred_theft'
      • .confidence is not 'low'
    • any of filter(...) where:
      • .text matches 'please (?:see|find|click|(?:re)?view)'
  5. all of:
    • length(recipients.to) ≤ 1
    • any of:
      • sender.email.email is recipients.to[0].email.email
      • recipients.to[0].email.domain.valid is False
      • sum([length(recipients.to), length(recipients.cc), length(recipients.bcc)]) is 0

Inspects: attachments[].file_extension, body.current_thread.links[0].display_text, body.current_thread.text, recipients.bcc, recipients.cc, recipients.to, recipients.to[0].email.domain.valid, recipients.to[0].email.email, sender.email.domain.sld, sender.email.email, type.inbound. Sensors: ml.nlu_classifier, regex.icontains, regex.iextract, strings.ilevenshtein, strings.istarts_with.

Indicators matched (5)

FieldMatchValue
regex.iextractregex(?P<starter>.*)\b\d+\.pdf$
regex.icontainsregex\b\d+\.pdf$
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsrequest
regex.icontainsregexplease (?:see|find|click|(?:re)?view)

Stages and Predicates

Stage 1: mql_rule

and
  or
    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(filter(...))
      filter(...).text regex_match "please (?:see|find|click|(?:re)?view)"
  not
    any(attachments)
      attachments.file_extension eq "pdf"
  or
    and
      body.current_thread.links[0].display_text regex_match "\\b\\d+\\.pdf$"
      strings.istarts_with func_call "strings.istarts_with(body.current_thread.links[0].display_text)"
    any(regex.iextract(body.current_thread.links[0].display_text))
      strings.ilevenshtein func_call "strings.ilevenshtein(regex.iextract(body.current_thread.links[0].display_text)[].named_groups['starter']) <= 4"
  or
    recipients.to[0].email.domain.valid eq "false"
    sender.email.email cross_field_compare "recipients.to[0].email.email"
    sum func_call "sum([length(recipients.to), length(recipients.cc), length(recipients.bcc)]) == 0"
  recipients.to length_compare "1"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
attachmentsarray_any(no value, null check)excludes:attachments

Indicators

These rows show field, operator, and value matches.

Link: Personal SharePoint with invalid recipients and credential theft language

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

Detects messages with undisclosed or invalid recipients containing a single link to a personal SharePoint domain (with '-my' pattern) and high-confidence credential theft language in short message body.

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

  • body
  • body.current_thread
  • body.links
  • recipients
  • recipients.cc
  • recipients.to
  • type

Rule body

type.inbound
// undisclosed recipients or no recipients
and (
  length(recipients.to) == 0
  or (
    all(recipients.to, .email.domain.valid == false)
    and all(recipients.cc, .email.domain.valid == false)
  )
)
// no previous threads
and length(body.previous_threads) == 0
// personal SharePoint domain pattern (firstname-my.sharepoint.com or similar)
and any(body.links,
        .href_url.domain.root_domain == "sharepoint.com"
        and strings.icontains(.href_url.domain.subdomain, "-my")
)
// high confidence credential theft intent from ML
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft" and .confidence in ("medium", "high")
)
// and message is relatively short and contains a single link
and (
  length(body.current_thread.text) < 1500
  and length(body.current_thread.links) == 1
)

Detection logic

Scope: inbound message.

Detects messages with undisclosed or invalid recipients containing a single link to a personal SharePoint domain (with '-my' pattern) and high-confidence credential theft language in short message body.

  1. inbound message
  2. 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
  3. length(body.previous_threads) is 0
  4. any of body.links where all hold:
    • .href_url.domain.root_domain is 'sharepoint.com'
    • .href_url.domain.subdomain contains '-my'
  5. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name is 'cred_theft'
    • .confidence in ('medium', 'high')
  6. all of:
    • length(body.current_thread.text) < 1500
    • length(body.current_thread.links) is 1

Inspects: body.current_thread.links, body.current_thread.text, body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.subdomain, body.previous_threads, recipients.cc, recipients.cc[].email.domain.valid, recipients.to, recipients.to[].email.domain.valid, type.inbound. Sensors: ml.nlu_classifier, strings.icontains.

Indicators matched (5)

FieldMatchValue
body.links[].href_url.domain.root_domainequalssharepoint.com
strings.icontainssubstring-my
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.links)
    and
      body.links.href_url.domain.root_domain eq "sharepoint.com"
      body.links.href_url.domain.subdomain contains "-my"
  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
       macro "all(recipients.cc)"
       macro "all(recipients.to)"
    recipients.to length_compare "0"
  body.current_thread.links length_compare "1"
  body.current_thread.text length_compare "1500"
  body.previous_threads length_compare "0"
  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"

Link: Personalized URL with recipient address on commonly abused web service

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

Detects messages containing links to file hosting or self-service platforms where the recipient's email address is embedded in the URL path, fragment, or base64-encoded components, indicating targeted personalization tactics.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesFree file host, 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[0]
  • sender.email
  • subject
  • type

Rule body

type.inbound
and length(recipients.to) == 1
and recipients.to[0].email.domain.valid
and 0 < length(body.links) < 10
and any(body.links,
        .parser == "hyperlink"
        and (
          // the recipient email is in the url
          (
            strings.icontains(.href_url.path, recipients.to[0].email.email)
            or strings.icontains(.href_url.fragment,
                                 recipients.to[0].email.email
            )
            or any(strings.scan_base64(.href_url.path, ignore_padding=true),
                   strings.icontains(., recipients.to[0].email.email)
            )
            or any(strings.scan_base64(.href_url.fragment, ignore_padding=true),
                   strings.icontains(., recipients.to[0].email.email)
            )
          )
        )
        and (
          (
            .href_url.domain.root_domain in $free_file_hosts
            or .href_url.domain.domain in $free_file_hosts
            or .href_url.domain.root_domain in $free_subdomain_hosts
            or .href_url.domain.domain in $free_subdomain_hosts
            or .href_url.domain.root_domain in $self_service_creation_platform_domains
            or .href_url.domain.domain in $self_service_creation_platform_domains
            or .href_url.domain.root_domain in $url_shorteners
            or .href_url.domain.domain in $url_shorteners
            or .href_url.domain.root_domain == 'sendgrid.net'
            or (
              .href_url.domain.tld in $suspicious_tlds
              and not .href_url.domain.tld in ('me', 'us')
            )
            or network.whois(.href_url.domain).days_old < 30
            or regex.icontains(.href_url.path,
                               '\/(?:wp-(?:admin|includes)\/|redirect)'
            )
          )
          and not .href_url.domain.root_domain in ('geotab.com')
        )
        // the url contains #
        and strings.contains(.href_url.url, '#')

        // the url doesnt contain #? or #/
        and not regex.contains(.href_url.url, '#[/?]')

        // not sharepoint
        and not .href_url.domain.root_domain == 'sharepoint.com'

        // the url doesnt contain campaign params
        and not regex.icontains(.href_url.url,
                                '(?:location|utm_(?:term|source|medium|content|campaign))='
        )
        // too many fp on typeform and no recent tp
        and not .href_url.domain.root_domain == 'typeform.com'

        // no welcome links on frame.io
        and not (
          .href_url.domain.domain == 'accounts.frame.io'
          and .href_url.path == '/welcome'
        )
        // we dont want links with common unsubscribe paths
        and not strings.icontains(.href_url.path, "unsubscribe")
)

// not mimecast email with malicious blocked url in it
and not (
  subject.base == 'A message triggered content policies'
  and strings.icontains(body.current_thread.text, 'Mimecast Services Limited')
)
and not any(ml.nlu_classifier(body.current_thread.text).intents,
            .name == 'benign' and .confidence == 'high'
)
and (
  (
    sender.email.domain.root_domain in $high_trust_sender_root_domains
    and not coalesce(headers.auth_summary.dmarc.pass, false)
  )
  or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)

Detection logic

Scope: inbound message.

Detects messages containing links to file hosting or self-service platforms where the recipient's email address is embedded in the URL path, fragment, or base64-encoded components, indicating targeted personalization tactics.

  1. inbound message
  2. length(recipients.to) is 1
  3. recipients.to[0].email.domain.valid
  4. all of:
    • length(body.links) > 0
    • length(body.links) < 10
  5. any of body.links where all hold:
    • .parser is 'hyperlink'
    • any of:
      • strings.icontains(.href_url.path)
      • strings.icontains(.href_url.fragment)
      • any of strings.scan_base64(.href_url.path) where:
        • strings.icontains(.)
      • any of strings.scan_base64(.href_url.fragment) where:
        • strings.icontains(.)
    • all of:
      • any of:
        • .href_url.domain.root_domain in $free_file_hosts
        • .href_url.domain.domain in $free_file_hosts
        • .href_url.domain.root_domain in $free_subdomain_hosts
        • .href_url.domain.domain in $free_subdomain_hosts
        • .href_url.domain.root_domain in $self_service_creation_platform_domains
        • .href_url.domain.domain in $self_service_creation_platform_domains
        • .href_url.domain.root_domain in $url_shorteners
        • .href_url.domain.domain in $url_shorteners
        • .href_url.domain.root_domain is 'sendgrid.net'
        • all of:
          • .href_url.domain.tld in $suspicious_tlds
          • not:
            • .href_url.domain.tld in ('me', 'us')
        • network.whois(.href_url.domain).days_old < 30
        • .href_url.path matches '\\/(?:wp-(?:admin|includes)\\/|redirect)'
      • not:
        • .href_url.domain.root_domain in ('geotab.com')
    • .href_url.url contains '#'
    • not:
      • .href_url.url matches '#[/?]'
    • not:
      • .href_url.domain.root_domain is 'sharepoint.com'
    • not:
      • .href_url.url matches '(?:location|utm_(?:term|source|medium|content|campaign))='
    • not:
      • .href_url.domain.root_domain is 'typeform.com'
    • not:
      • all of:
        • .href_url.domain.domain is 'accounts.frame.io'
        • .href_url.path is '/welcome'
    • not:
      • .href_url.path contains 'unsubscribe'
  6. not:
    • all of:
      • subject.base is 'A message triggered content policies'
      • body.current_thread.text contains 'Mimecast Services Limited'
  7. not:
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'benign'
      • .confidence is 'high'
  8. any of:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • not:
        • coalesce(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, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.tld, body.links[].href_url.fragment, body.links[].href_url.path, body.links[].href_url.url, body.links[].parser, headers.auth_summary.dmarc.pass, recipients.to, recipients.to[0].email.domain.valid, recipients.to[0].email.email, sender.email.domain.root_domain, subject.base, type.inbound. Sensors: ml.nlu_classifier, network.whois, regex.contains, regex.icontains, strings.contains, strings.icontains, strings.scan_base64. Reference lists: $free_file_hosts, $free_subdomain_hosts, $high_trust_sender_root_domains, $self_service_creation_platform_domains, $suspicious_tlds, $url_shorteners.

Indicators matched (4)

FieldMatchValue
body.links[].parserequalshyperlink
body.links[].href_url.domain.root_domainequalssendgrid.net
regex.icontainsregex\/(?:wp-(?:admin|includes)\/|redirect)
strings.containssubstring#

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        and
          not
            body.links.href_url.domain.tld in ["me", "us"]
           macro "body.links[].href_url.domain.tld in suspicious_tlds"
        body.links.href_url.domain.root_domain eq "sendgrid.net"
        body.links.href_url.path regex_match "\\/(?:wp-(?:admin|includes)\\/|redirect)"
        network.whois func_call "network.whois(body.links[].href_url.domain).days_old < 30"
         macro "body.links[].href_url.domain.domain in free_file_hosts"
         macro "body.links[].href_url.domain.domain in free_subdomain_hosts"
         macro "body.links[].href_url.domain.domain in self_service_creation_platform_domains"
         macro "body.links[].href_url.domain.domain in url_shorteners"
         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"
      not
        and
          body.links.href_url.domain.domain eq "accounts.frame.io"
          body.links.href_url.path eq "/welcome"
      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.path))
          strings.icontains func_call "strings.icontains(strings.scan_base64(body.links[].href_url.path)[])"
        strings.icontains func_call "strings.icontains(body.links[].href_url.fragment)"
        strings.icontains func_call "strings.icontains(body.links[].href_url.path)"
      not
        body.links.href_url.domain.root_domain eq "geotab.com"
      not
        body.links.href_url.domain.root_domain eq "sharepoint.com"
      not
        body.links.href_url.domain.root_domain eq "typeform.com"
      not
        body.links.href_url.path contains "unsubscribe"
      not
        body.links.href_url.url regex_match "#[/?]"
      not
        body.links.href_url.url regex_match "(?:location|utm_(?:term|source|medium|content|campaign))="
      body.links.href_url.url contains "#"
      body.links.parser eq "hyperlink"
  or
    and
      not
        coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       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).intents)
      and
        ml.nlu_classifier(body.current_thread.text).intents.confidence eq "high"
        ml.nlu_classifier(body.current_thread.text).intents.name eq "benign"
  not
    and
      body.current_thread.text contains "Mimecast Services Limited"
      subject.base eq "A message triggered content policies"
  body.links length_compare "0"
  body.links length_compare "10"
  recipients.to length_compare "1"
  recipients.to[0].email.domain.valid eq "true"
  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
body.current_thread.textcontainsMimecast Services Limitedexcludes:body.current_thread.text field:"body.current_thread.text" value:"Mimecast Services Limited"
subject.baseeqA message triggered content policiesexcludes:subject.base field:"subject.base" value:"A message triggered content policies"

Indicators

These rows show field, operator, and value matches.

Link: QR code in EML attachment with credential phishing indicators

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

This rule detects QR codes in EML attachments that return a phishing disposition when analyzed, or are leveraging a known open redirect.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Open redirect, QR code

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • type

Rule body

type.inbound
and length(attachments) == 1
and any(attachments,
        (.content_type == "message/rfc822" or .file_extension =~ "eml")
        // credential theft language in the attached EML
        and any(file.explode(.),
                .depth > 0
                and .scan.qr.type == "url"

                // linkanalysis phishing disposition
                and (
                  ml.link_analysis(.scan.qr.url).credphish.disposition == "phishing"
                  or (
                    strings.ilike(ml.link_analysis(.scan.qr.url).final_dom.display_text,
                                  "*robot*",
                                  "*session check*",
                                  "*verify*",
                                  "*human*"
                    )
                    and length(ml.link_analysis(.scan.qr.url).final_dom.display_text
                    ) < 250
                  )
                  or any(ml.link_analysis(.scan.qr.url).unique_urls_accessed,
                         .domain.domain == "challenges.cloudflare.com"
                         and strings.icontains(.path, "turnstile")
                  )
                  or any(.scan.qr.url.rewrite.encoders,
                         strings.icontains(., "open_redirect")
                  )
                )
                and .scan.qr.url.domain.root_domain not in $org_domains
        )
)

Detection logic

Scope: inbound message.

This rule detects QR codes in EML attachments that return a phishing disposition when analyzed, or are leveraging a known open redirect.

  1. inbound message
  2. length(attachments) is 1
  3. any of attachments where all hold:
    • any of:
      • .content_type is 'message/rfc822'
      • .file_extension is 'eml'
    • any of file.explode(.) where all hold:
      • .depth > 0
      • .scan.qr.type is 'url'
      • any of:
        • ml.link_analysis(.scan.qr.url).credphish.disposition is 'phishing'
        • all of:
          • ml.link_analysis(.scan.qr.url).final_dom.display_text matches any of 4 patterns
            • *robot*
            • *session check*
            • *verify*
            • *human*
          • length(ml.link_analysis(.scan.qr.url).final_dom.display_text) < 250
        • any of ml.link_analysis(.scan.qr.url).unique_urls_accessed where all hold:
          • .domain.domain is 'challenges.cloudflare.com'
          • .path contains 'turnstile'
        • any of .scan.qr.url.rewrite.encoders where:
          • . contains 'open_redirect'
      • .scan.qr.url.domain.root_domain not in $org_domains

Inspects: attachments[].content_type, attachments[].file_extension, type.inbound. Sensors: file.explode, ml.link_analysis, strings.icontains, strings.ilike. Reference lists: $org_domains.

Indicators matched (10)

FieldMatchValue
attachments[].content_typeequalsmessage/rfc822
attachments[].file_extensionequalseml
file.explode(attachments[])[].scan.qr.typeequalsurl
strings.ilikesubstring*robot*
strings.ilikesubstring*session check*
strings.ilikesubstring*verify*
strings.ilikesubstring*human*
ml.link_analysis(file.explode(attachments[])[].scan.qr.url).unique_urls_accessed[].domain.domainequalschallenges.cloudflare.com
strings.icontainssubstringturnstile
strings.icontainssubstringopen_redirect

Stages and Predicates

Stage 1: mql_rule

and
  any(attachments)
    and
      any(file.explode(attachments))
        and
          or
            and
              or
                ml.link_analysis(file.explode(attachments[])[].scan.qr.url).final_dom.display_text match "human"
                ml.link_analysis(file.explode(attachments[])[].scan.qr.url).final_dom.display_text match "robot"
                ml.link_analysis(file.explode(attachments[])[].scan.qr.url).final_dom.display_text match "session check"
                ml.link_analysis(file.explode(attachments[])[].scan.qr.url).final_dom.display_text match "verify"
              ml.link_analysis(file.explode(attachments[])[].scan.qr.url).final_dom.display_text length_compare "250"
            any(ml.link_analysis(file.explode(attachments).scan.qr.url).unique_urls_accessed)
              and
                ml.link_analysis(file.explode(attachments[])[].scan.qr.url).unique_urls_accessed[].domain.domain eq "challenges.cloudflare.com"
                ml.link_analysis(file.explode(attachments[])[].scan.qr.url).unique_urls_accessed[].path contains "turnstile"
            any(file.explode(attachments).scan.qr.url.rewrite.encoders)
              file.explode(attachments).scan.qr.url.rewrite.encoders contains "open_redirect"
            ml.link_analysis func_call "ml.link_analysis(file.explode(attachments[])[].scan.qr.url).credphish.disposition == phishing"
          file.explode(attachments[])[].depth gt "0"
          file.explode(attachments[])[].scan.qr.type eq "url"
           macro "file.explode(attachments[])[].scan.qr.url.domain.root_domain not in org_domains"
      or
        attachments.content_type eq "message/rfc822"
        attachments.file_extension eq "eml"
  attachments length_compare "1"
  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"

Link: QR code with phishing disposition in img or pdf

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

This rule analyzes image attachments for QR Codes in which LinkAnalysis concludes is phishing. The rule ensures that the URLs do not link to any organizational domains.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesQR code, 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(attachments) < 10
and any(attachments,
        (.file_type in $file_types_images or .file_type == "pdf")
        and any(file.explode(.),
                .scan.qr.type == "url"

                // linkanalysis phishing disposition
                and any([ml.link_analysis(.scan.qr.url)],
                        .credphish.disposition == "phishing"
                )
                and .scan.qr.url.domain.root_domain not in $org_domains
        )
)
and (
  not profile.by_sender_email().solicited
  or not profile.by_sender_email().any_messages_benign
  or (
    profile.by_sender_email().any_messages_malicious_or_spam
    and not profile.by_sender_email().any_messages_benign
  )
  or (
    sender.email.domain.domain in $org_domains
    and not coalesce(headers.auth_summary.dmarc.pass, false)
  )
)

// 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 analyzes image attachments for QR Codes in which LinkAnalysis concludes is phishing. The rule ensures that the URLs do not link to any organizational domains.

  1. inbound message
  2. length(attachments) < 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 all hold:
      • .scan.qr.type is 'url'
      • any of [ml.link_analysis(.scan.qr.url)] where:
        • .credphish.disposition is 'phishing'
      • .scan.qr.url.domain.root_domain not in $org_domains
  4. any of:
    • not:
      • profile.by_sender_email().solicited
    • not:
      • profile.by_sender_email().any_messages_benign
    • all of:
      • profile.by_sender_email().any_messages_malicious_or_spam
      • not:
        • profile.by_sender_email().any_messages_benign
    • all of:
      • sender.email.domain.domain in $org_domains
      • not:
        • coalesce(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

Inspects: attachments[].file_type, headers.auth_summary.dmarc.pass, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, ml.link_analysis, profile.by_sender_email. Reference lists: $file_types_images, $high_trust_sender_root_domains, $org_domains.

Indicators matched (3)

FieldMatchValue
attachments[].file_typeequalspdf
file.explode(attachments[])[].scan.qr.typeequalsurl
[ml.link_analysis(file.explode(attachments[])[].scan.qr.url)][].credphish.dispositionequalsphishing

Stages and Predicates

Stage 1: mql_rule

and
  any(attachments)
    and
      any(file.explode(attachments))
        and
          any([ml.link_analysis(file.explode(attachments).scan.qr.url)])
            [ml.link_analysis(file.explode(attachments).scan.qr.url)].credphish.disposition eq "phishing"
          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"
  or
    and
      not
        coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       macro "sender.email.domain.domain in org_domains"
    and
      not
        profile.by_sender_email func_call "profile.by_sender_email().any_messages_benign"
      profile.by_sender_email func_call "profile.by_sender_email().any_messages_malicious_or_spam"
    not
      profile.by_sender_email func_call "profile.by_sender_email().any_messages_benign"
    not
      profile.by_sender_email func_call "profile.by_sender_email().solicited"
  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"
  attachments 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"

Link: QR Code with suspicious language (untrusted sender)

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

This rule analyzes image attachments for QR Codes that contain URLs including the recipient's email address. It ensures that the URLs do not link to any organizational domains. Additionally, it examines the email body using Natural Language Processing to detect credential phishing language.In cases of null bodies, the rule is conditioned to check the image for any suspicious terms.

Threat classification

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

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

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound

// check image attachments for QR code, will want to add message.screenshot functionality here when it's ready
// and length(attachments) < 10
and any(attachments,
        (.file_type in $file_types_images or .file_type == "pdf")
        and any(file.explode(.),
                .scan.qr.type == "url"

                // recipient email address is present in the URL, a common tactic used in credential phishing attacks and the url is not in $org_domains
                and (
                  any(recipients.to,
                      .email.domain.valid
                      and (
                        strings.icontains(..scan.qr.data, .email.email)
                        or (
                          // recipient email found in qr data base64 encoded
                          any(beta.scan_base64(..scan.qr.data, format="url"),
                              strings.icontains(., ..email.email)
                          )
                        )
                      )
                  )
                  and .scan.qr.url.domain.root_domain not in $org_domains
                )
        )
)

// NLU has identified cred_theft language with high confidence
and (
  any(ml.nlu_classifier(body.current_thread.text).intents,
      .name == "cred_theft" and .confidence == "high"
  )
  or 
  // the attachment contains suspicious strings
  (
    any(attachments,
        (.file_type in $file_types_images or .file_type == "pdf")
        and any(file.explode(.),
                any(.scan.strings.strings,
                    regex.icontains(.,
                                    '(\b2fa\b|\bQ.?R\.?\s?\b|MFA|Muti[ -]?Factor Auth(entication)?)'
                    )
                )
        )
    )
  )
)
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
  )
  or (
    sender.email.domain.domain in $org_domains
    and not coalesce(headers.auth_summary.dmarc.pass, false)
  )
)

// 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 analyzes image attachments for QR Codes that contain URLs including the recipient's email address. It ensures that the URLs do not link to any organizational domains. Additionally, it examines the email body using Natural Language Processing to detect credential phishing language.In cases of null bodies, the rule is conditioned to check the image for any suspicious terms.

  1. inbound message
  2. 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'
      • all of:
        • any of recipients.to where all hold:
          • .email.domain.valid
          • any of:
            • strings.icontains(.scan.qr.data)
            • any of beta.scan_base64(.scan.qr.data) where:
              • strings.icontains(.)
        • .scan.qr.url.domain.root_domain not in $org_domains
  3. any of:
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'cred_theft'
      • .confidence is 'high'
    • 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 .scan.strings.strings where:
          • . matches '(\\b2fa\\b|\\bQ.?R\\.?\\s?\\b|MFA|Muti[ -]?Factor Auth(entication)?)'
  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
    • all of:
      • sender.email.domain.domain in $org_domains
      • not:
        • coalesce(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

Inspects: attachments[].file_type, body.current_thread.text, headers.auth_summary.dmarc.pass, recipients.to, recipients.to[].email.domain.valid, recipients.to[].email.email, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: beta.scan_base64, file.explode, ml.nlu_classifier, profile.by_sender, regex.icontains, strings.icontains. Reference lists: $file_types_images, $high_trust_sender_root_domains, $org_domains.

Indicators matched (5)

FieldMatchValue
attachments[].file_typeequalspdf
file.explode(attachments[])[].scan.qr.typeequalsurl
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh
regex.icontainsregex(\b2fa\b|\bQ.?R\.?\s?\b|MFA|Muti[ -]?Factor Auth(entication)?)

Stages and Predicates

Stage 1: mql_rule

and
  any(attachments)
    and
      any(file.explode(attachments))
        and
          any(recipients.to)
            and
              or
                any(beta.scan_base64(file.explode(attachments).scan.qr.data))
                  strings.icontains func_call "strings.icontains(beta.scan_base64(file.explode(attachments[])[].scan.qr.data)[])"
                strings.icontains func_call "strings.icontains(file.explode(attachments[])[].scan.qr.data)"
              recipients.to.email.domain.valid eq "true"
          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"
  or
    any(attachments)
      and
        any(file.explode(attachments))
          any(file.explode(attachments).scan.strings.strings)
            file.explode(attachments).scan.strings.strings regex_match "(\\b2fa\\b|\\bQ.?R\\.?\\s?\\b|MFA|Muti[ -]?Factor Auth(entication)?)"
        or
          attachments.file_type eq "pdf"
           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 eq "high"
        ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
  or
    and
      not
        coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
       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().prevalence in (new, outlier)"
  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"
  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"

Link: QuickBooks image lure with suspicious link

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

This rule detects messages with image attachments containing QuickBooks logo containing exactly 1 link to a suspicious URL.

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 == "Quickbooks")
)
and length(body.links) == 1
and (
  // body text is very short
  (
    0 <= (length(body.current_thread.text)) < 10
    or body.current_thread.text is null
  )
  or (
    length(body.current_thread.text) < 1500
    // or body is most likely all warning banner (text contains the sender and common warning banner language)
    and (
      regex.icontains(body.current_thread.text,
                      'caution|confidentiality notice|warning|disclaimer|permission'
      )
    )
  )
)

// suspicious link
and any(body.links,
        (
          .href_url.domain.root_domain not in $tranco_1m
          or .href_url.domain.domain in $free_file_hosts
          or .href_url.domain.root_domain in $free_file_hosts
          or .href_url.domain.root_domain in $free_subdomain_hosts
          or .href_url.domain.domain in $url_shorteners
          or .href_url.domain.domain in $social_landing_hosts
          or 

          // mass mailer link, masks the actual URL
          .href_url.domain.root_domain in (
            "hubspotlinks.com",
            "mandrillapp.com",
            "sendgrid.net",
            "naylorcampaigns.com",
            "rs6.net"
          )
        )

        // exclude sources of potential FPs
        and (
          .href_url.domain.root_domain not in (
            "svc.ms",
            "sharepoint.com",
            "1drv.ms",
            "microsoft.com",
            "aka.ms",
            "msftauthimages.net",
            "intuit.com",
            "turbotax.com",
            "intuit.ca"
          )
          or .href_url.domain.domain in $free_file_hosts
        )
        and .href_url.domain.root_domain not in $org_domains
)
and sender.email.domain.root_domain not in~ (
  'intuit.com',
  'turbotax.com',
  'intuit.ca'
)

// 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 messages with image attachments containing QuickBooks logo containing exactly 1 link to a suspicious URL.

  1. inbound message
  2. length(attachments) < 3
  3. any of attachments where all hold:
    • .file_type in $file_types_images
    • any of ml.logo_detect(.).brands where:
      • .name is 'Quickbooks'
  4. length(body.links) is 1
  5. any of:
    • any of:
      • all of:
        • length(body.current_thread.text) ≥ 0
        • length(body.current_thread.text) < 10
      • body.current_thread.text is missing
    • all of:
      • length(body.current_thread.text) < 1500
      • body.current_thread.text matches 'caution|confidentiality notice|warning|disclaimer|permission'
  6. any of body.links where all hold:
    • any of:
      • .href_url.domain.root_domain not in $tranco_1m
      • .href_url.domain.domain in $free_file_hosts
      • .href_url.domain.root_domain in $free_file_hosts
      • .href_url.domain.root_domain in $free_subdomain_hosts
      • .href_url.domain.domain in $url_shorteners
      • .href_url.domain.domain in $social_landing_hosts
      • .href_url.domain.root_domain in ('hubspotlinks.com', 'mandrillapp.com', 'sendgrid.net', 'naylorcampaigns.com', 'rs6.net')
    • any of:
      • .href_url.domain.root_domain not in ('svc.ms', 'sharepoint.com', '1drv.ms', 'microsoft.com', 'aka.ms', 'msftauthimages.net', 'intuit.com', 'turbotax.com', 'intuit.ca')
      • .href_url.domain.domain in $free_file_hosts
    • .href_url.domain.root_domain not in $org_domains
  7. sender.email.domain.root_domain not in ('intuit.com', 'turbotax.com', 'intuit.ca')
  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_type, body.current_thread.text, body.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: ml.logo_detect, regex.icontains. Reference lists: $file_types_images, $free_file_hosts, $free_subdomain_hosts, $high_trust_sender_root_domains, $org_domains, $social_landing_hosts, $tranco_1m, $url_shorteners.

Indicators matched (7)

FieldMatchValue
ml.logo_detect(attachments[]).brands[].nameequalsQuickbooks
regex.icontainsregexcaution|confidentiality notice|warning|disclaimer|permission
body.links[].href_url.domain.root_domainmemberhubspotlinks.com
body.links[].href_url.domain.root_domainmembermandrillapp.com
body.links[].href_url.domain.root_domainmembersendgrid.net
body.links[].href_url.domain.root_domainmembernaylorcampaigns.com
body.links[].href_url.domain.root_domainmemberrs6.net

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        not
          body.links.href_url.domain.root_domain in ["1drv.ms", "aka.ms", "intuit.ca", "intuit.com", "microsoft.com", "msftauthimages.net", "sharepoint.com", "svc.ms", "turbotax.com"]
         macro "body.links[].href_url.domain.domain in free_file_hosts"
      or
        body.links.href_url.domain.root_domain in ["hubspotlinks.com", "mandrillapp.com", "naylorcampaigns.com", "rs6.net", "sendgrid.net"]
         macro "body.links[].href_url.domain.domain in free_file_hosts"
         macro "body.links[].href_url.domain.domain in social_landing_hosts"
         macro "body.links[].href_url.domain.domain in url_shorteners"
         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 not in tranco_1m"
       macro "body.links[].href_url.domain.root_domain not 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"
  any(attachments)
    and
      any(ml.logo_detect(attachments).brands)
        ml.logo_detect(attachments).brands.name eq "Quickbooks"
       macro "attachments[].file_type in file_types_images"
  or
    and
      body.current_thread.text length_compare "0"
      body.current_thread.text length_compare "10"
    and
      body.current_thread.text length_compare "1500"
      body.current_thread.text regex_match "caution|confidentiality notice|warning|disclaimer|permission"
    body.current_thread.text is_null
  not
    sender.email.domain.root_domain in ["intuit.ca", "intuit.com", "turbotax.com"]
  attachments length_compare "3"
  body.links length_compare "1"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

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
    • caution
    • confidentiality notice
    • warning
    • disclaimer
    • permission
field:"body.current_thread.text" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link: Recipient domain in URL path

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

This rule detects URL paths which contain the recipient SLD multiple times. This has been observed in multiple credential phishing campaigns with MFA enrollment themed lures.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesLookalike domain

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
// 
and not profile.by_sender().solicited
// not high trust sender 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 
// any of the body links, contain the recipient domain repeating multiple times in a link path
any(
    // make a list of distinct email slds
    distinct(map(recipients.to, .email.domain.sld)),
    // take the list of slds and cat it into a string of /sld/sld/ and search for it in links
    any(body.links,
        strings.icontains(.href_url.path, strings.concat("/", .., "/", .., "/"))
    )
)

Detection logic

Scope: inbound message.

This rule detects URL paths which contain the recipient SLD multiple times. This has been observed in multiple credential phishing campaigns with MFA enrollment themed lures.

  1. inbound message
  2. not:
    • profile.by_sender().solicited
  3. 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
  4. any of distinct(...) where:
    • any of body.links where:
      • strings.icontains(.href_url.path)

Inspects: body.links, body.links[].href_url.path, headers.auth_summary.dmarc.pass, recipients.to, recipients.to[].email.domain.sld, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender, strings.concat, strings.icontains. Reference lists: $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"
  any(distinct(...))
    any(body.links)
      strings.icontains func_call "strings.icontains(body.links[].href_url.path)"
  not
    profile.by_sender func_call "profile.by_sender().solicited"
  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"

Link: Recipient email address in 'eta' parameter

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

Detects links containing the recipient's email address in the 'eta' query parameter, a technique commonly used to personalize malicious links and track targets.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • recipients
  • recipients.to[0]
  • type

Rule body

type.inbound
and length(recipients.to) == 1
and any(body.links,
        // eta is the only key
        length(keys(.href_url.query_params_decoded)) == 1
        and (
          // the recpieints email domain is in the value
          // we've seen cases where `.` in the local part are not in the value, thus we rely on domain only
          strings.icontains(.href_url.query_params_decoded["eta"][0],
                            recipients.to[0].email.domain.domain
          )
          // support base64 form as well
          or strings.icontains(strings.decode_base64(.href_url.query_params_decoded["eta"][0]
                               ),
                               recipients.to[0].email.domain.domain
          )
        )
)

Detection logic

Scope: inbound message.

Detects links containing the recipient's email address in the 'eta' query parameter, a technique commonly used to personalize malicious links and track targets.

  1. inbound message
  2. length(recipients.to) is 1
  3. any of body.links where all hold:
    • length(keys(.href_url.query_params_decoded)) is 1
    • any of:
      • strings.icontains(.href_url.query_params_decoded['eta'][0])
      • strings.icontains(strings.decode_base64(.href_url.query_params_decoded['eta'][0]))

Inspects: body.links, body.links[].href_url.query_params_decoded, body.links[].href_url.query_params_decoded['eta'][0], recipients.to, recipients.to[0].email.domain.domain, type.inbound. Sensors: strings.decode_base64, strings.icontains.

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        strings.icontains func_call "strings.icontains(body.links[].href_url.query_params_decoded['eta'][0])"
        strings.icontains func_call "strings.icontains(strings.decode_base64(body.links[].href_url.query_params_decoded['eta'][0]))"
      keys(body.links[].href_url.query_params_decoded) length_compare "1"
  recipients.to length_compare "1"
  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"

Link: Referrer anonymization service from untrusted sender

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

Detects messages containing links that utilize a referrer anonymization service. The rule examines senders who are either not in a trusted domain list or have failed DMARC authentication despite being from a trusted domain.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesOpen redirect, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
and any(body.links,
        // href.li
        (
          .href_url.domain.root_domain == "href.li"
          and .href_url.query_params is not null
        )
        or "href_li" in .href_url.rewrite.encoders
        // deref-mail 
        or (
          (
            (
              strings.istarts_with(.href_url.path, '/mail/client/')
              and strings.icontains(.href_url.query_params, 'redirectUrl=')
            )
            or "deref_mail" in .href_url.rewrite.encoders
          )
          // this seems to be a common behavior for gmx users
          and not sender.email.domain.domain in ("gmx.de", "gmx.net")
          and not (
            sender.email.domain.domain == "mail.com"
            and any(headers.domains, .root_domain == "mail.com")
          )
          // remove any links that include org domains
          and not any($org_domains,
                      strings.icontains(..href_url.query_params, .)
          )
          // remove any links that are to common "signature" sites
          // this does open up some FNs due to abuse of redirects of these sites
          // if FNs are obsevered, we should tighten the logic of these to account
          // for the redirect behavior
          and not any(['facebook.com', 'x.com', 'twitter.com', 'instagram.com'],
                      strings.icontains(..href_url.query_params, .)
          )

          // remove links which contain the sender domain if the sender doesn't have any malicious messages
          and not (
            strings.icontains(.href_url.query_params,
                              sender.email.domain.root_domain
            )
            and not profile.by_sender_domain().any_messages_malicious_or_spam
          )
        )
)
// apply sender profile elements specific to the sender_email
and (
  profile.by_sender_email().prevalence == "new"

  // if they aren't new, there are some condition that still result in a match
  or (
    // and have been flagged previous
    profile.by_sender_email().any_messages_malicious_or_spam
    // without any false positives
    and not profile.by_sender_email().any_messages_benign
  )
)
// negate solicited senders
and not profile.by_sender_email().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 containing links that utilize a referrer anonymization service. The rule examines senders who are either not in a trusted domain list or have failed DMARC authentication despite being from a trusted domain.

  1. inbound message
  2. any of body.links where any holds:
    • all of:
      • .href_url.domain.root_domain is 'href.li'
      • .href_url.query_params is set
    • .href_url.rewrite.encoders contains 'href_li'
    • all of:
      • any of:
        • all of:
          • .href_url.path starts with '/mail/client/'
          • .href_url.query_params contains 'redirectUrl='
        • .href_url.rewrite.encoders contains 'deref_mail'
      • not:
        • sender.email.domain.domain in ('gmx.de', 'gmx.net')
      • not:
        • all of:
          • sender.email.domain.domain is 'mail.com'
          • any of headers.domains where:
            • .root_domain is 'mail.com'
      • not:
        • any of $org_domains where:
          • strings.icontains(.href_url.query_params)
      • not:
        • any of ['facebook.com', 'x.com', 'twitter.com', 'instagram.com'] where:
          • strings.icontains(.href_url.query_params)
      • not:
        • all of:
          • strings.icontains(.href_url.query_params)
          • not:
            • profile.by_sender_domain().any_messages_malicious_or_spam
  3. any of:
    • profile.by_sender_email().prevalence is 'new'
    • all of:
      • profile.by_sender_email().any_messages_malicious_or_spam
      • not:
        • profile.by_sender_email().any_messages_benign
  4. not:
    • profile.by_sender_email().solicited
  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.links, body.links[].href_url.domain.root_domain, body.links[].href_url.path, body.links[].href_url.query_params, body.links[].href_url.rewrite.encoders, headers.auth_summary.dmarc.pass, headers.domains, headers.domains[].root_domain, sender.email.domain.domain, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender_domain, profile.by_sender_email, strings.icontains, strings.istarts_with. Reference lists: $high_trust_sender_root_domains, $org_domains.

Indicators matched (5)

FieldMatchValue
body.links[].href_url.domain.root_domainequalshref.li
body.links[].href_url.rewrite.encoderscontainshref_li
strings.istarts_withprefix/mail/client/
strings.icontainssubstringredirectUrl=
body.links[].href_url.rewrite.encoderscontainsderef_mail

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    or
      and
        not
          and
            any(headers.domains)
              headers.domains.root_domain eq "mail.com"
            sender.email.domain.domain eq "mail.com"
        not
          and
            not
              profile.by_sender_domain func_call "profile.by_sender_domain().any_messages_malicious_or_spam"
            strings.icontains func_call "strings.icontains(body.links[].href_url.query_params)"
        or
          and
            body.links.href_url.path starts_with "/mail/client/"
            body.links.href_url.query_params contains "redirectUrl="
          body.links.href_url.rewrite.encoders contains "deref_mail"
        not
          any($org_domains)
            strings.icontains func_call "strings.icontains(body.links[].href_url.query_params)"
        not
          any(['facebook.com', 'x.com', 'twitter.com', 'instagram.com'])
            strings.icontains func_call "strings.icontains(body.links[].href_url.query_params)"
        not
          sender.email.domain.domain in ["gmx.de", "gmx.net"]
      and
        body.links.href_url.domain.root_domain eq "href.li"
        body.links.href_url.query_params is_not_null
      body.links.href_url.rewrite.encoders contains "href_li"
  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_email func_call "profile.by_sender_email().any_messages_benign"
      profile.by_sender_email func_call "profile.by_sender_email().any_messages_malicious_or_spam"
    profile.by_sender_email func_call "profile.by_sender_email().prevalence == new"
  not
    profile.by_sender_email func_call "profile.by_sender_email().solicited"
  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"

Link: Remittance payment request with timeline template

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

Detects messages containing references to business days and account information with links containing 'remittance' in the URL path, commonly used in financial fraud schemes. This rule is looking at a specific template we're seeing in use with a expedited timeline.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Credential Phishing
Tactics and techniquesSocial engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • body.plain
  • type

Rule body

type.inbound
and strings.icontains(body.plain.raw, "business days")
and strings.icontains(body.plain.raw, "account")
and any(filter(body.links,
               .href_url.domain.root_domain not in $tranco_10k
               or (
                 .href_url.domain.root_domain in $tranco_10k
                 and (
                   .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.root_domain in $free_file_hosts
                   or .href_url.domain.domain in $free_file_hosts
                 )
               )
        ),
        strings.icontains(.href_url.path, "remittance")
)

Detection logic

Scope: inbound message.

Detects messages containing references to business days and account information with links containing 'remittance' in the URL path, commonly used in financial fraud schemes. This rule is looking at a specific template we're seeing in use with a expedited timeline.

  1. inbound message
  2. body.plain.raw contains 'business days'
  3. body.plain.raw contains 'account'
  4. any of filter(body.links) where:
    • .href_url.path contains 'remittance'

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.plain.raw, type.inbound. Sensors: strings.icontains. Reference lists: $free_file_hosts, $self_service_creation_platform_domains, $tranco_10k.

Indicators matched (3)

FieldMatchValue
strings.icontainssubstringbusiness days
strings.icontainssubstringaccount
strings.icontainssubstringremittance

Stages and Predicates

Stage 1: mql_rule

and
  any(filter(body.links))
    filter(body.links).href_url.path contains "remittance"
  body.plain.raw contains "account"
  body.plain.raw contains "business days"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.plain.rawcontains
  • account
  • business days
field:"body.plain.raw" kind:contains
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link: RFI document reference pattern in display text

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

Detects links with display text containing RFI (Request for Information) document reference patterns using format RFI-###-###-###, commonly used in construction and procurement fraud schemes.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud
Tactics and techniquesSocial engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • type

Rule body

type.inbound
and any(body.current_thread.links,
        regex.icontains(.display_text, '\bRFI-\d{1,5}-\d{1,5}-\d{1,5}\b')
        and not regex.icontains(.display_text,
                                '\bRFI-\d{2}-\d{2}-\d{4}\b',
                                '\bRFI-\d{4}-\d{2}-\d{2}\b'
        )
)
and length(body.links) < 11

Detection logic

Scope: inbound message.

Detects links with display text containing RFI (Request for Information) document reference patterns using format RFI-###-###-###, commonly used in construction and procurement fraud schemes.

  1. inbound message
  2. any of body.current_thread.links where all hold:
    • .display_text matches '\\bRFI-\\d{1,5}-\\d{1,5}-\\d{1,5}\\b'
    • not:
      • .display_text matches any of 2 patterns
        • \bRFI-\d{2}-\d{2}-\d{4}\b
        • \bRFI-\d{4}-\d{2}-\d{2}\b
  3. length(body.links) < 11

Inspects: body.current_thread.links, body.current_thread.links[].display_text, body.links, type.inbound. Sensors: regex.icontains.

Indicators matched (1)

FieldMatchValue
regex.icontainsregex\bRFI-\d{1,5}-\d{1,5}-\d{1,5}\b

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    and
      not
        or
          body.current_thread.links.display_text regex_match "\\bRFI-\\d{2}-\\d{2}-\\d{4}\\b"
          body.current_thread.links.display_text regex_match "\\bRFI-\\d{4}-\\d{2}-\\d{2}\\b"
      body.current_thread.links.display_text regex_match "\\bRFI-\\d{1,5}-\\d{1,5}-\\d{1,5}\\b"
  body.links length_compare "11"
  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"

Link: Romance/Sexual Language With Suspicious Link

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

Detects messages containing romantic or adult-themed language, combined with links to newly registered domains or suspicious reply-to addresses.

Threat classification

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

CategoryValues
Attack typesSpam
Tactics and techniquesSocial engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
and length(body.previous_threads) == 0
and any(ml.nlu_classifier(body.current_thread.text).topics,
        .name in ("Romance", "Sexually Explicit Messages")
        and .confidence == "high"
)
and 1 of (
  any(body.links, network.whois(.href_url.domain).days_old < 30),
  any(body.links, .href_url.domain.root_domain in $url_shorteners),
  any(body.links, .href_url.domain.domain in $free_subdomain_hosts),
  any(body.links, .href_url.domain.tld in ('ru', 'app', 'digital', 'click')),
  any(headers.reply_to, network.whois(.email.domain).days_old < 30)
)
and 0 < length(distinct(body.links,
                        .href_url.domain.root_domain not in ("aka.ms")
               )
) < 3
and all(body.links,
        .href_url.domain.root_domain != sender.email.domain.root_domain
)

Detection logic

Scope: inbound message.

Detects messages containing romantic or adult-themed language, combined with links to newly registered domains or suspicious reply-to addresses.

  1. inbound message
  2. length(body.previous_threads) is 0
  3. any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
    • .name in ('Romance', 'Sexually Explicit Messages')
    • .confidence is 'high'
  4. at least 1 of:
    • any of body.links where:
      • network.whois(.href_url.domain).days_old < 30
    • any of body.links where:
      • .href_url.domain.root_domain in $url_shorteners
    • any of body.links where:
      • .href_url.domain.domain in $free_subdomain_hosts
    • any of body.links where:
      • .href_url.domain.tld in ('ru', 'app', 'digital', 'click')
    • any of headers.reply_to where:
      • network.whois(.email.domain).days_old < 30
  5. all of:
    • length(distinct(body.links, .href_url.domain.root_domain not in ('aka.ms'))) > 0
    • length(distinct(body.links, .href_url.domain.root_domain not in ('aka.ms'))) < 3
  6. all of body.links where:
    • .href_url.domain.root_domain is not sender.email.domain.root_domain

Inspects: body.current_thread.text, body.links, body.links[].href_url.domain, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.tld, body.previous_threads, headers.reply_to, headers.reply_to[].email.domain, sender.email.domain.root_domain, type.inbound. Sensors: ml.nlu_classifier, network.whois. Reference lists: $free_subdomain_hosts, $url_shorteners.

Indicators matched (7)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).topics[].namememberRomance
ml.nlu_classifier(body.current_thread.text).topics[].namememberSexually Explicit Messages
ml.nlu_classifier(body.current_thread.text).topics[].confidenceequalshigh
body.links[].href_url.domain.tldmemberru
body.links[].href_url.domain.tldmemberapp
body.links[].href_url.domain.tldmemberdigital
body.links[].href_url.domain.tldmemberclick

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(body.links)
      body.links.href_url.domain.tld in ["app", "click", "digital", "ru"]
    any(body.links)
      network.whois func_call "network.whois(body.links[].href_url.domain).days_old < 30"
    any(headers.reply_to)
      network.whois func_call "network.whois(headers.reply_to[].email.domain).days_old < 30"
    any(body.links)
       macro "body.links[].href_url.domain.domain in free_subdomain_hosts"
    any(body.links)
       macro "body.links[].href_url.domain.root_domain in url_shorteners"
  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 ["Romance", "Sexually Explicit Messages"]
  body.previous_threads length_compare "0"
  distinct(body.links, .href_url.domain.root_domain not in ('aka.ms')) length_compare "0"
  distinct(body.links, .href_url.domain.root_domain not in ('aka.ms')) length_compare "3"
  type.inbound eq "true"
   macro "all(body.links)"

Indicators

These rows show field, operator, and value matches.

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

Link: ScreenConnect installer with suspicious relay domain

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

Detects when a link leads to a ConnectWise ScreenConnect installer and references a relay domain that doesn't match sender or organizational domains.

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware
Tactics and techniquesEvasion, Out of band pivot, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • sender.email
  • type

Rule body

type.inbound
and any(body.links,
        strings.ends_with(.href_url.url, ".exe")
        and any(ml.link_analysis(., mode="aggressive").files_downloaded,
                any(file.explode(.),
                    any(.scan.strings.strings,
                        strings.icontains(., "ScreenConnect")
                    )
                    and any(filter(.scan.strings.strings,
                                   strings.icontains(.,
                                                     "h="
                                   ) // relay domain
                                   and strings.icontains(.,
                                                         "k="
                                   ) // encoded encryption key
                            ),
                            any(regex.extract(., 'h=(?P<url>[^&]+)'),
                                strings.parse_url(strings.concat("https://",
                                                                 .named_groups["url"]
                                                  )
                                ).domain.root_domain not in $org_domains
                                and strings.parse_url(strings.concat("https://",
                                                                     .named_groups["url"]
                                                      )
                                ).domain.root_domain != sender.email.domain.root_domain
                            )
                    )
                )
        )
)
and not profile.by_sender_email().any_messages_benign

Detection logic

Scope: inbound message.

Detects when a link leads to a ConnectWise ScreenConnect installer and references a relay domain that doesn't match sender or organizational domains.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.url ends with '.exe'
    • any of ml.link_analysis(., mode='aggressive').files_downloaded where:
      • any of file.explode(.) where all hold:
        • any of .scan.strings.strings where:
          • . contains 'ScreenConnect'
        • any of filter(.scan.strings.strings) where:
          • any of regex.extract(.) where all hold:
            • strings.parse_url(strings.concat('https://', .named_groups['url'])).domain.root_domain not in $org_domains
            • strings.parse_url(strings.concat('https://', .named_groups['url'])).domain.root_domain is not sender.email.domain.root_domain
  3. not:
    • profile.by_sender_email().any_messages_benign

Inspects: body.links, body.links[].href_url.url, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, ml.link_analysis, profile.by_sender_email, regex.extract, strings.concat, strings.ends_with, strings.icontains, strings.parse_url. Reference lists: $org_domains.

Indicators matched (5)

FieldMatchValue
strings.ends_withsuffix.exe
strings.icontainssubstringScreenConnect
strings.icontainssubstringh=
strings.icontainssubstringk=
regex.extractregexh=(?P<url>[^&]+)

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      any(ml.link_analysis(body.links, mode='aggressive').files_downloaded)
        any(file.explode(ml.link_analysis(body.links, mode='aggressive').files_downloaded))
          and
            any(filter(file.explode(ml.link_analysis(body.links, mode='aggressive').files_downloaded).scan.strings.strings))
              any(regex.extract(filter(file.explode(ml.link_analysis(body.links, mode='aggressive').files_downloaded).scan.strings.strings)))
                and
                  strings.parse_url func_call "strings.parse_url(strings.concat('https://', regex.extract(filter(file.explode(ml.link_analysis(body.links[], mode='aggressive').files_downloaded[])[].scan.strings.strings)[])[].named_groups['url'])).domain.root_domain != sender.email.domain.root_domain"
                  strings.parse_url func_call "strings.parse_url(strings.concat('https://', regex.extract(filter(file.explode(ml.link_analysis(body.links[], mode='aggressive').files_downloaded[])[].scan.strings.strings)[])[].named_groups['url'])).domain.root_domain not in org_domains"
            any(file.explode(ml.link_analysis(body.links, mode='aggressive').files_downloaded).scan.strings.strings)
              file.explode(ml.link_analysis(body.links, mode='aggressive').files_downloaded).scan.strings.strings contains "ScreenConnect"
      body.links.href_url.url ends_with ".exe"
  not
    profile.by_sender_email func_call "profile.by_sender_email().any_messages_benign"
  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"

Link: ScreenConnect remote access tool delivery with unattended guest access

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

Detects inbound messages containing ScreenConnect links that direct recipients to download a Guest Access installer (.msi or .exe). The links use ScreenConnect's integration parameters specifying Guest session type and Access mode, indicating unsolicited remote access tool deployment. Lures observed include fake invoices, payment proofs, event invitations, and social gathering notifications — often urging recipients to open the link on a Windows desktop and install the downloaded file.

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware
Tactics and techniquesSocial engineering, Out of band pivot

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
// at least one link to screenconnect
and length(filter(body.links,
                  .href_url.domain.root_domain == "screenconnect.com"
                  // exclude tenant_domains (if the customer users screenconnect and has their own subdomain)
                  and .href_url.domain.domain not in $tenant_domains
           )
) > 0
// all the screenconnect links include an msi/exe with Guesst Access
and all(filter(body.links, .href_url.domain.root_domain == "screenconnect.com"),
        strings.iends_with(.href_url.path, '.msi', '.exe')
        // https://docs.connectwise.com/ScreenConnect_Documentation/Developers/Integration_guide
        // e = SessionType. Support, Meet, or Access
        and strings.icontains(.href_url.query_params, "e=Access")
        // y = ProcessType (host vs guest)
        and strings.icontains(.href_url.query_params, "y=Guest")
)

Detection logic

Scope: inbound message.

Detects inbound messages containing ScreenConnect links that direct recipients to download a Guest Access installer (.msi or .exe). The links use ScreenConnect's integration parameters specifying Guest session type and Access mode, indicating unsolicited remote access tool deployment. Lures observed include fake invoices, payment proofs, event invitations, and social gathering notifications — often urging recipients to open the link on a Windows desktop and install the downloaded file.

  1. inbound message
  2. length(filter(body.links, .href_url.domain.root_domain == 'screenconnect.com' and .href_url.domain.domain not in $tenant_domains)) > 0
  3. all of filter(body.links) where all hold:
    • .href_url.path ends with any of 2 patterns
      • .msi
      • .exe
    • .href_url.query_params contains 'e=Access'
    • .href_url.query_params contains 'y=Guest'

Inspects: body.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, type.inbound. Sensors: strings.icontains, strings.iends_with. Reference lists: $tenant_domains.

Indicators matched (5)

FieldMatchValue
body.links[].href_url.domain.root_domainequalsscreenconnect.com
strings.iends_withsuffix.msi
strings.iends_withsuffix.exe
strings.icontainssubstringe=Access
strings.icontainssubstringy=Guest

Stages and Predicates

Stage 1: mql_rule

and
  filter(body.links, .href_url.domain.root_domain == 'screenconnect.com' and .href_url.domain.domain not in $tenant_domains) length_compare "0"
  type.inbound eq "true"
   macro "all(filter(body.links))"

Indicators

These rows show field, operator, and value matches.

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

Link: Scribd fullscreen link from suspicious sender

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

Detects messages containing Scribd links with the fullscreen parameter from senders with no prior benign communication or recent history.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesFree file host, Social engineering, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and length(body.links) < 10
and any(body.links,
        (
          .href_url.domain.root_domain == "scribd.com"
          or strings.icontains(.href_url.query_params, 'scribd.com')
          or strings.icontains(.href_url.query_params, 'scribd%2ecom')
          or strings.icontains(.href_url.query_params, 'scribd%252ecom')
        )
        and strings.icontains(.href_url.fragment, 'fullscreen')
)
and not profile.by_sender_email().any_messages_benign

Detection logic

Scope: inbound message.

Detects messages containing Scribd links with the fullscreen parameter from senders with no prior benign communication or recent history.

  1. inbound message
  2. length(body.links) < 10
  3. any of body.links where all hold:
    • any of:
      • .href_url.domain.root_domain is 'scribd.com'
      • .href_url.query_params contains 'scribd.com'
      • .href_url.query_params contains 'scribd%2ecom'
      • .href_url.query_params contains 'scribd%252ecom'
    • .href_url.fragment contains 'fullscreen'
  4. not:
    • profile.by_sender_email().any_messages_benign

Inspects: body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.fragment, body.links[].href_url.query_params, type.inbound. Sensors: profile.by_sender_email, strings.icontains.

Indicators matched (5)

FieldMatchValue
body.links[].href_url.domain.root_domainequalsscribd.com
strings.icontainssubstringscribd.com
strings.icontainssubstringscribd%2ecom
strings.icontainssubstringscribd%252ecom
strings.icontainssubstringfullscreen

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        body.links.href_url.domain.root_domain eq "scribd.com"
        body.links.href_url.query_params contains "scribd%252ecom"
        body.links.href_url.query_params contains "scribd%2ecom"
        body.links.href_url.query_params contains "scribd.com"
      body.links.href_url.fragment contains "fullscreen"
  not
    profile.by_sender_email func_call "profile.by_sender_email().any_messages_benign"
  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"

Link: Secure SharePoint file share from new or unusual sender

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

This ASR rule detects the use of secure SharePoint links which require recipient verifcation before allowing access to the shared file. This has been observed as a method of evading automated analysis of the shared files' content.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesFree file host, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
// SharePoint email indicators
and strings.like(body.current_thread.text,
                 "*shared a file with you*",
                 "*shared with you*",
                 "*invited you to access a file*"
)
and strings.icontains(subject.subject, "shared")
// the Sharepoint file has been "Protected"
and any([body.plain.raw, body.current_thread.text],
        strings.icontains(.,
                          "This link only works for the direct recipients of this message"
        )
)
and any(body.links, .href_url.domain.root_domain == "sharepoint.com")

// sender is uncommon
and (
  (
    profile.by_sender_email().prevalence in ("new", "rare", "outlier")
    and not profile.by_sender_email().solicited
  )
  // or the reply-to address has never sent an email to the org
  or (
    sender.email.domain.root_domain == "sharepointonline.com"
    and beta.profile.by_reply_to().prevalence == "new"
  )
  // or the message contains suspect language
  or (regex.icontains(body.current_thread.text, '(kindly)'))
)

Detection logic

Scope: inbound message.

This ASR rule detects the use of secure SharePoint links which require recipient verifcation before allowing access to the shared file. This has been observed as a method of evading automated analysis of the shared files' content.

  1. inbound message
  2. body.current_thread.text matches any of 3 patterns
    • *shared a file with you*
    • *shared with you*
    • *invited you to access a file*
  3. subject.subject contains 'shared'
  4. any of [body.plain.raw, body.current_thread.text] where:
    • . contains 'This link only works for the direct recipients of this message'
  5. any of body.links where:
    • .href_url.domain.root_domain is 'sharepoint.com'
  6. any of:
    • all of:
      • profile.by_sender_email().prevalence in ('new', 'rare', 'outlier')
      • not:
        • profile.by_sender_email().solicited
    • all of:
      • sender.email.domain.root_domain is 'sharepointonline.com'
      • beta.profile.by_reply_to().prevalence is 'new'
    • body.current_thread.text matches '(kindly)'

Inspects: body.current_thread.text, body.links, body.links[].href_url.domain.root_domain, body.plain.raw, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: beta.profile.by_reply_to, profile.by_sender_email, regex.icontains, strings.icontains, strings.like.

Indicators matched (8)

FieldMatchValue
strings.likesubstring*shared a file with you*
strings.likesubstring*shared with you*
strings.likesubstring*invited you to access a file*
strings.icontainssubstringshared
strings.icontainssubstringThis link only works for the direct recipients of this message
body.links[].href_url.domain.root_domainequalssharepoint.com
sender.email.domain.root_domainequalssharepointonline.com
regex.icontainsregex(kindly)

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      not
        profile.by_sender_email func_call "profile.by_sender_email().solicited"
      profile.by_sender_email func_call "profile.by_sender_email().prevalence in (new, rare, outlier)"
    and
      beta.profile.by_reply_to func_call "beta.profile.by_reply_to().prevalence == new"
      sender.email.domain.root_domain eq "sharepointonline.com"
    body.current_thread.text regex_match "(kindly)"
  any([body.plain.raw, body.current_thread.text])
    [body.plain.raw, body.current_thread.text] contains "This link only works for the direct recipients of this message"
  or
    body.current_thread.text match "invited you to access a file"
    body.current_thread.text match "shared a file with you"
    body.current_thread.text match "shared with you"
  any(body.links)
    body.links.href_url.domain.root_domain eq "sharepoint.com"
  subject.subject contains "shared"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Self-sender credential theft with configuration placeholder

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

Detects messages where the sender and recipient are the same address, containing credential theft language and links with configuration placeholder text indicating a phishing lure.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • recipients
  • recipients.to[0]
  • sender.email
  • type

Rule body

type.inbound
// self sender
and length(recipients.to) == 1
and sender.email.email == recipients.to[0].email.email
and any(body.current_thread.links,
        strings.contains(ml.link_analysis(., mode="aggressive").final_dom.raw,
                         '/*──── CONFIG: Replace with your lure URL ────*/'
        )
)

Detection logic

Scope: inbound message.

Detects messages where the sender and recipient are the same address, containing credential theft language and links with configuration placeholder text indicating a phishing lure.

  1. inbound message
  2. length(recipients.to) is 1
  3. sender.email.email is recipients.to[0].email.email
  4. any of body.current_thread.links where:
    • ml.link_analysis(., mode='aggressive').final_dom.raw contains '/*──── CONFIG: Replace with your lure URL ────*/'

Inspects: body.current_thread.links, recipients.to, recipients.to[0].email.email, sender.email.email, type.inbound. Sensors: ml.link_analysis, strings.contains.

Indicators matched (1)

FieldMatchValue
strings.containssubstring/*──── CONFIG: Replace with your lure URL ────*/

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    ml.link_analysis(body.current_thread.links[], mode='aggressive').final_dom.raw contains "/*──── CONFIG: Replace with your lure URL ────*/"
  recipients.to length_compare "1"
  sender.email.email cross_field_compare "recipients.to[0].email.email"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
sender.email.emailcross_field_compare
  • recipients.to[0].email.email transforms: op:eq
field:"sender.email.email" kind:cross_field_compare value:"recipients.to[0].email.email"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link: Self-sender with IP geolocation check and suspicious link behavior

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

Detects messages where the sender and recipient are the same address that access IP geolocation services (ipinfo.io) and exhibit suspicious behavior, such as randomization scripting or confirmed credential harvesting indicators.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • headers.return_path
  • recipients
  • recipients.to[0]
  • sender.email
  • type

Rule body

type.inbound
// self sender
and (
  length(recipients.to) == 1
  and recipients.to[0].email.email == sender.email.email
)
and 0 < length(body.current_thread.links) < 10
and any(filter(body.current_thread.links,
               .href_url.domain.root_domain != sender.email.domain.root_domain
        ),
        any(ml.link_analysis(.).unique_urls_accessed,
            .url == 'https://ipinfo.io/json'
        )
)
and not headers.return_path.domain.root_domain == "salesforce.com"

Detection logic

Scope: inbound message.

Detects messages where the sender and recipient are the same address that access IP geolocation services (ipinfo.io) and exhibit suspicious behavior, such as randomization scripting or confirmed credential harvesting indicators.

  1. inbound message
  2. all of:
    • length(recipients.to) is 1
    • recipients.to[0].email.email is sender.email.email
  3. all of:
    • length(body.current_thread.links) > 0
    • length(body.current_thread.links) < 10
  4. any of filter(body.current_thread.links) where:
    • any of ml.link_analysis(.).unique_urls_accessed where:
      • .url is 'https://ipinfo.io/json'
  5. not:
    • headers.return_path.domain.root_domain is 'salesforce.com'

Inspects: body.current_thread.links, body.current_thread.links[].href_url.domain.root_domain, headers.return_path.domain.root_domain, recipients.to, recipients.to[0].email.email, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: ml.link_analysis.

Indicators matched (1)

FieldMatchValue
ml.link_analysis(filter(body.current_thread.links)[]).unique_urls_accessed[].urlequalshttps://ipinfo.io/json

Stages and Predicates

Stage 1: mql_rule

and
  any(filter(body.current_thread.links))
    any(ml.link_analysis(filter(body.current_thread.links)).unique_urls_accessed)
      ml.link_analysis(filter(body.current_thread.links)).unique_urls_accessed.url eq "https://ipinfo.io/json"
  not
    headers.return_path.domain.root_domain eq "salesforce.com"
  body.current_thread.links length_compare "0"
  body.current_thread.links length_compare "10"
  recipients.to length_compare "1"
  recipients.to[0].email.email cross_field_compare "sender.email.email"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.return_path.domain.root_domaineqsalesforce.comexcludes:headers.return_path.domain.root_domain field:"headers.return_path.domain.root_domain" value:"salesforce.com"

Indicators

These rows show field, operator, and value matches.

Link: Self-sender with sender org in subject and credential theft indicator

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

Detects messages where the sender and recipient are the same email address, containing organizational names in the subject, credential theft language with high confidence, and suspicious links. These messages often bypass traditional security measures by appearing to come from the recipient themselves.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • body.html
  • recipients
  • recipients.to[0]
  • sender.email
  • subject
  • type

Rule body

type.inbound
// self sender behavior
and length(recipients.to) == 1
and length(recipients.cc) == 0
and sender.email.email == recipients.to[0].email.email

// not self sender from the org_domain, this rule is not going to detect spoofed domains to limit FPs caused by various email auth issues.
and not sender.email.domain.domain in $org_domains
and profile.by_sender_email().prevalence == "new"

// org name in the subject, removing the subject from NLU to prevent the org being extracted from the subject
and any(filter(ml.nlu_classifier(body.current_thread.text, subject="").entities,
               .name == "org"
               and .text != sender.email.domain.sld
               and .text != sender.email.domain.domain
        ),
        // not an icontains, make it an exact match
        strings.contains(subject.base, .text)
)
// must contain a link
and 0 < length(body.current_thread.links) < 20

// cred theft
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft" and .confidence == "high"
)
// all attachments are inline images or there are 0 attachments
and (
  length(attachments) == 0
  // there are only image attachments and all image attachments are served inline
  or (
    length(attachments) > 0
    and (
      all(attachments,
          .file_type in $file_types_images
          // all images are embedded in the html
          and strings.icontains(body.html.raw,
                                strings.concat('src="cid:', .content_id)
          )
      )
    )
  )
)

Detection logic

Scope: inbound message.

Detects messages where the sender and recipient are the same email address, containing organizational names in the subject, credential theft language with high confidence, and suspicious links. These messages often bypass traditional security measures by appearing to come from the recipient themselves.

  1. inbound message
  2. length(recipients.to) is 1
  3. length(recipients.cc) is 0
  4. sender.email.email is recipients.to[0].email.email
  5. not:
    • sender.email.domain.domain in $org_domains
  6. profile.by_sender_email().prevalence is 'new'
  7. any of filter(...) where:
    • strings.contains(subject.base)
  8. all of:
    • length(body.current_thread.links) > 0
    • length(body.current_thread.links) < 20
  9. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name is 'cred_theft'
    • .confidence is 'high'
  10. any of:
    • length(attachments) is 0
    • all of:
      • length(attachments) > 0
      • all of attachments where all hold:
        • .file_type in $file_types_images
        • strings.icontains(body.html.raw)

Inspects: attachments[].content_id, attachments[].file_type, body.current_thread.links, body.current_thread.text, body.html.raw, recipients.cc, recipients.to, recipients.to[0].email.email, sender.email.domain.domain, sender.email.domain.sld, sender.email.email, subject.base, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender_email, strings.concat, strings.contains, strings.icontains. Reference lists: $file_types_images, $org_domains.

Indicators matched (3)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text, subject='').entities[].nameequalsorg
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      attachments length_compare "0"
       macro "all(attachments)"
    attachments length_compare "0"
  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(filter(...))
    strings.contains func_call "strings.contains(subject.base)"
  not
     macro "sender.email.domain.domain in org_domains"
  body.current_thread.links length_compare "0"
  body.current_thread.links length_compare "20"
  profile.by_sender_email func_call "profile.by_sender_email().prevalence == new"
  recipients.cc length_compare "0"
  recipients.to length_compare "1"
  sender.email.email cross_field_compare "recipients.to[0].email.email"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
sender.email.emailcross_field_compare
  • recipients.to[0].email.email transforms: op:eq
field:"sender.email.email" kind:cross_field_compare value:"recipients.to[0].email.email"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link: Self-sent message with quarterly document review request

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

Detects messages sent from a user to themselves containing a link with quarterly indicators (q1_, q2_, q3_, q4_) and specific document review language requesting urgent feedback.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Credential Phishing
Tactics and techniquesSocial engineering, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • recipients
  • recipients.to[0]
  • sender.email
  • subject
  • type

Rule body

type.inbound
// self sender
and length(recipients.to) == 1
and length(recipients.cc) == 0
and length(recipients.bcc) == 0
and (
  sender.email.email == recipients.to[0].email.email
  or recipients.to[0].email.domain.valid == false
)
// first link is not related to the sender via sld (to account for orgs that have multiple tlds)
and body.current_thread.links[0].href_url.domain.sld != sender.email.domain.sld
and regex.icontains(body.current_thread.links[0].display_text, 'q[1-4][ _]20')
and (
  strings.contains(body.current_thread.links[0].display_text, '#')
  or strings.contains(subject.base, '#')
  or regex.contains(subject.base, '^[^a-z]*$')
)

Detection logic

Scope: inbound message.

Detects messages sent from a user to themselves containing a link with quarterly indicators (q1_, q2_, q3_, q4_) and specific document review language requesting urgent feedback.

  1. inbound message
  2. length(recipients.to) is 1
  3. length(recipients.cc) is 0
  4. length(recipients.bcc) is 0
  5. any of:
    • sender.email.email is recipients.to[0].email.email
    • recipients.to[0].email.domain.valid is False
  6. body.current_thread.links[0].href_url.domain.sld is not sender.email.domain.sld
  7. body.current_thread.links[0].display_text matches 'q[1-4][ _]20'
  8. any of:
    • body.current_thread.links[0].display_text contains '#'
    • subject.base contains '#'
    • subject.base matches '^[^a-z]*$'

Inspects: body.current_thread.links[0].display_text, body.current_thread.links[0].href_url.domain.sld, recipients.bcc, recipients.cc, recipients.to, recipients.to[0].email.domain.valid, recipients.to[0].email.email, sender.email.domain.sld, sender.email.email, subject.base, type.inbound. Sensors: regex.contains, regex.icontains, strings.contains.

Indicators matched (3)

FieldMatchValue
regex.icontainsregexq[1-4][ _]20
strings.containssubstring#
regex.containsregex^[^a-z]*$

Stages and Predicates

Stage 1: mql_rule

and
  or
    body.current_thread.links[0].display_text contains "#"
    subject.base contains "#"
    subject.base regex_match "^[^a-z]*$"
  or
    recipients.to[0].email.domain.valid eq "false"
    sender.email.email cross_field_compare "recipients.to[0].email.email"
  body.current_thread.links[0].display_text regex_match "q[1-4][ _]20"
  body.current_thread.links[0].href_url.domain.sld cross_field_compare "sender.email.domain.sld"
  recipients.bcc length_compare "0"
  recipients.cc length_compare "0"
  recipients.to length_compare "1"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: SharePoint filename matches org name

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

Detects messages claiming to share files via SharePoint or OneDrive where the shared file name pattern matches the organizational naming pattern, indicating potential abuse of legitimate file sharing services to impersonate organizations.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Employee, 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(subject.subject, "*shared*", "*invit*")
and strings.ilike(body.current_thread.text,
                  "*shared a file with you*",
                  "*shared with you*",
                  "*invited you to access a file*"
)
and not strings.ilike(body.current_thread.text, "invited you to edit")
and (
  // use the display text of the link to determine the name of the file
  any(filter(body.current_thread.links,
             .href_url.domain.domain not in $tenant_domains
             and (
               .href_url.domain.root_domain == "sharepoint.com"
               or .href_url.domain.root_domain == "1drv.ms"
               // handle urls with mimecast rewriting
               or (
                 .href_url.domain.root_domain == 'mimecastprotect.com'
                 and strings.icontains(.href_url.query_params,
                                       '.sharepoint.com'
                 )
               )
             )
             and .display_text != "Open"
      ),
      .display_text =~ sender.email.domain.sld
      or any(regex.extract(body.current_thread.text,
                           "generated through (?P<org_name>[^']+)'s use"
             ),
             // the document name is the same as the org name as determined by the footer
             // this checks that the display_text starts with the org_name
             strings.istarts_with(.named_groups["org_name"], ..display_text)

             // this checks that the org_name is a substring of the display_text
             // it is in effect the "reverse" of the above check
             or (
               (
                 strings.istarts_with(..display_text, .named_groups["org_name"])
                 or strings.iends_with(..display_text,
                                       .named_groups["org_name"]
                 )
               )
               and (
                 length(.named_groups["org_name"]) / (
                   length(..display_text) * 1.0
                 )
               ) > 0.45
             )
      )
  )
)

Detection logic

Scope: inbound message.

Detects messages claiming to share files via SharePoint or OneDrive where the shared file name pattern matches the organizational naming pattern, indicating potential abuse of legitimate file sharing services to impersonate organizations.

  1. inbound message
  2. subject.subject matches any of 2 patterns
    • *shared*
    • *invit*
  3. body.current_thread.text matches any of 3 patterns
    • *shared a file with you*
    • *shared with you*
    • *invited you to access a file*
  4. not:
    • body.current_thread.text matches 'invited you to edit'
  5. any of filter(body.current_thread.links) where any holds:
    • .display_text is sender.email.domain.sld
    • any of regex.extract(body.current_thread.text) where any holds:
      • strings.istarts_with(.named_groups['org_name'])
      • all of:
        • any of:
          • strings.istarts_with(.display_text)
          • strings.iends_with(.display_text)
        • length(.named_groups['org_name']) / length(.display_text) * 1.0 > 0.45

Inspects: body.current_thread.links, body.current_thread.links[].display_text, body.current_thread.links[].href_url.domain.domain, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.links[].href_url.query_params, body.current_thread.text, sender.email.domain.sld, subject.subject, type.inbound. Sensors: regex.extract, strings.icontains, strings.iends_with, strings.ilike, strings.istarts_with. Reference lists: $tenant_domains.

Indicators matched (10)

FieldMatchValue
strings.ilikesubstring*shared*
strings.ilikesubstring*invit*
strings.ilikesubstring*shared a file with you*
strings.ilikesubstring*shared with you*
strings.ilikesubstring*invited you to access a file*
body.current_thread.links[].href_url.domain.root_domainequalssharepoint.com
body.current_thread.links[].href_url.domain.root_domainequals1drv.ms
body.current_thread.links[].href_url.domain.root_domainequalsmimecastprotect.com
strings.icontainssubstring.sharepoint.com
regex.extractregexgenerated through (?P<org_name>[^']+)'s use

Stages and Predicates

Stage 1: mql_rule

and
  any(filter(body.current_thread.links))
    or
      any(regex.extract(body.current_thread.text))
        or
          and
            or
              strings.iends_with func_call "strings.iends_with(filter(body.current_thread.links)[].display_text)"
              strings.istarts_with func_call "strings.istarts_with(filter(body.current_thread.links)[].display_text)"
             macro "(length(regex.extract(body.current_thread.text)[].named_groups['org_name']) / (length(filter(body.current_thread.links)[].display_text) * 1.0)) > 0.45"
          strings.istarts_with func_call "strings.istarts_with(regex.extract(body.current_thread.text)[].named_groups['org_name'])"
      filter(body.current_thread.links).display_text cross_field_compare "sender.email.domain.sld"
  not
    body.current_thread.text eq "invited you to edit"
  or
    body.current_thread.text match "invited you to access a file"
    body.current_thread.text match "shared a file with you"
    body.current_thread.text match "shared with you"
  or
    subject.subject match "invit"
    subject.subject match "shared"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
body.current_thread.texteqinvited you to editexcludes:body.current_thread.text field:"body.current_thread.text" value:"invited you to edit"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textwildcard
  • *invited you to access a file*
  • *shared a file with you*
  • *shared with you*
field:"body.current_thread.text" kind:wildcard
subject.subjectwildcard
  • *invit*
  • *shared*
field:"subject.subject" kind:wildcard
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link: SharePoint files shared from GoDaddy federated tenants

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

This matches on inbound Shared File notiifcation emails from Microsoft, where any link to SharePoint contains a default GoDaddy Federated Tenant Name. These have been observed being frequently abused to send credential phishing campaigns.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • headers
  • subject
  • type

Rule body

type.inbound
// Matches the message id observed. DKIM/SPF domains can be custom and therefore are unpredictable.
and strings.starts_with(headers.message_id, '<Share-')
and strings.ends_with(headers.message_id, '@odspnotify>')

// subject matches the default "shared <filename> with you" format
and strings.ends_with(subject.subject, ' with you')

// any of the links are the default netorgft name from GoDaddy
and any(body.links,
        // Default GoDaddy tenant names
        strings.starts_with(.href_url.domain.subdomain, 'netorg')
        and .href_url.domain.root_domain == "sharepoint.com"
)

// and sender has never had email sent to them
and not profile.by_sender().solicited

// and there haven't been any FPs reported for the sender
and not profile.by_sender().any_messages_benign

Detection logic

Scope: inbound message.

This matches on inbound Shared File notiifcation emails from Microsoft, where any link to SharePoint contains a default GoDaddy Federated Tenant Name. These have been observed being frequently abused to send credential phishing campaigns.

  1. inbound message
  2. headers.message_id starts with '<Share-'
  3. headers.message_id ends with '@odspnotify>'
  4. subject.subject ends with ' with you'
  5. any of body.links where all hold:
    • .href_url.domain.subdomain starts with 'netorg'
    • .href_url.domain.root_domain is 'sharepoint.com'
  6. not:
    • profile.by_sender().solicited
  7. not:
    • profile.by_sender().any_messages_benign

Inspects: body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.subdomain, headers.message_id, subject.subject, type.inbound. Sensors: profile.by_sender, strings.ends_with, strings.starts_with.

Indicators matched (5)

FieldMatchValue
strings.starts_withprefix<Share-
strings.ends_withsuffix@odspnotify>
strings.ends_withsuffix with you
strings.starts_withprefixnetorg
body.links[].href_url.domain.root_domainequalssharepoint.com

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      body.links.href_url.domain.root_domain eq "sharepoint.com"
      body.links.href_url.domain.subdomain starts_with "netorg"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  not
    profile.by_sender func_call "profile.by_sender().solicited"
  headers.message_id ends_with "@odspnotify>"
  headers.message_id starts_with "<Share-"
  subject.subject ends_with " with you"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: SharePoint OneNote or PDF link with self sender behavior

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

Detects messages where the sender and recipient are the same address, containing SharePoint links to OneNote or PDF files, with minimal attachments and non-standard message IDs indicating potential abuse of SharePoint services for malicious purposes.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Free file host, OneNote, PDF

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • headers
  • recipients
  • recipients.to[0]
  • sender.email
  • type

Rule body

type.inbound
// self sender
and length(recipients.to) == 1
and recipients.to[0].email.email == sender.email.email
// single link to sharepoint
and length(filter(body.current_thread.links,
                  .href_url.domain.root_domain == 'sharepoint.com'
                  // it is either a OneNote or PDF file, or unknown
                  and regex.icontains(.href_url.path,
                                      '\/:[obu]:\/(?:p|g\/personal)'
                  )
           )
) == 1
// only one link to sharepoint
and length(filter(body.current_thread.links,
                  .href_url.domain.root_domain == 'sharepoint.com'
           )
) == 1
// not sent via sharepoint
and not strings.starts_with(headers.message_id, '<Share-')
and not strings.ends_with(headers.message_id, '@odspnotify>')
// 0 or 1 attachments (this reduces FPs which had many attachments)
and length(attachments) - length(filter(attachments,
                                        strings.contains(body.html.raw,
                                                         strings.concat('src="cid:',
                                                                        .content_id
                                                         )
                                        )
                                 )
) <= 1

Detection logic

Scope: inbound message.

Detects messages where the sender and recipient are the same address, containing SharePoint links to OneNote or PDF files, with minimal attachments and non-standard message IDs indicating potential abuse of SharePoint services for malicious purposes.

  1. inbound message
  2. length(recipients.to) is 1
  3. recipients.to[0].email.email is sender.email.email
  4. length(filter(body.current_thread.links, .href_url.domain.root_domain == 'sharepoint.com' and regex.icontains(.href_url.path, '\\/:[obu]:\\/(?:p|g\\/personal)'))) is 1
  5. length(filter(body.current_thread.links, .href_url.domain.root_domain == 'sharepoint.com')) is 1
  6. not:
    • headers.message_id starts with '<Share-'
  7. not:
    • headers.message_id ends with '@odspnotify>'
  8. length(attachments) - length(filter(attachments, strings.contains(body.html.raw, strings.concat('src="cid:', .content_id)))) ≤ 1

Inspects: body.current_thread.links, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.links[].href_url.path, headers.message_id, recipients.to, recipients.to[0].email.email, sender.email.email, type.inbound. Sensors: regex.icontains, strings.ends_with, strings.starts_with.

Indicators matched (2)

FieldMatchValue
body.current_thread.links[].href_url.domain.root_domainequalssharepoint.com
regex.icontainsregex\/:[obu]:\/(?:p|g\/personal)

Stages and Predicates

Stage 1: mql_rule

and
  not
    headers.message_id ends_with "@odspnotify>"
  not
    headers.message_id starts_with "<Share-"
  filter(body.current_thread.links, .href_url.domain.root_domain == 'sharepoint.com' and regex.icontains(.href_url.path, '\\/:[obu]:\\/(?:p|g\\/personal)')) length_compare "1"
  filter(body.current_thread.links, .href_url.domain.root_domain == 'sharepoint.com') length_compare "1"
  recipients.to length_compare "1"
  recipients.to[0].email.email cross_field_compare "sender.email.email"
  type.inbound eq "true"
   macro "(length(attachments) - length(filter(attachments, strings.contains(body.html.raw, strings.concat('src=\"cid:', .content_id))))) <= 1"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
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-"

Indicators

These rows show field, operator, and value matches.

Link: Shortened URL with fragment matching subject

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

Detects messages containing shortened links where the URL fragment appears in the email subject line, indicating potential targeted link tracking or social engineering tactics.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, BEC/Fraud
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • subject
  • type

Rule body

type.inbound
and any(body.current_thread.links,
        .href_url.domain.root_domain in $url_shorteners
        and .href_url.fragment is not null
        and length(.href_url.fragment) > 5
        and strings.contains(subject.subject, .href_url.fragment)
)

Detection logic

Scope: inbound message.

Detects messages containing shortened links where the URL fragment appears in the email subject line, indicating potential targeted link tracking or social engineering tactics.

  1. inbound message
  2. any of body.current_thread.links where all hold:
    • .href_url.domain.root_domain in $url_shorteners
    • .href_url.fragment is set
    • length(.href_url.fragment) > 5
    • strings.contains(subject.subject)

Inspects: body.current_thread.links, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.links[].href_url.fragment, subject.subject, type.inbound. Sensors: strings.contains. Reference lists: $url_shorteners.

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    and
      body.current_thread.links.href_url.fragment is_not_null
      body.current_thread.links.href_url.fragment length_compare "5"
      strings.contains func_call "strings.contains(subject.subject)"
       macro "body.current_thread.links[].href_url.domain.root_domain in url_shorteners"
  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"

Link: Squarespace infrastructure abuse

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

Detects inbound messages containing exactly one Squarespace tracking link but lacking authentic Squarespace email headers and sender patterns.

Threat classification

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

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

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • headers
  • headers.domains
  • headers.return_path
  • type

Rule body

type.inbound
and any(body.links, .href_url.domain.domain == "engage.squarespace-mail.com")
and length(body.links) < 10
// there is one unique Squarespace Link in the message
and length(distinct(filter(body.links,
                           .href_url.domain.domain == "engage.squarespace-mail.com"
                    ),
                    .href_url.url
           )
) == 1
and not headers.return_path.domain.root_domain == "squarespace-mail.com"
and not any(headers.domains, .root_domain == "squarespace-mail.com")
and profile.by_sender_email().prevalence != "common"

Detection logic

Scope: inbound message.

Detects inbound messages containing exactly one Squarespace tracking link but lacking authentic Squarespace email headers and sender patterns.

  1. inbound message
  2. any of body.links where:
    • .href_url.domain.domain is 'engage.squarespace-mail.com'
  3. length(body.links) < 10
  4. length(distinct(filter(body.links, .href_url.domain.domain == 'engage.squarespace-mail.com'), .href_url.url)) is 1
  5. not:
    • headers.return_path.domain.root_domain is 'squarespace-mail.com'
  6. not:
    • any of headers.domains where:
      • .root_domain is 'squarespace-mail.com'
  7. profile.by_sender_email().prevalence is not 'common'

Inspects: body.links, body.links[].href_url.domain.domain, headers.domains, headers.domains[].root_domain, headers.return_path.domain.root_domain, type.inbound. Sensors: profile.by_sender_email.

Indicators matched (1)

FieldMatchValue
body.links[].href_url.domain.domainequalsengage.squarespace-mail.com

Stages and Predicates

Stage 1: mql_rule

and
  not
    any(headers.domains)
      headers.domains.root_domain eq "squarespace-mail.com"
  any(body.links)
    body.links.href_url.domain.domain eq "engage.squarespace-mail.com"
  not
    headers.return_path.domain.root_domain eq "squarespace-mail.com"
  body.links length_compare "10"
  distinct(filter(body.links, .href_url.domain.domain == 'engage.squarespace-mail.com'), .href_url.url) length_compare "1"
  profile.by_sender_email func_call "profile.by_sender_email().prevalence != common"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
headers.domainsarray_any(no value, null check)excludes:headers.domains
headers.return_path.domain.root_domaineqsquarespace-mail.comexcludes:headers.return_path.domain.root_domain field:"headers.return_path.domain.root_domain" value:"squarespace-mail.com"

Indicators

These rows show field, operator, and value matches.

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

Link: Suspicious Family fragment parameter with encoded recipient data

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

Detects messages containing links with URL fragments that include 'Family' parameters containing base64 or hex encoded email addresses, which may indicate personalized malicious content targeting specific recipients.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Encryption, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        // contains family
        regex.icontains(.href_url.fragment, 'Fa(?:m|rn)ily=')
        // the href_url contains a valid baes64 encoded email
        and (
          any(strings.scan_base64(.href_url.fragment, ignore_padding=true),
              strings.parse_email(.).domain.valid
              // double base64 encoded.. yup
              or any(strings.scan_base64(., ignore_padding=true),
                     strings.parse_email(.).domain.valid
              )
          )
          or any(regex.iextract(.href_url.fragment,
                                'Fa(?:m|rn)ily=$?(?P<email_addy>[^&]+)'
                 ),
                 // plain text email addresses
                 strings.parse_email(.named_groups["email_addy"]).domain.valid
                 // observed hex encoded email address in addition to the base64 encoded ones
                 or (
                   strings.icontains(.named_groups["email_addy"], '40')
                   and strings.icontains(.named_groups["email_addy"], '2e')
                   and length(.named_groups["email_addy"]) % 2 == 0
                 )
                 // sometimes the template messes up
                 or strings.icontains(.named_groups["email_addy"],
                                      'sf_base64_enc'
                 )
                 // messed up in a different way
                 or regex.icontains(.named_groups["email_addy"],
                                    'Fa(?:m|rn)ily'
                 )
          )
        )
)

Detection logic

Scope: inbound message.

Detects messages containing links with URL fragments that include 'Family' parameters containing base64 or hex encoded email addresses, which may indicate personalized malicious content targeting specific recipients.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.fragment matches 'Fa(?:m|rn)ily='
    • any of:
      • any of strings.scan_base64(.href_url.fragment) where any holds:
        • strings.parse_email(.).domain.valid
        • any of strings.scan_base64(.) where:
          • strings.parse_email(.).domain.valid
      • any of regex.iextract(.href_url.fragment) where any holds:
        • strings.parse_email(.named_groups['email_addy']).domain.valid
        • all of:
          • .named_groups['email_addy'] contains '40'
          • .named_groups['email_addy'] contains '2e'
          • length(.named_groups['email_addy']) % 2 is 0
        • .named_groups['email_addy'] contains 'sf_base64_enc'
        • .named_groups['email_addy'] matches 'Fa(?:m|rn)ily'

Inspects: body.links, body.links[].href_url.fragment, type.inbound. Sensors: regex.icontains, regex.iextract, strings.icontains, strings.parse_email, strings.scan_base64.

Indicators matched (6)

FieldMatchValue
regex.icontainsregexFa(?:m|rn)ily=
regex.iextractregexFa(?:m|rn)ily=$?(?P<email_addy>[^&]+)
strings.icontainssubstring40
strings.icontainssubstring2e
strings.icontainssubstringsf_base64_enc
regex.icontainsregexFa(?:m|rn)ily

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        any(regex.iextract(body.links.href_url.fragment))
          or
            and
              regex.iextract(body.links[].href_url.fragment)[].named_groups['email_addy'] contains "2e"
              regex.iextract(body.links[].href_url.fragment)[].named_groups['email_addy'] contains "40"
               macro "(length(regex.iextract(body.links[].href_url.fragment)[].named_groups['email_addy']) % 2) == 0"
            regex.iextract(body.links[].href_url.fragment)[].named_groups['email_addy'] contains "sf_base64_enc"
            regex.iextract(body.links[].href_url.fragment)[].named_groups['email_addy'] regex_match "Fa(?:m|rn)ily"
            strings.parse_email func_call "strings.parse_email(regex.iextract(body.links[].href_url.fragment)[].named_groups['email_addy']).domain.valid"
        any(strings.scan_base64(body.links.href_url.fragment))
          or
            any(strings.scan_base64(strings.scan_base64(body.links.href_url.fragment)))
              strings.parse_email func_call "strings.parse_email(strings.scan_base64(strings.scan_base64(body.links[].href_url.fragment)[])[]).domain.valid"
            strings.parse_email func_call "strings.parse_email(strings.scan_base64(body.links[].href_url.fragment)[]).domain.valid"
      body.links.href_url.fragment regex_match "Fa(?:m|rn)ily="
  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"

Link: Suspicious file retrieval with recipient targeting

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

Detects inbound messages containing links with '/getfile/filefor' URL paths that include the recipient's email address, indicating potential targeted file delivery or credential harvesting.

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

  • body
  • body.links
  • recipients
  • recipients.to[0]
  • type

Rule body

type.inbound
and any(body.links,
        // observed url path
        strings.icontains(.href_url.path, '/getfile/filefor')
        // with email
        and strings.icontains(.href_url.path, recipients.to[0].email.email)
)

Detection logic

Scope: inbound message.

Detects inbound messages containing links with '/getfile/filefor' URL paths that include the recipient's email address, indicating potential targeted file delivery or credential harvesting.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.path contains '/getfile/filefor'
    • strings.icontains(.href_url.path)

Inspects: body.links, body.links[].href_url.path, recipients.to[0].email.email, type.inbound. Sensors: strings.icontains.

Indicators matched (1)

FieldMatchValue
strings.icontainssubstring/getfile/filefor

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      body.links.href_url.path contains "/getfile/filefor"
      strings.icontains func_call "strings.icontains(body.links[].href_url.path)"
  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"

Link: Suspicious go.php redirect with document lure

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

Detects links containing a PHP redirect endpoint with authentication parameters, commonly used in malicious redirects and unauthorized access attempts.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • type

Rule body

type.inbound
and any(body.current_thread.links,
        strings.ends_with(.href_url.path, "go.php")
        and strings.starts_with(.href_url.query_params, "auth=", "c=")
        and strings.count(.href_url.path, "/") == 2
)

Detection logic

Scope: inbound message.

Detects links containing a PHP redirect endpoint with authentication parameters, commonly used in malicious redirects and unauthorized access attempts.

  1. inbound message
  2. any of body.current_thread.links where all hold:
    • .href_url.path ends with 'go.php'
    • .href_url.query_params starts with any of 2 patterns
      • auth=
      • c=
    • strings.count(.href_url.path, '/') is 2

Inspects: body.current_thread.links, body.current_thread.links[].href_url.path, body.current_thread.links[].href_url.query_params, type.inbound. Sensors: strings.count, strings.ends_with, strings.starts_with.

Indicators matched (3)

FieldMatchValue
strings.ends_withsuffixgo.php
strings.starts_withprefixauth=
strings.starts_withprefixc=

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    and
      or
        body.current_thread.links.href_url.query_params starts_with "auth="
        body.current_thread.links.href_url.query_params starts_with "c="
      body.current_thread.links.href_url.path ends_with "go.php"
      strings.count func_call "strings.count(body.current_thread.links[].href_url.path, \"/\") == 2"
  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"

Link: Suspicious HTML structure with subject mirrored in body and single link

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

Detects messages where the subject is mirrored in a styled HTML table element, while containing exactly one link. This structural pattern is indicative of templated lures designed to appear legitimate.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering, Impersonation: Brand

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • subject
  • type

Rule body

type.inbound
and any(html.xpath(body.html,
                   '//body/div//table/tbody/tr//table/tbody/tr/td[contains(@style, "rgb(41, 88, 140)")]/div/b'
        ).nodes,
        subject.base == .display_text
)
and any(html.xpath(body.html,
                   '//body/div//table/tbody/tr//table/tbody/tr/td/div[contains(@style, "margin-top: 12pt")]/div'
        ).nodes,
        strings.icontains(subject.base, .inner_text)
)
and length(html.xpath(body.html,
                      '//body/div//table/tbody/tr//table/tbody/tr/td/div[contains(@style, "margin-top: 12pt")]/div//a'
           ).nodes
) == 1

Detection logic

Scope: inbound message.

Detects messages where the subject is mirrored in a styled HTML table element, while containing exactly one link. This structural pattern is indicative of templated lures designed to appear legitimate.

  1. inbound message
  2. any of html.xpath(body.html, '//body/div//table/tbody/tr//table/tbody/tr/td[contains(@style, "rgb(41, 88, 140)")]/div/b').nodes where:
    • subject.base is .display_text
  3. any of html.xpath(body.html, '//body/div//table/tbody/tr//table/tbody/tr/td/div[contains(@style, "margin-top: 12pt")]/div').nodes where:
    • strings.icontains(subject.base)
  4. length(html.xpath(body.html, '//body/div//table/tbody/tr//table/tbody/tr/td/div[contains(@style, "margin-top: 12pt")]/div//a').nodes) is 1

Inspects: body.html, subject.base, type.inbound. Sensors: html.xpath, strings.icontains.

Stages and Predicates

Stage 1: mql_rule

and
  any(html.xpath(body.html, '//body/div//table/tbody/tr//table/tbody/tr/td/div[contains(@style, "margin-top: 12pt")]/div').nodes)
    strings.icontains func_call "strings.icontains(subject.base)"
  any(html.xpath(body.html, '//body/div//table/tbody/tr//table/tbody/tr/td[contains(@style, "rgb(41, 88, 140)")]/div/b').nodes)
    subject.base cross_field_compare "html.xpath(body.html, '//body/div//table/tbody/tr//table/tbody/tr/td[contains(@style, \"rgb(41, 88, 140)\")]/div/b').nodes.display_text"
  html.xpath(body.html, '//body/div//table/tbody/tr//table/tbody/tr/td/div[contains(@style, "margin-top: 12pt")]/div//a').nodes length_compare "1"
  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"

Link: Suspicious Loom HTML file path

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

Detects inbound messages containing links to Loom HTML files, which may be used to deliver malicious content or bypass security controls through the legitimate Loom 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
  • type

Rule body

type.inbound
and any(body.current_thread.links,
        regex.imatch(.href_url.path, '/loom/[^\/]+\.html')
)

Detection logic

Scope: inbound message.

Detects inbound messages containing links to Loom HTML files, which may be used to deliver malicious content or bypass security controls through the legitimate Loom platform.

  1. inbound message
  2. any of body.current_thread.links where:
    • .href_url.path matches '/loom/[^\\/]+\\.html'

Inspects: body.current_thread.links, body.current_thread.links[].href_url.path, type.inbound. Sensors: regex.imatch.

Indicators matched (1)

FieldMatchValue
regex.imatchregex/loom/[^\/]+\.html

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    body.current_thread.links.href_url.path regex_match "/loom/[^\\/]+\\.html"
  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"

Link: Suspicious recipient with timeout redirect

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

Detects inbound messages sent to self, invalid recipients, or undisclosed recipients containing links that, upon analysis, include a JavaScript setTimeout redirect. This technique delays redirection and appends URL fragments to evade static link inspection.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesScripting, Evasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • recipients
  • recipients.to
  • recipients.to[0]
  • sender.email
  • type

Rule body

type.inbound
and (
  // self sender or invaild recipent domain or local parts match
  (
    length(recipients.to) == 1
    and (
      sender.email.email == recipients.to[0].email.email
      or recipients.to[0].email.domain.valid == false
      or sender.email.local_part == recipients.to[0].email.local_part
    )
  )
  // no recipients defined
  or (
    (
      length(recipients.to) == 0
      or all(recipients.to, .email.domain.valid == false)
    )
    and length(recipients.cc) == 0
    and length(recipients.bcc) == 0
  )
)
and 0 < length(body.current_thread.links) < 10
and any(body.current_thread.links,
        any(html.xpath(ml.link_analysis(., mode="aggressive").final_dom,
                       "//script"
            ).nodes,
            strings.istarts_with(.raw,
                                 '<script>setTimeout(function(){window.location="'
            )
            and strings.iends_with(.raw, '"+location.hash},3000)</script>')
        )
)

Detection logic

Scope: inbound message.

Detects inbound messages sent to self, invalid recipients, or undisclosed recipients containing links that, upon analysis, include a JavaScript setTimeout redirect. This technique delays redirection and appends URL fragments to evade static link inspection.

  1. inbound message
  2. any of:
    • all of:
      • length(recipients.to) is 1
      • any of:
        • sender.email.email is recipients.to[0].email.email
        • recipients.to[0].email.domain.valid is False
        • sender.email.local_part is recipients.to[0].email.local_part
    • all of:
      • any of:
        • length(recipients.to) is 0
        • all of recipients.to where:
          • .email.domain.valid is False
      • length(recipients.cc) is 0
      • length(recipients.bcc) is 0
  3. all of:
    • length(body.current_thread.links) > 0
    • length(body.current_thread.links) < 10
  4. any of body.current_thread.links where:
    • any of html.xpath(ml.link_analysis(., mode='aggressive').final_dom, '//script').nodes where all hold:
      • .raw starts with '<script>setTimeout(function(){window.location="'
      • .raw ends with '"+location.hash},3000)</script>'

Inspects: body.current_thread.links, recipients.bcc, recipients.cc, recipients.to, recipients.to[0].email.domain.valid, recipients.to[0].email.email, recipients.to[0].email.local_part, recipients.to[].email.domain.valid, sender.email.email, sender.email.local_part, type.inbound. Sensors: html.xpath, ml.link_analysis, strings.iends_with, strings.istarts_with.

Indicators matched (2)

FieldMatchValue
strings.istarts_withprefix<script>setTimeout(function(){window.location="
strings.iends_withsuffix"+location.hash},3000)</script>

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    any(html.xpath(ml.link_analysis(body.current_thread.links, mode='aggressive').final_dom, '//script').nodes)
      and
        html.xpath(ml.link_analysis(body.current_thread.links[], mode='aggressive').final_dom, '//script').nodes[].raw ends_with "\"+location.hash},3000)</script>"
        html.xpath(ml.link_analysis(body.current_thread.links[], mode='aggressive').final_dom, '//script').nodes[].raw starts_with "<script>setTimeout(function(){window.location=\""
  or
    and
      or
        recipients.to length_compare "0"
         macro "all(recipients.to)"
      recipients.bcc length_compare "0"
      recipients.cc length_compare "0"
    and
      or
        recipients.to[0].email.domain.valid eq "false"
        sender.email.email cross_field_compare "recipients.to[0].email.email"
        sender.email.local_part cross_field_compare "recipients.to[0].email.local_part"
      recipients.to length_compare "1"
  body.current_thread.links length_compare "0"
  body.current_thread.links length_compare "10"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Suspicious SharePoint document name

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

The detection rule is intended to match on emails sent from SharePoint indicating a shared file to the recipient that contain suspicious content within the document name. The Link display text is leveraged to identify the name of the shared file.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesFree file host, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
and strings.ilike(subject.subject, "*shared*", "*invit*")
and strings.ilike(body.current_thread.text,
                  "*shared a file with you*",
                  "*shared with you*",
                  "*invited you to access a file*"
)
and not strings.ilike(body.current_thread.text, "invited you to edit")
and (
  // use the display text of the link to determine the name of the file
  any(filter(body.links,
             (
               .href_url.domain.root_domain == "sharepoint.com"
               or .href_url.domain.root_domain == "1drv.ms"
               // handle urls with mimecast rewriting
               or (
                 .href_url.domain.root_domain == 'mimecastprotect.com'
                 and strings.icontains(.href_url.query_params,
                                       '.sharepoint.com'
                 )
               )
             )
             and .display_text != "Open"
             and not .href_url.domain.domain in $tenant_domains
      ),

      // the file name does not include lowercase letters, while allowing for non letter chars
      regex.match(.display_text, '^[^a-z]+$')

      // file sharing service references
      or strings.icontains(.display_text, 'dropbox')
      or strings.icontains(.display_text, 'docusign')

      // file name lures
      // secure theme
      or regex.icontains(.display_text, 'secured?.*(?:file|document|docs|fax)')
      or regex.icontains(.display_text, 'important.*(?:file|document|docs|fax)')
      or regex.icontains(.display_text, 'shared?.*(?:file|document|docs|fax)')
      or regex.icontains(.display_text, 'protected.*(?:file|document|docs|fax)')
      or regex.icontains(.display_text, 'encrypted.*(?:file|document|docs|fax)')

      // scanner theme
      or strings.icontains(.display_text, 'scanne[rd]_')
      // image themed
      or strings.icontains(.display_text, '_IMG_')
      or regex.icontains(.display_text, '^IMG[_-](?:\d|\W)+$')

      // digits
      or regex.icontains(.display_text, 'doc(?:ument)?\s?\d+$')
      or regex.icontains(.display_text, '^\d+$')

      // onedrive theme
      or strings.icontains(.display_text, 'one_docx')
      or strings.icontains(.display_text, 'OneDrive')
      or regex.icontains(.display_text, 'A document.*One.?Drive')

      // action in file name
      or strings.icontains(.display_text, 'click here')
      or strings.icontains(.display_text, 'Download PDF')
      or strings.icontains(.display_text, 'Validate')
      or strings.icontains(.display_text, 'sent you ')

      // limited file name to "confidential"
      or .display_text =~ 'Confidentiality'
      or .display_text =~ 'Confidential'

      // invoice themes
      or any(ml.nlu_classifier(.display_text).entities, .name == "financial")
      or strings.icontains(.display_text, 'payment')
      or strings.icontains(.display_text, 'invoice')
      or regex.icontains(.display_text, 'INV(?:_|\s)?\d+$')
      // starts with INV_ or INV\x20
      or regex.icontains(.display_text, '^INV(?:_|\s)')
      or regex.icontains(.display_text, 'P[O0]\W+?\d+$')
      or strings.icontains(.display_text, 'receipt')
      or strings.icontains(.display_text, 'billing')
      or (
        strings.icontains(.display_text, 'statement')
        and not .display_text =~ "Privacy Statement"
      )
      or strings.icontains(.display_text, 'Past Due')
      or regex.icontains(.display_text, 'Remit(tance)?')
      or strings.icontains(.display_text, 'Purchase Order')

      // contract language
      or strings.icontains(.display_text, 'settlement')
      or strings.icontains(.display_text, 'contract agreement')
      or regex.icontains(.display_text, 'Pr[0o]p[0o]sal')
      or strings.icontains(.display_text, 'contract doc')

      // generic document name AND additional suspicious indicator
      or (
        regex.imatch(.display_text, 'documents?')
        and (
          // Find the share comment in the HTML and check for reply/forward "impersonation"
          regex.icontains(body.html.raw,
                          '<p style="font-size:16px;color:#323130;margin:40px 20px 28px">(re|fwd?)'
          )
        )
      )

      // Payroll/HR
      // section also used in abuse_dropbox_sus_names.yml with modified input
      or strings.icontains(.display_text, 'Payroll')
      or strings.icontains(.display_text, 'Employee Pay\b')
      or strings.icontains(.display_text, 'Salary')
      or strings.icontains(.display_text, 'Benefit Enrollment')
      or strings.icontains(.display_text, 'Employee Handbook')
      or strings.icontains(.display_text, 'Reimbursement Approved')
      or regex.icontains(.display_text,
                         '(?:Faculty|Staff)\s*(?:\w+\s+){0,3}\s*Eval(?:uation)?'
      )

      // pattern of `sld - open items`
      or strings.istarts_with(.display_text,
                              strings.concat(sender.email.domain.sld, ' - ')
      )
  )
)
and (
  // and sender has never had email sent to them
  profile.by_sender().solicited == false
  // often times no-reply is soliticed due to various behaviors
  or sender.email.email == "no-reply@sharepointonline.com"
)

Detection logic

Scope: inbound message.

The detection rule is intended to match on emails sent from SharePoint indicating a shared file to the recipient that contain suspicious content within the document name. The Link display text is leveraged to identify the name of the shared file.

  1. inbound message
  2. subject.subject matches any of 2 patterns
    • *shared*
    • *invit*
  3. body.current_thread.text matches any of 3 patterns
    • *shared a file with you*
    • *shared with you*
    • *invited you to access a file*
  4. not:
    • body.current_thread.text matches 'invited you to edit'
  5. any of filter(body.links) where any holds:
    • .display_text matches '^[^a-z]+$'
    • .display_text contains 'dropbox'
    • .display_text contains 'docusign'
    • .display_text matches 'secured?.*(?:file|document|docs|fax)'
    • .display_text matches 'important.*(?:file|document|docs|fax)'
    • .display_text matches 'shared?.*(?:file|document|docs|fax)'
    • .display_text matches 'protected.*(?:file|document|docs|fax)'
    • .display_text matches 'encrypted.*(?:file|document|docs|fax)'
    • .display_text contains 'scanne[rd]_'
    • .display_text contains '_IMG_'
    • .display_text matches '^IMG[_-](?:\\d|\\W)+$'
    • .display_text matches 'doc(?:ument)?\\s?\\d+$'
    • .display_text matches '^\\d+$'
    • .display_text contains 'one_docx'
    • .display_text contains 'OneDrive'
    • .display_text matches 'A document.*One.?Drive'
    • .display_text contains 'click here'
    • .display_text contains 'Download PDF'
    • .display_text contains 'Validate'
    • .display_text contains 'sent you '
    • .display_text is 'Confidentiality'
    • .display_text is 'Confidential'
    • any of ml.nlu_classifier(.display_text).entities where:
      • .name is 'financial'
    • .display_text contains 'payment'
    • .display_text contains 'invoice'
    • .display_text matches 'INV(?:_|\\s)?\\d+$'
    • .display_text matches '^INV(?:_|\\s)'
    • .display_text matches 'P[O0]\\W+?\\d+$'
    • .display_text contains 'receipt'
    • .display_text contains 'billing'
    • all of:
      • .display_text contains 'statement'
      • not:
        • .display_text is 'Privacy Statement'
    • .display_text contains 'Past Due'
    • .display_text matches 'Remit(tance)?'
    • .display_text contains 'Purchase Order'
    • .display_text contains 'settlement'
    • .display_text contains 'contract agreement'
    • .display_text matches 'Pr[0o]p[0o]sal'
    • .display_text contains 'contract doc'
    • all of:
      • .display_text matches 'documents?'
      • body.html.raw matches '<p style="font-size:16px;color:#323130;margin:40px 20px 28px">(re|fwd?)'
    • .display_text contains 'Payroll'
    • .display_text contains 'Employee Pay\\b'
    • .display_text contains 'Salary'
    • .display_text contains 'Benefit Enrollment'
    • .display_text contains 'Employee Handbook'
    • .display_text contains 'Reimbursement Approved'
    • .display_text matches '(?:Faculty|Staff)\\s*(?:\\w+\\s+){0,3}\\s*Eval(?:uation)?'
    • strings.istarts_with(.display_text)
  6. any of:
    • profile.by_sender().solicited is False
    • sender.email.email is 'no-reply@sharepointonline.com'

Inspects: body.current_thread.text, 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.query_params, sender.email.domain.sld, sender.email.email, subject.subject, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender, regex.icontains, regex.imatch, regex.match, strings.concat, strings.icontains, strings.ilike, strings.istarts_with. Reference lists: $tenant_domains.

Indicators matched (57)

FieldMatchValue
strings.ilikesubstring*shared*
strings.ilikesubstring*invit*
strings.ilikesubstring*shared a file with you*
strings.ilikesubstring*shared with you*
strings.ilikesubstring*invited you to access a file*
body.links[].href_url.domain.root_domainequalssharepoint.com
body.links[].href_url.domain.root_domainequals1drv.ms
body.links[].href_url.domain.root_domainequalsmimecastprotect.com
strings.icontainssubstring.sharepoint.com
regex.matchregex^[^a-z]+$
strings.icontainssubstringdropbox
strings.icontainssubstringdocusign
45 more
regex.icontainsregexsecured?.*(?:file|document|docs|fax)
regex.icontainsregeximportant.*(?:file|document|docs|fax)
regex.icontainsregexshared?.*(?:file|document|docs|fax)
regex.icontainsregexprotected.*(?:file|document|docs|fax)
regex.icontainsregexencrypted.*(?:file|document|docs|fax)
strings.icontainssubstringscanne[rd]_
strings.icontainssubstring_IMG_
regex.icontainsregex^IMG[_-](?:\d|\W)+$
regex.icontainsregexdoc(?:ument)?\s?\d+$
regex.icontainsregex^\d+$
strings.icontainssubstringone_docx
strings.icontainssubstringOneDrive
regex.icontainsregexA document.*One.?Drive
strings.icontainssubstringclick here
strings.icontainssubstringDownload PDF
strings.icontainssubstringValidate
strings.icontainssubstringsent you
filter(body.links)[].display_textequalsConfidentiality
filter(body.links)[].display_textequalsConfidential
ml.nlu_classifier(filter(body.links)[].display_text).entities[].nameequalsfinancial
strings.icontainssubstringpayment
strings.icontainssubstringinvoice
regex.icontainsregexINV(?:_|\s)?\d+$
regex.icontainsregex^INV(?:_|\s)
regex.icontainsregexP[O0]\W+?\d+$
strings.icontainssubstringreceipt
strings.icontainssubstringbilling
strings.icontainssubstringstatement
strings.icontainssubstringPast Due
regex.icontainsregexRemit(tance)?
strings.icontainssubstringPurchase Order
strings.icontainssubstringsettlement
strings.icontainssubstringcontract agreement
regex.icontainsregexPr[0o]p[0o]sal
strings.icontainssubstringcontract doc
regex.imatchregexdocuments?
regex.icontainsregex<p style="font-size:16px;color:#323130;margin:40px 20px 28px">(re|fwd?)
strings.icontainssubstringPayroll
strings.icontainssubstringEmployee Pay\b
strings.icontainssubstringSalary
strings.icontainssubstringBenefit Enrollment
strings.icontainssubstringEmployee Handbook
strings.icontainssubstringReimbursement Approved
regex.icontainsregex(?:Faculty|Staff)\s*(?:\w+\s+){0,3}\s*Eval(?:uation)?
sender.email.emailequalsno-reply@sharepointonline.com

Stages and Predicates

Stage 1: mql_rule

and
  any(filter(body.links))
    or
      and
        not
          filter(body.links).display_text eq "Privacy Statement"
        filter(body.links).display_text contains "statement"
      and
        body.html.raw regex_match "<p style=\"font-size:16px;color:#323130;margin:40px 20px 28px\">(re|fwd?)"
        filter(body.links).display_text regex_match "documents?"
      any(ml.nlu_classifier(filter(body.links).display_text).entities)
        ml.nlu_classifier(filter(body.links).display_text).entities.name eq "financial"
      filter(body.links).display_text contains "Benefit Enrollment"
      filter(body.links).display_text contains "Download PDF"
      filter(body.links).display_text contains "Employee Handbook"
      filter(body.links).display_text contains "Employee Pay\\b"
      filter(body.links).display_text contains "OneDrive"
      filter(body.links).display_text contains "Past Due"
      filter(body.links).display_text contains "Payroll"
      filter(body.links).display_text contains "Purchase Order"
      filter(body.links).display_text contains "Reimbursement Approved"
      filter(body.links).display_text contains "Salary"
      filter(body.links).display_text contains "Validate"
      filter(body.links).display_text contains "_IMG_"
      filter(body.links).display_text contains "billing"
      filter(body.links).display_text contains "click here"
      filter(body.links).display_text contains "contract agreement"
      filter(body.links).display_text contains "contract doc"
      filter(body.links).display_text contains "docusign"
      filter(body.links).display_text contains "dropbox"
      filter(body.links).display_text contains "invoice"
      filter(body.links).display_text contains "one_docx"
      filter(body.links).display_text contains "payment"
      filter(body.links).display_text contains "receipt"
      filter(body.links).display_text contains "scanne[rd]_"
      filter(body.links).display_text contains "sent you "
      filter(body.links).display_text contains "settlement"
      filter(body.links).display_text eq "Confidential"
      filter(body.links).display_text eq "Confidentiality"
      filter(body.links).display_text regex_match "(?:Faculty|Staff)\\s*(?:\\w+\\s+){0,3}\\s*Eval(?:uation)?"
      filter(body.links).display_text regex_match "A document.*One.?Drive"
      filter(body.links).display_text regex_match "INV(?:_|\\s)?\\d+$"
      filter(body.links).display_text regex_match "P[O0]\\W+?\\d+$"
      filter(body.links).display_text regex_match "Pr[0o]p[0o]sal"
      filter(body.links).display_text regex_match "Remit(tance)?"
      filter(body.links).display_text regex_match "^IMG[_-](?:\\d|\\W)+$"
      filter(body.links).display_text regex_match "^INV(?:_|\\s)"
      filter(body.links).display_text regex_match "^[^a-z]+$"
      filter(body.links).display_text regex_match "^\\d+$"
      filter(body.links).display_text regex_match "doc(?:ument)?\\s?\\d+$"
      filter(body.links).display_text regex_match "encrypted.*(?:file|document|docs|fax)"
      filter(body.links).display_text regex_match "important.*(?:file|document|docs|fax)"
      filter(body.links).display_text regex_match "protected.*(?:file|document|docs|fax)"
      filter(body.links).display_text regex_match "secured?.*(?:file|document|docs|fax)"
      filter(body.links).display_text regex_match "shared?.*(?:file|document|docs|fax)"
      strings.istarts_with func_call "strings.istarts_with(filter(body.links)[].display_text)"
  not
    body.current_thread.text eq "invited you to edit"
  or
    body.current_thread.text match "invited you to access a file"
    body.current_thread.text match "shared a file with you"
    body.current_thread.text match "shared with you"
  or
    profile.by_sender func_call "profile.by_sender().solicited == false"
    sender.email.email eq "no-reply@sharepointonline.com"
  or
    subject.subject match "invit"
    subject.subject match "shared"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
body.current_thread.texteqinvited you to editexcludes:body.current_thread.text field:"body.current_thread.text" value:"invited you to edit"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textwildcard
  • *invited you to access a file*
  • *shared a file with you*
  • *shared with you*
field:"body.current_thread.text" kind:wildcard
sender.email.emaileq
  • no-reply@sharepointonline.com
field:"sender.email.email" kind:eq value:"no-reply@sharepointonline.com"
subject.subjectwildcard
  • *invit*
  • *shared*
field:"subject.subject" kind:wildcard
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link: Suspicious Sharepoint folder share

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

Detection Rule matches on messages which contain a link to a sharepoint shared folder containing a single file which is either a .url file, the filename is all caps, or includes call to action wording. These messages must not be sent from sharepoint and are either not solicited or from a new or outlier sender.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesFree file host, Evasion

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 any(filter(body.links,
               // folder share
               strings.icontains(.href_url.domain.domain, "-my.sharepoint.com")
               and strings.icontains(.href_url.url, "/:f:/g/personal")
               
               // remove links which contains the domain sld in the subdomain (tenenat) name
               and not any($org_slds,
                           strings.icontains(..href_url.domain.subdomain, .)
               )
        ),
        ( // a shared URL file
          regex.icontains(ml.link_analysis(., mode="aggressive").final_dom.raw,
                          '<div role="row" aria-label="[^\"]+.url, url File, Shared'
          )
          or 
          // the name of the file is all caps allowing for special charaters too
          regex.contains(ml.link_analysis(., mode="aggressive").final_dom.raw,
                         '<button data-automationid=\"FieldRenderer-name\" data-selection-invoke=\"true\" title="[A-Z0-9_\-\s]+\.[^\"]{3,4}\" role=\"link\" type=\"button\"'
          )
          or 
          // includes odd wording
          regex.icontains(ml.link_analysis(., mode="aggressive").final_dom.raw,
                          '<button data-automationid=\"FieldRenderer-name\" data-selection-invoke=\"true\" title="[^\"]*(?:dropbox|docusign|secured?|important|shared?|protected|encrypted|scanne[rd]|_IMG_|IMG[_-](?:\d|\W)|doc(?:ument)?\s?\d+|one_drive|OneDrive|Access|Review Document|Click Here|Download|validate|Confidential(?:ity)?|payment|invoice|INV(?:_|\s)?\d+|INV(?:_|\s)|P[O0]\W+?\d+|Past Due|Remit(?:tance)?|statement|Purchase Order|settlement|contract agreement|Pr[0o]p[0o]sal|contract doc|EFax|\.\.\.)[^\"]*\.[^\"]{3,4}\" role=\"link\" type=\"button\"'
          )
        )
        // and only a single file shared
        and strings.icount(ml.link_analysis(., mode="aggressive").final_dom.raw,
                           '<div role="presentation" data-automationid="ListCell" class="ms-List-cell"'
        ) == 1
)
// message is not from sharepoint actual
and not (
  strings.starts_with(headers.message_id, '<Share-')
  and strings.ends_with(headers.message_id, '@odspnotify>')
)
and (
  // not solicited
  not profile.by_sender().solicited
  // new or outlier sender prevalence
  or profile.by_sender().prevalence in ("new", "outlier")
  // marked as spam and no FPs
  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.

Detection Rule matches on messages which contain a link to a sharepoint shared folder containing a single file which is either a .url file, the filename is all caps, or includes call to action wording. These messages must not be sent from sharepoint and are either not solicited or from a new or outlier sender.

  1. inbound message
  2. any of filter(body.links) where all hold:
    • any of:
      • ml.link_analysis(., mode='aggressive').final_dom.raw matches '<div role="row" aria-label="[^\\"]+.url, url File, Shared'
      • ml.link_analysis(., mode='aggressive').final_dom.raw matches '<button data-automationid=\\"FieldRenderer-name\\" data-selection-invoke=\\"true\\" title="[A-Z0-9_\\-\\s]+\\.[^\\"]{3,4}\\" role=\\"link\\" type=\\"button\\"'
      • ml.link_analysis(., mode='aggressive').final_dom.raw matches '<button data-automationid=\\"FieldRenderer-name\\" data-selection-invoke=\\"true\\" title="[^\\"]*(?:dropbox|docusign|secured?|important|shared?|protected|encrypted|scanne[rd]|_IMG_|IMG[_-](?:\\d|\\W)|doc(?:ument)?\\s?\\d+|one_drive|OneDrive|Access|Review Document|Click Here|Download|validate|Confidential(?:ity)?|payment|invoice|INV(?:_|\\s)?\\d+|INV(?:_|\\s)|P[O0]\\W+?\\d+|Past Due|Remit(?:tance)?|statement|Purchase Order|settlement|contract agreement|Pr[0o]p[0o]sal|contract doc|EFax|\\.\\.\\.)[^\\"]*\\.[^\\"]{3,4}\\" role=\\"link\\" type=\\"button\\"'
    • strings.icount(ml.link_analysis(., mode='aggressive').final_dom.raw, '<div role="presentation" data-automationid="ListCell" class="ms-List-cell"') is 1
  3. not:
    • all of:
      • headers.message_id starts with '<Share-'
      • headers.message_id ends with '@odspnotify>'
  4. any of:
    • not:
      • profile.by_sender().solicited
    • profile.by_sender().prevalence in ('new', 'outlier')
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  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.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.subdomain, body.links[].href_url.url, headers.auth_summary.dmarc.pass, headers.message_id, sender.email.domain.root_domain, type.inbound. Sensors: ml.link_analysis, profile.by_sender, regex.contains, regex.icontains, strings.ends_with, strings.icontains, strings.icount, strings.starts_with. Reference lists: $high_trust_sender_root_domains, $org_slds.

Indicators matched (5)

FieldMatchValue
strings.icontainssubstring-my.sharepoint.com
strings.icontainssubstring/:f:/g/personal
regex.icontainsregex<div role="row" aria-label="[^\"]+.url, url File, Shared
regex.containsregex<button data-automationid=\"FieldRenderer-name\" data-selection-invoke=\"true\" title="[A-Z0-9_\-\s]+\.[^\"]{3,4}\" role=\"link\" type=\"button\"
regex.icontainsregex<button data-automationid=\"FieldRenderer-name\" data-selection-invoke=\"true\" title="[^\"]*(?:dropbox|docusign|secured?|important|shared?|protected|encrypted|scanne[rd]|_IMG_|IMG[_-](?:\d|\W)|doc(?:ument)?\s?\d+|one_drive|OneDrive|Access|Review Document|Click Here|Download|validate|Confidential(?:ity)?|payment|invoice|INV(?:_|\s)?\d+|INV(?:_|\s)|P[O0]\W+?\d+|Past Due|Remit(?:tance)?|statement|Purchase Order|settlement|contract agreement|Pr[0o]p[0o]sal|contract doc|EFax|\.\.\.)[^\"]*\.[^\"]{3,4}\" role=\"link\" type=\"button\"

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(filter(body.links))
    and
      or
        ml.link_analysis(filter(body.links)[], mode='aggressive').final_dom.raw regex_match "<button data-automationid=\\\"FieldRenderer-name\\\" data-selection-invoke=\\\"true\\\" title=\"[A-Z0-9_\\-\\s]+\\.[^\\\"]{3,4}\\\" role=\\\"link\\\" type=\\\"button\\\""
        ml.link_analysis(filter(body.links)[], mode='aggressive').final_dom.raw regex_match "<button data-automationid=\\\"FieldRenderer-name\\\" data-selection-invoke=\\\"true\\\" title=\"[^\\\"]*(?:dropbox|docusign|secured?|important|shared?|protected|encrypted|scanne[rd]|_IMG_|IMG[_-](?:\\d|\\W)|doc(?:ument)?\\s?\\d+|one_drive|OneDrive|Access|Review Document|Click Here|Download|validate|Confidential(?:ity)?|payment|invoice|INV(?:_|\\s)?\\d+|INV(?:_|\\s)|P[O0]\\W+?\\d+|Past Due|Remit(?:tance)?|statement|Purchase Order|settlement|contract agreement|Pr[0o]p[0o]sal|contract doc|EFax|\\.\\.\\.)[^\\\"]*\\.[^\\\"]{3,4}\\\" role=\\\"link\\\" type=\\\"button\\\""
        ml.link_analysis(filter(body.links)[], mode='aggressive').final_dom.raw regex_match "<div role=\"row\" aria-label=\"[^\\\"]+.url, url File, Shared"
      strings.icount func_call "strings.icount(ml.link_analysis(filter(body.links)[], mode='aggressive').final_dom.raw, \"<div role=\"presentation\" data-automationid=\"ListCell\" class=\"ms-List-cell\"\") == 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"
    not
      profile.by_sender func_call "profile.by_sender().solicited"
    profile.by_sender func_call "profile.by_sender().prevalence in (new, outlier)"
  not
    and
      headers.message_id ends_with "@odspnotify>"
      headers.message_id starts_with "<Share-"
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
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-"

Indicators

These rows show field, operator, and value matches.

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

Link: Suspicious single-domain link with suspicious path and financial lure indicators

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

Detects inbound messages containing a single unique root domain across all links, where at least one link follows a suspicious path pattern. Additionally, the message body contains HTML elements consistent with financial lure tactics, such as 'cash offer', 'confirm info', or 'view rates' styled with specific background colors indicative of a structured deceptive template.

Threat classification

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

CategoryValues
Attack typesSpam
Tactics and techniquesSocial engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.html
  • type

Rule body

type.inbound
and length(distinct(body.current_thread.links, .href_url.domain.root_domain)) == 1
and any(body.current_thread.links,
        regex.contains(.href_url.path, '\/[a-z]\/[a-z0-9]{32}')
        and length(.href_url.domain.subdomain) == 3
)
and (
  any(html.xpath(body.html, '//a').nodes,
      (
        strings.icontains(.raw, "color:#4fb077")
        and strings.icontains(.display_text, 'cash offer')
      )
  )
  or (
    any(body.current_thread.links,
        strings.icontains(.display_text, 'confirm info', 'view rates')
    )
    and strings.icontains(body.html.raw, 'background-color: #007bc2')
  )
)

Detection logic

Scope: inbound message.

Detects inbound messages containing a single unique root domain across all links, where at least one link follows a suspicious path pattern. Additionally, the message body contains HTML elements consistent with financial lure tactics, such as 'cash offer', 'confirm info', or 'view rates' styled with specific background colors indicative of a structured deceptive template.

  1. inbound message
  2. length(distinct(body.current_thread.links, .href_url.domain.root_domain)) is 1
  3. any of body.current_thread.links where all hold:
    • .href_url.path matches '\\/[a-z]\\/[a-z0-9]{32}'
    • length(.href_url.domain.subdomain) is 3
  4. any of:
    • any of html.xpath(body.html, '//a').nodes where all hold:
      • .raw contains 'color:#4fb077'
      • .display_text contains 'cash offer'
    • all of:
      • any of body.current_thread.links where:
        • .display_text contains any of 2 patterns
          • confirm info
          • view rates
      • body.html.raw contains 'background-color: #007bc2'

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.links[].href_url.path, body.html, body.html.raw, type.inbound. Sensors: html.xpath, regex.contains, strings.icontains.

Indicators matched (6)

FieldMatchValue
regex.containsregex\/[a-z]\/[a-z0-9]{32}
strings.icontainssubstringcolor:#4fb077
strings.icontainssubstringcash offer
strings.icontainssubstringconfirm info
strings.icontainssubstringview rates
strings.icontainssubstringbackground-color: #007bc2

Stages and Predicates

Stage 1: mql_rule

and
  or
    and
      any(body.current_thread.links)
        or
          body.current_thread.links.display_text contains "confirm info"
          body.current_thread.links.display_text contains "view rates"
      body.html.raw contains "background-color: #007bc2"
    any(html.xpath(body.html, '//a').nodes)
      and
        html.xpath(body.html, '//a').nodes.display_text contains "cash offer"
        html.xpath(body.html, '//a').nodes.raw contains "color:#4fb077"
  any(body.current_thread.links)
    and
      body.current_thread.links.href_url.domain.subdomain length_compare "3"
      body.current_thread.links.href_url.path regex_match "\\/[a-z]\\/[a-z0-9]{32}"
  distinct(body.current_thread.links, .href_url.domain.root_domain) length_compare "1"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Suspicious URL path with binary character sequence

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

Detects inbound messages containing links with URLs that follow a specific suspicious pattern: starting with a forward slash, followed by a digit, uppercase letter, alphanumeric characters, a hyphen, more alphanumeric characters, and ending with exactly five binary digits (0s and 1s).

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        regex.contains(.href_url.path,
                       '^\/[0-9][A-Z][a-z0-9]+\-[a-z0-9]+[01]{5}$'
        )
)

Detection logic

Scope: inbound message.

Detects inbound messages containing links with URLs that follow a specific suspicious pattern: starting with a forward slash, followed by a digit, uppercase letter, alphanumeric characters, a hyphen, more alphanumeric characters, and ending with exactly five binary digits (0s and 1s).

  1. inbound message
  2. any of body.links where:
    • .href_url.path matches '^\\/[0-9][A-Z][a-z0-9]+\\-[a-z0-9]+[01]{5}$'

Inspects: body.links, body.links[].href_url.path, type.inbound. Sensors: regex.contains.

Indicators matched (1)

FieldMatchValue
regex.containsregex^\/[0-9][A-Z][a-z0-9]+\-[a-z0-9]+[01]{5}$

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    body.links.href_url.path regex_match "^\\/[0-9][A-Z][a-z0-9]+\\-[a-z0-9]+[01]{5}$"
  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"

Link: Suspicious URL with recipient targeting and special characters

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

Detects messages containing links with special characters in the path that include the recipient's email address in either the URL path or fragment, potentially encoded in base64. The URLs have a simple path structure and may end with suspicious patterns.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • recipients
  • recipients.to[0]
  • type

Rule body

type.inbound
and length(recipients.to) == 1
and recipients.to[0].email.domain.valid
and any(body.links,
        // a single path
        strings.count(.href_url.path, '/') == 2
        and (
          strings.icontains(.href_url.path, '/$')
          or strings.icontains(.href_url.path, '/*')
          or strings.icontains(.href_url.url, '/#')
        )
        and (
          // special char in the path
          (
            (
              strings.icontains(.href_url.path, '!')
              or strings.icontains(.href_url.path, '@')
            )

            // ensure expected ordering
            and regex.icontains(.href_url.url, '[!@].*\/[$\*#]')
          )
          // num{3}alpha or alphanum{3}
          or (
            // in subdomain
            regex.icontains(.href_url.domain.subdomain,
                            '^(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)(?:$|\.)'
            )
            // url path
            and regex.icontains(.href_url.path,
                                '\/(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)\/'
            )
          )
        )
        and (
          strings.icontains(.href_url.path, recipients.to[0].email.email)
          or any(strings.scan_base64(.href_url.url,
                                     ignore_padding=true,
                                     format="url"
                 ),
                 strings.icontains(., recipients.to[0].email.email)
          )
        )
)

Detection logic

Scope: inbound message.

Detects messages containing links with special characters in the path that include the recipient's email address in either the URL path or fragment, potentially encoded in base64. The URLs have a simple path structure and may end with suspicious patterns.

  1. inbound message
  2. length(recipients.to) is 1
  3. recipients.to[0].email.domain.valid
  4. any of body.links where all hold:
    • strings.count(.href_url.path, '/') is 2
    • any of:
      • .href_url.path contains '/$'
      • .href_url.path contains '/*'
      • .href_url.url contains '/#'
    • any of:
      • all of:
        • any of:
          • .href_url.path contains '!'
          • .href_url.path contains '@'
        • .href_url.url matches '[!@].*\\/[$\\*#]'
      • all of:
        • .href_url.domain.subdomain matches '^(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)(?:$|\\.)'
        • .href_url.path matches '\\/(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)\\/'
    • any of:
      • strings.icontains(.href_url.path)
      • any of strings.scan_base64(.href_url.url) where:
        • strings.icontains(.)

Inspects: body.links, body.links[].href_url.domain.subdomain, body.links[].href_url.path, body.links[].href_url.url, recipients.to, recipients.to[0].email.domain.valid, recipients.to[0].email.email, type.inbound. Sensors: regex.icontains, strings.count, strings.icontains, strings.scan_base64.

Indicators matched (8)

FieldMatchValue
strings.icontainssubstring/$
strings.icontainssubstring/*
strings.icontainssubstring/#
strings.icontainssubstring!
strings.icontainssubstring@
regex.icontainsregex[!@].*\/[$\*#]
regex.icontainsregex^(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)(?:$|\.)
regex.icontainsregex\/(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)\/

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        and
          or
            body.links.href_url.path contains "!"
            body.links.href_url.path contains "@"
          body.links.href_url.url regex_match "[!@].*\\/[$\\*#]"
        and
          body.links.href_url.domain.subdomain regex_match "^(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)(?:$|\\.)"
          body.links.href_url.path regex_match "\\/(?:[a-z]+[0-9]{3}|[0-9]{3}[a-z]+)\\/"
      or
        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.path)"
      or
        body.links.href_url.path contains "/$"
        body.links.href_url.path contains "/*"
        body.links.href_url.url contains "/#"
      strings.count func_call "strings.count(body.links[].href_url.path, \"/\") == 2"
  recipients.to length_compare "1"
  recipients.to[0].email.domain.valid eq "true"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Suspicious wp-admin path from mismatched sender domain

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

Detects inbound messages containing links to a WordPress /wp-admin/ path where the link domain does not match the sender's domain. Matches two patterns: a single directory under /wp-admin/ with no file extension, or a .php payload nested at least one subdirectory below /wp-admin/ (e.g. /wp-admin/foo/bar.php). Both are indicative of compromised WordPress sites being repurposed to host phishing pages; legitimate WP notification paths like/wp-admin/admin.php are excluded by the subdirectory requirement.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Social engineering, Spoofing

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
// either a single dir under /wp-admin/ with no file extension or a .php payload nested at least one subdirectory below /wp-admin/
and any(body.links,
        regex.icontains(.href_url.path,
                        '^/wp-admin/[^/\.]+/?$',
                        '/wp-admin/[^/]+/[^/]+\.php$'
        )
        // domain is not the same as the sender domain
        and .href_url.domain.root_domain != sender.email.domain.root_domain
)
and not (
  (
    sender.email.domain.root_domain in $high_trust_sender_root_domains
    // website security companies that send reports via email
    or sender.email.domain.root_domain in ('imperva.com', 'urllo.com')
  )
  and coalesce(headers.auth_summary.dmarc.pass, false)
)

Detection logic

Scope: inbound message.

Detects inbound messages containing links to a WordPress /wp-admin/ path where the link domain does not match the sender's domain. Matches two patterns: a single directory under /wp-admin/ with no file extension, or a .php payload nested at least one subdirectory below /wp-admin/ (e.g. /wp-admin/foo/bar.php). Both are indicative of compromised WordPress sites being repurposed to host phishing pages; legitimate WP notification paths like/wp-admin/admin.php are excluded by the subdirectory requirement.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.path matches any of 2 patterns
      • ^/wp-admin/[^/\.]+/?$
      • /wp-admin/[^/]+/[^/]+\.php$
    • .href_url.domain.root_domain is not sender.email.domain.root_domain
  3. not:
    • all of:
      • any of:
        • sender.email.domain.root_domain in $high_trust_sender_root_domains
        • sender.email.domain.root_domain in ('imperva.com', 'urllo.com')
      • coalesce(headers.auth_summary.dmarc.pass)

Inspects: body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.path, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: regex.icontains. Reference lists: $high_trust_sender_root_domains.

Indicators matched (2)

FieldMatchValue
regex.icontainsregex^/wp-admin/[^/\.]+/?$
regex.icontainsregex/wp-admin/[^/]+/[^/]+\.php$

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        body.links.href_url.path regex_match "/wp-admin/[^/]+/[^/]+\\.php$"
        body.links.href_url.path regex_match "^/wp-admin/[^/\\.]+/?$"
      body.links.href_url.domain.root_domain cross_field_compare "sender.email.domain.root_domain"
  not
    and
      or
        sender.email.domain.root_domain in ["imperva.com", "urllo.com"]
         macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
      coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
  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"

Link: SVG with embedded recipient data

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

Detects SVG links that contain the recipient's email address either in plain text or base64 encoded format within the URL, indicating potential tracking or targeting mechanisms.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • recipients
  • recipients.to
  • type

Rule body

type.inbound
and any(body.links,
        strings.iends_with(.href_url.path, '.svg')
        and any(recipients.to,
                .email.domain.valid
                // contained in the url
                and (
                  strings.icontains(..href_url.url, .email.email)
                  // or contains the base64 endcoded email
                  or any(strings.scan_base64(..href_url.url,
                                             format="url",
                                             ignore_padding=true
                         ),
                         strings.icontains(., ..email.email)
                  )
                )
        )
)

Detection logic

Scope: inbound message.

Detects SVG links that contain the recipient's email address either in plain text or base64 encoded format within the URL, indicating potential tracking or targeting mechanisms.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.path ends with '.svg'
    • any of recipients.to where all hold:
      • .email.domain.valid
      • any of:
        • strings.icontains(.href_url.url)
        • any of strings.scan_base64(.href_url.url) where:
          • strings.icontains(.)

Inspects: body.links, body.links[].href_url.path, body.links[].href_url.url, recipients.to, recipients.to[].email.domain.valid, recipients.to[].email.email, type.inbound. Sensors: strings.icontains, strings.iends_with, strings.scan_base64.

Indicators matched (1)

FieldMatchValue
strings.iends_withsuffix.svg

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      any(recipients.to)
        and
          or
            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"
      body.links.href_url.path ends_with ".svg"
  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"

Link: Tax document lure Portuguese/Spanish with suspicious domains

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

Detects messages in Portuguese/Spanish containing tax document phrases that link to suspicious domains including URL shorteners, free file hosts, or newly registered domains.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Credential Phishing, Malware/Ransomware
Tactics and techniquesFree file host, Free subdomain host, 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[0]
  • sender.email
  • subject
  • type

Rule body

type.inbound
and 0 < length(body.links) < 15
and length(recipients.to) == 1
and recipients.to[0].email.domain.valid
and (
  // portuguese tax document phrases
  regex.icontains(body.current_thread.text,
                  '(?:documento fiscal|documento tributário|documento de imposto|documento de impostos|formulário fiscal|declaração de imposto|declaração de impostos|declaração fiscal|documentação fiscal|comprovante fiscal|certidão fiscal|certificado fiscal|registro fiscal|comprovativo fiscal)'
  )
  // spanish tax document phrases
  or regex.icontains(body.current_thread.text,
                     '(?:Acessar Documento|Documento Fiscal|documento tributario|documento de impuestos|comprobante fiscal|constancia fiscal|declaración de impuestos|formulario fiscal|documentación fiscal|registro fiscal|certificado fiscal)'
  )
)

// suspicious domains
and any(body.links,
        .parser == 'hyperlink'
        and (
          .href_url.domain.domain in $url_shorteners
          or .href_url.domain.root_domain in $url_shorteners
          or .href_url.domain.domain in $free_file_hosts
          or .href_url.domain.root_domain in $free_file_hosts
          or .href_url.domain.domain in $free_subdomain_hosts
          or .href_url.domain.root_domain in $free_subdomain_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 network.whois(.href_url.domain).days_old < 30
        )
        and not .href_url.domain.root_domain in ('sharepoint.com', 'box.com')
)
// subject fields
and regex.icontains(subject.base, '(?:nf|\b[0-9]{7,10}\b|nota fiscal)')

// 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 in Portuguese/Spanish containing tax document phrases that link to suspicious domains including URL shorteners, free file hosts, or newly registered domains.

  1. inbound message
  2. all of:
    • length(body.links) > 0
    • length(body.links) < 15
  3. length(recipients.to) is 1
  4. recipients.to[0].email.domain.valid
  5. any of:
    • body.current_thread.text matches '(?:documento fiscal|documento tributário|documento de imposto|documento de impostos|formulário fiscal|declaração de imposto|declaração de impostos|declaração fiscal|documentação fiscal|comprovante fiscal|certidão fiscal|certificado fiscal|registro fiscal|comprovativo fiscal)'
    • body.current_thread.text matches '(?:Acessar Documento|Documento Fiscal|documento tributario|documento de impuestos|comprobante fiscal|constancia fiscal|declaración de impuestos|formulario fiscal|documentación fiscal|registro fiscal|certificado fiscal)'
  6. any of body.links where all hold:
    • .parser is 'hyperlink'
    • any of:
      • .href_url.domain.domain in $url_shorteners
      • .href_url.domain.root_domain in $url_shorteners
      • .href_url.domain.domain in $free_file_hosts
      • .href_url.domain.root_domain in $free_file_hosts
      • .href_url.domain.domain in $free_subdomain_hosts
      • .href_url.domain.root_domain in $free_subdomain_hosts
      • .href_url.domain.domain in $self_service_creation_platform_domains
      • .href_url.domain.root_domain in $self_service_creation_platform_domains
      • network.whois(.href_url.domain).days_old < 30
    • not:
      • .href_url.domain.root_domain in ('sharepoint.com', 'box.com')
  7. subject.base matches '(?:nf|\\b[0-9]{7,10}\\b|nota fiscal)'
  8. 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[].href_url.domain, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].parser, headers.auth_summary.dmarc.pass, recipients.to, recipients.to[0].email.domain.valid, sender.email.domain.root_domain, subject.base, type.inbound. Sensors: network.whois, regex.icontains. Reference lists: $free_file_hosts, $free_subdomain_hosts, $high_trust_sender_root_domains, $self_service_creation_platform_domains, $url_shorteners.

Indicators matched (4)

FieldMatchValue
regex.icontainsregex(?:documento fiscal|documento tributário|documento de imposto|documento de impostos|formulário fiscal|declaração de imposto|declaração de impostos|declaração fiscal|documentação fiscal|comprovante fiscal|certidão fiscal|certificado fiscal|registro fiscal|comprovativo fiscal)
regex.icontainsregex(?:Acessar Documento|Documento Fiscal|documento tributario|documento de impuestos|comprobante fiscal|constancia fiscal|declaración de impuestos|formulario fiscal|documentación fiscal|registro fiscal|certificado fiscal)
body.links[].parserequalshyperlink
regex.icontainsregex(?:nf|\b[0-9]{7,10}\b|nota fiscal)

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      not
        body.links.href_url.domain.root_domain in ["box.com", "sharepoint.com"]
      or
        network.whois func_call "network.whois(body.links[].href_url.domain).days_old < 30"
         macro "body.links[].href_url.domain.domain in free_file_hosts"
         macro "body.links[].href_url.domain.domain in free_subdomain_hosts"
         macro "body.links[].href_url.domain.domain in self_service_creation_platform_domains"
         macro "body.links[].href_url.domain.domain in url_shorteners"
         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"
      body.links.parser eq "hyperlink"
  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 "(?:Acessar Documento|Documento Fiscal|documento tributario|documento de impuestos|comprobante fiscal|constancia fiscal|declaración de impuestos|formulario fiscal|documentación fiscal|registro fiscal|certificado fiscal)"
    body.current_thread.text regex_match "(?:documento fiscal|documento tributário|documento de imposto|documento de impostos|formulário fiscal|declaração de imposto|declaração de impostos|declaração fiscal|documentação fiscal|comprovante fiscal|certidão fiscal|certificado fiscal|registro fiscal|comprovativo fiscal)"
  body.links length_compare "0"
  body.links length_compare "15"
  recipients.to length_compare "1"
  recipients.to[0].email.domain.valid eq "true"
  subject.base regex_match "(?:nf|\\b[0-9]{7,10}\\b|nota fiscal)"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.current_thread.textregex_match
  • (?:Acessar Documento|Documento Fiscal|documento tributario|documento de impuestos|comprobante fiscal|constancia fiscal|declaración de impuestos|formulario fiscal|documentación fiscal|registro fiscal|certificado fiscal)
  • (?:documento fiscal|documento tributário|documento de imposto|documento de impostos|formulário fiscal|declaração de imposto|declaração de impostos|declaração fiscal|documentação fiscal|comprovante fiscal|certidão fiscal|certificado fiscal|registro fiscal|comprovativo fiscal)
field:"body.current_thread.text" kind:regex_match
recipients.to[0].email.domain.valideq
  • true transforms: boolean
field:"recipients.to[0].email.domain.valid" kind:eq value:"true"
subject.baseregex_match
  • (?:nf|\b[0-9]{7,10}\b|nota fiscal)
field:"subject.base" kind:regex_match value:"(?:nf|\b[0-9]{7,10}\b|nota fiscal)"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Link: Tycoon2FA phishing kit (non-exhaustive)

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

Detects links utilizing the Tycoon2FA phishing kit, identified by specific DOM structure patterns and CDN characteristics, combined with suspicious domain indicators such as free subdomain hosts or suspicious TLDs. As the Tycoon2FA kit is evolving, this rule will not detect all variants of Tycoon2FA phishing, and is designed to compliment existing and future detections.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesFree subdomain host, Evasion, Credential Phishing

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • recipients
  • recipients.to
  • type

Rule body

type.inbound
and length(body.current_thread.links) < 10
and any(body.current_thread.links,
        // initial suspicious link check
        (
          .href_url.domain.root_domain in $free_subdomain_hosts
          or .href_url.domain.tld in $suspicious_tlds
          or any(recipients.to,
                 strings.icontains(..href_url.url, .email.email)
                 and .email.domain.valid
          )
        )

        // known Tycoon pattern (benign on its own, but a good confirming indicator when coupled with additional logic)
        and any(ml.link_analysis(.).unique_urls_accessed,
                .path in ("/cdn-cgi/rum")
        )

        // begin CAPTCHA options
        and (
          // Grid "CAPTCHA"
          (
            length(distinct(map(html.xpath(ml.link_analysis(.).final_dom,
                                           '//*/@class'
                                ).nodes,
                                .raw
                            ),
                            .
                   )
            ) == 5
            and all(distinct(map(html.xpath(ml.link_analysis(.).final_dom,
                                            '//*/@class'
                                 ).nodes,
                                 .raw
                             ),
                             .
                    ),
                    . in ("card", "title", "hint", "grid", "dot")
            )
          )
          // Unsplash image selection "CAPTCHA"
          or (
            any(distinct(map(html.xpath(ml.link_analysis(.).final_dom,
                                        '//*/@class'
                             ).nodes,
                             .raw
                         ),
                         .
                ),
                . in (
                  "captcha-container",
                  "puzzle-piece drag-hint",
                  "puzzle-image"
                )
            )
            or length(filter(ml.link_analysis(.).unique_urls_accessed,
                             .domain.domain == "images.unsplash.com"
                      )
            ) > 4
            or any(file.explode(ml.link_analysis(.).final_dom),
                   length(filter(.scan.javascript.identifiers,
                                 strings.icontains(., "puzzle")
                          )
                   ) > 3
            )
            or strings.ilike(ml.link_analysis(.).final_dom.raw,
                             "*Please align the puzzle correctly*",
                             "*Verified! You may proceed*",
                             "*Human Check*",
                             "*needs to review the security of your connection before proceeding.*"
            )
          )
          
          // Randomized image domain CAPTCHA
          // all image URL domains accessed are unique from each other
          or (
            length(filter(ml.link_analysis(.).unique_urls_accessed,
                          any([".jpg", ".png", ".jpeg"],
                              strings.ends_with(..path, .)
                          )
                   )
            ) == length(distinct(filter(ml.link_analysis(.).unique_urls_accessed,
                                        any([".jpg", ".png", ".jpeg"],
                                            strings.ends_with(..path, .)
                                        )
                                 ),
                                 .domain.root_domain
                        )
            )
            and length(filter(ml.link_analysis(.).unique_urls_accessed,
                              any([".jpg", ".png", ".jpeg"],
                                  strings.ends_with(..path, .)
                              )
                       )
            ) > 4
          )

          // Reoccuring form pattern
          or length(html.xpath(ml.link_analysis(.).final_dom,
                               "//form[@method='POST']//input[@name='zone' and @type='hidden']"
                    ).nodes
          ) == 1
        )
)

Detection logic

Scope: inbound message.

Detects links utilizing the Tycoon2FA phishing kit, identified by specific DOM structure patterns and CDN characteristics, combined with suspicious domain indicators such as free subdomain hosts or suspicious TLDs. As the Tycoon2FA kit is evolving, this rule will not detect all variants of Tycoon2FA phishing, and is designed to compliment existing and future detections.

  1. inbound message
  2. length(body.current_thread.links) < 10
  3. any of body.current_thread.links where all hold:
    • any of:
      • .href_url.domain.root_domain in $free_subdomain_hosts
      • .href_url.domain.tld in $suspicious_tlds
      • any of recipients.to where all hold:
        • strings.icontains(.href_url.url)
        • .email.domain.valid
    • any of ml.link_analysis(.).unique_urls_accessed where:
      • .path in ('/cdn-cgi/rum')
    • any of:
      • all of:
        • length(distinct(map(html.xpath(ml.link_analysis(.).final_dom, '//*/@class').nodes, .raw), .)) is 5
        • all of distinct(...) where:
          • . in ('card', 'title', 'hint', 'grid', 'dot')
      • any of:
        • any of distinct(...) where:
          • . in ('captcha-container', 'puzzle-piece drag-hint', 'puzzle-image')
        • length(filter(ml.link_analysis(.).unique_urls_accessed, .domain.domain == 'images.unsplash.com')) > 4
        • any of file.explode(...) where:
          • length(filter(.scan.javascript.identifiers, strings.icontains(., 'puzzle'))) > 3
        • ml.link_analysis(.).final_dom.raw matches any of 4 patterns
          • *Please align the puzzle correctly*
          • *Verified! You may proceed*
          • *Human Check*
          • *needs to review the security of your connection before proceeding.*
      • all of:
        • length(filter(ml.link_analysis(.).unique_urls_accessed, any(['.jpg', '.png', '.jpeg'], strings.ends_with(..path, .)))) is length(distinct(filter(ml.link_analysis(.).unique_urls_accessed, any(['.jpg', '.png', '.jpeg'], strings.ends_with(..path, .))), .domain.root_domain))
        • length(filter(ml.link_analysis(.).unique_urls_accessed, any(['.jpg', '.png', '.jpeg'], strings.ends_with(..path, .)))) > 4
      • length(html.xpath(ml.link_analysis(.).final_dom, "//form[@method='POST']//input[@name='zone' and @type='hidden']").nodes) is 1

Inspects: body.current_thread.links, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.links[].href_url.domain.tld, body.current_thread.links[].href_url.url, recipients.to, recipients.to[].email.domain.valid, recipients.to[].email.email, type.inbound. Sensors: file.explode, html.xpath, ml.link_analysis, strings.ends_with, strings.icontains, strings.ilike. Reference lists: $free_subdomain_hosts, $suspicious_tlds.

Indicators matched (15)

FieldMatchValue
ml.link_analysis(body.current_thread.links[]).unique_urls_accessed[].pathmember/cdn-cgi/rum
distinct(...)[]membercard
distinct(...)[]membertitle
distinct(...)[]memberhint
distinct(...)[]membergrid
distinct(...)[]memberdot
distinct(...)[]membercaptcha-container
distinct(...)[]memberpuzzle-piece drag-hint
distinct(...)[]memberpuzzle-image
ml.link_analysis(body.current_thread.links[]).unique_urls_accessed[].domain.domainequalsimages.unsplash.com
strings.icontainssubstringpuzzle
strings.ilikesubstring*Please align the puzzle correctly*
3 more
strings.ilikesubstring*Verified! You may proceed*
strings.ilikesubstring*Human Check*
strings.ilikesubstring*needs to review the security of your connection before proceeding.*

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    and
      or
        any(recipients.to)
          and
            recipients.to.email.domain.valid eq "true"
            strings.icontains func_call "strings.icontains(body.current_thread.links[].href_url.url)"
         macro "body.current_thread.links[].href_url.domain.root_domain in free_subdomain_hosts"
         macro "body.current_thread.links[].href_url.domain.tld in suspicious_tlds"
      or
        any(distinct(...))
          distinct(...) in ["captcha-container", "puzzle-image", "puzzle-piece drag-hint"]
        and
          distinct(map(html.xpath(ml.link_analysis(body.current_thread.links[]).final_dom, '//*/@class').nodes, body.current_thread.links[].raw), body.current_thread.links[]) length_compare "5"
           macro "all(distinct(...))"
        any(file.explode(...))
          filter(file.explode(...)[].scan.javascript.identifiers, strings.icontains(file.explode(...)[], 'puzzle')) length_compare "3"
        and
          filter(ml.link_analysis(body.current_thread.links[]).unique_urls_accessed, any(['.jpg', '.png', '.jpeg'], strings.ends_with(..path, body.current_thread.links[]))) length_compare "4"
          length func_call "length(filter(ml.link_analysis(body.current_thread.links[]).unique_urls_accessed, any(['.jpg', '.png', '.jpeg'], strings.ends_with(..path, body.current_thread.links[])))) == length(distinct(filter(ml.link_analysis(body.current_thread.links[]).unique_urls_accessed, any(['.jpg', '.png', '.jpeg'], strings.ends_with(..path, body.current_thread.links[]))), body.current_thread.links[].domain.root_domain))"
        filter(ml.link_analysis(body.current_thread.links[]).unique_urls_accessed, body.current_thread.links[].domain.domain == 'images.unsplash.com') length_compare "4"
        html.xpath(ml.link_analysis(body.current_thread.links[]).final_dom, "//form[@method='POST']//input[@name='zone' and @type='hidden']").nodes length_compare "1"
        ml.link_analysis(body.current_thread.links[]).final_dom.raw match "Human Check"
        ml.link_analysis(body.current_thread.links[]).final_dom.raw match "Please align the puzzle correctly"
        ml.link_analysis(body.current_thread.links[]).final_dom.raw match "Verified! You may proceed"
        ml.link_analysis(body.current_thread.links[]).final_dom.raw match "needs to review the security of your connection before proceeding."
      any(ml.link_analysis(body.current_thread.links).unique_urls_accessed)
        ml.link_analysis(body.current_thread.links).unique_urls_accessed.path eq "/cdn-cgi/rum"
  body.current_thread.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"

Link: Uncommon SharePoint document type with sender's display name

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

Detects SharePoint file shares containing personal OneNote or PDF files where the file name matches the sender's display name.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering, OneNote, PDF

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.links
  • headers
  • headers.hops
  • subject
  • type

Rule body

type.inbound

// Matches the message id observed. DKIM/SPF domains can be custom and therefore are unpredictable.
and (
  (
    strings.starts_with(headers.message_id, '<Share-')
    and strings.ends_with(headers.message_id, '@odspnotify>')
  )
  or (
    any(headers.hops,
        any(.fields,
            .name == "X-Google-Original-Message-ID"
            and strings.starts_with(.value, '<Share-')
            and strings.ends_with(.value, '@odspnotify>')
        )
    )
  )
)

// SharePoint email indicators
and strings.like(body.current_thread.text,
                 "*shared a file with you*",
                 "*shared with you*",
                 "*invited you to access a file*"
)
and strings.icontains(subject.subject, "shared")

// file name is the sender's name
and any(html.xpath(body.html,
                   '//table[@role="presentation"]//tr[last()]//text()'
        ).nodes,
        .display_text =~ sender.display_name
)

// link logic
and any(body.links,
        .href_url.domain.root_domain == "sharepoint.com"
        // it is a personal share
        and (
          // /g/ is only found with /personal
          strings.icontains(.href_url.path, '/g/personal/')
          or strings.icontains(.href_url.path, '/p/')
        )
        // it is either a OneNote or PDF
        and (
          strings.icontains(.href_url.path, '/:o:/')
          or strings.icontains(.href_url.path, '/:b:/')
          or strings.icontains(.href_url.path, '/:u:/')
        )
)

Detection logic

Scope: inbound message.

Detects SharePoint file shares containing personal OneNote or PDF files where the file name matches the sender's display name.

  1. inbound message
  2. any of:
    • all of:
      • headers.message_id starts with '<Share-'
      • 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 starts with '<Share-'
        • .value ends with '@odspnotify>'
  3. body.current_thread.text matches any of 3 patterns
    • *shared a file with you*
    • *shared with you*
    • *invited you to access a file*
  4. subject.subject contains 'shared'
  5. any of html.xpath(body.html, '//table[@role="presentation"]//tr[last()]//text()').nodes where:
    • .display_text is sender.display_name
  6. any of body.links where all hold:
    • .href_url.domain.root_domain is 'sharepoint.com'
    • any of:
      • .href_url.path contains '/g/personal/'
      • .href_url.path contains '/p/'
    • any of:
      • .href_url.path contains '/:o:/'
      • .href_url.path contains '/:b:/'
      • .href_url.path contains '/:u:/'

Inspects: body.current_thread.text, body.html, body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.path, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, headers.message_id, sender.display_name, subject.subject, type.inbound. Sensors: html.xpath, strings.ends_with, strings.icontains, strings.like, strings.starts_with.

Indicators matched (13)

FieldMatchValue
strings.starts_withprefix<Share-
strings.ends_withsuffix@odspnotify>
headers.hops[].fields[].nameequalsX-Google-Original-Message-ID
strings.likesubstring*shared a file with you*
strings.likesubstring*shared with you*
strings.likesubstring*invited you to access a file*
strings.icontainssubstringshared
body.links[].href_url.domain.root_domainequalssharepoint.com
strings.icontainssubstring/g/personal/
strings.icontainssubstring/p/
strings.icontainssubstring/:o:/
strings.icontainssubstring/:b:/
1 more
strings.icontainssubstring/:u:/

Stages and Predicates

Stage 1: mql_rule

and
  or
    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-"
    and
      headers.message_id ends_with "@odspnotify>"
      headers.message_id starts_with "<Share-"
  any(body.links)
    and
      or
        body.links.href_url.path contains "/:b:/"
        body.links.href_url.path contains "/:o:/"
        body.links.href_url.path contains "/:u:/"
      or
        body.links.href_url.path contains "/g/personal/"
        body.links.href_url.path contains "/p/"
      body.links.href_url.domain.root_domain eq "sharepoint.com"
  or
    body.current_thread.text match "invited you to access a file"
    body.current_thread.text match "shared a file with you"
    body.current_thread.text match "shared with you"
  any(html.xpath(body.html, '//table[@role="presentation"]//tr[last()]//text()').nodes)
    html.xpath(body.html, '//table[@role="presentation"]//tr[last()]//text()').nodes.display_text cross_field_compare "sender.display_name"
  subject.subject contains "shared"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Unformatted template with literal placeholder in mailto link

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

Detects inbound messages containing mailto links whose href URL still contains an unresolved template placeholder, indicating the sender used a templating system but failed to substitute real values before sending. Two patterns are flagged: an '@{domain}' placeholder, treated as a strong standalone signal; and a '{RECIPIENT_EMAIL}' or '{SENDER_EMAIL}' placeholder (case-insensitive, allowing an underscore or space before 'EMAIL'), which fires only when the NLU classifier detects high-confidence credential-theft (cred_theft) or business-email-compromise (bec) intent in the current thread, suppressing benign templated mail.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        .href_url.scheme == "mailto"
        and strings.contains(.href_url.url, '{')
        and strings.contains(.href_url.url, '}')
        and (
          // @{domain} pattern is strong
          regex.icontains(.href_url.url, '@\s*{\s*domain\s*}')
          // combine {RECIPIENT_EMAIL} and {SENDER EMAIL} with NLU to remove a bunch of
          // benign use cases
          or (
            regex.icontains(.href_url.url,
                            '{\s*(?:RECIPIENT|SENDER)[_\s]?EMAIL\s*}'
            )
            and any(ml.nlu_classifier(body.current_thread.text).intents,
                    .name in ("cred_theft", "bec") and .confidence == "high"
            )
          )
        )
)

Detection logic

Scope: inbound message.

Detects inbound messages containing mailto links whose href URL still contains an unresolved template placeholder, indicating the sender used a templating system but failed to substitute real values before sending. Two patterns are flagged: an '@{domain}' placeholder, treated as a strong standalone signal; and a '{RECIPIENT_EMAIL}' or '{SENDER_EMAIL}' placeholder (case-insensitive, allowing an underscore or space before 'EMAIL'), which fires only when the NLU classifier detects high-confidence credential-theft (cred_theft) or business-email-compromise (bec) intent in the current thread, suppressing benign templated mail.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.scheme is 'mailto'
    • .href_url.url contains '{'
    • .href_url.url contains '}'
    • any of:
      • .href_url.url matches '@\\s*{\\s*domain\\s*}'
      • all of:
        • .href_url.url matches '{\\s*(?:RECIPIENT|SENDER)[_\\s]?EMAIL\\s*}'
        • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
          • .name in ('cred_theft', 'bec')
          • .confidence is 'high'

Inspects: body.current_thread.text, body.links, body.links[].href_url.scheme, body.links[].href_url.url, type.inbound. Sensors: ml.nlu_classifier, regex.icontains, strings.contains.

Indicators matched (8)

FieldMatchValue
body.links[].href_url.schemeequalsmailto
strings.containssubstring{
strings.containssubstring}
regex.icontainsregex@\s*{\s*domain\s*}
regex.icontainsregex{\s*(?:RECIPIENT|SENDER)[_\s]?EMAIL\s*}
ml.nlu_classifier(body.current_thread.text).intents[].namemembercred_theft
ml.nlu_classifier(body.current_thread.text).intents[].namememberbec
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      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 in ["bec", "cred_theft"]
          body.links.href_url.url regex_match "{\\s*(?:RECIPIENT|SENDER)[_\\s]?EMAIL\\s*}"
        body.links.href_url.url regex_match "@\\s*{\\s*domain\\s*}"
      body.links.href_url.scheme eq "mailto"
      body.links.href_url.url contains "{"
      body.links.href_url.url contains "}"
  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"

Link: Unicode character obfuscation in display name with base64-encoded URL fragment

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

Detects inbound messages where the sender's display name contains Unicode format characters (such as word joiners or invisible separators) interspersed between letters to evade text-based detection. These messages carry links whose URL fragments are unusually long (over 100 characters) and match a base64url-encoded pattern, a technique used to smuggle encoded payloads past URL scanners.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and regex.icontains(sender.display_name, '[a-z]\p{Cf}+[a-z]')
and any(body.links,
        length(.href_url.fragment) > 100
        and regex.contains(.href_url.fragment, '^[A-Za-z0-9_-]+={0,2}$')
)

Detection logic

Scope: inbound message.

Detects inbound messages where the sender's display name contains Unicode format characters (such as word joiners or invisible separators) interspersed between letters to evade text-based detection. These messages carry links whose URL fragments are unusually long (over 100 characters) and match a base64url-encoded pattern, a technique used to smuggle encoded payloads past URL scanners.

  1. inbound message
  2. sender.display_name matches '[a-z]\\p{Cf}+[a-z]'
  3. any of body.links where all hold:
    • length(.href_url.fragment) > 100
    • .href_url.fragment matches '^[A-Za-z0-9_-]+={0,2}$'

Inspects: body.links, body.links[].href_url.fragment, sender.display_name, type.inbound. Sensors: regex.contains, regex.icontains.

Indicators matched (2)

FieldMatchValue
regex.icontainsregex[a-z]\p{Cf}+[a-z]
regex.containsregex^[A-Za-z0-9_-]+={0,2}$

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      body.links.href_url.fragment length_compare "100"
      body.links.href_url.fragment regex_match "^[A-Za-z0-9_-]+={0,2}$"
  sender.display_name regex_match "[a-z]\\p{Cf}+[a-z]"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Unsolicited email contains link leading to Tycoon URL structure

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

Detects unsolicited messages containing links leading to specific tycoon URL patterns that include encoded email addresses or base64-encoded content in the path structure.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • recipients
  • recipients.to[0]
  • type

Rule body

type.inbound
and 0 < length(body.links) < 15
and length(recipients.to) == 1
and recipients.to[0].email.domain.valid
and any(body.links,
        // single path
        strings.count(ml.link_analysis(., mode="aggressive").effective_url.path,
                      '/'
        ) == 2
        // tycoon url struct
        and regex.icontains(ml.link_analysis(., mode="aggressive").effective_url.path,
                            '\/.*[!@].*\/[$*](?:[a-zA-Z0-9.\-_]+(?:@|%40)[a-zA-Z0-9.-]+\.[a-zA-Z]{2,3}|(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})|$)'
        )
)

Detection logic

Scope: inbound message.

Detects unsolicited messages containing links leading to specific tycoon URL patterns that include encoded email addresses or base64-encoded content in the path structure.

  1. inbound message
  2. all of:
    • length(body.links) > 0
    • length(body.links) < 15
  3. length(recipients.to) is 1
  4. recipients.to[0].email.domain.valid
  5. any of body.links where all hold:
    • strings.count(ml.link_analysis(., mode='aggressive').effective_url.path, '/') is 2
    • ml.link_analysis(., mode='aggressive').effective_url.path matches '\\/.*[!@].*\\/[$*](?:[a-zA-Z0-9.\\-_]+(?:@|%40)[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,3}|(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})|$)'

Inspects: body.links, recipients.to, recipients.to[0].email.domain.valid, type.inbound. Sensors: ml.link_analysis, regex.icontains, strings.count.

Indicators matched (1)

FieldMatchValue
regex.icontainsregex\/.*[!@].*\/[$*](?:[a-zA-Z0-9.\-_]+(?:@|%40)[a-zA-Z0-9.-]+\.[a-zA-Z]{2,3}|(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})|$)

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      ml.link_analysis(body.links[], mode='aggressive').effective_url.path regex_match "\\/.*[!@].*\\/[$*](?:[a-zA-Z0-9.\\-_]+(?:@|%40)[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,3}|(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})|$)"
      strings.count func_call "strings.count(ml.link_analysis(body.links[], mode='aggressive').effective_url.path, \"/\") == 2"
  body.links length_compare "0"
  body.links length_compare "15"
  recipients.to length_compare "1"
  recipients.to[0].email.domain.valid eq "true"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Unsolicited email contains link to page containing Tycoon URI structure

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

Detects links containing Tycoon phishing kit URI patterns with specific alphanumeric sequences separated by exclamation marks or at symbols from unsolicited senders.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and 0 < length(body.links) < 15
and any(body.links,
        any(html.xpath(ml.link_analysis(.).final_dom, '//script//text()').nodes,
            // full tycoon uri struct
            any(.links,
                regex.icontains(.href_url.path,
                                '^\/[a-z0-9]{0,30}[!@][a-z0-9]{0,30}\/'
                )
                and not regex.icontains(.href_url.path, '\/[!@][a-z]{2,30}\/')
                and not strings.istarts_with(.href_url.domain.domain, 'www.')
                and not regex.icontains(.href_url.domain.root_domain,
                                        '(?:fpjs\.io|(?:medium|unpkg|alicdn)\.com|turtl\.co)'
                )
            )
        )
        // tycoon structured path and cloudflare captcha domain
        or (
          regex.icontains(.display_text,
                          '\/[a-zA-Z0-9]{0,30}[!@][a-zA-Z0-9]{0,30}\/'
          )
          and strings.icontains(.display_text, 'challenges.cloudflare.com')
        )
)

Detection logic

Scope: inbound message.

Detects links containing Tycoon phishing kit URI patterns with specific alphanumeric sequences separated by exclamation marks or at symbols from unsolicited senders.

  1. inbound message
  2. all of:
    • length(body.links) > 0
    • length(body.links) < 15
  3. any of body.links where any holds:
    • any of html.xpath(ml.link_analysis(.).final_dom, '//script//text()').nodes where:
      • any of .links where all hold:
        • .href_url.path matches '^\\/[a-z0-9]{0,30}[!@][a-z0-9]{0,30}\\/'
        • not:
          • .href_url.path matches '\\/[!@][a-z]{2,30}\\/'
        • not:
          • .href_url.domain.domain starts with 'www.'
        • not:
          • .href_url.domain.root_domain matches '(?:fpjs\\.io|(?:medium|unpkg|alicdn)\\.com|turtl\\.co)'
    • all of:
      • .display_text matches '\\/[a-zA-Z0-9]{0,30}[!@][a-zA-Z0-9]{0,30}\\/'
      • .display_text contains 'challenges.cloudflare.com'

Inspects: body.links, body.links[].display_text, type.inbound. Sensors: html.xpath, ml.link_analysis, regex.icontains, strings.icontains, strings.istarts_with.

Indicators matched (3)

FieldMatchValue
regex.icontainsregex^\/[a-z0-9]{0,30}[!@][a-z0-9]{0,30}\/
regex.icontainsregex\/[a-zA-Z0-9]{0,30}[!@][a-zA-Z0-9]{0,30}\/
strings.icontainssubstringchallenges.cloudflare.com

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    or
      any(html.xpath(ml.link_analysis(body.links).final_dom, '//script//text()').nodes)
        any(html.xpath(ml.link_analysis(body.links).final_dom, '//script//text()').nodes.links)
          and
            not
              html.xpath(ml.link_analysis(body.links[]).final_dom, '//script//text()').nodes[].links[].href_url.domain.domain starts_with "www."
            not
              html.xpath(ml.link_analysis(body.links[]).final_dom, '//script//text()').nodes[].links[].href_url.domain.root_domain regex_match "(?:fpjs\\.io|(?:medium|unpkg|alicdn)\\.com|turtl\\.co)"
            not
              html.xpath(ml.link_analysis(body.links[]).final_dom, '//script//text()').nodes[].links[].href_url.path regex_match "\\/[!@][a-z]{2,30}\\/"
            html.xpath(ml.link_analysis(body.links[]).final_dom, '//script//text()').nodes[].links[].href_url.path regex_match "^\\/[a-z0-9]{0,30}[!@][a-z0-9]{0,30}\\/"
      and
        body.links.display_text contains "challenges.cloudflare.com"
        body.links.display_text regex_match "\\/[a-zA-Z0-9]{0,30}[!@][a-zA-Z0-9]{0,30}\\/"
  body.links length_compare "0"
  body.links length_compare "15"
  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"

Link: URL fragment with hexadecimal pattern obfuscation

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

Detects links containing URL fragments with repeating hexadecimal patterns, commonly used to obfuscate malicious destinations or bypass security filters.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        regex.contains(.href_url.fragment, '.html\/\?(?:[a-f0-9]{2}\.){12,}')
)

Detection logic

Scope: inbound message.

Detects links containing URL fragments with repeating hexadecimal patterns, commonly used to obfuscate malicious destinations or bypass security filters.

  1. inbound message
  2. any of body.links where:
    • .href_url.fragment matches '.html\\/\\?(?:[a-f0-9]{2}\\.){12,}'

Inspects: body.links, body.links[].href_url.fragment, type.inbound. Sensors: regex.contains.

Indicators matched (1)

FieldMatchValue
regex.containsregex.html\/\?(?:[a-f0-9]{2}\.){12,}

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    body.links.href_url.fragment regex_match ".html\\/\\?(?:[a-f0-9]{2}\\.){12,}"
  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"

Link: URL fragmented by hidden spans

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

Detects messages containing HTML links that are broken up with inline <span> elements styled with display:none, injecting random alphanumeric strings inside the URL to defeat text-based scanning while rendering strings that looks like a link to the recipient. Observed lures impersonate HR or payroll communications, such as fake 401K enrollment notices and PTO balance alerts, sent from unrelated or spoofed domains to drive clicks on the obfuscated link.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.html
  • type

Rule body

type.inbound
and strings.icontains(body.html.raw, 'https:/<span')
and regex.icontains(body.html.raw,
                    'https:/<span[^>]{0,300}display:\s*none[^>]{0,300}>[A-Z0-9]{6,}\s*</span>/'
)

Detection logic

Scope: inbound message.

Detects messages containing HTML links that are broken up with inline <span> elements styled with display:none, injecting random alphanumeric strings inside the URL to defeat text-based scanning while rendering strings that looks like a link to the recipient. Observed lures impersonate HR or payroll communications, such as fake 401K enrollment notices and PTO balance alerts, sent from unrelated or spoofed domains to drive clicks on the obfuscated link.

  1. inbound message
  2. body.html.raw contains 'https:/<span'
  3. body.html.raw matches 'https:/<span[^>]{0,300}display:\\s*none[^>]{0,300}>[A-Z0-9]{6,}\\s*</span>/'

Inspects: body.html.raw, type.inbound. Sensors: regex.icontains, strings.icontains.

Indicators matched (2)

FieldMatchValue
strings.icontainssubstringhttps:/<span
regex.icontainsregexhttps:/<span[^>]{0,300}display:\s*none[^>]{0,300}>[A-Z0-9]{6,}\s*</span>/

Stages and Predicates

Stage 1: mql_rule

and
  body.html.raw contains "https:/<span"
  body.html.raw regex_match "https:/<span[^>]{0,300}display:\\s*none[^>]{0,300}>[A-Z0-9]{6,}\\s*</span>/"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: URL path containing /moni/index

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

Detects inbound messages containing links to '/moni/index.' paths, either directly in the URL path or within query parameters. This pattern has been observed in the wild leading to credential phishing

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesOpen redirect, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • type

Rule body

type.inbound
and any(body.current_thread.links,
        regex.icontains(.href_url.path, '\/moni\/index\.')
        or any(values(.href_url.query_params_decoded),
               any(., regex.icontains(., '\/moni\/index\.'))
        )
        or .href_url.path == "/moni"
)

Detection logic

Scope: inbound message.

Detects inbound messages containing links to '/moni/index.' paths, either directly in the URL path or within query parameters. This pattern has been observed in the wild leading to credential phishing

  1. inbound message
  2. any of body.current_thread.links where any holds:
    • .href_url.path matches '\\/moni\\/index\\.'
    • any of values(.href_url.query_params_decoded) where:
      • any of . where:
        • . matches '\\/moni\\/index\\.'
    • .href_url.path is '/moni'

Inspects: body.current_thread.links, body.current_thread.links[].href_url.path, body.current_thread.links[].href_url.query_params_decoded, type.inbound. Sensors: regex.icontains.

Indicators matched (2)

FieldMatchValue
regex.icontainsregex\/moni\/index\.
body.current_thread.links[].href_url.pathequals/moni

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    or
      any(values(body.current_thread.links.href_url.query_params_decoded))
        any(values(body.current_thread.links.href_url.query_params_decoded))
          values(body.current_thread.links.href_url.query_params_decoded) regex_match "\\/moni\\/index\\."
      body.current_thread.links.href_url.path eq "/moni"
      body.current_thread.links.href_url.path regex_match "\\/moni\\/index\\."
  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"

Link: URL redirecting to blob URL

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

Detects messages containing links that redirect to blob URLs, indicating potential malware delivery or credential harvesting.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesEvasion, Free file host, Open redirect

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • recipients
  • recipients.to[0]
  • type

Rule body

type.inbound
and 0 < length(body.links) < 10
and length(recipients.to) == 1
and recipients.to[0].email.domain.valid
and any(body.links,
        // the url redirects to a blob url
        ml.link_analysis(.).effective_url.scheme =~ 'blob'
)

Detection logic

Scope: inbound message.

Detects messages containing links that redirect to blob URLs, indicating potential malware delivery or credential harvesting.

  1. inbound message
  2. all of:
    • length(body.links) > 0
    • length(body.links) < 10
  3. length(recipients.to) is 1
  4. recipients.to[0].email.domain.valid
  5. any of body.links where:
    • ml.link_analysis(.).effective_url.scheme is 'blob'

Inspects: body.links, recipients.to, recipients.to[0].email.domain.valid, type.inbound. Sensors: ml.link_analysis.

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    ml.link_analysis func_call "ml.link_analysis(body.links[]).effective_url.scheme =~ blob"
  body.links length_compare "0"
  body.links length_compare "10"
  recipients.to length_compare "1"
  recipients.to[0].email.domain.valid eq "true"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: URL scheme obfuscation via split HTML anchors

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

Detects URLs intentionally split across multiple adjacent HTML anchor tags to evade URL analysis and detection systems. This sophisticated evasion technique breaks the URL scheme (http/https) across separate anchor elements, rendering as: <a>h</a><a>ttp://malicious.com</a> The technique bypasses many security tools that expect complete, well-formed URLs while displaying a seemingly normal link to end users. This pattern is strongly associated with credential phishing and compromised email accounts. References: - Observed in wild credential phishing campaigns (2024-2025) - Evades traditional URL extraction and analysis tools

Threat classification

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

CategoryValues
Attack typesCredential Phishing, BEC/Fraud
Tactics and techniquesEvasion, HTML injection, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • type

Rule body

type.inbound
and length(body.current_thread.links) == 2
and length(filter(html.xpath(body.html, "//a").nodes,
                  .display_text == "h"
                  and any(.links, .href_url.scheme in ("http", "https"))
           )
) == 1
and length(filter(html.xpath(body.html, "//a").nodes,
                  (
                    strings.starts_with(.display_text, "ttp://")
                    or strings.starts_with(.display_text, "ttps://")
                  )
                  and any(.links, .href_url.scheme in ("http", "https"))
           )
) == 1

Detection logic

Scope: inbound message.

Detects URLs intentionally split across multiple adjacent HTML anchor tags to evade URL analysis and detection systems. This sophisticated evasion technique breaks the URL scheme (http/https) across separate anchor elements, rendering as: <a>h</a><a>ttp://malicious.com</a> The technique bypasses many security tools that expect complete, well-formed URLs while displaying a seemingly normal link to end users. This pattern is strongly associated with credential phishing and compromised email accounts. References: - Observed in wild credential phishing campaigns (2024-2025) - Evades traditional URL extraction and analysis tools

  1. inbound message
  2. length(body.current_thread.links) is 2
  3. length(filter(html.xpath(body.html, '//a').nodes, .display_text == 'h' and any(.links, .href_url.scheme in ('http', 'https')))) is 1
  4. length(filter(html.xpath(body.html, '//a').nodes, strings.starts_with(.display_text, 'ttp://') or strings.starts_with(.display_text, 'ttps://') and any(.links, .href_url.scheme in ('http', 'https')))) is 1

Inspects: body.current_thread.links, body.html, type.inbound. Sensors: html.xpath, strings.starts_with.

Indicators matched (5)

FieldMatchValue
html.xpath(body.html, '//a').nodes[].display_textequalsh
html.xpath(body.html, '//a').nodes[].links[].href_url.schemememberhttp
html.xpath(body.html, '//a').nodes[].links[].href_url.schemememberhttps
strings.starts_withprefixttp://
strings.starts_withprefixttps://

Stages and Predicates

Stage 1: mql_rule

and
  body.current_thread.links length_compare "2"
  filter(html.xpath(body.html, '//a').nodes, .display_text == 'h' and any(.links, .href_url.scheme in ('http', 'https'))) length_compare "1"
  filter(html.xpath(body.html, '//a').nodes, strings.starts_with(.display_text, 'ttp://') or strings.starts_with(.display_text, 'ttps://') and any(.links, .href_url.scheme in ('http', 'https'))) length_compare "1"
  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"

Link: URL shortener chaining to workers.dev redirect

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

Detects inbound messages containing shortened links that ultimately redirect to or embed content hosted on workers.dev, a Cloudflare Workers subdomain frequently abused to host credential phishing or malicious redirect infrastructure. Observed lures include fake business inquiry notifications, advertising account verification alerts, and order/checkout confirmation messages designed to entice recipients into clicking the shortened link. This chaining technique obscures the final malicious destination behind a trusted URL shortener before landing on abused cloud infrastructure.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesOpen redirect, Free subdomain host, Social engineering, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        .href_url.domain.domain in $url_shorteners
        and (
          any(ml.link_analysis(.).final_dom.links,
              .href_url.domain.root_domain == "workers.dev"
          )

          // or the thing just redirects to workers.dev directly
          or any(ml.link_analysis(.).redirect_history,
                 .domain.root_domain == "workers.dev"
          )
        )
)

Detection logic

Scope: inbound message.

Detects inbound messages containing shortened links that ultimately redirect to or embed content hosted on workers.dev, a Cloudflare Workers subdomain frequently abused to host credential phishing or malicious redirect infrastructure. Observed lures include fake business inquiry notifications, advertising account verification alerts, and order/checkout confirmation messages designed to entice recipients into clicking the shortened link. This chaining technique obscures the final malicious destination behind a trusted URL shortener before landing on abused cloud infrastructure.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.domain.domain in $url_shorteners
    • any of:
      • any of ml.link_analysis(.).final_dom.links where:
        • .href_url.domain.root_domain is 'workers.dev'
      • any of ml.link_analysis(.).redirect_history where:
        • .domain.root_domain is 'workers.dev'

Inspects: body.links, body.links[].href_url.domain.domain, type.inbound. Sensors: ml.link_analysis. Reference lists: $url_shorteners.

Indicators matched (2)

FieldMatchValue
ml.link_analysis(body.links[]).final_dom.links[].href_url.domain.root_domainequalsworkers.dev
ml.link_analysis(body.links[]).redirect_history[].domain.root_domainequalsworkers.dev

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        any(ml.link_analysis(body.links).final_dom.links)
          ml.link_analysis(body.links).final_dom.links.href_url.domain.root_domain eq "workers.dev"
        any(ml.link_analysis(body.links).redirect_history)
          ml.link_analysis(body.links).redirect_history.domain.root_domain eq "workers.dev"
       macro "body.links[].href_url.domain.domain in url_shorteners"
  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"

Link: URL shortener with copy-paste instructions and credential theft language

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

Detects messages containing only URL shorteners with copy-paste instructions and high-confidence credential theft language, typically used to evade URL analysis by requiring manual URL entry.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • recipients
  • recipients.to
  • recipients.to[0]
  • sender.email
  • type

Rule body

type.inbound
and length(body.current_thread.links) > 0
and all(body.current_thread.links,
        .href_url.domain.root_domain in $url_shorteners
)
and (
  strings.icontains(body.current_thread.text, 'copy')
  and (
    strings.icontains(body.current_thread.text, 'pasting')
    or strings.icontains(body.current_thread.text, 'paste')
  )
)
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == 'cred_theft' and .confidence == 'high'
)
and (
  // self sender
  (
    length(recipients.to) == 1
    and sender.email.email == recipients.to[0].email.email
  )
  // or the sender is all undisclosed or there is no recipients
  or (
    length(recipients.to) == 0
    or all(recipients.to, .email.domain.valid == false)
  )
)
// negate display urls that match the sender root domain
and not any(body.current_thread.links,
            .display_url.domain.root_domain == sender.email.domain.root_domain
)

Detection logic

Scope: inbound message.

Detects messages containing only URL shorteners with copy-paste instructions and high-confidence credential theft language, typically used to evade URL analysis by requiring manual URL entry.

  1. inbound message
  2. length(body.current_thread.links) > 0
  3. all of body.current_thread.links where:
    • .href_url.domain.root_domain in $url_shorteners
  4. all of:
    • body.current_thread.text contains 'copy'
    • any of:
      • body.current_thread.text contains 'pasting'
      • body.current_thread.text contains 'paste'
  5. any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
    • .name is 'cred_theft'
    • .confidence is 'high'
  6. any of:
    • all of:
      • length(recipients.to) is 1
      • sender.email.email is recipients.to[0].email.email
    • any of:
      • length(recipients.to) is 0
      • all of recipients.to where:
        • .email.domain.valid is False
  7. not:
    • any of body.current_thread.links where:
      • .display_url.domain.root_domain is sender.email.domain.root_domain

Inspects: body.current_thread.links, body.current_thread.links[].display_url.domain.root_domain, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.text, recipients.to, recipients.to[0].email.email, recipients.to[].email.domain.valid, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: ml.nlu_classifier, strings.icontains. Reference lists: $url_shorteners.

Indicators matched (5)

FieldMatchValue
strings.icontainssubstringcopy
strings.icontainssubstringpasting
strings.icontainssubstringpaste
ml.nlu_classifier(body.current_thread.text).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh

Stages and Predicates

Stage 1: mql_rule

and
  not
    any(body.current_thread.links)
      body.current_thread.links.display_url.domain.root_domain cross_field_compare "sender.email.domain.root_domain"
  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"
  or
    and
      recipients.to length_compare "1"
      sender.email.email cross_field_compare "recipients.to[0].email.email"
    recipients.to length_compare "0"
     macro "all(recipients.to)"
  or
    body.current_thread.text contains "paste"
    body.current_thread.text contains "pasting"
  body.current_thread.links length_compare "0"
  body.current_thread.text contains "copy"
  type.inbound eq "true"
   macro "all(body.current_thread.links)"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
body.current_thread.linksarray_any(no value, null check)excludes:body.current_thread.links

Indicators

These rows show field, operator, and value matches.

Link: URL using underscore-dot substitution in display text

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

Detects inbound messages containing links where the display text starts with 'https://' and uses an underscore followed by 'com/' in place of a standard dot-com domain format (e.g., 'example_com/'). This technique is used to bypass display text URL parsing, as the malformed URL cannot be resolved by standard URL parsers.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        strings.starts_with(.display_text, 'https://')
        and strings.contains(.display_text, '_com/')
        and not strings.contains(.display_text, '.com/')
        and strings.parse_url(.display_text).url is null
)

Detection logic

Scope: inbound message.

Detects inbound messages containing links where the display text starts with 'https://' and uses an underscore followed by 'com/' in place of a standard dot-com domain format (e.g., 'example_com/'). This technique is used to bypass display text URL parsing, as the malformed URL cannot be resolved by standard URL parsers.

  1. inbound message
  2. any of body.links where all hold:
    • .display_text starts with 'https://'
    • .display_text contains '_com/'
    • not:
      • .display_text contains '.com/'
    • strings.parse_url(.display_text).url is missing

Inspects: body.links, body.links[].display_text, type.inbound. Sensors: strings.contains, strings.parse_url, strings.starts_with.

Indicators matched (2)

FieldMatchValue
strings.starts_withprefixhttps://
strings.containssubstring_com/

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      not
        body.links.display_text contains ".com/"
      body.links.display_text contains "_com/"
      body.links.display_text starts_with "https://"
      strings.parse_url(body.links[].display_text).url is_null
  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"

Link: Webflow link from unsolicited sender

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

This detection rule matches on messaging containing at least one link to webflow.io from an unsolicited sender. Webflow.io provides a free plan enabling users to create custom websites and file hosting. This services has been abused by threat actors to host landing pages directing victims to a next stage of credential phishing.

Threat classification

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

CategoryValues
Attack typesCallback Phishing
Tactics and techniquesFree file host, Free subdomain host

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 any(body.links,
        // webflow link
        .href_url.domain.root_domain == 'webflow.io'
        and .href_url.domain.subdomain != ""
        and .href_url.domain.subdomain != "www"
        and .href_url.path == "/"
)
// not solicited or from malicious/spam user with no FPs
and (
  not profile.by_sender_email().solicited
  or (
    profile.by_sender_email().any_messages_malicious_or_spam
    and not profile.by_sender_email().any_messages_benign
  )
)

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

This detection rule matches on messaging containing at least one link to webflow.io from an unsolicited sender. Webflow.io provides a free plan enabling users to create custom websites and file hosting. This services has been abused by threat actors to host landing pages directing victims to a next stage of credential phishing.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.domain.root_domain is 'webflow.io'
    • .href_url.domain.subdomain is not ''
    • .href_url.domain.subdomain is not 'www'
    • .href_url.path is '/'
  3. any of:
    • not:
      • profile.by_sender_email().solicited
    • all of:
      • profile.by_sender_email().any_messages_malicious_or_spam
      • not:
        • profile.by_sender_email().any_messages_benign
  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.links, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.subdomain, body.links[].href_url.path, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender_email. Reference lists: $high_trust_sender_root_domains.

Indicators matched (2)

FieldMatchValue
body.links[].href_url.domain.root_domainequalswebflow.io
body.links[].href_url.pathequals/

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_email func_call "profile.by_sender_email().any_messages_benign"
      profile.by_sender_email func_call "profile.by_sender_email().any_messages_malicious_or_spam"
    not
      profile.by_sender_email func_call "profile.by_sender_email().solicited"
  any(body.links)
    and
      body.links.href_url.domain.root_domain eq "webflow.io"
      body.links.href_url.domain.subdomain ne ""
      body.links.href_url.domain.subdomain ne "www"
      body.links.href_url.path eq "/"
  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"

Link: WordPress admin targeting with recipient identifier in URL parts

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

Detects messages containing links to WordPress administrative paths (wp-admin, wp-content, wp-includes, etc.) where the URL fragment or query param values contains base64-encoded data that includes the recipient's email address, indicating potential targeted compromise attempts.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • recipients
  • recipients.to[0]
  • type

Rule body

type.inbound
and recipients.to[0].email.domain.valid
and any(body.links,
        regex.icontains(.href_url.path,
                        '\/(?:wp-(?:admin|includes|content|login|json|signup|activate|cron|mail)|xmlrpc\.php)'
        )
        and (
          // fragments base64 encoded
          any(strings.scan_base64(.href_url.fragment),
              strings.icontains(., recipients.to[0].email.email)
          )
          // fragments not base64 encoded
          or strings.icontains(.href_url.fragment, recipients.to[0].email.email)
          // query param values are exactly the recipient
          or (
            any(flatten(values(.href_url.query_params_decoded)),
                . == recipients.to[0].email.email
                or any(strings.scan_base64(.),
                       . == recipients.to[0].email.email
                )
            )
            // not an unsub URL
            and not strings.icontains(.href_url.url, 'unsub')
            // less than two query_params
            and length(keys(.href_url.query_params_decoded)) <= 2
          )
        )
)

Detection logic

Scope: inbound message.

Detects messages containing links to WordPress administrative paths (wp-admin, wp-content, wp-includes, etc.) where the URL fragment or query param values contains base64-encoded data that includes the recipient's email address, indicating potential targeted compromise attempts.

  1. inbound message
  2. recipients.to[0].email.domain.valid
  3. any of body.links where all hold:
    • .href_url.path matches '\\/(?:wp-(?:admin|includes|content|login|json|signup|activate|cron|mail)|xmlrpc\\.php)'
    • any of:
      • any of strings.scan_base64(.href_url.fragment) where:
        • strings.icontains(.)
      • strings.icontains(.href_url.fragment)
      • all of:
        • any of flatten(...) where any holds:
          • . is recipients.to[0].email.email
          • any of strings.scan_base64(.) where:
            • . is recipients.to[0].email.email
        • not:
          • .href_url.url contains 'unsub'
        • length(keys(.href_url.query_params_decoded)) ≤ 2

Inspects: body.links, body.links[].href_url.fragment, body.links[].href_url.path, body.links[].href_url.query_params_decoded, body.links[].href_url.url, recipients.to[0].email.domain.valid, recipients.to[0].email.email, type.inbound. Sensors: regex.icontains, strings.icontains, strings.scan_base64.

Indicators matched (1)

FieldMatchValue
regex.icontainsregex\/(?:wp-(?:admin|includes|content|login|json|signup|activate|cron|mail)|xmlrpc\.php)

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        and
          any(flatten(...))
            or
              any(strings.scan_base64(flatten(...)))
                strings.scan_base64(flatten(...)) cross_field_compare "recipients.to[0].email.email"
              flatten(...) cross_field_compare "recipients.to[0].email.email"
          not
            body.links.href_url.url contains "unsub"
          keys(body.links[].href_url.query_params_decoded) length_compare "2"
        any(strings.scan_base64(body.links.href_url.fragment))
          strings.icontains func_call "strings.icontains(strings.scan_base64(body.links[].href_url.fragment)[])"
        strings.icontains func_call "strings.icontains(body.links[].href_url.fragment)"
      body.links.href_url.path regex_match "\\/(?:wp-(?:admin|includes|content|login|json|signup|activate|cron|mail)|xmlrpc\\.php)"
  recipients.to[0].email.domain.valid eq "true"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Link: Zoho form link from unsolicited sender

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

This detection rule matches on messages containing at least one link to forms.zohopublic.com from an unsolicited sender. Zoho provides a free plan enabling users to create custom websites and file hosting. This service has been abused by threat actors to host landing pages via forms directing victims to a next stage of credential phishing.

Threat classification

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

CategoryValues
Attack typesCallback Phishing
Tactics and techniquesFree file host

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
// filter links to zoho forms
and any(filter(body.links,
               // zoho forms link
               .href_url.domain.domain == 'forms.zohopublic.com'
               // remove a common FP for linking directly 
               and not strings.istarts_with(.href_url.path, '/quickbooking/')
        ),
        // remove FPs by checking there is only one link
        // ensure the link is within the current_thread
        (
          strings.contains(body.current_thread.text, .display_text)
          or strings.contains(body.current_thread.text, .href_url.url)
        )
        // and ensure that link only occurs once within body.html
        and (
          (
            body.html.raw is not null
            and (
              strings.count(body.html.raw, .display_text) == 1
              or strings.count(body.html.raw, .href_url.url) == 1
            )
          )
          or (
            // and ensure that link only occurs once within plaintext if html.raw is null
            body.plain.raw is not null
            and (
              strings.count(body.plain.raw, .display_text) == 1
              or strings.count(body.plain.raw, .href_url.url) == 1
            )
          )
        )
)

// dont match messages with lots of links or long bodies, often marketing messages
and length(body.links) < 20
and length(body.current_thread.text) < 900
// not solicited or from malicious/spam user with no FPs
and (
  not profile.by_sender().solicited
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)

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

This detection rule matches on messages containing at least one link to forms.zohopublic.com from an unsolicited sender. Zoho provides a free plan enabling users to create custom websites and file hosting. This service has been abused by threat actors to host landing pages via forms directing victims to a next stage of credential phishing.

  1. inbound message
  2. any of filter(body.links) where all hold:
    • any of:
      • strings.contains(body.current_thread.text)
      • strings.contains(body.current_thread.text)
    • any of:
      • all of:
        • body.html.raw is set
        • any of:
          • strings.count(body.html.raw) is 1
          • strings.count(body.html.raw) is 1
      • all of:
        • body.plain.raw is set
        • any of:
          • strings.count(body.plain.raw) is 1
          • strings.count(body.plain.raw) is 1
  3. length(body.links) < 20
  4. length(body.current_thread.text) < 900
  5. any of:
    • not:
      • profile.by_sender().solicited
    • 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, body.html.raw, body.links, body.links[].href_url.domain.domain, body.links[].href_url.path, body.plain.raw, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender, strings.contains, strings.count, strings.istarts_with. Reference lists: $high_trust_sender_root_domains.

Indicators matched (1)

FieldMatchValue
body.links[].href_url.domain.domainequalsforms.zohopublic.com

Stages and Predicates

Stage 1: mql_rule

and
  any(filter(body.links))
    and
      or
        and
          body.html.raw is_not_null
          strings.count func_call "strings.count(body.html.raw) == 1"
        and
          body.plain.raw is_not_null
          strings.count func_call "strings.count(body.plain.raw) == 1"
      strings.contains func_call "strings.contains(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"
    not
      profile.by_sender func_call "profile.by_sender().solicited"
  body.current_thread.text length_compare "900"
  body.links length_compare "20"
  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"

Low reputation link to auto-downloaded HTML file with smuggling indicators

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

Message contains a low reputation link to an automatically downloaded HTML file that contains HTML smuggling indicators, such as atob function use, excessive hexadecimal (0x) usage, etc.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Free file host, Free subdomain host, HTML smuggling, Impersonation: Brand, Open redirect, Social engineering

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        (
          .href_url.domain.root_domain not in $tranco_1m
          or .href_url.domain.domain in $free_file_hosts
          or .href_url.domain.root_domain in $free_file_hosts
          or .href_url.domain.root_domain in $free_subdomain_hosts
          or .href_url.domain.domain in $url_shorteners
          or .href_url.domain.domain in $social_landing_hosts
          or 

          // mass mailer link, masks the actual URL
          .href_url.domain.root_domain in (
            "hubspotlinks.com",
            "mandrillapp.com",
            "sendgrid.net",
            "rs6.net"
          )

          // Google AMP redirect
          or (
            .href_url.domain.sld == "google"
            and strings.starts_with(.href_url.path, "/amp/")
          )
        )

        // exclude sources of potential FPs
        and (
          .href_url.domain.root_domain not in (
            "svc.ms",
            "sharepoint.com",
            "1drv.ms",
            "microsoft.com",
            "aka.ms",
            "msftauthimages.net",
            "mimecastprotect.com",
            "office.com"
          )
          or .href_url.domain.domain in $free_file_hosts
        )
        and .href_url.domain.root_domain not in $org_domains
        and .href_url.domain.valid
)
and any(body.links,
        any(ml.link_analysis(.).files_downloaded,
            any(file.explode(.),
                .scan.entropy.entropy >= 5
                and (
                  length(filter(.scan.javascript.identifiers,
                                strings.like(.,
                                             "document",
                                             "write",
                                             "atob",
                                             "onload"
                                )
                         )
                  ) > 2
                  // usage: document['write'](atob)
                  or any(.scan.strings.strings,
                         regex.icontains(., "document.{0,10}write.{0,10}atob")
                  )
                  or any(.scan.strings.strings, strings.icount(., "_0x") > 50)
                  // usage: some_var = atob();
                  or any(.scan.strings.strings,
                         regex.icontains(., "=.?atob.*;")
                  )
                  // usage: atob(atob
                  or any(.scan.strings.strings, strings.ilike(., "*atob?atob*"))
                  // usage: eval(atob)
                  or any(.scan.strings.strings, strings.ilike(., "*eval?atob*"))
                  // usage: atob(_0x)
                  or any(.scan.strings.strings, strings.ilike(., "*atob(?0x*"))
                  // usage: obfuscating "atob"
                  or any(.scan.javascript.identifiers,
                         strings.ilike(., '*ato\u0062*')
                  )
                  // usage: document.head.insertAdjacentHTML("beforeend", atob(...
                  or any(.scan.strings.strings,
                         strings.ilike(., "*document*insertAdjacentHTML*atob*")
                  )
                )
            )
        )
)
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.

Message contains a low reputation link to an automatically downloaded HTML file that contains HTML smuggling indicators, such as atob function use, excessive hexadecimal (0x) usage, etc.

  1. inbound message
  2. any of body.links where all hold:
    • any of:
      • .href_url.domain.root_domain not in $tranco_1m
      • .href_url.domain.domain in $free_file_hosts
      • .href_url.domain.root_domain in $free_file_hosts
      • .href_url.domain.root_domain in $free_subdomain_hosts
      • .href_url.domain.domain in $url_shorteners
      • .href_url.domain.domain in $social_landing_hosts
      • .href_url.domain.root_domain in ('hubspotlinks.com', 'mandrillapp.com', 'sendgrid.net', 'rs6.net')
      • all of:
        • .href_url.domain.sld is 'google'
        • .href_url.path starts with '/amp/'
    • any of:
      • .href_url.domain.root_domain not in ('svc.ms', 'sharepoint.com', '1drv.ms', 'microsoft.com', 'aka.ms', 'msftauthimages.net', 'mimecastprotect.com', 'office.com')
      • .href_url.domain.domain in $free_file_hosts
    • .href_url.domain.root_domain not in $org_domains
    • .href_url.domain.valid
  3. any of body.links where:
    • any of ml.link_analysis(.).files_downloaded where:
      • any of file.explode(.) where all hold:
        • .scan.entropy.entropy ≥ 5
        • any of:
          • length(filter(.scan.javascript.identifiers, strings.like(., 'document', 'write', 'atob', 'onload'))) > 2
          • any of .scan.strings.strings where:
            • . matches 'document.{0,10}write.{0,10}atob'
          • any of .scan.strings.strings where:
            • strings.icount(., '_0x') > 50
          • any of .scan.strings.strings where:
            • . matches '=.?atob.*;'
          • any of .scan.strings.strings where:
            • . matches '*atob?atob*'
          • any of .scan.strings.strings where:
            • . matches '*eval?atob*'
          • any of .scan.strings.strings where:
            • . matches '*atob(?0x*'
          • any of .scan.javascript.identifiers where:
            • . matches '*ato\\u0062*'
          • any of .scan.strings.strings where:
            • . matches '*document*insertAdjacentHTML*atob*'
  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.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.sld, body.links[].href_url.domain.valid, body.links[].href_url.path, type.inbound. Sensors: file.explode, ml.link_analysis, profile.by_sender, regex.icontains, strings.icount, strings.ilike, strings.like, strings.starts_with. Reference lists: $free_file_hosts, $free_subdomain_hosts, $org_domains, $social_landing_hosts, $tranco_1m, $url_shorteners.

Indicators matched (17)

FieldMatchValue
body.links[].href_url.domain.root_domainmemberhubspotlinks.com
body.links[].href_url.domain.root_domainmembermandrillapp.com
body.links[].href_url.domain.root_domainmembersendgrid.net
body.links[].href_url.domain.root_domainmemberrs6.net
body.links[].href_url.domain.sldequalsgoogle
strings.starts_withprefix/amp/
strings.likesubstringdocument
strings.likesubstringwrite
strings.likesubstringatob
strings.likesubstringonload
regex.icontainsregexdocument.{0,10}write.{0,10}atob
regex.icontainsregex=.?atob.*;
5 more
strings.ilikesubstring*atob?atob*
strings.ilikesubstring*eval?atob*
strings.ilikesubstring*atob(?0x*
strings.ilikesubstring*ato\u0062*
strings.ilikesubstring*document*insertAdjacentHTML*atob*

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    any(ml.link_analysis(body.links).files_downloaded)
      any(file.explode(ml.link_analysis(body.links).files_downloaded))
        and
          or
            any(file.explode(ml.link_analysis(body.links).files_downloaded).scan.javascript.identifiers)
              file.explode(ml.link_analysis(body.links).files_downloaded).scan.javascript.identifiers match "ato\\u0062"
            any(file.explode(ml.link_analysis(body.links).files_downloaded).scan.strings.strings)
              file.explode(ml.link_analysis(body.links).files_downloaded).scan.strings.strings match "atob(?0x"
            any(file.explode(ml.link_analysis(body.links).files_downloaded).scan.strings.strings)
              file.explode(ml.link_analysis(body.links).files_downloaded).scan.strings.strings match "atob?atob"
            any(file.explode(ml.link_analysis(body.links).files_downloaded).scan.strings.strings)
              file.explode(ml.link_analysis(body.links).files_downloaded).scan.strings.strings match "eval?atob"
            any(file.explode(ml.link_analysis(body.links).files_downloaded).scan.strings.strings)
              file.explode(ml.link_analysis(body.links).files_downloaded).scan.strings.strings regex_match "=.?atob.*;"
            any(file.explode(ml.link_analysis(body.links).files_downloaded).scan.strings.strings)
              file.explode(ml.link_analysis(body.links).files_downloaded).scan.strings.strings regex_match "document.{0,10}write.{0,10}atob"
            any(file.explode(ml.link_analysis(body.links).files_downloaded).scan.strings.strings)
              file.explode(ml.link_analysis(body.links).files_downloaded).scan.strings.strings wildcard "*document*insertAdjacentHTML*atob*"
            any(file.explode(ml.link_analysis(body.links).files_downloaded).scan.strings.strings)
              strings.icount func_call "strings.icount(file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].scan.strings.strings[], \"_0x\") > 50"
            filter(file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].scan.javascript.identifiers, strings.like(file.explode(ml.link_analysis(body.links[]).files_downloaded[])[], 'document', 'write', 'atob', 'onload')) length_compare "2"
          file.explode(ml.link_analysis(body.links[]).files_downloaded[])[].scan.entropy.entropy ge "5"
  any(body.links)
    and
      or
        not
          body.links.href_url.domain.root_domain in ["1drv.ms", "aka.ms", "microsoft.com", "mimecastprotect.com", "msftauthimages.net", "office.com", "sharepoint.com", "svc.ms"]
         macro "body.links[].href_url.domain.domain in free_file_hosts"
      or
        and
          body.links.href_url.domain.sld eq "google"
          body.links.href_url.path starts_with "/amp/"
        body.links.href_url.domain.root_domain in ["hubspotlinks.com", "mandrillapp.com", "rs6.net", "sendgrid.net"]
         macro "body.links[].href_url.domain.domain in free_file_hosts"
         macro "body.links[].href_url.domain.domain in social_landing_hosts"
         macro "body.links[].href_url.domain.domain in url_shorteners"
         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 not in tranco_1m"
      body.links.href_url.domain.valid eq "true"
       macro "body.links[].href_url.domain.root_domain not in org_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"
  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"

Malware: Pikabot delivery via URL auto-download

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

This rule detects URLs matching a known Pikabot pattern where the linked domain has been reported to URLhaus, or the link downloads an archive containing a JS file, or a file in the archive hash is found in Malware Bazaar.

Threat classification

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

CategoryValues
Attack typesMalware/Ransomware
Tactics and techniquesEvasion

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 any(body.links,
        regex.imatch(.display_url.url, '.+\/[a-z0-9]+\/\?[0-9a-z]+')
)
and (
  any(body.links,
      .href_url.domain.domain in $abuse_ch_urlhaus_domains_trusted_reporters
      and not .href_url.domain.domain in ("drive.google.com", "github.com")
  )
  or any(body.links,
         any(ml.link_analysis(., mode="aggressive").files_downloaded,
             .file_extension in~ $file_extensions_common_archives
             and (
               any(file.explode(.),
                   .file_extension =~ "js"
                   or .scan.hash.sha256 in $abuse_ch_malwarebazaar_sha256_trusted_reporters
               )
             )
         )
  )
)

// 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 detects URLs matching a known Pikabot pattern where the linked domain has been reported to URLhaus, or the link downloads an archive containing a JS file, or a file in the archive hash is found in Malware Bazaar.

  1. inbound message
  2. any of body.links where:
    • .display_url.url matches '.+\\/[a-z0-9]+\\/\\?[0-9a-z]+'
  3. any of:
    • any of body.links where all hold:
      • .href_url.domain.domain in $abuse_ch_urlhaus_domains_trusted_reporters
      • not:
        • .href_url.domain.domain in ('drive.google.com', 'github.com')
    • any of body.links where:
      • any of ml.link_analysis(., mode='aggressive').files_downloaded where all hold:
        • .file_extension in $file_extensions_common_archives
        • any of file.explode(.) where any holds:
          • .file_extension is 'js'
          • .scan.hash.sha256 in $abuse_ch_malwarebazaar_sha256_trusted_reporters
  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. any of:
    • not:
      • profile.by_sender().solicited
    • profile.by_sender().any_messages_malicious_or_spam

Inspects: body.links, body.links[].display_url.url, body.links[].href_url.domain.domain, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: file.explode, ml.link_analysis, profile.by_sender, regex.imatch. Reference lists: $abuse_ch_malwarebazaar_sha256_trusted_reporters, $abuse_ch_urlhaus_domains_trusted_reporters, $file_extensions_common_archives, $high_trust_sender_root_domains.

Indicators matched (2)

FieldMatchValue
regex.imatchregex.+\/[a-z0-9]+\/\?[0-9a-z]+
file.explode(ml.link_analysis(body.links[], mode='aggressive').files_downloaded[])[].file_extensionequalsjs

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(body.links)
      any(ml.link_analysis(body.links, mode='aggressive').files_downloaded)
        and
          any(file.explode(ml.link_analysis(body.links, mode='aggressive').files_downloaded))
            or
              file.explode(ml.link_analysis(body.links[], mode='aggressive').files_downloaded[])[].file_extension eq "js"
               macro "file.explode(ml.link_analysis(body.links[], mode='aggressive').files_downloaded[])[].scan.hash.sha256 in abuse_ch_malwarebazaar_sha256_trusted_reporters"
           macro "ml.link_analysis(body.links[], mode='aggressive').files_downloaded[].file_extension in file_extensions_common_archives"
    any(body.links)
      and
        not
          body.links.href_url.domain.domain in ["drive.google.com", "github.com"]
         macro "body.links[].href_url.domain.domain in abuse_ch_urlhaus_domains_trusted_reporters"
  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"
  any(body.links)
    body.links.display_url.url regex_match ".+\\/[a-z0-9]+\\/\\?[0-9a-z]+"
  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"

Microsoft device code phishing

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

An attacker may generate a user code and send it to a target mailbox. With an appropriate lure, the targeted user may action the device code login and provide an attacker with the means to take over their account. This rule looks for the presence of the Microsoft device login portal link, as well as mentions of 'device code' or a 9 character alphanumeric device code value.

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.html
  • body.links
  • sender.email
  • type

Rule body

type.inbound

// Not from MS as the device code will be generated and sent by the attacker
and sender.email.domain.root_domain not in~ (
  "microsoft.com",
  "microsoftonline.com"
)

// Link to the device code MS pages
and any(body.links,
        (
          .href_url.url == "https://microsoft.com/devicelogin"
          or .href_url.url == "https://login.microsoftonline.com/common/oauth2/deviceauth"
          or .href_url.url == "https://aka.ms/devicelogin"
        )
)

// Body text references device codes
and (
  strings.icontains(body.html.display_text, "device code")
  or 
  // A nine character string containing a combination of letters and characters
  regex.icontains(body.html.display_text, '[\W]([A-Z0-9]{9})[\W]')
)
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.

An attacker may generate a user code and send it to a target mailbox. With an appropriate lure, the targeted user may action the device code login and provide an attacker with the means to take over their account. This rule looks for the presence of the Microsoft device login portal link, as well as mentions of 'device code' or a 9 character alphanumeric device code value.

  1. inbound message
  2. sender.email.domain.root_domain not in ('microsoft.com', 'microsoftonline.com')
  3. any of body.links where any holds:
    • .href_url.url is 'https://microsoft.com/devicelogin'
    • .href_url.url is 'https://login.microsoftonline.com/common/oauth2/deviceauth'
    • .href_url.url is 'https://aka.ms/devicelogin'
  4. any of:
    • body.html.display_text contains 'device code'
    • body.html.display_text matches '[\\W]([A-Z0-9]{9})[\\W]'
  5. 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.html.display_text, body.links, body.links[].href_url.url, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender, regex.icontains, strings.icontains.

Indicators matched (5)

FieldMatchValue
body.links[].href_url.urlequalshttps://microsoft.com/devicelogin
body.links[].href_url.urlequalshttps://login.microsoftonline.com/common/oauth2/deviceauth
body.links[].href_url.urlequalshttps://aka.ms/devicelogin
strings.icontainssubstringdevice code
regex.icontainsregex[\W]([A-Z0-9]{9})[\W]

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(body.links)
    or
      body.links.href_url.url eq "https://aka.ms/devicelogin"
      body.links.href_url.url eq "https://login.microsoftonline.com/common/oauth2/deviceauth"
      body.links.href_url.url eq "https://microsoft.com/devicelogin"
  or
    body.html.display_text contains "device code"
    body.html.display_text regex_match "[\\W]([A-Z0-9]{9})[\\W]"
  not
    sender.email.domain.root_domain in ["microsoft.com", "microsoftonline.com"]
  type.inbound eq "true"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

New link domain (<=10d) from untrusted sender

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

Detects links in the body of an email where the linked domain is less than 10 days old from untrusted senders.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and length(body.links) > 0
and any(body.links,
        network.whois(.href_url.domain).days_old <= 10
        // Mimecast link logic
        or (
          .href_url.domain.root_domain in (
            "mimecastprotect.com",
            "mimecast.com"
          )
          and any(.href_url.query_params_decoded['domain'],
                  network.whois(strings.parse_domain(.)).days_old <= 10
          )
        )
)
and (
  (
    profile.by_sender().prevalence in ("new", "outlier")
    and not profile.by_sender().solicited
  )
  or profile.by_sender().any_messages_malicious_or_spam
)
// negate senders which have had previous messages marked as benign which pass auth
and not (
  profile.by_sender().any_messages_benign
  and profile.by_sender().auth_failed == false
)

Detection logic

Scope: inbound message.

Detects links in the body of an email where the linked domain is less than 10 days old from untrusted senders.

  1. inbound message
  2. length(body.links) > 0
  3. any of body.links where any holds:
    • network.whois(.href_url.domain).days_old ≤ 10
    • all of:
      • .href_url.domain.root_domain in ('mimecastprotect.com', 'mimecast.com')
      • any of .href_url.query_params_decoded['domain'] where:
        • network.whois(strings.parse_domain(.)).days_old ≤ 10
  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:
    • all of:
      • profile.by_sender().any_messages_benign
      • profile.by_sender().auth_failed is False

Inspects: body.links, body.links[].href_url.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.query_params_decoded['domain'], type.inbound. Sensors: network.whois, profile.by_sender, strings.parse_domain.

Indicators matched (2)

FieldMatchValue
body.links[].href_url.domain.root_domainmembermimecastprotect.com
body.links[].href_url.domain.root_domainmembermimecast.com

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    or
      and
        any(body.links.href_url.query_params_decoded['domain'])
          network.whois func_call "network.whois(strings.parse_domain(body.links[].href_url.query_params_decoded['domain'][])).days_old <= 10"
        body.links.href_url.domain.root_domain in ["mimecast.com", "mimecastprotect.com"]
      network.whois func_call "network.whois(body.links[].href_url.domain).days_old <= 10"
  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
    and
      profile.by_sender func_call "profile.by_sender().any_messages_benign"
      profile.by_sender func_call "profile.by_sender().auth_failed == false"
  body.links length_compare "0"
  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"

Notion suspicious file share

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

Message contains a notion link that contains suspicious terms. You may need to deactivate or fork this rule if your organization uses Notion.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesEvasion, Free file host

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • sender.email
  • type

Rule body

type.inbound
and any(body.links,
        .href_url.domain.root_domain in~ ("notion.so", "notion.site")
        and (
          strings.ilike(.href_url.url,
                        '*shared*',
                        '*document*',
                        '*secure*',
                        '*office*',
                        '*important*',
                        '*wants-to*',
                        '*share*',
                        '*statement*'
          )
          or strings.ilike(.display_url.url,
                           '*shared*',
                           '*document*',
                           '*secure*',
                           '*office*',
                           '*important*',
                           '*wants-to*',
                           '*share*',
                           '*statement*'
          )
          or strings.ilike(.display_text,
                           '*shared*',
                           '*document*',
                           '*secure*',
                           '*office*',
                           '*important*',
                           '*wants-to*',
                           '*share*',
                           '*statement*'
          )
        )
)
and sender.email.domain.domain != 'mail.notion.so'
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.

Message contains a notion link that contains suspicious terms. You may need to deactivate or fork this rule if your organization uses Notion.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.domain.root_domain in ('notion.so', 'notion.site')
    • any of:
      • .href_url.url matches any of 8 patterns
        • *shared*
        • *document*
        • *secure*
        • *office*
        • *important*
        • *wants-to*
        • *share*
        • *statement*
      • .display_url.url matches any of 8 patterns
        • *shared*
        • *document*
        • *secure*
        • *office*
        • *important*
        • *wants-to*
        • *share*
        • *statement*
      • .display_text matches any of 8 patterns
        • *shared*
        • *document*
        • *secure*
        • *office*
        • *important*
        • *wants-to*
        • *share*
        • *statement*
  3. sender.email.domain.domain is not 'mail.notion.so'
  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: body.links, body.links[].display_text, body.links[].display_url.url, body.links[].href_url.domain.root_domain, body.links[].href_url.url, sender.email.domain.domain, type.inbound. Sensors: profile.by_sender, strings.ilike.

Indicators matched (10)

FieldMatchValue
body.links[].href_url.domain.root_domainmembernotion.so
body.links[].href_url.domain.root_domainmembernotion.site
strings.ilikesubstring*shared*
strings.ilikesubstring*document*
strings.ilikesubstring*secure*
strings.ilikesubstring*office*
strings.ilikesubstring*important*
strings.ilikesubstring*wants-to*
strings.ilikesubstring*share*
strings.ilikesubstring*statement*

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        body.links.display_text match "document"
        body.links.display_text match "important"
        body.links.display_text match "office"
        body.links.display_text match "secure"
        body.links.display_text match "share"
        body.links.display_text match "shared"
        body.links.display_text match "statement"
        body.links.display_text match "wants-to"
        body.links.display_url.url match "document"
        body.links.display_url.url match "important"
        body.links.display_url.url match "office"
        body.links.display_url.url match "secure"
        body.links.display_url.url match "share"
        body.links.display_url.url match "shared"
        body.links.display_url.url match "statement"
        body.links.display_url.url match "wants-to"
        body.links.href_url.url match "document"
        body.links.href_url.url match "important"
        body.links.href_url.url match "office"
        body.links.href_url.url match "secure"
        body.links.href_url.url match "share"
        body.links.href_url.url match "shared"
        body.links.href_url.url match "statement"
        body.links.href_url.url match "wants-to"
      body.links.href_url.domain.root_domain in ["notion.site", "notion.so"]
  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)"
  sender.email.domain.domain ne "mail.notion.so"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Open redirect (go2.aspx) leading to Microsoft credential phishing

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

This rule is designed to detect credential phishing attacks that exploit go2.aspx redirects and masquerade as Microsoft-related emails.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Open redirect

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.html
  • body.links
  • headers
  • type

Rule body

type.inbound

// url path ends with go2.aspx
and any(body.links,
        strings.ends_with(.href_url.path, "go2.aspx")

        // query params from href_url or ml.link_analysis contain a redirection string ending with a base64
        // pattern intended to capture an encoded email passed as an additional parameter
        and (
          regex.contains(.href_url.query_params,
                         '[a-z]=[a-z0-9-]+\.[a-z]{2,3}.+[A-Za-z0-9+/=]$|=[^=]$|={3,}$'
          )
          or regex.icontains(ml.link_analysis(.).effective_url.query_params,
                             '[a-z]=[a-z0-9-]+\.[a-z]{2,3}.+[A-Za-z0-9+/=]$|=[^=]$|={3,}$'
          )
        )
)
and headers.mailer is null
and regex.icontains(body.html.inner_text,
                    '(i\x{034F}c\x{034F}r\x{034F}os\x{034F}of\x{034F}|icrosof)|(office|o)\s?365'
)

Detection logic

Scope: inbound message.

This rule is designed to detect credential phishing attacks that exploit go2.aspx redirects and masquerade as Microsoft-related emails.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.path ends with 'go2.aspx'
    • any of:
      • .href_url.query_params matches '[a-z]=[a-z0-9-]+\\.[a-z]{2,3}.+[A-Za-z0-9+/=]$|=[^=]$|={3,}$'
      • ml.link_analysis(.).effective_url.query_params matches '[a-z]=[a-z0-9-]+\\.[a-z]{2,3}.+[A-Za-z0-9+/=]$|=[^=]$|={3,}$'
  3. headers.mailer is missing
  4. body.html.inner_text matches '(i\\x{034F}c\\x{034F}r\\x{034F}os\\x{034F}of\\x{034F}|icrosof)|(office|o)\\s?365'

Inspects: body.html.inner_text, body.links, body.links[].href_url.path, body.links[].href_url.query_params, headers.mailer, type.inbound. Sensors: ml.link_analysis, regex.contains, regex.icontains, strings.ends_with.

Indicators matched (4)

FieldMatchValue
strings.ends_withsuffixgo2.aspx
regex.containsregex[a-z]=[a-z0-9-]+\.[a-z]{2,3}.+[A-Za-z0-9+/=]$|=[^=]$|={3,}$
regex.icontainsregex[a-z]=[a-z0-9-]+\.[a-z]{2,3}.+[A-Za-z0-9+/=]$|=[^=]$|={3,}$
regex.icontainsregex(i\x{034F}c\x{034F}r\x{034F}os\x{034F}of\x{034F}|icrosof)|(office|o)\s?365

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      or
        body.links.href_url.query_params regex_match "[a-z]=[a-z0-9-]+\\.[a-z]{2,3}.+[A-Za-z0-9+/=]$|=[^=]$|={3,}$"
        ml.link_analysis(body.links[]).effective_url.query_params regex_match "[a-z]=[a-z0-9-]+\\.[a-z]{2,3}.+[A-Za-z0-9+/=]$|=[^=]$|={3,}$"
      body.links.href_url.path ends_with "go2.aspx"
  body.html.inner_text regex_match "(i\\x{034F}c\\x{034F}r\\x{034F}os\\x{034F}of\\x{034F}|icrosof)|(office|o)\\s?365"
  headers.mailer is_null
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
body.html.inner_textregex_match
    • (i\x{034F}c\x{034F}r\x{034F}os\x{034F}of\x{034F}|icrosof)
    • (office|o)\s?365
field:"body.html.inner_text" kind:regex_match
headers.maileris_null
  • (no value, null check)
field:"headers.mailer" kind:is_null
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Open Redirect: Google domain with /url path and suspicious indicators

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

This rule examines messages containing image attachments that utilize Google's open redirect (google[.]com/url...). To enhance accuracy and minimize false positives, the rule conducts additional assessments for suspicious indicators, as indicated in the comments.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Open redirect

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • body.html
  • body.links
  • headers
  • headers.auth_summary
  • sender.email
  • 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 sender.email.domain.root_domain not in $org_domains
// negate auth'ed google messages
and not (
  sender.email.domain.sld == "google"
  and sender.email.local_part in ("googlealerts-noreply", "comments-noreply")
  and headers.auth_summary.spf.pass
  and headers.auth_summary.dmarc.pass
)
// not a reply
and (length(headers.references) == 0 or headers.in_reply_to is null)
// With a Google Redirect
and any(body.links,
        (
          .href_url.domain.sld == "google"
          and .href_url.path == "/url"
          and regex.contains(.href_url.query_params, "hl=.{2}&q=http(s)?://")
        )
        or any(.href_url.rewrite.encoders, . == 'google_open_redirect')
)
and 2 of (
  // Not a google logo
  any(attachments,
      .file_type in $file_types_images
      and (
        any(ml.logo_detect(.).brands, not strings.starts_with(.name, "Google"))
        or any(ml.logo_detect(file.message_screenshot()).brands,
               not strings.starts_with(.name, "Google")
        )
      )
  ),
  // Body analysis - NLU - Credential theft
  (
    any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft" and .confidence in~ ("medium", "high")
    )
  ),
  // Image analysis - NLU - Credential theft language
  (
    any(attachments,
        .file_type in $file_types_images
        and any(file.explode(.),
                any(ml.nlu_classifier(.scan.ocr.raw).intents,
                    .name == "cred_theft"
                )
        )
    )
  ),
  // Content analysis - Body - Urgency
  (
    any(ml.nlu_classifier(body.current_thread.text).entities,
        .name == "urgency"
    )
  ),

  // White font is found in html raw
  (
    length(body.html.display_text) < 500
    and regex.icontains(body.html.raw,
                        '<div style="color: #fff(fff)?.[^<]+<\/div><\/div><\/body><\/html>$'
    )
  )

  // domains using .app matching this pattern observed abusing google's redirect
  or regex.icontains(sender.email.domain.domain,
                     '[a-z]{3,}\.\d{5,}[^\.]+\.app$'
  )
)

Detection logic

Scope: inbound message.

This rule examines messages containing image attachments that utilize Google's open redirect (google[.]com/url...). To enhance accuracy and minimize false positives, the rule conducts additional assessments for suspicious indicators, as indicated in the comments.

  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. sender.email.domain.root_domain not in $org_domains
  4. not:
    • all of:
      • sender.email.domain.sld is 'google'
      • sender.email.local_part in ('googlealerts-noreply', 'comments-noreply')
      • headers.auth_summary.spf.pass
      • headers.auth_summary.dmarc.pass
  5. any of:
    • length(headers.references) is 0
    • headers.in_reply_to is missing
  6. any of body.links where any holds:
    • all of:
      • .href_url.domain.sld is 'google'
      • .href_url.path is '/url'
      • .href_url.query_params matches 'hl=.{2}&q=http(s)?://'
    • any of .href_url.rewrite.encoders where:
      • . is 'google_open_redirect'
  7. at least 2 of:
    • any of attachments where all hold:
      • .file_type in $file_types_images
      • any of:
        • any of ml.logo_detect(.).brands where:
          • not:
            • .name starts with 'Google'
        • any of ml.logo_detect(file.message_screenshot()).brands where:
          • not:
            • .name starts with 'Google'
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'cred_theft'
      • .confidence in ('medium', 'high')
    • 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:
          • .name is 'cred_theft'
    • any of ml.nlu_classifier(body.current_thread.text).entities where:
      • .name is 'urgency'
    • any of:
      • all of:
        • length(body.html.display_text) < 500
        • body.html.raw matches '<div style="color: #fff(fff)?.[^<]+<\\/div><\\/div><\\/body><\\/html>$'
      • sender.email.domain.domain matches '[a-z]{3,}\\.\\d{5,}[^\\.]+\\.app$'

Inspects: attachments[].file_type, body.current_thread.text, body.html.display_text, body.html.raw, body.links, body.links[].href_url.domain.sld, body.links[].href_url.path, body.links[].href_url.query_params, body.links[].href_url.rewrite.encoders, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.in_reply_to, headers.references, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.domain.sld, sender.email.local_part, type.inbound. Sensors: file.explode, file.message_screenshot, ml.logo_detect, ml.nlu_classifier, regex.contains, regex.icontains, strings.starts_with. Reference lists: $file_types_images, $org_domains.

Indicators matched (11)

FieldMatchValue
body.links[].href_url.domain.sldequalsgoogle
body.links[].href_url.pathequals/url
regex.containsregexhl=.{2}&q=http(s)?://
body.links[].href_url.rewrite.encoders[]equalsgoogle_open_redirect
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(file.explode(attachments[])[].scan.ocr.raw).intents[].nameequalscred_theft
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsurgency
regex.icontainsregex<div style="color: #fff(fff)?.[^<]+<\/div><\/div><\/body><\/html>$
regex.icontainsregex[a-z]{3,}\.\d{5,}[^\.]+\.app$

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(attachments)
      and
        or
          any(ml.logo_detect(attachments).brands)
            not
              ml.logo_detect(attachments[]).brands[].name starts_with "Google"
          any(ml.logo_detect(file.message_screenshot()).brands)
            not
              ml.logo_detect(file.message_screenshot()).brands.name starts_with "Google"
         macro "attachments[].file_type in file_types_images"
    any(attachments)
      and
        any(file.explode(attachments))
          any(ml.nlu_classifier(file.explode(attachments).scan.ocr.raw).intents)
            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 in ["high", "medium"]
        ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
    and
      body.html.display_text length_compare "500"
      body.html.raw regex_match "<div style=\"color: #fff(fff)?.[^<]+<\\/div><\\/div><\\/body><\\/html>$"
    any(ml.nlu_classifier(body.current_thread.text).entities)
      ml.nlu_classifier(body.current_thread.text).entities.name eq "urgency"
    sender.email.domain.domain regex_match "[a-z]{3,}\\.\\d{5,}[^\\.]+\\.app$"
  any(body.links)
    or
      and
        body.links.href_url.domain.sld eq "google"
        body.links.href_url.path eq "/url"
        body.links.href_url.query_params regex_match "hl=.{2}&q=http(s)?://"
      any(body.links.href_url.rewrite.encoders)
        body.links.href_url.rewrite.encoders eq "google_open_redirect"
  or
    and
      attachments length_compare "0"
       macro "all(attachments)"
    attachments length_compare "0"
  not
    and
      headers.auth_summary.dmarc.pass eq "true"
      headers.auth_summary.spf.pass eq "true"
      sender.email.domain.sld eq "google"
      sender.email.local_part in ["comments-noreply", "googlealerts-noreply"]
  or
    headers.in_reply_to is_null
    headers.references length_compare "0"
  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
body.html.rawregex_match
  • <div style="color: #fff(fff)?.[^<]+<\/div><\/div><\/body><\/html>$
field:"body.html.raw" kind:regex_match
headers.in_reply_tois_null
  • (no value, null check)
field:"headers.in_reply_to" kind:is_null
sender.email.domain.domainregex_match
  • [a-z]{3,}.\d{5,}[^.]+.app$
field:"sender.email.domain.domain" kind:regex_match value:"[a-z]{3,}.\d{5,}[^.]+.app$"
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Open redirect: Google Web Light

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

Message contains use of the Google Web Light open redirect. Google Web Light was sunset on December 19 2022.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Malware/Ransomware
Tactics and techniquesOpen redirect

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        .href_url.domain.root_domain == "googleweblight.com"
        and regex.match(.href_url.query_params, "(lite_url|u)=.*")
)
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.

Message contains use of the Google Web Light open redirect. Google Web Light was sunset on December 19 2022.

  1. inbound message
  2. any of body.links where all hold:
    • .href_url.domain.root_domain is 'googleweblight.com'
    • .href_url.query_params matches '(lite_url|u)=.*'
  3. any of:
    • not:
      • profile.by_sender().solicited
    • profile.by_sender().any_messages_malicious_or_spam
  4. not:
    • profile.by_sender().any_messages_benign

Inspects: body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.query_params, type.inbound. Sensors: profile.by_sender, regex.match.

Indicators matched (2)

FieldMatchValue
body.links[].href_url.domain.root_domainequalsgoogleweblight.com
regex.matchregex(lite_url|u)=.*

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    and
      body.links.href_url.domain.root_domain eq "googleweblight.com"
      body.links.href_url.query_params regex_match "(lite_url|u)=.*"
  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"
  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"

Outlook hyperlink bypass: left-to-right mark (LRM) in base HTML tag

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

The exploit involves tricking Outlook for Windows into displaying a fake domain while opening another one. This is achieved by adding a <base> HTML tag with a fake domain and a left-to-right mark (Unicode U+200E). Links within <a> tags will display the fake domain but open the actual domain when clicked on.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, Exploit

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.html
  • type

Rule body

type.inbound
and regex.contains(body.html.raw, 'base.{0,100}\x{200E}/>')

Detection logic

Scope: inbound message.

The exploit involves tricking Outlook for Windows into displaying a fake domain while opening another one. This is achieved by adding a <base> HTML tag with a fake domain and a left-to-right mark (Unicode U+200E). Links within <a> tags will display the fake domain but open the actual domain when clicked on.

  1. inbound message
  2. body.html.raw matches 'base.{0,100}\\x{200E}/>'

Inspects: body.html.raw, type.inbound. Sensors: regex.contains.

Indicators matched (1)

FieldMatchValue
regex.containsregexbase.{0,100}\x{200E}/>

Stages and Predicates

Stage 1: mql_rule

and
  body.html.raw regex_match "base.{0,100}\\x{200E}/>"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Service abuse: Dropbox Paper with copy-paste instructions

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

Detects messages containing copy-paste instructions with links to Dropbox Paper documents, commonly used to bypass security controls by instructing users to manually navigate to malicious content.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering, Free file host, Evasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.current_thread
  • type

Rule body

type.inbound
and strings.icontains(body.current_thread.text, 'copy')
and strings.icontains(body.current_thread.text, 'paste')
and any(body.current_thread.links,
        strings.icontains(.display_url.url, 'https://www.dropbox.com/scl/fi/')
        and strings.icontains(.display_url.url, '.paper')
)

Detection logic

Scope: inbound message.

Detects messages containing copy-paste instructions with links to Dropbox Paper documents, commonly used to bypass security controls by instructing users to manually navigate to malicious content.

  1. inbound message
  2. body.current_thread.text contains 'copy'
  3. body.current_thread.text contains 'paste'
  4. any of body.current_thread.links where all hold:
    • .display_url.url contains 'https://www.dropbox.com/scl/fi/'
    • .display_url.url contains '.paper'

Inspects: body.current_thread.links, body.current_thread.links[].display_url.url, body.current_thread.text, type.inbound. Sensors: strings.icontains.

Indicators matched (4)

FieldMatchValue
strings.icontainssubstringcopy
strings.icontainssubstringpaste
strings.icontainssubstringhttps://www.dropbox.com/scl/fi/
strings.icontainssubstring.paper

Stages and Predicates

Stage 1: mql_rule

and
  any(body.current_thread.links)
    and
      body.current_thread.links.display_url.url contains ".paper"
      body.current_thread.links.display_url.url contains "https://www.dropbox.com/scl/fi/"
  body.current_thread.text contains "copy"
  body.current_thread.text contains "paste"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Service abuse: Google Tag Manager debug cookie clearing with open redirect potential

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

Detects messages containing links to Google Tag Manager's debug cookie clearing endpoint with suspicious URL parameters that may be exploited for open redirects, or links that have been rewritten through Google Tag Manager encoding methods.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesOpen redirect, Service abuse

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • body
  • body.links
  • type

Rule body

type.inbound
and any(body.links,
        (
          .href_url.domain.root_domain == "googletagmanager.com"
          and .href_url.path == "/debug/clearcookies"
          and any(.href_url.query_params_decoded["url"],
                  strings.parse_url(.).domain.valid
          )
        )
        or 'google_tag_manager' in .href_url.rewrite.encoders
)

Detection logic

Scope: inbound message.

Detects messages containing links to Google Tag Manager's debug cookie clearing endpoint with suspicious URL parameters that may be exploited for open redirects, or links that have been rewritten through Google Tag Manager encoding methods.

  1. inbound message
  2. any of body.links where any holds:
    • all of:
      • .href_url.domain.root_domain is 'googletagmanager.com'
      • .href_url.path is '/debug/clearcookies'
      • any of .href_url.query_params_decoded['url'] where:
        • strings.parse_url(.).domain.valid
    • .href_url.rewrite.encoders contains 'google_tag_manager'

Inspects: body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.path, body.links[].href_url.query_params_decoded['url'], body.links[].href_url.rewrite.encoders, type.inbound. Sensors: strings.parse_url.

Indicators matched (3)

FieldMatchValue
body.links[].href_url.domain.root_domainequalsgoogletagmanager.com
body.links[].href_url.pathequals/debug/clearcookies
body.links[].href_url.rewrite.encoderscontainsgoogle_tag_manager

Stages and Predicates

Stage 1: mql_rule

and
  any(body.links)
    or
      and
        any(body.links.href_url.query_params_decoded['url'])
          strings.parse_url func_call "strings.parse_url(body.links[].href_url.query_params_decoded['url'][]).domain.valid"
        body.links.href_url.domain.root_domain eq "googletagmanager.com"
        body.links.href_url.path eq "/debug/clearcookies"
      body.links.href_url.rewrite.encoders contains "google_tag_manager"
  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"

Sharepoint online with external recipients and external display name

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

An email from Sharepoint Online that was sent to multiple recipients that did not originate from a sender, by display name, in your organization.

Threat classification

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

CategoryValues
Attack typesCredential Phishing, Spam
Tactics and techniquesEvasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • recipients
  • recipients.to
  • sender.email
  • type

Rule body

type.inbound
and sender.email.email == "no-reply@sharepointonline.com"
and length(recipients.to) > 40 // You may want to adjust this threshold if 40 is too aggressive
and any(recipients.to, .email.domain.domain in $free_email_providers)
and sender.display_name not in $org_display_names

Detection logic

Scope: inbound message.

An email from Sharepoint Online that was sent to multiple recipients that did not originate from a sender, by display name, in your organization.

  1. inbound message
  2. sender.email.email is 'no-reply@sharepointonline.com'
  3. length(recipients.to) > 40
  4. any of recipients.to where:
    • .email.domain.domain in $free_email_providers
  5. sender.display_name not in $org_display_names

Inspects: recipients.to, recipients.to[].email.domain.domain, sender.display_name, sender.email.email, type.inbound. Reference lists: $free_email_providers, $org_display_names.

Indicators matched (1)

FieldMatchValue
sender.email.emailequalsno-reply@sharepointonline.com

Stages and Predicates

Stage 1: mql_rule

and
  any(recipients.to)
     macro "recipients.to[].email.domain.domain in free_email_providers"
  recipients.to length_compare "40"
  sender.email.email eq "no-reply@sharepointonline.com"
  type.inbound eq "true"
   macro "sender.display_name not in org_display_names"

Indicators

These rows show field, operator, and value matches.

Suspicious link to Looker Studio (lookerstudio.google.com) from a new and unsolicited sender

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

This rule detects messages containing links to lookerstudio with a non standard lookerstudio template from a new and unsolicited sender.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, 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 length(body.current_thread.text) < 1000
and regex.icontains(body.current_thread.text,
                    '(shared.{0,30}with you|View Document)'
)
and any(body.links, .href_url.domain.domain == "lookerstudio.google.com")
and (
  profile.by_sender().prevalence in ("new", "outlier")
  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.

This rule detects messages containing links to lookerstudio with a non standard lookerstudio template from a new and unsolicited sender.

  1. inbound message
  2. length(body.current_thread.text) < 1000
  3. body.current_thread.text matches '(shared.{0,30}with you|View Document)'
  4. any of body.links where:
    • .href_url.domain.domain is 'lookerstudio.google.com'
  5. all of:
    • profile.by_sender().prevalence in ('new', 'outlier')
    • 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, body.links, body.links[].href_url.domain.domain, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: profile.by_sender, regex.icontains. Reference lists: $high_trust_sender_root_domains.

Indicators matched (2)

FieldMatchValue
regex.icontainsregex(shared.{0,30}with you|View Document)
body.links[].href_url.domain.domainequalslookerstudio.google.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"
  any(body.links)
    body.links.href_url.domain.domain eq "lookerstudio.google.com"
  not
    profile.by_sender func_call "profile.by_sender().solicited"
  body.current_thread.text length_compare "1000"
  body.current_thread.text regex_match "(shared.{0,30}with you|View Document)"
  profile.by_sender func_call "profile.by_sender().prevalence in (new, outlier)"
  type.inbound eq "true"

Indicators

These rows show field, operator, and value matches.

Suspicious Links to Cloudflare R2 and Edge Services

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

Detects links to Cloudflare R2 storage buckets, Pages, and Workers domains from unsolicited or previously malicious senders who are not on a trusted sender list or have failed DMARC authentication.

Threat classification

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

CategoryValues
Attack typesBEC/Fraud, Callback Phishing, Credential Phishing, Extortion, Malware/Ransomware, Spam
Tactics and techniquesFree file host

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 any(body.links,
        // Check root domain first 
        .href_url.domain.root_domain in ("r2.dev", "pages.dev", "workers.dev")
// Check the specific pub-{hex}.r2.dev subdomain pattern only for r2.dev
)
// negate emails with unsubscribe links
and not any(body.links,
            strings.icontains(.href_url.url, "unsubscribe")
            or strings.icontains(.display_text, "unsubscribe")
)
// negate bulk mailer domains
and not any(body.links,
            .href_url.domain.root_domain in $bulk_mailer_url_root_domains
)
and not (
  any(ml.nlu_classifier(body.current_thread.text).topics,
      .name in (
        "Newsletters and Digests",
        "Advertising and Promotions",
        "Educational and Research",
        "B2B Cold Outreach",
        "Health and Wellness",
        "Professional and Career Development",
        "Romance",
        "Sexually Explicit Messages",
        "Software and App Updates",
        "Acts of Violence",
        "Voicemail Call and Missed Call Notifications"
      )
      and .confidence == "high"
  )
)
// 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.

Detects links to Cloudflare R2 storage buckets, Pages, and Workers domains from unsolicited or previously malicious senders who are not on a trusted sender list or have failed DMARC authentication.

  1. inbound message
  2. any of body.links where:
    • .href_url.domain.root_domain in ('r2.dev', 'pages.dev', 'workers.dev')
  3. not:
    • any of body.links where any holds:
      • .href_url.url contains 'unsubscribe'
      • .display_text contains 'unsubscribe'
  4. not:
    • any of body.links where:
      • .href_url.domain.root_domain in $bulk_mailer_url_root_domains
  5. not:
    • any of ml.nlu_classifier(body.current_thread.text).topics where all hold:
      • .name in ('Newsletters and Digests', 'Advertising and Promotions', 'Educational and Research', 'B2B Cold Outreach', 'Health and Wellness', 'Professional and Career Development', 'Romance', 'Sexually Explicit Messages', 'Software and App Updates', 'Acts of Violence', 'Voicemail Call and Missed Call Notifications')
      • .confidence is 'high'
  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
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  8. not:
    • profile.by_sender().any_messages_benign

Inspects: body.current_thread.text, body.links, body.links[].display_text, body.links[].href_url.domain.root_domain, body.links[].href_url.url, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender, strings.icontains. Reference lists: $bulk_mailer_url_root_domains, $high_trust_sender_root_domains.

Indicators matched (3)

FieldMatchValue
body.links[].href_url.domain.root_domainmemberr2.dev
body.links[].href_url.domain.root_domainmemberpages.dev
body.links[].href_url.domain.root_domainmemberworkers.dev

Stages and Predicates

Stage 1: mql_rule

and
  not
    any(body.links)
      or
        body.links.display_text contains "unsubscribe"
        body.links.href_url.url contains "unsubscribe"
  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 in ["Acts of Violence", "Advertising and Promotions", "B2B Cold Outreach", "Educational and Research", "Health and Wellness", "Newsletters and Digests", "Professional and Career Development", "Romance", "Sexually Explicit Messages", "Software and App Updates", "Voicemail Call and Missed Call Notifications"]
  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
    any(body.links)
       macro "body.links[].href_url.domain.root_domain in bulk_mailer_url_root_domains"
  any(body.links)
    body.links.href_url.domain.root_domain in ["pages.dev", "r2.dev", "workers.dev"]
  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
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

Indicators

These rows show field, operator, and value matches.

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

Suspicious message with unscannable Cloudflare link

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

This rule detects messages with unscannable links to cloudflare infrastructure with suspicious indicators in the subject or display name from an unsolicited sender.

Threat classification

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

CategoryValues
Attack typesCredential Phishing

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
and (
  (
    // few links
    0 < length(body.links) < 20
    // fewer unique root domain links
    and length(distinct(body.links, .href_url.domain.root_domain)) < 10
    // sender domain matches no body domains
    and all(body.links,
            .href_url.domain.root_domain != sender.email.domain.root_domain
    )
  )
  or beta.scan_qr(file.message_screenshot()).found
)

// negate bouncebacks and undeliverables
and not any(attachments,
            .content_type in (
              "message/global-delivery-status",
              "message/delivery-status"
            )
)

// suspicious subject or display name
and (
  regex.icontains(subject.subject,
                  "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",
                  "report",
                  "revised.*policy",
                  "scam",
                  "scanned.?invoice",
                  "secured?.update",
                  "security breach",
                  "securlty",
                  "signed.*delivery",
                  "statement is ready",
                  "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"
  )
  or any($suspicious_subjects, strings.icontains(subject.subject, .))
  or regex.icontains(sender.display_name,
                     "Admin",
                     "Administrator",
                     "Alert",
                     "Assistant",
                     "Billing",
                     "Benefits",
                     "Bonus",
                     "CEO",
                     "CFO",
                     "CIO",
                     "CTO",
                     "Chairman",
                     "Claim",
                     "Confirm",
                     "Critical",
                     "Customer Service",
                     "Deal",
                     "Discount",
                     "Director",
                     "Exclusive",
                     "Executive",
                     "Fax",
                     "Free",
                     "Gift",
                     "/bHR/b",
                     "Helpdesk",
                     "Human Resources",
                     "Immediate",
                     "Important",
                     "Info",
                     "Information",
                     "Invoice",
                     '\bIT\b',
                     "Legal",
                     "Lottery",
                     "Management",
                     "Manager",
                     "Member Services",
                     "Notification",
                     "Offer",
                     "Operations",
                     "Order",
                     "Partner",
                     "Payment",
                     "Payroll",
                     "President",
                     "Premium",
                     "Prize",
                     "Receipt",
                     "Refund",
                     "Registrar",
                     "Required",
                     "Reward",
                     "Sales",
                     "Secretary",
                     "Security",
                     "Service",
                     "Signature",
                     "SSA",
                     "Storage",
                     "Support",
                     "Sweepstakes",
                     "System",
                     "Tax",
                     "Tech Support",
                     "Update",
                     "Upgrade",
                     "Urgent",
                     "Validate",
                     "Verify",
                     "VIP",
                     "Webmaster",
                     "Winner",
  )
  or any(body.links, strings.ends_with(.href_url.url, ".exe"))
  or profile.by_sender_email().days_known < 1
)

// link can't be scanned due to Cloudflare captcha
and (
  any(body.links,
      (
        strings.icontains(ml.link_analysis(., mode="aggressive").final_dom.display_text,
                          "cloudflare"
        )
        // includes the turnstile CAPTCHA
        or (
          strings.icontains(ml.link_analysis(., mode="aggressive").final_dom.raw,
                            'https://challenges.cloudflare.com/turnstile/'
          )
          // has a short body length indicating the page is gated behind the turnstile instead
          // of just including the turnstile
          and length((
                       ml.link_analysis(., mode="aggressive").final_dom.display_text
                     )
          ) < 200
        )
      )
      and not (
        ( // a Cloudflare error page
          strings.ilike(ml.link_analysis(., mode="aggressive").final_dom.display_text,
                        "*error code*"
          )
          and any(ml.link_analysis(., mode="aggressive").final_dom.links,
                  strings.icontains(.href_url.query_params,
                                    "utm_source=errorcode"
                  )
          )
        ) // a cookie warning mentioning Cloudflare
        or regex.icontains(ml.link_analysis(., mode="aggressive").final_dom.display_text,
                           "cookie.{0,50}Cloudflare"
        )
        or ml.link_analysis(., mode="aggressive").effective_url.domain.root_domain in (
          "marketbeat.com"
        )
      )
  )
  or any(beta.scan_qr(file.message_screenshot()).items,
         .type == "url"
         and (
           strings.icontains(ml.link_analysis(.url, mode="aggressive").final_dom.display_text,
                             "cloudflare"
           )
           // includes the turnstile CAPTCHA
           or (
             strings.icontains(ml.link_analysis(.url, mode="aggressive").final_dom.raw,
                               'https://challenges.cloudflare.com/turnstile/'
             )
             // has a short body length indicating the page is gated behind the turnstile instead
             // of just including the turnstile
             and length((
                          ml.link_analysis(.url, mode="aggressive").final_dom.display_text
                        )
             ) < 200
           )
         )
         and not (
           ( // a Cloudflare error page
             strings.ilike(ml.link_analysis(.url, mode="aggressive").final_dom.display_text,
                           "*error code*"
             )
             and any(ml.link_analysis(.url, mode="aggressive").final_dom.links,
                     strings.icontains(.href_url.query_params,
                                       "utm_source=errorcode"
                     )
             )
           ) // a cookie warning mentioning Cloudflare
           or regex.icontains(ml.link_analysis(.url, mode="aggressive").final_dom.display_text,
                              "cookie.{0,50}Cloudflare"
           )
           or ml.link_analysis(.url, mode="aggressive").effective_url.domain.root_domain in (
             "marketbeat.com"
           )
         )
  )
)
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 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 with unscannable links to cloudflare infrastructure with suspicious indicators in the subject or display name from an unsolicited sender.

  1. inbound message
  2. any of:
    • all of:
      • all of:
        • length(body.links) > 0
        • length(body.links) < 20
      • length(distinct(body.links, .href_url.domain.root_domain)) < 10
      • all of body.links where:
        • .href_url.domain.root_domain is not sender.email.domain.root_domain
    • beta.scan_qr(file.message_screenshot()).found
  3. not:
    • any of attachments where:
      • .content_type in ('message/global-delivery-status', 'message/delivery-status')
  4. any of:
    • subject.subject matches any of 124 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
      • report
      • revised.*policy
      • scam
      • scanned.?invoice
      • secured?.update
      • security breach
      • securlty
      • signed.*delivery
      • statement is ready
      • 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
    • any of $suspicious_subjects where:
      • strings.icontains(subject.subject)
    • sender.display_name matches any of 73 patterns
      • Admin
      • Administrator
      • Alert
      • Assistant
      • Billing
      • Benefits
      • Bonus
      • CEO
      • CFO
      • CIO
      • CTO
      • Chairman
      • Claim
      • Confirm
      • Critical
      • Customer Service
      • Deal
      • Discount
      • Director
      • Exclusive
      • Executive
      • Fax
      • Free
      • Gift
      • /bHR/b
      • Helpdesk
      • Human Resources
      • Immediate
      • Important
      • Info
      • Information
      • Invoice
      • \bIT\b
      • Legal
      • Lottery
      • Management
      • Manager
      • Member Services
      • Notification
      • Offer
      • Operations
      • Order
      • Partner
      • Payment
      • Payroll
      • President
      • Premium
      • Prize
      • Receipt
      • Refund
      • Registrar
      • Required
      • Reward
      • Sales
      • Secretary
      • Security
      • Service
      • Signature
      • SSA
      • Storage
      • Support
      • Sweepstakes
      • System
      • Tax
      • Tech Support
      • Update
      • Upgrade
      • Urgent
      • Validate
      • Verify
      • VIP
      • Webmaster
      • Winner
    • any of body.links where:
      • .href_url.url ends with '.exe'
    • profile.by_sender_email().days_known < 1
  5. any of:
    • any of body.links where all hold:
      • any of:
        • ml.link_analysis(., mode='aggressive').final_dom.display_text contains 'cloudflare'
        • all of:
          • ml.link_analysis(., mode='aggressive').final_dom.raw contains 'https://challenges.cloudflare.com/turnstile/'
          • length(ml.link_analysis(., mode='aggressive').final_dom.display_text) < 200
      • none of:
        • all of:
          • ml.link_analysis(., mode='aggressive').final_dom.display_text matches '*error code*'
          • any of ml.link_analysis(., mode='aggressive').final_dom.links where:
            • .href_url.query_params contains 'utm_source=errorcode'
        • ml.link_analysis(., mode='aggressive').final_dom.display_text matches 'cookie.{0,50}Cloudflare'
        • ml.link_analysis(.).effective_url.domain.root_domain in ('marketbeat.com')
    • any of beta.scan_qr(file.message_screenshot()).items where all hold:
      • .type is 'url'
      • any of:
        • ml.link_analysis(.url, mode='aggressive').final_dom.display_text contains 'cloudflare'
        • all of:
          • ml.link_analysis(.url, mode='aggressive').final_dom.raw contains 'https://challenges.cloudflare.com/turnstile/'
          • length(ml.link_analysis(.url, mode='aggressive').final_dom.display_text) < 200
      • none of:
        • all of:
          • ml.link_analysis(.url, mode='aggressive').final_dom.display_text matches '*error code*'
          • any of ml.link_analysis(.url, mode='aggressive').final_dom.links where:
            • .href_url.query_params contains 'utm_source=errorcode'
        • ml.link_analysis(.url, mode='aggressive').final_dom.display_text matches 'cookie.{0,50}Cloudflare'
        • ml.link_analysis(.url).effective_url.domain.root_domain in ('marketbeat.com')
  6. any of:
    • not:
      • profile.by_sender_email().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  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_messages_benign

Inspects: attachments[].content_type, body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.url, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: beta.scan_qr, file.message_screenshot, ml.link_analysis, profile.by_sender, profile.by_sender_email, regex.icontains, strings.ends_with, strings.icontains, strings.ilike. Reference lists: $high_trust_sender_root_domains, $suspicious_subjects.

Indicators matched (201)

FieldMatchValue
regex.icontainsregextermination.*notice
regex.icontainsregex38417
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
189 more
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.icontainsregexreport
regex.icontainsregexrevised.*policy
regex.icontainsregexscam
regex.icontainsregexscanned.?invoice
regex.icontainsregexsecured?.update
regex.icontainsregexsecurity breach
regex.icontainsregexsecurlty
regex.icontainsregexsigned.*delivery
regex.icontainsregexstatement is ready
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.icontainsregexAdmin
regex.icontainsregexAdministrator
regex.icontainsregexAlert
regex.icontainsregexAssistant
regex.icontainsregexBilling
regex.icontainsregexBenefits
regex.icontainsregexBonus
regex.icontainsregexCEO
regex.icontainsregexCFO
regex.icontainsregexCIO
regex.icontainsregexCTO
regex.icontainsregexChairman
regex.icontainsregexClaim
regex.icontainsregexConfirm
regex.icontainsregexCritical
regex.icontainsregexCustomer Service
regex.icontainsregexDeal
regex.icontainsregexDiscount
regex.icontainsregexDirector
regex.icontainsregexExclusive
regex.icontainsregexExecutive
regex.icontainsregexFax
regex.icontainsregexFree
regex.icontainsregexGift
regex.icontainsregex/bHR/b
regex.icontainsregexHelpdesk
regex.icontainsregexHuman Resources
regex.icontainsregexImmediate
regex.icontainsregexImportant
regex.icontainsregexInfo
regex.icontainsregexInformation
regex.icontainsregexInvoice
regex.icontainsregex\bIT\b
regex.icontainsregexLegal
regex.icontainsregexLottery
regex.icontainsregexManagement
regex.icontainsregexManager
regex.icontainsregexMember Services
regex.icontainsregexNotification
regex.icontainsregexOffer
regex.icontainsregexOperations
regex.icontainsregexOrder
regex.icontainsregexPartner
regex.icontainsregexPayment
regex.icontainsregexPayroll
regex.icontainsregexPresident
regex.icontainsregexPremium
regex.icontainsregexPrize
regex.icontainsregexReceipt
regex.icontainsregexRefund
regex.icontainsregexRegistrar
regex.icontainsregexRequired
regex.icontainsregexReward
regex.icontainsregexSales
regex.icontainsregexSecretary
regex.icontainsregexSecurity
regex.icontainsregexService
regex.icontainsregexSignature
regex.icontainsregexSSA
regex.icontainsregexStorage
regex.icontainsregexSupport
regex.icontainsregexSweepstakes
regex.icontainsregexSystem
regex.icontainsregexTax
regex.icontainsregexTech Support
regex.icontainsregexUpdate
regex.icontainsregexUpgrade
regex.icontainsregexUrgent
regex.icontainsregexValidate
regex.icontainsregexVerify
regex.icontainsregexVIP
regex.icontainsregexWebmaster
regex.icontainsregexWinner
strings.ends_withsuffix.exe
strings.icontainssubstringcloudflare
strings.icontainssubstringhttps://challenges.cloudflare.com/turnstile/
beta.scan_qr(file.message_screenshot()).items[].typeequalsurl

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(beta.scan_qr(file.message_screenshot()).items)
      and
        not
          or
            and
              any(ml.link_analysis(beta.scan_qr(file.message_screenshot()).items.url, mode='aggressive').final_dom.links)
                ml.link_analysis(beta.scan_qr(file.message_screenshot()).items.url, mode='aggressive').final_dom.links.href_url.query_params contains "utm_source=errorcode"
              ml.link_analysis(beta.scan_qr(file.message_screenshot()).items[].url, mode='aggressive').final_dom.display_text match "error code"
            ml.link_analysis func_call "ml.link_analysis(beta.scan_qr(file.message_screenshot()).items[].url).effective_url.domain.root_domain in (marketbeat.com)"
            ml.link_analysis(beta.scan_qr(file.message_screenshot()).items[].url, mode='aggressive').final_dom.display_text regex_match "cookie.{0,50}Cloudflare"
        or
          and
            ml.link_analysis(beta.scan_qr(file.message_screenshot()).items[].url, mode='aggressive').final_dom.display_text length_compare "200"
            ml.link_analysis(beta.scan_qr(file.message_screenshot()).items[].url, mode='aggressive').final_dom.raw contains "https://challenges.cloudflare.com/turnstile/"
          ml.link_analysis(beta.scan_qr(file.message_screenshot()).items[].url, mode='aggressive').final_dom.display_text contains "cloudflare"
        beta.scan_qr(file.message_screenshot()).items.type eq "url"
    any(body.links)
      and
        not
          or
            and
              any(ml.link_analysis(body.links, mode='aggressive').final_dom.links)
                ml.link_analysis(body.links, mode='aggressive').final_dom.links.href_url.query_params contains "utm_source=errorcode"
              ml.link_analysis(body.links[], mode='aggressive').final_dom.display_text match "error code"
            ml.link_analysis func_call "ml.link_analysis(body.links[]).effective_url.domain.root_domain in (marketbeat.com)"
            ml.link_analysis(body.links[], mode='aggressive').final_dom.display_text regex_match "cookie.{0,50}Cloudflare"
        or
          and
            ml.link_analysis(body.links[], mode='aggressive').final_dom.display_text length_compare "200"
            ml.link_analysis(body.links[], mode='aggressive').final_dom.raw contains "https://challenges.cloudflare.com/turnstile/"
          ml.link_analysis(body.links[], mode='aggressive').final_dom.display_text contains "cloudflare"
  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_email func_call "profile.by_sender_email().solicited"
  not
    any(attachments)
      attachments.content_type in ["message/delivery-status", "message/global-delivery-status"]
  or
    and
      body.links length_compare "0"
      body.links length_compare "20"
      distinct(body.links, .href_url.domain.root_domain) length_compare "10"
       macro "all(body.links)"
    beta.scan_qr func_call "beta.scan_qr(file.message_screenshot()).found"
  or
    any(body.links)
      body.links.href_url.url ends_with ".exe"
    any($suspicious_subjects)
      strings.icontains func_call "strings.icontains(subject.subject)"
    profile.by_sender_email func_call "profile.by_sender_email().days_known < 1"
    sender.display_name regex_match "/bHR/b"
    sender.display_name regex_match "Admin"
    sender.display_name regex_match "Administrator"
    sender.display_name regex_match "Alert"
    sender.display_name regex_match "Assistant"
    sender.display_name regex_match "Benefits"
    sender.display_name regex_match "Billing"
    sender.display_name regex_match "Bonus"
    sender.display_name regex_match "CEO"
    sender.display_name regex_match "CFO"
    sender.display_name regex_match "CIO"
    sender.display_name regex_match "CTO"
    sender.display_name regex_match "Chairman"
    sender.display_name regex_match "Claim"
    sender.display_name regex_match "Confirm"
    sender.display_name regex_match "Critical"
    sender.display_name regex_match "Customer Service"
    sender.display_name regex_match "Deal"
    sender.display_name regex_match "Director"
    sender.display_name regex_match "Discount"
    sender.display_name regex_match "Exclusive"
    sender.display_name regex_match "Executive"
    sender.display_name regex_match "Fax"
    sender.display_name regex_match "Free"
    sender.display_name regex_match "Gift"
    sender.display_name regex_match "Helpdesk"
    sender.display_name regex_match "Human Resources"
    sender.display_name regex_match "Immediate"
    sender.display_name regex_match "Important"
    sender.display_name regex_match "Info"
    sender.display_name regex_match "Information"
    sender.display_name regex_match "Invoice"
    sender.display_name regex_match "Legal"
    sender.display_name regex_match "Lottery"
    sender.display_name regex_match "Management"
    sender.display_name regex_match "Manager"
    sender.display_name regex_match "Member Services"
    sender.display_name regex_match "Notification"
    sender.display_name regex_match "Offer"
    sender.display_name regex_match "Operations"
    sender.display_name regex_match "Order"
    sender.display_name regex_match "Partner"
    sender.display_name regex_match "Payment"
    sender.display_name regex_match "Payroll"
    sender.display_name regex_match "Premium"
    sender.display_name regex_match "President"
    sender.display_name regex_match "Prize"
    sender.display_name regex_match "Receipt"
    sender.display_name regex_match "Refund"
    sender.display_name regex_match "Registrar"
    sender.display_name regex_match "Required"
    sender.display_name regex_match "Reward"
    sender.display_name regex_match "SSA"
    sender.display_name regex_match "Sales"
    sender.display_name regex_match "Secretary"
    sender.display_name regex_match "Security"
    sender.display_name regex_match "Service"
    sender.display_name regex_match "Signature"
    sender.display_name regex_match "Storage"
    sender.display_name regex_match "Support"
    sender.display_name regex_match "Sweepstakes"
    sender.display_name regex_match "System"
    sender.display_name regex_match "Tax"
    sender.display_name regex_match "Tech Support"
    sender.display_name regex_match "Update"
    sender.display_name regex_match "Upgrade"
    sender.display_name regex_match "Urgent"
    sender.display_name regex_match "VIP"
    sender.display_name regex_match "Validate"
    sender.display_name regex_match "Verify"
    sender.display_name regex_match "Webmaster"
    sender.display_name regex_match "Winner"
    sender.display_name regex_match "\\bIT\\b"
    subject.subject regex_match "38417"
    subject.subject regex_match ":completed"
    subject.subject regex_match "[il1]{2}mit.*ma[il1]{2} ?bo?x"
    subject.subject regex_match "[il][il][il]egai[ -]"
    subject.subject regex_match "[li][li][li]ega[li] attempt"
    subject.subject regex_match "[ng]-?[io]n .*block"
    subject.subject regex_match "[ng]-?[io]n .*cancel"
    subject.subject regex_match "[ng]-?[io]n .*deactiv"
    subject.subject regex_match "[ng]-?[io]n .*disabl"
    subject.subject regex_match "abandon.*package"
    subject.subject regex_match "about.your.account"
    subject.subject regex_match "acc(ou)?n?t (is )?on ho[li]d"
    subject.subject regex_match "acc(ou)?n?t.*terminat"
    subject.subject regex_match "acc(oun)?t.*[il1]{2}mitation"
    subject.subject regex_match "access.*limitation"
    subject.subject regex_match "account (will be )?block"
    subject.subject regex_match "account v[il]o[li]at"
    subject.subject regex_match "account.*de-?activat"
    subject.subject regex_match "account.*locked"
    subject.subject regex_match "account.*re-verification"
    subject.subject regex_match "account.*security"
    subject.subject regex_match "account.*suspension"
    subject.subject regex_match "account.has.been"
    subject.subject regex_match "account.has.expired"
    subject.subject regex_match "account.will.be.blocked"
    subject.subject regex_match "action.*required"
    subject.subject regex_match "activity.*acc(oun)?t"
    subject.subject regex_match "almost.full"
    subject.subject regex_match "app[li]e.[il]d"
    subject.subject regex_match "authenticate.*account"
    subject.subject regex_match "been.*suspend"
    subject.subject regex_match "clos.*of.*account.*processed"
    subject.subject regex_match "confirm.your.account"
    subject.subject regex_match "courier.*able"
    subject.subject regex_match "crediential.*notif"
    subject.subject regex_match "deactivation.*in.*progress"
    subject.subject regex_match "delivery.*attempt.*failed"
    subject.subject regex_match "document.received"
    subject.subject regex_match "documented.*shared.*with.*you"
    subject.subject regex_match "dropbox.*document"
    subject.subject regex_match "e-?ma[il1]+ .{010}suspen"
    subject.subject regex_match "e-?ma[il1]{1} user"
    subject.subject regex_match "e-?ma[il1]{2} acc"
    subject.subject regex_match "e-?ma[il1]{2}.*up.?grade"
    subject.subject regex_match "e.?ma[il1]{2}.*server"
    subject.subject regex_match "e.?ma[il1]{2}.*suspend"
    subject.subject regex_match "email.update"
    subject.subject regex_match "faxed you"
    subject.subject regex_match "fraud(ulent)?.*charge"
    subject.subject regex_match "from.helpdesk"
    subject.subject regex_match "fu[il1]{2}.*ma[il1]+[ -]?box"
    subject.subject regex_match "has.been.*suspended"
    subject.subject regex_match "has.been.limited"
    subject.subject regex_match "have.locked"
    subject.subject regex_match "he[li]p ?desk upgrade"
    subject.subject regex_match "heipdesk"
    subject.subject regex_match "i[il]iega[il]"
    subject.subject regex_match "ii[il]ega[il]"
    subject.subject regex_match "incoming e?mail"
    subject.subject regex_match "incoming.*fax"
    subject.subject regex_match "lock.*security"
    subject.subject regex_match "ma[il1]{1}[ -]?box.*quo"
    subject.subject regex_match "ma[il1]{2}[ -]?box.*fu[il1]"
    subject.subject regex_match "ma[il1]{2}box stor"
    subject.subject regex_match "ma[il1]{2}box.*[il1]{2}mit"
    subject.subject regex_match "mail on.?hold"
    subject.subject regex_match "mail.*box.*migration"
    subject.subject regex_match "mail.*de-?activat"
    subject.subject regex_match "mail.update.required"
    subject.subject regex_match "mails.*pending"
    subject.subject regex_match "messages.*pending"
    subject.subject regex_match "missed.*shipping.*notification"
    subject.subject regex_match "missed.shipment.notification"
    subject.subject regex_match "must.update.your.account"
    subject.subject regex_match "new [sl][io]g?[nig][ -]?in from"
    subject.subject regex_match "new voice ?-?mail"
    subject.subject regex_match "notifications.*pending"
    subject.subject regex_match "office.*3.*6.*5.*suspend"
    subject.subject regex_match "office365"
    subject.subject regex_match "on google docs with you"
    subject.subject regex_match "online doc"
    subject.subject regex_match "password.*compromised"
    subject.subject regex_match "periodic maintenance"
    subject.subject regex_match "potential(ly)? unauthorized"
    subject.subject regex_match "refund not approved"
    subject.subject regex_match "report"
    subject.subject regex_match "revised.*policy"
    subject.subject regex_match "scam"
    subject.subject regex_match "scanned.?invoice"
    subject.subject regex_match "secured?.update"
    subject.subject regex_match "security breach"
    subject.subject regex_match "securlty"
    subject.subject regex_match "signed.*delivery"
    subject.subject regex_match "statement is ready"
    subject.subject regex_match "status of your .{314}? ?delivery"
    subject.subject regex_match "susp[il1]+c[il1]+ous.*act[il1]+v[il1]+ty"
    subject.subject regex_match "suspicious.*sign.*[io]n"
    subject.subject regex_match "suspicious.activit"
    subject.subject regex_match "temporar(il)?y deactivate"
    subject.subject regex_match "temporar[il1]{2}y disab[li]ed"
    subject.subject regex_match "temporarily.*lock"
    subject.subject regex_match "termination.*notice"
    subject.subject regex_match "un-?usua[li].activity"
    subject.subject regex_match "unable.*deliver"
    subject.subject regex_match "unauthorized.*activit"
    subject.subject regex_match "unauthorized.device"
    subject.subject regex_match "undelivered message"
    subject.subject regex_match "unread.*doc"
    subject.subject regex_match "unusual.activity"
    subject.subject regex_match "upgrade.*account"
    subject.subject regex_match "upgrade.notice"
    subject.subject regex_match "urgent message"
    subject.subject regex_match "urgent.verification"
    subject.subject regex_match "v[il1]o[li1]at[il1]on security"
    subject.subject regex_match "va[il1]{1}date.*ma[il1]{2}[ -]?box"
    subject.subject regex_match "verification ?-?require"
    subject.subject regex_match "verification( )?-?need"
    subject.subject regex_match "verify.your?.account"
    subject.subject regex_match "web ?-?ma[il1]{2}"
    subject.subject regex_match "web[ -]?ma[il1]{2}"
    subject.subject regex_match "will.be.suspended"
    subject.subject regex_match "your (customer )?account .as"
    subject.subject regex_match "your.office.365"
    subject.subject regex_match "your.online.access"
  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
attachmentsarray_any(no value, null check)excludes:attachments

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
sender.display_nameregex_match
  • /bHR/b
  • Admin
  • Administrator
  • Alert
  • Assistant
  • Benefits
  • Billing
  • Bonus
  • CEO
  • CFO
  • CIO
  • CTO
  • Chairman
  • Claim
  • Confirm
  • Critical
  • Customer Service
  • Deal
  • Director
  • Discount
  • Exclusive
  • Executive
  • Fax
  • Free
  • Gift
  • Helpdesk
  • Human Resources
  • Immediate
  • Important
  • Info
  • Information
  • Invoice
  • Legal
  • Lottery
  • Management
  • Manager
  • Member Services
  • Notification
  • Offer
  • Operations
  • +33 more values (see full rule source)
field:"sender.display_name" kind:regex_match
subject.subjectregex_match
  • 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
  • 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 v[il]o[li]at
  • account.*de-?activat
  • account.*locked
  • account.*re-verification
  • account.*security
  • account.*suspension
  • account.has.been
  • account.has.expired
  • account.will.be.blocked
  • action.*required
  • 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
  • +84 more values (see full rule source)
field:"subject.subject" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Suspicious message with unscannable Vercel link

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

This rule detects messages with unscannable links to Vercel infrastructure with suspicious indicators in the subject or display name from an unsolicited sender.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

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

Rule body

type.inbound
and (
  // few links
  0 < length(body.links) < 20
  // fewer unique root domain links
  and length(distinct(body.links, .href_url.domain.root_domain)) < 10
  // sender domain matches no body domains
  and all(body.links,
          .href_url.domain.root_domain != sender.email.domain.root_domain
          // sender email address in body looks like this
          or .href_url.url == sender.email.domain.root_domain
  )
)

// negate bouncebacks and undeliverables
and not any(attachments,
            .content_type in (
              "message/global-delivery-status",
              "message/delivery-status"
            )
)

// suspicious subject or display name
and (
  regex.icontains(subject.subject,
                  "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",
                  "report",
                  "revised.*policy",
                  "scam",
                  "scanned.?invoice",
                  "secured?.update",
                  "security breach",
                  "securlty",
                  "signed.*delivery",
                  "statement is ready",
                  "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"
  )
  or any($suspicious_subjects, strings.icontains(subject.subject, .))
  or regex.icontains(sender.display_name,
                     "Admin",
                     "Administrator",
                     "Alert",
                     "Assistant",
                     "Billing",
                     "Benefits",
                     "Bonus",
                     "CEO",
                     "CFO",
                     "CIO",
                     "CTO",
                     "Chairman",
                     "Claim",
                     "Confirm",
                     "Critical",
                     "Customer Service",
                     "Deal",
                     "Discount",
                     "Director",
                     "Exclusive",
                     "Executive",
                     "Fax",
                     "Free",
                     "Gift",
                     "/bHR/b",
                     "Helpdesk",
                     "Human Resources",
                     "Immediate",
                     "Important",
                     "Info",
                     "Information",
                     "Invoice",
                     '\bIT\b',
                     "Legal",
                     "Lottery",
                     "Management",
                     "Manager",
                     "Member Services",
                     "Notification",
                     "Offer",
                     "Operations",
                     "Order",
                     "Partner",
                     "Payment",
                     "Payroll",
                     "President",
                     "Premium",
                     "Prize",
                     "Receipt",
                     "Refund",
                     "Registrar",
                     "Required",
                     "Reward",
                     "Sales",
                     "Secretary",
                     "Security",
                     "Service",
                     "Signature",
                     "SSA",
                     "Storage",
                     "Support",
                     "Sweepstakes",
                     "System",
                     "Tax",
                     "Tech Support",
                     "Update",
                     "Upgrade",
                     "Urgent",
                     "Validate",
                     "Verify",
                     "VIP",
                     "Webmaster",
                     "Winner",
  )
  or any(body.links,
         strings.ends_with(.href_url.url, ".exe")
         or .href_url.domain.root_domain in $social_landing_hosts
         or .href_url.domain.domain in $free_subdomain_hosts
         or .href_url.domain.root_domain in $free_subdomain_hosts
  )
)

// link can't be scanned due to Vercel block page
and any(body.links,
        strings.icontains(ml.link_analysis(., mode="aggressive").final_dom.display_text,
                          "Vercel Security Checkpoint"
        )
        or strings.icontains(ml.link_analysis(., mode="aggressive").final_dom.raw,
                             'https://vercel.link/security-checkpoint'
        )
)
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 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 with unscannable links to Vercel infrastructure with suspicious indicators in the subject or display name from an unsolicited sender.

  1. inbound message
  2. all of:
    • all of:
      • length(body.links) > 0
      • length(body.links) < 20
    • length(distinct(body.links, .href_url.domain.root_domain)) < 10
    • all of body.links where any holds:
      • .href_url.domain.root_domain is not sender.email.domain.root_domain
      • .href_url.url is sender.email.domain.root_domain
  3. not:
    • any of attachments where:
      • .content_type in ('message/global-delivery-status', 'message/delivery-status')
  4. any of:
    • subject.subject matches any of 124 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
      • report
      • revised.*policy
      • scam
      • scanned.?invoice
      • secured?.update
      • security breach
      • securlty
      • signed.*delivery
      • statement is ready
      • 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
    • any of $suspicious_subjects where:
      • strings.icontains(subject.subject)
    • sender.display_name matches any of 73 patterns
      • Admin
      • Administrator
      • Alert
      • Assistant
      • Billing
      • Benefits
      • Bonus
      • CEO
      • CFO
      • CIO
      • CTO
      • Chairman
      • Claim
      • Confirm
      • Critical
      • Customer Service
      • Deal
      • Discount
      • Director
      • Exclusive
      • Executive
      • Fax
      • Free
      • Gift
      • /bHR/b
      • Helpdesk
      • Human Resources
      • Immediate
      • Important
      • Info
      • Information
      • Invoice
      • \bIT\b
      • Legal
      • Lottery
      • Management
      • Manager
      • Member Services
      • Notification
      • Offer
      • Operations
      • Order
      • Partner
      • Payment
      • Payroll
      • President
      • Premium
      • Prize
      • Receipt
      • Refund
      • Registrar
      • Required
      • Reward
      • Sales
      • Secretary
      • Security
      • Service
      • Signature
      • SSA
      • Storage
      • Support
      • Sweepstakes
      • System
      • Tax
      • Tech Support
      • Update
      • Upgrade
      • Urgent
      • Validate
      • Verify
      • VIP
      • Webmaster
      • Winner
    • any of body.links where any holds:
      • .href_url.url ends with '.exe'
      • .href_url.domain.root_domain in $social_landing_hosts
      • .href_url.domain.domain in $free_subdomain_hosts
      • .href_url.domain.root_domain in $free_subdomain_hosts
  5. any of body.links where any holds:
    • ml.link_analysis(., mode='aggressive').final_dom.display_text contains 'Vercel Security Checkpoint'
    • ml.link_analysis(., mode='aggressive').final_dom.raw contains 'https://vercel.link/security-checkpoint'
  6. any of:
    • not:
      • profile.by_sender_email().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  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_messages_benign

Inspects: attachments[].content_type, body.links, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.url, headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: ml.link_analysis, profile.by_sender, profile.by_sender_email, regex.icontains, strings.ends_with, strings.icontains. Reference lists: $free_subdomain_hosts, $high_trust_sender_root_domains, $social_landing_hosts, $suspicious_subjects.

Indicators matched (200)

FieldMatchValue
regex.icontainsregextermination.*notice
regex.icontainsregex38417
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
188 more
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.icontainsregexreport
regex.icontainsregexrevised.*policy
regex.icontainsregexscam
regex.icontainsregexscanned.?invoice
regex.icontainsregexsecured?.update
regex.icontainsregexsecurity breach
regex.icontainsregexsecurlty
regex.icontainsregexsigned.*delivery
regex.icontainsregexstatement is ready
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.icontainsregexAdmin
regex.icontainsregexAdministrator
regex.icontainsregexAlert
regex.icontainsregexAssistant
regex.icontainsregexBilling
regex.icontainsregexBenefits
regex.icontainsregexBonus
regex.icontainsregexCEO
regex.icontainsregexCFO
regex.icontainsregexCIO
regex.icontainsregexCTO
regex.icontainsregexChairman
regex.icontainsregexClaim
regex.icontainsregexConfirm
regex.icontainsregexCritical
regex.icontainsregexCustomer Service
regex.icontainsregexDeal
regex.icontainsregexDiscount
regex.icontainsregexDirector
regex.icontainsregexExclusive
regex.icontainsregexExecutive
regex.icontainsregexFax
regex.icontainsregexFree
regex.icontainsregexGift
regex.icontainsregex/bHR/b
regex.icontainsregexHelpdesk
regex.icontainsregexHuman Resources
regex.icontainsregexImmediate
regex.icontainsregexImportant
regex.icontainsregexInfo
regex.icontainsregexInformation
regex.icontainsregexInvoice
regex.icontainsregex\bIT\b
regex.icontainsregexLegal
regex.icontainsregexLottery
regex.icontainsregexManagement
regex.icontainsregexManager
regex.icontainsregexMember Services
regex.icontainsregexNotification
regex.icontainsregexOffer
regex.icontainsregexOperations
regex.icontainsregexOrder
regex.icontainsregexPartner
regex.icontainsregexPayment
regex.icontainsregexPayroll
regex.icontainsregexPresident
regex.icontainsregexPremium
regex.icontainsregexPrize
regex.icontainsregexReceipt
regex.icontainsregexRefund
regex.icontainsregexRegistrar
regex.icontainsregexRequired
regex.icontainsregexReward
regex.icontainsregexSales
regex.icontainsregexSecretary
regex.icontainsregexSecurity
regex.icontainsregexService
regex.icontainsregexSignature
regex.icontainsregexSSA
regex.icontainsregexStorage
regex.icontainsregexSupport
regex.icontainsregexSweepstakes
regex.icontainsregexSystem
regex.icontainsregexTax
regex.icontainsregexTech Support
regex.icontainsregexUpdate
regex.icontainsregexUpgrade
regex.icontainsregexUrgent
regex.icontainsregexValidate
regex.icontainsregexVerify
regex.icontainsregexVIP
regex.icontainsregexWebmaster
regex.icontainsregexWinner
strings.ends_withsuffix.exe
strings.icontainssubstringVercel Security Checkpoint
strings.icontainssubstringhttps://vercel.link/security-checkpoint

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(body.links)
      or
        body.links.href_url.url ends_with ".exe"
         macro "body.links[].href_url.domain.domain in free_subdomain_hosts"
         macro "body.links[].href_url.domain.root_domain in free_subdomain_hosts"
         macro "body.links[].href_url.domain.root_domain in social_landing_hosts"
    any($suspicious_subjects)
      strings.icontains func_call "strings.icontains(subject.subject)"
    sender.display_name regex_match "/bHR/b"
    sender.display_name regex_match "Admin"
    sender.display_name regex_match "Administrator"
    sender.display_name regex_match "Alert"
    sender.display_name regex_match "Assistant"
    sender.display_name regex_match "Benefits"
    sender.display_name regex_match "Billing"
    sender.display_name regex_match "Bonus"
    sender.display_name regex_match "CEO"
    sender.display_name regex_match "CFO"
    sender.display_name regex_match "CIO"
    sender.display_name regex_match "CTO"
    sender.display_name regex_match "Chairman"
    sender.display_name regex_match "Claim"
    sender.display_name regex_match "Confirm"
    sender.display_name regex_match "Critical"
    sender.display_name regex_match "Customer Service"
    sender.display_name regex_match "Deal"
    sender.display_name regex_match "Director"
    sender.display_name regex_match "Discount"
    sender.display_name regex_match "Exclusive"
    sender.display_name regex_match "Executive"
    sender.display_name regex_match "Fax"
    sender.display_name regex_match "Free"
    sender.display_name regex_match "Gift"
    sender.display_name regex_match "Helpdesk"
    sender.display_name regex_match "Human Resources"
    sender.display_name regex_match "Immediate"
    sender.display_name regex_match "Important"
    sender.display_name regex_match "Info"
    sender.display_name regex_match "Information"
    sender.display_name regex_match "Invoice"
    sender.display_name regex_match "Legal"
    sender.display_name regex_match "Lottery"
    sender.display_name regex_match "Management"
    sender.display_name regex_match "Manager"
    sender.display_name regex_match "Member Services"
    sender.display_name regex_match "Notification"
    sender.display_name regex_match "Offer"
    sender.display_name regex_match "Operations"
    sender.display_name regex_match "Order"
    sender.display_name regex_match "Partner"
    sender.display_name regex_match "Payment"
    sender.display_name regex_match "Payroll"
    sender.display_name regex_match "Premium"
    sender.display_name regex_match "President"
    sender.display_name regex_match "Prize"
    sender.display_name regex_match "Receipt"
    sender.display_name regex_match "Refund"
    sender.display_name regex_match "Registrar"
    sender.display_name regex_match "Required"
    sender.display_name regex_match "Reward"
    sender.display_name regex_match "SSA"
    sender.display_name regex_match "Sales"
    sender.display_name regex_match "Secretary"
    sender.display_name regex_match "Security"
    sender.display_name regex_match "Service"
    sender.display_name regex_match "Signature"
    sender.display_name regex_match "Storage"
    sender.display_name regex_match "Support"
    sender.display_name regex_match "Sweepstakes"
    sender.display_name regex_match "System"
    sender.display_name regex_match "Tax"
    sender.display_name regex_match "Tech Support"
    sender.display_name regex_match "Update"
    sender.display_name regex_match "Upgrade"
    sender.display_name regex_match "Urgent"
    sender.display_name regex_match "VIP"
    sender.display_name regex_match "Validate"
    sender.display_name regex_match "Verify"
    sender.display_name regex_match "Webmaster"
    sender.display_name regex_match "Winner"
    sender.display_name regex_match "\\bIT\\b"
    subject.subject regex_match "38417"
    subject.subject regex_match ":completed"
    subject.subject regex_match "[il1]{2}mit.*ma[il1]{2} ?bo?x"
    subject.subject regex_match "[il][il][il]egai[ -]"
    subject.subject regex_match "[li][li][li]ega[li] attempt"
    subject.subject regex_match "[ng]-?[io]n .*block"
    subject.subject regex_match "[ng]-?[io]n .*cancel"
    subject.subject regex_match "[ng]-?[io]n .*deactiv"
    subject.subject regex_match "[ng]-?[io]n .*disabl"
    subject.subject regex_match "abandon.*package"
    subject.subject regex_match "about.your.account"
    subject.subject regex_match "acc(ou)?n?t (is )?on ho[li]d"
    subject.subject regex_match "acc(ou)?n?t.*terminat"
    subject.subject regex_match "acc(oun)?t.*[il1]{2}mitation"
    subject.subject regex_match "access.*limitation"
    subject.subject regex_match "account (will be )?block"
    subject.subject regex_match "account v[il]o[li]at"
    subject.subject regex_match "account.*de-?activat"
    subject.subject regex_match "account.*locked"
    subject.subject regex_match "account.*re-verification"
    subject.subject regex_match "account.*security"
    subject.subject regex_match "account.*suspension"
    subject.subject regex_match "account.has.been"
    subject.subject regex_match "account.has.expired"
    subject.subject regex_match "account.will.be.blocked"
    subject.subject regex_match "action.*required"
    subject.subject regex_match "activity.*acc(oun)?t"
    subject.subject regex_match "almost.full"
    subject.subject regex_match "app[li]e.[il]d"
    subject.subject regex_match "authenticate.*account"
    subject.subject regex_match "been.*suspend"
    subject.subject regex_match "clos.*of.*account.*processed"
    subject.subject regex_match "confirm.your.account"
    subject.subject regex_match "courier.*able"
    subject.subject regex_match "crediential.*notif"
    subject.subject regex_match "deactivation.*in.*progress"
    subject.subject regex_match "delivery.*attempt.*failed"
    subject.subject regex_match "document.received"
    subject.subject regex_match "documented.*shared.*with.*you"
    subject.subject regex_match "dropbox.*document"
    subject.subject regex_match "e-?ma[il1]+ .{010}suspen"
    subject.subject regex_match "e-?ma[il1]{1} user"
    subject.subject regex_match "e-?ma[il1]{2} acc"
    subject.subject regex_match "e-?ma[il1]{2}.*up.?grade"
    subject.subject regex_match "e.?ma[il1]{2}.*server"
    subject.subject regex_match "e.?ma[il1]{2}.*suspend"
    subject.subject regex_match "email.update"
    subject.subject regex_match "faxed you"
    subject.subject regex_match "fraud(ulent)?.*charge"
    subject.subject regex_match "from.helpdesk"
    subject.subject regex_match "fu[il1]{2}.*ma[il1]+[ -]?box"
    subject.subject regex_match "has.been.*suspended"
    subject.subject regex_match "has.been.limited"
    subject.subject regex_match "have.locked"
    subject.subject regex_match "he[li]p ?desk upgrade"
    subject.subject regex_match "heipdesk"
    subject.subject regex_match "i[il]iega[il]"
    subject.subject regex_match "ii[il]ega[il]"
    subject.subject regex_match "incoming e?mail"
    subject.subject regex_match "incoming.*fax"
    subject.subject regex_match "lock.*security"
    subject.subject regex_match "ma[il1]{1}[ -]?box.*quo"
    subject.subject regex_match "ma[il1]{2}[ -]?box.*fu[il1]"
    subject.subject regex_match "ma[il1]{2}box stor"
    subject.subject regex_match "ma[il1]{2}box.*[il1]{2}mit"
    subject.subject regex_match "mail on.?hold"
    subject.subject regex_match "mail.*box.*migration"
    subject.subject regex_match "mail.*de-?activat"
    subject.subject regex_match "mail.update.required"
    subject.subject regex_match "mails.*pending"
    subject.subject regex_match "messages.*pending"
    subject.subject regex_match "missed.*shipping.*notification"
    subject.subject regex_match "missed.shipment.notification"
    subject.subject regex_match "must.update.your.account"
    subject.subject regex_match "new [sl][io]g?[nig][ -]?in from"
    subject.subject regex_match "new voice ?-?mail"
    subject.subject regex_match "notifications.*pending"
    subject.subject regex_match "office.*3.*6.*5.*suspend"
    subject.subject regex_match "office365"
    subject.subject regex_match "on google docs with you"
    subject.subject regex_match "online doc"
    subject.subject regex_match "password.*compromised"
    subject.subject regex_match "periodic maintenance"
    subject.subject regex_match "potential(ly)? unauthorized"
    subject.subject regex_match "refund not approved"
    subject.subject regex_match "report"
    subject.subject regex_match "revised.*policy"
    subject.subject regex_match "scam"
    subject.subject regex_match "scanned.?invoice"
    subject.subject regex_match "secured?.update"
    subject.subject regex_match "security breach"
    subject.subject regex_match "securlty"
    subject.subject regex_match "signed.*delivery"
    subject.subject regex_match "statement is ready"
    subject.subject regex_match "status of your .{314}? ?delivery"
    subject.subject regex_match "susp[il1]+c[il1]+ous.*act[il1]+v[il1]+ty"
    subject.subject regex_match "suspicious.*sign.*[io]n"
    subject.subject regex_match "suspicious.activit"
    subject.subject regex_match "temporar(il)?y deactivate"
    subject.subject regex_match "temporar[il1]{2}y disab[li]ed"
    subject.subject regex_match "temporarily.*lock"
    subject.subject regex_match "termination.*notice"
    subject.subject regex_match "un-?usua[li].activity"
    subject.subject regex_match "unable.*deliver"
    subject.subject regex_match "unauthorized.*activit"
    subject.subject regex_match "unauthorized.device"
    subject.subject regex_match "undelivered message"
    subject.subject regex_match "unread.*doc"
    subject.subject regex_match "unusual.activity"
    subject.subject regex_match "upgrade.*account"
    subject.subject regex_match "upgrade.notice"
    subject.subject regex_match "urgent message"
    subject.subject regex_match "urgent.verification"
    subject.subject regex_match "v[il1]o[li1]at[il1]on security"
    subject.subject regex_match "va[il1]{1}date.*ma[il1]{2}[ -]?box"
    subject.subject regex_match "verification ?-?require"
    subject.subject regex_match "verification( )?-?need"
    subject.subject regex_match "verify.your?.account"
    subject.subject regex_match "web ?-?ma[il1]{2}"
    subject.subject regex_match "web[ -]?ma[il1]{2}"
    subject.subject regex_match "will.be.suspended"
    subject.subject regex_match "your (customer )?account .as"
    subject.subject regex_match "your.office.365"
    subject.subject 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
    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_email func_call "profile.by_sender_email().solicited"
  not
    any(attachments)
      attachments.content_type in ["message/delivery-status", "message/global-delivery-status"]
  any(body.links)
    or
      ml.link_analysis(body.links[], mode='aggressive').final_dom.display_text contains "Vercel Security Checkpoint"
      ml.link_analysis(body.links[], mode='aggressive').final_dom.raw contains "https://vercel.link/security-checkpoint"
  not
    profile.by_sender func_call "profile.by_sender().any_messages_benign"
  body.links length_compare "0"
  body.links length_compare "20"
  distinct(body.links, .href_url.domain.root_domain) length_compare "10"
  type.inbound eq "true"
   macro "all(body.links)"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
attachmentsarray_any(no value, null check)excludes:attachments

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
sender.display_nameregex_match
  • /bHR/b
  • Admin
  • Administrator
  • Alert
  • Assistant
  • Benefits
  • Billing
  • Bonus
  • CEO
  • CFO
  • CIO
  • CTO
  • Chairman
  • Claim
  • Confirm
  • Critical
  • Customer Service
  • Deal
  • Director
  • Discount
  • Exclusive
  • Executive
  • Fax
  • Free
  • Gift
  • Helpdesk
  • Human Resources
  • Immediate
  • Important
  • Info
  • Information
  • Invoice
  • Legal
  • Lottery
  • Management
  • Manager
  • Member Services
  • Notification
  • Offer
  • Operations
  • +33 more values (see full rule source)
field:"sender.display_name" kind:regex_match
subject.subjectregex_match
  • 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
  • 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 v[il]o[li]at
  • account.*de-?activat
  • account.*locked
  • account.*re-verification
  • account.*security
  • account.*suspension
  • account.has.been
  • account.has.expired
  • account.will.be.blocked
  • action.*required
  • 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
  • +84 more values (see full rule source)
field:"subject.subject" kind:regex_match
type.inboundeq
  • true transforms: boolean
field:"type.inbound" kind:eq value:"true"

Suspicious Office 365 app authorization (OAuth) link

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

Message contains a suspicious Office 365 app authorization (OAuth) link. The app may be compromised or was stood up for malicious purposes. Once the app has been authorized, the attacker will have read or write permissions to the user's Office 365 account.

Threat classification

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

CategoryValues
Attack typesCredential Phishing

Telemetry coverage

PlatformRecord / event type
SublimeInbound email message

Message attributes

  • attachments
  • body
  • body.current_thread
  • type

Rule body

type.inbound
and (
  // links in email body
  any([body.links, body.current_thread.links],
      any(.,
          (
            .href_url.domain.domain == 'login.microsoftonline.com'
            or strings.icontains(.href_url.query_params,
                                 "login.microsoftonline.com"
            )
          )
          and (
            strings.ilike(.href_url.query_params,
                          '*offline_access*',
                          '*.readwrite*',
                          '*.read*',
                          '*ctx=*',
                          '*prompt=none*'
            )
            or (
              (
                strings.icontains(.href_url.path, '/common/reprocess')
                or strings.icontains(.href_url.query_params,
                                     "/common/reprocess"
                )
              )
              and strings.icontains(.href_url.query_params, 'ctx=')
              and strings.icontains(.href_url.query_params, 'sessionId=')
            )
          )
      )
  )
  // links in PDF, HTML, DOCX and PPTX attachments
  or any(filter(attachments, .file_type in ("pdf", "html", "docx", "pptx")),
         any(file.explode(.),
             any(.scan.url.urls,
                 .domain.domain == 'login.microsoftonline.com'
                 and (
                   strings.ilike(.query_params,
                                 '*offline_access*',
                                 '*.readwrite*',
                                 '*.read*',
                                 '*ctx=*',
                                 '*prompt=none*'
                   )
                   or (
                     strings.icontains(.path, '/common/reprocess')
                     and strings.icontains(.query_params, 'ctx=')
                     and strings.icontains(.query_params, 'sessionId=')
                   )
                 )
             )
         )
  )
  or any(attachments,
         (
           .file_type == "ics"
           or .file_extension == "ics"
           or .content_type in ("application/ics", "text/calendar")
         )
         //
         // 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(beta.file.parse_ics(.).events,
                 any(.links,
                     .href_url.domain.domain == 'login.microsoftonline.com'
                     and (
                       strings.ilike(.href_url.query_params,
                                     '*offline_access*',
                                     '*.readwrite*',
                                     '*.read*',
                                     '*ctx=*',
                                     '*prompt=none*'
                       )
                       or (
                         strings.icontains(.href_url.path, '/common/reprocess')
                         and strings.icontains(.href_url.query_params, 'ctx=')
                         and strings.icontains(.href_url.query_params,
                                               'sessionId='
                         )
                       )
                     )
                 )
         )
  )
)

Detection logic

Scope: inbound message.

Message contains a suspicious Office 365 app authorization (OAuth) link. The app may be compromised or was stood up for malicious purposes. Once the app has been authorized, the attacker will have read or write permissions to the user's Office 365 account.

  1. inbound message
  2. any of:
    • any of [body.links, body.current_thread.links] where:
      • any of . where all hold:
        • any of:
          • .href_url.domain.domain is 'login.microsoftonline.com'
          • .href_url.query_params contains 'login.microsoftonline.com'
        • any of:
          • .href_url.query_params matches any of 5 patterns
            • *offline_access*
            • *.readwrite*
            • *.read*
            • *ctx=*
            • *prompt=none*
          • all of:
            • any of:
              • .href_url.path contains '/common/reprocess'
              • .href_url.query_params contains '/common/reprocess'
            • .href_url.query_params contains 'ctx='
            • .href_url.query_params contains 'sessionId='
    • any of filter(attachments) where:
      • any of file.explode(.) where:
        • any of .scan.url.urls where all hold:
          • .domain.domain is 'login.microsoftonline.com'
          • any of:
            • .query_params matches any of 5 patterns
              • *offline_access*
              • *.readwrite*
              • *.read*
              • *ctx=*
              • *prompt=none*
            • all of:
              • .path contains '/common/reprocess'
              • .query_params contains 'ctx='
              • .query_params contains 'sessionId='
    • any of attachments where all hold:
      • any of:
        • .file_type is 'ics'
        • .file_extension is 'ics'
        • .content_type in ('application/ics', 'text/calendar')
      • any of beta.file.parse_ics(.).events where:
        • any of .links where all hold:
          • .href_url.domain.domain is 'login.microsoftonline.com'
          • any of:
            • .href_url.query_params matches any of 5 patterns
              • *offline_access*
              • *.readwrite*
              • *.read*
              • *ctx=*
              • *prompt=none*
            • all of:
              • .href_url.path contains '/common/reprocess'
              • .href_url.query_params contains 'ctx='
              • .href_url.query_params contains 'sessionId='

Inspects: attachments[].content_type, attachments[].file_extension, attachments[].file_type, body.current_thread.links, body.links, type.inbound. Sensors: beta.file.parse_ics, file.explode, strings.icontains, strings.ilike.

Indicators matched (20)

FieldMatchValue
[body.links, body.current_thread.links][][].href_url.domain.domainequalslogin.microsoftonline.com
strings.icontainssubstringlogin.microsoftonline.com
strings.ilikesubstring*offline_access*
strings.ilikesubstring*.readwrite*
strings.ilikesubstring*.read*
strings.ilikesubstring*ctx=*
strings.ilikesubstring*prompt=none*
strings.icontainssubstring/common/reprocess
strings.icontainssubstringctx=
strings.icontainssubstringsessionId=
attachments[].file_typememberpdf
attachments[].file_typememberhtml
8 more
attachments[].file_typememberdocx
attachments[].file_typememberpptx
file.explode(filter(attachments)[])[].scan.url.urls[].domain.domainequalslogin.microsoftonline.com
attachments[].file_typeequalsics
attachments[].file_extensionequalsics
attachments[].content_typememberapplication/ics
attachments[].content_typemembertext/calendar
beta.file.parse_ics(attachments[]).events[].links[].href_url.domain.domainequalslogin.microsoftonline.com

Stages and Predicates

Stage 1: mql_rule

and
  or
    any(attachments)
      and
        any(beta.file.parse_ics(attachments).events)
          any(beta.file.parse_ics(attachments).events.links)
            and
              or
                and
                  beta.file.parse_ics(attachments[]).events[].links[].href_url.path contains "/common/reprocess"
                  beta.file.parse_ics(attachments[]).events[].links[].href_url.query_params contains "ctx="
                  beta.file.parse_ics(attachments[]).events[].links[].href_url.query_params contains "sessionId="
                beta.file.parse_ics(attachments[]).events[].links[].href_url.query_params match ".read"
                beta.file.parse_ics(attachments[]).events[].links[].href_url.query_params match ".readwrite"
                beta.file.parse_ics(attachments[]).events[].links[].href_url.query_params match "ctx="
                beta.file.parse_ics(attachments[]).events[].links[].href_url.query_params match "offline_access"
                beta.file.parse_ics(attachments[]).events[].links[].href_url.query_params match "prompt=none"
              beta.file.parse_ics(attachments[]).events[].links[].href_url.domain.domain eq "login.microsoftonline.com"
        or
          attachments.content_type in ["application/ics", "text/calendar"]
          attachments.file_extension eq "ics"
          attachments.file_type eq "ics"
    any([body.links, body.current_thread.links])
      any([body.links, body.current_thread.links])
        and
          or
            and
              or
                [body.links, body.current_thread.links].href_url.path contains "/common/reprocess"
                [body.links, body.current_thread.links].href_url.query_params contains "/common/reprocess"
              [body.links, body.current_thread.links].href_url.query_params contains "ctx="
              [body.links, body.current_thread.links].href_url.query_params contains "sessionId="
            [body.links, body.current_thread.links].href_url.query_params match ".read"
            [body.links, body.current_thread.links].href_url.query_params match ".readwrite"
            [body.links, body.current_thread.links].href_url.query_params match "ctx="
            [body.links, body.current_thread.links].href_url.query_params match "offline_access"
            [body.links, body.current_thread.links].href_url.query_params match "prompt=none"
          or
            [body.links, body.current_thread.links].href_url.domain.domain eq "login.microsoftonline.com"
            [body.links, body.current_thread.links].href_url.query_params contains "login.microsoftonline.com"
    any(filter(attachments))
      any(file.explode(filter(attachments)))
        any(file.explode(filter(attachments)).scan.url.urls)
          and
            or
              and
                file.explode(filter(attachments)[])[].scan.url.urls[].path contains "/common/reprocess"
                file.explode(filter(attachments)[])[].scan.url.urls[].query_params contains "ctx="
                file.explode(filter(attachments)[])[].scan.url.urls[].query_params contains "sessionId="
              file.explode(filter(attachments)[])[].scan.url.urls[].query_params match ".read"
              file.explode(filter(attachments)[])[].scan.url.urls[].query_params match ".readwrite"
              file.explode(filter(attachments)[])[].scan.url.urls[].query_params match "ctx="
              file.explode(filter(attachments)[])[].scan.url.urls[].query_params match "offline_access"
              file.explode(filter(attachments)[])[].scan.url.urls[].query_params match "prompt=none"
            file.explode(filter(attachments)[])[].scan.url.urls[].domain.domain eq "login.microsoftonline.com"
  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"